Line data Source code
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 0 : 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 :
117 0 : bool isConfigTexturable(GrPixelConfig config) const override {
118 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
119 : }
120 :
121 0 : bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
122 0 : if (withMSAA) {
123 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
124 : } else {
125 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
126 : }
127 : }
128 0 : bool canConfigBeImageStorage(GrPixelConfig config) const override {
129 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseAsImageStorage_Flag);
130 : }
131 0 : bool canConfigBeFBOColorAttachment(GrPixelConfig config) const {
132 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kFBOColorAttachment_Flag);
133 : }
134 :
135 0 : bool isConfigTexSupportEnabled(GrPixelConfig config) const {
136 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag);
137 : }
138 :
139 0 : bool canUseConfigWithTexelBuffer(GrPixelConfig config) const {
140 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseWithTexelBuffer_Flag);
141 : }
142 :
143 : /** Returns the mapping between GrPixelConfig components and GL internal format components. */
144 0 : const GrSwizzle& configSwizzle(GrPixelConfig config) const {
145 0 : return fConfigTable[config].fSwizzle;
146 : }
147 :
148 0 : GrGLenum configSizedInternalFormat(GrPixelConfig config) const {
149 0 : 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 */
164 0 : GrGLenum getImageFormat(GrPixelConfig config) const {
165 0 : 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 : */
173 0 : const SkTArray<StencilFormat, true>& stencilFormats() const {
174 0 : 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 : */
180 0 : bool hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config) const {
181 0 : 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 : */
190 0 : int getStencilFormatIndexForConfig(GrPixelConfig config) const {
191 0 : SkASSERT(this->hasStencilFormatBeenDeterminedForConfig(config));
192 0 : 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 : */
199 0 : void setStencilFormatIndexForConfig(GrPixelConfig config, int index) {
200 0 : SkASSERT(!this->hasStencilFormatBeenDeterminedForConfig(config));
201 0 : if (index < 0) {
202 0 : fConfigTable[config].fStencilFormatIndex = ConfigInfo::kUnsupported_StencilFormatIndex;
203 : } else {
204 0 : fConfigTable[config].fStencilFormatIndex = index;
205 : }
206 0 : }
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 : */
213 0 : void markConfigAsValidColorAttachment(GrPixelConfig config) {
214 0 : fConfigTable[config].fFlags |= ConfigInfo::kVerifiedColorAttachment_Flag;
215 0 : }
216 :
217 : /**
218 : * Call to check whether a config has been verified as a valid color
219 : * attachment.
220 : */
221 0 : bool isConfigVerifiedColorAttachment(GrPixelConfig config) const {
222 0 : return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kVerifiedColorAttachment_Flag);
223 : }
224 :
225 : /**
226 : * Reports the type of MSAA FBO support.
227 : */
228 0 : MSFBOType msFBOType() const { return fMSFBOType; }
229 :
230 : /**
231 : * Does the preferred MSAA FBO extension have MSAA renderbuffers?
232 : */
233 0 : bool usesMSAARenderBuffers() const {
234 0 : return kNone_MSFBOType != fMSFBOType &&
235 0 : kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
236 0 : kES_EXT_MsToTexture_MSFBOType != fMSFBOType &&
237 0 : kMixedSamples_MSFBOType != fMSFBOType;
238 : }
239 :
240 : /**
241 : * What functionality is supported by glBlitFramebuffer.
242 : */
243 0 : 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 : */
249 0 : bool usesImplicitMSAAResolve() const {
250 0 : return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
251 0 : kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
252 : }
253 :
254 : InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
255 :
256 : /// What type of buffer mapping is supported?
257 0 : MapBufferType mapBufferType() const { return fMapBufferType; }
258 :
259 : /// What type of transfer buffer is supported?
260 0 : TransferBufferType transferBufferType() const { return fTransferBufferType; }
261 :
262 : /// The maximum number of fragment uniform vectors (GLES has min. 16).
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
273 0 : bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
274 :
275 : /// Is there support for GL_UNPACK_FLIP_Y
276 0 : bool unpackFlipYSupport() const { return fUnpackFlipYSupport; }
277 :
278 : /// Is there support for GL_PACK_ROW_LENGTH
279 0 : bool packRowLengthSupport() const { return fPackRowLengthSupport; }
280 :
281 : /// Is there support for GL_PACK_REVERSE_ROW_ORDER
282 0 : bool packFlipYSupport() const { return fPackFlipYSupport; }
283 :
284 : /// Is there support for texture parameter GL_TEXTURE_USAGE
285 0 : bool textureUsageSupport() const { return fTextureUsageSupport; }
286 :
287 : /// Is there support for GL_RED and GL_R8
288 0 : bool textureRedSupport() const { return fTextureRedSupport; }
289 :
290 : /// Is GL_ARB_IMAGING supported
291 0 : bool imagingSupport() const { return fImagingSupport; }
292 :
293 : /// Is there support for Vertex Array Objects?
294 0 : bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; }
295 :
296 : /// Is there support for GL_EXT_direct_state_access?
297 : bool directStateAccessSupport() const { return fDirectStateAccessSupport; }
298 :
299 : /// Is there support for GL_KHR_debug?
300 : bool debugSupport() const { return fDebugSupport; }
301 :
302 : /// Is there support for ES2 compatability?
303 0 : bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
304 :
305 : /// Is there support for glDraw*Instanced?
306 0 : 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.
310 0 : 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.
314 0 : bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
315 :
316 : /// Is there support for glDrawRangeElements?
317 0 : bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
318 :
319 : /// Are the baseInstance fields supported in indirect draw commands?
320 0 : bool baseInstanceSupport() const { return fBaseInstanceSupport; }
321 :
322 : /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
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 :
332 0 : bool isCoreProfile() const { return fIsCoreProfile; }
333 :
334 0 : bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; }
335 :
336 0 : bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; }
337 :
338 : /// Are textures with GL_TEXTURE_RECTANGLE type supported.
339 0 : bool rectangleTextureSupport() const { return fRectangleTextureSupport; }
340 :
341 : /// GL_ARB_texture_swizzle
342 0 : bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
343 :
344 0 : bool mipMapLevelAndLodControlSupport() const { return fMipMapLevelAndLodControlSupport; }
345 :
346 0 : bool doManualMipmapping() const { return fDoManualMipmapping; }
347 :
348 0 : bool srgbDecodeDisableSupport() const { return fSRGBDecodeDisableSupport; }
349 0 : bool srgbDecodeDisableAffectsMipmaps() const { return fSRGBDecodeDisableAffectsMipmaps; }
350 :
351 : /**
352 : * Returns a string containing the caps info.
353 : */
354 : SkString dump() const override;
355 :
356 0 : bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; }
357 0 : bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; }
358 0 : bool rgbaToBgraReadbackConversionsAreSlow() const {
359 0 : return fRGBAToBGRAReadbackConversionsAreSlow;
360 : }
361 :
362 : bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
363 : bool* rectsMustMatch, bool* disallowSubrect) const override;
364 :
365 : private:
366 : enum ExternalFormatUsage {
367 : kTexImage_ExternalFormatUsage,
368 : kOther_ExternalFormatUsage,
369 :
370 : kLast_ExternalFormatUsage = kOther_ExternalFormatUsage
371 : };
372 : static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1;
373 : bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
374 : ExternalFormatUsage usage, GrGLenum* externalFormat,
375 : GrGLenum* externalType) const;
376 :
377 : void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
378 : void initGLSL(const GrGLContextInfo&);
379 : bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*);
380 :
381 : void onApplyOptionsOverrides(const GrContextOptions& options) override;
382 :
383 : void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*);
384 : void initBlendEqationSupport(const GrGLContextInfo&);
385 : void initStencilFormats(const GrGLContextInfo&);
386 : // This must be called after initFSAASupport().
387 : void initConfigTable(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*,
388 : GrShaderCaps*);
389 :
390 : void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*, GrShaderCaps*);
391 :
392 : GrGLStandard fStandard;
393 :
394 : SkTArray<StencilFormat, true> fStencilFormats;
395 :
396 : int fMaxFragmentUniformVectors;
397 :
398 : MSFBOType fMSFBOType;
399 : InvalidateFBType fInvalidateFBType;
400 : MapBufferType fMapBufferType;
401 : TransferBufferType fTransferBufferType;
402 :
403 : bool fUnpackRowLengthSupport : 1;
404 : bool fUnpackFlipYSupport : 1;
405 : bool fPackRowLengthSupport : 1;
406 : bool fPackFlipYSupport : 1;
407 : bool fTextureUsageSupport : 1;
408 : bool fTextureRedSupport : 1;
409 : bool fImagingSupport : 1;
410 : bool fVertexArrayObjectSupport : 1;
411 : bool fDirectStateAccessSupport : 1;
412 : bool fDebugSupport : 1;
413 : bool fES2CompatibilitySupport : 1;
414 : bool fDrawInstancedSupport : 1;
415 : bool fDrawIndirectSupport : 1;
416 : bool fDrawRangeElementsSupport : 1;
417 : bool fMultiDrawIndirectSupport : 1;
418 : bool fBaseInstanceSupport : 1;
419 : bool fUseNonVBOVertexAndIndexDynamicData : 1;
420 : bool fIsCoreProfile : 1;
421 : bool fBindFragDataLocationSupport : 1;
422 : bool fRGBA8888PixelsOpsAreSlow : 1;
423 : bool fPartialFBOReadIsSlow : 1;
424 : bool fBindUniformLocationSupport : 1;
425 : bool fRectangleTextureSupport : 1;
426 : bool fTextureSwizzleSupport : 1;
427 : bool fMipMapLevelAndLodControlSupport : 1;
428 : bool fRGBAToBGRAReadbackConversionsAreSlow : 1;
429 : bool fDoManualMipmapping : 1;
430 : bool fSRGBDecodeDisableSupport : 1;
431 : bool fSRGBDecodeDisableAffectsMipmaps : 1;
432 :
433 : uint32_t fBlitFramebufferFlags;
434 :
435 : /** Number type of the components (with out considering number of bits.) */
436 : enum FormatType {
437 : kNormalizedFixedPoint_FormatType,
438 : kFloat_FormatType,
439 : kInteger_FormatType,
440 : };
441 :
442 : struct ReadPixelsFormat {
443 0 : ReadPixelsFormat() : fFormat(0), fType(0) {}
444 : GrGLenum fFormat;
445 : GrGLenum fType;
446 : };
447 :
448 : struct ConfigFormats {
449 0 : ConfigFormats() {
450 : // Inits to known bad GL enum values.
451 0 : memset(this, 0xAB, sizeof(ConfigFormats));
452 0 : }
453 : GrGLenum fBaseInternalFormat;
454 : GrGLenum fSizedInternalFormat;
455 :
456 : /** The external format and type are to be used when uploading/downloading data using this
457 : config where both the CPU data and GrSurface are the same config. To get the external
458 : format and type when converting between configs while copying to/from memory use
459 : getExternalFormat().
460 : The kTexImage external format is usually the same as kOther except for kSRGBA on some
461 : GL contexts. */
462 : GrGLenum fExternalFormat[kExternalFormatUsageCnt];
463 : GrGLenum fExternalType;
464 :
465 : // Either the base or sized internal format depending on the GL and config.
466 : GrGLenum fInternalFormatTexImage;
467 : GrGLenum fInternalFormatRenderbuffer;
468 : };
469 :
470 : struct ConfigInfo {
471 0 : ConfigInfo() : fStencilFormatIndex(kUnknown_StencilIndex), fFlags(0) {}
472 :
473 : ConfigFormats fFormats;
474 :
475 : FormatType fFormatType;
476 :
477 : // On ES contexts there are restrictions on type type/format that may be used for
478 : // ReadPixels. One is implicitly specified by the current FBO's format. The other is
479 : // queryable. This stores the queried option (lazily).
480 : ReadPixelsFormat fSecondReadPixelsFormat;
481 :
482 : enum {
483 : // This indicates that a stencil format has not yet been determined for the config.
484 : kUnknown_StencilIndex = -1,
485 : // This indicates that there is no supported stencil format for the config.
486 : kUnsupported_StencilFormatIndex = -2
487 : };
488 :
489 : // Index fStencilFormats.
490 : int fStencilFormatIndex;
491 :
492 : enum {
493 : kVerifiedColorAttachment_Flag = 0x1,
494 : kTextureable_Flag = 0x2,
495 : kRenderable_Flag = 0x4,
496 : kRenderableWithMSAA_Flag = 0x8,
497 : /** kFBOColorAttachment means that even if the config cannot be a GrRenderTarget, we can
498 : still attach it to a FBO for blitting or reading pixels. */
499 : kFBOColorAttachment_Flag = 0x10,
500 : kCanUseTexStorage_Flag = 0x20,
501 : kCanUseWithTexelBuffer_Flag = 0x40,
502 : kCanUseAsImageStorage_Flag = 0x80,
503 : };
504 : uint32_t fFlags;
505 :
506 : GrSwizzle fSwizzle;
507 : };
508 :
509 : ConfigInfo fConfigTable[kGrPixelConfigCnt];
510 :
511 : typedef GrCaps INHERITED;
512 : };
513 :
514 : #endif
|