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 "GrDrawTargetCaps.h"
13 #include "GrGLStencilAttachment.h"
14 #include "SkChecksum.h"
15 #include "SkTHash.h"
16 #include "SkTArray.h"
17 
18 class GrGLContextInfo;
19 class GrGLSLCaps;
20 
21 /**
22  * Stores some capabilities of a GL context. Most are determined by the GL
23  * version and the extensions string. It also tracks formats that have passed
24  * the FBO completeness test.
25  */
26 class GrGLCaps : public GrDrawTargetCaps {
27 public:
28     SK_DECLARE_INST_COUNT(GrGLCaps)
29 
30     typedef GrGLStencilAttachment::Format StencilFormat;
31 
32     /**
33      * The type of MSAA for FBOs supported. Different extensions have different
34      * semantics of how / when a resolve is performed.
35      */
36     enum MSFBOType {
37         /**
38          * no support for MSAA FBOs
39          */
40         kNone_MSFBOType = 0,
41         /**
42          * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object).
43          */
44         kDesktop_ARB_MSFBOType,
45         /**
46          * earlier GL_EXT_framebuffer* extensions
47          */
48         kDesktop_EXT_MSFBOType,
49         /**
50          * Similar to kDesktop_ARB but with additional restrictions on glBlitFramebuffer.
51          */
52         kES_3_0_MSFBOType,
53         /**
54          * GL_APPLE_framebuffer_multisample ES extension
55          */
56         kES_Apple_MSFBOType,
57         /**
58          * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
59          * Instead the texture is multisampled when bound to the FBO and then resolved automatically
60          * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
61          * GR_GL_MAX_SAMPLES_IMG).
62          */
63         kES_IMG_MsToTexture_MSFBOType,
64         /**
65          * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
66          * GL_MAX_SAMPLES value.
67          */
68         kES_EXT_MsToTexture_MSFBOType,
69 
70         kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType
71     };
72 
73     enum InvalidateFBType {
74         kNone_InvalidateFBType,
75         kDiscard_InvalidateFBType,       //<! glDiscardFramebuffer()
76         kInvalidate_InvalidateFBType,     //<! glInvalidateFramebuffer()
77 
78         kLast_InvalidateFBType = kInvalidate_InvalidateFBType
79     };
80 
81     enum MapBufferType {
82         kNone_MapBufferType,
83         kMapBuffer_MapBufferType,         // glMapBuffer()
84         kMapBufferRange_MapBufferType,    // glMapBufferRange()
85         kChromium_MapBufferType,          // GL_CHROMIUM_map_sub
86 
87         kLast_MapBufferType = kChromium_MapBufferType,
88     };
89 
90     /**
91      * Creates a GrGLCaps that advertises no support for any extensions,
92      * formats, etc. Call init to initialize from a GrGLContextInfo.
93      */
94     GrGLCaps();
95 
96     GrGLCaps(const GrGLCaps& caps);
97 
98     GrGLCaps& operator = (const GrGLCaps& caps);
99 
100     /**
101      * Resets the caps such that nothing is supported.
102      */
103     void reset() override;
104 
105     /**
106      * Initializes the GrGLCaps to the set of features supported in the current
107      * OpenGL context accessible via ctxInfo.
108      */
109     bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface);
110 
111     /**
112      * Call to note that a color config has been verified as a valid color
113      * attachment. This may save future calls to glCheckFramebufferStatus
114      * using isConfigVerifiedColorAttachment().
115      */
markConfigAsValidColorAttachment(GrPixelConfig config)116     void markConfigAsValidColorAttachment(GrPixelConfig config) {
117         fVerifiedColorConfigs.markVerified(config);
118     }
119 
120     /**
121      * Call to check whether a config has been verified as a valid color
122      * attachment.
123      */
isConfigVerifiedColorAttachment(GrPixelConfig config)124     bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
125         return fVerifiedColorConfigs.isVerified(config);
126     }
127 
128     /**
129      * Call to note that a color config / stencil format pair passed
130      * FBO status check. We may skip calling glCheckFramebufferStatus for
131      * this combination in the future using
132      * isColorConfigAndStencilFormatVerified().
133      */
134     void markColorConfigAndStencilFormatAsVerified(
135                     GrPixelConfig config,
136                     const GrGLStencilAttachment::Format& format);
137 
138     /**
139      * Call to check whether color config / stencil format pair has already
140      * passed FBO status check.
141      */
142     bool isColorConfigAndStencilFormatVerified(
143                     GrPixelConfig config,
144                     const GrGLStencilAttachment::Format& format) const;
145 
146     /**
147      * Reports the type of MSAA FBO support.
148      */
msFBOType()149     MSFBOType msFBOType() const { return fMSFBOType; }
150 
151     /**
152      * Does the supported MSAA FBO extension have MSAA renderbuffers?
153      */
usesMSAARenderBuffers()154     bool usesMSAARenderBuffers() const {
155         return kNone_MSFBOType != fMSFBOType &&
156                kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
157                kES_EXT_MsToTexture_MSFBOType != fMSFBOType;
158     }
159 
160     /**
161      * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
162      * then implicitly resolved when read.
163      */
usesImplicitMSAAResolve()164     bool usesImplicitMSAAResolve() const {
165         return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
166                kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
167     }
168 
fbMixedSamplesSupport()169     bool fbMixedSamplesSupport() const { return fFBMixedSamplesSupport; }
170 
invalidateFBType()171     InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
172 
173     /// What type of buffer mapping is supported?
mapBufferType()174     MapBufferType mapBufferType() const { return fMapBufferType; }
175 
176     /**
177      * Gets an array of legal stencil formats. These formats are not guaranteed
178      * to be supported by the driver but are legal GLenum names given the GL
179      * version and extensions supported.
180      */
stencilFormats()181     const SkTArray<StencilFormat, true>& stencilFormats() const {
182         return fStencilFormats;
183     }
184 
185     /// The maximum number of fragment uniform vectors (GLES has min. 16).
maxFragmentUniformVectors()186     int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; }
187 
188     /// maximum number of attribute values per vertex
maxVertexAttributes()189     int maxVertexAttributes() const { return fMaxVertexAttributes; }
190 
191     /// maximum number of texture units accessible in the fragment shader.
maxFragmentTextureUnits()192     int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; }
193 
194     /// ES requires an extension to support RGBA8 in RenderBufferStorage
rgba8RenderbufferSupport()195     bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; }
196 
197     /**
198      * Depending on the ES extensions present the BGRA external format may
199      * correspond either a BGRA or RGBA internalFormat. On desktop GL it is
200      * RGBA.
201      */
bgraIsInternalFormat()202     bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; }
203 
204     /// GL_ARB_texture_swizzle support
textureSwizzleSupport()205     bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
206 
207     /// Is there support for GL_UNPACK_ROW_LENGTH
unpackRowLengthSupport()208     bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
209 
210     /// Is there support for GL_UNPACK_FLIP_Y
unpackFlipYSupport()211     bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
212 
213     /// Is there support for GL_PACK_ROW_LENGTH
packRowLengthSupport()214     bool packRowLengthSupport() const { return fPackRowLengthSupport; }
215 
216     /// Is there support for GL_PACK_REVERSE_ROW_ORDER
packFlipYSupport()217     bool packFlipYSupport() const { return fPackFlipYSupport; }
218 
219     /// Is there support for texture parameter GL_TEXTURE_USAGE
textureUsageSupport()220     bool textureUsageSupport() const { return fTextureUsageSupport; }
221 
222     /// Is there support for glTexStorage
texStorageSupport()223     bool texStorageSupport() const { return fTexStorageSupport; }
224 
225     /// Is there support for GL_RED and GL_R8
textureRedSupport()226     bool textureRedSupport() const { return fTextureRedSupport; }
227 
228     /// Is GL_ARB_IMAGING supported
imagingSupport()229     bool imagingSupport() const { return fImagingSupport; }
230 
231     /// Is GL_ARB_fragment_coord_conventions supported?
fragCoordConventionsSupport()232     bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; }
233 
234     /// Is there support for Vertex Array Objects?
vertexArrayObjectSupport()235     bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
236 
237     /// Is there support for ES2 compatability?
ES2CompatibilitySupport()238     bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
239 
240     /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
useNonVBOVertexAndIndexDynamicData()241     bool useNonVBOVertexAndIndexDynamicData() const {
242         return fUseNonVBOVertexAndIndexDynamicData;
243     }
244 
245     /// Does ReadPixels support the provided format/type combo?
246     bool readPixelsSupported(const GrGLInterface* intf,
247                              GrGLenum format,
248                              GrGLenum type,
249                              GrGLenum currFboFormat) const;
250 
isCoreProfile()251     bool isCoreProfile() const { return fIsCoreProfile; }
252 
253 
fullClearIsFree()254     bool fullClearIsFree() const { return fFullClearIsFree; }
255 
256     /**
257      * Returns a string containing the caps info.
258      */
259     SkString dump() const override;
260 
261     /**
262      * LATC can appear under one of three possible names. In order to know
263      * which GL internal format to use, we need to keep track of which name
264      * we found LATC under. The default is LATC.
265      */
266     enum LATCAlias {
267         kLATC_LATCAlias,
268         kRGTC_LATCAlias,
269         k3DC_LATCAlias
270     };
271 
latcAlias()272     LATCAlias latcAlias() const { return fLATCAlias; }
273 
glslCaps()274     GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); }
275 
276 private:
277     /**
278      * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
279      * performing glCheckFrameBufferStatus for the same config.
280      */
281     struct VerifiedColorConfigs {
VerifiedColorConfigsVerifiedColorConfigs282         VerifiedColorConfigs() {
283             this->reset();
284         }
285 
resetVerifiedColorConfigs286         void reset() {
287             for (int i = 0; i < kNumUints; ++i) {
288                 fVerifiedColorConfigs[i] = 0;
289             }
290         }
291 
292         static const int kNumUints = (kGrPixelConfigCnt  + 31) / 32;
293         uint32_t fVerifiedColorConfigs[kNumUints];
294 
markVerifiedVerifiedColorConfigs295         void markVerified(GrPixelConfig config) {
296 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
297                 return;
298 #endif
299             int u32Idx = config / 32;
300             int bitIdx = config % 32;
301             fVerifiedColorConfigs[u32Idx] |= 1 << bitIdx;
302         }
303 
isVerifiedVerifiedColorConfigs304         bool isVerified(GrPixelConfig config) const {
305 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
306             return false;
307 #endif
308             int u32Idx = config / 32;
309             int bitIdx = config % 32;
310             return SkToBool(fVerifiedColorConfigs[u32Idx] & (1 << bitIdx));
311         }
312     };
313 
314     void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
315     void initStencilFormats(const GrGLContextInfo&);
316     // This must be called after initFSAASupport().
317     void initConfigRenderableTable(const GrGLContextInfo&);
318     void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*);
319 
320     bool doReadPixelsSupported(const GrGLInterface* intf, GrGLenum format, GrGLenum type) const;
321 
322     // tracks configs that have been verified to pass the FBO completeness when
323     // used as a color attachment
324     VerifiedColorConfigs fVerifiedColorConfigs;
325 
326     SkTArray<StencilFormat, true> fStencilFormats;
327     // tracks configs that have been verified to pass the FBO completeness when
328     // used as a color attachment when a particular stencil format is used
329     // as a stencil attachment.
330     SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs;
331 
332     int fMaxFragmentUniformVectors;
333     int fMaxVertexAttributes;
334     int fMaxFragmentTextureUnits;
335 
336     MSFBOType           fMSFBOType;
337     InvalidateFBType    fInvalidateFBType;
338     MapBufferType       fMapBufferType;
339     LATCAlias           fLATCAlias;
340 
341     bool fRGBA8RenderbufferSupport : 1;
342     bool fBGRAIsInternalFormat : 1;
343     bool fTextureSwizzleSupport : 1;
344     bool fUnpackRowLengthSupport : 1;
345     bool fUnpackFlipYSupport : 1;
346     bool fPackRowLengthSupport : 1;
347     bool fPackFlipYSupport : 1;
348     bool fTextureUsageSupport : 1;
349     bool fTexStorageSupport : 1;
350     bool fTextureRedSupport : 1;
351     bool fImagingSupport  : 1;
352     bool fTwoFormatLimit : 1;
353     bool fFragCoordsConventionSupport : 1;
354     bool fVertexArrayObjectSupport : 1;
355     bool fES2CompatibilitySupport : 1;
356     bool fUseNonVBOVertexAndIndexDynamicData : 1;
357     bool fIsCoreProfile : 1;
358     bool fFullClearIsFree : 1;
359     bool fFBMixedSamplesSupport : 1;
360 
361     struct ReadPixelsSupportedFormat {
362         GrGLenum fFormat;
363         GrGLenum fType;
364         GrGLenum fFboFormat;
365 
366         bool operator==(const ReadPixelsSupportedFormat& rhs) const {
367             return fFormat    == rhs.fFormat
368                 && fType      == rhs.fType
369                 && fFboFormat == rhs.fFboFormat;
370         }
371     };
372     mutable SkTHashMap<ReadPixelsSupportedFormat, bool> fReadPixelsSupportedCache;
373 
374     typedef GrDrawTargetCaps INHERITED;
375 };
376 
377 
378 class GrGLSLCaps : public GrShaderCaps {
379 public:
380     SK_DECLARE_INST_COUNT(GrGLSLCaps)
381 
382     /**
383     * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
384     * special layout qualifiers in the fragment shader.
385     */
386     enum AdvBlendEqInteraction {
387         kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
388         kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
389         kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
390         kSpecificEnables_AdvBlendEqInteraction,  //<! Specific layout qualifiers per equation
391 
392         kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
393     };
394 
395     /**
396      * Creates a GrGLSLCaps that advertises no support for any extensions,
397      * formats, etc. Call init to initialize from a GrGLContextInfo.
398      */
399     GrGLSLCaps();
~GrGLSLCaps()400     ~GrGLSLCaps() override {}
401 
402     GrGLSLCaps(const GrGLSLCaps& caps);
403 
404     GrGLSLCaps& operator = (const GrGLSLCaps& caps);
405 
406     /**
407      * Resets the caps such that nothing is supported.
408      */
409     void reset() override;
410 
411     /**
412      * Initializes the GrGLSLCaps to the set of features supported in the current
413      * OpenGL context accessible via ctxInfo.
414      */
415     bool init(const GrGLContextInfo&, const GrGLInterface*, const GrGLCaps&);
416 
417     /**
418      * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
419      *
420      * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
421      */
fbFetchSupport()422     bool fbFetchSupport() const { return fFBFetchSupport; }
423 
fbFetchNeedsCustomOutput()424     bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
425 
fbFetchColorName()426     const char* fbFetchColorName() const { return fFBFetchColorName; }
427 
fbFetchExtensionString()428     const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
429 
dropsTileOnZeroDivide()430     bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
431 
advBlendEqInteraction()432     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
433 
mustEnableAdvBlendEqs()434     bool mustEnableAdvBlendEqs() const {
435         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
436     }
437 
mustEnableSpecificAdvBlendEqs()438     bool mustEnableSpecificAdvBlendEqs() const {
439         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
440     }
441 
442     /**
443     * Returns a string containing the caps info.
444     */
445     SkString dump() const override;
446 
447 private:
448     // Must be called after fGeometryShaderSupport is initialized.
449     void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*);
450 
451     bool fDropsTileOnZeroDivide : 1;
452     bool fFBFetchSupport : 1;
453     bool fFBFetchNeedsCustomOutput : 1;
454 
455     const char* fFBFetchColorName;
456     const char* fFBFetchExtensionString;
457 
458     AdvBlendEqInteraction fAdvBlendEqInteraction;
459 
460     typedef GrShaderCaps INHERITED;
461 };
462 
463 
464 #endif
465