• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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