Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
compositor_opengl.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 "GLES3/gl3.h"
10
11namespace flutter {
12
13namespace {
14
15constexpr uint32_t kWindowFrameBufferId = 0;
16
17// The metadata for an OpenGL framebuffer backing store.
18struct FramebufferBackingStore {
19 uint32_t framebuffer_id = 0;
20 uint32_t texture_id = 0;
21 uint32_t depth_stencil_id = 0;
22};
23
24typedef const impeller::GLProc<decltype(glBlitFramebuffer)> BlitFramebufferProc;
25
26const BlitFramebufferProc& GetBlitFramebufferProc(
27 const impeller::ProcTableGLES& gl) {
28 if (gl.BlitFramebuffer.IsAvailable()) {
29 return gl.BlitFramebuffer;
30 } else if (gl.BlitFramebufferANGLE.IsAvailable()) {
31 return gl.BlitFramebufferANGLE;
32 }
33
34 // CompositorOpenGL::Initialize verifies that a blit procedure is available.
36}
37
38} // namespace
39
42 bool enable_impeller)
43 : engine_(engine), resolver_(resolver), enable_impeller_(enable_impeller) {}
44
46 const FlutterBackingStoreConfig& config,
47 FlutterBackingStore* result) {
48 if (!is_initialized_ && !Initialize()) {
49 return false;
50 }
51
52 auto store = std::make_unique<FramebufferBackingStore>();
53
54 gl_->GenTextures(1, &store->texture_id);
55 gl_->GenFramebuffers(1, &store->framebuffer_id);
56
57 gl_->BindFramebuffer(GL_FRAMEBUFFER, store->framebuffer_id);
58
59 gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
60 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
61 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
62 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
63 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
64 gl_->TexImage2D(GL_TEXTURE_2D, 0, format_.general_format, config.size.width,
65 config.size.height, 0, format_.general_format,
66 GL_UNSIGNED_BYTE, nullptr);
67 gl_->BindTexture(GL_TEXTURE_2D, 0);
68
69 if (enable_impeller_) {
70 if (supports_implicit_msaa_) {
71 // MSAA color attachment
72 gl_->FramebufferTexture2DMultisampleEXT(
73 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
74 store->texture_id, 0, 4);
75 } else {
76 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
77 GL_TEXTURE_2D, store->texture_id, 0);
78 }
79
80 // Impeller always requires depth/stencil attachment.
81 gl_->GenRenderbuffers(1, &store->depth_stencil_id);
82 gl_->BindRenderbuffer(GL_RENDERBUFFER, store->depth_stencil_id);
83 if (supports_implicit_msaa_) {
84 gl_->RenderbufferStorageMultisampleEXT(
85 GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, config.size.width,
86 config.size.height);
87 } else {
88 gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
89 config.size.width, config.size.height);
90 }
91 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
92 GL_RENDERBUFFER, store->depth_stencil_id);
93 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
94 GL_RENDERBUFFER, store->depth_stencil_id);
95 } else {
96 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
97 GL_TEXTURE_2D, store->texture_id, 0);
98 }
99
102 result->open_gl.framebuffer.name = store->framebuffer_id;
103 result->open_gl.framebuffer.target = format_.sized_format;
104 result->open_gl.framebuffer.user_data = store.release();
106 // Backing store destroyed in `CompositorOpenGL::CollectBackingStore`, set
107 // on FlutterCompositor.collect_backing_store_callback during engine start.
108 };
109 return true;
110}
111
113 FML_DCHECK(is_initialized_);
116
117 auto user_data = static_cast<FramebufferBackingStore*>(
119
120 gl_->DeleteFramebuffers(1, &user_data->framebuffer_id);
121 gl_->DeleteTextures(1, &user_data->texture_id);
122
123 if (user_data->depth_stencil_id != 0) {
124 gl_->DeleteRenderbuffers(1, &user_data->depth_stencil_id);
125 }
126
127 delete user_data;
128 return true;
129}
130
132 const FlutterLayer** layers,
133 size_t layers_count) {
134 FML_DCHECK(view != nullptr);
135
136 // Clear the view if there are no layers to present.
137 if (layers_count == 0) {
138 // Normally the compositor is initialized when the first backing store is
139 // created. However, on an empty frame no backing stores are created and
140 // the present needs to initialize the compositor.
141 if (!is_initialized_ && !Initialize()) {
142 return false;
143 }
144
145 return Clear(view);
146 }
147
148 // TODO: Support compositing layers and platform views.
149 // See: https://github.com/flutter/flutter/issues/31713
150 FML_DCHECK(is_initialized_);
152 FML_DCHECK(layers[0]->offset.x == 0 && layers[0]->offset.y == 0);
155 FML_DCHECK(layers[0]->backing_store->open_gl.type ==
157
158 auto width = layers[0]->size.width;
159 auto height = layers[0]->size.height;
160
161 // Check if this frame can be presented. This resizes the surface if a resize
162 // is pending and |width| and |height| match the target size.
163 if (!view->OnFrameGenerated(width, height)) {
164 return false;
165 }
166
167 // |OnFrameGenerated| should return false if the surface isn't valid.
168 FML_DCHECK(view->surface() != nullptr);
169 FML_DCHECK(view->surface()->IsValid());
170
171 egl::WindowSurface* surface = view->surface();
172 if (!surface->MakeCurrent()) {
173 return false;
174 }
175
176 auto source_id = layers[0]->backing_store->open_gl.framebuffer.name;
177
178 // Disable the scissor test as it can affect blit operations.
179 // Prevents regressions like: https://github.com/flutter/flutter/issues/140828
180 // See OpenGL specification version 4.6, section 18.3.1.
181 gl_->Disable(GL_SCISSOR_TEST);
182 gl_->BindFramebuffer(GL_READ_FRAMEBUFFER, source_id);
183 gl_->BindFramebuffer(GL_DRAW_FRAMEBUFFER, kWindowFrameBufferId);
184
185 auto blitFramebuffer = GetBlitFramebufferProc(*gl_);
186 blitFramebuffer(0, // srcX0
187 0, // srcY0
188 width, // srcX1
189 height, // srcY1
190 0, // dstX0
191 0, // dstY0
192 width, // dstX1
193 height, // dstY1
194 GL_COLOR_BUFFER_BIT, // mask
195 GL_NEAREST // filter
196 );
197
198 if (!surface->SwapBuffers()) {
199 return false;
200 }
201
202 view->OnFramePresented();
203 return true;
204}
205
206bool CompositorOpenGL::Initialize() {
207 FML_DCHECK(!is_initialized_);
208
209 egl::Manager* manager = engine_->egl_manager();
210 if (!manager) {
211 return false;
212 }
213
214 if (!manager->render_context()->MakeCurrent()) {
215 return false;
216 }
217
218 gl_ = std::make_unique<impeller::ProcTableGLES>(resolver_);
219 if (!gl_->IsValid()) {
220 gl_.reset();
221 return false;
222 }
223
224 if (gl_->GetDescription()->HasExtension("GL_EXT_texture_format_BGRA8888")) {
225 format_.sized_format = GL_BGRA8_EXT;
226 format_.general_format = GL_BGRA_EXT;
227 } else {
228 format_.sized_format = GL_RGBA8;
229 format_.general_format = GL_RGBA;
230 }
231
232 if (!gl_->BlitFramebuffer.IsAvailable() &&
233 !gl_->BlitFramebufferANGLE.IsAvailable()) {
234 FML_LOG(ERROR) << "Unable to find OpenGL blit framebuffer procedure.";
235 return false;
236 }
237
238 supports_implicit_msaa_ =
239 gl_->GetCapabilities()->SupportsImplicitResolvingMSAA();
240
241 is_initialized_ = true;
242 return true;
243}
244
245bool CompositorOpenGL::Clear(FlutterWindowsView* view) {
246 FML_DCHECK(is_initialized_);
247
248 // Check if this frame can be presented. This resizes the surface if needed.
249 if (!view->OnEmptyFrameGenerated()) {
250 return false;
251 }
252
253 // |OnEmptyFrameGenerated| should return false if the surface isn't valid.
254 FML_DCHECK(view->surface() != nullptr);
255 FML_DCHECK(view->surface()->IsValid());
256
257 egl::WindowSurface* surface = view->surface();
258 if (!surface->MakeCurrent()) {
259 return false;
260 }
261
262 gl_->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
263 gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
264
265 if (!surface->SwapBuffers()) {
266 return false;
267 }
268
269 view->OnFramePresented();
270 return true;
271}
272
273} // namespace flutter
bool Present(FlutterWindowsView *view, const FlutterLayer **layers, size_t layers_count) override
|Compositor|
bool CreateBackingStore(const FlutterBackingStoreConfig &config, FlutterBackingStore *result) override
|Compositor|
bool CollectBackingStore(const FlutterBackingStore *store) override
|Compositor|
CompositorOpenGL(FlutterWindowsEngine *engine, impeller::ProcTableGLES::Resolver resolver, bool enable_impeller)
std::function< void *(const char *function_name)> Resolver
uint32_t framebuffer_id
uint32_t depth_stencil_id
@ kFlutterLayerContentTypeBackingStore
Definition embedder.h:2157
@ kFlutterOpenGLTargetTypeFramebuffer
Definition embedder.h:424
@ kFlutterBackingStoreTypeOpenGL
Definition embedder.h:2106
FlutterEngine engine
Definition main.cc:84
VkSurfaceKHR surface
Definition main.cc:65
FlView * view
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
#define FML_LOG(severity)
Definition logging.h:101
#define FML_UNREACHABLE()
Definition logging.h:128
#define FML_DCHECK(condition)
Definition logging.h:122
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 manager
impeller::ShaderType type
int32_t height
int32_t width
FlutterSize size
The size of the render target the engine expects to render into.
Definition embedder.h:2148
FlutterBackingStoreType type
Specifies the type of backing store.
Definition embedder.h:2126
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition embedder.h:2132
FlutterPoint offset
Definition embedder.h:2200
FlutterLayerContentType type
Definition embedder.h:2189
const FlutterBackingStore * backing_store
Definition embedder.h:2193
FlutterSize size
The size of the layer (in physical pixels).
Definition embedder.h:2202
FlutterOpenGLTargetType type
Definition embedder.h:1969
FlutterOpenGLFramebuffer framebuffer
Definition embedder.h:1975
uint32_t name
The name of the framebuffer.
Definition embedder.h:551
VoidCallback destruction_callback
Definition embedder.h:558
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition embedder.h:554
double height
Definition embedder.h:636
double width
Definition embedder.h:635
int64_t texture_id