10 #include "flutter/fml/mapping.h"
11 #include "flutter/fml/trace_event.h"
22 const auto render_target =
24 if (usage == render_target) {
54 reactor_(
std::move(reactor)),
57 is_wrapped_(is_wrapped) {
66 reactor_->GetProcTable().GetCapabilities()->max_texture_size;
67 if (tex_size.Max(max_size) != max_size) {
69 <<
" would exceed max supported size of " << max_size <<
".";
77 reactor_->CollectHandle(handle_);
81 bool TextureGLES::IsValid()
const {
86 void TextureGLES::SetLabel(std::string_view label) {
87 reactor_->SetDebugLabel(handle_, std::string{label.data(), label.size()});
94 std::shared_ptr<const fml::Mapping>
data;
97 switch (pixel_format) {
101 type = GL_UNSIGNED_BYTE;
109 type = GL_UNSIGNED_BYTE;
119 type = GL_HALF_FLOAT;
136 std::shared_ptr<const fml::Mapping> mapping) {
137 switch (pixel_format) {
143 type = GL_UNSIGNED_BYTE;
144 data = std::move(mapping);
150 type = GL_UNSIGNED_BYTE;
151 data = std::move(mapping);
158 data = std::move(mapping);
164 type = GL_HALF_FLOAT;
165 data = std::move(mapping);
187 bool is_valid_ =
false;
191 bool TextureGLES::OnSetContents(
const uint8_t* contents,
198 bool TextureGLES::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
204 if (mapping->GetSize() == 0u) {
208 if (mapping->GetMapping() ==
nullptr) {
213 VALIDATION_LOG <<
"Incorrect texture usage flags for setting contents on "
214 "this texture object.";
219 VALIDATION_LOG <<
"Cannot set the contents of a wrapped texture.";
225 if (tex_descriptor.size.IsEmpty()) {
229 if (!tex_descriptor.IsValid()) {
233 if (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 auto data = std::make_shared<TexImage2DData>(tex_descriptor.format,
260 if (!data || !data->IsValid()) {
267 size = tex_descriptor.size,
270 ](
const auto& reactor) {
271 auto gl_handle = reactor.GetGLHandle(handle);
272 if (!gl_handle.has_value()) {
274 <<
"Texture was collected before it could be uploaded to the GPU.";
277 const auto& gl = reactor.GetProcTable();
278 gl.BindTexture(texture_type, gl_handle.value());
279 const GLvoid* tex_data =
nullptr;
281 tex_data = data->data->GetMapping();
285 TRACE_EVENT1(
"impeller",
"TexImage2DUpload",
"Bytes",
286 std::to_string(data->data->GetSize()).c_str());
287 gl.TexImage2D(texture_target,
289 data->internal_format,
293 data->external_format,
300 contents_initialized_ = reactor_->AddOperation(texture_upload);
301 return contents_initialized_;
305 ISize TextureGLES::GetSize()
const {
319 return GL_STENCIL_INDEX8;
321 return GL_DEPTH24_STENCIL8;
323 return GL_DEPTH32F_STENCIL8;
338 void TextureGLES::InitializeContentsIfNecessary()
const {
342 if (contents_initialized_) {
345 contents_initialized_ =
true;
351 auto size = GetSize();
353 if (size.IsEmpty()) {
357 const auto& gl = reactor_->GetProcTable();
358 auto handle = reactor_->GetGLHandle(handle_);
359 if (!handle.has_value()) {
360 VALIDATION_LOG <<
"Could not initialize the contents of texture.";
367 if (!tex_data.IsValid()) {
371 gl.BindTexture(GL_TEXTURE_2D, handle.value());
373 TRACE_EVENT0(
"impeller",
"TexImage2DInitialization");
374 gl.TexImage2D(GL_TEXTURE_2D,
376 tex_data.internal_format,
380 tex_data.external_format,
388 auto render_buffer_format =
390 if (!render_buffer_format.has_value()) {
394 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
396 TRACE_EVENT0(
"impeller",
"RenderBufferStorageInitialization");
397 gl.RenderbufferStorage(GL_RENDERBUFFER,
398 render_buffer_format.value(),
405 auto render_buffer_msaa =
407 if (!render_buffer_msaa.has_value()) {
411 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
413 TRACE_EVENT0(
"impeller",
"RenderBufferStorageInitialization");
414 gl.RenderbufferStorageMultisampleEXT(
417 render_buffer_msaa.value(),
431 return reactor_->GetGLHandle(handle_);
436 if (!handle.has_value()) {
439 const auto& gl = reactor_->GetProcTable();
443 if (!target.has_value()) {
447 gl.BindTexture(target.value(), handle.value());
452 gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
455 InitializeContentsIfNecessary();
469 VALIDATION_LOG <<
"Generating mipmaps for multisample textures is not "
470 "supported in the GLES backend.";
483 if (!handle.has_value()) {
487 const auto& gl = reactor_->GetProcTable();
500 return GL_COLOR_ATTACHMENT0;
502 return GL_DEPTH_ATTACHMENT;
504 return GL_STENCIL_ATTACHMENT;
514 InitializeContentsIfNecessary();
516 if (!handle.has_value()) {
519 const auto& gl = reactor_->GetProcTable();
522 gl.FramebufferTexture2D(target,
530 gl.FramebufferRenderbuffer(target,
539 gl.FramebufferTexture2DMultisampleEXT(
553 Scalar TextureGLES::GetYCoordScale()
const {