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; }
66 
67     /**
68     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
69     * given shader type. If the shader type is not supported or the precision level is not
70     * supported in that shader type then the returned struct will report false when supported() is
71     * called.
72     */
getFloatShaderPrecisionInfo(GrShaderType shaderType,GrSLPrecision precision)73     const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
74                                                      GrSLPrecision precision) const {
75         return fFloatPrecisions[shaderType][precision];
76     };
77 
78     /**
79     * Is there any difference between the float shader variable precision types? If this is true
80     * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
81     * report the same info for all precisions in all shader types.
82     */
floatPrecisionVaries()83     bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
84 
85     /**
86      * PLS storage size in bytes (0 when not supported). The PLS spec defines a minimum size of 16
87      * bytes whenever PLS is supported.
88      */
pixelLocalStorageSize()89     int pixelLocalStorageSize() const { return fPixelLocalStorageSize; }
90 
91     /**
92      * True if this context supports the necessary extensions and features to enable the PLS path
93      * renderer.
94      */
plsPathRenderingSupport()95     bool plsPathRenderingSupport() const {
96 #if GR_ENABLE_PLS_PATH_RENDERING
97         return fPLSPathRenderingSupport;
98 #else
99         return false;
100 #endif
101     }
102 
103 protected:
104     /** Subclasses must call this after initialization in order to apply caps overrides requested by
105         the client. Note that overrides will only reduce the caps never expand them. */
106     void applyOptionsOverrides(const GrContextOptions& options);
107 
108     bool fShaderDerivativeSupport : 1;
109     bool fGeometryShaderSupport : 1;
110     bool fPathRenderingSupport : 1;
111     bool fDstReadInShaderSupport : 1;
112     bool fDualSourceBlendingSupport : 1;
113     bool fIntegerSupport : 1;
114 
115     bool fShaderPrecisionVaries;
116     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
117     int fPixelLocalStorageSize;
118     bool fPLSPathRenderingSupport;
119 
120 private:
onApplyOptionsOverrides(const GrContextOptions &)121     virtual void onApplyOptionsOverrides(const GrContextOptions&) {};
122     typedef SkRefCnt INHERITED;
123 };
124 
125 /**
126  * Represents the capabilities of a GrContext.
127  */
128 class GrCaps : public SkRefCnt {
129 public:
130     GrCaps(const GrContextOptions&);
131 
132     virtual SkString dump() const;
133 
shaderCaps()134     GrShaderCaps* shaderCaps() const { return fShaderCaps; }
135 
npotTextureTileSupport()136     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
137     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
138         only for POT textures) */
mipMapSupport()139     bool mipMapSupport() const { return fMipMapSupport; }
twoSidedStencilSupport()140     bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
stencilWrapOpsSupport()141     bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
discardRenderTargetSupport()142     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
gpuTracingSupport()143     bool gpuTracingSupport() const { return fGpuTracingSupport; }
compressedTexSubImageSupport()144     bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
oversizedStencilSupport()145     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
textureBarrierSupport()146     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
usesMixedSamples()147     bool usesMixedSamples() const { return fUsesMixedSamples; }
148 
useDrawInsteadOfClear()149     bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
useDrawInsteadOfPartialRenderTargetWrite()150     bool useDrawInsteadOfPartialRenderTargetWrite() const {
151         return fUseDrawInsteadOfPartialRenderTargetWrite;
152     }
153 
useDrawInsteadOfAllRenderTargetWrites()154     bool useDrawInsteadOfAllRenderTargetWrites() const {
155         return fUseDrawInsteadOfAllRenderTargetWrites;
156     }
157 
preferVRAMUseOverFlushes()158     bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
159 
160     /**
161      * Indicates the capabilities of the fixed function blend unit.
162      */
163     enum BlendEquationSupport {
164         kBasic_BlendEquationSupport,             //<! Support to select the operator that
165                                                  //   combines src and dst terms.
166         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
167                                                  //   SVG/PDF blend modes. Requires blend barriers.
168         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
169                                                  //   require blend barriers, and permits overlap.
170 
171         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
172     };
173 
blendEquationSupport()174     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
175 
advancedBlendEquationSupport()176     bool advancedBlendEquationSupport() const {
177         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
178     }
179 
advancedCoherentBlendEquationSupport()180     bool advancedCoherentBlendEquationSupport() const {
181         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
182     }
183 
canUseAdvancedBlendEquation(GrBlendEquation equation)184     bool canUseAdvancedBlendEquation(GrBlendEquation equation) const {
185         SkASSERT(GrBlendEquationIsAdvanced(equation));
186         return SkToBool(fAdvBlendEqBlacklist & (1 << equation));
187     }
188 
189     /**
190      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
191      * textures allows partial mappings or full mappings.
192      */
193     enum MapFlags {
194         kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
195 
196         kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
197                                       //   the other flags to have meaning.k
198         kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
199     };
200 
mapBufferFlags()201     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
202 
203     // Scratch textures not being reused means that those scratch textures
204     // that we upload to (i.e., don't have a render target) will not be
205     // recycled in the texture cache. This is to prevent ghosting by drivers
206     // (in particular for deferred architectures).
reuseScratchTextures()207     bool reuseScratchTextures() const { return fReuseScratchTextures; }
reuseScratchBuffers()208     bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
209 
maxRenderTargetSize()210     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
maxTextureSize()211     int maxTextureSize() const { return fMaxTextureSize; }
212     /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
213         It is usually the max texture size, unless we're overriding it for testing. */
maxTileSize()214     int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; }
215 
216     // Will be 0 if MSAA is not supported
maxColorSampleCount()217     int maxColorSampleCount() const { return fMaxColorSampleCount; }
218     // Will be 0 if MSAA is not supported
maxStencilSampleCount()219     int maxStencilSampleCount() const { return fMaxStencilSampleCount; }
220     // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode
221     // where the rasterizer runs with more samples than are in the target framebuffer.
maxRasterSamples()222     int maxRasterSamples() const { return fMaxRasterSamples; }
223     // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount.
224     // If we are using mixed samples, we only care about stencil.
maxSampleCount()225     int maxSampleCount() const {
226         if (this->usesMixedSamples()) {
227             return this->maxStencilSampleCount();
228         } else {
229             return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount());
230         }
231     }
232 
233 
234     virtual bool isConfigTexturable(GrPixelConfig config) const = 0;
235     virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
236 
suppressPrints()237     bool suppressPrints() const { return fSuppressPrints; }
238 
immediateFlush()239     bool immediateFlush() const { return fImmediateFlush; }
240 
drawPathMasksToCompressedTexturesSupport()241     bool drawPathMasksToCompressedTexturesSupport() const {
242         return fDrawPathMasksToCompressedTextureSupport;
243     }
244 
geometryBufferMapThreshold()245     size_t geometryBufferMapThreshold() const {
246         SkASSERT(fGeometryBufferMapThreshold >= 0);
247         return fGeometryBufferMapThreshold;
248     }
249 
supportsInstancedDraws()250     bool supportsInstancedDraws() const {
251         return fSupportsInstancedDraws;
252     }
253 
fullClearIsFree()254     bool fullClearIsFree() const { return fFullClearIsFree; }
255 
256     /** True in environments that will issue errors if memory uploaded to buffers
257         is not initialized (even if not read by draw calls). */
mustClearUploadedBufferData()258     bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
259 
260 protected:
261     /** Subclasses must call this at the end of their constructors in order to apply caps
262         overrides requested by the client. Note that overrides will only reduce the caps never
263         expand them. */
264     void applyOptionsOverrides(const GrContextOptions& options);
265 
266     SkAutoTUnref<GrShaderCaps>    fShaderCaps;
267 
268     bool fNPOTTextureTileSupport                     : 1;
269     bool fMipMapSupport                              : 1;
270     bool fTwoSidedStencilSupport                     : 1;
271     bool fStencilWrapOpsSupport                      : 1;
272     bool fDiscardRenderTargetSupport                 : 1;
273     bool fReuseScratchTextures                       : 1;
274     bool fReuseScratchBuffers                        : 1;
275     bool fGpuTracingSupport                          : 1;
276     bool fCompressedTexSubImageSupport               : 1;
277     bool fOversizedStencilSupport                    : 1;
278     bool fTextureBarrierSupport                      : 1;
279     bool fUsesMixedSamples                           : 1;
280     bool fSupportsInstancedDraws                     : 1;
281     bool fFullClearIsFree                            : 1;
282     bool fMustClearUploadedBufferData                : 1;
283 
284     // Driver workaround
285     bool fUseDrawInsteadOfClear                      : 1;
286     bool fUseDrawInsteadOfPartialRenderTargetWrite   : 1;
287     bool fUseDrawInsteadOfAllRenderTargetWrites      : 1;
288 
289     // ANGLE workaround
290     bool fPreferVRAMUseOverFlushes                   : 1;
291 
292     BlendEquationSupport fBlendEquationSupport;
293     uint32_t fAdvBlendEqBlacklist;
294     GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
295 
296     uint32_t fMapBufferFlags;
297     int fGeometryBufferMapThreshold;
298 
299     int fMaxRenderTargetSize;
300     int fMaxTextureSize;
301     int fMaxTileSize;
302     int fMaxColorSampleCount;
303     int fMaxStencilSampleCount;
304     int fMaxRasterSamples;
305 
306 private:
onApplyOptionsOverrides(const GrContextOptions &)307     virtual void onApplyOptionsOverrides(const GrContextOptions&) {};
308 
309     bool fSuppressPrints : 1;
310     bool fImmediateFlush: 1;
311     bool fDrawPathMasksToCompressedTextureSupport : 1;
312 
313     typedef SkRefCnt INHERITED;
314 };
315 
316 #endif
317