Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
6
7#include "flutter/fml/closure.h"
11
12namespace impeller {
13
15
16static 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
23static 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
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 framebuffer.";
52 DeleteFBO(gl, fbo, fbo_type);
53 return std::nullopt;
54 }
55
56 return fbo;
57};
58
60 default;
61
63 return label;
64}
65
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
121 default;
122
124 return label;
125}
126
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
149 .UpdateBufferData([&gl, this](uint8_t* data, size_t length) {
150 gl.ReadPixels(source_region.GetX(), source_region.GetY(),
152 GL_RGBA, GL_UNSIGNED_BYTE, data + destination_offset);
153 });
154
155 return true;
156};
157
159
161 return label;
162}
163
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
static bool read(SkStream *stream, void *buffer, size_t amount)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition aaclip.cpp:27
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition closure.h:32
static TextureGLES & Cast(Texture &base)
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
const ProcTableGLES & GetProcTable() const
Get the OpenGL proc. table the reactor uses to manage handles.
bool SetAsFramebufferAttachment(GLenum target, AttachmentType attachment_type) const
std::optional< GLuint > GetGLHandle() const
#define FML_LOG(severity)
Definition logging.h:82
size_t length
FlTexture * texture
static std::optional< GLuint > ConfigureFBO(const ProcTableGLES &gl, const std::shared_ptr< Texture > &texture, GLenum fbo_type)
static void DeleteFBO(const ProcTableGLES &gl, GLuint fbo, GLenum type)
bool Encode(const ReactorGLES &reactor) const override
std::shared_ptr< DeviceBuffer > destination
std::shared_ptr< Texture > source
bool Encode(const ReactorGLES &reactor) const override
std::shared_ptr< Texture > destination
std::shared_ptr< Texture > source
bool Encode(const ReactorGLES &reactor) const override
std::shared_ptr< Texture > texture
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:304
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition rect.h:314
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:300
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition rect.h:308
#define ERROR(message)
#define VALIDATION_LOG
Definition validation.h:73