| 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/logging.h"
11 #include "flutter/fml/mapping.h"
12 #include "flutter/fml/trace_event.h"
13 #include "impeller/base/allocation.h"
14 #include "impeller/base/strings.h"
15 #include "impeller/base/validation.h"
16 #include "impeller/core/formats.h"
17 #include "impeller/core/texture_descriptor.h"
18 #include "impeller/renderer/backend/gles/formats_gles.h"
19
20 namespace impeller {
21
22 namespace {
23 static bool IsDepthStencilFormat(PixelFormat format) {
24 switch (format) {
25 case PixelFormat::kS8UInt:
26 case PixelFormat::kD24UnormS8Uint:
27 case PixelFormat::kD32FloatS8UInt:
28 return true;
29 case PixelFormat::kUnknown:
30 case PixelFormat::kA8UNormInt:
31 case PixelFormat::kR8UNormInt:
32 case PixelFormat::kR8G8UNormInt:
33 case PixelFormat::kR8G8B8A8UNormInt:
34 case PixelFormat::kR8G8B8A8UNormIntSRGB:
35 case PixelFormat::kB8G8R8A8UNormInt:
36 case PixelFormat::kB8G8R8A8UNormIntSRGB:
37 case PixelFormat::kR32G32B32A32Float:
38 case PixelFormat::kR16G16B16A16Float:
39 case PixelFormat::kB10G10R10XR:
40 case PixelFormat::kB10G10R10XRSRGB:
41 case PixelFormat::kB10G10R10A10XR:
42 return false;
43 }
44 FML_UNREACHABLE();
45 }
46
47 static TextureGLES::Type GetTextureTypeFromDescriptor(
48 const TextureDescriptor& desc) {
49 const auto usage = static_cast<TextureUsageMask>(desc.usage);
50 const auto render_target = TextureUsage::kRenderTarget;
51 const auto is_msaa = desc.sample_count == SampleCount::kCount4;
52 if (usage == render_target && IsDepthStencilFormat(desc.format)) {
53 return is_msaa ? TextureGLES::Type::kRenderBufferMultisampled
54 : TextureGLES::Type::kRenderBuffer;
55 }
56 return is_msaa ? TextureGLES::Type::kTextureMultisampled
57 : TextureGLES::Type::kTexture;
58 }
59
60 struct TexImage2DData {
61 GLint internal_format = 0;
62 GLenum external_format = GL_NONE;
63 GLenum type = GL_NONE;
64 std::shared_ptr<const fml::Mapping> data;
65
66 explicit TexImage2DData(PixelFormat pixel_format) {
67 switch (pixel_format) {
68 case PixelFormat::kA8UNormInt:
69 internal_format = GL_ALPHA;
70 external_format = GL_ALPHA;
71 type = GL_UNSIGNED_BYTE;
72 break;
73 case PixelFormat::kR8UNormInt:
74 internal_format = GL_RED;
75 external_format = GL_RED;
76 type = GL_UNSIGNED_BYTE;
77 break;
78 case PixelFormat::kR8G8B8A8UNormInt:
79 case PixelFormat::kB8G8R8A8UNormInt:
80 case PixelFormat::kR8G8B8A8UNormIntSRGB:
81 case PixelFormat::kB8G8R8A8UNormIntSRGB:
82 internal_format = GL_RGBA;
83 external_format = GL_RGBA;
84 type = GL_UNSIGNED_BYTE;
85 break;
86 case PixelFormat::kR32G32B32A32Float:
87 internal_format = GL_RGBA;
88 external_format = GL_RGBA;
89 type = GL_FLOAT;
90 break;
91 case PixelFormat::kR16G16B16A16Float:
92 internal_format = GL_RGBA;
93 external_format = GL_RGBA;
94 type = GL_HALF_FLOAT;
95 break;
96 case PixelFormat::kS8UInt:
97 // Pure stencil textures are only available in OpenGL 4.4+, which is
98 // ~0% of mobile devices. Instead, we use a depth-stencil texture and
99 // only use the stencil component.
100 //
101 // https://registry.khronos.org/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
102 case PixelFormat::kD24UnormS8Uint:
103 internal_format = GL_DEPTH_STENCIL;
104 external_format = GL_DEPTH_STENCIL;
105 type = GL_UNSIGNED_INT_24_8;
106 break;
107 case PixelFormat::kUnknown:
108 case PixelFormat::kD32FloatS8UInt:
109 case PixelFormat::kR8G8UNormInt:
110 case PixelFormat::kB10G10R10XRSRGB:
111 case PixelFormat::kB10G10R10XR:
112 case PixelFormat::kB10G10R10A10XR:
113 return;
114 }
115 is_valid_ = true;
116 }
117
118 TexImage2DData(PixelFormat pixel_format,
119 std::shared_ptr<const fml::Mapping> mapping)
120 : TexImage2DData(pixel_format) {
121 data = std::move(mapping);
122 }
123
124 bool IsValid() const { return is_valid_; }
125
126 private:
127 bool is_valid_ = false;
128 };
129 } // namespace
130
131 HandleType ToHandleType(TextureGLES::Type type) {
132 switch (type) {
133 case TextureGLES::Type::kTexture:
134 case TextureGLES::Type::kTextureMultisampled:
135 return HandleType::kTexture;
136 case TextureGLES::Type::kRenderBuffer:
137 case TextureGLES::Type::kRenderBufferMultisampled:
138 return HandleType::kRenderBuffer;
139 }
140 FML_UNREACHABLE();
141 }
142
143 std::shared_ptr<TextureGLES> TextureGLES::WrapFBO(
144 std::shared_ptr<ReactorGLES> reactor,
145 TextureDescriptor desc,
146 GLuint fbo) {
147 auto texture = std::shared_ptr<TextureGLES>(
148 new TextureGLES(std::move(reactor), desc, fbo, std::nullopt));
149 if (!texture->IsValid()) {
150 return nullptr;
151 }
152 return texture;
153 }
154
155 std::shared_ptr<TextureGLES> TextureGLES::WrapTexture(
156 std::shared_ptr<ReactorGLES> reactor,
157 TextureDescriptor desc,
158 HandleGLES external_handle) {
159 if (external_handle.IsDead()) {
160 VALIDATION_LOG << "Cannot wrap a dead handle.";
161 return nullptr;
162 }
163 if (external_handle.GetType() != HandleType::kTexture) {
164 VALIDATION_LOG << "Cannot wrap a non-texture handle.";
165 return nullptr;
166 }
167 auto texture = std::shared_ptr<TextureGLES>(
168 new TextureGLES(std::move(reactor), desc, std::nullopt, external_handle));
169 if (!texture->IsValid()) {
170 return nullptr;
171 }
172 return texture;
173 }
174
175 std::shared_ptr<TextureGLES> TextureGLES::CreatePlaceholder(
176 std::shared_ptr<ReactorGLES> reactor,
177 TextureDescriptor desc) {
178 return TextureGLES::WrapFBO(std::move(reactor), desc, 0u);
179 }
180
181 TextureGLES::TextureGLES(std::shared_ptr<ReactorGLES> reactor,
182 TextureDescriptor desc)
183 : TextureGLES(std::move(reactor), //
184 desc, //
185 std::nullopt, //
186 std::nullopt //
187 ) {}
188
189 TextureGLES::TextureGLES(std::shared_ptr<ReactorGLES> reactor,
190 TextureDescriptor desc,
191 std::optional<GLuint> fbo,
192 std::optional<HandleGLES> external_handle)
193 : Texture(desc),
194 reactor_(std::move(reactor)),
195 type_(GetTextureTypeFromDescriptor(GetTextureDescriptor())),
196 handle_(external_handle.has_value()
197 ? external_handle.value()
198 : reactor_->CreateUntrackedHandle(ToHandleType(type_))),
199 is_wrapped_(fbo.has_value() || external_handle.has_value()),
200 wrapped_fbo_(fbo) {
201 // Ensure the texture descriptor itself is valid.
202 if (!GetTextureDescriptor().IsValid()) {
203 VALIDATION_LOG << "Invalid texture descriptor.";
204 return;
205 }
206 // Ensure the texture doesn't exceed device capabilities.
207 const auto tex_size = GetTextureDescriptor().size;
208 const auto max_size =
209 reactor_->GetProcTable().GetCapabilities()->max_texture_size;
210 if (tex_size.Max(max_size) != max_size) {
211 VALIDATION_LOG << "Texture of size " << tex_size
212 << " would exceed max supported size of " << max_size << ".";
213 return;
214 }
215
216 is_valid_ = true;
217 }
218
219 // |Texture|
220 TextureGLES::~TextureGLES() {
221 reactor_->CollectHandle(handle_);
222 if (cached_fbo_ != GL_NONE) {
223 reactor_->GetProcTable().DeleteFramebuffers(1, &cached_fbo_);
224 }
225 }
226
227 // |Texture|
228 bool TextureGLES::IsValid() const {
229 return is_valid_;
230 }
231
232 // |Texture|
233 void TextureGLES::SetLabel(std::string_view label) {
234 #ifdef IMPELLER_DEBUG
235 reactor_->SetDebugLabel(handle_, label);
236 #endif // IMPELLER_DEBUG
237 }
238
239 // |Texture|
240 void TextureGLES::SetLabel(std::string_view label, std::string_view trailing) {
241 #ifdef IMPELLER_DEBUG
242 if (reactor_->CanSetDebugLabels()) {
243 reactor_->SetDebugLabel(handle_,
244 SPrintF("%s %s", label.data(), trailing.data()));
245 }
246 #endif // IMPELLER_DEBUG
247 }
248
249 // |Texture|
250 bool TextureGLES::OnSetContents(const uint8_t* contents,
251 size_t length,
252 size_t slice) {
253 return OnSetContents(CreateMappingWithCopy(contents, Bytes{length}), slice);
254 }
255
256 // |Texture|
257 bool TextureGLES::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
258 size_t slice) {
259 if (!mapping) {
260 return false;
261 }
262
263 if (mapping->GetSize() == 0u) {
264 return true;
265 }
266
267 if (mapping->GetMapping() == nullptr) {
268 return false;
269 }
270
271 if (GetType() != Type::kTexture) {
272 VALIDATION_LOG << "Incorrect texture usage flags for setting contents on "
273 "this texture object.";
274 return false;
275 }
276
277 if (is_wrapped_) {
278 VALIDATION_LOG << "Cannot set the contents of a wrapped texture.";
279 return false;
280 }
281
282 const auto& tex_descriptor = GetTextureDescriptor();
283
284 if (tex_descriptor.size.IsEmpty()) {
285 return true;
286 }
287
288 if (!tex_descriptor.IsValid() ||
289 mapping->GetSize() < tex_descriptor.GetByteSizeOfBaseMipLevel()) {
290 return false;
291 }
292
293 GLenum texture_type;
294 GLenum texture_target;
295 switch (tex_descriptor.type) {
296 case TextureType::kTexture2D:
297 texture_type = GL_TEXTURE_2D;
298 texture_target = GL_TEXTURE_2D;
299 break;
300 case TextureType::kTexture2DMultisample:
301 VALIDATION_LOG << "Multisample texture uploading is not supported for "
302 "the OpenGLES backend.";
303 return false;
304 case TextureType::kTextureCube:
305 texture_type = GL_TEXTURE_CUBE_MAP;
306 texture_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
307 break;
308 case TextureType::kTextureExternalOES:
309 texture_type = GL_TEXTURE_EXTERNAL_OES;
310 texture_target = GL_TEXTURE_EXTERNAL_OES;
311 break;
312 }
313
314 auto data = std::make_shared<TexImage2DData>(tex_descriptor.format,
315 std::move(mapping));
316 if (!data || !data->IsValid()) {
317 VALIDATION_LOG << "Invalid texture format.";
318 return false;
319 }
320
321 ReactorGLES::Operation texture_upload = [handle = handle_, //
322 data, //
323 size = tex_descriptor.size, //
324 texture_type, //
325 texture_target //
326 ](const auto& reactor) {
327 auto gl_handle = reactor.GetGLHandle(handle);
328 if (!gl_handle.has_value()) {
329 VALIDATION_LOG
330 << "Texture was collected before it could be uploaded to the GPU.";
331 return;
332 }
333 const auto& gl = reactor.GetProcTable();
334 gl.BindTexture(texture_type, gl_handle.value());
335 const GLvoid* tex_data = nullptr;
336 if (data->data) {
337 tex_data = data->data->GetMapping();
338 }
339
340 {
341 TRACE_EVENT1("impeller", "TexImage2DUpload", "Bytes",
342 std::to_string(data->data->GetSize()).c_str());
343 gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
344 gl.TexImage2D(texture_target, // target
345 0u, // LOD level
346 data->internal_format, // internal format
347 size.width, // width
348 size.height, // height
349 0u, // border
350 data->external_format, // external format
351 data->type, // type
352 tex_data // data
353 );
354 }
355 };
356
357 slices_initialized_ = reactor_->AddOperation(texture_upload);
358 return slices_initialized_[0];
359 }
360
361 // |Texture|
362 ISize TextureGLES::GetSize() const {
363 return GetTextureDescriptor().size;
364 }
365
366 static std::optional<GLenum> ToRenderBufferFormat(PixelFormat format) {
367 switch (format) {
368 case PixelFormat::kB8G8R8A8UNormInt:
369 case PixelFormat::kR8G8B8A8UNormInt:
370 return GL_RGBA4;
371 case PixelFormat::kR32G32B32A32Float:
372 return GL_RGBA32F;
373 case PixelFormat::kR16G16B16A16Float:
374 return GL_RGBA16F;
375 case PixelFormat::kS8UInt:
376 return GL_STENCIL_INDEX8;
377 case PixelFormat::kD24UnormS8Uint:
378 return GL_DEPTH24_STENCIL8;
379 case PixelFormat::kD32FloatS8UInt:
380 return GL_DEPTH32F_STENCIL8;
381 case PixelFormat::kUnknown:
382 case PixelFormat::kA8UNormInt:
383 case PixelFormat::kR8UNormInt:
384 case PixelFormat::kR8G8UNormInt:
385 case PixelFormat::kR8G8B8A8UNormIntSRGB:
386 case PixelFormat::kB8G8R8A8UNormIntSRGB:
387 case PixelFormat::kB10G10R10XRSRGB:
388 case PixelFormat::kB10G10R10XR:
389 case PixelFormat::kB10G10R10A10XR:
390 return std::nullopt;
391 }
392 FML_UNREACHABLE();
393 }
394
395 TextureGLES::Type TextureGLES::ComputeTypeForBinding(GLenum target) const {
396 // When binding to a GL_READ_FRAMEBUFFER, any multisampled
397 // textures must be bound as single sampled.
398 if (target == GL_READ_FRAMEBUFFER && type_ == Type::kTextureMultisampled) {
399 return Type::kTexture;
400 }
401 return type_;
402 }
403
404 void TextureGLES::InitializeContentsIfNecessary() const {
405 if (!IsValid() || slices_initialized_[0]) {
406 return;
407 }
408 slices_initialized_[0] = true;
409
410 if (is_wrapped_) {
411 return;
412 }
413
414 auto size = GetSize();
415
416 if (size.IsEmpty()) {
417 return;
418 }
419
420 const auto& gl = reactor_->GetProcTable();
421 std::optional<GLuint> handle = reactor_->GetGLHandle(handle_);
422 if (!handle.has_value()) {
423 VALIDATION_LOG << "Could not initialize the contents of texture.";
424 return;
425 }
426
427 switch (type_) {
428 case Type::kTexture:
429 case Type::kTextureMultisampled: {
430 TexImage2DData tex_data(GetTextureDescriptor().format);
431 if (!tex_data.IsValid()) {
432 VALIDATION_LOG << "Invalid format for texture image.";
433 return;
434 }
435 gl.BindTexture(GL_TEXTURE_2D, handle.value());
436 {
437 TRACE_EVENT0("impeller", "TexImage2DInitialization");
438 gl.TexImage2D(GL_TEXTURE_2D, // target
439 0u, // LOD level (base mip level size checked)
440 tex_data.internal_format, // internal format
441 size.width, // width
442 size.height, // height
443 0u, // border
444 tex_data.external_format, // format
445 tex_data.type, // type
446 nullptr // data
447 );
448 }
449 } break;
450 case Type::kRenderBuffer:
451 case Type::kRenderBufferMultisampled: {
452 auto render_buffer_format =
453 ToRenderBufferFormat(GetTextureDescriptor().format);
454 if (!render_buffer_format.has_value()) {
455 VALIDATION_LOG << "Invalid format for render-buffer image.";
456 return;
457 }
458 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
459 {
460 TRACE_EVENT0("impeller", "RenderBufferStorageInitialization");
461 if (type_ == Type::kRenderBufferMultisampled) {
462 gl.RenderbufferStorageMultisampleEXT(
463 GL_RENDERBUFFER, // target
464 4, // samples
465 render_buffer_format.value(), // internal format
466 size.width, // width
467 size.height // height
468 );
469 } else {
470 gl.RenderbufferStorage(
471 GL_RENDERBUFFER, // target
472 render_buffer_format.value(), // internal format
473 size.width, // width
474 size.height // height
475 );
476 }
477 }
478 } break;
479 }
480 }
481
482 std::optional<GLuint> TextureGLES::GetGLHandle() const {
483 if (!IsValid()) {
484 return std::nullopt;
485 }
486 return reactor_->GetGLHandle(handle_);
487 }
488
489 bool TextureGLES::Bind() const {
490 auto handle = GetGLHandle();
491 if (!handle.has_value()) {
492 return false;
493 }
494 const auto& gl = reactor_->GetProcTable();
495
496 if (fence_.has_value()) {
497 std::optional<GLsync> fence = reactor_->GetGLFence(fence_.value());
498 if (fence.has_value()) {
499 gl.WaitSync(fence.value(), 0, GL_TIMEOUT_IGNORED);
500 }
501 reactor_->CollectHandle(fence_.value());
502 fence_ = std::nullopt;
503 }
504
505 switch (type_) {
506 case Type::kTexture:
507 case Type::kTextureMultisampled: {
508 const auto target = ToTextureTarget(GetTextureDescriptor().type);
509 if (!target.has_value()) {
510 VALIDATION_LOG << "Could not bind texture of this type.";
511 return false;
512 }
513 gl.BindTexture(target.value(), handle.value());
514 } break;
515 case Type::kRenderBuffer:
516 case Type::kRenderBufferMultisampled:
517 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
518 break;
519 }
520 InitializeContentsIfNecessary();
521 return true;
522 }
523
524 void TextureGLES::MarkContentsInitialized() {
525 for (size_t i = 0; i < slices_initialized_.size(); i++) {
526 slices_initialized_[i] = true;
527 }
528 }
529
530 void TextureGLES::MarkSliceInitialized(size_t slice) const {
531 slices_initialized_[slice] = true;
532 }
533
534 bool TextureGLES::IsSliceInitialized(size_t slice) const {
535 return slices_initialized_[slice];
536 }
537
538 bool TextureGLES::GenerateMipmap() {
539 if (!IsValid()) {
540 return false;
541 }
542
543 auto type = GetTextureDescriptor().type;
544 switch (type) {
545 case TextureType::kTexture2D:
546 break;
547 case TextureType::kTexture2DMultisample:
548 VALIDATION_LOG << "Generating mipmaps for multisample textures is not "
549 "supported in the GLES backend.";
550 return false;
551 case TextureType::kTextureCube:
552 break;
553 case TextureType::kTextureExternalOES:
554 break;
555 }
556
557 if (!Bind()) {
558 return false;
559 }
560
561 auto handle = GetGLHandle();
562 if (!handle.has_value()) {
563 return false;
564 }
565
566 const auto& gl = reactor_->GetProcTable();
567 gl.GenerateMipmap(ToTextureType(type));
568 mipmap_generated_ = true;
569 return true;
570 }
571
572 TextureGLES::Type TextureGLES::GetType() const {
573 return type_;
574 }
575
576 static GLenum ToAttachmentType(TextureGLES::AttachmentType point) {
577 switch (point) {
578 case TextureGLES::AttachmentType::kColor0:
579 return GL_COLOR_ATTACHMENT0;
580 case TextureGLES::AttachmentType::kDepth:
581 return GL_DEPTH_ATTACHMENT;
582 case TextureGLES::AttachmentType::kStencil:
583 return GL_STENCIL_ATTACHMENT;
584 }
585 }
586
587 bool TextureGLES::SetAsFramebufferAttachment(
588 GLenum target,
589 AttachmentType attachment_type) const {
590 if (!IsValid()) {
591 return false;
592 }
593 InitializeContentsIfNecessary();
594 auto handle = GetGLHandle();
595 if (!handle.has_value()) {
596 return false;
597 }
598 const auto& gl = reactor_->GetProcTable();
599
600 switch (ComputeTypeForBinding(target)) {
601 case Type::kTexture:
602 gl.FramebufferTexture2D(target, // target
603 ToAttachmentType(attachment_type), // attachment
604 GL_TEXTURE_2D, // textarget
605 handle.value(), // texture
606 0 // level
607 );
608 break;
609 case Type::kTextureMultisampled:
610 gl.FramebufferTexture2DMultisampleEXT(
611 target, // target
612 ToAttachmentType(attachment_type), // attachment
613 GL_TEXTURE_2D, // textarget
614 handle.value(), // texture
615 0, // level
616 4 // samples
617 );
618 break;
619 case Type::kRenderBuffer:
620 case Type::kRenderBufferMultisampled:
621 gl.FramebufferRenderbuffer(
622 target, // target
623 ToAttachmentType(attachment_type), // attachment
624 GL_RENDERBUFFER, // render-buffer target
625 handle.value() // render-buffer
626 );
627 break;
628 }
629
630 return true;
631 }
632
633 // |Texture|
634 Scalar TextureGLES::GetYCoordScale() const {
635 switch (GetCoordinateSystem()) {
636 case TextureCoordinateSystem::kUploadFromHost:
637 return 1.0;
638 case TextureCoordinateSystem::kRenderToTexture:
639 return -1.0;
640 }
641 FML_UNREACHABLE();
642 }
643
644 bool TextureGLES::IsWrapped() const {
645 return is_wrapped_;
646 }
647
648 std::optional<GLuint> TextureGLES::GetFBO() const {
649 return wrapped_fbo_;
650 }
651
652 void TextureGLES::SetFence(HandleGLES fence) {
653 FML_DCHECK(!fence_.has_value());
654 fence_ = fence;
655 }
656
657 // Visible for testing.
658 std::optional<HandleGLES> TextureGLES::GetSyncFence() const {
659 return fence_;
660 }
661
662 void TextureGLES::SetCachedFBO(GLuint fbo) {
663 cached_fbo_ = fbo;
664 }
665
666 GLuint TextureGLES::GetCachedFBO() const {
667 return cached_fbo_;
668 }
669
670 } // namespace impeller
impeller::ReactorGLES::Operation
std::function< void(const ReactorGLES &reactor)> Operation
Definition: reactor_gles.h:214
impeller::ISize
ISize64 ISize
Definition: size.h:174
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::TextureType::kTextureExternalOES
@ kTextureExternalOES
impeller::HandleType::kRenderBuffer
@ kRenderBuffer
impeller::TextureGLES::GetCachedFBO
GLuint GetCachedFBO() const
Retrieve the cached FBO object, or GL_NONE if there is no object.
Definition: texture_gles.cc:666
impeller::TextureGLES::Type
Type
Definition: texture_gles.h:21
impeller::TextureGLES::Type::kTextureMultisampled
@ kTextureMultisampled
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::TextureGLES::GenerateMipmap
bool GenerateMipmap()
Definition: texture_gles.cc:538
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::PixelFormat::kB8G8R8A8UNormIntSRGB
@ kB8G8R8A8UNormIntSRGB
impeller::TextureGLES::AttachmentType::kDepth
@ kDepth
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
impeller::TextureGLES::GetFBO
std::optional< GLuint > GetFBO() const
Definition: texture_gles.cc:648
allocation.h
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt
value
int32_t value
Definition: dl_golden_unittests.cc:444
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:64
impeller::TextureGLES::MarkSliceInitialized
void MarkSliceInitialized(size_t slice) const
Indicates that a specific texture slice has been initialized.
Definition: texture_gles.cc:530
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
impeller::HandleType
HandleType
Definition: handle_gles.h:18
impeller::TextureGLES::GetGLHandle
std::optional< GLuint > GetGLHandle() const
Definition: texture_gles.cc:482
texture_descriptor.h
impeller::HandleType::kTexture
@ kTexture
texture_gles.h
impeller::TextureGLES::TextureGLES
TextureGLES(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc)
Definition: texture_gles.cc:181
formats.h
impeller::TextureGLES::Type::kRenderBufferMultisampled
@ kRenderBufferMultisampled
impeller::TextureUsage::kRenderTarget
@ kRenderTarget
impeller::TextureGLES::MarkContentsInitialized
void MarkContentsInitialized()
Indicates that all texture storage has already been allocated and contents initialized.
Definition: texture_gles.cc:524
impeller::TextureGLES::AttachmentType::kColor0
@ kColor0
validation.h
impeller::TextureGLES::IsValid
bool IsValid() const override
Definition: texture_gles.cc:228
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:99
impeller::TextureCoordinateSystem::kUploadFromHost
@ kUploadFromHost
impeller::TextureDescriptor::type
TextureType type
Definition: texture_descriptor.h:40
impeller::TextureGLES::IsSliceInitialized
bool IsSliceInitialized(size_t slice) const
Definition: texture_gles.cc:534
impeller::HandleGLES::GetType
HandleType GetType() const
Definition: handle_gles.h:74
impeller::TextureType::kTexture2DMultisample
@ kTexture2DMultisample
impeller::TextureCoordinateSystem::kRenderToTexture
@ kRenderToTexture
impeller::Texture
Definition: texture.h:17
impeller::TextureGLES::IsWrapped
bool IsWrapped() const
Definition: texture_gles.cc:644
impeller::TextureGLES::WrapFBO
static std::shared_ptr< TextureGLES > WrapFBO(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, GLuint fbo)
Create a texture by wrapping an external framebuffer object whose lifecycle is owned by the caller.
Definition: texture_gles.cc:143
impeller::TextureGLES::Type::kRenderBuffer
@ kRenderBuffer
type
GLenum type
Definition: texture_gles.cc:63
impeller::TextureGLES::ComputeTypeForBinding
Type ComputeTypeForBinding(GLenum target) const
Definition: texture_gles.cc:395
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::PixelFormat::kR8G8UNormInt
@ kR8G8UNormInt
external_format
GLenum external_format
Definition: texture_gles.cc:62
impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::TextureGLES::WrapTexture
static std::shared_ptr< TextureGLES > WrapTexture(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, HandleGLES external_handle)
Create a texture by wrapping an external OpenGL texture handle. Ownership of the texture handle is as...
Definition: texture_gles.cc:155
impeller::TextureType::kTextureCube
@ kTextureCube
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::ToHandleType
HandleType ToHandleType(TextureGLES::Type type)
Definition: texture_gles.cc:131
internal_format
GLint internal_format
Definition: texture_gles.cc:61
impeller::ToTextureType
constexpr GLenum ToTextureType(TextureType type)
Definition: formats_gles.h:171
impeller::Texture::mipmap_generated_
bool mipmap_generated_
Definition: texture.h:79
impeller::HandleGLES::IsDead
constexpr bool IsDead() const
Determines if the handle is dead.
Definition: handle_gles.h:53
impeller::TextureUsageMask
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:308
strings.h
impeller::TextureGLES::AttachmentType::kStencil
@ kStencil
impeller::TextureType::kTexture2D
@ kTexture2D
impeller::PixelFormat::kR32G32B32A32Float
@ kR32G32B32A32Float
impeller::PixelFormat::kUnknown
@ kUnknown
impeller::CreateMappingWithCopy
std::shared_ptr< fml::Mapping > CreateMappingWithCopy(const uint8_t *contents, Bytes length)
Creates a mapping with copy of the bytes.
Definition: allocation.cc:83
formats_gles.h
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::TextureGLES::GetType
Type GetType() const
Definition: texture_gles.cc:572
impeller::TextureGLES::~TextureGLES
~TextureGLES() override
Definition: texture_gles.cc:220
impeller::PixelFormat::kR8G8B8A8UNormIntSRGB
@ kR8G8B8A8UNormIntSRGB
impeller::TextureGLES::CreatePlaceholder
static std::shared_ptr< TextureGLES > CreatePlaceholder(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc)
Create a "texture" that is never expected to be bound/unbound explicitly or initialized in any way....
Definition: texture_gles.cc:175
impeller::TextureGLES::GetSyncFence
std::optional< HandleGLES > GetSyncFence() const
Definition: texture_gles.cc:658
std
Definition: comparable.h:95
impeller::TextureGLES::AttachmentType
AttachmentType
Definition: texture_gles.h:92
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:38
impeller::ToTextureTarget
constexpr std::optional< GLenum > ToTextureTarget(TextureType type)
Definition: formats_gles.h:185
impeller::PixelFormat::kB10G10R10XRSRGB
@ kB10G10R10XRSRGB
impeller::TextureGLES::SetCachedFBO
void SetCachedFBO(GLuint fbo)
Definition: texture_gles.cc:662
impeller::TextureGLES
Definition: texture_gles.h:18
impeller::TextureGLES::SetFence
void SetFence(HandleGLES fence)
Attach a sync fence to this texture that will be waited on before encoding a rendering operation that...
Definition: texture_gles.cc:652
impeller::TextureGLES::Bind
bool Bind() const
Definition: texture_gles.cc:489
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::TextureGLES::Type::kTexture
@ kTexture
impeller::Texture::GetCoordinateSystem
TextureCoordinateSystem GetCoordinateSystem() const
Definition: texture.cc:77
impeller
Definition: allocation.cc:12
impeller::ToRenderBufferFormat
static std::optional< GLenum > ToRenderBufferFormat(PixelFormat format)
Definition: texture_gles.cc:366
impeller::ToAttachmentType
static GLenum ToAttachmentType(TextureGLES::AttachmentType point)
Definition: texture_gles.cc:576
impeller::Bytes
AllocationSize< 1u > Bytes
Definition: allocation_size.h:151
impeller::HandleGLES
Represents a handle to an underlying OpenGL object. Unlike OpenGL object handles, these handles can b...
Definition: handle_gles.h:37
impeller::TextureGLES::SetAsFramebufferAttachment
bool SetAsFramebufferAttachment(GLenum target, AttachmentType attachment_type) const
Definition: texture_gles.cc:587