Flutter Impeller
impeller::TextureGLES Class Referencefinal

#include <texture_gles.h>

Inheritance diagram for impeller::TextureGLES:
impeller::Texture impeller::BackendCast< TextureGLES, Texture >

Public Types

enum class  Type {
  kTexture ,
  kTextureMultisampled ,
  kRenderBuffer ,
  kRenderBufferMultisampled
}
 
enum class  AttachmentType {
  kColor0 ,
  kDepth ,
  kStencil
}
 

Public Member Functions

 TextureGLES (std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, bool threadsafe=false)
 
bool IsValid () const override
 
std::optional< GLuint > GetGLHandle () const
 
bool Bind ()
 
bool GenerateMipmap ()
 
bool SetAsFramebufferAttachment (GLenum target, AttachmentType attachment_type, uint32_t mip_level=0, uint32_t slice=0)
 
Type GetType () const
 
bool IsWrapped () const
 
void Leak ()
 Reset the internal texture state so that the reactor will not free the associated handle. More...
 
std::optional< GLuint > GetFBO () const
 
void MarkContentsInitialized ()
 Indicates that all texture storage has already been allocated and contents initialized. More...
 
void MarkSliceInitialized (size_t slice)
 Indicates that a specific texture slice has been initialized. More...
 
bool IsSliceInitialized (size_t slice) const
 
void MarkSliceMipLevelInitialized (size_t slice, size_t mip_level)
 Indicates that storage for mip_level of slice has been allocated by a glTexImage2D call (or equivalent). More...
 
bool IsSliceMipLevelInitialized (size_t slice, size_t mip_level) const
 
void SetFence (HandleGLES fence)
 Attach a sync fence to this texture that will be waited on before encoding a rendering operation that references it. More...
 
void SetCachedFBO (HandleGLES fbo)
 
const HandleGLES & GetCachedFBO () const
 Retrieve the cached FBO object, or a dead handle if there is no object. More...
 
void SetCachedFBOSubresource (uint32_t mip_level, uint32_t slice)
 Records the subresource the cached FBO is currently bound to. More...
 
bool CachedFBOMatchesSubresource (uint32_t mip_level, uint32_t slice) const
 
std::optional< HandleGLES > GetSyncFence () const
 
Type ComputeTypeForBinding (GLenum target) const
 
- Public Member Functions inherited from impeller::Texture
virtual ~Texture ()
 
bool SetContents (const uint8_t *contents, size_t length, size_t slice=0, bool is_opaque=false)
 
bool SetContents (std::shared_ptr< const fml::Mapping > mapping, size_t slice=0, bool is_opaque=false)
 
bool IsOpaque () const
 
size_t GetMipCount () const
 
const TextureDescriptor & GetTextureDescriptor () const
 
bool NeedsMipmapGeneration () const
 

Static Public Member Functions

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. More...
 
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 assumed by the reactor. More...
 
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. It only exists to setup a render pass description. More...
 
- Static Public Member Functions inherited from impeller::BackendCast< TextureGLES, Texture >
static TextureGLES & Cast (Texture &base)
 
static const TextureGLES & Cast (const Texture &base)
 
static TextureGLES * Cast (Texture *base)
 
static const TextureGLES * Cast (const Texture *base)
 

Additional Inherited Members

- Protected Member Functions inherited from impeller::Texture
 Texture (TextureDescriptor desc)
 
- Protected Attributes inherited from impeller::Texture
bool mipmap_generated_ = false
 

Detailed Description

Definition at line 20 of file texture_gles.h.

Member Enumeration Documentation

◆ AttachmentType

Enumerator
kColor0 
kDepth 
kStencil 

Definition at line 93 of file texture_gles.h.

93  {
94  kColor0,
95  kDepth,
96  kStencil,
97  };

◆ Type

Enumerator
kTexture 
kTextureMultisampled 
kRenderBuffer 
kRenderBufferMultisampled 

Definition at line 23 of file texture_gles.h.

23  {
24  kTexture,
25  kTextureMultisampled,
27  kRenderBufferMultisampled,
28  };

Constructor & Destructor Documentation

◆ TextureGLES()

impeller::TextureGLES::TextureGLES ( std::shared_ptr< ReactorGLES >  reactor,
TextureDescriptor  desc,
bool  threadsafe = false 
)

Definition at line 133 of file texture_gles.cc.

136  : TextureGLES(std::move(reactor), //
137  desc, //
138  threadsafe, //
139  std::nullopt, //
140  std::nullopt //
141  ) {}
TextureGLES(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, bool threadsafe=false)
std::shared_ptr< ReactorGLES > reactor

Referenced by WrapFBO(), and WrapTexture().

Member Function Documentation

◆ Bind()

bool impeller::TextureGLES::Bind ( )

Definition at line 532 of file texture_gles.cc.

532  {
533  auto handle = GetGLHandle();
534  if (!handle.has_value()) {
535  return false;
536  }
537  const auto& gl = reactor_->GetProcTable();
538 
539  if (fence_.IsValid()) {
540  std::optional<GLsync> fence = reactor_->GetGLFence(fence_.Get());
541  if (fence.has_value()) {
542  gl.WaitSync(fence.value(), 0, GL_TIMEOUT_IGNORED);
543  }
544  fence_.Reset();
545  }
546 
547  switch (type_) {
548  case Type::kTexture:
550  const auto target = ToTextureTarget(GetTextureDescriptor().type);
551  if (!target.has_value()) {
552  VALIDATION_LOG << "Could not bind texture of this type.";
553  return false;
554  }
555  gl.BindTexture(target.value(), handle.value());
556  } break;
557  case Type::kRenderBuffer:
559  gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
560  break;
561  }
562  InitializeContentsIfNecessary();
563  return true;
564 }
std::optional< GLuint > GetGLHandle() const
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:55
const HandleGLES & Get() const
void Reset()
Collect the managed handle and replace it with a dead handle.
constexpr std::optional< GLenum > ToTextureTarget(TextureType type)
Definition: formats_gles.h:204
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::UniqueHandleGLES::Get(), GetGLHandle(), impeller::Texture::GetTextureDescriptor(), impeller::UniqueHandleGLES::IsValid(), kRenderBuffer, kRenderBufferMultisampled, kTexture, kTextureMultisampled, impeller::UniqueHandleGLES::Reset(), impeller::ToTextureTarget(), and VALIDATION_LOG.

Referenced by GenerateMipmap().

◆ CachedFBOMatchesSubresource()

bool impeller::TextureGLES::CachedFBOMatchesSubresource ( uint32_t  mip_level,
uint32_t  slice 
) const

Whether the cached FBO is currently bound to (mip_level, slice). When false, the FBO must be re-attached before use.

Definition at line 782 of file texture_gles.cc.

783  {
784  return cached_fbo_mip_level_ == mip_level && cached_fbo_slice_ == slice;
785 }

Referenced by impeller::EncodeCommandsInReactor().

◆ ComputeTypeForBinding()

TextureGLES::Type impeller::TextureGLES::ComputeTypeForBinding ( GLenum  target) const

Definition at line 388 of file texture_gles.cc.

388  {
389  // When binding to a GL_READ_FRAMEBUFFER, any multisampled
390  // textures must be bound as single sampled.
391  if (target == GL_READ_FRAMEBUFFER && type_ == Type::kTextureMultisampled) {
392  return Type::kTexture;
393  }
394  return type_;
395 }

References kTexture, and kTextureMultisampled.

Referenced by SetAsFramebufferAttachment().

◆ CreatePlaceholder()

std::shared_ptr< TextureGLES > impeller::TextureGLES::CreatePlaceholder ( std::shared_ptr< ReactorGLES >  reactor,
TextureDescriptor  desc 
)
static

Create a "texture" that is never expected to be bound/unbound explicitly or initialized in any way. It only exists to setup a render pass description.

Parameters
[in]reactorThe reactor
[in]descThe description
Returns
If a texture placeholder could be created.

Definition at line 127 of file texture_gles.cc.

129  {
130  return TextureGLES::WrapFBO(std::move(reactor), desc, 0u);
131 }
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:95

References reactor, and WrapFBO().

Referenced by impeller::SurfaceGLES::WrapFBO().

◆ GenerateMipmap()

bool impeller::TextureGLES::GenerateMipmap ( )

Definition at line 597 of file texture_gles.cc.

597  {
598  if (!IsValid()) {
599  return false;
600  }
601 
602  auto type = GetTextureDescriptor().type;
603  switch (type) {
605  break;
607  VALIDATION_LOG << "Generating mipmaps for multisample textures is not "
608  "supported in the GLES backend.";
609  return false;
611  break;
613  break;
614  }
615 
616  if (!Bind()) {
617  return false;
618  }
619 
620  auto handle = GetGLHandle();
621  if (!handle.has_value()) {
622  return false;
623  }
624 
625  const auto& gl = reactor_->GetProcTable();
626  gl.GenerateMipmap(ToTextureType(type));
627  mipmap_generated_ = true;
628  return true;
629 }
bool IsValid() const override
bool mipmap_generated_
Definition: texture.h:69
constexpr GLenum ToTextureType(TextureType type)
Definition: formats_gles.h:190

References Bind(), GetGLHandle(), impeller::Texture::GetTextureDescriptor(), IsValid(), impeller::kTexture2D, impeller::kTexture2DMultisample, impeller::kTextureCube, impeller::kTextureExternalOES, impeller::Texture::mipmap_generated_, impeller::ToTextureType(), impeller::TextureDescriptor::type, and VALIDATION_LOG.

◆ GetCachedFBO()

const HandleGLES & impeller::TextureGLES::GetCachedFBO ( ) const

Retrieve the cached FBO object, or a dead handle if there is no object.

Definition at line 773 of file texture_gles.cc.

773  {
774  return cached_fbo_.Get();
775 }

References impeller::UniqueHandleGLES::Get().

Referenced by impeller::EncodeCommandsInReactor().

◆ GetFBO()

std::optional< GLuint > impeller::TextureGLES::GetFBO ( ) const

Definition at line 755 of file texture_gles.cc.

755  {
756  return wrapped_fbo_;
757 }

Referenced by impeller::EncodeCommandsInReactor().

◆ GetGLHandle()

std::optional< GLuint > impeller::TextureGLES::GetGLHandle ( ) const

Definition at line 525 of file texture_gles.cc.

525  {
526  if (!IsValid()) {
527  return std::nullopt;
528  }
529  return reactor_->GetGLHandle(handle_.Get());
530 }

References impeller::UniqueHandleGLES::Get(), and IsValid().

Referenced by Bind(), impeller::ConfigureFBO(), impeller::BlitCopyBufferToTextureCommandGLES::Encode(), GenerateMipmap(), impeller::interop::ImpellerTextureGetOpenGLHandle(), and SetAsFramebufferAttachment().

◆ GetSyncFence()

std::optional< HandleGLES > impeller::TextureGLES::GetSyncFence ( ) const

Definition at line 765 of file texture_gles.cc.

765  {
766  return fence_.IsValid() ? std::optional(fence_.Get()) : std::nullopt;
767 }
Definition: comparable.h:93

References impeller::UniqueHandleGLES::Get(), and impeller::UniqueHandleGLES::IsValid().

◆ GetType()

TextureGLES::Type impeller::TextureGLES::GetType ( ) const

Definition at line 631 of file texture_gles.cc.

631  {
632  return type_;
633 }

Referenced by impeller::BlitCopyBufferToTextureCommandGLES::Encode().

◆ IsSliceInitialized()

bool impeller::TextureGLES::IsSliceInitialized ( size_t  slice) const

Definition at line 576 of file texture_gles.cc.

576  {
577  return IsSliceMipLevelInitialized(slice, 0);
578 }
bool IsSliceMipLevelInitialized(size_t slice, size_t mip_level) const

References IsSliceMipLevelInitialized().

◆ IsSliceMipLevelInitialized()

bool impeller::TextureGLES::IsSliceMipLevelInitialized ( size_t  slice,
size_t  mip_level 
) const

Definition at line 588 of file texture_gles.cc.

589  {
590  if (slice >= slice_mip_initialized_.size() ||
591  mip_level >= kMaxTrackedMipLevels) {
592  return false;
593  }
594  return slice_mip_initialized_[slice].test(mip_level);
595 }

Referenced by impeller::BlitCopyBufferToTextureCommandGLES::Encode(), and IsSliceInitialized().

◆ IsValid()

bool impeller::TextureGLES::IsValid ( ) const
overridevirtual

Implements impeller::Texture.

Definition at line 184 of file texture_gles.cc.

184  {
185  return is_valid_;
186 }

Referenced by GenerateMipmap(), GetGLHandle(), and SetAsFramebufferAttachment().

◆ IsWrapped()

bool impeller::TextureGLES::IsWrapped ( ) const

Definition at line 751 of file texture_gles.cc.

751  {
752  return is_wrapped_;
753 }

Referenced by impeller::ConfigureFBO(), impeller::BlitCopyBufferToTextureCommandGLES::Encode(), and impeller::EncodeCommandsInReactor().

◆ Leak()

void impeller::TextureGLES::Leak ( )

Reset the internal texture state so that the reactor will not free the associated handle.

Definition at line 179 of file texture_gles.cc.

179  {
180  handle_.Release();
181 }
HandleGLES Release()
Release ownership of the handle.

References impeller::UniqueHandleGLES::Release().

◆ MarkContentsInitialized()

void impeller::TextureGLES::MarkContentsInitialized ( )

Indicates that all texture storage has already been allocated and contents initialized.

This is similar to calling MarkSliceInitialized with all slices.

See also
MarkSliceInitialized.

Definition at line 566 of file texture_gles.cc.

566  {
567  for (auto& slice_mips : slice_mip_initialized_) {
568  slice_mips.set();
569  }
570 }

◆ MarkSliceInitialized()

void impeller::TextureGLES::MarkSliceInitialized ( size_t  slice)

Indicates that a specific texture slice has been initialized.

Parameters
[in]sliceThe slice to mark as being initialized.

Definition at line 572 of file texture_gles.cc.

572  {
574 }
void MarkSliceMipLevelInitialized(size_t slice, size_t mip_level)
Indicates that storage for mip_level of slice has been allocated by a glTexImage2D call (or equivalen...

References MarkSliceMipLevelInitialized().

◆ MarkSliceMipLevelInitialized()

void impeller::TextureGLES::MarkSliceMipLevelInitialized ( size_t  slice,
size_t  mip_level 
)

Indicates that storage for mip_level of slice has been allocated by a glTexImage2D call (or equivalent).

GLES raises GL_INVALID_OPERATION when glTexSubImage2D targets a level that has not been previously defined, so every per-level upload must check this first and allocate on demand.

Parameters
[in]sliceThe slice (cubemap face for cubemaps, otherwise always 0).
[in]mip_levelThe mip level whose storage was allocated.

Definition at line 580 of file texture_gles.cc.

580  {
581  if (slice >= slice_mip_initialized_.size() ||
582  mip_level >= kMaxTrackedMipLevels) {
583  return;
584  }
585  slice_mip_initialized_[slice].set(mip_level);
586 }

Referenced by impeller::BlitCopyBufferToTextureCommandGLES::Encode(), and MarkSliceInitialized().

◆ SetAsFramebufferAttachment()

bool impeller::TextureGLES::SetAsFramebufferAttachment ( GLenum  target,
AttachmentType  attachment_type,
uint32_t  mip_level = 0,
uint32_t  slice = 0 
)

Definition at line 688 of file texture_gles.cc.

691  {
692  if (!IsValid()) {
693  return false;
694  }
695  InitializeContentsIfNecessary();
696  const auto& gl = reactor_->GetProcTable();
697  if (mip_level > 0 &&
698  !gl.GetCapabilities()->SupportsFramebufferRenderMipmap()) {
699  VALIDATION_LOG << "Rendering into a non-zero mip level is not supported on "
700  "the GLES backend.";
701  return false;
702  }
703  if (!EnsureSliceMipLevelStorage(slice, mip_level)) {
704  return false;
705  }
706  auto handle = GetGLHandle();
707  if (!handle.has_value()) {
708  return false;
709  }
710  const GLint level = static_cast<GLint>(mip_level);
711 
712  switch (ComputeTypeForBinding(target)) {
713  case Type::kTexture: {
714  // Cube maps attach a specific face; 2D textures attach the 2D target.
715  GLenum textarget =
717  ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice
718  : GL_TEXTURE_2D;
719  gl.FramebufferTexture2D(target, // target
720  ToAttachmentType(attachment_type), // attachment
721  textarget, // textarget
722  handle.value(), // texture
723  level // level
724  );
725  break;
726  }
728  gl.FramebufferTexture2DMultisampleEXT(
729  target, // target
730  ToAttachmentType(attachment_type), // attachment
731  GL_TEXTURE_2D, // textarget
732  handle.value(), // texture
733  level, // level
734  4 // samples
735  );
736  break;
737  case Type::kRenderBuffer:
739  gl.FramebufferRenderbuffer(
740  target, // target
741  ToAttachmentType(attachment_type), // attachment
742  GL_RENDERBUFFER, // render-buffer target
743  handle.value() // render-buffer
744  );
745  break;
746  }
747 
748  return true;
749 }
Type ComputeTypeForBinding(GLenum target) const
static GLenum ToAttachmentType(TextureGLES::AttachmentType point)

References ComputeTypeForBinding(), GetGLHandle(), impeller::Texture::GetTextureDescriptor(), IsValid(), kRenderBuffer, kRenderBufferMultisampled, kTexture, impeller::kTextureCube, kTextureMultisampled, impeller::ToAttachmentType(), impeller::TextureDescriptor::type, and VALIDATION_LOG.

Referenced by impeller::ConfigureFBO(), and impeller::EncodeCommandsInReactor().

◆ SetCachedFBO()

void impeller::TextureGLES::SetCachedFBO ( HandleGLES  fbo)

Store the FBO object for recycling in the 2D renderer.

The color0 texture used by the 2D renderer will use this texture object to store the associated FBO the first time it is used.

Definition at line 769 of file texture_gles.cc.

769  {
770  cached_fbo_ = UniqueHandleGLES(reactor_, fbo);
771 }

Referenced by impeller::EncodeCommandsInReactor().

◆ SetCachedFBOSubresource()

void impeller::TextureGLES::SetCachedFBOSubresource ( uint32_t  mip_level,
uint32_t  slice 
)

Records the subresource the cached FBO is currently bound to.

Definition at line 777 of file texture_gles.cc.

777  {
778  cached_fbo_mip_level_ = mip_level;
779  cached_fbo_slice_ = slice;
780 }

Referenced by impeller::EncodeCommandsInReactor().

◆ SetFence()

void impeller::TextureGLES::SetFence ( HandleGLES  fence)

Attach a sync fence to this texture that will be waited on before encoding a rendering operation that references it.

Parameters
[in]fenceA handle to a sync fence.

Definition at line 759 of file texture_gles.cc.

759  {
760  FML_DCHECK(!fence_.IsValid());
761  fence_ = UniqueHandleGLES(reactor_, fence);
762 }

References impeller::UniqueHandleGLES::IsValid().

◆ WrapFBO()

std::shared_ptr< TextureGLES > impeller::TextureGLES::WrapFBO ( std::shared_ptr< ReactorGLES >  reactor,
TextureDescriptor  desc,
GLuint  fbo 
)
static

Create a texture by wrapping an external framebuffer object whose lifecycle is owned by the caller.

This is useful for creating a render target for the default window managed framebuffer.

Parameters
[in]reactorThe reactor
[in]descThe description
[in]fboThe fbo
Returns
If a texture representation of the framebuffer could be created.

Definition at line 95 of file texture_gles.cc.

98  {
99  auto texture = std::shared_ptr<TextureGLES>(
100  new TextureGLES(std::move(reactor), desc, false, fbo, std::nullopt));
101  if (!texture->IsValid()) {
102  return nullptr;
103  }
104  return texture;
105 }

References reactor, and TextureGLES().

Referenced by CreatePlaceholder(), impeller::testing::TEST_P(), and impeller::SurfaceGLES::WrapFBO().

◆ WrapTexture()

std::shared_ptr< TextureGLES > impeller::TextureGLES::WrapTexture ( std::shared_ptr< ReactorGLES >  reactor,
TextureDescriptor  desc,
HandleGLES  external_handle 
)
static

Create a texture by wrapping an external OpenGL texture handle. Ownership of the texture handle is assumed by the reactor.

Parameters
[in]reactorThe reactor
[in]descThe description
[in]external_handleThe external handle
Returns
If a texture representation of the framebuffer could be created.

Definition at line 107 of file texture_gles.cc.

110  {
111  if (external_handle.IsDead()) {
112  VALIDATION_LOG << "Cannot wrap a dead handle.";
113  return nullptr;
114  }
115  if (external_handle.GetType() != HandleType::kTexture) {
116  VALIDATION_LOG << "Cannot wrap a non-texture handle.";
117  return nullptr;
118  }
119  auto texture = std::shared_ptr<TextureGLES>(new TextureGLES(
120  std::move(reactor), desc, false, std::nullopt, external_handle));
121  if (!texture->IsValid()) {
122  return nullptr;
123  }
124  return texture;
125 }

References impeller::HandleGLES::GetType(), impeller::HandleGLES::IsDead(), impeller::kTexture, reactor, TextureGLES(), and VALIDATION_LOG.

Referenced by impeller::interop::ImpellerTextureCreateWithOpenGLTextureHandleNew().


The documentation for this class was generated from the following files: