From be79e0a0a6ea278907da5a98ddaf1f28d4ccfde9 Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Tue, 1 Apr 2025 17:04:08 +1300 Subject: [PATCH] Rename FlRenderer to FlCompositorOpenGL (#166037) Matches the Flutter engine compositor and is similar to the Windows embedder classes. --- .../ci/licenses_golden/licenses_flutter | 16 +- .../src/flutter/shell/platform/linux/BUILD.gn | 5 +- .../shell/platform/linux/fl_compositor.cc | 47 +++++ .../shell/platform/linux/fl_compositor.h | 104 +++++++++++ ...fl_renderer.cc => fl_compositor_opengl.cc} | 174 ++++++++++-------- .../platform/linux/fl_compositor_opengl.h | 74 ++++++++ ...r_test.cc => fl_compositor_opengl_test.cc} | 131 ++++++------- .../flutter/shell/platform/linux/fl_engine.cc | 31 ++-- .../shell/platform/linux/fl_engine_private.h | 10 +- .../shell/platform/linux/fl_engine_test.cc | 2 +- .../shell/platform/linux/fl_renderable.h | 2 +- .../shell/platform/linux/fl_renderer.h | 141 -------------- .../flutter/shell/platform/linux/fl_view.cc | 20 +- 13 files changed, 434 insertions(+), 323 deletions(-) create mode 100644 engine/src/flutter/shell/platform/linux/fl_compositor.cc create mode 100644 engine/src/flutter/shell/platform/linux/fl_compositor.h rename engine/src/flutter/shell/platform/linux/{fl_renderer.cc => fl_compositor_opengl.cc} (83%) create mode 100644 engine/src/flutter/shell/platform/linux/fl_compositor_opengl.h rename engine/src/flutter/shell/platform/linux/{fl_renderer_test.cc => fl_compositor_opengl_test.cc} (74%) delete mode 100644 engine/src/flutter/shell/platform/linux/fl_renderer.h diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 06829eef5d..40ce340469 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -53211,6 +53211,11 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_binary_codec_test.cc + ../../.. ORIGIN: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_binary_messenger_test.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/linux/fl_compositor.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/linux/fl_compositor.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/linux/fl_compositor_opengl.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/linux/fl_compositor_opengl.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/linux/fl_compositor_opengl_test.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_dart_project.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_dart_project_private.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc + ../../../flutter/LICENSE @@ -53290,9 +53295,6 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_pointer_manager.h + ../../../fl ORIGIN: ../../../flutter/shell/platform/linux/fl_pointer_manager_test.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_renderable.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_renderable.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_test.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc + ../../../flutter/LICENSE @@ -56228,6 +56230,11 @@ FILE: ../../../flutter/shell/platform/linux/fl_binary_codec_test.cc FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_test.cc +FILE: ../../../flutter/shell/platform/linux/fl_compositor.cc +FILE: ../../../flutter/shell/platform/linux/fl_compositor.h +FILE: ../../../flutter/shell/platform/linux/fl_compositor_opengl.cc +FILE: ../../../flutter/shell/platform/linux/fl_compositor_opengl.h +FILE: ../../../flutter/shell/platform/linux/fl_compositor_opengl_test.cc FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc FILE: ../../../flutter/shell/platform/linux/fl_dart_project_private.h FILE: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc @@ -56307,9 +56314,6 @@ FILE: ../../../flutter/shell/platform/linux/fl_pointer_manager.h FILE: ../../../flutter/shell/platform/linux/fl_pointer_manager_test.cc FILE: ../../../flutter/shell/platform/linux/fl_renderable.cc FILE: ../../../flutter/shell/platform/linux/fl_renderable.h -FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc -FILE: ../../../flutter/shell/platform/linux/fl_renderer.h -FILE: ../../../flutter/shell/platform/linux/fl_renderer_test.cc FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc diff --git a/engine/src/flutter/shell/platform/linux/BUILD.gn b/engine/src/flutter/shell/platform/linux/BUILD.gn index dfae597ef8..f44abc08c2 100644 --- a/engine/src/flutter/shell/platform/linux/BUILD.gn +++ b/engine/src/flutter/shell/platform/linux/BUILD.gn @@ -105,6 +105,8 @@ source_set("flutter_linux_sources") { "fl_basic_message_channel.cc", "fl_binary_codec.cc", "fl_binary_messenger.cc", + "fl_compositor.cc", + "fl_compositor_opengl.cc", "fl_dart_project.cc", "fl_display_monitor.cc", "fl_engine.cc", @@ -136,7 +138,6 @@ source_set("flutter_linux_sources") { "fl_plugin_registry.cc", "fl_pointer_manager.cc", "fl_renderable.cc", - "fl_renderer.cc", "fl_scrolling_manager.cc", "fl_settings.cc", "fl_settings_channel.cc", @@ -213,6 +214,7 @@ executable("flutter_linux_unittests") { "fl_basic_message_channel_test.cc", "fl_binary_codec_test.cc", "fl_binary_messenger_test.cc", + "fl_compositor_opengl_test.cc", "fl_dart_project_test.cc", "fl_display_monitor_test.cc", "fl_engine_test.cc", @@ -235,7 +237,6 @@ executable("flutter_linux_unittests") { "fl_platform_handler_test.cc", "fl_plugin_registrar_test.cc", "fl_pointer_manager_test.cc", - "fl_renderer_test.cc", "fl_scrolling_manager_test.cc", "fl_settings_handler_test.cc", "fl_settings_portal_test.cc", diff --git a/engine/src/flutter/shell/platform/linux/fl_compositor.cc b/engine/src/flutter/shell/platform/linux/fl_compositor.cc new file mode 100644 index 0000000000..a9c9979039 --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/fl_compositor.cc @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fl_compositor.h" + +G_DEFINE_QUARK(fl_compositor_error_quark, fl_compositor_error) + +G_DEFINE_TYPE(FlCompositor, fl_compositor, G_TYPE_OBJECT) + +static void fl_compositor_class_init(FlCompositorClass* klass) {} + +static void fl_compositor_init(FlCompositor* self) {} + +gboolean fl_compositor_create_backing_store( + FlCompositor* self, + const FlutterBackingStoreConfig* config, + FlutterBackingStore* backing_store_out) { + g_return_val_if_fail(FL_IS_COMPOSITOR(self), FALSE); + return FL_COMPOSITOR_GET_CLASS(self)->create_backing_store(self, config, + backing_store_out); +} + +gboolean fl_compositor_collect_backing_store( + FlCompositor* self, + const FlutterBackingStore* backing_store) { + g_return_val_if_fail(FL_IS_COMPOSITOR(self), FALSE); + return FL_COMPOSITOR_GET_CLASS(self)->collect_backing_store(self, + backing_store); +} + +void fl_compositor_wait_for_frame(FlCompositor* self, + int target_width, + int target_height) { + g_return_if_fail(FL_IS_COMPOSITOR(self)); + FL_COMPOSITOR_GET_CLASS(self)->wait_for_frame(self, target_width, + target_height); +} + +gboolean fl_compositor_present_layers(FlCompositor* self, + FlutterViewId view_id, + const FlutterLayer** layers, + size_t layers_count) { + g_return_val_if_fail(FL_IS_COMPOSITOR(self), FALSE); + return FL_COMPOSITOR_GET_CLASS(self)->present_layers(self, view_id, layers, + layers_count); +} diff --git a/engine/src/flutter/shell/platform/linux/fl_compositor.h b/engine/src/flutter/shell/platform/linux/fl_compositor.h new file mode 100644 index 0000000000..4e4892433e --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/fl_compositor.h @@ -0,0 +1,104 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_H_ + +#include + +#include "flutter/shell/platform/embedder/embedder.h" + +G_BEGIN_DECLS + +G_DECLARE_DERIVABLE_TYPE(FlCompositor, fl_compositor, FL, COMPOSITOR, GObject) + +struct _FlCompositorClass { + GObjectClass parent_class; + + gboolean (*create_backing_store)(FlCompositor* compositor, + const FlutterBackingStoreConfig* config, + FlutterBackingStore* backing_store_out); + + gboolean (*collect_backing_store)(FlCompositor* compositor, + const FlutterBackingStore* backing_store); + + gboolean (*present_layers)(FlCompositor* compositor, + FlutterViewId view_id, + const FlutterLayer** layers, + size_t layers_count); + + void (*wait_for_frame)(FlCompositor* compositor, + int target_width, + int target_height); +}; + +/** + * FlCompositor: + * + * #FlCompositor is an abstract class that implements Flutter compositing. + */ + +/** + * fl_compositor_create_backing_store: + * @compositor: an #FlCompositor. + * @config: backing store config. + * @backing_store_out: saves created backing store. + * + * Obtain a backing store for a specific #FlutterLayer. + * + * Returns %TRUE if successful. + */ +gboolean fl_compositor_create_backing_store( + FlCompositor* compositor, + const FlutterBackingStoreConfig* config, + FlutterBackingStore* backing_store_out); + +/** + * fl_compositor_collect_backing_store: + * @compositor: an #FlCompositor. + * @backing_store: backing store to be released. + * + * A callback invoked by the engine to release the backing store. The + * embedder may collect any resources associated with the backing store. + * + * Returns %TRUE if successful. + */ +gboolean fl_compositor_collect_backing_store( + FlCompositor* compositor, + const FlutterBackingStore* backing_store); + +/** + * fl_compositor_present_layers: + * @compositor: an #FlCompositor. + * @view_id: view to present. + * @layers: layers to be composited. + * @layers_count: number of layers. + * + * Callback invoked by the engine to composite the contents of each layer + * onto the screen. + * + * Returns %TRUE if successful. + */ +gboolean fl_compositor_present_layers(FlCompositor* compositor, + FlutterViewId view_id, + const FlutterLayer** layers, + size_t layers_count); + +/** + * fl_compositor_wait_for_frame: + * @compositor: an #FlCompositor. + * @target_width: width of frame being waited for + * @target_height: height of frame being waited for + * + * Holds the thread until frame with requested dimensions is presented. + * While waiting for frame Flutter platform and raster tasks are being + * processed. + */ +void fl_compositor_wait_for_frame(FlCompositor* compositor, + int target_width, + int target_height); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_H_ diff --git a/engine/src/flutter/shell/platform/linux/fl_renderer.cc b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl.cc similarity index 83% rename from engine/src/flutter/shell/platform/linux/fl_renderer.cc rename to engine/src/flutter/shell/platform/linux/fl_compositor_opengl.cc index a1362e974f..20d2a6ca84 100644 --- a/engine/src/flutter/shell/platform/linux/fl_renderer.cc +++ b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fl_renderer.h" +#include "fl_compositor_opengl.h" #include #include @@ -36,10 +36,8 @@ static const char* fragment_shader_src = " gl_FragColor = texture2D(texture, texcoord);\n" "}\n"; -G_DEFINE_QUARK(fl_renderer_error_quark, fl_renderer_error) - -struct _FlRenderer { - GObject parent_instance; +struct _FlCompositorOpenGL { + FlCompositor parent_instance; // Engine we are rendering. GWeakRef engine; @@ -85,7 +83,9 @@ struct _FlRenderer { GCond present_condition; }; -G_DEFINE_TYPE(FlRenderer, fl_renderer, G_TYPE_OBJECT) +G_DEFINE_TYPE(FlCompositorOpenGL, + fl_compositor_opengl, + fl_compositor_get_type()) // Check if running on an NVIDIA driver. static gboolean is_nvidia() { @@ -131,7 +131,7 @@ static GLfloat pixels_to_gl_coords(GLfloat position, GLfloat pixels) { } // Perform single run OpenGL initialization. -static void initialize(FlRenderer* self) { +static void initialize(FlCompositorOpenGL* self) { if (self->initialized) { return; } @@ -146,7 +146,7 @@ static void initialize(FlRenderer* self) { } } -static void fl_renderer_unblock_main_thread(FlRenderer* self) { +static void fl_compositor_opengl_unblock_main_thread(FlCompositorOpenGL* self) { if (self->blocking_main_thread) { self->blocking_main_thread = false; @@ -157,7 +157,7 @@ static void fl_renderer_unblock_main_thread(FlRenderer* self) { } } -static void setup_shader(FlRenderer* self) { +static void setup_shader(FlCompositorOpenGL* self) { GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_src, nullptr); glCompileShader(vertex_shader); @@ -194,7 +194,8 @@ static void setup_shader(FlRenderer* self) { glDeleteShader(fragment_shader); } -static void render_with_blit(FlRenderer* self, GPtrArray* framebuffers) { +static void render_with_blit(FlCompositorOpenGL* self, + GPtrArray* framebuffers) { // Disable the scissor test as it can affect blit operations. // Prevents regressions like: https://github.com/flutter/flutter/issues/140828 // See OpenGL specification version 4.6, section 18.3.1. @@ -214,7 +215,7 @@ static void render_with_blit(FlRenderer* self, GPtrArray* framebuffers) { glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } -static void render_with_textures(FlRenderer* self, +static void render_with_textures(FlCompositorOpenGL* self, GPtrArray* framebuffers, int width, int height) { @@ -280,7 +281,7 @@ static void render_with_textures(FlRenderer* self, glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding); } -static void render(FlRenderer* self, +static void render(FlCompositorOpenGL* self, GPtrArray* framebuffers, int width, int height) { @@ -291,11 +292,11 @@ static void render(FlRenderer* self, } } -static gboolean present_layers(FlRenderer* self, +static gboolean present_layers(FlCompositorOpenGL* self, FlutterViewId view_id, const FlutterLayer** layers, size_t layers_count) { - g_return_val_if_fail(FL_IS_RENDERER(self), FALSE); + g_return_val_if_fail(FL_IS_COMPOSITOR_OPENGL(self), FALSE); // ignore incoming frame with wrong dimensions in trivial case with just one // layer @@ -308,7 +309,7 @@ static gboolean present_layers(FlRenderer* self, self->had_first_frame = true; - fl_renderer_unblock_main_thread(self); + fl_compositor_opengl_unblock_main_thread(self); g_autoptr(GPtrArray) framebuffers = g_ptr_array_new_with_free_func(g_object_unref); @@ -405,7 +406,7 @@ static gboolean present_layers(FlRenderer* self, } typedef struct { - FlRenderer* self; + FlCompositorOpenGL* self; FlutterViewId view_id; @@ -420,7 +421,7 @@ typedef struct { // Perform the present on the main thread. static void present_layers_task_cb(gpointer user_data) { PresentLayersData* data = static_cast(user_data); - FlRenderer* self = data->self; + FlCompositorOpenGL* self = data->self; // Perform the present. fl_opengl_manager_make_current(self->opengl_manager); @@ -428,52 +429,18 @@ static void present_layers_task_cb(gpointer user_data) { present_layers(self, data->view_id, data->layers, data->layers_count); fl_opengl_manager_clear_current(self->opengl_manager); - // Complete fl_renderer_present_layers(). + // Complete fl_compositor_opengl_present_layers(). g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->present_mutex); data->finished = TRUE; g_cond_signal(&self->present_condition); } -static void fl_renderer_dispose(GObject* object) { - FlRenderer* self = FL_RENDERER(object); - - fl_renderer_unblock_main_thread(self); - - g_weak_ref_clear(&self->engine); - g_clear_object(&self->opengl_manager); - g_clear_pointer(&self->framebuffers_by_view_id, g_hash_table_unref); - g_mutex_clear(&self->present_mutex); - g_cond_clear(&self->present_condition); - - G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(object); -} - -static void fl_renderer_class_init(FlRendererClass* klass) { - G_OBJECT_CLASS(klass)->dispose = fl_renderer_dispose; -} - -static void fl_renderer_init(FlRenderer* self) { - self->framebuffers_by_view_id = g_hash_table_new_full( - g_direct_hash, g_direct_equal, nullptr, - reinterpret_cast(g_ptr_array_unref)); - g_mutex_init(&self->present_mutex); - g_cond_init(&self->present_condition); -} - -FlRenderer* fl_renderer_new(FlEngine* engine) { - FlRenderer* self = FL_RENDERER(g_object_new(fl_renderer_get_type(), nullptr)); - - g_weak_ref_init(&self->engine, engine); - self->opengl_manager = - FL_OPENGL_MANAGER(g_object_ref(fl_engine_get_opengl_manager(engine))); - - return self; -} - -gboolean fl_renderer_create_backing_store( - FlRenderer* self, +static gboolean fl_compositor_opengl_create_backing_store( + FlCompositor* compositor, const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor); + fl_opengl_manager_make_current(self->opengl_manager); initialize(self); @@ -492,16 +459,19 @@ gboolean fl_renderer_create_backing_store( fl_framebuffer_get_id(framebuffer); backing_store_out->open_gl.framebuffer.target = self->sized_format; backing_store_out->open_gl.framebuffer.destruction_callback = [](void* p) { - // Backing store destroyed in fl_renderer_collect_backing_store(), set - // on FlutterCompositor.collect_backing_store_callback during engine start. + // Backing store destroyed in fl_compositor_opengl_collect_backing_store(), + // set on FlutterCompositor.collect_backing_store_callback during engine + // start. }; return TRUE; } -gboolean fl_renderer_collect_backing_store( - FlRenderer* self, +static gboolean fl_compositor_opengl_collect_backing_store( + FlCompositor* compositor, const FlutterBackingStore* backing_store) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor); + fl_opengl_manager_make_current(self->opengl_manager); // OpenGL context is required when destroying #FlFramebuffer. @@ -509,10 +479,10 @@ gboolean fl_renderer_collect_backing_store( return TRUE; } -void fl_renderer_wait_for_frame(FlRenderer* self, - int target_width, - int target_height) { - g_return_if_fail(FL_IS_RENDERER(self)); +static void fl_compositor_opengl_wait_for_frame(FlCompositor* compositor, + int target_width, + int target_height) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor); self->target_width = target_width; self->target_height = target_height; @@ -526,10 +496,12 @@ void fl_renderer_wait_for_frame(FlRenderer* self, } } -gboolean fl_renderer_present_layers(FlRenderer* self, - FlutterViewId view_id, - const FlutterLayer** layers, - size_t layers_count) { +static gboolean fl_compositor_opengl_present_layers(FlCompositor* compositor, + FlutterViewId view_id, + const FlutterLayer** layers, + size_t layers_count) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor); + // Detach the context from raster thread. Needed because blitting // will be done on the main thread, which will make the context current. fl_opengl_manager_clear_current(self->opengl_manager); @@ -561,8 +533,54 @@ gboolean fl_renderer_present_layers(FlRenderer* self, return data.result; } -void fl_renderer_setup(FlRenderer* self) { - g_return_if_fail(FL_IS_RENDERER(self)); +static void fl_compositor_opengl_dispose(GObject* object) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(object); + + fl_compositor_opengl_unblock_main_thread(self); + + g_weak_ref_clear(&self->engine); + g_clear_object(&self->opengl_manager); + g_clear_pointer(&self->framebuffers_by_view_id, g_hash_table_unref); + g_mutex_clear(&self->present_mutex); + g_cond_clear(&self->present_condition); + + G_OBJECT_CLASS(fl_compositor_opengl_parent_class)->dispose(object); +} + +static void fl_compositor_opengl_class_init(FlCompositorOpenGLClass* klass) { + FL_COMPOSITOR_CLASS(klass)->create_backing_store = + fl_compositor_opengl_create_backing_store; + FL_COMPOSITOR_CLASS(klass)->collect_backing_store = + fl_compositor_opengl_collect_backing_store; + FL_COMPOSITOR_CLASS(klass)->wait_for_frame = + fl_compositor_opengl_wait_for_frame; + FL_COMPOSITOR_CLASS(klass)->present_layers = + fl_compositor_opengl_present_layers; + + G_OBJECT_CLASS(klass)->dispose = fl_compositor_opengl_dispose; +} + +static void fl_compositor_opengl_init(FlCompositorOpenGL* self) { + self->framebuffers_by_view_id = g_hash_table_new_full( + g_direct_hash, g_direct_equal, nullptr, + reinterpret_cast(g_ptr_array_unref)); + g_mutex_init(&self->present_mutex); + g_cond_init(&self->present_condition); +} + +FlCompositorOpenGL* fl_compositor_opengl_new(FlEngine* engine) { + FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL( + g_object_new(fl_compositor_opengl_get_type(), nullptr)); + + g_weak_ref_init(&self->engine, engine); + self->opengl_manager = + FL_OPENGL_MANAGER(g_object_ref(fl_engine_get_opengl_manager(engine))); + + return self; +} + +void fl_compositor_opengl_setup(FlCompositorOpenGL* self) { + g_return_if_fail(FL_IS_COMPOSITOR_OPENGL(self)); // Note: NVIDIA and Vivante are temporarily disabled due to // https://github.com/flutter/flutter/issues/152099 @@ -576,12 +594,12 @@ void fl_renderer_setup(FlRenderer* self) { } } -void fl_renderer_render(FlRenderer* self, - FlutterViewId view_id, - int width, - int height, - const GdkRGBA* background_color) { - g_return_if_fail(FL_IS_RENDERER(self)); +void fl_compositor_opengl_render(FlCompositorOpenGL* self, + FlutterViewId view_id, + int width, + int height, + const GdkRGBA* background_color) { + g_return_if_fail(FL_IS_COMPOSITOR_OPENGL(self)); glClearColor(background_color->red, background_color->green, background_color->blue, background_color->alpha); @@ -596,8 +614,8 @@ void fl_renderer_render(FlRenderer* self, glFlush(); } -void fl_renderer_cleanup(FlRenderer* self) { - g_return_if_fail(FL_IS_RENDERER(self)); +void fl_compositor_opengl_cleanup(FlCompositorOpenGL* self) { + g_return_if_fail(FL_IS_COMPOSITOR_OPENGL(self)); if (self->program != 0) { glDeleteProgram(self->program); diff --git a/engine/src/flutter/shell/platform/linux/fl_compositor_opengl.h b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl.h new file mode 100644 index 0000000000..aeead55660 --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl.h @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_OPENGL_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_OPENGL_H_ + +#include + +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/fl_compositor.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(FlCompositorOpenGL, + fl_compositor_opengl, + FL, + COMPOSITOR_OPENGL, + FlCompositor) + +/** + * FlCompositorOpenGL: + * + * #FlCompositorOpenGL is an abstract class that allows Flutter to draw pixels. + */ + +/** + * fl_compositor_opengl_new: + * @engine: an #FlEngine. + * + * Creates a new OpenGL compositor. + * + * Returns: a new #FlCompositorOpenGL. + */ +FlCompositorOpenGL* fl_compositor_opengl_new(FlEngine* engine); + +/** + * fl_compositor_opengl_setup: + * @compositor: an #FlCompositorOpenGL. + * + * Creates OpenGL resources required before rendering. Requires an active + * context. + */ +void fl_compositor_opengl_setup(FlCompositorOpenGL* compositor); + +/** + * fl_compositor_opengl_render: + * @compositor: an #FlCompositorOpenGL. + * @view_id: view to render. + * @width: width of the window in pixels. + * @height: height of the window in pixels. + * @background_color: color to use for background. + * + * Performs OpenGL commands to render current Flutter view. + */ +void fl_compositor_opengl_render(FlCompositorOpenGL* compositor, + FlutterViewId view_id, + int width, + int height, + const GdkRGBA* background_color); + +/** + * fl_compositor_opengl_cleanup: + * @compositor: an #FlCompositorOpenGL. + * + * Removes OpenGL resources used for rendering. Requires an active + * context. + */ +void fl_compositor_opengl_cleanup(FlCompositorOpenGL* compositor); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_COMPOSITOR_OPENGL_H_ diff --git a/engine/src/flutter/shell/platform/linux/fl_renderer_test.cc b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl_test.cc similarity index 74% rename from engine/src/flutter/shell/platform/linux/fl_renderer_test.cc rename to engine/src/flutter/shell/platform/linux/fl_compositor_opengl_test.cc index 9c189ce11f..0dba8acd3a 100644 --- a/engine/src/flutter/shell/platform/linux/fl_renderer_test.cc +++ b/engine/src/flutter/shell/platform/linux/fl_compositor_opengl_test.cc @@ -8,6 +8,7 @@ #include "flutter/common/constants.h" #include "flutter/fml/logging.h" #include "flutter/fml/synchronization/waitable_event.h" +#include "flutter/shell/platform/linux/fl_compositor_opengl.h" #include "flutter/shell/platform/linux/fl_engine_private.h" #include "flutter/shell/platform/linux/fl_framebuffer.h" #include "flutter/shell/platform/linux/testing/mock_epoxy.h" @@ -15,7 +16,7 @@ #include -TEST(FlRendererTest, BackgroundColor) { +TEST(FlCompositorOpenGLTest, BackgroundColor) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -28,16 +29,16 @@ TEST(FlRendererTest, BackgroundColor) { EXPECT_CALL(epoxy, glClearColor(0.2, 0.3, 0.4, 0.5)); g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); FlutterBackingStoreConfig config = { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -49,8 +50,8 @@ TEST(FlRendererTest, BackgroundColor) { .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers, 1); latch.Signal(); }).detach(); @@ -60,15 +61,15 @@ TEST(FlRendererTest, BackgroundColor) { GdkRGBA background_color = { .red = 0.2, .green = 0.3, .blue = 0.4, .alpha = 0.5}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - 1024, 1024, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, 1024, + 1024, &background_color); // Wait until the raster thread has finished before letting // the engine go out of scope. latch.Wait(); } -TEST(FlRendererTest, RestoresGLState) { +TEST(FlCompositorOpenGLTest, RestoresGLState) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -77,12 +78,12 @@ TEST(FlRendererTest, RestoresGLState) { constexpr int kHeight = 100; g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); g_autoptr(FlFramebuffer) framebuffer = fl_framebuffer_new(GL_RGB, kWidth, kHeight); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), kWidth, kHeight); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), kWidth, kHeight); FlutterBackingStore backing_store; backing_store.type = kFlutterBackingStoreTypeOpenGL; @@ -103,9 +104,9 @@ TEST(FlRendererTest, RestoresGLState) { // Simulate raster thread. std::thread([&]() { - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers.data(), - layers.size()); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers.data(), + layers.size()); latch.Signal(); }).detach(); @@ -115,8 +116,8 @@ TEST(FlRendererTest, RestoresGLState) { GdkRGBA background_color = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - kWidth, kHeight, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, + kWidth, kHeight, &background_color); GLuint texture_2d_binding; glGetIntegerv(GL_TEXTURE_BINDING_2D, @@ -128,7 +129,7 @@ TEST(FlRendererTest, RestoresGLState) { latch.Wait(); } -TEST(FlRendererTest, BlitFramebuffer) { +TEST(FlCompositorOpenGLTest, BlitFramebuffer) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -143,16 +144,16 @@ TEST(FlRendererTest, BlitFramebuffer) { EXPECT_CALL(epoxy, glBlitFramebuffer); g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); FlutterBackingStoreConfig config = { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -163,8 +164,8 @@ TEST(FlRendererTest, BlitFramebuffer) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers, 1); latch.Signal(); }).detach(); @@ -174,13 +175,13 @@ TEST(FlRendererTest, BlitFramebuffer) { GdkRGBA background_color = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - 1024, 1024, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, 1024, + 1024, &background_color); latch.Wait(); } -TEST(FlRendererTest, BlitFramebufferExtension) { +TEST(FlCompositorOpenGLTest, BlitFramebufferExtension) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -200,16 +201,16 @@ TEST(FlRendererTest, BlitFramebufferExtension) { EXPECT_CALL(epoxy, glBlitFramebuffer); g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); FlutterBackingStoreConfig config = { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -220,8 +221,8 @@ TEST(FlRendererTest, BlitFramebufferExtension) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers, 1); latch.Signal(); }).detach(); @@ -230,14 +231,14 @@ TEST(FlRendererTest, BlitFramebufferExtension) { } GdkRGBA background_color = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - 1024, 1024, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, 1024, + 1024, &background_color); // Wait until the raster thread has finished before letting // the engine go out of scope. latch.Wait(); } -TEST(FlRendererTest, NoBlitFramebuffer) { +TEST(FlCompositorOpenGLTest, NoBlitFramebuffer) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -250,16 +251,16 @@ TEST(FlRendererTest, NoBlitFramebuffer) { EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(20)); g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); FlutterBackingStoreConfig config = { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -270,8 +271,8 @@ TEST(FlRendererTest, NoBlitFramebuffer) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers, 1); latch.Signal(); }).detach(); @@ -281,15 +282,15 @@ TEST(FlRendererTest, NoBlitFramebuffer) { GdkRGBA background_color = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - 1024, 1024, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, 1024, + 1024, &background_color); // Wait until the raster thread has finished before letting // the engine go out of scope. latch.Wait(); } -TEST(FlRendererTest, BlitFramebufferNvidia) { +TEST(FlCompositorOpenGLTest, BlitFramebufferNvidia) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -303,16 +304,16 @@ TEST(FlRendererTest, BlitFramebufferNvidia) { EXPECT_CALL(epoxy, epoxy_gl_version).WillRepeatedly(::testing::Return(30)); g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); FlutterBackingStoreConfig config = { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -323,8 +324,8 @@ TEST(FlRendererTest, BlitFramebufferNvidia) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), - flutter::kFlutterImplicitViewId, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), + flutter::kFlutterImplicitViewId, layers, 1); latch.Signal(); }).detach(); @@ -334,15 +335,15 @@ TEST(FlRendererTest, BlitFramebufferNvidia) { GdkRGBA background_color = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}; - fl_renderer_render(FL_RENDERER(renderer), flutter::kFlutterImplicitViewId, - 1024, 1024, &background_color); + fl_compositor_opengl_render(compositor, flutter::kFlutterImplicitViewId, 1024, + 1024, &background_color); // Wait until the raster thread has finished before letting // the engine go out of scope. latch.Wait(); } -TEST(FlRendererTest, MultiView) { +TEST(FlCompositorOpenGLTest, MultiView) { ::testing::NiceMock epoxy; g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlEngine) engine = fl_engine_new(project); @@ -357,13 +358,13 @@ TEST(FlRendererTest, MultiView) { g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new(); g_autoptr(FlMockRenderable) secondary_renderable = fl_mock_renderable_new(); - g_autoptr(FlRenderer) renderer = fl_renderer_new(engine); - fl_renderer_setup(FL_RENDERER(renderer)); + g_autoptr(FlCompositorOpenGL) compositor = fl_compositor_opengl_new(engine); + fl_compositor_opengl_setup(compositor); fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable)); FlutterViewId view_id = fl_engine_add_view(engine, FL_RENDERABLE(secondary_renderable), 1024, 768, 1.0, nullptr, nullptr, nullptr); - fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024); + fl_compositor_wait_for_frame(FL_COMPOSITOR(compositor), 1024, 1024); EXPECT_EQ(fl_mock_renderable_get_redraw_count(renderable), static_cast(0)); @@ -374,8 +375,8 @@ TEST(FlRendererTest, MultiView) { .struct_size = sizeof(FlutterBackingStoreConfig), .size = {.width = 1024, .height = 1024}}; FlutterBackingStore backing_store; - fl_renderer_create_backing_store(FL_RENDERER(renderer), &config, - &backing_store); + fl_compositor_create_backing_store(FL_COMPOSITOR(compositor), &config, + &backing_store); fml::AutoResetWaitableEvent latch; @@ -386,7 +387,7 @@ TEST(FlRendererTest, MultiView) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), view_id, layers, 1); + fl_compositor_present_layers(FL_COMPOSITOR(compositor), view_id, layers, 1); latch.Signal(); }).detach(); diff --git a/engine/src/flutter/shell/platform/linux/fl_engine.cc b/engine/src/flutter/shell/platform/linux/fl_engine.cc index a2bbb209f0..6a3481e9db 100644 --- a/engine/src/flutter/shell/platform/linux/fl_engine.cc +++ b/engine/src/flutter/shell/platform/linux/fl_engine.cc @@ -13,6 +13,7 @@ #include "flutter/shell/platform/common/engine_switches.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/linux/fl_binary_messenger_private.h" +#include "flutter/shell/platform/linux/fl_compositor_opengl.h" #include "flutter/shell/platform/linux/fl_dart_project_private.h" #include "flutter/shell/platform/linux/fl_display_monitor.h" #include "flutter/shell/platform/linux/fl_engine_private.h" @@ -21,7 +22,6 @@ #include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h" #include "flutter/shell/platform/linux/fl_platform_handler.h" #include "flutter/shell/platform/linux/fl_plugin_registrar_private.h" -#include "flutter/shell/platform/linux/fl_renderer.h" #include "flutter/shell/platform/linux/fl_settings_handler.h" #include "flutter/shell/platform/linux/fl_texture_gl_private.h" #include "flutter/shell/platform/linux/fl_texture_registrar_private.h" @@ -49,7 +49,7 @@ struct _FlEngine { FlDisplayMonitor* display_monitor; // Renders the Flutter app. - FlRenderer* renderer; + FlCompositor* compositor; // Manages OpenGL contexts. FlOpenGLManager* opengl_manager; @@ -252,26 +252,25 @@ static bool compositor_create_backing_store_callback( const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out, void* user_data) { - g_return_val_if_fail(FL_IS_RENDERER(user_data), false); - return fl_renderer_create_backing_store(FL_RENDERER(user_data), config, - backing_store_out); + FlEngine* self = static_cast(user_data); + return fl_compositor_create_backing_store(self->compositor, config, + backing_store_out); } // Called when the backing store is to be released. static bool compositor_collect_backing_store_callback( const FlutterBackingStore* backing_store, void* user_data) { - g_return_val_if_fail(FL_IS_RENDERER(user_data), false); - return fl_renderer_collect_backing_store(FL_RENDERER(user_data), - backing_store); + FlEngine* self = static_cast(user_data); + return fl_compositor_collect_backing_store(self->compositor, backing_store); } // Called when embedder should composite contents of each layer onto the screen. static bool compositor_present_view_callback( const FlutterPresentViewInfo* info) { - g_return_val_if_fail(FL_IS_RENDERER(info->user_data), false); - return fl_renderer_present_layers(FL_RENDERER(info->user_data), info->view_id, - info->layers, info->layers_count); + FlEngine* self = static_cast(info->user_data); + return fl_compositor_present_layers(self->compositor, info->view_id, + info->layers, info->layers_count); } // Flutter engine rendering callbacks. @@ -484,7 +483,7 @@ static void fl_engine_dispose(GObject* object) { g_clear_object(&self->project); g_clear_object(&self->display_monitor); - g_clear_object(&self->renderer); + g_clear_object(&self->compositor); g_clear_object(&self->opengl_manager); g_clear_object(&self->texture_registrar); g_clear_object(&self->binary_messenger); @@ -561,7 +560,7 @@ static FlEngine* fl_engine_new_full(FlDartProject* project, FlEngine* self = FL_ENGINE(g_object_new(fl_engine_get_type(), nullptr)); self->project = FL_DART_PROJECT(g_object_ref(project)); - self->renderer = fl_renderer_new(self); + self->compositor = FL_COMPOSITOR(fl_compositor_opengl_new(self)); if (binary_messenger != nullptr) { self->binary_messenger = FL_BINARY_MESSENGER(g_object_ref(binary_messenger)); @@ -596,9 +595,9 @@ G_MODULE_EXPORT FlEngine* fl_engine_new_headless(FlDartProject* project) { return fl_engine_new(project); } -FlRenderer* fl_engine_get_renderer(FlEngine* self) { +FlCompositor* fl_engine_get_compositor(FlEngine* self) { g_return_val_if_fail(FL_IS_ENGINE(self), nullptr); - return self->renderer; + return self->compositor; } FlOpenGLManager* fl_engine_get_opengl_manager(FlEngine* self) { @@ -668,7 +667,7 @@ gboolean fl_engine_start(FlEngine* self, GError** error) { FlutterCompositor compositor = {}; compositor.struct_size = sizeof(FlutterCompositor); - compositor.user_data = self->renderer; + compositor.user_data = self; compositor.create_backing_store_callback = compositor_create_backing_store_callback; compositor.collect_backing_store_callback = diff --git a/engine/src/flutter/shell/platform/linux/fl_engine_private.h b/engine/src/flutter/shell/platform/linux/fl_engine_private.h index 3be38cf8ff..6447ea96b4 100644 --- a/engine/src/flutter/shell/platform/linux/fl_engine_private.h +++ b/engine/src/flutter/shell/platform/linux/fl_engine_private.h @@ -8,12 +8,12 @@ #include #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/fl_compositor.h" #include "flutter/shell/platform/linux/fl_display_monitor.h" #include "flutter/shell/platform/linux/fl_keyboard_manager.h" #include "flutter/shell/platform/linux/fl_mouse_cursor_handler.h" #include "flutter/shell/platform/linux/fl_opengl_manager.h" #include "flutter/shell/platform/linux/fl_renderable.h" -#include "flutter/shell/platform/linux/fl_renderer.h" #include "flutter/shell/platform/linux/fl_task_runner.h" #include "flutter/shell/platform/linux/fl_text_input_handler.h" #include "flutter/shell/platform/linux/fl_windowing_handler.h" @@ -64,14 +64,14 @@ FlEngine* fl_engine_new_with_binary_messenger( FlBinaryMessenger* binary_messenger); /** - * fl_engine_get_renderer: + * fl_engine_get_compositor: * @engine: an #FlEngine. * - * Gets the renderer used by this engine. + * Gets the compositor used by this engine. * - * Returns: an #FlRenderer. + * Returns: an #FlCompositor. */ -FlRenderer* fl_engine_get_renderer(FlEngine* engine); +FlCompositor* fl_engine_get_compositor(FlEngine* engine); /** * fl_engine_get_opengl_manager: diff --git a/engine/src/flutter/shell/platform/linux/fl_engine_test.cc b/engine/src/flutter/shell/platform/linux/fl_engine_test.cc index c2cff862be..6cd9fabe57 100644 --- a/engine/src/flutter/shell/platform/linux/fl_engine_test.cc +++ b/engine/src/flutter/shell/platform/linux/fl_engine_test.cc @@ -981,7 +981,7 @@ TEST(FlEngineTest, ChildObjects) { // Check objects exist before engine started. EXPECT_NE(fl_engine_get_binary_messenger(engine), nullptr); - EXPECT_NE(fl_engine_get_renderer(engine), nullptr); + EXPECT_NE(fl_engine_get_compositor(engine), nullptr); EXPECT_NE(fl_engine_get_display_monitor(engine), nullptr); EXPECT_NE(fl_engine_get_task_runner(engine), nullptr); EXPECT_NE(fl_engine_get_keyboard_manager(engine), nullptr); diff --git a/engine/src/flutter/shell/platform/linux/fl_renderable.h b/engine/src/flutter/shell/platform/linux/fl_renderable.h index 82773b2638..e8201859ce 100644 --- a/engine/src/flutter/shell/platform/linux/fl_renderable.h +++ b/engine/src/flutter/shell/platform/linux/fl_renderable.h @@ -34,7 +34,7 @@ struct _FlRenderableInterface { * @renderable: an #FlRenderable * * Indicate the renderable needs to redraw. When ready, the renderable should - * call fl_renderer_draw(). + * call fl_compositor_draw(). */ void fl_renderable_redraw(FlRenderable* renderable); diff --git a/engine/src/flutter/shell/platform/linux/fl_renderer.h b/engine/src/flutter/shell/platform/linux/fl_renderer.h deleted file mode 100644 index 74f6d5b934..0000000000 --- a/engine/src/flutter/shell/platform/linux/fl_renderer.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_H_ - -#include - -#include "flutter/shell/platform/embedder/embedder.h" - -#include "flutter/shell/platform/linux/fl_renderable.h" -#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" - -G_BEGIN_DECLS - -/** - * FlRendererError: - * Errors for #FlRenderer objects to set on failures. - */ - -typedef enum { - FL_RENDERER_ERROR_FAILED, -} FlRendererError; - -GQuark fl_renderer_error_quark(void) G_GNUC_CONST; - -G_DECLARE_FINAL_TYPE(FlRenderer, fl_renderer, FL, RENDERER, GObject) - -/** - * FlRenderer: - * - * #FlRenderer is an abstract class that allows Flutter to draw pixels. - */ - -/** - * fl_renderer_new: - * @engine: an #FlEngine. - * - * Creates a new renderer. - * - * Returns: a new #FlRenderer. - */ -FlRenderer* fl_renderer_new(FlEngine* engine); - -/** - * fl_renderer_create_backing_store: - * @renderer: an #FlRenderer. - * @config: backing store config. - * @backing_store_out: saves created backing store. - * - * Obtain a backing store for a specific #FlutterLayer. - * - * Returns %TRUE if successful. - */ -gboolean fl_renderer_create_backing_store( - FlRenderer* renderer, - const FlutterBackingStoreConfig* config, - FlutterBackingStore* backing_store_out); - -/** - * fl_renderer_collect_backing_store: - * @renderer: an #FlRenderer. - * @backing_store: backing store to be released. - * - * A callback invoked by the engine to release the backing store. The - * embedder may collect any resources associated with the backing store. - * - * Returns %TRUE if successful. - */ -gboolean fl_renderer_collect_backing_store( - FlRenderer* renderer, - const FlutterBackingStore* backing_store); - -/** - * fl_renderer_present_layers: - * @renderer: an #FlRenderer. - * @view_id: view to present. - * @layers: layers to be composited. - * @layers_count: number of layers. - * - * Callback invoked by the engine to composite the contents of each layer - * onto the screen. - * - * Returns %TRUE if successful. - */ -gboolean fl_renderer_present_layers(FlRenderer* renderer, - FlutterViewId view_id, - const FlutterLayer** layers, - size_t layers_count); - -/** - * fl_renderer_wait_for_frame: - * @renderer: an #FlRenderer. - * @target_width: width of frame being waited for - * @target_height: height of frame being waited for - * - * Holds the thread until frame with requested dimensions is presented. - * While waiting for frame Flutter platform and raster tasks are being - * processed. - */ -void fl_renderer_wait_for_frame(FlRenderer* renderer, - int target_width, - int target_height); - -/** - * fl_renderer_setup: - * @renderer: an #FlRenderer. - * - * Creates OpenGL resources required before rendering. Requires an active OpenGL - * context. - */ -void fl_renderer_setup(FlRenderer* renderer); - -/** - * fl_renderer_render: - * @renderer: an #FlRenderer. - * @view_id: view to render. - * @width: width of the window in pixels. - * @height: height of the window in pixels. - * @background_color: color to use for background. - * - * Performs OpenGL commands to render current Flutter view. - */ -void fl_renderer_render(FlRenderer* renderer, - FlutterViewId view_id, - int width, - int height, - const GdkRGBA* background_color); - -/** - * fl_renderer_cleanup: - * - * Removes OpenGL resources used for rendering. Requires an active OpenGL - * context. - */ -void fl_renderer_cleanup(FlRenderer* renderer); - -G_END_DECLS - -#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_H_ diff --git a/engine/src/flutter/shell/platform/linux/fl_view.cc b/engine/src/flutter/shell/platform/linux/fl_view.cc index 5ec1c152d9..8e3a9a7c86 100644 --- a/engine/src/flutter/shell/platform/linux/fl_view.cc +++ b/engine/src/flutter/shell/platform/linux/fl_view.cc @@ -11,6 +11,7 @@ #include "flutter/common/constants.h" #include "flutter/shell/platform/linux/fl_accessible_node.h" +#include "flutter/shell/platform/linux/fl_compositor_opengl.h" #include "flutter/shell/platform/linux/fl_engine_private.h" #include "flutter/shell/platform/linux/fl_key_event.h" #include "flutter/shell/platform/linux/fl_opengl_manager.h" @@ -194,9 +195,9 @@ static void handle_geometry_changed(FlView* self) { // Note: `gtk_widget_init()` initializes the size allocation to 1x1. if (allocation.width > 1 && allocation.height > 1 && gtk_widget_get_realized(GTK_WIDGET(self))) { - fl_renderer_wait_for_frame(fl_engine_get_renderer(self->engine), - allocation.width * scale_factor, - allocation.height * scale_factor); + fl_compositor_wait_for_frame(fl_engine_get_compositor(self->engine), + allocation.width * scale_factor, + allocation.height * scale_factor); } } @@ -464,7 +465,8 @@ static void realize_cb(FlView* self) { return; } - fl_renderer_setup(fl_engine_get_renderer(self->engine)); + fl_compositor_opengl_setup( + FL_COMPOSITOR_OPENGL(fl_engine_get_compositor(self->engine))); GtkWidget* toplevel_window = gtk_widget_get_toplevel(GTK_WIDGET(self)); @@ -502,9 +504,10 @@ static gboolean render_cb(FlView* self, GdkGLContext* context) { int width = gtk_widget_get_allocated_width(GTK_WIDGET(self->gl_area)); int height = gtk_widget_get_allocated_height(GTK_WIDGET(self->gl_area)); gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self->gl_area)); - fl_renderer_render(fl_engine_get_renderer(self->engine), self->view_id, - width * scale_factor, height * scale_factor, - self->background_color); + fl_compositor_opengl_render( + FL_COMPOSITOR_OPENGL(fl_engine_get_compositor(self->engine)), + self->view_id, width * scale_factor, height * scale_factor, + self->background_color); return TRUE; } @@ -520,7 +523,8 @@ static void unrealize_cb(FlView* self) { return; } - fl_renderer_cleanup(fl_engine_get_renderer(self->engine)); + fl_compositor_opengl_cleanup( + FL_COMPOSITOR_OPENGL(fl_engine_get_compositor(self->engine))); } static void size_allocate_cb(FlView* self) {