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 | #include "include/private/GrGLTypesPriv.h" |
14 | #include "include/private/SkChecksum.h" |
15 | #include "include/private/SkTArray.h" |
16 | #include "include/private/SkTHash.h" |
17 | #include "src/gpu/GrCaps.h" |
18 | #include "src/gpu/GrSwizzle.h" |
19 | #include "src/gpu/gl/GrGLStencilAttachment.h" |
20 | #include "src/gpu/gl/GrGLUtil.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+, OpenGL ES 3.0+, GL_ARB_framebuffer_object, |
45 | * GL_CHROMIUM_framebuffer_multisample, GL_ANGLE_framebuffer_multisample, |
46 | * or GL_EXT_framebuffer_multisample |
47 | */ |
48 | kStandard_MSFBOType, |
49 | /** |
50 | * GL_APPLE_framebuffer_multisample ES extension |
51 | */ |
52 | kES_Apple_MSFBOType, |
53 | /** |
54 | * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers. |
55 | * Instead the texture is multisampled when bound to the FBO and then resolved automatically |
56 | * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call |
57 | * GR_GL_MAX_SAMPLES_IMG). |
58 | */ |
59 | kES_IMG_MsToTexture_MSFBOType, |
60 | /** |
61 | * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard |
62 | * GL_MAX_SAMPLES value. |
63 | */ |
64 | kES_EXT_MsToTexture_MSFBOType, |
65 | |
66 | kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType |
67 | }; |
68 | |
69 | enum BlitFramebufferFlags { |
70 | kNoSupport_BlitFramebufferFlag = 1 << 0, |
71 | kNoScalingOrMirroring_BlitFramebufferFlag = 1 << 1, |
72 | kResolveMustBeFull_BlitFrambufferFlag = 1 << 2, |
73 | kNoMSAADst_BlitFramebufferFlag = 1 << 3, |
74 | kNoFormatConversion_BlitFramebufferFlag = 1 << 4, |
75 | kNoFormatConversionForMSAASrc_BlitFramebufferFlag = 1 << 5, |
76 | kRectsMustMatchForMSAASrc_BlitFramebufferFlag = 1 << 6, |
77 | }; |
78 | |
79 | enum InvalidateFBType { |
80 | kNone_InvalidateFBType, |
81 | kDiscard_InvalidateFBType, //<! glDiscardFramebuffer() |
82 | kInvalidate_InvalidateFBType, //<! glInvalidateFramebuffer() |
83 | |
84 | kLast_InvalidateFBType = kInvalidate_InvalidateFBType |
85 | }; |
86 | |
87 | enum MapBufferType { |
88 | kNone_MapBufferType, |
89 | kMapBuffer_MapBufferType, // glMapBuffer() |
90 | kMapBufferRange_MapBufferType, // glMapBufferRange() |
91 | kChromium_MapBufferType, // GL_CHROMIUM_map_sub |
92 | |
93 | kLast_MapBufferType = kChromium_MapBufferType, |
94 | }; |
95 | |
96 | enum class TransferBufferType { |
97 | kNone, |
98 | kNV_PBO, // NV__pixel_buffer_object |
99 | kARB_PBO, // ARB_pixel_buffer_object |
100 | kChromium, // CHROMIUM_pixel_transfer_buffer_object |
101 | }; |
102 | |
103 | enum class FenceType { |
104 | kNone, |
105 | kSyncObject, |
106 | kNVFence |
107 | }; |
108 | |
109 | /** |
110 | * Initializes the GrGLCaps to the set of features supported in the current |
111 | * OpenGL context accessible via ctxInfo. |
112 | */ |
113 | GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo, |
114 | const GrGLInterface* glInterface); |
115 | |
116 | bool isFormatSRGB(const GrBackendFormat&) const override; |
117 | |
118 | bool isFormatTexturable(const GrBackendFormat&) const override; |
119 | bool isFormatTexturable(GrGLFormat) const; |
120 | |
121 | bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, |
122 | int sampleCount = 1) const override; |
123 | bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; |
124 | bool isFormatRenderable(GrGLFormat format, int sampleCount) const { |
125 | return sampleCount <= this->maxRenderTargetSampleCount(format); |
126 | } |
127 | |
128 | int getRenderTargetSampleCount(int requestedCount, |
129 | const GrBackendFormat& format) const override { |
130 | return this->getRenderTargetSampleCount(requestedCount, format.asGLFormat()); |
131 | } |
132 | int getRenderTargetSampleCount(int requestedCount, GrGLFormat) const; |
133 | |
134 | int maxRenderTargetSampleCount(const GrBackendFormat& format) const override { |
135 | return this->maxRenderTargetSampleCount(format.asGLFormat()); |
136 | } |
137 | int maxRenderTargetSampleCount(GrGLFormat) const; |
138 | |
139 | size_t bytesPerPixel(GrGLFormat) const; |
140 | size_t bytesPerPixel(const GrBackendFormat&) const override; |
141 | |
142 | bool isFormatCopyable(const GrBackendFormat&) const override; |
143 | |
144 | bool canFormatBeFBOColorAttachment(GrGLFormat) const; |
145 | |
146 | GrGLFormat getFormatFromColorType(GrColorType colorType) const { |
147 | int idx = static_cast<int>(colorType); |
148 | return fColorTypeToFormatTable[idx]; |
149 | } |
150 | |
151 | /** |
152 | * Gets the internal format to use with glTexImage...() and glTexStorage...(). May be sized or |
153 | * base depending upon the GL. Not applicable to compressed textures. |
154 | */ |
155 | GrGLenum getTexImageOrStorageInternalFormat(GrGLFormat format) const { |
156 | return this->getFormatInfo(format).fInternalFormatForTexImageOrStorage; |
157 | } |
158 | |
159 | /** |
160 | * Gets the external format and type to pass to glTexImage2D with nullptr to create an |
161 | * uninitialized texture. See getTexImageOrStorageInternalFormat() for the internal format. |
162 | */ |
163 | void getTexImageExternalFormatAndType(GrGLFormat surfaceFormat, GrGLenum* externalFormat, |
164 | GrGLenum* externalType) const; |
165 | |
166 | /** |
167 | * Given a src data color type and a color type interpretation for a texture of a given format |
168 | * this provides the external GL format and type to use with glTexSubImage2d. The color types |
169 | * should originate from supportedWritePixelsColorType(). |
170 | */ |
171 | void getTexSubImageExternalFormatAndType(GrGLFormat surfaceFormat, GrColorType surfaceColorType, |
172 | GrColorType memoryColorType, GrGLenum* externalFormat, |
173 | GrGLenum* externalType) const; |
174 | |
175 | /** |
176 | * Gets the external format, type, and bytes per pixel to use when uploading solid color data |
177 | * via glTexSubImage...() to clear the texture at creation. |
178 | */ |
179 | void getTexSubImageDefaultFormatTypeAndColorType(GrGLFormat format, |
180 | GrGLenum* externalFormat, |
181 | GrGLenum* externalType, |
182 | GrColorType* colorType) const; |
183 | |
184 | void getReadPixelsFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType, |
185 | GrColorType memoryColorType, GrGLenum* externalFormat, |
186 | GrGLenum* externalType) const; |
187 | |
188 | /** |
189 | * Gets an array of legal stencil formats. These formats are not guaranteed |
190 | * to be supported by the driver but are legal GLenum names given the GL |
191 | * version and extensions supported. |
192 | */ |
193 | const SkTArray<StencilFormat, true>& stencilFormats() const { |
194 | return fStencilFormats; |
195 | } |
196 | |
197 | bool formatSupportsTexStorage(GrGLFormat) const; |
198 | |
199 | /** |
200 | * Would it be useful to check GL_IMPLEMENTATION_READ_FORMAT and _TYPE for this format to |
201 | * detect more efficient glReadPixels arguments? |
202 | */ |
203 | bool shouldQueryImplementationReadSupport(GrGLFormat format) const; |
204 | |
205 | /** |
206 | * Let caps know the result of GL_IMPLEMENTATION_READ_FORMAT and _TYPE query for a format |
207 | * to update supported glReadPixels arguments. |
208 | */ |
209 | void didQueryImplementationReadSupport(GrGLFormat format, |
210 | GrGLenum readFormat, |
211 | GrGLenum readType) const; |
212 | |
213 | /** |
214 | * Gets the internal format to use with glRenderbufferStorageMultisample...(). May be sized or |
215 | * base depending upon the GL. Not applicable to compressed textures. |
216 | */ |
217 | GrGLenum getRenderbufferInternalFormat(GrGLFormat format) const { |
218 | return this->getFormatInfo(format).fInternalFormatForRenderbuffer; |
219 | } |
220 | |
221 | /** |
222 | * Gets the default external type to use with glTex[Sub]Image... when the data pointer is null. |
223 | */ |
224 | GrGLenum getFormatDefaultExternalType(GrGLFormat format) const { |
225 | return this->getFormatInfo(format).fDefaultExternalType; |
226 | } |
227 | |
228 | /** |
229 | * Has a stencil format index been found for the format (or we've found that no format works). |
230 | */ |
231 | bool hasStencilFormatBeenDeterminedForFormat(GrGLFormat format) const { |
232 | return this->getFormatInfo(format).fStencilFormatIndex != FormatInfo::kUnknown_StencilIndex; |
233 | } |
234 | |
235 | /** |
236 | * Gets the stencil format index for the format. This assumes |
237 | * hasStencilFormatBeenDeterminedForFormat has already been checked. Returns a value < 0 if |
238 | * no stencil format is supported with the format. Otherwise, returned index refers to the array |
239 | * returned by stencilFormats(). |
240 | */ |
241 | int getStencilFormatIndexForFormat(GrGLFormat format) const { |
242 | SkASSERT(this->hasStencilFormatBeenDeterminedForFormat(format)); |
243 | return this->getFormatInfo(format).fStencilFormatIndex; |
244 | } |
245 | |
246 | /** |
247 | * If index is >= 0 this records an index into stencilFormats() as the best stencil format for |
248 | * the format. If < 0 it records that the format has no supported stencil format index. |
249 | */ |
250 | void setStencilFormatIndexForFormat(GrGLFormat, int index); |
251 | |
252 | /** |
253 | * Reports the type of MSAA FBO support. |
254 | */ |
255 | MSFBOType msFBOType() const { return fMSFBOType; } |
256 | |
257 | /** |
258 | * Does the preferred MSAA FBO extension have MSAA renderbuffers? |
259 | */ |
260 | bool usesMSAARenderBuffers() const { |
261 | return kNone_MSFBOType != fMSFBOType && |
262 | kES_IMG_MsToTexture_MSFBOType != fMSFBOType && |
263 | kES_EXT_MsToTexture_MSFBOType != fMSFBOType; |
264 | } |
265 | |
266 | /** |
267 | * What functionality is supported by glBlitFramebuffer. |
268 | */ |
269 | uint32_t blitFramebufferSupportFlags() const { return fBlitFramebufferFlags; } |
270 | |
271 | /** |
272 | * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and |
273 | * then implicitly resolved when read. |
274 | */ |
275 | bool usesImplicitMSAAResolve() const { |
276 | return kES_IMG_MsToTexture_MSFBOType == fMSFBOType || |
277 | kES_EXT_MsToTexture_MSFBOType == fMSFBOType; |
278 | } |
279 | |
280 | InvalidateFBType invalidateFBType() const { return fInvalidateFBType; } |
281 | |
282 | /// What type of buffer mapping is supported? |
283 | MapBufferType mapBufferType() const { return fMapBufferType; } |
284 | |
285 | /// What type of transfer buffer is supported? |
286 | TransferBufferType transferBufferType() const { return fTransferBufferType; } |
287 | |
288 | /// How are GrFences implemented? |
289 | FenceType fenceType() const { return fFenceType; } |
290 | |
291 | /// The maximum number of fragment uniform vectors (GLES has min. 16). |
292 | int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; } |
293 | |
294 | /// Is there support for GL_PACK_REVERSE_ROW_ORDER |
295 | bool packFlipYSupport() const { return fPackFlipYSupport; } |
296 | |
297 | /// Is there support for texture parameter GL_TEXTURE_USAGE |
298 | bool textureUsageSupport() const { return fTextureUsageSupport; } |
299 | |
300 | /// Is GL_ARB_IMAGING supported |
301 | bool imagingSupport() const { return fImagingSupport; } |
302 | |
303 | /// Is there support for Vertex Array Objects? |
304 | bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; } |
305 | |
306 | /// Is there support for GL_KHR_debug? |
307 | bool debugSupport() const { return fDebugSupport; } |
308 | |
309 | /// Is there support for ES2 compatability? |
310 | bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; } |
311 | |
312 | /// Is there support for GL_ANGLE_base_vertex_base_instance? |
313 | bool ANGLEMultiDrawSupport() const { return fANGLEMultiDrawSupport; } |
314 | |
315 | /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect |
316 | /// draw commands cannot be used unless we have base instance support. |
317 | bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; } |
318 | |
319 | /// Is there support for glDrawRangeElements? |
320 | bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; } |
321 | |
322 | /// Are the glDraw*Base(VertexBase)Instance methods, and baseInstance fields in indirect draw |
323 | //commands supported? |
324 | bool baseVertexBaseInstanceSupport() const { return fBaseVertexBaseInstanceSupport; } |
325 | |
326 | /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content. |
327 | bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; } |
328 | |
329 | SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override; |
330 | |
331 | SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, |
332 | const GrBackendFormat& surfaceFormat, |
333 | GrColorType srcColorType) const override; |
334 | |
335 | bool isCoreProfile() const { return fIsCoreProfile; } |
336 | |
337 | bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; } |
338 | |
339 | bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; } |
340 | |
341 | /// Are textures with GL_TEXTURE_RECTANGLE type supported. |
342 | bool rectangleTextureSupport() const { return fRectangleTextureSupport; } |
343 | |
344 | bool mipmapLevelAndLodControlSupport() const { return fMipmapLevelAndLodControlSupport; } |
345 | |
346 | bool doManualMipmapping() const { return fDoManualMipmapping; } |
347 | |
348 | void onDumpJSON(SkJSONWriter*) const override; |
349 | |
350 | bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; } |
351 | bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; } |
352 | bool rgbaToBgraReadbackConversionsAreSlow() const { |
353 | return fRGBAToBGRAReadbackConversionsAreSlow; |
354 | } |
355 | |
356 | bool useBufferDataNullHint() const { return fUseBufferDataNullHint; } |
357 | |
358 | // Certain Intel GPUs on Mac fail to clear if the glClearColor is made up of only 1s and 0s. |
359 | bool clearToBoundaryValuesIsBroken() const { return fClearToBoundaryValuesIsBroken; } |
360 | |
361 | /// glClearTex(Sub)Image support |
362 | bool clearTextureSupport() const { return fClearTextureSupport; } |
363 | |
364 | // Adreno/MSAA drops a draw on the imagefiltersbase GM if the base vertex param to |
365 | // glDrawArrays is nonzero. |
366 | // https://bugs.chromium.org/p/skia/issues/detail?id=6650 |
367 | bool drawArraysBaseVertexIsBroken() const { return fDrawArraysBaseVertexIsBroken; } |
368 | |
369 | // If true then we must use an intermediate surface to perform partial updates to unorm textures |
370 | // that have ever been bound to a FBO. |
371 | bool disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() const { |
372 | return fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO; |
373 | } |
374 | |
375 | // Use an intermediate surface to write pixels (full or partial overwrite) to into a texture |
376 | // that is bound to an FBO. |
377 | bool useDrawInsteadOfAllRenderTargetWrites() const { |
378 | return fUseDrawInsteadOfAllRenderTargetWrites; |
379 | } |
380 | |
381 | // At least some Adreno 3xx drivers draw lines incorrectly after drawing non-lines. Toggling |
382 | // face culling on and off seems to resolve this. |
383 | bool requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() const { |
384 | return fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines; |
385 | } |
386 | |
387 | // Some Adreno drivers refuse to ReadPixels from an MSAA buffer that has stencil attached. |
388 | bool detachStencilFromMSAABuffersBeforeReadPixels() const { |
389 | return fDetachStencilFromMSAABuffersBeforeReadPixels; |
390 | } |
391 | |
392 | // Older Android versions seem to have an issue with setting GL_TEXTURE_BASE_LEVEL or |
393 | // GL_TEXTURE_MAX_LEVEL for GL_TEXTURE_EXTERNAL_OES textures. |
394 | bool dontSetBaseOrMaxLevelForExternalTextures() const { |
395 | return fDontSetBaseOrMaxLevelForExternalTextures; |
396 | } |
397 | |
398 | // PowerVRGX6250 drops every pixel if we modify the sample mask while color writes are disabled. |
399 | bool neverDisableColorWrites() const { return fNeverDisableColorWrites; } |
400 | |
401 | // Texture parameters must be used to enable MIP mapping even when a sampler object is used. |
402 | bool mustSetAnyTexParameterToEnableMipmapping() const { |
403 | return fMustSetAnyTexParameterToEnableMipmapping; |
404 | } |
405 | |
406 | // Returns the observed maximum number of instances the driver can handle in a single draw call |
407 | // without crashing, or 'pendingInstanceCount' if this workaround is not necessary. |
408 | // NOTE: the return value may be larger than pendingInstanceCount. |
409 | int maxInstancesPerDrawWithoutCrashing(int pendingInstanceCount) const { |
410 | return (fMaxInstancesPerDrawWithoutCrashing) |
411 | ? fMaxInstancesPerDrawWithoutCrashing : pendingInstanceCount; |
412 | } |
413 | |
414 | bool canCopyTexSubImage(GrGLFormat dstFormat, bool dstHasMSAARenderBuffer, |
415 | const GrTextureType* dstTypeIfTexture, |
416 | GrGLFormat srcFormat, bool srcHasMSAARenderBuffer, |
417 | const GrTextureType* srcTypeIfTexture) const; |
418 | bool canCopyAsBlit(GrGLFormat dstFormat, int dstSampleCnt, |
419 | const GrTextureType* dstTypeIfTexture, |
420 | GrGLFormat srcFormat, int srcSampleCnt, |
421 | const GrTextureType* srcTypeIfTexture, |
422 | const SkRect& srcBounds, bool srcBoundsExact, |
423 | const SkIRect& srcRect, const SkIPoint& dstPoint) const; |
424 | bool canCopyAsDraw(GrGLFormat dstFormat, bool srcIsTexturable) const; |
425 | |
426 | DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src, |
427 | GrColorType) const override; |
428 | |
429 | bool programBinarySupport() const { return fProgramBinarySupport; } |
430 | bool programParameterSupport() const { return fProgramParameterSupport; } |
431 | |
432 | bool samplerObjectSupport() const { return fSamplerObjectSupport; } |
433 | |
434 | bool tiledRenderingSupport() const { return fTiledRenderingSupport; } |
435 | |
436 | bool fbFetchRequiresEnablePerSample() const { return fFBFetchRequiresEnablePerSample; } |
437 | |
438 | /* Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? */ |
439 | bool srgbWriteControl() const { return fSRGBWriteControl; } |
440 | |
441 | /** Skip checks for GL errors, shader compilation success, program link success. */ |
442 | bool skipErrorChecks() const { return fSkipErrorChecks; } |
443 | |
444 | GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; |
445 | |
446 | GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override; |
447 | |
448 | uint64_t computeFormatKey(const GrBackendFormat&) const override; |
449 | |
450 | GrProgramDesc makeDesc(GrRenderTarget*, const GrProgramInfo&) const override; |
451 | |
452 | #if GR_TEST_UTILS |
453 | GrGLStandard standard() const { return fStandard; } |
454 | |
455 | std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override; |
456 | #endif |
457 | |
458 | private: |
459 | enum ExternalFormatUsage { |
460 | kTexImage_ExternalFormatUsage, |
461 | kReadPixels_ExternalFormatUsage, |
462 | }; |
463 | void getExternalFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType, |
464 | GrColorType memoryColorType, ExternalFormatUsage usage, |
465 | GrGLenum* externalFormat, GrGLenum* externalType) const; |
466 | |
467 | void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*); |
468 | void initGLSL(const GrGLContextInfo&, const GrGLInterface*); |
469 | bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*); |
470 | |
471 | struct FormatWorkarounds { |
472 | bool fDisableSRGBRenderWithMSAAForMacAMD = false; |
473 | bool fDisableRGBA16FTexStorageForCrBug1008003 = false; |
474 | bool fDisableBGRATextureStorageForIntelWindowsES = false; |
475 | bool fDisableRGB8ForMali400 = false; |
476 | bool fDisableLuminance16F = false; |
477 | bool fDontDisableTexStorageOnAndroid = false; |
478 | bool fDisallowDirectRG8ReadPixels = false; |
479 | bool fDisallowBGRA8ReadPixels = false; |
480 | }; |
481 | |
482 | void applyDriverCorrectnessWorkarounds(const GrGLContextInfo&, const GrContextOptions&, |
483 | const GrGLInterface*, |
484 | GrShaderCaps*, FormatWorkarounds*); |
485 | |
486 | void onApplyOptionsOverrides(const GrContextOptions& options) override; |
487 | |
488 | bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const override; |
489 | |
490 | void initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo&, |
491 | const GrGLInterface*); |
492 | void initBlendEqationSupport(const GrGLContextInfo&); |
493 | void initStencilSupport(const GrGLContextInfo&); |
494 | // This must be called after initFSAASupport(). |
495 | void initFormatTable(const GrGLContextInfo&, const GrGLInterface*, const FormatWorkarounds&); |
496 | void setupSampleCounts(const GrGLContextInfo&, const GrGLInterface*); |
497 | bool onSurfaceSupportsWritePixels(const GrSurface*) const override; |
498 | bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, |
499 | const SkIRect& srcRect, const SkIPoint& dstPoint) const override; |
500 | GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override; |
501 | bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; |
502 | |
503 | SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, |
504 | GrColorType) const override; |
505 | |
506 | GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override; |
507 | |
508 | GrGLStandard fStandard = kNone_GrGLStandard; |
509 | |
510 | SkTArray<StencilFormat, true> fStencilFormats; |
511 | |
512 | int fMaxFragmentUniformVectors = 0; |
513 | |
514 | MSFBOType fMSFBOType = kNone_MSFBOType; |
515 | InvalidateFBType fInvalidateFBType = kNone_InvalidateFBType; |
516 | MapBufferType fMapBufferType = kNone_MapBufferType; |
517 | TransferBufferType fTransferBufferType = TransferBufferType::kNone; |
518 | FenceType fFenceType = FenceType::kNone; |
519 | |
520 | bool fPackFlipYSupport : 1; |
521 | bool fTextureUsageSupport : 1; |
522 | bool fImagingSupport : 1; |
523 | bool fVertexArrayObjectSupport : 1; |
524 | bool fDebugSupport : 1; |
525 | bool fES2CompatibilitySupport : 1; |
526 | bool fDrawRangeElementsSupport : 1; |
527 | bool fANGLEMultiDrawSupport : 1; |
528 | bool fMultiDrawIndirectSupport : 1; |
529 | bool fBaseVertexBaseInstanceSupport : 1; |
530 | bool fUseNonVBOVertexAndIndexDynamicData : 1; |
531 | bool fIsCoreProfile : 1; |
532 | bool fBindFragDataLocationSupport : 1; |
533 | bool fRGBA8888PixelsOpsAreSlow : 1; |
534 | bool fPartialFBOReadIsSlow : 1; |
535 | bool fBindUniformLocationSupport : 1; |
536 | bool fRectangleTextureSupport : 1; |
537 | bool fMipmapLevelAndLodControlSupport : 1; |
538 | bool fRGBAToBGRAReadbackConversionsAreSlow : 1; |
539 | bool fUseBufferDataNullHint : 1; |
540 | bool fClearTextureSupport : 1; |
541 | bool fProgramBinarySupport : 1; |
542 | bool fProgramParameterSupport : 1; |
543 | bool fSamplerObjectSupport : 1; |
544 | bool fTiledRenderingSupport : 1; |
545 | bool fFBFetchRequiresEnablePerSample : 1; |
546 | bool fSRGBWriteControl : 1; |
547 | bool fSkipErrorChecks : 1; |
548 | |
549 | // Driver workarounds |
550 | bool fDoManualMipmapping : 1; |
551 | bool fClearToBoundaryValuesIsBroken : 1; |
552 | bool fDrawArraysBaseVertexIsBroken : 1; |
553 | bool fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO : 1; |
554 | bool fUseDrawInsteadOfAllRenderTargetWrites : 1; |
555 | bool fRequiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines : 1; |
556 | bool fDetachStencilFromMSAABuffersBeforeReadPixels : 1; |
557 | bool fDontSetBaseOrMaxLevelForExternalTextures : 1; |
558 | bool fNeverDisableColorWrites : 1; |
559 | bool fMustSetAnyTexParameterToEnableMipmapping : 1; |
560 | int fMaxInstancesPerDrawWithoutCrashing = 0; |
561 | |
562 | uint32_t fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag; |
563 | |
564 | struct ReadPixelsFormat { |
565 | ReadPixelsFormat() : fFormat(0), fType(0) {} |
566 | GrGLenum fFormat; |
567 | GrGLenum fType; |
568 | }; |
569 | |
570 | /** Number type of the components (with out considering number of bits.) */ |
571 | enum class FormatType { |
572 | kUnknown, |
573 | kNormalizedFixedPoint, |
574 | kFloat, |
575 | }; |
576 | |
577 | // ColorTypeInfo for a specific format |
578 | struct ColorTypeInfo { |
579 | GrColorType fColorType = GrColorType::kUnknown; |
580 | enum { |
581 | kUploadData_Flag = 0x1, |
582 | // Does Ganesh itself support rendering to this colorType & format pair. Renderability |
583 | // still additionally depends on if the format can be an FBO color attachment. |
584 | kRenderable_Flag = 0x2, |
585 | }; |
586 | uint32_t fFlags = 0; |
587 | |
588 | GrSwizzle fReadSwizzle; |
589 | GrSwizzle fWriteSwizzle; |
590 | |
591 | struct ExternalIOFormats { |
592 | GrColorType fColorType = GrColorType::kUnknown; |
593 | |
594 | /** The external format and type are to be used when uploading/downloading data using |
595 | data of fColorType and uploading to a texture of a given GrGLFormat and its |
596 | intended GrColorType. The fExternalTexImageFormat is the format to use for TexImage |
597 | calls. The fExternalReadFormat is used when calling ReadPixels. If either is zero |
598 | that signals that either TexImage or ReadPixels is not supported for the combination |
599 | of format and color types. */ |
600 | GrGLenum fExternalType = 0; |
601 | GrGLenum fExternalTexImageFormat = 0; |
602 | GrGLenum fExternalReadFormat = 0; |
603 | /** |
604 | * Must check whether GL_IMPLEMENTATION_COLOR_READ_FORMAT and _TYPE match |
605 | * fExternalReadFormat and fExternalType before using with glReadPixels. |
606 | */ |
607 | bool fRequiresImplementationReadQuery = false; |
608 | }; |
609 | |
610 | GrGLenum externalFormat(GrColorType externalColorType, ExternalFormatUsage usage, |
611 | bool haveQueriedImplementationReadFormat) const { |
612 | for (int i = 0; i < fExternalIOFormatCount; ++i) { |
613 | if (fExternalIOFormats[i].fColorType == externalColorType) { |
614 | if (usage == kTexImage_ExternalFormatUsage) { |
615 | return fExternalIOFormats[i].fExternalTexImageFormat; |
616 | } else { |
617 | SkASSERT(usage == kReadPixels_ExternalFormatUsage); |
618 | if (!haveQueriedImplementationReadFormat && |
619 | fExternalIOFormats[i].fRequiresImplementationReadQuery) { |
620 | return 0; |
621 | } |
622 | return fExternalIOFormats[i].fExternalReadFormat; |
623 | } |
624 | } |
625 | } |
626 | return 0; |
627 | } |
628 | |
629 | GrGLenum externalType(GrColorType externalColorType) const { |
630 | for (int i = 0; i < fExternalIOFormatCount; ++i) { |
631 | if (fExternalIOFormats[i].fColorType == externalColorType) { |
632 | return fExternalIOFormats[i].fExternalType; |
633 | } |
634 | } |
635 | return 0; |
636 | } |
637 | |
638 | std::unique_ptr<ExternalIOFormats[]> fExternalIOFormats; |
639 | int fExternalIOFormatCount = 0; |
640 | }; |
641 | |
642 | struct FormatInfo { |
643 | uint32_t colorTypeFlags(GrColorType colorType) const { |
644 | for (int i = 0; i < fColorTypeInfoCount; ++i) { |
645 | if (fColorTypeInfos[i].fColorType == colorType) { |
646 | return fColorTypeInfos[i].fFlags; |
647 | } |
648 | } |
649 | return 0; |
650 | } |
651 | |
652 | GrGLenum externalFormat(GrColorType surfaceColorType, GrColorType externalColorType, |
653 | ExternalFormatUsage usage) const { |
654 | for (int i = 0; i < fColorTypeInfoCount; ++i) { |
655 | if (fColorTypeInfos[i].fColorType == surfaceColorType) { |
656 | return fColorTypeInfos[i].externalFormat(externalColorType, usage, |
657 | fHaveQueriedImplementationReadSupport); |
658 | } |
659 | } |
660 | return 0; |
661 | } |
662 | |
663 | GrGLenum externalType(GrColorType surfaceColorType, GrColorType externalColorType) const { |
664 | for (int i = 0; i < fColorTypeInfoCount; ++i) { |
665 | if (fColorTypeInfos[i].fColorType == surfaceColorType) { |
666 | return fColorTypeInfos[i].externalType(externalColorType); |
667 | } |
668 | } |
669 | return 0; |
670 | } |
671 | |
672 | enum { |
673 | kTexturable_Flag = 0x1, |
674 | /** kFBOColorAttachment means that even if the format cannot be a GrRenderTarget, we can |
675 | still attach it to a FBO for blitting or reading pixels. */ |
676 | kFBOColorAttachment_Flag = 0x2, |
677 | kFBOColorAttachmentWithMSAA_Flag = 0x4, |
678 | kUseTexStorage_Flag = 0x8, |
679 | }; |
680 | uint32_t fFlags = 0; |
681 | |
682 | FormatType fFormatType = FormatType::kUnknown; |
683 | |
684 | // Not defined for uncompressed formats. Passed to glCompressedTexImage... |
685 | GrGLenum fCompressedInternalFormat = 0; |
686 | |
687 | // Value to uses as the "internalformat" argument to glTexImage or glTexStorage. It is |
688 | // initialized in coordination with the presence/absence of the kUseTexStorage flag. In |
689 | // other words, it is only guaranteed to be compatible with glTexImage if the flag is not |
690 | // set and or with glTexStorage if the flag is set. |
691 | GrGLenum fInternalFormatForTexImageOrStorage = 0; |
692 | |
693 | // Value to uses as the "internalformat" argument to glRenderbufferStorageMultisample... |
694 | GrGLenum fInternalFormatForRenderbuffer = 0; |
695 | |
696 | // Default values to use along with fInternalFormatForTexImageOrStorage for function |
697 | // glTexImage2D when not input providing data (passing nullptr) or when clearing it by |
698 | // uploading a block of solid color data. Not defined for compressed formats. |
699 | GrGLenum fDefaultExternalFormat = 0; |
700 | GrGLenum fDefaultExternalType = 0; |
701 | // When the above two values are used to initialize a texture by uploading cleared data to |
702 | // it the data should be of this color type. |
703 | GrColorType fDefaultColorType = GrColorType::kUnknown; |
704 | // This value is only valid for regular formats. Compressed formats will be 0. |
705 | GrGLenum fBytesPerPixel = 0; |
706 | |
707 | bool fHaveQueriedImplementationReadSupport = false; |
708 | |
709 | enum { |
710 | // This indicates that a stencil format has not yet been determined for the config. |
711 | kUnknown_StencilIndex = -1, |
712 | // This indicates that there is no supported stencil format for the config. |
713 | kUnsupported_StencilFormatIndex = -2 |
714 | }; |
715 | |
716 | // Index fStencilFormats. |
717 | int fStencilFormatIndex = kUnknown_StencilIndex; |
718 | |
719 | SkTDArray<int> fColorSampleCounts; |
720 | |
721 | std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; |
722 | int fColorTypeInfoCount = 0; |
723 | }; |
724 | |
725 | FormatInfo fFormatTable[kGrGLFormatCount]; |
726 | |
727 | FormatInfo& getFormatInfo(GrGLFormat format) { return fFormatTable[static_cast<int>(format)]; } |
728 | const FormatInfo& getFormatInfo(GrGLFormat format) const { |
729 | return fFormatTable[static_cast<int>(format)]; |
730 | } |
731 | |
732 | GrGLFormat fColorTypeToFormatTable[kGrColorTypeCnt]; |
733 | void setColorTypeFormat(GrColorType, GrGLFormat); |
734 | |
735 | typedef GrCaps INHERITED; |
736 | }; |
737 | |
738 | #endif |
739 | |