| Flutter Impeller |

texture_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
5 #include "impeller/renderer/backend/gles/texture_gles.h"
6
7 #include <optional>
8 #include <utility>
9
10 #include "flutter/fml/mapping.h"
11 #include "flutter/fml/trace_event.h"
12 #include "impeller/base/allocation.h"
13 #include "impeller/base/validation.h"
14 #include "impeller/core/formats.h"
15 #include "impeller/core/texture_descriptor.h"
16 #include "impeller/renderer/backend/gles/formats_gles.h"
17
18 namespace impeller {
19
20 static TextureGLES::Type GetTextureTypeFromDescriptor(
21 const TextureDescriptor& desc) {
22 const auto usage = static_cast<TextureUsageMask>(desc.usage);
23 const auto render_target =
24 static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
25 const auto is_msaa = desc.sample_count == SampleCount::kCount4;
26 if (usage == render_target && desc.format == PixelFormat::kS8UInt) {
27 return is_msaa ? TextureGLES::Type::kRenderBufferMultisampled
28 : TextureGLES::Type::kRenderBuffer;
29 }
30 return is_msaa ? TextureGLES::Type::kTextureMultisampled
31 : TextureGLES::Type::kTexture;
32 }
33
34 HandleType ToHandleType(TextureGLES::Type type) {
35 switch (type) {
36 case TextureGLES::Type::kTexture:
37 case TextureGLES::Type::kTextureMultisampled:
38 return HandleType::kTexture;
39 case TextureGLES::Type::kRenderBuffer:
40 case TextureGLES::Type::kRenderBufferMultisampled:
41 return HandleType::kRenderBuffer;
42 }
43 FML_UNREACHABLE();
44 }
45
46 TextureGLES::TextureGLES(ReactorGLES::Ref reactor, TextureDescriptor desc)
47 : TextureGLES(std::move(reactor), desc, false) {}
48
49 TextureGLES::TextureGLES(ReactorGLES::Ref reactor,
50 TextureDescriptor desc,
51 enum IsWrapped wrapped)
52 : TextureGLES(std::move(reactor), desc, true) {}
53
54 TextureGLES::TextureGLES(std::shared_ptr<ReactorGLES> reactor,
55 TextureDescriptor desc,
56 bool is_wrapped)
57 : Texture(desc),
58 reactor_(std::move(reactor)),
59 type_(GetTextureTypeFromDescriptor(GetTextureDescriptor())),
60 handle_(reactor_->CreateHandle(ToHandleType(type_))),
61 is_wrapped_(is_wrapped) {
62 // Ensure the texture descriptor itself is valid.
63 if (!GetTextureDescriptor().IsValid()) {
64 VALIDATION_LOG << "Invalid texture descriptor.";
65 return;
66 }
67 // Ensure the texture doesn't exceed device capabilities.
68 const auto tex_size = GetTextureDescriptor().size;
69 const auto max_size =
70 reactor_->GetProcTable().GetCapabilities()->max_texture_size;
71 if (tex_size.Max(max_size) != max_size) {
72 VALIDATION_LOG << "Texture of size " << tex_size
73 << " would exceed max supported size of " << max_size << ".";
74 return;
75 }
76
77 is_valid_ = true;
78 }
79
80 // |Texture|
81 TextureGLES::~TextureGLES() {
82 reactor_->CollectHandle(handle_);
83 }
84
85 // |Texture|
86 bool TextureGLES::IsValid() const {
87 return is_valid_;
88 }
89
90 // |Texture|
91 void TextureGLES::SetLabel(std::string_view label) {
92 reactor_->SetDebugLabel(handle_, std::string{label.data(), label.size()});
93 }
94
95 struct TexImage2DData {
96 GLint internal_format = 0;
97 GLenum external_format = GL_NONE;
98 GLenum type = GL_NONE;
99 std::shared_ptr<const fml::Mapping> data;
100
101 explicit TexImage2DData(PixelFormat pixel_format) {
102 switch (pixel_format) {
103 case PixelFormat::kA8UNormInt:
104 internal_format = GL_ALPHA;
105 external_format = GL_ALPHA;
106 type = GL_UNSIGNED_BYTE;
107 break;
108 case PixelFormat::kR8G8B8A8UNormInt:
109 case PixelFormat::kB8G8R8A8UNormInt:
110 case PixelFormat::kR8G8B8A8UNormIntSRGB:
111 case PixelFormat::kB8G8R8A8UNormIntSRGB:
112 internal_format = GL_RGBA;
113 external_format = GL_RGBA;
114 type = GL_UNSIGNED_BYTE;
115 break;
116 case PixelFormat::kR32G32B32A32Float:
117 internal_format = GL_RGBA;
118 external_format = GL_RGBA;
119 type = GL_FLOAT;
120 break;
121 case PixelFormat::kR16G16B16A16Float:
122 internal_format = GL_RGBA;
123 external_format = GL_RGBA;
124 type = GL_HALF_FLOAT;
125 break;
126 case PixelFormat::kS8UInt:
127 // Pure stencil textures are only available in OpenGL 4.4+, which is
128 // ~0% of mobile devices. Instead, we use a depth-stencil texture and
129 // only use the stencil component.
130 //
131 // https://registry.khronos.org/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
132 internal_format = GL_DEPTH_STENCIL;
133 external_format = GL_DEPTH_STENCIL;
134 type = GL_UNSIGNED_INT_24_8;
135 break;
136 case PixelFormat::kUnknown:
137 case PixelFormat::kD24UnormS8Uint:
138 case PixelFormat::kD32FloatS8UInt:
139 case PixelFormat::kR8UNormInt:
140 case PixelFormat::kR8G8UNormInt:
141 case PixelFormat::kB10G10R10XRSRGB:
142 case PixelFormat::kB10G10R10XR:
143 case PixelFormat::kB10G10R10A10XR:
144 return;
145 }
146 is_valid_ = true;
147 }
148
149 TexImage2DData(PixelFormat pixel_format,
150 std::shared_ptr<const fml::Mapping> mapping)
151 : TexImage2DData(pixel_format) {
152 data = std::move(mapping);
153 }
154
155 bool IsValid() const { return is_valid_; }
156
157 private:
158 bool is_valid_ = false;
159 };
160
161 // |Texture|
162 bool TextureGLES::OnSetContents(const uint8_t* contents,
163 size_t length,
164 size_t slice) {
165 return OnSetContents(CreateMappingWithCopy(contents, length), slice);
166 }
167
168 // |Texture|
169 bool TextureGLES::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
170 size_t slice) {
171 if (!mapping) {
172 return false;
173 }
174
175 if (mapping->GetSize() == 0u) {
176 return true;
177 }
178
179 if (mapping->GetMapping() == nullptr) {
180 return false;
181 }
182
183 if (GetType() != Type::kTexture) {
184 VALIDATION_LOG << "Incorrect texture usage flags for setting contents on "
185 "this texture object.";
186 return false;
187 }
188
189 if (is_wrapped_) {
190 VALIDATION_LOG << "Cannot set the contents of a wrapped texture.";
191 return false;
192 }
193
194 const auto& tex_descriptor = GetTextureDescriptor();
195
196 if (tex_descriptor.size.IsEmpty()) {
197 return true;
198 }
199
200 if (!tex_descriptor.IsValid()) {
201 return false;
202 }
203
204 if (mapping->GetSize() < tex_descriptor.GetByteSizeOfBaseMipLevel()) {
205 return false;
206 }
207
208 GLenum texture_type;
209 GLenum texture_target;
210 switch (tex_descriptor.type) {
211 case TextureType::kTexture2D:
212 texture_type = GL_TEXTURE_2D;
213 texture_target = GL_TEXTURE_2D;
214 break;
215 case TextureType::kTexture2DMultisample:
216 VALIDATION_LOG << "Multisample texture uploading is not supported for "
217 "the OpenGLES backend.";
218 return false;
219 case TextureType::kTextureCube:
220 texture_type = GL_TEXTURE_CUBE_MAP;
221 texture_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
222 break;
223 case TextureType::kTextureExternalOES:
224 texture_type = GL_TEXTURE_EXTERNAL_OES;
225 texture_target = GL_TEXTURE_EXTERNAL_OES;
226 break;
227 }
228
229 auto data = std::make_shared<TexImage2DData>(tex_descriptor.format,
230 std::move(mapping));
231 if (!data || !data->IsValid()) {
232 VALIDATION_LOG << "Invalid texture format.";
233 return false;
234 }
235
236 ReactorGLES::Operation texture_upload = [handle = handle_, //
237 data, //
238 size = tex_descriptor.size, //
239 texture_type, //
240 texture_target //
241 ](const auto& reactor) {
242 auto gl_handle = reactor.GetGLHandle(handle);
243 if (!gl_handle.has_value()) {
244 VALIDATION_LOG
245 << "Texture was collected before it could be uploaded to the GPU.";
246 return;
247 }
248 const auto& gl = reactor.GetProcTable();
249 gl.BindTexture(texture_type, gl_handle.value());
250 const GLvoid* tex_data = nullptr;
251 if (data->data) {
252 tex_data = data->data->GetMapping();
253 }
254
255 {
256 TRACE_EVENT1("impeller", "TexImage2DUpload", "Bytes",
257 std::to_string(data->data->GetSize()).c_str());
258 gl.TexImage2D(texture_target, // target
259 0u, // LOD level
260 data->internal_format, // internal format
261 size.width, // width
262 size.height, // height
263 0u, // border
264 data->external_format, // external format
265 data->type, // type
266 tex_data // data
267 );
268 }
269 };
270
271 contents_initialized_ = reactor_->AddOperation(texture_upload);
272 return contents_initialized_;
273 }
274
275 // |Texture|
276 ISize TextureGLES::GetSize() const {
277 return GetTextureDescriptor().size;
278 }
279
280 static std::optional<GLenum> ToRenderBufferFormat(PixelFormat format) {
281 switch (format) {
282 case PixelFormat::kB8G8R8A8UNormInt:
283 case PixelFormat::kR8G8B8A8UNormInt:
284 return GL_RGBA4;
285 case PixelFormat::kR32G32B32A32Float:
286 return GL_RGBA32F;
287 case PixelFormat::kR16G16B16A16Float:
288 return GL_RGBA16F;
289 case PixelFormat::kS8UInt:
290 return GL_STENCIL_INDEX8;
291 case PixelFormat::kD24UnormS8Uint:
292 return GL_DEPTH24_STENCIL8;
293 case PixelFormat::kD32FloatS8UInt:
294 return GL_DEPTH32F_STENCIL8;
295 case PixelFormat::kUnknown:
296 case PixelFormat::kA8UNormInt:
297 case PixelFormat::kR8UNormInt:
298 case PixelFormat::kR8G8UNormInt:
299 case PixelFormat::kR8G8B8A8UNormIntSRGB:
300 case PixelFormat::kB8G8R8A8UNormIntSRGB:
301 case PixelFormat::kB10G10R10XRSRGB:
302 case PixelFormat::kB10G10R10XR:
303 case PixelFormat::kB10G10R10A10XR:
304 return std::nullopt;
305 }
306 FML_UNREACHABLE();
307 }
308
309 void TextureGLES::InitializeContentsIfNecessary() const {
310 if (!IsValid()) {
311 return;
312 }
313 if (contents_initialized_) {
314 return;
315 }
316 contents_initialized_ = true;
317
318 if (is_wrapped_) {
319 return;
320 }
321
322 auto size = GetSize();
323
324 if (size.IsEmpty()) {
325 return;
326 }
327
328 const auto& gl = reactor_->GetProcTable();
329 auto handle = reactor_->GetGLHandle(handle_);
330 if (!handle.has_value()) {
331 VALIDATION_LOG << "Could not initialize the contents of texture.";
332 return;
333 }
334
335 switch (type_) {
336 case Type::kTexture:
337 case Type::kTextureMultisampled: {
338 TexImage2DData tex_data(GetTextureDescriptor().format);
339 if (!tex_data.IsValid()) {
340 VALIDATION_LOG << "Invalid format for texture image.";
341 return;
342 }
343 gl.BindTexture(GL_TEXTURE_2D, handle.value());
344 {
345 TRACE_EVENT0("impeller", "TexImage2DInitialization");
346 gl.TexImage2D(GL_TEXTURE_2D, // target
347 0u, // LOD level (base mip level size checked)
348 tex_data.internal_format, // internal format
349 size.width, // width
350 size.height, // height
351 0u, // border
352 tex_data.external_format, // format
353 tex_data.type, // type
354 nullptr // data
355 );
356 }
357 } break;
358 case Type::kRenderBuffer:
359 case Type::kRenderBufferMultisampled: {
360 auto render_buffer_format =
361 ToRenderBufferFormat(GetTextureDescriptor().format);
362 if (!render_buffer_format.has_value()) {
363 VALIDATION_LOG << "Invalid format for render-buffer image.";
364 return;
365 }
366 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
367 {
368 TRACE_EVENT0("impeller", "RenderBufferStorageInitialization");
369 if (type_ == Type::kRenderBufferMultisampled) {
370 gl.RenderbufferStorageMultisampleEXT(
371 GL_RENDERBUFFER, // target
372 4, // samples
373 render_buffer_format.value(), // internal format
374 size.width, // width
375 size.height // height
376 );
377 } else {
378 gl.RenderbufferStorage(
379 GL_RENDERBUFFER, // target
380 render_buffer_format.value(), // internal format
381 size.width, // width
382 size.height // height
383 );
384 }
385 }
386 } break;
387 }
388 }
389
390 std::optional<GLuint> TextureGLES::GetGLHandle() const {
391 if (!IsValid()) {
392 return std::nullopt;
393 }
394 return reactor_->GetGLHandle(handle_);
395 }
396
397 bool TextureGLES::Bind() const {
398 auto handle = GetGLHandle();
399 if (!handle.has_value()) {
400 return false;
401 }
402 const auto& gl = reactor_->GetProcTable();
403 switch (type_) {
404 case Type::kTexture:
405 case Type::kTextureMultisampled: {
406 const auto target = ToTextureTarget(GetTextureDescriptor().type);
407 if (!target.has_value()) {
408 VALIDATION_LOG << "Could not bind texture of this type.";
409 return false;
410 }
411 gl.BindTexture(target.value(), handle.value());
412 } break;
413 case Type::kRenderBuffer:
414 case Type::kRenderBufferMultisampled:
415 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
416 break;
417 }
418 InitializeContentsIfNecessary();
419 return true;
420 }
421
422 bool TextureGLES::GenerateMipmap() {
423 if (!IsValid()) {
424 return false;
425 }
426
427 auto type = GetTextureDescriptor().type;
428 switch (type) {
429 case TextureType::kTexture2D:
430 break;
431 case TextureType::kTexture2DMultisample:
432 VALIDATION_LOG << "Generating mipmaps for multisample textures is not "
433 "supported in the GLES backend.";
434 return false;
435 case TextureType::kTextureCube:
436 break;
437 case TextureType::kTextureExternalOES:
438 break;
439 }
440
441 if (!Bind()) {
442 return false;
443 }
444
445 auto handle = GetGLHandle();
446 if (!handle.has_value()) {
447 return false;
448 }
449
450 const auto& gl = reactor_->GetProcTable();
451 gl.GenerateMipmap(ToTextureType(type));
452 mipmap_generated_ = true;
453 return true;
454 }
455
456 TextureGLES::Type TextureGLES::GetType() const {
457 return type_;
458 }
459
460 static GLenum ToAttachmentPoint(TextureGLES::AttachmentPoint point) {
461 switch (point) {
462 case TextureGLES::AttachmentPoint::kColor0:
463 return GL_COLOR_ATTACHMENT0;
464 case TextureGLES::AttachmentPoint::kDepth:
465 return GL_DEPTH_ATTACHMENT;
466 case TextureGLES::AttachmentPoint::kStencil:
467 return GL_STENCIL_ATTACHMENT;
468 }
469 }
470
471 bool TextureGLES::SetAsFramebufferAttachment(GLenum target,
472 AttachmentPoint point) const {
473 if (!IsValid()) {
474 return false;
475 }
476 InitializeContentsIfNecessary();
477 auto handle = GetGLHandle();
478 if (!handle.has_value()) {
479 return false;
480 }
481 const auto& gl = reactor_->GetProcTable();
482
483 switch (type_) {
484 case Type::kTexture:
485 gl.FramebufferTexture2D(target, // target
486 ToAttachmentPoint(point), // attachment
487 GL_TEXTURE_2D, // textarget
488 handle.value(), // texture
489 0 // level
490 );
491 break;
492 case Type::kTextureMultisampled:
493 gl.FramebufferTexture2DMultisampleEXT(
494 target, // target
495 ToAttachmentPoint(point), // attachment
496 GL_TEXTURE_2D, // textarget
497 handle.value(), // texture
498 0, // level
499 4 // samples
500 );
501 break;
502 case Type::kRenderBuffer:
503 case Type::kRenderBufferMultisampled:
504 gl.FramebufferRenderbuffer(target, // target
505 ToAttachmentPoint(point), // attachment
506 GL_RENDERBUFFER, // render-buffer target
507 handle.value() // render-buffer
508 );
509 break;
510 }
511
512 return true;
513 }
514
515 // |Texture|
516 Scalar TextureGLES::GetYCoordScale() const {
517 switch (GetCoordinateSystem()) {
518 case TextureCoordinateSystem::kUploadFromHost:
519 return 1.0;
520 case TextureCoordinateSystem::kRenderToTexture:
521 return -1.0;
522 }
523 FML_UNREACHABLE();
524 }
525
526 } // namespace impeller
impeller::ReactorGLES::Operation
std::function< void(const ReactorGLES &reactor)> Operation
Definition: reactor_gles.h:195
impeller::TexImage2DData::IsValid
bool IsValid() const
Definition: texture_gles.cc:155
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::TextureType::kTextureExternalOES
@ kTextureExternalOES
impeller::ToAttachmentPoint
static GLenum ToAttachmentPoint(TextureGLES::AttachmentPoint point)
Definition: texture_gles.cc:460
impeller::TexImage2DData::TexImage2DData
TexImage2DData(PixelFormat pixel_format)
Definition: texture_gles.cc:101
impeller::HandleType::kRenderBuffer
@ kRenderBuffer
impeller::TextureGLES::Type
Type
Definition: texture_gles.h:18
impeller::TextureGLES::Type::kTextureMultisampled
@ kTextureMultisampled
impeller::TextureUsageMask
uint64_t TextureUsageMask
Definition: formats.h:295
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::TextureGLES::AttachmentPoint::kDepth
@ kDepth
impeller::TextureGLES::GenerateMipmap
bool GenerateMipmap()
Definition: texture_gles.cc:422
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::PixelFormat::kB8G8R8A8UNormIntSRGB
@ kB8G8R8A8UNormIntSRGB
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
allocation.h
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt
impeller::TextureGLES::AttachmentPoint
AttachmentPoint
Definition: texture_gles.h:44
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::ReactorGLES::Ref
std::shared_ptr< ReactorGLES > Ref
Definition: reactor_gles.h:87
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
impeller::HandleType
HandleType
Definition: handle_gles.h:22
impeller::TextureGLES::GetGLHandle
std::optional< GLuint > GetGLHandle() const
Definition: texture_gles.cc:390
texture_descriptor.h
impeller::HandleType::kTexture
@ kTexture
formats.h
texture_gles.h
impeller::TextureUsage::kRenderTarget
@ kRenderTarget
impeller::TexImage2DData
Definition: texture_gles.cc:95
impeller::TextureGLES::Type::kRenderBufferMultisampled
@ kRenderBufferMultisampled
impeller::TexImage2DData::internal_format
GLint internal_format
Definition: texture_gles.cc:96
impeller::TextureDescriptor::sample_count
SampleCount sample_count
Definition: texture_descriptor.h:45
validation.h
impeller::TextureDescriptor::usage
TextureUsageMask usage
Definition: texture_descriptor.h:43
impeller::TextureGLES::AttachmentPoint::kColor0
@ kColor0
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
impeller::TextureCoordinateSystem::kUploadFromHost
@ kUploadFromHost
impeller::TextureDescriptor::type
TextureType type
Definition: texture_descriptor.h:39
impeller::TextureType::kTexture2DMultisample
@ kTexture2DMultisample
impeller::TextureCoordinateSystem::kRenderToTexture
@ kRenderToTexture
impeller::Texture
Definition: texture.h:17
impeller::TextureGLES::Type::kRenderBuffer
@ kRenderBuffer
impeller::TextureGLES::TextureGLES
TextureGLES(ReactorGLES::Ref reactor, TextureDescriptor desc)
Definition: texture_gles.cc:46
impeller::GetTextureTypeFromDescriptor
static TextureGLES::Type GetTextureTypeFromDescriptor(const TextureDescriptor &desc)
Definition: texture_gles.cc:20
impeller::TextureGLES::SetAsFramebufferAttachment
bool SetAsFramebufferAttachment(GLenum target, AttachmentPoint point) const
Definition: texture_gles.cc:471
impeller::PixelFormat::kR8G8UNormInt
@ kR8G8UNormInt
impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::TextureType::kTextureCube
@ kTextureCube
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::ToHandleType
HandleType ToHandleType(TextureGLES::Type type)
Definition: texture_gles.cc:34
impeller::ToTextureType
constexpr GLenum ToTextureType(TextureType type)
Definition: formats_gles.h:170
impeller::Texture::mipmap_generated_
bool mipmap_generated_
Definition: texture.h:61
impeller::TextureGLES::AttachmentPoint::kStencil
@ kStencil
impeller::TextureType::kTexture2D
@ kTexture2D
impeller::PixelFormat::kR32G32B32A32Float
@ kR32G32B32A32Float
impeller::PixelFormat::kUnknown
@ kUnknown
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
formats_gles.h
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::TextureGLES::GetType
Type GetType() const
Definition: texture_gles.cc:456
impeller::TextureGLES::~TextureGLES
~TextureGLES() override
Definition: texture_gles.cc:81
impeller::PixelFormat::kR8G8B8A8UNormIntSRGB
@ kR8G8B8A8UNormIntSRGB
std
Definition: comparable.h:95
impeller::CreateMappingWithCopy
std::shared_ptr< fml::Mapping > CreateMappingWithCopy(const uint8_t *contents, size_t length)
Definition: allocation.cc:83
impeller::TexImage2DData::type
GLenum type
Definition: texture_gles.cc:98
impeller::SampleCount::kCount4
@ kCount4
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::ToTextureTarget
constexpr std::optional< GLenum > ToTextureTarget(TextureType type)
Definition: formats_gles.h:184
impeller::TextureGLES::IsWrapped
IsWrapped
Definition: texture_gles.h:25
impeller::PixelFormat::kB10G10R10XRSRGB
@ kB10G10R10XRSRGB
impeller::TextureGLES
Definition: texture_gles.h:15
impeller::TexImage2DData::TexImage2DData
TexImage2DData(PixelFormat pixel_format, std::shared_ptr< const fml::Mapping > mapping)
Definition: texture_gles.cc:149
impeller::TextureGLES::Bind
bool Bind() const
Definition: texture_gles.cc:397
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::TexImage2DData::data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:99
impeller::TextureGLES::Type::kTexture
@ kTexture
impeller::Texture::GetCoordinateSystem
TextureCoordinateSystem GetCoordinateSystem() const
Definition: texture.cc:77
impeller
Definition: aiks_context.cc:10
impeller::ToRenderBufferFormat
static std::optional< GLenum > ToRenderBufferFormat(PixelFormat format)
Definition: texture_gles.cc:280
impeller::TexImage2DData::external_format
GLenum external_format
Definition: texture_gles.cc:97