forked from firka/flutter
Rename FlRenderer to FlCompositorOpenGL (#166037)
Matches the Flutter engine compositor and is similar to the Windows embedder classes.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
47
engine/src/flutter/shell/platform/linux/fl_compositor.cc
Normal file
47
engine/src/flutter/shell/platform/linux/fl_compositor.cc
Normal 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);
|
||||
}
|
||||
104
engine/src/flutter/shell/platform/linux/fl_compositor.h
Normal file
104
engine/src/flutter/shell/platform/linux/fl_compositor.h
Normal 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_
|
||||
@@ -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);
|
||||
@@ -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_
|
||||
@@ -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();
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user