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 "GrShaderCaps.h" 14 #include "SkImageInfo.h" 15 #include "SkRefCnt.h" 16 #include "SkString.h" 17 18 class GrBackendFormat; 19 class GrBackendRenderTarget; 20 class GrBackendTexture; 21 struct GrContextOptions; 22 class GrRenderTargetProxy; 23 class GrSurface; 24 class SkJSONWriter; 25 26 /** 27 * Represents the capabilities of a GrContext. 28 */ 29 class GrCaps : public SkRefCnt { 30 public: 31 GrCaps(const GrContextOptions&); 32 33 void dumpJSON(SkJSONWriter*) const; 34 shaderCaps()35 const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } 36 npotTextureTileSupport()37 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 38 /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. 39 only for POT textures) */ mipMapSupport()40 bool mipMapSupport() const { return fMipMapSupport; } 41 42 /** 43 * Skia convention is that a device only has sRGB support if it supports sRGB formats for both 44 * textures and framebuffers. In addition: 45 * Decoding to linear of an sRGB texture can be disabled. 46 */ srgbSupport()47 bool srgbSupport() const { return fSRGBSupport; } 48 /** 49 * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? 50 */ srgbWriteControl()51 bool srgbWriteControl() const { return fSRGBWriteControl; } srgbDecodeDisableSupport()52 bool srgbDecodeDisableSupport() const { return fSRGBDecodeDisableSupport; } discardRenderTargetSupport()53 bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } gpuTracingSupport()54 bool gpuTracingSupport() const { return fGpuTracingSupport; } oversizedStencilSupport()55 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } textureBarrierSupport()56 bool textureBarrierSupport() const { return fTextureBarrierSupport; } sampleLocationsSupport()57 bool sampleLocationsSupport() const { return fSampleLocationsSupport; } multisampleDisableSupport()58 bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } instanceAttribSupport()59 bool instanceAttribSupport() const { return fInstanceAttribSupport; } usesMixedSamples()60 bool usesMixedSamples() const { return fUsesMixedSamples; } 61 62 // Returns whether mixed samples is supported for the given backend render target. isMixedSamplesSupportedForRT(const GrBackendRenderTarget & rt)63 bool isMixedSamplesSupportedForRT(const GrBackendRenderTarget& rt) const { 64 return this->usesMixedSamples() && this->onIsMixedSamplesSupportedForRT(rt); 65 } 66 67 // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some 68 // systems. This cap is only set if primitive restart will improve performance. usePrimitiveRestart()69 bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } 70 preferClientSideDynamicBuffers()71 bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } 72 73 // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to 74 // initialize each tile with a constant value rather than loading each pixel from memory. preferFullscreenClears()75 bool preferFullscreenClears() const { return fPreferFullscreenClears; } 76 preferVRAMUseOverFlushes()77 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 78 blacklistCoverageCounting()79 bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; } 80 avoidStencilBuffers()81 bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } 82 83 /** 84 * Indicates the capabilities of the fixed function blend unit. 85 */ 86 enum BlendEquationSupport { 87 kBasic_BlendEquationSupport, //<! Support to select the operator that 88 // combines src and dst terms. 89 kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific 90 // SVG/PDF blend modes. Requires blend barriers. 91 kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not 92 // require blend barriers, and permits overlap. 93 94 kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport 95 }; 96 blendEquationSupport()97 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 98 advancedBlendEquationSupport()99 bool advancedBlendEquationSupport() const { 100 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 101 } 102 advancedCoherentBlendEquationSupport()103 bool advancedCoherentBlendEquationSupport() const { 104 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 105 } 106 canUseAdvancedBlendEquation(GrBlendEquation equation)107 bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { 108 SkASSERT(GrBlendEquationIsAdvanced(equation)); 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 { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; } 147 maxRasterSamples()148 int maxRasterSamples() const { return fMaxRasterSamples; } 149 maxWindowRectangles()150 int maxWindowRectangles() const { return fMaxWindowRectangles; } 151 152 // Returns whether mixed samples is supported for the given backend render target. isWindowRectanglesSupportedForRT(const GrBackendRenderTarget & rt)153 bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { 154 return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); 155 } 156 157 // A tuned, platform-specific value for the maximum number of analytic fragment processors we 158 // should use to implement a clip, before falling back on a mask. maxClipAnalyticFPs()159 int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; } 160 161 virtual bool isConfigTexturable(GrPixelConfig) const = 0; 162 163 // Returns whether a texture of the given config can be copied to a texture of the same config. 164 virtual bool isConfigCopyable(GrPixelConfig) const = 0; 165 166 // Returns the maximum supported sample count for a config. 0 means the config is not renderable 167 // 1 means the config is renderable but doesn't support MSAA. 168 virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0; 169 isConfigRenderable(GrPixelConfig config)170 bool isConfigRenderable(GrPixelConfig config) const { 171 return this->maxRenderTargetSampleCount(config) > 0; 172 } 173 174 // TODO: Remove this after Flutter updated to no longer use it. isConfigRenderable(GrPixelConfig config,bool withMSAA)175 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 176 return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0); 177 } 178 179 // Find a sample count greater than or equal to the requested count which is supported for a 180 // color buffer of the given config or 0 if no such sample count is supported. If the requested 181 // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. 182 // For historical reasons requestedCount==0 is handled identically to requestedCount==1. 183 virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0; 184 // TODO: Remove. Legacy name used by Chrome. getSampleCount(int requestedCount,GrPixelConfig config)185 int getSampleCount(int requestedCount, GrPixelConfig config) const { 186 return this->getRenderTargetSampleCount(requestedCount, config); 187 } 188 189 /** 190 * Backends may have restrictions on what types of surfaces support GrGpu::writePixels(). 191 * If this returns false then the caller should implement a fallback where a temporary texture 192 * is created, pixels are written to it, and then that is copied or drawn into the the surface. 193 */ 194 virtual bool surfaceSupportsWritePixels(const GrSurface* surface) const = 0; 195 196 /** 197 * Given a dst pixel config and a src color type what color type must the caller coax the 198 * the data into in order to use GrGpu::writePixels(). 199 */ supportedWritePixelsColorType(GrPixelConfig config,GrColorType)200 virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config, 201 GrColorType /*srcColorType*/) const { 202 return GrPixelConfigToColorType(config); 203 } 204 suppressPrints()205 bool suppressPrints() const { return fSuppressPrints; } 206 bufferMapThreshold()207 size_t bufferMapThreshold() const { 208 SkASSERT(fBufferMapThreshold >= 0); 209 return fBufferMapThreshold; 210 } 211 212 /** True in environments that will issue errors if memory uploaded to buffers 213 is not initialized (even if not read by draw calls). */ mustClearUploadedBufferData()214 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 215 wireframeMode()216 bool wireframeMode() const { return fWireframeMode; } 217 sampleShadingSupport()218 bool sampleShadingSupport() const { return fSampleShadingSupport; } 219 fenceSyncSupport()220 bool fenceSyncSupport() const { return fFenceSyncSupport; } crossContextTextureSupport()221 bool crossContextTextureSupport() const { return fCrossContextTextureSupport; } 222 223 /** 224 * This is can be called before allocating a texture to be a dst for copySurface. This is only 225 * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It 226 * will populate the origin, config, and flags fields of the desc such that copySurface can 227 * efficiently succeed. rectsMustMatch will be set to true if the copy operation must ensure 228 * that the src and dest rects are identical. disallowSubrect will be set to true if copy rect 229 * must equal src's bounds. 230 */ 231 virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, 232 bool* rectsMustMatch, bool* disallowSubrect) const = 0; 233 234 bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const; 235 236 /** 237 * Returns true if the GrBackendTexture can be used with the supplied SkColorType. If it is 238 * compatible, the passed in GrPixelConfig will be set to a config that matches the backend 239 * format and requested SkColorType. 240 */ 241 virtual bool validateBackendTexture(const GrBackendTexture& tex, SkColorType ct, 242 GrPixelConfig*) const = 0; 243 virtual bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, 244 GrPixelConfig*) const = 0; 245 246 // TODO: replace validateBackendTexture and validateBackendRenderTarget with calls to 247 // getConfigFromBackendFormat? 248 // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too 249 virtual bool getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, 250 GrPixelConfig*) const = 0; 251 252 protected: 253 /** Subclasses must call this at the end of their constructors in order to apply caps 254 overrides requested by the client. Note that overrides will only reduce the caps never 255 expand them. */ 256 void applyOptionsOverrides(const GrContextOptions& options); 257 258 sk_sp<GrShaderCaps> fShaderCaps; 259 260 bool fNPOTTextureTileSupport : 1; 261 bool fMipMapSupport : 1; 262 bool fSRGBSupport : 1; 263 bool fSRGBWriteControl : 1; 264 bool fSRGBDecodeDisableSupport : 1; 265 bool fDiscardRenderTargetSupport : 1; 266 bool fReuseScratchTextures : 1; 267 bool fReuseScratchBuffers : 1; 268 bool fGpuTracingSupport : 1; 269 bool fOversizedStencilSupport : 1; 270 bool fTextureBarrierSupport : 1; 271 bool fSampleLocationsSupport : 1; 272 bool fMultisampleDisableSupport : 1; 273 bool fInstanceAttribSupport : 1; 274 bool fUsesMixedSamples : 1; 275 bool fUsePrimitiveRestart : 1; 276 bool fPreferClientSideDynamicBuffers : 1; 277 bool fPreferFullscreenClears : 1; 278 bool fMustClearUploadedBufferData : 1; 279 280 // Driver workaround 281 bool fBlacklistCoverageCounting : 1; 282 bool fAvoidStencilBuffers : 1; 283 284 // ANGLE performance workaround 285 bool fPreferVRAMUseOverFlushes : 1; 286 287 bool fSampleShadingSupport : 1; 288 // TODO: this may need to be an enum to support different fence types 289 bool fFenceSyncSupport : 1; 290 291 // Vulkan doesn't support this (yet) and some drivers have issues, too 292 bool fCrossContextTextureSupport : 1; 293 294 BlendEquationSupport fBlendEquationSupport; 295 uint32_t fAdvBlendEqBlacklist; 296 GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); 297 298 uint32_t fMapBufferFlags; 299 int fBufferMapThreshold; 300 301 int fMaxRenderTargetSize; 302 int fMaxPreferredRenderTargetSize; 303 int fMaxVertexAttributes; 304 int fMaxTextureSize; 305 int fMaxTileSize; 306 int fMaxRasterSamples; 307 int fMaxWindowRectangles; 308 int fMaxClipAnalyticFPs; 309 310 private: onApplyOptionsOverrides(const GrContextOptions &)311 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} onDumpJSON(SkJSONWriter *)312 virtual void onDumpJSON(SkJSONWriter*) const {} 313 314 // Backends should implement this if they have any extra requirements for use of mixed 315 // samples for a specific GrBackendRenderTarget outside of basic support. onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget &)316 virtual bool onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget&) const { 317 return true; 318 } 319 // Backends should implement this if they have any extra requirements for use of window 320 // rectangles for a specific GrBackendRenderTarget outside of basic support. onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget &)321 virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { 322 return true; 323 } 324 325 bool fSuppressPrints : 1; 326 bool fWireframeMode : 1; 327 328 typedef SkRefCnt INHERITED; 329 }; 330 331 #endif 332