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 shaderCaps()37 const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } 38 npotTextureTileSupport()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) */ mipMapSupport()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 */ srgbSupport()48 bool srgbSupport() const { return fSRGBSupport; } 49 /** 50 * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? 51 */ srgbWriteControl()52 bool srgbWriteControl() const { return fSRGBWriteControl; } discardRenderTargetSupport()53 bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } gpuTracingSupport()54 bool gpuTracingSupport() const { return fGpuTracingSupport; } compressedTexSubImageSupport()55 bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } oversizedStencilSupport()56 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } textureBarrierSupport()57 bool textureBarrierSupport() const { return fTextureBarrierSupport; } sampleLocationsSupport()58 bool sampleLocationsSupport() const { return fSampleLocationsSupport; } multisampleDisableSupport()59 bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } instanceAttribSupport()60 bool instanceAttribSupport() const { return fInstanceAttribSupport; } usesMixedSamples()61 bool usesMixedSamples() const { return fUsesMixedSamples; } halfFloatVertexAttributeSupport()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. usePrimitiveRestart()66 bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } 67 preferClientSideDynamicBuffers()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. preferFullscreenClears()72 bool preferFullscreenClears() const { return fPreferFullscreenClears; } 73 preferVRAMUseOverFlushes()74 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 75 blacklistCoverageCounting()76 bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; } 77 avoidStencilBuffers()78 bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } 79 avoidWritePixelsFastPath()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 blendEquationSupport()96 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 97 advancedBlendEquationSupport()98 bool advancedBlendEquationSupport() const { 99 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 100 } 101 advancedCoherentBlendEquationSupport()102 bool advancedCoherentBlendEquationSupport() const { 103 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 104 } 105 isAdvancedBlendEquationBlacklisted(GrBlendEquation equation)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 mapBufferFlags()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). reuseScratchTextures()130 bool reuseScratchTextures() const { return fReuseScratchTextures; } reuseScratchBuffers()131 bool reuseScratchBuffers() const { return fReuseScratchBuffers; } 132 133 /// maximum number of attribute values per vertex maxVertexAttributes()134 int maxVertexAttributes() const { return fMaxVertexAttributes; } 135 maxRenderTargetSize()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. */ maxPreferredRenderTargetSize()140 int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; } 141 maxTextureSize()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. */ maxTileSize()146 int maxTileSize() const { 147 SkASSERT(fMaxTileSize <= fMaxTextureSize); 148 return fMaxTileSize; 149 } 150 maxRasterSamples()151 int maxRasterSamples() const { return fMaxRasterSamples; } 152 maxWindowRectangles()153 int maxWindowRectangles() const { return fMaxWindowRectangles; } 154 155 // Returns whether mixed samples is supported for the given backend render target. isWindowRectanglesSupportedForRT(const GrBackendRenderTarget & rt)156 bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { 157 return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); 158 } 159 160 // A tuned, platform-specific value for the maximum number of analytic fragment processors we 161 // should use to implement a clip, before falling back on a mask. maxClipAnalyticFPs()162 int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; } 163 164 virtual bool isConfigTexturable(GrPixelConfig) const = 0; 165 166 // Returns whether a texture of the given config can be copied to a texture of the same config. 167 virtual bool isConfigCopyable(GrPixelConfig) const = 0; 168 169 // Returns the maximum supported sample count for a config. 0 means the config is not renderable 170 // 1 means the config is renderable but doesn't support MSAA. 171 virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0; 172 isConfigRenderable(GrPixelConfig config)173 bool isConfigRenderable(GrPixelConfig config) const { 174 return this->maxRenderTargetSampleCount(config) > 0; 175 } 176 177 // TODO: Remove this after Flutter updated to no longer use it. isConfigRenderable(GrPixelConfig config,bool withMSAA)178 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 179 return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0); 180 } 181 182 // Find a sample count greater than or equal to the requested count which is supported for a 183 // color buffer of the given config or 0 if no such sample count is supported. If the requested 184 // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. 185 // For historical reasons requestedCount==0 is handled identically to requestedCount==1. 186 virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0; 187 // TODO: Remove. Legacy name used by Chrome. getSampleCount(int requestedCount,GrPixelConfig config)188 int getSampleCount(int requestedCount, GrPixelConfig config) const { 189 return this->getRenderTargetSampleCount(requestedCount, config); 190 } 191 192 /** 193 * Backends may have restrictions on what types of surfaces support GrGpu::writePixels(). 194 * If this returns false then the caller should implement a fallback where a temporary texture 195 * is created, pixels are written to it, and then that is copied or drawn into the the surface. 196 */ 197 bool surfaceSupportsWritePixels(const GrSurface*) const; 198 199 /** 200 * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). 201 * If this returns false then the caller should implement a fallback where a temporary texture 202 * is created, the surface is drawn or copied into the temporary, and pixels are read from the 203 * temporary. 204 */ 205 virtual bool surfaceSupportsReadPixels(const GrSurface*) const = 0; 206 207 /** 208 * Given a dst pixel config and a src color type what color type must the caller coax the 209 * the data into in order to use GrGpu::writePixels(). 210 */ supportedWritePixelsColorType(GrPixelConfig config,GrColorType)211 virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config, 212 GrColorType /*srcColorType*/) const { 213 return GrPixelConfigToColorType(config); 214 } 215 216 /** 217 * Given a src pixel config and a dst color type what color type must the caller read to using 218 * GrGpu::readPixels() and then coax into dstColorType. 219 */ supportedReadPixelsColorType(GrPixelConfig config,GrColorType)220 virtual GrColorType supportedReadPixelsColorType(GrPixelConfig config, 221 GrColorType /*dstColorType*/) const { 222 return GrPixelConfigToColorType(config); 223 } 224 suppressPrints()225 bool suppressPrints() const { return fSuppressPrints; } 226 bufferMapThreshold()227 size_t bufferMapThreshold() const { 228 SkASSERT(fBufferMapThreshold >= 0); 229 return fBufferMapThreshold; 230 } 231 232 /** True in environments that will issue errors if memory uploaded to buffers 233 is not initialized (even if not read by draw calls). */ mustClearUploadedBufferData()234 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 235 236 /** Returns true if the given backend supports importing AHardwareBuffers via the 237 * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API 238 * level >= 26. 239 * */ supportsAHardwareBufferImages()240 bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; } 241 wireframeMode()242 bool wireframeMode() const { return fWireframeMode; } 243 fenceSyncSupport()244 bool fenceSyncSupport() const { return fFenceSyncSupport; } crossContextTextureSupport()245 bool crossContextTextureSupport() const { return fCrossContextTextureSupport; } 246 /** 247 * Returns whether or not we will be able to do a copy given the passed in params 248 */ 249 bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 250 const SkIRect& srcRect, const SkIPoint& dstPoint) const; 251 dynamicStateArrayGeometryProcessorTextureSupport()252 bool dynamicStateArrayGeometryProcessorTextureSupport() const { 253 return fDynamicStateArrayGeometryProcessorTextureSupport; 254 } 255 256 // Not all backends support clearing with a scissor test (e.g. Metal), this will always 257 // return true if performColorClearsAsDraws() returns true. performPartialClearsAsDraws()258 bool performPartialClearsAsDraws() const { 259 return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws; 260 } 261 262 // Many drivers have issues with color clears. performColorClearsAsDraws()263 bool performColorClearsAsDraws() const { 264 return fPerformColorClearsAsDraws; 265 } 266 267 /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit 268 /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil 269 /// op instead of using glClear seems to resolve the issue. performStencilClearsAsDraws()270 bool performStencilClearsAsDraws() const { 271 return fPerformStencilClearsAsDraws; 272 } 273 274 /** 275 * This is can be called before allocating a texture to be a dst for copySurface. This is only 276 * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It 277 * will populate config and flags fields of the desc such that copySurface can efficiently 278 * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation 279 * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if 280 * copy rect must equal src's bounds. 281 */ 282 virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, 283 GrSurfaceOrigin* origin, bool* rectsMustMatch, 284 bool* disallowSubrect) const = 0; 285 286 bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const; 287 288 /** 289 * If the GrBackendRenderTarget can be used with the supplied SkColorType the return will be 290 * the config that matches the backend format and requested SkColorType. Otherwise, kUnknown is 291 * returned. 292 */ 293 virtual GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&, 294 SkColorType) const = 0; 295 296 // TODO: replace validateBackendRenderTarget with calls to getConfigFromBackendFormat? 297 // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too 298 // Returns kUnknown if a valid config could not be determined. 299 virtual GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat& format, 300 SkColorType ct) const = 0; 301 302 /** 303 * Special method only for YUVA images. Returns a config that matches the backend format or 304 * kUnknown if a config could not be determined. 305 */ 306 virtual GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat& format) const = 0; 307 308 /** These are used when creating a new texture internally. */ 309 virtual GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct, 310 GrSRGBEncoded srgbEncoded) const = 0; 311 GrBackendFormat getBackendFormatFromColorType(SkColorType ct) const; 312 313 /** 314 * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and 315 * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support. 316 */ clampToBorderSupport()317 bool clampToBorderSupport() const { return fClampToBorderSupport; } 318 workarounds()319 const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; } 320 321 protected: 322 /** Subclasses must call this at the end of their constructors in order to apply caps 323 overrides requested by the client. Note that overrides will only reduce the caps never 324 expand them. */ 325 void applyOptionsOverrides(const GrContextOptions& options); 326 327 sk_sp<GrShaderCaps> fShaderCaps; 328 329 bool fNPOTTextureTileSupport : 1; 330 bool fMipMapSupport : 1; 331 bool fSRGBSupport : 1; 332 bool fSRGBWriteControl : 1; 333 bool fDiscardRenderTargetSupport : 1; 334 bool fReuseScratchTextures : 1; 335 bool fReuseScratchBuffers : 1; 336 bool fGpuTracingSupport : 1; 337 bool fCompressedTexSubImageSupport : 1; 338 bool fOversizedStencilSupport : 1; 339 bool fTextureBarrierSupport : 1; 340 bool fSampleLocationsSupport : 1; 341 bool fMultisampleDisableSupport : 1; 342 bool fInstanceAttribSupport : 1; 343 bool fUsesMixedSamples : 1; 344 bool fUsePrimitiveRestart : 1; 345 bool fPreferClientSideDynamicBuffers : 1; 346 bool fPreferFullscreenClears : 1; 347 bool fMustClearUploadedBufferData : 1; 348 bool fSupportsAHardwareBufferImages : 1; 349 bool fHalfFloatVertexAttributeSupport : 1; 350 bool fClampToBorderSupport : 1; 351 bool fPerformPartialClearsAsDraws : 1; 352 bool fPerformColorClearsAsDraws : 1; 353 bool fPerformStencilClearsAsDraws : 1; 354 355 // Driver workaround 356 bool fBlacklistCoverageCounting : 1; 357 bool fAvoidStencilBuffers : 1; 358 bool fAvoidWritePixelsFastPath : 1; 359 360 // ANGLE performance workaround 361 bool fPreferVRAMUseOverFlushes : 1; 362 363 // TODO: this may need to be an enum to support different fence types 364 bool fFenceSyncSupport : 1; 365 366 // Requires fence sync support in GL. 367 bool fCrossContextTextureSupport : 1; 368 369 // Not (yet) implemented in VK backend. 370 bool fDynamicStateArrayGeometryProcessorTextureSupport : 1; 371 372 BlendEquationSupport fBlendEquationSupport; 373 uint32_t fAdvBlendEqBlacklist; 374 GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); 375 376 uint32_t fMapBufferFlags; 377 int fBufferMapThreshold; 378 379 int fMaxRenderTargetSize; 380 int fMaxPreferredRenderTargetSize; 381 int fMaxVertexAttributes; 382 int fMaxTextureSize; 383 int fMaxTileSize; 384 int fMaxRasterSamples; 385 int fMaxWindowRectangles; 386 int fMaxClipAnalyticFPs; 387 388 GrDriverBugWorkarounds fDriverBugWorkarounds; 389 390 private: onApplyOptionsOverrides(const GrContextOptions &)391 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} onDumpJSON(SkJSONWriter *)392 virtual void onDumpJSON(SkJSONWriter*) const {} 393 virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0; 394 virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 395 const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0; 396 397 // Backends should implement this if they have any extra requirements for use of window 398 // rectangles for a specific GrBackendRenderTarget outside of basic support. onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget &)399 virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { 400 return true; 401 } 402 403 bool fSuppressPrints : 1; 404 bool fWireframeMode : 1; 405 406 typedef SkRefCnt INHERITED; 407 }; 408 409 #endif 410