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 "GrTypes.h"
12 #include "GrTypesPriv.h"
13 #include "GrBlend.h"
14 #include "GrShaderVar.h"
15 #include "SkRefCnt.h"
16 #include "SkString.h"
17 
18 struct GrContextOptions;
19 
20 class GrShaderCaps : public SkRefCnt {
21 public:
22     /** Info about shader variable precision within a given shader stage. That is, this info
23         is relevant to a float (or vecNf) variable declared with a GrSLPrecision
24         in a given GrShaderType. The info here is hoisted from the OpenGL spec. */
25     struct PrecisionInfo {
PrecisionInfoPrecisionInfo26         PrecisionInfo() {
27             fLogRangeLow = 0;
28             fLogRangeHigh = 0;
29             fBits = 0;
30         }
31 
32         /** Is this precision level allowed in the shader stage? */
supportedPrecisionInfo33         bool supported() const { return 0 != fBits; }
34 
35         bool operator==(const PrecisionInfo& that) const {
36             return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh &&
37                    fBits == that.fBits;
38         }
39         bool operator!=(const PrecisionInfo& that) const { return !(*this == that); }
40 
41         /** floor(log2(|min_value|)) */
42         int fLogRangeLow;
43         /** floor(log2(|max_value|)) */
44         int fLogRangeHigh;
45         /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this
46             struct) :
47             """
48             If the smallest representable value greater than 1 is 1 + e, then fBits will
49             contain floor(log2(e)), and every value in the range [2^fLogRangeLow,
50             2^fLogRangeHigh] can be represented to at least one part in 2^fBits.
51             """
52           */
53         int fBits;
54     };
55 
56     GrShaderCaps();
57 
58     virtual SkString dump() const;
59 
shaderDerivativeSupport()60     bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
geometryShaderSupport()61     bool geometryShaderSupport() const { return fGeometryShaderSupport; }
pathRenderingSupport()62     bool pathRenderingSupport() const { return fPathRenderingSupport; }
dstReadInShaderSupport()63     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
dualSourceBlendingSupport()64     bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
integerSupport()65     bool integerSupport() const { return fIntegerSupport; }
texelBufferSupport()66     bool texelBufferSupport() const { return fTexelBufferSupport; }
67 
68     /**
69     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
70     * given shader type. If the shader type is not supported or the precision level is not
71     * supported in that shader type then the returned struct will report false when supported() is
72     * called.
73     */
getFloatShaderPrecisionInfo(GrShaderType shaderType,GrSLPrecision precision)74     const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
75                                                      GrSLPrecision precision) const {
76         return fFloatPrecisions[shaderType][precision];
77     }
78 
79     /**
80     * Is there any difference between the float shader variable precision types? If this is true
81     * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
82     * report the same info for all precisions in all shader types.
83     */
floatPrecisionVaries()84     bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
85 
86     /**
87      * PLS storage size in bytes (0 when not supported). The PLS spec defines a minimum size of 16
88      * bytes whenever PLS is supported.
89      */
pixelLocalStorageSize()90     int pixelLocalStorageSize() const { return fPixelLocalStorageSize; }
91 
92     /**
93      * True if this context supports the necessary extensions and features to enable the PLS path
94      * renderer.
95      */
plsPathRenderingSupport()96     bool plsPathRenderingSupport() const {
97 #if GR_ENABLE_PLS_PATH_RENDERING
98         return fPLSPathRenderingSupport;
99 #else
100         return false;
101 #endif
102     }
103 
104 protected:
105     /** Subclasses must call this after initialization in order to apply caps overrides requested by
106         the client. Note that overrides will only reduce the caps never expand them. */
107     void applyOptionsOverrides(const GrContextOptions& options);
108 
109     bool fShaderDerivativeSupport : 1;
110     bool fGeometryShaderSupport : 1;
111     bool fPathRenderingSupport : 1;
112     bool fDstReadInShaderSupport : 1;
113     bool fDualSourceBlendingSupport : 1;
114     bool fIntegerSupport : 1;
115     bool fTexelBufferSupport : 1;
116 
117     bool fShaderPrecisionVaries;
118     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
119     int fPixelLocalStorageSize;
120     bool fPLSPathRenderingSupport;
121 
122 private:
onApplyOptionsOverrides(const GrContextOptions &)123     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
124     typedef SkRefCnt INHERITED;
125 };
126 
127 /**
128  * Represents the capabilities of a GrContext.
129  */
130 class GrCaps : public SkRefCnt {
131 public:
132     GrCaps(const GrContextOptions&);
133 
134     virtual SkString dump() const;
135 
shaderCaps()136     GrShaderCaps* shaderCaps() const { return fShaderCaps; }
137 
npotTextureTileSupport()138     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
139     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
140         only for POT textures) */
mipMapSupport()141     bool mipMapSupport() const { return fMipMapSupport; }
142 
143     /**
144      * Skia convention is that a device only has sRGB support if it supports sRGB formats for both
145      * textures and framebuffers. In addition:
146      *   Decoding to linear of an sRGB texture can be disabled.
147      */
srgbSupport()148     bool srgbSupport() const { return fSRGBSupport; }
149     /**
150      * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers?
151      */
srgbWriteControl()152     bool srgbWriteControl() const { return fSRGBWriteControl; }
twoSidedStencilSupport()153     bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
stencilWrapOpsSupport()154     bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
discardRenderTargetSupport()155     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
gpuTracingSupport()156     bool gpuTracingSupport() const { return fGpuTracingSupport; }
compressedTexSubImageSupport()157     bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
oversizedStencilSupport()158     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
textureBarrierSupport()159     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
sampleLocationsSupport()160     bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
multisampleDisableSupport()161     bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
usesMixedSamples()162     bool usesMixedSamples() const { return fUsesMixedSamples; }
preferClientSideDynamicBuffers()163     bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
164 
useDrawInsteadOfClear()165     bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
useDrawInsteadOfPartialRenderTargetWrite()166     bool useDrawInsteadOfPartialRenderTargetWrite() const {
167         return fUseDrawInsteadOfPartialRenderTargetWrite;
168     }
169 
useDrawInsteadOfAllRenderTargetWrites()170     bool useDrawInsteadOfAllRenderTargetWrites() const {
171         return fUseDrawInsteadOfAllRenderTargetWrites;
172     }
173 
preferVRAMUseOverFlushes()174     bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
175 
176     /**
177      * Indicates the level of support for gr_instanced::* functionality. A higher level includes
178      * all functionality from the levels below it.
179      */
180     enum class InstancedSupport {
181         kNone,
182         kBasic,
183         kMultisampled,
184         kMixedSampled
185     };
186 
instancedSupport()187     InstancedSupport instancedSupport() const { return fInstancedSupport; }
188 
avoidInstancedDrawsToFPTargets()189     bool avoidInstancedDrawsToFPTargets() const { return fAvoidInstancedDrawsToFPTargets; }
190 
191     /**
192      * Indicates the capabilities of the fixed function blend unit.
193      */
194     enum BlendEquationSupport {
195         kBasic_BlendEquationSupport,             //<! Support to select the operator that
196                                                  //   combines src and dst terms.
197         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
198                                                  //   SVG/PDF blend modes. Requires blend barriers.
199         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
200                                                  //   require blend barriers, and permits overlap.
201 
202         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
203     };
204 
blendEquationSupport()205     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
206 
advancedBlendEquationSupport()207     bool advancedBlendEquationSupport() const {
208         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
209     }
210 
advancedCoherentBlendEquationSupport()211     bool advancedCoherentBlendEquationSupport() const {
212         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
213     }
214 
canUseAdvancedBlendEquation(GrBlendEquation equation)215     bool canUseAdvancedBlendEquation(GrBlendEquation equation) const {
216         SkASSERT(GrBlendEquationIsAdvanced(equation));
217         return SkToBool(fAdvBlendEqBlacklist & (1 << equation));
218     }
219 
220     /**
221      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
222      * textures allows partial mappings or full mappings.
223      */
224     enum MapFlags {
225         kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
226 
227         kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
228                                       //   the other flags to have meaning.k
229         kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
230     };
231 
mapBufferFlags()232     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
233 
234     // Scratch textures not being reused means that those scratch textures
235     // that we upload to (i.e., don't have a render target) will not be
236     // recycled in the texture cache. This is to prevent ghosting by drivers
237     // (in particular for deferred architectures).
reuseScratchTextures()238     bool reuseScratchTextures() const { return fReuseScratchTextures; }
reuseScratchBuffers()239     bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
240 
241     /// maximum number of attribute values per vertex
maxVertexAttributes()242     int maxVertexAttributes() const { return fMaxVertexAttributes; }
243 
maxRenderTargetSize()244     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
maxTextureSize()245     int maxTextureSize() const { return fMaxTextureSize; }
246     /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
247         It is usually the max texture size, unless we're overriding it for testing. */
maxTileSize()248     int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; }
249 
250     // Will be 0 if MSAA is not supported
maxColorSampleCount()251     int maxColorSampleCount() const { return fMaxColorSampleCount; }
252     // Will be 0 if MSAA is not supported
maxStencilSampleCount()253     int maxStencilSampleCount() const { return fMaxStencilSampleCount; }
254     // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode
255     // where the rasterizer runs with more samples than are in the target framebuffer.
maxRasterSamples()256     int maxRasterSamples() const { return fMaxRasterSamples; }
257     // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount.
258     // If we are using mixed samples, we only care about stencil.
maxSampleCount()259     int maxSampleCount() const {
260         if (this->usesMixedSamples()) {
261             return this->maxStencilSampleCount();
262         } else {
263             return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount());
264         }
265     }
266 
maxWindowRectangles()267     int maxWindowRectangles() const { return fMaxWindowRectangles; }
268 
269     virtual bool isConfigTexturable(GrPixelConfig config) const = 0;
270     virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
271 
suppressPrints()272     bool suppressPrints() const { return fSuppressPrints; }
273 
immediateFlush()274     bool immediateFlush() const { return fImmediateFlush; }
275 
bufferMapThreshold()276     size_t bufferMapThreshold() const {
277         SkASSERT(fBufferMapThreshold >= 0);
278         return fBufferMapThreshold;
279     }
280 
fullClearIsFree()281     bool fullClearIsFree() const { return fFullClearIsFree; }
282 
283     /** True in environments that will issue errors if memory uploaded to buffers
284         is not initialized (even if not read by draw calls). */
mustClearUploadedBufferData()285     bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
286 
sampleShadingSupport()287     bool sampleShadingSupport() const { return fSampleShadingSupport; }
288 
fenceSyncSupport()289     bool fenceSyncSupport() const { return fFenceSyncSupport; }
290 
291 protected:
292     /** Subclasses must call this at the end of their constructors in order to apply caps
293         overrides requested by the client. Note that overrides will only reduce the caps never
294         expand them. */
295     void applyOptionsOverrides(const GrContextOptions& options);
296 
297     SkAutoTUnref<GrShaderCaps>    fShaderCaps;
298 
299     bool fNPOTTextureTileSupport                     : 1;
300     bool fMipMapSupport                              : 1;
301     bool fSRGBSupport                                : 1;
302     bool fSRGBWriteControl                           : 1;
303     bool fTwoSidedStencilSupport                     : 1;
304     bool fStencilWrapOpsSupport                      : 1;
305     bool fDiscardRenderTargetSupport                 : 1;
306     bool fReuseScratchTextures                       : 1;
307     bool fReuseScratchBuffers                        : 1;
308     bool fGpuTracingSupport                          : 1;
309     bool fCompressedTexSubImageSupport               : 1;
310     bool fOversizedStencilSupport                    : 1;
311     bool fTextureBarrierSupport                      : 1;
312     bool fSampleLocationsSupport                     : 1;
313     bool fMultisampleDisableSupport                  : 1;
314     bool fUsesMixedSamples                           : 1;
315     bool fPreferClientSideDynamicBuffers             : 1;
316     bool fFullClearIsFree                            : 1;
317     bool fMustClearUploadedBufferData                : 1;
318 
319     // Driver workaround
320     bool fUseDrawInsteadOfClear                      : 1;
321     bool fUseDrawInsteadOfPartialRenderTargetWrite   : 1;
322     bool fUseDrawInsteadOfAllRenderTargetWrites      : 1;
323     bool fAvoidInstancedDrawsToFPTargets             : 1;
324 
325     // ANGLE workaround
326     bool fPreferVRAMUseOverFlushes                   : 1;
327 
328     bool fSampleShadingSupport                       : 1;
329     // TODO: this may need to be an enum to support different fence types
330     bool fFenceSyncSupport                           : 1;
331 
332     InstancedSupport fInstancedSupport;
333 
334     BlendEquationSupport fBlendEquationSupport;
335     uint32_t fAdvBlendEqBlacklist;
336     GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
337 
338     uint32_t fMapBufferFlags;
339     int fBufferMapThreshold;
340 
341     int fMaxRenderTargetSize;
342     int fMaxVertexAttributes;
343     int fMaxTextureSize;
344     int fMaxTileSize;
345     int fMaxColorSampleCount;
346     int fMaxStencilSampleCount;
347     int fMaxRasterSamples;
348     int fMaxWindowRectangles;
349 
350 private:
onApplyOptionsOverrides(const GrContextOptions &)351     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
352 
353     bool fSuppressPrints : 1;
354     bool fImmediateFlush: 1;
355 
356     typedef SkRefCnt INHERITED;
357 };
358 
359 #endif
360