| Flutter Windows Embedder |

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
5 #include "flutter/shell/platform/windows/compositor_opengl.h"
6
7 #include "GLES3/gl3.h"
8 #include "flutter/shell/platform/windows/flutter_windows_engine.h"
9 #include "flutter/shell/platform/windows/flutter_windows_view.h"
10
11 namespace flutter {
12
13 namespace {
14
15 constexpr uint32_t kWindowFrameBufferId = 0;
16
17 // The metadata for an OpenGL framebuffer backing store.
18 struct FramebufferBackingStore {
19 uint32_t framebuffer_id;
20 uint32_t texture_id;
21 };
22
23 } // namespace
24
25 CompositorOpenGL::CompositorOpenGL(FlutterWindowsEngine* engine,
26 impeller::ProcTableGLES::Resolver resolver)
27 : engine_(engine), resolver_(resolver) {}
28
29 bool CompositorOpenGL::CreateBackingStore(
30 const FlutterBackingStoreConfig& config,
31 FlutterBackingStore* result) {
32 if (!is_initialized_ && !Initialize()) {
33 return false;
34 }
35
36 auto store = std::make_unique<FramebufferBackingStore>();
37
38 gl_->GenTextures(1, &store->texture_id);
39 gl_->GenFramebuffers(1, &store->framebuffer_id);
40
41 gl_->BindFramebuffer(GL_FRAMEBUFFER, store->framebuffer_id);
42
43 gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
44 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
45 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
46 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
47 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
48 gl_->TexImage2D(GL_TEXTURE_2D, 0, format_.general_format, config.size.width,
49 config.size.height, 0, format_.general_format,
50 GL_UNSIGNED_BYTE, nullptr);
51 gl_->BindTexture(GL_TEXTURE_2D, 0);
52
53 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
54 store->texture_id, 0);
55
56 result->type = kFlutterBackingStoreTypeOpenGL;
57 result->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
58 result->open_gl.framebuffer.name = store->framebuffer_id;
59 result->open_gl.framebuffer.target = format_.sized_format;
60 result->open_gl.framebuffer.user_data = store.release();
61 result->open_gl.framebuffer.destruction_callback = [](void* user_data) {
62 // Backing store destroyed in `CompositorOpenGL::CollectBackingStore`, set
63 // on FlutterCompositor.collect_backing_store_callback during engine start.
64 };
65 return true;
66 }
67
68 bool CompositorOpenGL::CollectBackingStore(const FlutterBackingStore* store) {
69 FML_DCHECK(is_initialized_);
70 FML_DCHECK(store->type == kFlutterBackingStoreTypeOpenGL);
71 FML_DCHECK(store->open_gl.type == kFlutterOpenGLTargetTypeFramebuffer);
72
73 auto user_data = static_cast<FramebufferBackingStore*>(
74 store->open_gl.framebuffer.user_data);
75
76 gl_->DeleteFramebuffers(1, &user_data->framebuffer_id);
77 gl_->DeleteTextures(1, &user_data->texture_id);
78
79 delete user_data;
80 return true;
81 }
82
83 bool CompositorOpenGL::Present(FlutterWindowsView* view,
84 const FlutterLayer** layers,
85 size_t layers_count) {
86 FML_DCHECK(view != nullptr);
87
88 // Clear the view if there are no layers to present.
89 if (layers_count == 0) {
90 // Normally the compositor is initialized when the first backing store is
91 // created. However, on an empty frame no backing stores are created and
92 // the present needs to initialize the compositor.
93 if (!is_initialized_ && !Initialize()) {
94 return false;
95 }
96
97 return Clear(view);
98 }
99
100 // TODO: Support compositing layers and platform views.
101 // See: https://github.com/flutter/flutter/issues/31713
102 FML_DCHECK(is_initialized_);
103 FML_DCHECK(layers_count == 1);
104 FML_DCHECK(layers[0]->offset.x == 0 && layers[0]->offset.y == 0);
105 FML_DCHECK(layers[0]->type == kFlutterLayerContentTypeBackingStore);
106 FML_DCHECK(layers[0]->backing_store->type == kFlutterBackingStoreTypeOpenGL);
107 FML_DCHECK(layers[0]->backing_store->open_gl.type ==
108 kFlutterOpenGLTargetTypeFramebuffer);
109
110 auto width = layers[0]->size.width;
111 auto height = layers[0]->size.height;
112
113 // Check if this frame can be presented. This resizes the surface if a resize
114 // is pending and |width| and |height| match the target size.
115 if (!view->OnFrameGenerated(width, height)) {
116 return false;
117 }
118
119 // |OnFrameGenerated| should return false if the surface isn't valid.
120 FML_DCHECK(view->surface() != nullptr);
121 FML_DCHECK(view->surface()->IsValid());
122
123 egl::WindowSurface* surface = view->surface();
124 if (!surface->MakeCurrent()) {
125 return false;
126 }
127
128 auto source_id = layers[0]->backing_store->open_gl.framebuffer.name;
129
130 // Disable the scissor test as it can affect blit operations.
131 // Prevents regressions like: https://github.com/flutter/flutter/issues/140828
132 // See OpenGL specification version 4.6, section 18.3.1.
133 gl_->Disable(GL_SCISSOR_TEST);
134
135 gl_->BindFramebuffer(GL_READ_FRAMEBUFFER, source_id);
136 gl_->BindFramebuffer(GL_DRAW_FRAMEBUFFER, kWindowFrameBufferId);
137
138 gl_->BlitFramebuffer(0, // srcX0
139 0, // srcY0
140 width, // srcX1
141 height, // srcY1
142 0, // dstX0
143 0, // dstY0
144 width, // dstX1
145 height, // dstY1
146 GL_COLOR_BUFFER_BIT, // mask
147 GL_NEAREST // filter
148 );
149
150 if (!surface->SwapBuffers()) {
151 return false;
152 }
153
154 view->OnFramePresented();
155 return true;
156 }
157
158 bool CompositorOpenGL::Initialize() {
159 FML_DCHECK(!is_initialized_);
160
161 egl::Manager* manager = engine_->egl_manager();
162 if (!manager) {
163 return false;
164 }
165
166 if (!manager->render_context()->MakeCurrent()) {
167 return false;
168 }
169
170 gl_ = std::make_unique<impeller::ProcTableGLES>(resolver_);
171 if (!gl_->IsValid()) {
172 gl_.reset();
173 return false;
174 }
175
176 if (gl_->GetDescription()->HasExtension("GL_EXT_texture_format_BGRA8888")) {
177 format_.sized_format = GL_BGRA8_EXT;
178 format_.general_format = GL_BGRA_EXT;
179 } else {
180 format_.sized_format = GL_RGBA8;
181 format_.general_format = GL_RGBA;
182 }
183
184 is_initialized_ = true;
185 return true;
186 }
187
188 bool CompositorOpenGL::Clear(FlutterWindowsView* view) {
189 FML_DCHECK(is_initialized_);
190
191 // Check if this frame can be presented. This resizes the surface if needed.
192 if (!view->OnEmptyFrameGenerated()) {
193 return false;
194 }
195
196 // |OnEmptyFrameGenerated| should return false if the surface isn't valid.
197 FML_DCHECK(view->surface() != nullptr);
198 FML_DCHECK(view->surface()->IsValid());
199
200 egl::WindowSurface* surface = view->surface();
201 if (!surface->MakeCurrent()) {
202 return false;
203 }
204
205 gl_->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
206 gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
207
208 if (!surface->SwapBuffers()) {
209 return false;
210 }
211
212 view->OnFramePresented();
213 return true;
214 }
215
216 } // namespace flutter
flutter::egl::Manager::render_context
virtual Context * render_context() const
Definition: manager.cc:318
flutter::FlutterWindowsView
Definition: flutter_windows_view.h:34
flutter::FlutterWindowsView::surface
egl::WindowSurface * surface() const
Definition: flutter_windows_view.cc:750
flutter::egl::WindowSurface
Definition: window_surface.h:19
user_data
void * user_data
Definition: flutter_windows_view_unittests.cc:53
flutter::CompositorOpenGL::CompositorOpenGL
CompositorOpenGL(FlutterWindowsEngine *engine, impeller::ProcTableGLES::Resolver resolver)
Definition: compositor_opengl.cc:25
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:90
flutter::egl::Context::MakeCurrent
virtual bool MakeCurrent() const
Definition: context.cc:29
flutter::CompositorOpenGL::CreateBackingStore
bool CreateBackingStore(const FlutterBackingStoreConfig &config, FlutterBackingStore *result) override
|Compositor|
Definition: compositor_opengl.cc:29
framebuffer_id
uint32_t framebuffer_id
Definition: compositor_opengl.cc:19
flutter_windows_view.h
flutter::egl::Surface::IsValid
virtual bool IsValid() const
Definition: surface.cc:19
flutter::CompositorOpenGL::CollectBackingStore
bool CollectBackingStore(const FlutterBackingStore *store) override
|Compositor|
Definition: compositor_opengl.cc:68
flutter::egl::Surface::MakeCurrent
virtual bool MakeCurrent() const
Definition: surface.cc:50
compositor_opengl.h
flutter::FlutterWindowsView::OnFrameGenerated
bool OnFrameGenerated(size_t width, size_t height)
Definition: flutter_windows_view.cc:153
flutter::egl::Surface::SwapBuffers
virtual bool SwapBuffers() const
Definition: surface.cc:59
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::egl::Manager
Definition: manager.h:31
type
enum flutter::testing::@88::KeyboardChange::Type type
flutter::CompositorOpenGL::Present
bool Present(FlutterWindowsView *view, const FlutterLayer **layers, size_t layers_count) override
|Compositor|
Definition: compositor_opengl.cc:83
flutter_windows_engine.h
flutter::FlutterWindowsEngine::egl_manager
egl::Manager * egl_manager() const
Definition: flutter_windows_engine.h:165
texture_id
uint32_t texture_id
Definition: compositor_opengl.cc:20
flutter::FlutterWindowsView::OnFramePresented
virtual void OnFramePresented()
Definition: flutter_windows_view.cc:646