| Flutter Impeller |

blit_command_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/blit_command_gles.h"
6
7 #include "flutter/fml/closure.h"
8 #include "impeller/base/validation.h"
9 #include "impeller/renderer/backend/gles/device_buffer_gles.h"
10 #include "impeller/renderer/backend/gles/texture_gles.h"
11
12 namespace impeller {
13
14 BlitEncodeGLES::~BlitEncodeGLES() = default;
15
16 static void DeleteFBO(const ProcTableGLES& gl, GLuint fbo, GLenum type) {
17 if (fbo != GL_NONE) {
18 gl.BindFramebuffer(type, GL_NONE);
19 gl.DeleteFramebuffers(1u, &fbo);
20 }
21 };
22
23 static std::optional<GLuint> ConfigureFBO(
24 const ProcTableGLES& gl,
25 const std::shared_ptr<Texture>& texture,
26 GLenum fbo_type) {
27 auto handle = TextureGLES::Cast(texture.get())->GetGLHandle();
28 if (!handle.has_value()) {
29 return std::nullopt;
30 }
31
32 if (TextureGLES::Cast(*texture).IsWrapped()) {
33 // The texture is attached to the default FBO, so there's no need to
34 // create/configure one.
35 gl.BindFramebuffer(fbo_type, 0);
36 return 0;
37 }
38
39 GLuint fbo;
40 gl.GenFramebuffers(1u, &fbo);
41 gl.BindFramebuffer(fbo_type, fbo);
42
43 if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment(
44 fbo_type, TextureGLES::AttachmentPoint::kColor0)) {
45 VALIDATION_LOG << "Could not attach texture to framebuffer.";
46 DeleteFBO(gl, fbo, fbo_type);
47 return std::nullopt;
48 }
49
50 if (gl.CheckFramebufferStatus(fbo_type) != GL_FRAMEBUFFER_COMPLETE) {
51 VALIDATION_LOG << "Could not create a complete frambuffer.";
52 DeleteFBO(gl, fbo, fbo_type);
53 return std::nullopt;
54 }
55
56 return fbo;
57 };
58
59 BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES() =
60 default;
61
62 std::string BlitCopyTextureToTextureCommandGLES::GetLabel() const {
63 return label;
64 }
65
66 bool BlitCopyTextureToTextureCommandGLES::Encode(
67 const ReactorGLES& reactor) const {
68 const auto& gl = reactor.GetProcTable();
69
70 // glBlitFramebuffer is a GLES3 proc. Since we target GLES2, we need to
71 // emulate the blit when it's not available in the driver.
72 if (!gl.BlitFramebuffer.IsAvailable()) {
73 // TODO(bdero): Emulate the blit using a raster draw call here.
74 FML_LOG(ERROR) << "Texture blit fallback not implemented yet for GLES2.";
75 return false;
76 }
77
78 GLuint read_fbo = GL_NONE;
79 GLuint draw_fbo = GL_NONE;
80 fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {
81 DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER);
82 DeleteFBO(gl, draw_fbo, GL_DRAW_FRAMEBUFFER);
83 });
84
85 {
86 auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
87 if (!read.has_value()) {
88 return false;
89 }
90 read_fbo = read.value();
91 }
92
93 {
94 auto draw = ConfigureFBO(gl, destination, GL_DRAW_FRAMEBUFFER);
95 if (!draw.has_value()) {
96 return false;
97 }
98 draw_fbo = draw.value();
99 }
100
101 gl.Disable(GL_SCISSOR_TEST);
102 gl.Disable(GL_DEPTH_TEST);
103 gl.Disable(GL_STENCIL_TEST);
104
105 gl.BlitFramebuffer(source_region.GetX(), // srcX0
106 source_region.GetY(), // srcY0
107 source_region.GetWidth(), // srcX1
108 source_region.GetHeight(), // srcY1
109 destination_origin.x, // dstX0
110 destination_origin.y, // dstY0
111 source_region.GetWidth(), // dstX1
112 source_region.GetHeight(), // dstY1
113 GL_COLOR_BUFFER_BIT, // mask
114 GL_NEAREST // filter
115 );
116
117 return true;
118 };
119
120 BlitCopyTextureToBufferCommandGLES::~BlitCopyTextureToBufferCommandGLES() =
121 default;
122
123 std::string BlitCopyTextureToBufferCommandGLES::GetLabel() const {
124 return label;
125 }
126
127 bool BlitCopyTextureToBufferCommandGLES::Encode(
128 const ReactorGLES& reactor) const {
129 if (source->GetTextureDescriptor().format != PixelFormat::kR8G8B8A8UNormInt) {
130 VALIDATION_LOG << "Only textures with pixel format RGBA are supported yet.";
131 return false;
132 }
133
134 const auto& gl = reactor.GetProcTable();
135
136 GLuint read_fbo = GL_NONE;
137 fml::ScopedCleanupClosure delete_fbos(
138 [&gl, &read_fbo]() { DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER); });
139
140 {
141 auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
142 if (!read.has_value()) {
143 return false;
144 }
145 read_fbo = read.value();
146 }
147
148 DeviceBufferGLES::Cast(*destination)
149 .UpdateBufferData([&gl, this](uint8_t* data, size_t length) {
150 gl.ReadPixels(source_region.GetX(), source_region.GetY(),
151 source_region.GetWidth(), source_region.GetHeight(),
152 GL_RGBA, GL_UNSIGNED_BYTE, data + destination_offset);
153 });
154
155 return true;
156 };
157
158 BlitGenerateMipmapCommandGLES::~BlitGenerateMipmapCommandGLES() = default;
159
160 std::string BlitGenerateMipmapCommandGLES::GetLabel() const {
161 return label;
162 }
163
164 bool BlitGenerateMipmapCommandGLES::Encode(const ReactorGLES& reactor) const {
165 auto texture_gles = TextureGLES::Cast(texture.get());
166 if (!texture_gles->GenerateMipmap()) {
167 return false;
168 }
169
170 return true;
171 };
172
173 } // namespace impeller
impeller::ReactorGLES::GetProcTable
const ProcTableGLES & GetProcTable() const
Get the OpenGL proc. table the reactor uses to manage handles.
Definition: reactor_gles.cc:48
impeller::TPoint::y
Type y
Definition: point.h:26
impeller::BlitCopyTextureToTextureCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:66
impeller::DeleteFBO
static void DeleteFBO(const ProcTableGLES &gl, GLuint fbo, GLenum type)
Definition: blit_command_gles.cc:16
impeller::ConfigureFBO
static std::optional< GLuint > ConfigureFBO(const ProcTableGLES &gl, const std::shared_ptr< Texture > &texture, GLenum fbo_type)
Definition: blit_command_gles.cc:23
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::BlitCopyTextureToTextureCommand::destination
std::shared_ptr< Texture > destination
Definition: blit_command.h:20
impeller::TextureGLES::GetGLHandle
std::optional< GLuint > GetGLHandle() const
Definition: texture_gles.cc:390
texture_gles.h
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:163
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:175
validation.h
impeller::BlitCopyTextureToTextureCommand::destination_origin
IPoint destination_origin
Definition: blit_command.h:22
impeller::TextureGLES::AttachmentPoint::kColor0
@ kColor0
impeller::BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES
~BlitCopyTextureToTextureCommandGLES() override
impeller::BlitGenerateMipmapCommand::texture
std::shared_ptr< Texture > texture
Definition: blit_command.h:39
device_buffer_gles.h
impeller::BlitCommand::label
std::string label
Definition: blit_command.h:15
impeller::BlitGenerateMipmapCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:164
impeller::TextureGLES::SetAsFramebufferAttachment
bool SetAsFramebufferAttachment(GLenum target, AttachmentPoint point) const
Definition: texture_gles.cc:471
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:171
impeller::BlitCopyTextureToBufferCommand::destination_offset
size_t destination_offset
Definition: blit_command.h:29
impeller::BlitCopyTextureToBufferCommand::destination
std::shared_ptr< DeviceBuffer > destination
Definition: blit_command.h:27
impeller::BlitCopyTextureToBufferCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:123
impeller::ProcTableGLES
Definition: proc_table_gles.h:217
impeller::BlitCopyTextureToTextureCommand::source
std::shared_ptr< Texture > source
Definition: blit_command.h:19
impeller::BlitCopyTextureToBufferCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:127
impeller::DeviceBufferGLES::UpdateBufferData
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
Definition: device_buffer_gles.cc:113
impeller::TPoint::x
Type x
Definition: point.h:25
blit_command_gles.h
impeller::BlitGenerateMipmapCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:160
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::BlitCopyTextureToBufferCommandGLES::~BlitCopyTextureToBufferCommandGLES
~BlitCopyTextureToBufferCommandGLES() override
impeller::BackendCast< TextureGLES, Texture >::Cast
static TextureGLES & Cast(Texture &base)
Definition: backend_cast.h:15
impeller::BlitCopyTextureToBufferCommand::source
std::shared_ptr< Texture > source
Definition: blit_command.h:26
impeller::BlitCopyTextureToTextureCommand::source_region
IRect source_region
Definition: blit_command.h:21
impeller::ReactorGLES
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
Definition: reactor_gles.h:56
impeller::TextureGLES::IsWrapped
IsWrapped
Definition: texture_gles.h:25
impeller::BlitGenerateMipmapCommandGLES::~BlitGenerateMipmapCommandGLES
~BlitGenerateMipmapCommandGLES() override
impeller::BlitCopyTextureToTextureCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:62
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:167
impeller
Definition: aiks_context.cc:10
impeller::BlitCopyTextureToBufferCommand::source_region
IRect source_region
Definition: blit_command.h:28
impeller::BlitEncodeGLES::~BlitEncodeGLES
virtual ~BlitEncodeGLES()