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