1 2 /* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #ifndef GrCaps_DEFINED 9 #define GrCaps_DEFINED 10 11 #include "../private/GrTypesPriv.h" 12 #include "GrBlend.h" 13 #include "GrDriverBugWorkarounds.h" 14 #include "GrShaderCaps.h" 15 #include "SkImageInfo.h" 16 #include "SkRefCnt.h" 17 #include "SkString.h" 18 19 class GrBackendFormat; 20 class GrBackendRenderTarget; 21 class GrBackendTexture; 22 struct GrContextOptions; 23 class GrRenderTargetProxy; 24 class GrSurface; 25 class GrSurfaceProxy; 26 class SkJSONWriter; 27 28 /** 29 * Represents the capabilities of a GrContext. 30 */ 31 class GrCaps : public SkRefCnt { 32 public: 33 GrCaps(const GrContextOptions&); 34 35 void dumpJSON(SkJSONWriter*) const; 36 37 const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } 38 39 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 40 /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. 41 only for POT textures) */ 42 bool mipMapSupport() const { return fMipMapSupport; } 43 44 /** 45 * Skia convention is that a device only has sRGB support if it supports sRGB formats for both 46 * textures and framebuffers. 47 */ 48 bool srgbSupport() const { return fSRGBSupport; } 49 /** 50 * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? 51 */ 52 bool srgbWriteControl() const { return fSRGBWriteControl; } 53 bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } 54 bool gpuTracingSupport() const { return fGpuTracingSupport; } 55 bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } 56 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } 57 bool textureBarrierSupport() const { return fTextureBarrierSupport; } 58 bool sampleLocationsSupport() const { return fSampleLocationsSupport; } 59 bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } 60 bool instanceAttribSupport() const { return fInstanceAttribSupport; } 61 bool usesMixedSamples() const { return fUsesMixedSamples; } 62 bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; } 63 64 // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some 65 // systems. This cap is only set if primitive restart will improve performance. 66 bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } 67 68 bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } 69 70 // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to 71 // initialize each tile with a constant value rather than loading each pixel from memory. 72 bool preferFullscreenClears() const { return fPreferFullscreenClears; } 73 74 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 75 76 bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; } 77 78 bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } 79 80 bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; } 81 82 /** 83 * Indicates the capabilities of the fixed function blend unit. 84 */ 85 enum BlendEquationSupport { 86 kBasic_BlendEquationSupport, //<! Support to select the operator that 87 // combines src and dst terms. 88 kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific 89 // SVG/PDF blend modes. Requires blend barriers. 90 kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not 91 // require blend barriers, and permits overlap. 92 93 kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport 94 }; 95 96 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 97 98 bool advancedBlendEquationSupport() const { 99 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 100 } 101 102 bool advancedCoherentBlendEquationSupport() const { 103 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 104 } 105 106 bool isAdvancedBlendEquationBlacklisted(GrBlendEquation equation) const { 107 SkASSERT(GrBlendEquationIsAdvanced(equation)); 108 SkASSERT(this->advancedBlendEquationSupport()); 109 return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); 110 } 111 112 /** 113 * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and 114 * textures allows partial mappings or full mappings. 115 */ 116 enum MapFlags { 117 kNone_MapFlags = 0x0, //<! Cannot map the resource. 118 119 kCanMap_MapFlag = 0x1, //<! The resource can be mapped. Must be set for any of 120 // the other flags to have meaning. 121 kSubset_MapFlag = 0x2, //<! The resource can be partially mapped. 122 }; 123 124 uint32_t mapBufferFlags() const { return fMapBufferFlags; } 125 126 // Scratch textures not being reused means that those scratch textures 127 // that we upload to (i.e., don't have a render target) will not be 128 // recycled in the texture cache. This is to prevent ghosting by drivers 129 // (in particular for deferred architectures). 130 bool reuseScratchTextures() const { return fReuseScratchTextures; } 131 bool reuseScratchBuffers() const { return fReuseScratchBuffers; } 132 133 /// maximum number of attribute values per vertex 134 int maxVertexAttributes() const { return fMaxVertexAttributes; } 135 136 int maxRenderTargetSize() const { return fMaxRenderTargetSize; } 137 138 /** This is the largest render target size that can be used without incurring extra perfomance 139 cost. It is usually the max RT size, unless larger render targets are known to be slower. */ 140 int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; } 141 142 int maxTextureSize() const { return fMaxTextureSize; } 143 144 /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps. 145 It is usually the max texture size, unless we're overriding it for testing. */ 146 int maxTileSize() const { 147 SkASSERT(fMaxTileSize <= fMaxTextureSize); 148 return fMaxTileSize; 149 } 150 151 int maxWindowRectangles() const { return fMaxWindowRectangles; } 152 153 // Returns whether mixed samples is supported for the given backend render target. 154 bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { 155 return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); 156 } 157 158 // A tuned, platform-specific value for the maximum number of analytic fragment processors we 159 // should use to implement a clip, before falling back on a mask. 160 int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; } 161 162 virtual bool isConfigTexturable(GrPixelConfig) const = 0; 163 164 // Returns whether a texture of the given config can be copied to a texture of the same config. 165 virtual bool isConfigCopyable(GrPixelConfig) const = 0; 166 167 // Returns the maximum supported sample count for a config. 0 means the config is not renderable 168 // 1 means the config is renderable but doesn't support MSAA. 169 virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0; 170 171 bool isConfigRenderable(GrPixelConfig config) const { 172 return this->maxRenderTargetSampleCount(config) > 0; 173 } 174 175 // TODO: Remove this after Flutter updated to no longer use it. 176 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 177 return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0); 178 } 179 180 // Find a sample count greater than or equal to the requested count which is supported for a 181 // color buffer of the given config or 0 if no such sample count is supported. If the requested 182 // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. 183 // For historical reasons requestedCount==0 is handled identically to requestedCount==1. 184 virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0; 185 // TODO: Remove. Legacy name used by Chrome. 186 int getSampleCount(int requestedCount, GrPixelConfig config) const { 187 return this->getRenderTargetSampleCount(requestedCount, config); 188 } 189 190 /** 191 * Backends may have restrictions on what types of surfaces support GrGpu::writePixels(). 192 * If this returns false then the caller should implement a fallback where a temporary texture 193 * is created, pixels are written to it, and then that is copied or drawn into the the surface. 194 */ 195 bool surfaceSupportsWritePixels(const GrSurface*) const; 196 197 /** 198 * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). 199 * If this returns false then the caller should implement a fallback where a temporary texture 200 * is created, the surface is drawn or copied into the temporary, and pixels are read from the 201 * temporary. 202 */ 203 virtual bool surfaceSupportsReadPixels(const GrSurface*) const = 0; 204 205 /** 206 * Given a dst pixel config and a src color type what color type must the caller coax the 207 * the data into in order to use GrGpu::writePixels(). 208 */ 209 virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config, 210 GrColorType /*srcColorType*/) const { 211 return GrPixelConfigToColorType(config); 212 } 213 214 /** 215 * Given a src pixel config and a dst color type what color type must the caller read to using 216 * GrGpu::readPixels() and then coax into dstColorType. 217 */ 218 virtual GrColorType supportedReadPixelsColorType(GrPixelConfig config, 219 GrColorType /*dstColorType*/) const { 220 return GrPixelConfigToColorType(config); 221 } 222 223 bool suppressPrints() const { return fSuppressPrints; } 224 225 size_t bufferMapThreshold() const { 226 SkASSERT(fBufferMapThreshold >= 0); 227 return fBufferMapThreshold; 228 } 229 230 /** True in environments that will issue errors if memory uploaded to buffers 231 is not initialized (even if not read by draw calls). */ 232 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 233 234 /** Returns true if the given backend supports importing AHardwareBuffers via the 235 * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API 236 * level >= 26. 237 * */ 238 bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; } 239 240 bool wireframeMode() const { return fWireframeMode; } 241 242 bool fenceSyncSupport() const { return fFenceSyncSupport; } 243 bool crossContextTextureSupport() const { return fCrossContextTextureSupport; } 244 /** 245 * Returns whether or not we will be able to do a copy given the passed in params 246 */ 247 bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 248 const SkIRect& srcRect, const SkIPoint& dstPoint) const; 249 250 bool dynamicStateArrayGeometryProcessorTextureSupport() const { 251 return fDynamicStateArrayGeometryProcessorTextureSupport; 252 } 253 254 // Not all backends support clearing with a scissor test (e.g. Metal), this will always 255 // return true if performColorClearsAsDraws() returns true. 256 bool performPartialClearsAsDraws() const { 257 return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws; 258 } 259 260 // Many drivers have issues with color clears. 261 bool performColorClearsAsDraws() const { 262 return fPerformColorClearsAsDraws; 263 } 264 265 /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit 266 /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil 267 /// op instead of using glClear seems to resolve the issue. 268 bool performStencilClearsAsDraws() const { 269 return fPerformStencilClearsAsDraws; 270 } 271 272 /** 273 * This is can be called before allocating a texture to be a dst for copySurface. This is only 274 * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It 275 * will populate config and flags fields of the desc such that copySurface can efficiently 276 * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation 277 * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if 278 * copy rect must equal src's bounds. 279 */ 280 virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, 281 GrSurfaceOrigin* origin, bool* rectsMustMatch, 282 bool* disallowSubrect) const = 0; 283 284 bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const; 285 286 /** 287 * If the GrBackendRenderTarget can be used with the supplied SkColorType the return will be 288 * the config that matches the backend format and requested SkColorType. Otherwise, kUnknown is 289 * returned. 290 */ 291 virtual GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&, 292 SkColorType) const = 0; 293 294 // TODO: replace validateBackendRenderTarget with calls to getConfigFromBackendFormat? 295 // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too 296 // Returns kUnknown if a valid config could not be determined. 297 virtual GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat& format, 298 SkColorType ct) const = 0; 299 300 /** 301 * Special method only for YUVA images. Returns a config that matches the backend format or 302 * kUnknown if a config could not be determined. 303 */ 304 virtual GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat& format) const = 0; 305 306 /** These are used when creating a new texture internally. */ 307 virtual GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct, 308 GrSRGBEncoded srgbEncoded) const = 0; 309 GrBackendFormat getBackendFormatFromColorType(SkColorType ct) const; 310 311 /** 312 * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and 313 * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support. 314 */ 315 bool clampToBorderSupport() const { return fClampToBorderSupport; } 316 317 const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; } 318 319 protected: 320 /** Subclasses must call this at the end of their constructors in order to apply caps 321 overrides requested by the client. Note that overrides will only reduce the caps never 322 expand them. */ 323 void applyOptionsOverrides(const GrContextOptions& options); 324 325 sk_sp<GrShaderCaps> fShaderCaps; 326 327 bool fNPOTTextureTileSupport : 1; 328 bool fMipMapSupport : 1; 329 bool fSRGBSupport : 1; 330 bool fSRGBWriteControl : 1; 331 bool fDiscardRenderTargetSupport : 1; 332 bool fReuseScratchTextures : 1; 333 bool fReuseScratchBuffers : 1; 334 bool fGpuTracingSupport : 1; 335 bool fCompressedTexSubImageSupport : 1; 336 bool fOversizedStencilSupport : 1; 337 bool fTextureBarrierSupport : 1; 338 bool fSampleLocationsSupport : 1; 339 bool fMultisampleDisableSupport : 1; 340 bool fInstanceAttribSupport : 1; 341 bool fUsesMixedSamples : 1; 342 bool fUsePrimitiveRestart : 1; 343 bool fPreferClientSideDynamicBuffers : 1; 344 bool fPreferFullscreenClears : 1; 345 bool fMustClearUploadedBufferData : 1; 346 bool fSupportsAHardwareBufferImages : 1; 347 bool fHalfFloatVertexAttributeSupport : 1; 348 bool fClampToBorderSupport : 1; 349 bool fPerformPartialClearsAsDraws : 1; 350 bool fPerformColorClearsAsDraws : 1; 351 bool fPerformStencilClearsAsDraws : 1; 352 353 // Driver workaround 354 bool fBlacklistCoverageCounting : 1; 355 bool fAvoidStencilBuffers : 1; 356 bool fAvoidWritePixelsFastPath : 1; 357 358 // ANGLE performance workaround 359 bool fPreferVRAMUseOverFlushes : 1; 360 361 // TODO: this may need to be an enum to support different fence types 362 bool fFenceSyncSupport : 1; 363 364 // Requires fence sync support in GL. 365 bool fCrossContextTextureSupport : 1; 366 367 // Not (yet) implemented in VK backend. 368 bool fDynamicStateArrayGeometryProcessorTextureSupport : 1; 369 370 BlendEquationSupport fBlendEquationSupport; 371 uint32_t fAdvBlendEqBlacklist; 372 GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); 373 374 uint32_t fMapBufferFlags; 375 int fBufferMapThreshold; 376 377 int fMaxRenderTargetSize; 378 int fMaxPreferredRenderTargetSize; 379 int fMaxVertexAttributes; 380 int fMaxTextureSize; 381 int fMaxTileSize; 382 int fMaxWindowRectangles; 383 int fMaxClipAnalyticFPs; 384 385 GrDriverBugWorkarounds fDriverBugWorkarounds; 386 387 private: 388 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} 389 virtual void onDumpJSON(SkJSONWriter*) const {} 390 virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0; 391 virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 392 const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0; 393 394 // Backends should implement this if they have any extra requirements for use of window 395 // rectangles for a specific GrBackendRenderTarget outside of basic support. 396 virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { 397 return true; 398 } 399 400 bool fSuppressPrints : 1; 401 bool fWireframeMode : 1; 402 403 typedef SkRefCnt INHERITED; 404 }; 405 406 #endif 407