23static bool IsDepthStencilFormat(
PixelFormat format) {
49 const TextureDescriptor& desc,
50 const std::shared_ptr<const CapabilitiesGLES>& capabilities) {
54 if (usage == render_target && IsDepthStencilFormat(desc.format)) {
58 return is_msaa ? (capabilities->SupportsImplicitResolvingMSAA()
79 std::shared_ptr<ReactorGLES> reactor,
82 auto texture = std::shared_ptr<TextureGLES>(
83 new TextureGLES(std::move(reactor), desc,
false, fbo, std::nullopt));
91 std::shared_ptr<ReactorGLES> reactor,
94 if (external_handle.
IsDead()) {
103 std::move(reactor), desc,
false, std::nullopt, external_handle));
111 std::shared_ptr<ReactorGLES> reactor,
129 std::optional<GLuint> fbo,
130 std::optional<HandleGLES> external_handle)
132 reactor_(
std::move(reactor)),
133 type_(GetTextureTypeFromDescriptor(
134 GetTextureDescriptor(),
135 reactor_->GetProcTable().GetCapabilities())),
136 handle_(external_handle.has_value()
137 ? external_handle.
value()
138 : (threadsafe ? reactor_->CreateHandle(
ToHandleType(type_))
139 : reactor_->CreateUntrackedHandle(
141 is_wrapped_(fbo.has_value() || external_handle.has_value()),
149 const auto max_size =
150 reactor_->GetProcTable().GetCapabilities()->max_texture_size;
151 if (tex_size.Max(max_size) != max_size) {
153 <<
" would exceed max supported size of " << max_size <<
".";
162 reactor_->CollectHandle(handle_);
163 if (!cached_fbo_.
IsDead()) {
164 reactor_->CollectHandle(cached_fbo_);
178void TextureGLES::SetLabel(std::string_view label) {
180 reactor_->SetDebugLabel(handle_, label);
185void TextureGLES::SetLabel(std::string_view label, std::string_view trailing) {
187 if (reactor_->CanSetDebugLabels()) {
188 reactor_->SetDebugLabel(handle_, std::format(
"{} {}", label, trailing));
194bool TextureGLES::OnSetContents(
const uint8_t* contents,
201bool TextureGLES::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
207 if (mapping->GetSize() == 0u) {
211 if (mapping->GetMapping() ==
nullptr) {
216 VALIDATION_LOG <<
"Incorrect texture usage flags for setting contents on "
217 "this texture object.";
222 VALIDATION_LOG <<
"Cannot set the contents of a wrapped texture.";
228 if (tex_descriptor.size.IsEmpty()) {
232 if (!tex_descriptor.IsValid() ||
233 mapping->GetSize() < tex_descriptor.GetByteSizeOfBaseMipLevel()) {
238 GLenum texture_target;
239 switch (tex_descriptor.type) {
241 texture_type = GL_TEXTURE_2D;
242 texture_target = GL_TEXTURE_2D;
245 VALIDATION_LOG <<
"Multisample texture uploading is not supported for "
246 "the OpenGLES backend.";
249 texture_type = GL_TEXTURE_CUBE_MAP;
250 texture_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
253 texture_type = GL_TEXTURE_EXTERNAL_OES;
254 texture_target = GL_TEXTURE_EXTERNAL_OES;
258 std::optional<PixelFormatGLES> gles_format =
261 reactor_->GetProcTable().GetDescription()->HasExtension(
262 "GL_EXT_texture_format_BGRA8888"));
263 if (!gles_format.has_value()) {
270 format = gles_format.value(),
271 size = tex_descriptor.size,
274 ](
const auto& reactor) {
275 auto gl_handle = reactor.GetGLHandle(handle);
276 if (!gl_handle.has_value()) {
278 <<
"Texture was collected before it could be uploaded to the GPU.";
281 const auto& gl = reactor.GetProcTable();
282 gl.BindTexture(texture_type, gl_handle.value());
283 const GLvoid* tex_data =
nullptr;
285 tex_data = mapping->GetMapping();
290 std::to_string(mapping->GetSize()).c_str());
291 gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
292 gl.TexImage2D(texture_target,
304 const bool added = reactor_->AddOperation(texture_upload);
312ISize TextureGLES::GetSize()
const {
326 return GL_STENCIL_INDEX8;
328 return GL_DEPTH24_STENCIL8;
330 return GL_DEPTH32F_STENCIL8;
355void TextureGLES::InitializeContentsIfNecessary() {
366 auto size = GetSize();
368 if (
size.IsEmpty()) {
373 const auto& gl = reactor_->GetProcTable();
374 std::optional<GLuint> handle = reactor_->GetGLHandle(handle_);
375 if (!handle.has_value()) {
376 VALIDATION_LOG <<
"Could not initialize the contents of texture.";
387 reactor_->GetProcTable().GetDescription()->HasExtension(
388 "GL_EXT_texture_format_BGRA8888"));
389 if (!gles_format.has_value()) {
400 gl.BindTexture(GL_TEXTURE_CUBE_MAP, handle.value());
401 for (
size_t face = 0; face < 6; ++face) {
402 gl.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
404 gles_format->internal_format,
408 gles_format->external_format,
421 gl.BindTexture(GL_TEXTURE_2D, handle.value());
422 gl.TexImage2D(GL_TEXTURE_2D,
424 gles_format->internal_format,
428 gles_format->external_format,
437 auto render_buffer_format =
439 if (!render_buffer_format.has_value()) {
443 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
449 if (gl.GetCapabilities()->SupportsImplicitResolvingMSAA()) {
450 gl.RenderbufferStorageMultisampleEXT(
453 render_buffer_format.value(),
458 gl.RenderbufferStorageMultisample(
461 render_buffer_format.value(),
467 gl.RenderbufferStorage(
469 render_buffer_format.value(),
487 return reactor_->GetGLHandle(handle_);
492 if (!handle.has_value()) {
495 const auto& gl = reactor_->GetProcTable();
497 if (fence_.has_value()) {
498 std::optional<GLsync> fence = reactor_->GetGLFence(fence_.value());
499 if (fence.has_value()) {
500 gl.WaitSync(fence.value(), 0, GL_TIMEOUT_IGNORED);
502 reactor_->CollectHandle(fence_.value());
503 fence_ = std::nullopt;
510 if (!
target.has_value()) {
514 gl.BindTexture(
target.value(), handle.value());
518 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
521 InitializeContentsIfNecessary();
526 for (
auto& slice_mips : slice_mip_initialized_) {
540 if (slice >= slice_mip_initialized_.size() ||
541 mip_level >= kMaxTrackedMipLevels) {
544 slice_mip_initialized_[slice].set(mip_level);
548 size_t mip_level)
const {
549 if (slice >= slice_mip_initialized_.size() ||
550 mip_level >= kMaxTrackedMipLevels) {
553 return slice_mip_initialized_[slice].test(mip_level);
566 VALIDATION_LOG <<
"Generating mipmaps for multisample textures is not "
567 "supported in the GLES backend.";
580 if (!handle.has_value()) {
584 const auto& gl = reactor_->GetProcTable();
597 return GL_COLOR_ATTACHMENT0;
599 return GL_DEPTH_ATTACHMENT;
601 return GL_STENCIL_ATTACHMENT;
610 InitializeContentsIfNecessary();
612 if (!handle.has_value()) {
615 const auto& gl = reactor_->GetProcTable();
619 gl.FramebufferTexture2D(
target,
627 gl.FramebufferTexture2DMultisampleEXT(
638 gl.FramebufferRenderbuffer(
651Scalar TextureGLES::GetYCoordScale()
const {
Represents a handle to an underlying OpenGL object. Unlike OpenGL object handles, these handles can b...
constexpr bool IsDead() const
Determines if the handle is dead.
HandleType GetType() const
static HandleGLES DeadHandle()
Creates a dead handle.
std::function< void(const ReactorGLES &reactor)> Operation
void MarkSliceInitialized(size_t slice)
Indicates that a specific texture slice has been initialized.
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.
void MarkContentsInitialized()
Indicates that all texture storage has already been allocated and contents initialized.
const HandleGLES & GetCachedFBO() const
Retrieve the cached FBO object, or a dead handle if there is no object.
bool SetAsFramebufferAttachment(GLenum target, AttachmentType attachment_type)
std::optional< HandleGLES > GetSyncFence() const
bool IsSliceMipLevelInitialized(size_t slice, size_t mip_level) const
bool IsSliceInitialized(size_t slice) const
@ kRenderBufferMultisampled
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...
bool IsValid() const override
void SetFence(HandleGLES fence)
Attach a sync fence to this texture that will be waited on before encoding a rendering operation that...
void Leak()
Reset the internal texture state so that the reactor will not free the associated handle.
void SetCachedFBO(HandleGLES fbo)
TextureGLES(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, bool threadsafe=false)
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....
std::optional< GLuint > GetFBO() const
Type ComputeTypeForBinding(GLenum target) const
std::optional< GLuint > GetGLHandle() const
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...
const TextureDescriptor & GetTextureDescriptor() const
TextureCoordinateSystem GetCoordinateSystem() const
uint32_t uint32_t * format
#define FML_UNREACHABLE()
#define FML_DCHECK(condition)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
std::optional< PixelFormatGLES > ToPixelFormatGLES(PixelFormat pixel_format, bool supports_bgra)
constexpr std::optional< GLenum > ToTextureTarget(TextureType type)
std::shared_ptr< fml::Mapping > CreateMappingWithCopy(const uint8_t *contents, Bytes length)
Creates a mapping with copy of the bytes.
AllocationSize< 1u > Bytes
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
constexpr GLenum ToTextureType(TextureType type)
static std::optional< GLenum > ToRenderBufferFormat(PixelFormat format)
static GLenum ToAttachmentType(TextureGLES::AttachmentType point)
Mask< TextureUsage > TextureUsageMask
HandleType ToHandleType(TextureGLES::Type type)
impeller::ShaderType type
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)