1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #ifndef GrGLCaps_DEFINED
10 #define GrGLCaps_DEFINED
11 
12 #include <functional>
13 
14 #include "glsl/GrGLSL.h"
15 #include "GrCaps.h"
16 #include "GrGLStencilAttachment.h"
17 #include "GrSwizzle.h"
18 #include "SkChecksum.h"
19 #include "SkTHash.h"
20 #include "SkTArray.h"
21 
22 class GrGLContextInfo;
23 class GrGLSLCaps;
24 class GrGLRenderTarget;
25 
26 /**
27  * Stores some capabilities of a GL context. Most are determined by the GL
28  * version and the extensions string. It also tracks formats that have passed
29  * the FBO completeness test.
30  */
31 class GrGLCaps : public GrCaps {
32 public:
33     typedef GrGLStencilAttachment::Format StencilFormat;
34 
35     /**
36      * The type of MSAA for FBOs supported. Different extensions have different
37      * semantics of how / when a resolve is performed.
38      */
39     enum MSFBOType {
40         /**
41          * no support for MSAA FBOs
42          */
43         kNone_MSFBOType = 0,
44         /**
45          * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object).
46          */
47         kDesktop_ARB_MSFBOType,
48         /**
49          * earlier GL_EXT_framebuffer* extensions
50          */
51         kDesktop_EXT_MSFBOType,
52         /**
53          * Similar to kDesktop_ARB but with additional restrictions on glBlitFramebuffer.
54          */
55         kES_3_0_MSFBOType,
56         /**
57          * GL_APPLE_framebuffer_multisample ES extension
58          */
59         kES_Apple_MSFBOType,
60         /**
61          * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
62          * Instead the texture is multisampled when bound to the FBO and then resolved automatically
63          * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
64          * GR_GL_MAX_SAMPLES_IMG).
65          */
66         kES_IMG_MsToTexture_MSFBOType,
67         /**
68          * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
69          * GL_MAX_SAMPLES value.
70          */
71         kES_EXT_MsToTexture_MSFBOType,
72         /**
73          * GL_NV_framebuffer_mixed_samples.
74          */
75         kMixedSamples_MSFBOType,
76 
77         kLast_MSFBOType = kMixedSamples_MSFBOType
78     };
79 
80     enum BlitFramebufferSupport {
81         kNone_BlitFramebufferSupport,
82         /**
83          * ANGLE exposes a limited blit framebuffer extension that does not allow for stretching
84          * or mirroring.
85          */
86         kNoScalingNoMirroring_BlitFramebufferSupport,
87         kFull_BlitFramebufferSupport
88     };
89 
90     enum InvalidateFBType {
91         kNone_InvalidateFBType,
92         kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
93         kInvalidate_InvalidateFBType,    //<! glInvalidateFramebuffer()
94 
95         kLast_InvalidateFBType = kInvalidate_InvalidateFBType
96     };
97 
98     enum MapBufferType {
99         kNone_MapBufferType,
100         kMapBuffer_MapBufferType,         // glMapBuffer()
101         kMapBufferRange_MapBufferType,    // glMapBufferRange()
102         kChromium_MapBufferType,          // GL_CHROMIUM_map_sub
103 
104         kLast_MapBufferType = kChromium_MapBufferType,
105     };
106 
107     enum TransferBufferType {
108         kNone_TransferBufferType,
109         kPBO_TransferBufferType,          // ARB_pixel_buffer_object
110         kChromium_TransferBufferType,     // CHROMIUM_pixel_transfer_buffer_object
111 
112         kLast_TransferBufferType = kChromium_TransferBufferType,
113     };
114 
115     /**
116      * Initializes the GrGLCaps to the set of features supported in the current
117      * OpenGL context accessible via ctxInfo.
118      */
119     GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
120              const GrGLInterface* glInterface);
121 
isConfigTexturable(GrPixelConfig config)122     bool isConfigTexturable(GrPixelConfig config) const override {
123         SkASSERT(kGrPixelConfigCnt > config);
124         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
125     }
126 
isConfigRenderable(GrPixelConfig config,bool withMSAA)127     bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
128         SkASSERT(kGrPixelConfigCnt > config);
129         if (withMSAA) {
130             return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
131         } else {
132             return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
133         }
134     }
135 
136     /** Returns the mapping between GrPixelConfig components and GL internal format components. */
configSwizzle(GrPixelConfig config)137     const GrSwizzle& configSwizzle(GrPixelConfig config) const {
138         return fConfigTable[config].fSwizzle;
139     }
140 
141     bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
142                             GrGLenum* internalFormat, GrGLenum* externalFormat,
143                             GrGLenum* externalType) const;
144 
145     bool getCompressedTexImageFormats(GrPixelConfig surfaceConfig, GrGLenum* internalFormat) const;
146 
147     bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
148                              GrGLenum* externalFormat, GrGLenum* externalType) const;
149 
150     bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
151 
152     /**
153     * Gets an array of legal stencil formats. These formats are not guaranteed
154     * to be supported by the driver but are legal GLenum names given the GL
155     * version and extensions supported.
156     */
stencilFormats()157     const SkTArray<StencilFormat, true>& stencilFormats() const {
158         return fStencilFormats;
159     }
160 
161     /**
162      * Has a stencil format index been found for the config (or we've found that no format works).
163      */
hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config)164     bool hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config) const {
165         return fConfigTable[config].fStencilFormatIndex != ConfigInfo::kUnknown_StencilIndex;
166     }
167 
168     /**
169      * Gets the stencil format index for the config. This assumes
170      * hasStencilFormatBeenDeterminedForConfig has already been checked. Returns a value < 0 if
171      * no stencil format is supported with the config. Otherwise, returned index refers to the array
172      * returned by stencilFormats().
173      */
getStencilFormatIndexForConfig(GrPixelConfig config)174     int getStencilFormatIndexForConfig(GrPixelConfig config) const {
175         SkASSERT(this->hasStencilFormatBeenDeterminedForConfig(config));
176         return fConfigTable[config].fStencilFormatIndex;
177     }
178 
179     /**
180      * If index is >= 0 this records an index into stencilFormats() as the best stencil format for
181      * the config. If < 0 it records that the config has no supported stencil format index.
182      */
setStencilFormatIndexForConfig(GrPixelConfig config,int index)183     void setStencilFormatIndexForConfig(GrPixelConfig config, int index) {
184         SkASSERT(!this->hasStencilFormatBeenDeterminedForConfig(config));
185         if (index < 0) {
186             fConfigTable[config].fStencilFormatIndex = ConfigInfo::kUnsupported_StencilFormatIndex;
187         } else {
188             fConfigTable[config].fStencilFormatIndex = index;
189         }
190     }
191 
192     /**
193      * Call to note that a color config has been verified as a valid color
194      * attachment. This may save future calls to glCheckFramebufferStatus
195      * using isConfigVerifiedColorAttachment().
196      */
markConfigAsValidColorAttachment(GrPixelConfig config)197     void markConfigAsValidColorAttachment(GrPixelConfig config) {
198         fConfigTable[config].fFlags |= ConfigInfo::kVerifiedColorAttachment_Flag;
199     }
200 
201     /**
202      * Call to check whether a config has been verified as a valid color
203      * attachment.
204      */
isConfigVerifiedColorAttachment(GrPixelConfig config)205     bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
206         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kVerifiedColorAttachment_Flag);
207     }
208 
209     /**
210      * Reports the type of MSAA FBO support.
211      */
msFBOType()212     MSFBOType msFBOType() const { return fMSFBOType; }
213 
214     /**
215      * Does the preferred MSAA FBO extension have MSAA renderbuffers?
216      */
usesMSAARenderBuffers()217     bool usesMSAARenderBuffers() const {
218         return kNone_MSFBOType != fMSFBOType &&
219                kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
220                kES_EXT_MsToTexture_MSFBOType != fMSFBOType &&
221                kMixedSamples_MSFBOType != fMSFBOType;
222     }
223 
224     /**
225      * What functionality is supported by glBlitFramebuffer.
226      */
blitFramebufferSupport()227     BlitFramebufferSupport blitFramebufferSupport() const { return fBlitFramebufferSupport; }
228 
229     /**
230      * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
231      * then implicitly resolved when read.
232      */
usesImplicitMSAAResolve()233     bool usesImplicitMSAAResolve() const {
234         return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
235                kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
236     }
237 
invalidateFBType()238     InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
239 
240     /// What type of buffer mapping is supported?
mapBufferType()241     MapBufferType mapBufferType() const { return fMapBufferType; }
242 
243     /// What type of transfer buffer is supported?
transferBufferType()244     TransferBufferType transferBufferType() const { return fTransferBufferType; }
245 
246     /// The maximum number of fragment uniform vectors (GLES has min. 16).
maxFragmentUniformVectors()247     int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
248 
249     /// maximum number of attribute values per vertex
maxVertexAttributes()250     int maxVertexAttributes() const { return fMaxVertexAttributes; }
251 
252     /// maximum number of texture units accessible in the fragment shader.
maxFragmentTextureUnits()253     int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; }
254 
255     /**
256      * Depending on the ES extensions present the BGRA external format may
257      * correspond to either a BGRA or RGBA internalFormat. On desktop GL it is
258      * RGBA.
259      */
260     bool bgraIsInternalFormat() const;
261 
262     /// Is there support for GL_UNPACK_ROW_LENGTH
unpackRowLengthSupport()263     bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
264 
265     /// Is there support for GL_UNPACK_FLIP_Y
unpackFlipYSupport()266     bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
267 
268     /// Is there support for GL_PACK_ROW_LENGTH
packRowLengthSupport()269     bool packRowLengthSupport() const { return fPackRowLengthSupport; }
270 
271     /// Is there support for GL_PACK_REVERSE_ROW_ORDER
packFlipYSupport()272     bool packFlipYSupport() const { return fPackFlipYSupport; }
273 
274     /// Is there support for texture parameter GL_TEXTURE_USAGE
textureUsageSupport()275     bool textureUsageSupport() const { return fTextureUsageSupport; }
276 
277     /// Is there support for glTexStorage
texStorageSupport()278     bool texStorageSupport() const { return fTexStorageSupport; }
279 
280     /// Is there support for GL_RED and GL_R8
textureRedSupport()281     bool textureRedSupport() const { return fTextureRedSupport; }
282 
283     /// Is GL_ARB_IMAGING supported
imagingSupport()284     bool imagingSupport() const { return fImagingSupport; }
285 
286     /// Is there support for Vertex Array Objects?
vertexArrayObjectSupport()287     bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
288 
289     /// Is there support for GL_EXT_direct_state_access?
directStateAccessSupport()290     bool directStateAccessSupport() const { return fDirectStateAccessSupport; }
291 
292     /// Is there support for GL_KHR_debug?
debugSupport()293     bool debugSupport() const { return fDebugSupport; }
294 
295     /// Is there support for ES2 compatability?
ES2CompatibilitySupport()296     bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
297 
298     /// Can we call glDisable(GL_MULTISAMPLE)?
multisampleDisableSupport()299     bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
300 
301     /// Is there support for glDraw*Indirect? Note that the baseInstance fields of indirect draw
302     /// commands cannot be used unless we have base instance support.
drawIndirectSupport()303     bool drawIndirectSupport() const { return fDrawIndirectSupport; }
304 
305     /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect
306     /// draw commands cannot be used unless we have base instance support.
multiDrawIndirectSupport()307     bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
308 
309     /// Are the baseInstance fields supported in indirect draw commands?
baseInstanceSupport()310     bool baseInstanceSupport() const { return fBaseInstanceSupport; }
311 
312     /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
useNonVBOVertexAndIndexDynamicData()313     bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
314 
315     /// Does ReadPixels support reading readConfig pixels from a FBO that is renderTargetConfig?
316     bool readPixelsSupported(GrPixelConfig renderTargetConfig,
317                              GrPixelConfig readConfig,
318                              std::function<void (GrGLenum, GrGLint*)> getIntegerv,
319                              std::function<bool ()> bindRenderTarget) const;
320 
isCoreProfile()321     bool isCoreProfile() const { return fIsCoreProfile; }
322 
bindFragDataLocationSupport()323     bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; }
324 
bindUniformLocationSupport()325     bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; }
326 
327     /// Are textures with GL_TEXTURE_EXTERNAL_OES type supported.
externalTextureSupport()328     bool externalTextureSupport() const { return fExternalTextureSupport; }
329 
330     /// Are textures with GL_TEXTURE_RECTANGLE type supported.
rectangleTextureSupport()331     bool rectangleTextureSupport() const { return fRectangleTextureSupport; }
332 
333     /// GL_ARB_texture_swizzle
textureSwizzleSupport()334     bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
335 
336     /**
337      * Is there support for enabling/disabling sRGB writes for sRGB-capable color attachments?
338      * If false this does not mean sRGB is not supported but rather that if it is supported
339      * it cannot be turned off for configs that support it.
340      */
srgbWriteControl()341     bool srgbWriteControl() const { return fSRGBWriteControl; }
342 
343     /**
344      * Returns a string containing the caps info.
345      */
346     SkString dump() const override;
347 
rgba8888PixelsOpsAreSlow()348     bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; }
partialFBOReadIsSlow()349     bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; }
350 
glslCaps()351     const GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); }
352 
353 private:
354     enum ExternalFormatUsage {
355         kTexImage_ExternalFormatUsage,
356         kOther_ExternalFormatUsage,
357 
358         kLast_ExternalFormatUsage = kOther_ExternalFormatUsage
359     };
360     static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1;
361     bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
362                            ExternalFormatUsage usage, GrGLenum* externalFormat,
363                            GrGLenum* externalType) const;
364 
365     void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
366     void initGLSL(const GrGLContextInfo&);
367     bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*);
368 
369     void onApplyOptionsOverrides(const GrContextOptions& options) override;
370 
371     void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
372     void initBlendEqationSupport(const GrGLContextInfo&);
373     void initStencilFormats(const GrGLContextInfo&);
374     // This must be called after initFSAASupport().
375     void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli, GrGLSLCaps* glslCaps);
376 
377     void initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
378                                   const GrGLInterface* intf,
379                                   GrGLSLCaps* glslCaps);
380 
381     GrGLStandard fStandard;
382 
383     SkTArray<StencilFormat, true> fStencilFormats;
384 
385     int fMaxFragmentUniformVectors;
386     int fMaxVertexAttributes;
387     int fMaxFragmentTextureUnits;
388 
389     MSFBOType           fMSFBOType;
390     InvalidateFBType    fInvalidateFBType;
391     MapBufferType       fMapBufferType;
392     TransferBufferType  fTransferBufferType;
393 
394     bool fUnpackRowLengthSupport : 1;
395     bool fUnpackFlipYSupport : 1;
396     bool fPackRowLengthSupport : 1;
397     bool fPackFlipYSupport : 1;
398     bool fTextureUsageSupport : 1;
399     bool fTexStorageSupport : 1;
400     bool fTextureRedSupport : 1;
401     bool fImagingSupport  : 1;
402     bool fVertexArrayObjectSupport : 1;
403     bool fDirectStateAccessSupport : 1;
404     bool fDebugSupport : 1;
405     bool fES2CompatibilitySupport : 1;
406     bool fMultisampleDisableSupport : 1;
407     bool fDrawIndirectSupport : 1;
408     bool fMultiDrawIndirectSupport : 1;
409     bool fBaseInstanceSupport : 1;
410     bool fUseNonVBOVertexAndIndexDynamicData : 1;
411     bool fIsCoreProfile : 1;
412     bool fBindFragDataLocationSupport : 1;
413     bool fSRGBWriteControl : 1;
414     bool fRGBA8888PixelsOpsAreSlow : 1;
415     bool fPartialFBOReadIsSlow : 1;
416     bool fBindUniformLocationSupport : 1;
417     bool fExternalTextureSupport : 1;
418     bool fRectangleTextureSupport : 1;
419     bool fTextureSwizzleSupport : 1;
420 
421     BlitFramebufferSupport fBlitFramebufferSupport;
422 
423     /** Number type of the components (with out considering number of bits.) */
424     enum FormatType {
425         kNormalizedFixedPoint_FormatType,
426         kFloat_FormatType,
427     };
428 
429     struct ReadPixelsFormat {
ReadPixelsFormatReadPixelsFormat430         ReadPixelsFormat() : fFormat(0), fType(0) {}
431         GrGLenum fFormat;
432         GrGLenum fType;
433     };
434 
435     struct ConfigFormats {
ConfigFormatsConfigFormats436         ConfigFormats() {
437             // Inits to known bad GL enum values.
438             memset(this, 0xAB, sizeof(ConfigFormats));
439         }
440         GrGLenum fBaseInternalFormat;
441         GrGLenum fSizedInternalFormat;
442 
443         /** The external format and type are to be used when uploading/downloading data using this
444             config where both the CPU data and GrSurface are the same config. To get the external
445             format and type when converting between configs while copying to/from memory use
446             getExternalFormat().
447             The kTexImage external format is usually the same as kOther except for kSRGBA on some
448             GL contexts. */
449         GrGLenum fExternalFormat[kExternalFormatUsageCnt];
450         GrGLenum fExternalType;
451 
452 
453         // Either the base or sized internal format depending on the GL and config.
454         GrGLenum fInternalFormatTexImage;
455         GrGLenum fInternalFormatRenderbuffer;
456     };
457 
458     struct ConfigInfo {
ConfigInfoConfigInfo459         ConfigInfo() : fStencilFormatIndex(kUnknown_StencilIndex), fFlags(0) {}
460 
461         ConfigFormats fFormats;
462 
463         FormatType fFormatType;
464 
465         // On ES contexts there are restrictions on type type/format that may be used for
466         // ReadPixels. One is implicitly specified by the current FBO's format. The other is
467         // queryable. This stores the queried option (lazily).
468         ReadPixelsFormat fSecondReadPixelsFormat;
469 
470         enum {
471             // This indicates that a stencil format has not yet been determined for the config.
472             kUnknown_StencilIndex = -1,
473             // This indicates that there is no supported stencil format for the config.
474             kUnsupported_StencilFormatIndex = -2
475         };
476 
477         // Index fStencilFormats.
478         int      fStencilFormatIndex;
479 
480         enum {
481             kVerifiedColorAttachment_Flag = 0x1,
482             kTextureable_Flag             = 0x2,
483             kRenderable_Flag              = 0x4,
484             kRenderableWithMSAA_Flag      = 0x8,
485         };
486         uint32_t fFlags;
487 
488         GrSwizzle fSwizzle;
489     };
490 
491     ConfigInfo fConfigTable[kGrPixelConfigCnt];
492 
493     typedef GrCaps INHERITED;
494 };
495 
496 #endif
497