Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9b70e4b

Browse files
committed
[Windows] Move to FlutterCompositor for rendering
1 parent 101396f commit 9b70e4b

13 files changed

+541
-25
lines changed

impeller/renderer/backend/gles/description_gles.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ std::string DescriptionGLES::GetString() const {
156156
return stream.str();
157157
}
158158

159+
Version DescriptionGLES::GetGlVersion() const {
160+
return gl_version_;
161+
}
162+
159163
bool DescriptionGLES::IsES() const {
160164
return is_es_;
161165
}

impeller/renderer/backend/gles/description_gles.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class DescriptionGLES {
2626

2727
std::string GetString() const;
2828

29+
Version GetGlVersion() const;
30+
2931
bool HasExtension(const std::string& ext) const;
3032

3133
/// @brief Returns whether GLES includes the debug extension.

shell/platform/linux/fl_backing_store_provider.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ uint32_t fl_backing_store_provider_get_gl_format(FlBackingStoreProvider* self) {
8282
// In Linux kN32_SkColorType is assumed to be kBGRA_8888_SkColorType.
8383
// So we must choose a valid gl format to be compatible with surface format
8484
// BGRA8.
85-
// Following logics are copied from Skia GrGLCaps.cpp.
85+
// Following logics are copied from Skia GrGLCaps.cpp:
86+
// https://github.com/google/skia/blob/4738ed711e03212aceec3cd502a4adb545f38e63/src/gpu/ganesh/gl/GrGLCaps.cpp#L1963-L2116
8687

8788
if (epoxy_is_desktop_gl()) {
8889
// For OpenGL.

shell/platform/windows/BUILD.gn

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ source_set("flutter_windows_source") {
4242
"accessibility_bridge_windows.h",
4343
"angle_surface_manager.cc",
4444
"angle_surface_manager.h",
45+
"compositor.h",
46+
"compositor_opengl.cc",
47+
"compositor_opengl.h",
48+
"compositor_software.cc",
49+
"compositor_software.h",
4550
"cursor_handler.cc",
4651
"cursor_handler.h",
4752
"direct_manipulation.cc",
@@ -134,6 +139,7 @@ source_set("flutter_windows_source") {
134139
deps = [
135140
":flutter_windows_headers",
136141
"//flutter/fml:fml",
142+
"//flutter/impeller/renderer/backend/gles",
137143
"//flutter/shell/platform/common:common_cpp",
138144
"//flutter/shell/platform/common:common_cpp_input",
139145
"//flutter/shell/platform/common:common_cpp_switches",
@@ -175,6 +181,8 @@ executable("flutter_windows_unittests") {
175181
# Common Windows test sources.
176182
sources = [
177183
"accessibility_bridge_windows_unittests.cc",
184+
"compositor_opengl_unittests.cc",
185+
"compositor_software_unittests.cc",
178186
"cursor_handler_unittests.cc",
179187
"direct_manipulation_unittests.cc",
180188
"dpi_utils_unittests.cc",
@@ -234,6 +242,7 @@ executable("flutter_windows_unittests") {
234242
":flutter_windows_fixtures",
235243
":flutter_windows_headers",
236244
":flutter_windows_source",
245+
"//flutter/impeller/renderer/backend/gles",
237246
"//flutter/shell/platform/common:common_cpp",
238247
"//flutter/shell/platform/common/client_wrapper:client_wrapper",
239248
"//flutter/shell/platform/embedder:embedder_as_internal_library",

shell/platform/windows/compositor.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_H_
7+
8+
#include "flutter/shell/platform/embedder/embedder.h"
9+
10+
namespace flutter {
11+
12+
// Enables the Flutter engine to render content on Windows.
13+
//
14+
// The engine uses this to:
15+
//
16+
// 1. Create backing stores used for rendering Flutter content
17+
// 2. Composite and present Flutter content and platform views onto a view
18+
//
19+
// Platform views are not yet supported.
20+
class Compositor {
21+
public:
22+
virtual ~Compositor() = default;
23+
24+
// Create a backing store used for rendering Flutter content.
25+
//
26+
// The backing store's configuration is stored in |backing_store_out|.
27+
virtual bool CreateBackingStore(const FlutterBackingStoreConfig& config,
28+
FlutterBackingStore* backing_store_out) = 0;
29+
30+
// Destroys a backing store and releases its resources.
31+
virtual bool CollectBackingStore(const FlutterBackingStore* store) = 0;
32+
33+
// Present Flutter content and platform views onto the view.
34+
virtual bool Present(const FlutterLayer** layers, size_t layers_count) = 0;
35+
};
36+
37+
} // namespace flutter
38+
39+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_H_
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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_view.h"
9+
10+
namespace flutter {
11+
12+
namespace {
13+
14+
// The metadata for an OpenGL framebuffer backing store.
15+
struct FramebufferBackingStore {
16+
uint32_t framebuffer_id;
17+
uint32_t texture_id;
18+
};
19+
20+
} // namespace
21+
22+
CompositorOpenGL::CompositorOpenGL(FlutterWindowsEngine* engine,
23+
impeller::ProcTableGLES::Resolver resolver)
24+
: engine_(engine), resolver_(resolver) {}
25+
26+
bool CompositorOpenGL::CreateBackingStore(
27+
const FlutterBackingStoreConfig& config,
28+
FlutterBackingStore* result) {
29+
if (!is_initialized_ && !Initialize()) {
30+
return false;
31+
}
32+
33+
auto store = std::make_unique<FramebufferBackingStore>();
34+
35+
gl_->GenTextures(1, &store->texture_id);
36+
gl_->GenFramebuffers(1, &store->framebuffer_id);
37+
38+
gl_->BindFramebuffer(GL_FRAMEBUFFER, store->framebuffer_id);
39+
gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
40+
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
41+
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
42+
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
43+
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
44+
gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, config.size.width,
45+
config.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
46+
gl_->BindTexture(GL_TEXTURE_2D, 0);
47+
48+
gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
49+
GL_TEXTURE_2D, store->texture_id, 0);
50+
51+
result->type = kFlutterBackingStoreTypeOpenGL;
52+
result->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
53+
result->open_gl.framebuffer.name = store->framebuffer_id;
54+
result->open_gl.framebuffer.target = format_;
55+
result->open_gl.framebuffer.user_data = store.release();
56+
result->open_gl.framebuffer.destruction_callback = nullptr;
57+
return true;
58+
}
59+
60+
bool CompositorOpenGL::CollectBackingStore(const FlutterBackingStore* store) {
61+
FML_DCHECK(is_initialized_);
62+
FML_DCHECK(store->type == kFlutterBackingStoreTypeOpenGL);
63+
FML_DCHECK(store->open_gl.type == kFlutterOpenGLTargetTypeFramebuffer);
64+
65+
auto user_data = static_cast<FramebufferBackingStore*>(
66+
store->open_gl.framebuffer.user_data);
67+
68+
gl_->DeleteFramebuffers(1, &user_data->framebuffer_id);
69+
gl_->DeleteTextures(1, &user_data->texture_id);
70+
71+
delete user_data;
72+
return true;
73+
}
74+
75+
bool CompositorOpenGL::Present(const FlutterLayer** layers,
76+
size_t layers_count) {
77+
FML_DCHECK(is_initialized_);
78+
FML_DCHECK(layers_count == 1);
79+
FML_DCHECK(layers[0]->type == kFlutterLayerContentTypeBackingStore);
80+
FML_DCHECK(layers[0]->backing_store->type == kFlutterBackingStoreTypeOpenGL);
81+
FML_DCHECK(layers[0]->backing_store->open_gl.type ==
82+
kFlutterOpenGLTargetTypeFramebuffer);
83+
84+
auto width = layers[0]->size.width;
85+
auto height = layers[0]->size.height;
86+
87+
// Acquiring the view's framebuffer ID resizes its surface if necessary.
88+
auto destination_id = engine_->view()->GetFrameBufferId(width, height);
89+
auto source_id = layers[0]->backing_store->open_gl.framebuffer.name;
90+
91+
if (!engine_->surface_manager()->MakeCurrent()) {
92+
return false;
93+
}
94+
95+
gl_->BindFramebuffer(GL_READ_FRAMEBUFFER, source_id);
96+
gl_->BindFramebuffer(GL_DRAW_FRAMEBUFFER, destination_id);
97+
98+
gl_->BlitFramebuffer(0, // srcX0
99+
0, // srcY0
100+
width, // srcX1
101+
height, // srcY1
102+
0, // dstX0
103+
0, // dstY0
104+
width, // dstX1
105+
height, // dstY1
106+
GL_COLOR_BUFFER_BIT, // mask
107+
GL_NEAREST // filter
108+
);
109+
110+
return engine_->view()->SwapBuffers();
111+
}
112+
113+
bool CompositorOpenGL::Initialize() {
114+
FML_DCHECK(!is_initialized_);
115+
116+
if (!engine_->surface_manager()->MakeCurrent()) {
117+
return false;
118+
}
119+
120+
auto gl = std::make_unique<impeller::ProcTableGLES>(resolver_);
121+
if (!gl->IsValid()) {
122+
return false;
123+
}
124+
125+
// Based off Skia's logic:
126+
// https://github.com/google/skia/blob/4738ed711e03212aceec3cd502a4adb545f38e63/src/gpu/ganesh/gl/GrGLCaps.cpp#L1963-L2116
127+
auto description = gl->GetDescription();
128+
if (description->HasExtension("GL_EXT_texture_format_BGRA8888")) {
129+
format_ = GL_BGRA8_EXT;
130+
} else if (description->HasExtension("GL_APPLE_texture_format_BGRA8888") &&
131+
description->GetGlVersion().IsAtLeast(impeller::Version(3, 0))) {
132+
format_ = GL_BGRA8_EXT;
133+
} else {
134+
format_ = GL_RGBA8;
135+
}
136+
137+
gl_ = std::move(gl);
138+
is_initialized_ = true;
139+
return true;
140+
}
141+
142+
} // namespace flutter
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_OPENGL_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_OPENGL_H_
7+
8+
#include <memory>
9+
10+
#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h"
11+
#include "flutter/shell/platform/embedder/embedder.h"
12+
#include "flutter/shell/platform/windows/compositor.h"
13+
#include "flutter/shell/platform/windows/flutter_windows_engine.h"
14+
15+
namespace flutter {
16+
17+
// Enables the Flutter engine to render content on Windows using OpenGL.
18+
class CompositorOpenGL : public Compositor {
19+
public:
20+
CompositorOpenGL(FlutterWindowsEngine* engine,
21+
impeller::ProcTableGLES::Resolver resolver);
22+
23+
/// |Compositor|
24+
bool CreateBackingStore(const FlutterBackingStoreConfig& config,
25+
FlutterBackingStore* result) override;
26+
27+
/// |Compositor|
28+
bool CollectBackingStore(const FlutterBackingStore* store) override;
29+
30+
/// |Compositor|
31+
bool Present(const FlutterLayer** layers, size_t layers_count) override;
32+
33+
private:
34+
// The Flutter engine that manages the views to render.
35+
FlutterWindowsEngine* engine_;
36+
37+
private:
38+
// The compositor initializes itself lazily once |CreateBackingStore| is
39+
// called. True if initialization completed successfully.
40+
bool is_initialized_ = false;
41+
42+
// Function used to resolve GLES functions.
43+
impeller::ProcTableGLES::Resolver resolver_;
44+
45+
// Table of resolved GLES functions. Null until the compositor is initialized.
46+
std::unique_ptr<impeller::ProcTableGLES> gl_;
47+
48+
// The OpenGL texture target format for backing stores. Invalid value until
49+
// the compositor is initialized.
50+
uint32_t format_;
51+
52+
// Initialize the compositor. This must run on the raster thread.
53+
bool Initialize();
54+
};
55+
56+
} // namespace flutter
57+
58+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_COMPOSITOR_OPENGL_H_

0 commit comments

Comments
 (0)