Rename FlRenderer to FlCompositorOpenGL (#166037)

Matches the Flutter engine compositor and is similar to the Windows
embedder classes.
This commit is contained in:
Robert Ancell
2025-04-01 17:04:08 +13:00
committed by GitHub
parent 8b0cf61ebd
commit be79e0a0a6
13 changed files with 434 additions and 323 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -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);
}

View File

@@ -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 <glib-object.h>
#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_

View File

@@ -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 <epoxy/egl.h>
#include <epoxy/gl.h>
@@ -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<PresentLayersData*>(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<GDestroyNotify>(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<GDestroyNotify>(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);

View File

@@ -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 <gtk/gtk.h>
#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_

View File

@@ -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 <epoxy/egl.h>
TEST(FlRendererTest, BackgroundColor) {
TEST(FlCompositorOpenGLTest, BackgroundColor) {
::testing::NiceMock<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<flutter::testing::MockEpoxy> 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<size_t>(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();

View File

@@ -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<FlEngine*>(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<FlEngine*>(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<FlEngine*>(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 =

View File

@@ -8,12 +8,12 @@
#include <glib-object.h>
#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:

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 <gtk/gtk.h>
#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_

View File

@@ -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) {