8 #include "flutter/fml/logging.h"
16 constexpr uint32_t kWindowFrameBufferId = 0;
19 struct FramebufferBackingStore {
26 typedef const impeller::GLProc<decltype(glBlitFramebuffer)> BlitFramebufferProc;
28 const BlitFramebufferProc& GetBlitFramebufferProc(
29 const impeller::ProcTableGLES& gl) {
30 if (gl.BlitFramebuffer.IsAvailable()) {
31 return gl.BlitFramebuffer;
32 }
else if (gl.BlitFramebufferANGLE.IsAvailable()) {
33 return gl.BlitFramebufferANGLE;
43 impeller::ProcTableGLES::Resolver resolver,
45 : engine_(engine), resolver_(resolver), enable_impeller_(enable_impeller) {}
48 const FlutterBackingStoreConfig& config,
49 FlutterBackingStore* result) {
50 if (!is_initialized_ && !Initialize()) {
54 auto store = std::make_unique<FramebufferBackingStore>();
56 gl_->GenFramebuffers(1, &store->framebuffer_id);
57 gl_->BindFramebuffer(GL_FRAMEBUFFER, store->framebuffer_id);
59 if (enable_impeller_) {
60 if (supports_implicit_msaa_) {
61 gl_->GenTextures(1, &store->texture_id);
62 gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
63 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
64 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
65 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
66 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
67 gl_->TexImage2D(GL_TEXTURE_2D, 0, format_.sized_format, config.size.width,
68 config.size.height, 0, format_.general_format,
69 GL_UNSIGNED_BYTE,
nullptr);
70 gl_->BindTexture(GL_TEXTURE_2D, 0);
73 gl_->FramebufferTexture2DMultisampleEXT(
74 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
75 store->texture_id, 0, 4);
78 gl_->GenRenderbuffers(1, &store->depth_stencil_id);
79 gl_->BindRenderbuffer(GL_RENDERBUFFER, store->depth_stencil_id);
80 gl_->RenderbufferStorageMultisampleEXT(
81 GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, config.size.width,
83 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
84 GL_RENDERBUFFER, store->depth_stencil_id);
85 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
86 GL_RENDERBUFFER, store->depth_stencil_id);
87 }
else if (supports_offscreen_msaa_) {
89 gl_->GenRenderbuffers(1, &store->color_renderbuffer_id);
90 gl_->BindRenderbuffer(GL_RENDERBUFFER, store->color_renderbuffer_id);
91 gl_->RenderbufferStorageMultisample(
92 GL_RENDERBUFFER, 4, format_.sized_format, config.size.width,
94 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
96 store->color_renderbuffer_id);
99 gl_->GenRenderbuffers(1, &store->depth_stencil_id);
100 gl_->BindRenderbuffer(GL_RENDERBUFFER, store->depth_stencil_id);
101 gl_->RenderbufferStorageMultisample(
102 GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, config.size.width,
104 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
105 GL_RENDERBUFFER, store->depth_stencil_id);
106 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
107 GL_RENDERBUFFER, store->depth_stencil_id);
109 gl_->GenTextures(1, &store->texture_id);
110 gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
111 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
112 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
113 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
114 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
115 gl_->TexImage2D(GL_TEXTURE_2D, 0, format_.sized_format, config.size.width,
116 config.size.height, 0, format_.general_format,
117 GL_UNSIGNED_BYTE,
nullptr);
118 gl_->BindTexture(GL_TEXTURE_2D, 0);
120 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
121 GL_TEXTURE_2D, store->texture_id, 0);
123 gl_->GenRenderbuffers(1, &store->depth_stencil_id);
124 gl_->BindRenderbuffer(GL_RENDERBUFFER, store->depth_stencil_id);
125 gl_->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
126 config.size.width, config.size.height);
127 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
128 GL_RENDERBUFFER, store->depth_stencil_id);
129 gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
130 GL_RENDERBUFFER, store->depth_stencil_id);
133 gl_->GenTextures(1, &store->texture_id);
134 gl_->BindTexture(GL_TEXTURE_2D, store->texture_id);
135 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
136 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
137 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
138 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
139 gl_->TexImage2D(GL_TEXTURE_2D, 0, format_.sized_format, config.size.width,
140 config.size.height, 0, format_.general_format,
141 GL_UNSIGNED_BYTE,
nullptr);
142 gl_->BindTexture(GL_TEXTURE_2D, 0);
144 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
145 GL_TEXTURE_2D, store->texture_id, 0);
148 result->type = kFlutterBackingStoreTypeOpenGL;
149 result->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
150 result->open_gl.framebuffer.name = store->framebuffer_id;
151 result->open_gl.framebuffer.target = format_.sized_format;
152 result->open_gl.framebuffer.user_data = store.release();
153 result->open_gl.framebuffer.destruction_callback = [](
void*
user_data) {
161 FML_DCHECK(is_initialized_);
162 FML_DCHECK(store->type == kFlutterBackingStoreTypeOpenGL);
163 FML_DCHECK(store->open_gl.type == kFlutterOpenGLTargetTypeFramebuffer);
165 auto user_data =
static_cast<FramebufferBackingStore*
>(
166 store->open_gl.framebuffer.user_data);
168 gl_->DeleteFramebuffers(1, &
user_data->framebuffer_id);
170 gl_->DeleteTextures(1, &
user_data->texture_id);
172 if (
user_data->color_renderbuffer_id != 0) {
173 gl_->DeleteRenderbuffers(1, &
user_data->color_renderbuffer_id);
176 gl_->DeleteRenderbuffers(1, &
user_data->depth_stencil_id);
184 const FlutterLayer** layers,
185 size_t layers_count) {
186 FML_DCHECK(view !=
nullptr);
189 if (layers_count == 0) {
193 if (!is_initialized_ && !Initialize()) {
202 FML_DCHECK(is_initialized_);
203 FML_DCHECK(layers_count == 1);
204 FML_DCHECK(layers[0]->offset.x == 0 && layers[0]->offset.y == 0);
205 FML_DCHECK(layers[0]->
type == kFlutterLayerContentTypeBackingStore);
206 FML_DCHECK(layers[0]->backing_store->type == kFlutterBackingStoreTypeOpenGL);
207 FML_DCHECK(layers[0]->backing_store->open_gl.type ==
208 kFlutterOpenGLTargetTypeFramebuffer);
210 auto width = layers[0]->size.width;
211 auto height = layers[0]->size.height;
220 FML_DCHECK(view->
surface() !=
nullptr);
228 auto source_id = layers[0]->backing_store->open_gl.framebuffer.name;
233 gl_->Disable(GL_SCISSOR_TEST);
234 gl_->BindFramebuffer(GL_READ_FRAMEBUFFER, source_id);
235 gl_->BindFramebuffer(GL_DRAW_FRAMEBUFFER, kWindowFrameBufferId);
237 auto blitFramebuffer = GetBlitFramebufferProc(*gl_);
258 bool CompositorOpenGL::Initialize() {
259 FML_DCHECK(!is_initialized_);
270 gl_ = std::make_unique<impeller::ProcTableGLES>(resolver_);
271 if (!gl_->IsValid()) {
276 if (gl_->GetDescription()->HasExtension(
"GL_EXT_texture_format_BGRA8888")) {
277 format_.sized_format = GL_BGRA8_EXT;
278 format_.general_format = GL_BGRA_EXT;
280 format_.sized_format = GL_RGBA8;
281 format_.general_format = GL_RGBA;
284 if (!gl_->BlitFramebuffer.IsAvailable() &&
285 !gl_->BlitFramebufferANGLE.IsAvailable()) {
286 FML_LOG(ERROR) <<
"Unable to find OpenGL blit framebuffer procedure.";
290 supports_implicit_msaa_ =
291 gl_->GetCapabilities()->SupportsImplicitResolvingMSAA();
292 supports_offscreen_msaa_ = gl_->GetCapabilities()->SupportsOffscreenMSAA();
294 if (enable_impeller_ && !supports_implicit_msaa_ &&
295 !supports_offscreen_msaa_) {
299 FML_LOG(WARNING) <<
"Rendering without MSAA.";
302 is_initialized_ =
true;
306 bool CompositorOpenGL::Clear(FlutterWindowsView* view) {
307 FML_DCHECK(is_initialized_);
310 if (!view->OnEmptyFrameGenerated()) {
315 FML_DCHECK(view->surface() !=
nullptr);
316 FML_DCHECK(view->surface()->IsValid());
318 egl::WindowSurface* surface = view->surface();
319 if (!surface->MakeCurrent()) {
323 gl_->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
324 gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
326 if (!surface->SwapBuffers()) {
330 view->OnFramePresented();
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)
egl::Manager * egl_manager() const
virtual void OnFramePresented()
egl::WindowSurface * surface() const
bool OnFrameGenerated(size_t width, size_t height)
virtual bool MakeCurrent() const
virtual Context * render_context() const
virtual bool SwapBuffers() const
virtual bool IsValid() const
virtual bool MakeCurrent() const
uint32_t color_renderbuffer_id
uint32_t depth_stencil_id
enum flutter::testing::@104::KeyboardChange::Type type