Move tracking of renderables from FlRenderer to FlEngine (#165848)
Motivated by work on refactoring FlRenderer to FlCompositor.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "flutter/common/constants.h"
|
||||
#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"
|
||||
@@ -93,6 +94,9 @@ struct _FlEngine {
|
||||
// Next ID to use for a view.
|
||||
FlutterViewId next_view_id;
|
||||
|
||||
// Objects rendering the views.
|
||||
GHashTable* renderables_by_view_id;
|
||||
|
||||
// Function to call when a platform message is received.
|
||||
FlEnginePlatformMessageHandler platform_message_handler;
|
||||
gpointer platform_message_handler_data;
|
||||
@@ -489,6 +493,7 @@ static void fl_engine_dispose(GObject* object) {
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
g_clear_object(&self->mouse_cursor_handler);
|
||||
g_clear_object(&self->task_runner);
|
||||
g_clear_pointer(&self->renderables_by_view_id, g_hash_table_unref);
|
||||
|
||||
if (self->platform_message_handler_destroy_notify) {
|
||||
self->platform_message_handler_destroy_notify(
|
||||
@@ -534,6 +539,12 @@ static void fl_engine_init(FlEngine* self) {
|
||||
|
||||
// Implicit view is 0, so start at 1.
|
||||
self->next_view_id = 1;
|
||||
self->renderables_by_view_id = g_hash_table_new_full(
|
||||
g_direct_hash, g_direct_equal, nullptr, [](gpointer value) {
|
||||
GWeakRef* ref = static_cast<GWeakRef*>(value);
|
||||
g_weak_ref_clear(ref);
|
||||
free(ref);
|
||||
});
|
||||
|
||||
self->texture_registrar = fl_texture_registrar_new(self);
|
||||
}
|
||||
@@ -734,7 +745,15 @@ void fl_engine_notify_display_update(FlEngine* self,
|
||||
}
|
||||
}
|
||||
|
||||
void fl_engine_set_implicit_view(FlEngine* self, FlRenderable* renderable) {
|
||||
GWeakRef* ref = g_new(GWeakRef, 1);
|
||||
g_weak_ref_init(ref, G_OBJECT(renderable));
|
||||
g_hash_table_insert(self->renderables_by_view_id,
|
||||
GINT_TO_POINTER(flutter::kFlutterImplicitViewId), ref);
|
||||
}
|
||||
|
||||
FlutterViewId fl_engine_add_view(FlEngine* self,
|
||||
FlRenderable* renderable,
|
||||
size_t width,
|
||||
size_t height,
|
||||
double pixel_ratio,
|
||||
@@ -748,6 +767,11 @@ FlutterViewId fl_engine_add_view(FlEngine* self,
|
||||
FlutterViewId view_id = self->next_view_id;
|
||||
self->next_view_id++;
|
||||
|
||||
GWeakRef* ref = g_new(GWeakRef, 1);
|
||||
g_weak_ref_init(ref, G_OBJECT(renderable));
|
||||
g_hash_table_insert(self->renderables_by_view_id, GINT_TO_POINTER(view_id),
|
||||
ref);
|
||||
|
||||
// We don't know which display this view will open on, so set to zero and this
|
||||
// will be updated in a following FlutterWindowMetricsEvent
|
||||
FlutterEngineDisplayId display_id = 0;
|
||||
@@ -784,6 +808,14 @@ gboolean fl_engine_add_view_finish(FlEngine* self,
|
||||
return g_task_propagate_boolean(G_TASK(result), error);
|
||||
}
|
||||
|
||||
FlRenderable* fl_engine_get_renderable(FlEngine* self, FlutterViewId view_id) {
|
||||
g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
|
||||
|
||||
GWeakRef* ref = static_cast<GWeakRef*>(g_hash_table_lookup(
|
||||
self->renderables_by_view_id, GINT_TO_POINTER(view_id)));
|
||||
return FL_RENDERABLE(g_weak_ref_get(ref));
|
||||
}
|
||||
|
||||
void fl_engine_remove_view(FlEngine* self,
|
||||
FlutterViewId view_id,
|
||||
GCancellable* cancellable,
|
||||
@@ -791,6 +823,8 @@ void fl_engine_remove_view(FlEngine* self,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_ENGINE(self));
|
||||
|
||||
g_hash_table_remove(self->renderables_by_view_id, GINT_TO_POINTER(view_id));
|
||||
|
||||
g_autoptr(GTask) task = g_task_new(self, cancellable, callback, user_data);
|
||||
|
||||
FlutterRemoveViewInfo info;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#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_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"
|
||||
@@ -127,9 +128,19 @@ void fl_engine_notify_display_update(FlEngine* engine,
|
||||
const FlutterEngineDisplay* displays,
|
||||
size_t displays_length);
|
||||
|
||||
/**
|
||||
* fl_engine_set_implicit_view:
|
||||
* @engine: an #FlEngine.
|
||||
* @renderable: the object that will render the implicit view.
|
||||
*
|
||||
* Sets the object to render the implicit view.
|
||||
*/
|
||||
void fl_engine_set_implicit_view(FlEngine* engine, FlRenderable* renderable);
|
||||
|
||||
/**
|
||||
* fl_engine_add_view:
|
||||
* @engine: an #FlEngine.
|
||||
* @renderable: the object that will render this view.
|
||||
* @width: width of view in pixels.
|
||||
* @height: height of view in pixels.
|
||||
* @pixel_ratio: scale factor for view.
|
||||
@@ -144,6 +155,7 @@ void fl_engine_notify_display_update(FlEngine* engine,
|
||||
* Returns: the ID for the view.
|
||||
*/
|
||||
FlutterViewId fl_engine_add_view(FlEngine* engine,
|
||||
FlRenderable* renderable,
|
||||
size_t width,
|
||||
size_t height,
|
||||
double pixel_ratio,
|
||||
@@ -166,6 +178,18 @@ gboolean fl_engine_add_view_finish(FlEngine* engine,
|
||||
GAsyncResult* result,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_engine_get_renderable:
|
||||
* @engine: an #FlEngine.
|
||||
* @view_id: ID to check.
|
||||
*
|
||||
* Gets the renderable associated with the give view ID.
|
||||
*
|
||||
* Returns: (transfer full): a reference to an #FlRenderable or %NULL if none
|
||||
* for this ID.
|
||||
*/
|
||||
FlRenderable* fl_engine_get_renderable(FlEngine* engine, FlutterViewId view_id);
|
||||
|
||||
/**
|
||||
* fl_engine_remove_view:
|
||||
* @engine: an #FlEngine.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
|
||||
|
||||
// MOCK_ENGINE_PROC is leaky by design
|
||||
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
|
||||
@@ -651,8 +652,10 @@ TEST(FlEngineTest, AddView) {
|
||||
return kSuccess;
|
||||
}));
|
||||
|
||||
g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
|
||||
FlutterViewId view_id =
|
||||
fl_engine_add_view(engine, 123, 456, 2.0, nullptr, add_view_cb, loop);
|
||||
fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
|
||||
nullptr, add_view_cb, loop);
|
||||
EXPECT_GT(view_id, 0);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
@@ -688,8 +691,10 @@ TEST(FlEngineTest, AddViewError) {
|
||||
return kSuccess;
|
||||
}));
|
||||
|
||||
FlutterViewId view_id = fl_engine_add_view(engine, 123, 456, 2.0, nullptr,
|
||||
add_view_error_cb, loop);
|
||||
g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
|
||||
FlutterViewId view_id =
|
||||
fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
|
||||
nullptr, add_view_error_cb, loop);
|
||||
EXPECT_GT(view_id, 0);
|
||||
|
||||
// Blocks here until add_view_error_cb is called.
|
||||
@@ -718,8 +723,10 @@ TEST(FlEngineTest, AddViewEngineError) {
|
||||
return kInvalidArguments;
|
||||
}));
|
||||
|
||||
FlutterViewId view_id = fl_engine_add_view(engine, 123, 456, 2.0, nullptr,
|
||||
add_view_engine_error_cb, loop);
|
||||
g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
|
||||
FlutterViewId view_id =
|
||||
fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
|
||||
nullptr, add_view_engine_error_cb, loop);
|
||||
EXPECT_GT(view_id, 0);
|
||||
|
||||
// Blocks here until remove_view_engine_error_cb is called.
|
||||
|
||||
@@ -51,9 +51,6 @@ typedef struct {
|
||||
// The format used to create textures.
|
||||
GLint general_format;
|
||||
|
||||
// Views being rendered.
|
||||
GHashTable* views;
|
||||
|
||||
// target dimension for resizing
|
||||
int target_width;
|
||||
int target_height;
|
||||
@@ -85,12 +82,6 @@ typedef struct {
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(FlRenderer, fl_renderer, G_TYPE_OBJECT)
|
||||
|
||||
static void free_weak_ref(gpointer value) {
|
||||
GWeakRef* ref = static_cast<GWeakRef*>(value);
|
||||
g_weak_ref_clear(ref);
|
||||
free(ref);
|
||||
}
|
||||
|
||||
// Check if running on an NVIDIA driver.
|
||||
static gboolean is_nvidia() {
|
||||
const gchar* vendor = reinterpret_cast<const gchar*>(glGetString(GL_VENDOR));
|
||||
@@ -349,10 +340,12 @@ static gboolean present_layers(FlRenderer* self,
|
||||
}
|
||||
}
|
||||
|
||||
GWeakRef* ref = static_cast<GWeakRef*>(
|
||||
g_hash_table_lookup(priv->views, GINT_TO_POINTER(view_id)));
|
||||
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&priv->engine));
|
||||
if (engine == nullptr) {
|
||||
return TRUE;
|
||||
}
|
||||
g_autoptr(FlRenderable) renderable =
|
||||
ref != nullptr ? FL_RENDERABLE(g_weak_ref_get(ref)) : nullptr;
|
||||
fl_engine_get_renderable(engine, view_id);
|
||||
if (renderable == nullptr) {
|
||||
return TRUE;
|
||||
}
|
||||
@@ -462,7 +455,6 @@ static void fl_renderer_dispose(GObject* object) {
|
||||
fl_renderer_unblock_main_thread(self);
|
||||
|
||||
g_weak_ref_clear(&priv->engine);
|
||||
g_clear_pointer(&priv->views, g_hash_table_unref);
|
||||
g_clear_pointer(&priv->framebuffers_by_view_id, g_hash_table_unref);
|
||||
g_mutex_clear(&priv->present_mutex);
|
||||
g_cond_clear(&priv->present_condition);
|
||||
@@ -477,8 +469,6 @@ static void fl_renderer_class_init(FlRendererClass* klass) {
|
||||
static void fl_renderer_init(FlRenderer* self) {
|
||||
FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
|
||||
fl_renderer_get_instance_private(self));
|
||||
priv->views = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
|
||||
free_weak_ref);
|
||||
priv->framebuffers_by_view_id = g_hash_table_new_full(
|
||||
g_direct_hash, g_direct_equal, nullptr,
|
||||
reinterpret_cast<GDestroyNotify>(g_ptr_array_unref));
|
||||
@@ -495,28 +485,6 @@ void fl_renderer_set_engine(FlRenderer* self, FlEngine* engine) {
|
||||
g_weak_ref_init(&priv->engine, engine);
|
||||
}
|
||||
|
||||
void fl_renderer_add_renderable(FlRenderer* self,
|
||||
FlutterViewId view_id,
|
||||
FlRenderable* renderable) {
|
||||
FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
|
||||
fl_renderer_get_instance_private(self));
|
||||
|
||||
g_return_if_fail(FL_IS_RENDERER(self));
|
||||
|
||||
GWeakRef* ref = g_new(GWeakRef, 1);
|
||||
g_weak_ref_init(ref, G_OBJECT(renderable));
|
||||
g_hash_table_insert(priv->views, GINT_TO_POINTER(view_id), ref);
|
||||
}
|
||||
|
||||
void fl_renderer_remove_view(FlRenderer* self, FlutterViewId view_id) {
|
||||
FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
|
||||
fl_renderer_get_instance_private(self));
|
||||
|
||||
g_return_if_fail(FL_IS_RENDERER(self));
|
||||
|
||||
g_hash_table_remove(priv->views, GINT_TO_POINTER(view_id));
|
||||
}
|
||||
|
||||
void* fl_renderer_get_proc_address(FlRenderer* self, const char* name) {
|
||||
g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
|
||||
|
||||
|
||||
@@ -66,27 +66,6 @@ struct _FlRendererClass {
|
||||
*/
|
||||
void fl_renderer_set_engine(FlRenderer* renderer, FlEngine* engine);
|
||||
|
||||
/**
|
||||
* fl_renderer_add_renderable:
|
||||
* @renderer: an #FlRenderer.
|
||||
* @view_id: the ID of the view.
|
||||
* @renderable: object that is to be rendered on.
|
||||
*
|
||||
* Add a view to render on.
|
||||
*/
|
||||
void fl_renderer_add_renderable(FlRenderer* renderer,
|
||||
FlutterViewId view_id,
|
||||
FlRenderable* renderable);
|
||||
|
||||
/**
|
||||
* fl_renderer_remove_view:
|
||||
* @renderer: an #FlRenderer.
|
||||
* @view_id: the ID of the view.
|
||||
*
|
||||
* Remove a view from the renderer.
|
||||
*/
|
||||
void fl_renderer_remove_view(FlRenderer* renderer, FlutterViewId view_id);
|
||||
|
||||
/**
|
||||
* fl_renderer_get_proc_address:
|
||||
* @renderer: an #FlRenderer.
|
||||
|
||||
@@ -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_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_framebuffer.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_epoxy.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
|
||||
@@ -30,9 +31,7 @@ TEST(FlRendererTest, BackgroundColor) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
@@ -84,9 +83,7 @@ TEST(FlRendererTest, RestoresGLState) {
|
||||
g_autoptr(FlFramebuffer) framebuffer =
|
||||
fl_framebuffer_new(GL_RGB, kWidth, kHeight);
|
||||
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), kWidth, kHeight);
|
||||
|
||||
FlutterBackingStore backing_store;
|
||||
@@ -151,9 +148,7 @@ TEST(FlRendererTest, BlitFramebuffer) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
@@ -211,9 +206,7 @@ TEST(FlRendererTest, BlitFramebufferExtension) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
@@ -264,9 +257,7 @@ TEST(FlRendererTest, NoBlitFramebuffer) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
@@ -320,9 +311,7 @@ TEST(FlRendererTest, BlitFramebufferNvidia) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(renderable));
|
||||
fl_renderer_wait_for_frame(FL_RENDERER(renderer), 1024, 1024);
|
||||
FlutterBackingStoreConfig config = {
|
||||
.struct_size = sizeof(FlutterBackingStoreConfig),
|
||||
@@ -377,11 +366,10 @@ TEST(FlRendererTest, MultiView) {
|
||||
g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
|
||||
fl_renderer_setup(FL_RENDERER(renderer));
|
||||
fl_renderer_set_engine(FL_RENDERER(renderer), engine);
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer),
|
||||
flutter::kFlutterImplicitViewId,
|
||||
FL_RENDERABLE(renderable));
|
||||
fl_renderer_add_renderable(FL_RENDERER(renderer), 1,
|
||||
FL_RENDERABLE(secondary_renderable));
|
||||
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);
|
||||
|
||||
EXPECT_EQ(fl_mock_renderable_get_redraw_count(renderable),
|
||||
@@ -405,7 +393,7 @@ TEST(FlRendererTest, MultiView) {
|
||||
.backing_store = &backing_store,
|
||||
.size = {.width = 1024, .height = 1024}};
|
||||
const FlutterLayer* layers[] = {&layer0};
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), 1, layers, 1);
|
||||
fl_renderer_present_layers(FL_RENDERER(renderer), view_id, layers, 1);
|
||||
latch.Signal();
|
||||
}).detach();
|
||||
|
||||
|
||||
@@ -479,9 +479,6 @@ static void realize_cb(FlView* self) {
|
||||
g_signal_connect_swapped(toplevel_window, "delete-event",
|
||||
G_CALLBACK(window_delete_event_cb), self);
|
||||
|
||||
fl_renderer_add_renderable(FL_RENDERER(self->renderer), self->view_id,
|
||||
FL_RENDERABLE(self));
|
||||
|
||||
// Flutter engine will need to make the context current from raster thread
|
||||
// during initialization.
|
||||
fl_renderer_clear_current(FL_RENDERER(self->renderer));
|
||||
@@ -558,9 +555,6 @@ static void fl_view_dispose(GObject* object) {
|
||||
self->cursor_changed_cb_id = 0;
|
||||
}
|
||||
|
||||
// Stop rendering.
|
||||
fl_renderer_remove_view(FL_RENDERER(self->renderer), self->view_id);
|
||||
|
||||
// Release the view ID from the engine.
|
||||
fl_engine_remove_view(self->engine, self->view_id, nullptr, nullptr,
|
||||
nullptr);
|
||||
@@ -773,6 +767,8 @@ G_MODULE_EXPORT FlView* fl_view_new(FlDartProject* project) {
|
||||
g_signal_connect_swapped(self->gl_area, "unrealize", G_CALLBACK(unrealize_cb),
|
||||
self);
|
||||
|
||||
fl_engine_set_implicit_view(engine, FL_RENDERABLE(self));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -784,14 +780,11 @@ G_MODULE_EXPORT FlView* fl_view_new_for_engine(FlEngine* engine) {
|
||||
g_assert(FL_IS_RENDERER_GDK(renderer));
|
||||
self->renderer = FL_RENDERER_GDK(g_object_ref(renderer));
|
||||
|
||||
self->view_id = fl_engine_add_view(engine, 1, 1, 1.0, self->cancellable,
|
||||
view_added_cb, self);
|
||||
self->view_id = fl_engine_add_view(engine, FL_RENDERABLE(self), 1, 1, 1.0,
|
||||
self->cancellable, view_added_cb, self);
|
||||
|
||||
setup_engine(self);
|
||||
|
||||
fl_renderer_add_renderable(FL_RENDERER(self->renderer), self->view_id,
|
||||
FL_RENDERABLE(self));
|
||||
|
||||
g_signal_connect_swapped(self->gl_area, "realize",
|
||||
G_CALLBACK(secondary_realize_cb), self);
|
||||
return self;
|
||||
|
||||
Reference in New Issue
Block a user