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