Flutter Impeller
capabilities_gles.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <algorithm>
8 
11 
12 namespace impeller {
13 
14 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_shader_framebuffer_fetch.txt
15 static const constexpr char* kFramebufferFetchExt =
16  "GL_EXT_shader_framebuffer_fetch";
17 
18 static const constexpr char* kTextureBorderClampExt =
19  "GL_EXT_texture_border_clamp";
20 static const constexpr char* kNvidiaTextureBorderClampExt =
21  "GL_NV_texture_border_clamp";
22 
23 // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_multisampled_render_to_texture.txt
24 static const constexpr char* kMultisampledRenderToTextureExt =
25  "GL_EXT_multisampled_render_to_texture";
26 
27 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_multisampled_render_to_texture2.txt
28 static const constexpr char* kMultisampledRenderToTexture2Ext =
29  "GL_EXT_multisampled_render_to_texture2";
30 
31 // https://registry.khronos.org/OpenGL/extensions/OES/OES_element_index_uint.txt
32 static const constexpr char* kElementIndexUintExt = "GL_OES_element_index_uint";
33 
34 // The BC family spans three separate OpenGL ES extensions: S3TC (BC1-BC3),
35 // RGTC (BC5), and BPTC (BC7). All three are required to report kBC support.
36 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_compression_s3tc.txt
37 static const constexpr char* kTextureCompressionS3TCExt =
38  "GL_EXT_texture_compression_s3tc";
39 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_compression_rgtc.txt
40 static const constexpr char* kTextureCompressionRGTCExt =
41  "GL_EXT_texture_compression_rgtc";
42 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_compression_bptc.txt
43 static const constexpr char* kTextureCompressionBPTCExt =
44  "GL_EXT_texture_compression_bptc";
45 
46 // https://registry.khronos.org/OpenGL/extensions/KHR/KHR_texture_compression_astc_hdr.txt
47 static const constexpr char* kTextureCompressionAstcLdrExt =
48  "GL_KHR_texture_compression_astc_ldr";
49 // https://registry.khronos.org/OpenGL/extensions/OES/OES_texture_compression_astc.txt
50 static const constexpr char* kTextureCompressionAstcOesExt =
51  "GL_OES_texture_compression_astc";
52 // https://registry.khronos.org/OpenGL/extensions/KHR/KHR_texture_compression_astc_hdr.txt
53 static const constexpr char* kTextureCompressionAstcHdrExt =
54  "GL_KHR_texture_compression_astc_hdr";
55 
56 // https://registry.khronos.org/OpenGL/extensions/APPLE/APPLE_texture_max_level.txt
57 static const constexpr char* kAppleTextureMaxLevelExt =
58  "GL_APPLE_texture_max_level";
59 
60 // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_filter_anisotropic.txt
61 static const constexpr char* kTextureFilterAnisotropicExt =
62  "GL_EXT_texture_filter_anisotropic";
63 
65  {
66  GLint value = 0;
67  gl.GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value);
69  }
70 
71  {
72  GLint value = 0;
73  gl.GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &value);
75  }
76 
77  auto const desc = gl.GetDescription();
78 
79  if (desc->IsES()) {
80  GLint value = 0;
81  gl.GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &value);
83  }
84 
85  {
86  GLint value = 0;
87  gl.GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &value);
89  }
90 
91  {
92  GLint value = 0;
93  gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &value);
95  }
96 
97  {
98  GLint value = 0;
99  gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
101  }
102 
103  if (desc->IsES()) {
104  GLint value = 0;
105  gl.GetIntegerv(GL_MAX_VARYING_VECTORS, &value);
107  }
108 
109  {
110  GLint value = 0;
111  gl.GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
113  }
114 
115  {
116  GLint value = 0;
117  gl.GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &value);
119  }
120 
121  if (desc->IsES()) {
122  GLint value = 0;
123  gl.GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &value);
125  }
126 
127  {
128  GLint values[2] = {};
129  gl.GetIntegerv(GL_MAX_VIEWPORT_DIMS, values);
130  max_viewport_dims = ISize{values[0], values[1]};
131  }
132 
133  {
134  GLint value = 0;
135  gl.GetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &value);
137  }
138 
139  if (desc->IsES()) {
140  GLint value = 0;
141  gl.GetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &value);
143  }
144 
145  if (desc->IsES()) {
146  default_glyph_atlas_format_ = PixelFormat::kA8UNormInt;
147  } else {
148  default_glyph_atlas_format_ = PixelFormat::kR8UNormInt;
149  }
150 
151  if (desc->GetGlVersion().major_version >= 3) {
152  supports_texture_to_texture_blits_ = true;
153  }
154 
155  supports_framebuffer_fetch_ = desc->HasExtension(kFramebufferFetchExt);
156 
157  if (desc->HasExtension(kTextureBorderClampExt) ||
158  desc->HasExtension(kNvidiaTextureBorderClampExt)) {
159  supports_decal_sampler_address_mode_ = true;
160  }
161 
162  if (desc->HasExtension(kElementIndexUintExt)) {
163  supports_32bit_primitive_indices_ = true;
164  }
165 
166  if (desc->HasExtension(kMultisampledRenderToTextureExt)) {
167  supports_implicit_msaa_ = true;
168 
169  if (desc->HasExtension(kMultisampledRenderToTexture2Ext)) {
170  // We hard-code 4x MSAA, so let's make sure it's supported.
171  GLint value = 0;
172  gl.GetIntegerv(GL_MAX_SAMPLES_EXT, &value);
173  supports_offscreen_msaa_ = value >= 4;
174  }
175  } else if (desc->GetGlVersion().major_version >= 3 && desc->IsES()) {
176  GLint value = 0;
177  gl.GetIntegerv(GL_MAX_SAMPLES, &value);
178  supports_offscreen_msaa_ = value >= 4;
179  }
180  is_es_ = desc->IsES();
181  is_angle_ = desc->IsANGLE();
182 
183  // ETC2 and EAC are mandatory in OpenGL ES 3.0. BC and ASTC are gated behind
184  // extensions and are not present on most mobile or desktop GLES. The whole BC
185  // family requires S3TC, RGTC, and BPTC to all be present.
186  supports_texture_compression_bc_ =
187  desc->HasExtension(kTextureCompressionS3TCExt) &&
188  desc->HasExtension(kTextureCompressionRGTCExt) &&
189  desc->HasExtension(kTextureCompressionBPTCExt);
190  // Either extension is sufficient: both expose the same LDR 2D ASTC internal
191  // formats this backend uses. KHR is the common one; OES is a superset that
192  // also adds HDR and 3D, which are not used here.
193  supports_texture_compression_astc_ =
194  desc->HasExtension(kTextureCompressionAstcLdrExt) ||
195  desc->HasExtension(kTextureCompressionAstcOesExt);
196  // HDR reuses the same internal formats as LDR, gated by a separate extension.
197  // The OES extension is a superset that also covers HDR.
198  supports_texture_compression_astc_hdr_ =
199  desc->HasExtension(kTextureCompressionAstcHdrExt) ||
200  desc->HasExtension(kTextureCompressionAstcOesExt);
201  supports_texture_compression_etc2_ =
202  desc->IsES() && desc->GetGlVersion().major_version >= 3;
203 
204  // GL_TEXTURE_MAX_LEVEL is core on desktop GL and ES 3.0+, and available on
205  // ES 2.0 through GL_APPLE_texture_max_level.
206  supports_texture_max_level_ = !desc->IsES() ||
207  desc->GetGlVersion().major_version >= 3 ||
208  desc->HasExtension(kAppleTextureMaxLevelExt);
209 
210  // Anisotropic filtering is not part of any core GL or GLES version; it is
211  // always gated on GL_EXT_texture_filter_anisotropic. The query and the
212  // texture parameter are applied with core ES 2.0 entry points (GetFloatv
213  // and TexParameterfv), so only the extension check is needed here.
214  if (desc->HasExtension(kTextureFilterAnisotropicExt)) {
215  GLfloat value = 1.0f;
217  // The extension guarantees a maximum of at least 2. The limit is a float
218  // but is always an integer in practice, so floor it.
219  max_sampler_anisotropy_ = static_cast<uint32_t>(std::max(value, 2.0f));
220  }
221 }
222 
224  return is_es_;
225 }
226 
228  // Rendering into a non-zero mip level is not yet supported on the GLES
229  // backend. The texture storage path allocates levels with mutable, lazily
230  // allocated glTexImage2D storage, which yields an incomplete framebuffer
231  // when a non-base mip level is attached. Until that is reworked, do not
232  // advertise the capability so callers fall back instead of failing to
233  // create the framebuffer. Rendering into a cube map face is unaffected.
234  return false;
235 }
236 
238  return supports_texture_max_level_;
239 }
240 
242  switch (stage) {
249  return 0u;
250  }
251  FML_UNREACHABLE();
252 }
253 
255  return supports_offscreen_msaa_;
256 }
257 
259  return supports_implicit_msaa_;
260 }
261 
263  return false;
264 }
265 
267  return supports_texture_to_texture_blits_;
268 }
269 
271  return supports_framebuffer_fetch_;
272 }
273 
275  return false;
276 }
277 
279  return false;
280 }
281 
283  return false;
284 }
285 
287  return supports_decal_sampler_address_mode_;
288 }
289 
291  return false;
292 }
293 
295  return true;
296 }
297 
300 }
301 
303  return PixelFormat::kS8UInt;
304 }
305 
308 }
309 
311  return is_angle_;
312 }
313 
315  return false;
316 }
317 
319  return supports_32bit_primitive_indices_;
320 }
321 
323  // Without GL_TEXTURE_MAX_LEVEL the sampled mip range cannot be bounded to
324  // the levels the texture declares, so a hand-uploaded chain is mipmap
325  // incomplete and samples as black.
326  return supports_texture_max_level_;
327 }
328 
330  return false;
331 }
332 
334  CompressedTextureFamily family) const {
335  switch (family) {
337  return supports_texture_compression_bc_;
339  return supports_texture_compression_etc2_;
341  return supports_texture_compression_astc_;
343  return supports_texture_compression_astc_hdr_;
344  }
345  return false;
346 }
347 
349  return default_glyph_atlas_format_;
350 }
351 
353  return max_texture_size;
354 }
355 
357  return max_sampler_anisotropy_;
358 }
359 
361  return 256;
362 }
363 
365 #ifdef FML_OS_EMSCRIPTEN
366  // WebGL has special requirements here to keep indexes and other data
367  // separate. See
368  // https://registry.khronos.org/webgl/specs/latest/2.0/#BUFFER_OBJECT_BINDING
369  return true;
370 #else
371  return false;
372 #endif
373 }
374 
375 } // namespace impeller
bool IsES() const
Whether this is an ES GL variant or (if false) desktop GL.
bool SupportsImplicitResolvingMSAA() const override
Whether the context backend supports multisampled rendering to the on-screen surface without requirin...
PixelFormat GetDefaultDepthStencilFormat() const override
Returns a supported PixelFormat for textures that store both a stencil and depth component....
PixelFormat GetDefaultColorFormat() const override
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
bool SupportsSSBO() const override
Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.
bool SupportsTextureToTextureBlits() const override
Whether the context backend supports blitting from one texture region to another texture region (via ...
ISize GetMaximumRenderPassAttachmentSize() const override
Return the maximum size of a render pass attachment.
bool SupportsFramebufferRenderMipmap() const override
CapabilitiesGLES(const ProcTableGLES &gl)
bool SupportsPrimitiveRestart() const override
Whether primitive restart is supported.
size_t GetMaxTextureUnits(ShaderStage stage) const
bool NeedsPartitionedHostBuffer() const override
Whether the host buffer should use separate device buffers for indexes from other data.
bool SupportsTriangleFan() const override
Whether the primitive type TriangleFan is supported by the backend.
bool Supports32BitPrimitiveIndices() const override
Whether 32-bit values are supported in index buffers used to draw primitives.
uint32_t GetMaxSamplerAnisotropy() const override
The maximum anisotropy clamp supported by device samplers.
bool SupportsTextureCompression(CompressedTextureFamily family) const override
Whether the given family of block-compressed texture formats is supported by this device....
bool SupportsTextureMaxLevel() const
Whether GL_TEXTURE_MAX_LEVEL can be set to bound a texture's sampled mip range. Core on desktop GL an...
bool SupportsOffscreenMSAA() const override
Whether the context backend supports attaching offscreen MSAA color/stencil textures.
size_t GetMinimumUniformAlignment() const override
The minimum alignment of uniform value offsets in bytes.
PixelFormat GetDefaultStencilFormat() const override
Returns a supported PixelFormat for textures that store stencil information. May include a depth chan...
bool SupportsReadFromResolve() const override
Whether the context backend supports binding the current RenderPass attachments. This is supported if...
bool SupportsDeviceTransientTextures() const override
Whether the context backend supports allocating StorageMode::kDeviceTransient (aka "memoryless") text...
bool SupportsDecalSamplerAddressMode() const override
Whether the context backend supports SamplerAddressMode::Decal.
PixelFormat GetDefaultGlyphAtlasFormat() const override
Returns the default pixel format for the alpha bitmap glyph atlas.
bool SupportsExtendedRangeFormats() const override
Whether the XR formats are supported on this device.
bool SupportsCompute() const override
Whether the context backend supports ComputePass.
bool SupportsManuallyMippedTextures() const override
Whether a texture whose mip levels were uploaded by hand (rather than produced by BlitPass::GenerateM...
bool SupportsComputeSubgroups() const override
Whether the context backend supports configuring ComputePass command subgroups.
bool SupportsFramebufferFetch() const override
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
const DescriptionGLES * GetDescription() const
int32_t value
static constexpr const char * kTextureBorderClampExt
static constexpr const char * kTextureCompressionAstcLdrExt
static constexpr const char * kMultisampledRenderToTexture2Ext
static constexpr const char * kTextureCompressionBPTCExt
static constexpr const char * kNvidiaTextureBorderClampExt
static constexpr const char * kTextureFilterAnisotropicExt
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
static constexpr const char * kAppleTextureMaxLevelExt
CompressedTextureFamily
The family of a block-compressed pixel format. GPUs support compressed formats on a per-family basis,...
Definition: formats.h:146
@ kASTCHDR
ASTC HDR. A separate device feature from ASTC LDR.
@ kBC
S3TC, RGTC, and BPTC (BC1 through BC7). Desktop GPUs.
@ kETC2
ETC2 and EAC. Mobile, OpenGL ES 3.0, and WebGL2.
@ kASTC
ASTC LDR. Modern mobile and some desktop.
static constexpr const char * kFramebufferFetchExt
static constexpr const char * kTextureCompressionAstcOesExt
static constexpr const char * kTextureCompressionRGTCExt
static constexpr const char * kElementIndexUintExt
static constexpr const char * kMultisampledRenderToTextureExt
static constexpr const char * kTextureCompressionS3TCExt
static constexpr const char * kTextureCompressionAstcHdrExt
#define IMPELLER_GL_MAX_TEXTURE_MAX_ANISOTROPY
Definition: gles.h:17