diff --git a/shell/platform/linux/fl_engine.cc b/shell/platform/linux/fl_engine.cc index f39e3fd596d7c..55cd0c7551bb9 100644 --- a/shell/platform/linux/fl_engine.cc +++ b/shell/platform/linux/fl_engine.cc @@ -207,8 +207,8 @@ static bool compositor_collect_backing_store_callback( 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->layers, - info->layers_count); + return fl_renderer_present_layers(FL_RENDERER(info->user_data), info->view_id, + info->layers, info->layers_count); } // Flutter engine rendering callbacks. diff --git a/shell/platform/linux/fl_renderer.cc b/shell/platform/linux/fl_renderer.cc index f54d129ce7b63..80bdbea2db06a 100644 --- a/shell/platform/linux/fl_renderer.cc +++ b/shell/platform/linux/fl_renderer.cc @@ -38,7 +38,8 @@ typedef struct { // Engine we are rendering. GWeakRef engine; - FlView* view; + // Views being rendered. + GHashTable* views; // target dimension for resizing int target_width; @@ -244,6 +245,7 @@ static void fl_renderer_dispose(GObject* object) { fl_renderer_unblock_main_thread(self); g_weak_ref_clear(&priv->engine); + g_clear_pointer(&priv->views, g_hash_table_unref); g_clear_pointer(&priv->framebuffers, g_ptr_array_unref); G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(object); @@ -256,6 +258,8 @@ static void fl_renderer_class_init(FlRendererClass* klass) { static void fl_renderer_init(FlRenderer* self) { FlRendererPrivate* priv = reinterpret_cast( fl_renderer_get_instance_private(self)); + priv->views = + g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, nullptr); priv->framebuffers = g_ptr_array_new_with_free_func(g_object_unref); } @@ -268,14 +272,15 @@ void fl_renderer_set_engine(FlRenderer* self, FlEngine* engine) { g_weak_ref_init(&priv->engine, engine); } -gboolean fl_renderer_start(FlRenderer* self, FlView* view) { +void fl_renderer_add_view(FlRenderer* self, + FlutterViewId view_id, + FlView* view) { FlRendererPrivate* priv = reinterpret_cast( fl_renderer_get_instance_private(self)); - g_return_val_if_fail(FL_IS_RENDERER(self), FALSE); + g_return_if_fail(FL_IS_RENDERER(self)); - priv->view = view; - return TRUE; + g_hash_table_insert(priv->views, GINT_TO_POINTER(view_id), view); } void* fl_renderer_get_proc_address(FlRenderer* self, const char* name) { @@ -370,6 +375,7 @@ 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) { FlRendererPrivate* priv = reinterpret_cast( @@ -407,8 +413,10 @@ gboolean fl_renderer_present_layers(FlRenderer* self, } } - if (priv->view != nullptr) { - fl_view_redraw(priv->view); + FlView* view = + FL_VIEW(g_hash_table_lookup(priv->views, GINT_TO_POINTER(view_id))); + if (view != nullptr) { + fl_view_redraw(view); } return TRUE; diff --git a/shell/platform/linux/fl_renderer.h b/shell/platform/linux/fl_renderer.h index 6103b01f73810..2b7d44635db87 100644 --- a/shell/platform/linux/fl_renderer.h +++ b/shell/platform/linux/fl_renderer.h @@ -102,15 +102,16 @@ struct _FlRendererClass { void fl_renderer_set_engine(FlRenderer* renderer, FlEngine* engine); /** - * fl_renderer_start: + * fl_renderer_add_view: * @renderer: an #FlRenderer. + * @view_id: the ID of the view. * @view: the view Flutter is renderering to. * - * Start the renderer. - * - * Returns: %TRUE if successfully started. + * Add a view to render on. */ -gboolean fl_renderer_start(FlRenderer* renderer, FlView* view); +void fl_renderer_add_view(FlRenderer* renderer, + FlutterViewId view_id, + FlView* view); /** * fl_renderer_get_proc_address: @@ -189,6 +190,7 @@ gboolean fl_renderer_collect_backing_store( /** * fl_renderer_present_layers: * @renderer: an #FlRenderer. + * @view_id: view to present. * @layers: layers to be composited. * @layers_count: number of layers. * @@ -198,6 +200,7 @@ gboolean fl_renderer_collect_backing_store( * Returns %TRUE if successful. */ gboolean fl_renderer_present_layers(FlRenderer* renderer, + FlutterViewId view_id, const FlutterLayer** layers, size_t layers_count); diff --git a/shell/platform/linux/fl_renderer_test.cc b/shell/platform/linux/fl_renderer_test.cc index f38e85e0cc550..1426e4ec8b136 100644 --- a/shell/platform/linux/fl_renderer_test.cc +++ b/shell/platform/linux/fl_renderer_test.cc @@ -24,7 +24,7 @@ TEST(FlRendererTest, RestoresGLState) { g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new(); g_autoptr(FlFramebuffer) framebuffer = fl_framebuffer_new(kWidth, kHeight); - fl_renderer_start(FL_RENDERER(renderer), view); + fl_renderer_add_view(FL_RENDERER(renderer), 0, view); fl_renderer_wait_for_frame(FL_RENDERER(renderer), kWidth, kHeight); FlutterBackingStore backing_store; @@ -42,7 +42,7 @@ TEST(FlRendererTest, RestoresGLState) { constexpr GLuint kFakeTextureName = 123; glBindTexture(GL_TEXTURE_2D, kFakeTextureName); - fl_renderer_present_layers(FL_RENDERER(renderer), layers.data(), + fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers.data(), layers.size()); fl_renderer_render(FL_RENDERER(renderer), kWidth, kHeight); @@ -97,7 +97,7 @@ TEST(FlRendererTest, BlitFramebuffer) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), layers, 1); + fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1); fl_renderer_render(FL_RENDERER(renderer), 1024, 1024); } @@ -131,7 +131,7 @@ TEST(FlRendererTest, BlitFramebufferExtension) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), layers, 1); + fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1); fl_renderer_render(FL_RENDERER(renderer), 1024, 1024); } @@ -160,7 +160,7 @@ TEST(FlRendererTest, NoBlitFramebuffer) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), layers, 1); + fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1); fl_renderer_render(FL_RENDERER(renderer), 1024, 1024); } @@ -190,6 +190,6 @@ TEST(FlRendererTest, BlitFramebufferNvidia) { .backing_store = &backing_store, .size = {.width = 1024, .height = 1024}}; const FlutterLayer* layers[] = {&layer0}; - fl_renderer_present_layers(FL_RENDERER(renderer), layers, 1); + fl_renderer_present_layers(FL_RENDERER(renderer), 0, layers, 1); fl_renderer_render(FL_RENDERER(renderer), 1024, 1024); } diff --git a/shell/platform/linux/fl_view.cc b/shell/platform/linux/fl_view.cc index 18eb5e6175378..088de80af1f86 100644 --- a/shell/platform/linux/fl_view.cc +++ b/shell/platform/linux/fl_view.cc @@ -586,7 +586,7 @@ static void realize_cb(FlView* self) { init_keyboard(self); - fl_renderer_start(FL_RENDERER(self->renderer), self); + fl_renderer_add_view(FL_RENDERER(self->renderer), self->view_id, self); if (!fl_engine_start(self->engine, &error)) { g_warning("Failed to start Flutter engine: %s", error->message);