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 "GrShaderCaps.h"
16 #include "SkRefCnt.h"
17 #include "SkString.h"
18 
19 struct GrContextOptions;
20 class GrRenderTarget;
21 
22 /**
23  * Represents the capabilities of a GrContext.
24  */
25 class GrCaps : public SkRefCnt {
26 public:
27     GrCaps(const GrContextOptions&);
28 
29     virtual SkString dump() const;
30 
shaderCaps()31     const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
32 
npotTextureTileSupport()33     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
34     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
35         only for POT textures) */
mipMapSupport()36     bool mipMapSupport() const { return fMipMapSupport; }
37 
38     /**
39      * Skia convention is that a device only has sRGB support if it supports sRGB formats for both
40      * textures and framebuffers. In addition:
41      *   Decoding to linear of an sRGB texture can be disabled.
42      */
srgbSupport()43     bool srgbSupport() const { return fSRGBSupport; }
44     /**
45      * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers?
46      */
srgbWriteControl()47     bool srgbWriteControl() const { return fSRGBWriteControl; }
twoSidedStencilSupport()48     bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
stencilWrapOpsSupport()49     bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
discardRenderTargetSupport()50     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
gpuTracingSupport()51     bool gpuTracingSupport() const { return fGpuTracingSupport; }
compressedTexSubImageSupport()52     bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
oversizedStencilSupport()53     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
textureBarrierSupport()54     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
sampleLocationsSupport()55     bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
multisampleDisableSupport()56     bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
usesMixedSamples()57     bool usesMixedSamples() const { return fUsesMixedSamples; }
preferClientSideDynamicBuffers()58     bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
59 
useDrawInsteadOfClear()60     bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
useDrawInsteadOfPartialRenderTargetWrite()61     bool useDrawInsteadOfPartialRenderTargetWrite() const {
62         return fUseDrawInsteadOfPartialRenderTargetWrite;
63     }
64 
useDrawInsteadOfAllRenderTargetWrites()65     bool useDrawInsteadOfAllRenderTargetWrites() const {
66         return fUseDrawInsteadOfAllRenderTargetWrites;
67     }
68 
preferVRAMUseOverFlushes()69     bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
70 
71     /**
72      * Indicates the level of support for gr_instanced::* functionality. A higher level includes
73      * all functionality from the levels below it.
74      */
75     enum class InstancedSupport {
76         kNone,
77         kBasic,
78         kMultisampled,
79         kMixedSampled
80     };
81 
instancedSupport()82     InstancedSupport instancedSupport() const { return fInstancedSupport; }
83 
avoidInstancedDrawsToFPTargets()84     bool avoidInstancedDrawsToFPTargets() const { return fAvoidInstancedDrawsToFPTargets; }
85 
86     /**
87      * Indicates the capabilities of the fixed function blend unit.
88      */
89     enum BlendEquationSupport {
90         kBasic_BlendEquationSupport,             //<! Support to select the operator that
91                                                  //   combines src and dst terms.
92         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
93                                                  //   SVG/PDF blend modes. Requires blend barriers.
94         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
95                                                  //   require blend barriers, and permits overlap.
96 
97         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
98     };
99 
blendEquationSupport()100     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
101 
advancedBlendEquationSupport()102     bool advancedBlendEquationSupport() const {
103         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
104     }
105 
advancedCoherentBlendEquationSupport()106     bool advancedCoherentBlendEquationSupport() const {
107         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
108     }
109 
canUseAdvancedBlendEquation(GrBlendEquation equation)110     bool canUseAdvancedBlendEquation(GrBlendEquation equation) const {
111         SkASSERT(GrBlendEquationIsAdvanced(equation));
112         return SkToBool(fAdvBlendEqBlacklist & (1 << equation));
113     }
114 
115     /**
116      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
117      * textures allows partial mappings or full mappings.
118      */
119     enum MapFlags {
120         kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
121 
122         kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
123                                       //   the other flags to have meaning.k
124         kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
125     };
126 
mapBufferFlags()127     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
128 
129     // Scratch textures not being reused means that those scratch textures
130     // that we upload to (i.e., don't have a render target) will not be
131     // recycled in the texture cache. This is to prevent ghosting by drivers
132     // (in particular for deferred architectures).
reuseScratchTextures()133     bool reuseScratchTextures() const { return fReuseScratchTextures; }
reuseScratchBuffers()134     bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
135 
136     /// maximum number of attribute values per vertex
maxVertexAttributes()137     int maxVertexAttributes() const { return fMaxVertexAttributes; }
138 
maxRenderTargetSize()139     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
maxTextureSize()140     int maxTextureSize() const { return fMaxTextureSize; }
141     /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps.
142         It is usually the max texture size, unless we're overriding it for testing. */
maxTileSize()143     int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; }
144 
145     // Will be 0 if MSAA is not supported
maxColorSampleCount()146     int maxColorSampleCount() const { return fMaxColorSampleCount; }
147     // Will be 0 if MSAA is not supported
maxStencilSampleCount()148     int maxStencilSampleCount() const { return fMaxStencilSampleCount; }
149     // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode
150     // where the rasterizer runs with more samples than are in the target framebuffer.
maxRasterSamples()151     int maxRasterSamples() const { return fMaxRasterSamples; }
152     // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount.
153     // If we are using mixed samples, we only care about stencil.
maxSampleCount()154     int maxSampleCount() const {
155         if (this->usesMixedSamples()) {
156             return this->maxStencilSampleCount();
157         } else {
158             return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount());
159         }
160     }
161 
maxWindowRectangles()162     int maxWindowRectangles() const { return fMaxWindowRectangles; }
163 
164     virtual bool isConfigTexturable(GrPixelConfig config) const = 0;
165     virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
166     virtual bool canConfigBeImageStorage(GrPixelConfig config) const = 0;
167 
suppressPrints()168     bool suppressPrints() const { return fSuppressPrints; }
169 
immediateFlush()170     bool immediateFlush() const { return fImmediateFlush; }
171 
bufferMapThreshold()172     size_t bufferMapThreshold() const {
173         SkASSERT(fBufferMapThreshold >= 0);
174         return fBufferMapThreshold;
175     }
176 
fullClearIsFree()177     bool fullClearIsFree() const { return fFullClearIsFree; }
178 
179     /** True in environments that will issue errors if memory uploaded to buffers
180         is not initialized (even if not read by draw calls). */
mustClearUploadedBufferData()181     bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
182 
sampleShadingSupport()183     bool sampleShadingSupport() const { return fSampleShadingSupport; }
184 
fenceSyncSupport()185     bool fenceSyncSupport() const { return fFenceSyncSupport; }
crossContextTextureSupport()186     bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
187 
188     /**
189      * This is can be called before allocating a texture to be a dst for copySurface. This is only
190      * used for doing dst copies needed in blends, thus the src is always a GrRenderTarget. It will
191      * populate the origin, config, and flags fields of the desc such that copySurface can
192      * efficiently succeed.
193      */
194     virtual bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const = 0;
195 
196 protected:
197     /** Subclasses must call this at the end of their constructors in order to apply caps
198         overrides requested by the client. Note that overrides will only reduce the caps never
199         expand them. */
200     void applyOptionsOverrides(const GrContextOptions& options);
201 
202     sk_sp<GrShaderCaps> fShaderCaps;
203 
204     bool fNPOTTextureTileSupport                     : 1;
205     bool fMipMapSupport                              : 1;
206     bool fSRGBSupport                                : 1;
207     bool fSRGBWriteControl                           : 1;
208     bool fTwoSidedStencilSupport                     : 1;
209     bool fStencilWrapOpsSupport                      : 1;
210     bool fDiscardRenderTargetSupport                 : 1;
211     bool fReuseScratchTextures                       : 1;
212     bool fReuseScratchBuffers                        : 1;
213     bool fGpuTracingSupport                          : 1;
214     bool fCompressedTexSubImageSupport               : 1;
215     bool fOversizedStencilSupport                    : 1;
216     bool fTextureBarrierSupport                      : 1;
217     bool fSampleLocationsSupport                     : 1;
218     bool fMultisampleDisableSupport                  : 1;
219     bool fUsesMixedSamples                           : 1;
220     bool fPreferClientSideDynamicBuffers             : 1;
221     bool fFullClearIsFree                            : 1;
222     bool fMustClearUploadedBufferData                : 1;
223 
224     // Driver workaround
225     bool fUseDrawInsteadOfClear                      : 1;
226     bool fUseDrawInsteadOfPartialRenderTargetWrite   : 1;
227     bool fUseDrawInsteadOfAllRenderTargetWrites      : 1;
228     bool fAvoidInstancedDrawsToFPTargets             : 1;
229 
230     // ANGLE workaround
231     bool fPreferVRAMUseOverFlushes                   : 1;
232 
233     bool fSampleShadingSupport                       : 1;
234     // TODO: this may need to be an enum to support different fence types
235     bool fFenceSyncSupport                           : 1;
236 
237     // Vulkan doesn't support this (yet) and some drivers have issues, too
238     bool fCrossContextTextureSupport                 : 1;
239 
240     InstancedSupport fInstancedSupport;
241 
242     BlendEquationSupport fBlendEquationSupport;
243     uint32_t fAdvBlendEqBlacklist;
244     GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
245 
246     uint32_t fMapBufferFlags;
247     int fBufferMapThreshold;
248 
249     int fMaxRenderTargetSize;
250     int fMaxVertexAttributes;
251     int fMaxTextureSize;
252     int fMaxTileSize;
253     int fMaxColorSampleCount;
254     int fMaxStencilSampleCount;
255     int fMaxRasterSamples;
256     int fMaxWindowRectangles;
257 
258 private:
onApplyOptionsOverrides(const GrContextOptions &)259     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
260 
261     bool fSuppressPrints : 1;
262     bool fImmediateFlush: 1;
263 
264     typedef SkRefCnt INHERITED;
265 };
266 
267 #endif
268