Restore creation of engine before Linux widget is realized. (flutter/engine#53604)
Due to changes in the renderer in fc560d4 the engine was created once a widget is realized, not when the widget is created. If a Flutter application changed the default my_application.cc template to show the Flutter widget after plugins are run then these plugins would not be able to access the engine. Solved by removing the GdkWindow from the renderer constructor and setting in later when the widget is realized. This works because the renderer is not used until the widget is realized. Fixes https://github.com/flutter/flutter/issues/144873
This commit is contained in:
parent
8998424bbc
commit
e3b2d11dba
@ -149,18 +149,6 @@ static void platform_message_handler_free(gpointer data) {
|
|||||||
g_free(self);
|
g_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void engine_weak_notify_cb(gpointer user_data,
|
|
||||||
GObject* where_the_object_was) {
|
|
||||||
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(user_data);
|
|
||||||
|
|
||||||
// Disconnect any handlers.
|
|
||||||
// Take the reference in case a handler tries to modify this table.
|
|
||||||
g_autoptr(GHashTable) handlers = self->platform_message_handlers;
|
|
||||||
self->platform_message_handlers = g_hash_table_new_full(
|
|
||||||
g_str_hash, g_str_equal, g_free, platform_message_handler_free);
|
|
||||||
g_hash_table_remove_all(handlers);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean fl_binary_messenger_platform_message_cb(
|
static gboolean fl_binary_messenger_platform_message_cb(
|
||||||
FlEngine* engine,
|
FlEngine* engine,
|
||||||
const gchar* channel,
|
const gchar* channel,
|
||||||
@ -187,13 +175,6 @@ static gboolean fl_binary_messenger_platform_message_cb(
|
|||||||
static void fl_binary_messenger_impl_dispose(GObject* object) {
|
static void fl_binary_messenger_impl_dispose(GObject* object) {
|
||||||
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(object);
|
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(object);
|
||||||
|
|
||||||
{
|
|
||||||
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
|
|
||||||
if (engine) {
|
|
||||||
g_object_weak_unref(G_OBJECT(engine), engine_weak_notify_cb, self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_weak_ref_clear(&self->engine);
|
g_weak_ref_clear(&self->engine);
|
||||||
|
|
||||||
g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);
|
g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);
|
||||||
@ -383,6 +364,17 @@ static void set_warns_on_channel_overflow(FlBinaryMessenger* messenger,
|
|||||||
set_warns_on_channel_overflow_response_cb, nullptr);
|
set_warns_on_channel_overflow_response_cb, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void shutdown(FlBinaryMessenger* messenger) {
|
||||||
|
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);
|
||||||
|
|
||||||
|
// Disconnect any handlers.
|
||||||
|
// Take the reference in case a handler tries to modify this table.
|
||||||
|
g_autoptr(GHashTable) handlers = self->platform_message_handlers;
|
||||||
|
self->platform_message_handlers = g_hash_table_new_full(
|
||||||
|
g_str_hash, g_str_equal, g_free, platform_message_handler_free);
|
||||||
|
g_hash_table_remove_all(handlers);
|
||||||
|
}
|
||||||
|
|
||||||
static void fl_binary_messenger_impl_class_init(
|
static void fl_binary_messenger_impl_class_init(
|
||||||
FlBinaryMessengerImplClass* klass) {
|
FlBinaryMessengerImplClass* klass) {
|
||||||
G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_impl_dispose;
|
G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_impl_dispose;
|
||||||
@ -396,6 +388,7 @@ static void fl_binary_messenger_impl_iface_init(
|
|||||||
iface->send_on_channel_finish = send_on_channel_finish;
|
iface->send_on_channel_finish = send_on_channel_finish;
|
||||||
iface->resize_channel = resize_channel;
|
iface->resize_channel = resize_channel;
|
||||||
iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow;
|
iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow;
|
||||||
|
iface->shutdown = shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fl_binary_messenger_impl_init(FlBinaryMessengerImpl* self) {
|
static void fl_binary_messenger_impl_init(FlBinaryMessengerImpl* self) {
|
||||||
@ -413,7 +406,6 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
|
|||||||
FL_IS_BINARY_MESSENGER_IMPL(self);
|
FL_IS_BINARY_MESSENGER_IMPL(self);
|
||||||
|
|
||||||
g_weak_ref_init(&self->engine, G_OBJECT(engine));
|
g_weak_ref_init(&self->engine, G_OBJECT(engine));
|
||||||
g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);
|
|
||||||
|
|
||||||
fl_engine_set_platform_message_handler(
|
fl_engine_set_platform_message_handler(
|
||||||
engine, fl_binary_messenger_platform_message_cb, self, NULL);
|
engine, fl_binary_messenger_platform_message_cb, self, NULL);
|
||||||
@ -490,3 +482,9 @@ G_MODULE_EXPORT void fl_binary_messenger_set_warns_on_channel_overflow(
|
|||||||
return FL_BINARY_MESSENGER_GET_IFACE(self)->set_warns_on_channel_overflow(
|
return FL_BINARY_MESSENGER_GET_IFACE(self)->set_warns_on_channel_overflow(
|
||||||
self, channel, warns);
|
self, channel, warns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fl_binary_messenger_shutdown(FlBinaryMessenger* self) {
|
||||||
|
g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
|
||||||
|
|
||||||
|
return FL_BINARY_MESSENGER_GET_IFACE(self)->shutdown(self);
|
||||||
|
}
|
||||||
|
@ -22,6 +22,14 @@ G_BEGIN_DECLS
|
|||||||
*/
|
*/
|
||||||
FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine);
|
FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fl_binary_messenger_shutdown:
|
||||||
|
* @messenger: an #FlBinaryMessenger.
|
||||||
|
*
|
||||||
|
* Shutdown the messenger closing any open channels.
|
||||||
|
*/
|
||||||
|
void fl_binary_messenger_shutdown(FlBinaryMessenger* messenger);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_
|
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_
|
||||||
|
@ -634,7 +634,7 @@ static void kill_handler_notify_cb(gpointer was_called) {
|
|||||||
|
|
||||||
TEST(FlBinaryMessengerTest, DeletingEngineClearsHandlers) {
|
TEST(FlBinaryMessengerTest, DeletingEngineClearsHandlers) {
|
||||||
FlEngine* engine = make_mock_engine();
|
FlEngine* engine = make_mock_engine();
|
||||||
g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
|
FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(engine);
|
||||||
gboolean was_killed = FALSE;
|
gboolean was_killed = FALSE;
|
||||||
|
|
||||||
// Listen for messages from the engine.
|
// Listen for messages from the engine.
|
||||||
|
@ -399,6 +399,9 @@ static void fl_engine_dispose(GObject* object) {
|
|||||||
self->aot_data = nullptr;
|
self->aot_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fl_binary_messenger_shutdown(self->binary_messenger);
|
||||||
|
fl_texture_registrar_shutdown(self->texture_registrar);
|
||||||
|
|
||||||
g_clear_object(&self->project);
|
g_clear_object(&self->project);
|
||||||
g_clear_object(&self->renderer);
|
g_clear_object(&self->renderer);
|
||||||
g_clear_object(&self->texture_registrar);
|
g_clear_object(&self->texture_registrar);
|
||||||
|
@ -39,6 +39,7 @@ static void fl_renderer_gdk_clear_current(FlRenderer* renderer) {
|
|||||||
gdk_gl_context_clear_current();
|
gdk_gl_context_clear_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements FlRenderer::get_refresh_rate.
|
||||||
static gdouble fl_renderer_gdk_get_refresh_rate(FlRenderer* renderer) {
|
static gdouble fl_renderer_gdk_get_refresh_rate(FlRenderer* renderer) {
|
||||||
FlRendererGdk* self = FL_RENDERER_GDK(renderer);
|
FlRendererGdk* self = FL_RENDERER_GDK(renderer);
|
||||||
GdkDisplay* display = gdk_window_get_display(self->window);
|
GdkDisplay* display = gdk_window_get_display(self->window);
|
||||||
@ -78,14 +79,22 @@ static void fl_renderer_gdk_class_init(FlRendererGdkClass* klass) {
|
|||||||
|
|
||||||
static void fl_renderer_gdk_init(FlRendererGdk* self) {}
|
static void fl_renderer_gdk_init(FlRendererGdk* self) {}
|
||||||
|
|
||||||
FlRendererGdk* fl_renderer_gdk_new(GdkWindow* window) {
|
FlRendererGdk* fl_renderer_gdk_new() {
|
||||||
FlRendererGdk* self =
|
FlRendererGdk* self =
|
||||||
FL_RENDERER_GDK(g_object_new(fl_renderer_gdk_get_type(), nullptr));
|
FL_RENDERER_GDK(g_object_new(fl_renderer_gdk_get_type(), nullptr));
|
||||||
self->window = window;
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fl_renderer_gdk_set_window(FlRendererGdk* self, GdkWindow* window) {
|
||||||
|
g_return_if_fail(FL_IS_RENDERER_GDK(self));
|
||||||
|
|
||||||
|
g_assert(self->window == nullptr);
|
||||||
|
self->window = window;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean fl_renderer_gdk_create_contexts(FlRendererGdk* self, GError** error) {
|
gboolean fl_renderer_gdk_create_contexts(FlRendererGdk* self, GError** error) {
|
||||||
|
g_return_val_if_fail(FL_IS_RENDERER_GDK(self), FALSE);
|
||||||
|
|
||||||
self->gdk_context = gdk_window_create_gl_context(self->window, error);
|
self->gdk_context = gdk_window_create_gl_context(self->window, error);
|
||||||
if (self->gdk_context == nullptr) {
|
if (self->gdk_context == nullptr) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -23,13 +23,22 @@ G_DECLARE_FINAL_TYPE(FlRendererGdk,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fl_renderer_gdk_new:
|
* fl_renderer_gdk_new:
|
||||||
* @window: the window that is being rendered on.
|
|
||||||
*
|
*
|
||||||
* Creates an object that allows Flutter to render by OpenGL ES.
|
* Creates an object that allows Flutter to render by OpenGL ES.
|
||||||
*
|
*
|
||||||
* Returns: a new #FlRendererGdk.
|
* Returns: a new #FlRendererGdk.
|
||||||
*/
|
*/
|
||||||
FlRendererGdk* fl_renderer_gdk_new(GdkWindow* window);
|
FlRendererGdk* fl_renderer_gdk_new();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fl_renderer_gdk_set_window:
|
||||||
|
* @renderer: an #FlRendererGdk.
|
||||||
|
* @window: the window that is being rendered on.
|
||||||
|
*
|
||||||
|
* Set the window that is being rendered on. This is only called once when the
|
||||||
|
* window is available.
|
||||||
|
*/
|
||||||
|
void fl_renderer_gdk_set_window(FlRendererGdk* renderer, GdkWindow* window);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fl_renderer_gdk_create_contexts:
|
* fl_renderer_gdk_create_contexts:
|
||||||
|
@ -11,7 +11,7 @@ static constexpr int kMillisecondsPerMicrosecond = 1000;
|
|||||||
struct _FlTaskRunner {
|
struct _FlTaskRunner {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
FlEngine* engine;
|
GWeakRef engine;
|
||||||
|
|
||||||
GMutex mutex;
|
GMutex mutex;
|
||||||
GCond cond;
|
GCond cond;
|
||||||
@ -51,11 +51,14 @@ static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner* self) {
|
|||||||
|
|
||||||
g_mutex_unlock(&self->mutex);
|
g_mutex_unlock(&self->mutex);
|
||||||
|
|
||||||
l = expired_tasks;
|
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
|
||||||
while (l != nullptr && self->engine) {
|
if (engine != nullptr) {
|
||||||
FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
|
l = expired_tasks;
|
||||||
fl_engine_execute_task(self->engine, &task->task);
|
while (l != nullptr) {
|
||||||
l = l->next;
|
FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
|
||||||
|
fl_engine_execute_task(engine, &task->task);
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free_full(expired_tasks, g_free);
|
g_list_free_full(expired_tasks, g_free);
|
||||||
@ -120,12 +123,6 @@ static void fl_task_runner_tasks_did_change_locked(FlTaskRunner* self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void engine_weak_notify_cb(gpointer user_data,
|
|
||||||
GObject* where_the_object_was) {
|
|
||||||
FlTaskRunner* self = FL_TASK_RUNNER(user_data);
|
|
||||||
self->engine = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fl_task_runner_dispose(GObject* object) {
|
void fl_task_runner_dispose(GObject* object) {
|
||||||
FlTaskRunner* self = FL_TASK_RUNNER(object);
|
FlTaskRunner* self = FL_TASK_RUNNER(object);
|
||||||
|
|
||||||
@ -133,11 +130,7 @@ void fl_task_runner_dispose(GObject* object) {
|
|||||||
// main thread
|
// main thread
|
||||||
g_assert(!self->blocking_main_thread);
|
g_assert(!self->blocking_main_thread);
|
||||||
|
|
||||||
if (self->engine != nullptr) {
|
g_weak_ref_clear(&self->engine);
|
||||||
g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
|
|
||||||
self->engine = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex_clear(&self->mutex);
|
g_mutex_clear(&self->mutex);
|
||||||
g_cond_clear(&self->cond);
|
g_cond_clear(&self->cond);
|
||||||
|
|
||||||
@ -159,11 +152,10 @@ static void fl_task_runner_init(FlTaskRunner* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlTaskRunner* fl_task_runner_new(FlEngine* engine) {
|
FlTaskRunner* fl_task_runner_new(FlEngine* engine) {
|
||||||
FlTaskRunner* res =
|
FlTaskRunner* self =
|
||||||
FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr));
|
FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr));
|
||||||
res->engine = engine;
|
g_weak_ref_init(&self->engine, G_OBJECT(engine));
|
||||||
g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, res);
|
return self;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fl_task_runner_post_task(FlTaskRunner* self,
|
void fl_task_runner_post_task(FlTaskRunner* self,
|
||||||
|
@ -23,7 +23,7 @@ struct _FlTextureRegistrarImpl {
|
|||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
// Weak reference to the engine this texture registrar is created for.
|
// Weak reference to the engine this texture registrar is created for.
|
||||||
FlEngine* engine;
|
GWeakRef engine;
|
||||||
|
|
||||||
// ID to assign to the next new texture.
|
// ID to assign to the next new texture.
|
||||||
int64_t next_id;
|
int64_t next_id;
|
||||||
@ -54,20 +54,6 @@ G_DEFINE_TYPE_WITH_CODE(
|
|||||||
static void fl_texture_registrar_default_init(
|
static void fl_texture_registrar_default_init(
|
||||||
FlTextureRegistrarInterface* iface) {}
|
FlTextureRegistrarInterface* iface) {}
|
||||||
|
|
||||||
static void engine_weak_notify_cb(gpointer user_data,
|
|
||||||
GObject* where_the_object_was) {
|
|
||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(user_data);
|
|
||||||
self->engine = nullptr;
|
|
||||||
|
|
||||||
// Unregister any textures.
|
|
||||||
g_mutex_lock(&self->textures_mutex);
|
|
||||||
g_autoptr(GHashTable) textures = self->textures;
|
|
||||||
self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
|
|
||||||
g_object_unref);
|
|
||||||
g_hash_table_remove_all(textures);
|
|
||||||
g_mutex_unlock(&self->textures_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fl_texture_registrar_impl_dispose(GObject* object) {
|
static void fl_texture_registrar_impl_dispose(GObject* object) {
|
||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(object);
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(object);
|
||||||
|
|
||||||
@ -75,10 +61,7 @@ static void fl_texture_registrar_impl_dispose(GObject* object) {
|
|||||||
g_clear_pointer(&self->textures, g_hash_table_unref);
|
g_clear_pointer(&self->textures, g_hash_table_unref);
|
||||||
g_mutex_unlock(&self->textures_mutex);
|
g_mutex_unlock(&self->textures_mutex);
|
||||||
|
|
||||||
if (self->engine != nullptr) {
|
g_weak_ref_clear(&self->engine);
|
||||||
g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
|
|
||||||
self->engine = nullptr;
|
|
||||||
}
|
|
||||||
g_mutex_clear(&self->textures_mutex);
|
g_mutex_clear(&self->textures_mutex);
|
||||||
|
|
||||||
G_OBJECT_CLASS(fl_texture_registrar_impl_parent_class)->dispose(object);
|
G_OBJECT_CLASS(fl_texture_registrar_impl_parent_class)->dispose(object);
|
||||||
@ -94,7 +77,8 @@ static gboolean register_texture(FlTextureRegistrar* registrar,
|
|||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
||||||
|
|
||||||
if (FL_IS_TEXTURE_GL(texture) || FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
|
if (FL_IS_TEXTURE_GL(texture) || FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
|
||||||
if (self->engine == nullptr) {
|
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
|
||||||
|
if (engine == nullptr) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +88,7 @@ static gboolean register_texture(FlTextureRegistrar* registrar,
|
|||||||
// https://github.com/flutter/flutter/issues/124009 int64_t id =
|
// https://github.com/flutter/flutter/issues/124009 int64_t id =
|
||||||
// self->next_id++;
|
// self->next_id++;
|
||||||
int64_t id = reinterpret_cast<int64_t>(texture);
|
int64_t id = reinterpret_cast<int64_t>(texture);
|
||||||
if (fl_engine_register_external_texture(self->engine, id)) {
|
if (fl_engine_register_external_texture(engine, id)) {
|
||||||
fl_texture_set_id(texture, id);
|
fl_texture_set_id(texture, id);
|
||||||
g_mutex_lock(&self->textures_mutex);
|
g_mutex_lock(&self->textures_mutex);
|
||||||
g_hash_table_insert(self->textures, GINT_TO_POINTER(id),
|
g_hash_table_insert(self->textures, GINT_TO_POINTER(id),
|
||||||
@ -134,11 +118,12 @@ static gboolean mark_texture_frame_available(FlTextureRegistrar* registrar,
|
|||||||
FlTexture* texture) {
|
FlTexture* texture) {
|
||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
||||||
|
|
||||||
if (self->engine == nullptr) {
|
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
|
||||||
|
if (engine == nullptr) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fl_engine_mark_texture_frame_available(self->engine,
|
return fl_engine_mark_texture_frame_available(engine,
|
||||||
fl_texture_get_id(texture));
|
fl_texture_get_id(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,12 +131,13 @@ static gboolean unregister_texture(FlTextureRegistrar* registrar,
|
|||||||
FlTexture* texture) {
|
FlTexture* texture) {
|
||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
||||||
|
|
||||||
if (self->engine == nullptr) {
|
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
|
||||||
|
if (engine == nullptr) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean result = fl_engine_unregister_external_texture(
|
gboolean result =
|
||||||
self->engine, fl_texture_get_id(texture));
|
fl_engine_unregister_external_texture(engine, fl_texture_get_id(texture));
|
||||||
|
|
||||||
g_mutex_lock(&self->textures_mutex);
|
g_mutex_lock(&self->textures_mutex);
|
||||||
if (!g_hash_table_remove(self->textures,
|
if (!g_hash_table_remove(self->textures,
|
||||||
@ -163,12 +149,25 @@ static gboolean unregister_texture(FlTextureRegistrar* registrar,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void shutdown(FlTextureRegistrar* registrar) {
|
||||||
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
|
||||||
|
|
||||||
|
// Unregister any textures.
|
||||||
|
g_mutex_lock(&self->textures_mutex);
|
||||||
|
g_autoptr(GHashTable) textures = self->textures;
|
||||||
|
self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
|
||||||
|
g_object_unref);
|
||||||
|
g_hash_table_remove_all(textures);
|
||||||
|
g_mutex_unlock(&self->textures_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void fl_texture_registrar_impl_iface_init(
|
static void fl_texture_registrar_impl_iface_init(
|
||||||
FlTextureRegistrarInterface* iface) {
|
FlTextureRegistrarInterface* iface) {
|
||||||
iface->register_texture = register_texture;
|
iface->register_texture = register_texture;
|
||||||
iface->lookup_texture = lookup_texture;
|
iface->lookup_texture = lookup_texture;
|
||||||
iface->mark_texture_frame_available = mark_texture_frame_available;
|
iface->mark_texture_frame_available = mark_texture_frame_available;
|
||||||
iface->unregister_texture = unregister_texture;
|
iface->unregister_texture = unregister_texture;
|
||||||
|
iface->shutdown = shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl* self) {
|
static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl* self) {
|
||||||
@ -213,6 +212,12 @@ G_MODULE_EXPORT gboolean fl_texture_registrar_unregister_texture(
|
|||||||
texture);
|
texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fl_texture_registrar_shutdown(FlTextureRegistrar* self) {
|
||||||
|
g_return_if_fail(FL_IS_TEXTURE_REGISTRAR(self));
|
||||||
|
|
||||||
|
return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->shutdown(self);
|
||||||
|
}
|
||||||
|
|
||||||
FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) {
|
FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) {
|
||||||
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(
|
FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(
|
||||||
g_object_new(fl_texture_registrar_impl_get_type(), nullptr));
|
g_object_new(fl_texture_registrar_impl_get_type(), nullptr));
|
||||||
@ -220,8 +225,7 @@ FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) {
|
|||||||
// Added to stop compiler complaining about an unused function.
|
// Added to stop compiler complaining about an unused function.
|
||||||
FL_IS_TEXTURE_REGISTRAR_IMPL(self);
|
FL_IS_TEXTURE_REGISTRAR_IMPL(self);
|
||||||
|
|
||||||
self->engine = engine;
|
g_weak_ref_init(&self->engine, G_OBJECT(engine));
|
||||||
g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);
|
|
||||||
|
|
||||||
return FL_TEXTURE_REGISTRAR(self);
|
return FL_TEXTURE_REGISTRAR(self);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,14 @@ FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine);
|
|||||||
FlTexture* fl_texture_registrar_lookup_texture(FlTextureRegistrar* registrar,
|
FlTexture* fl_texture_registrar_lookup_texture(FlTextureRegistrar* registrar,
|
||||||
int64_t texture_id);
|
int64_t texture_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fl_texture_registrar_shutdown:
|
||||||
|
* @registrar: an #FlTextureRegistrar.
|
||||||
|
*
|
||||||
|
* Shutdown the registrary and unregister any textures.
|
||||||
|
*/
|
||||||
|
void fl_texture_registrar_shutdown(FlTextureRegistrar* registrar);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_PRIVATE_H_
|
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_PRIVATE_H_
|
||||||
|
@ -550,13 +550,8 @@ static gboolean window_state_event_cb(FlView* self, GdkEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GdkGLContext* create_context_cb(FlView* self) {
|
static GdkGLContext* create_context_cb(FlView* self) {
|
||||||
self->renderer =
|
fl_renderer_gdk_set_window(self->renderer,
|
||||||
fl_renderer_gdk_new(gtk_widget_get_parent_window(GTK_WIDGET(self)));
|
gtk_widget_get_parent_window(GTK_WIDGET(self)));
|
||||||
self->engine = fl_engine_new(self->project, FL_RENDERER(self->renderer));
|
|
||||||
fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb,
|
|
||||||
self, nullptr);
|
|
||||||
fl_engine_set_on_pre_engine_restart_handler(
|
|
||||||
self->engine, on_pre_engine_restart_cb, self, nullptr);
|
|
||||||
|
|
||||||
// Must initialize the keymap before the keyboard.
|
// Must initialize the keymap before the keyboard.
|
||||||
self->keymap = gdk_keymap_get_for_display(gdk_display_get_default());
|
self->keymap = gdk_keymap_get_for_display(gdk_display_get_default());
|
||||||
@ -654,6 +649,17 @@ static void size_allocate_cb(FlView* self) {
|
|||||||
handle_geometry_changed(self);
|
handle_geometry_changed(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fl_view_constructed(GObject* object) {
|
||||||
|
FlView* self = FL_VIEW(object);
|
||||||
|
|
||||||
|
self->renderer = fl_renderer_gdk_new();
|
||||||
|
self->engine = fl_engine_new(self->project, FL_RENDERER(self->renderer));
|
||||||
|
fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb,
|
||||||
|
self, nullptr);
|
||||||
|
fl_engine_set_on_pre_engine_restart_handler(
|
||||||
|
self->engine, on_pre_engine_restart_cb, self, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
static void fl_view_set_property(GObject* object,
|
static void fl_view_set_property(GObject* object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue* value,
|
const GValue* value,
|
||||||
@ -750,6 +756,7 @@ static gboolean fl_view_key_release_event(GtkWidget* widget,
|
|||||||
|
|
||||||
static void fl_view_class_init(FlViewClass* klass) {
|
static void fl_view_class_init(FlViewClass* klass) {
|
||||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||||
|
object_class->constructed = fl_view_constructed;
|
||||||
object_class->set_property = fl_view_set_property;
|
object_class->set_property = fl_view_set_property;
|
||||||
object_class->get_property = fl_view_get_property;
|
object_class->get_property = fl_view_get_property;
|
||||||
object_class->notify = fl_view_notify;
|
object_class->notify = fl_view_notify;
|
||||||
|
@ -7,6 +7,19 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
TEST(FlViewTest, GetEngine) {
|
||||||
|
flutter::testing::fl_ensure_gtk_init();
|
||||||
|
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||||
|
g_autoptr(FlView) view = fl_view_new(project);
|
||||||
|
|
||||||
|
// Check the engine is immediately available (i.e. before the widget is
|
||||||
|
// realized).
|
||||||
|
FlEngine* engine = fl_view_get_engine(view);
|
||||||
|
EXPECT_NE(engine, nullptr);
|
||||||
|
|
||||||
|
g_object_ref_sink(view);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FlViewTest, StateUpdateDoesNotHappenInInit) {
|
TEST(FlViewTest, StateUpdateDoesNotHappenInInit) {
|
||||||
flutter::testing::fl_ensure_gtk_init();
|
flutter::testing::fl_ensure_gtk_init();
|
||||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||||
|
@ -104,6 +104,8 @@ struct _FlBinaryMessengerInterface {
|
|||||||
void (*set_warns_on_channel_overflow)(FlBinaryMessenger* messenger,
|
void (*set_warns_on_channel_overflow)(FlBinaryMessenger* messenger,
|
||||||
const gchar* channel,
|
const gchar* channel,
|
||||||
bool warns);
|
bool warns);
|
||||||
|
|
||||||
|
void (*shutdown)(FlBinaryMessenger* messenger);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FlBinaryMessengerResponseHandleClass {
|
struct _FlBinaryMessengerResponseHandleClass {
|
||||||
|
@ -37,6 +37,8 @@ struct _FlTextureRegistrarInterface {
|
|||||||
|
|
||||||
gboolean (*unregister_texture)(FlTextureRegistrar* registrar,
|
gboolean (*unregister_texture)(FlTextureRegistrar* registrar,
|
||||||
FlTexture* texture);
|
FlTexture* texture);
|
||||||
|
|
||||||
|
void (*shutdown)(FlTextureRegistrar* registrar);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,6 +141,8 @@ static void fl_mock_binary_messenger_set_warns_on_channel_overflow(
|
|||||||
channel, warns);
|
channel, warns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fl_mock_binary_messenger_shutdown(FlBinaryMessenger* messenger) {}
|
||||||
|
|
||||||
static void fl_mock_binary_messenger_iface_init(
|
static void fl_mock_binary_messenger_iface_init(
|
||||||
FlBinaryMessengerInterface* iface) {
|
FlBinaryMessengerInterface* iface) {
|
||||||
iface->set_message_handler_on_channel =
|
iface->set_message_handler_on_channel =
|
||||||
@ -152,6 +154,7 @@ static void fl_mock_binary_messenger_iface_init(
|
|||||||
iface->resize_channel = fl_mock_binary_messenger_resize_channel;
|
iface->resize_channel = fl_mock_binary_messenger_resize_channel;
|
||||||
iface->set_warns_on_channel_overflow =
|
iface->set_warns_on_channel_overflow =
|
||||||
fl_mock_binary_messenger_set_warns_on_channel_overflow;
|
fl_mock_binary_messenger_set_warns_on_channel_overflow;
|
||||||
|
iface->shutdown = fl_mock_binary_messenger_shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fl_mock_binary_messenger_init(FlMockBinaryMessenger* self) {}
|
static void fl_mock_binary_messenger_init(FlMockBinaryMessenger* self) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user