diff --git a/shell/platform/linux/BUILD.gn b/shell/platform/linux/BUILD.gn index efad5e89d868e..f6e49a65633ee 100644 --- a/shell/platform/linux/BUILD.gn +++ b/shell/platform/linux/BUILD.gn @@ -59,6 +59,7 @@ _public_headers = [ "public/flutter_linux/fl_standard_message_codec.h", "public/flutter_linux/fl_standard_method_codec.h", "public/flutter_linux/fl_string_codec.h", + "public/flutter_linux/fl_texture_registrar.h", "public/flutter_linux/fl_value.h", "public/flutter_linux/fl_view.h", "public/flutter_linux/flutter_linux.h", @@ -80,6 +81,7 @@ source_set("flutter_linux_sources") { "fl_binary_messenger.cc", "fl_dart_project.cc", "fl_engine.cc", + "fl_external_texture_gl.cc", "fl_json_message_codec.cc", "fl_json_method_codec.cc", "fl_key_event_plugin.cc", @@ -99,6 +101,7 @@ source_set("flutter_linux_sources") { "fl_standard_method_codec.cc", "fl_string_codec.cc", "fl_text_input_plugin.cc", + "fl_texture_registrar.cc", "fl_value.cc", "fl_view.cc", ] diff --git a/shell/platform/linux/fl_engine.cc b/shell/platform/linux/fl_engine.cc index 7308bb792c64a..7141565ef5b61 100644 --- a/shell/platform/linux/fl_engine.cc +++ b/shell/platform/linux/fl_engine.cc @@ -3,12 +3,14 @@ // found in the LICENSE file. #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" +#include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/linux/fl_engine_private.h" #include "flutter/shell/platform/linux/fl_binary_messenger_private.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_renderer_headless.h" +#include "flutter/shell/platform/linux/fl_texture_registrar_private.h" #include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h" #include @@ -27,6 +29,7 @@ struct _FlEngine { FlDartProject* project; FlRenderer* renderer; FlBinaryMessenger* binary_messenger; + FlTextureRegistrar* texture_registrar; FlutterEngineAOTData aot_data; FLUTTER_API_SYMBOL(FlutterEngine) engine; @@ -210,6 +213,20 @@ static bool fl_engine_gl_make_resource_current(void* user_data) { return result; } +static bool fl_engine_gl_external_texture_frame_callback( + void* user_data, + int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* texture) { + FlEngine* self = static_cast(user_data); + if (!self->texture_registrar) { + return false; + } + return fl_texture_registrar_populate_texture( + self->texture_registrar, texture_id, width, height, texture); +} + // Called by the engine to determine if it is on the GTK thread. static bool fl_engine_runs_task_on_current_thread(void* user_data) { FlEngine* self = static_cast(user_data); @@ -268,7 +285,8 @@ static FlPluginRegistrar* fl_engine_get_registrar_for_plugin( const gchar* name) { FlEngine* self = FL_ENGINE(registry); - return fl_plugin_registrar_new(nullptr, self->binary_messenger); + return fl_plugin_registrar_new(nullptr, self->binary_messenger, + self->texture_registrar); } static void fl_engine_plugin_registry_iface_init( @@ -291,6 +309,7 @@ static void fl_engine_dispose(GObject* object) { g_clear_object(&self->project); g_clear_object(&self->renderer); + g_clear_object(&self->texture_registrar); g_clear_object(&self->binary_messenger); if (self->platform_message_handler_destroy_notify) { @@ -310,6 +329,7 @@ static void fl_engine_class_init(FlEngineClass* klass) { static void fl_engine_init(FlEngine* self) { self->thread = g_thread_self(); + self->texture_registrar = fl_texture_registrar_new(self); self->binary_messenger = fl_binary_messenger_new(self); } @@ -344,6 +364,8 @@ gboolean fl_engine_start(FlEngine* self, GError** error) { config.open_gl.fbo_callback = fl_engine_gl_get_fbo; config.open_gl.present = fl_engine_gl_present; config.open_gl.make_resource_current = fl_engine_gl_make_resource_current; + config.open_gl.gl_external_texture_frame_callback = + fl_engine_gl_external_texture_frame_callback; FlutterTaskRunnerDescription platform_task_runner = {}; platform_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription); @@ -575,8 +597,31 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self, FlutterEngineSendPointerEvent(self->engine, &fl_event, 1); } +bool fl_engine_mark_texture_frame_available(FlEngine* self, + int64_t texture_id) { + g_return_val_if_fail(FL_IS_ENGINE(self), false); + return !FlutterEngineMarkExternalTextureFrameAvailable(self->engine, + texture_id); +} + +bool fl_engine_register_external_texture(FlEngine* self, int64_t texture_id) { + g_return_val_if_fail(FL_IS_ENGINE(self), false); + return !FlutterEngineRegisterExternalTexture(self->engine, texture_id); +} + +void fl_engine_unregister_external_texture(FlEngine* self, int64_t texture_id) { + g_return_if_fail(FL_IS_ENGINE(self)); + FlutterEngineUnregisterExternalTexture(self->engine, texture_id); +} + G_MODULE_EXPORT FlBinaryMessenger* fl_engine_get_binary_messenger( FlEngine* self) { g_return_val_if_fail(FL_IS_ENGINE(self), nullptr); return self->binary_messenger; } + +G_MODULE_EXPORT FlTextureRegistrar* fl_engine_get_texture_registrar( + FlEngine* self) { + g_return_val_if_fail(FL_IS_ENGINE(self), nullptr); + return self->texture_registrar; +} diff --git a/shell/platform/linux/fl_engine_private.h b/shell/platform/linux/fl_engine_private.h index 6c912979ba16c..e399f1ef33479 100644 --- a/shell/platform/linux/fl_engine_private.h +++ b/shell/platform/linux/fl_engine_private.h @@ -175,6 +175,41 @@ GBytes* fl_engine_send_platform_message_finish(FlEngine* engine, GAsyncResult* result, GError** error); +/** + * fl_engine_mark_texture_frame_available: + * @engine: an #FlEngine. + * @texture_id: an int64_t. + * + * Tells the Flutter engine that a new texture frame is available for the given + * texture. + * + * Returns: true on success. + */ +bool fl_engine_mark_texture_frame_available(FlEngine* engine, + int64_t texture_id); + +/** + * fl_engine_register_external_texture: + * @engine: an #FlEngine. + * @texture_id: an int64_t. + * + * Tells the Flutter engine that a new external texture is available. + * + * Returns: true on success. + */ +bool fl_engine_register_external_texture(FlEngine* engine, int64_t texture_id); + +/** + * fl_engine_unregister_external_texture: + * @engine: an #FlEngine. + * @texture_id: an int64_t. + * + * Tells the Flutter engine that an existing external texture is not available + * anymore. + */ +void fl_engine_unregister_external_texture(FlEngine* engine, + int64_t texture_id); + G_END_DECLS #endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_ diff --git a/shell/platform/linux/fl_external_texture_gl.cc b/shell/platform/linux/fl_external_texture_gl.cc new file mode 100644 index 0000000000000..675097a3e4d91 --- /dev/null +++ b/shell/platform/linux/fl_external_texture_gl.cc @@ -0,0 +1,131 @@ +// Copyright 2020 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 "flutter/shell/platform/linux/fl_external_texture_gl.h" + +#include +#include +#include + +struct _FlExternalTextureGl { + GLuint gl_texture_id; + FlTextureCallback callback; + struct { + bool valid; + void (*genTextures)(GLsizei n, GLuint* textures); + void (*bindTexture)(GLenum target, GLuint texture); + void (*texParameteri)(GLenum target, GLenum pname, GLenum param); + void (*texImage2D)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* data); + void (*deleteTextures)(GLsizei n, const GLuint* textures); + } gl; + void* user_data; +}; + +G_DEFINE_TYPE(FlExternalTextureGl, fl_external_texture_gl, G_TYPE_OBJECT) + +static void fl_external_texture_gl_dispose(GObject* object) { + FlExternalTextureGl* self = FL_EXTERNAL_TEXTURE_GL(object); + if (self->gl.valid) { + self->gl.deleteTextures(1, &self->gl_texture_id); + } + + G_OBJECT_CLASS(fl_external_texture_gl_parent_class)->dispose(object); +} + +static void fl_external_texture_gl_class_init(FlExternalTextureGlClass* klass) { + G_OBJECT_CLASS(klass)->dispose = fl_external_texture_gl_dispose; +} + +static void fl_external_texture_gl_init(FlExternalTextureGl* self) {} + +int64_t fl_external_texture_gl_texture_id(FlExternalTextureGl* self) { + return reinterpret_cast(self); +} + +bool fl_external_texture_gl_populate_texture( + FlExternalTextureGl* self, + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + size_t real_width = width, real_height = height; + if (!fl_external_texture_gl_copy_pixel_buffer(self, &real_width, + &real_height)) + return false; + + opengl_texture->target = GL_TEXTURE_2D; + opengl_texture->name = self->gl_texture_id; + opengl_texture->format = GL_RGBA8; + opengl_texture->destruction_callback = nullptr; + opengl_texture->user_data = static_cast(self); + opengl_texture->width = real_width; + opengl_texture->height = real_height; + + return true; +} + +void fl_external_texture_gl_load_funcs(FlExternalTextureGl* self) { + self->gl.genTextures = reinterpret_cast( + eglGetProcAddress("glGenTextures")); + self->gl.bindTexture = reinterpret_cast( + eglGetProcAddress("glBindTexture")); + self->gl.texParameteri = reinterpret_cast( + eglGetProcAddress("glTexParameteri")); + self->gl.texImage2D = + reinterpret_cast( + eglGetProcAddress("glTexImage2D")); + self->gl.deleteTextures = reinterpret_cast( + eglGetProcAddress("glDeleteTextures")); + self->gl.valid = true; +} + +bool fl_external_texture_gl_copy_pixel_buffer(FlExternalTextureGl* self, + size_t* width, + size_t* height) { + const FlPixelBuffer* pixel_buffer = + self->callback(*width, *height, self->user_data); + if (!pixel_buffer || !pixel_buffer->buffer) + return false; + *width = pixel_buffer->width; + *height = pixel_buffer->height; + + if (!self->gl.valid) + fl_external_texture_gl_load_funcs(self); + if (self->gl_texture_id == 0) { + self->gl.genTextures(1, &self->gl_texture_id); + self->gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id); + self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_BORDER); + self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_BORDER); + self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + self->gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + self->gl.bindTexture(GL_TEXTURE_2D, self->gl_texture_id); + } + self->gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, + pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixel_buffer->buffer); + return true; +} + +FlExternalTextureGl* fl_external_texture_gl_new( + FlTextureCallback texture_callback, + void* user_data) { + FlExternalTextureGl* self = FL_EXTERNAL_TEXTURE_GL( + g_object_new(fl_external_texture_gl_get_type(), nullptr)); + + self->callback = texture_callback; + self->user_data = user_data; + + return self; +} diff --git a/shell/platform/linux/fl_external_texture_gl.h b/shell/platform/linux/fl_external_texture_gl.h new file mode 100644 index 0000000000000..cfbb0499f50ff --- /dev/null +++ b/shell/platform/linux/fl_external_texture_gl.h @@ -0,0 +1,85 @@ +// Copyright 2020 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_EXTERNAL_TEXURE_GL_H +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_EXTERNAL_TEXURE_GL_H + +#include +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h" + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(FlExternalTextureGl, + fl_external_texture_gl, + FL, + EXTERNAL_TEXTURE_GL, + GObject) + +/** + * FlExternalTextureGl: + * + * #FlExternalTextureGl is an abstraction over OpenGL textures. + */ + +/** + * fl_external_texture_gl_new: + * @texture_callback: An #FlTextureCallback. + * @user_data: A void*. + * + * Creates a new #FlExternalTextureGl. + * + * Returns: a new #FlExternalTextureGl. + */ +FlExternalTextureGl* fl_external_texture_gl_new( + FlTextureCallback texture_callback, + void* user_data); + +/** + * fl_external_texture_gl_populate_texture: + * @width: a size_t. + * @height: a size_t. + * @opengl_texture: a FlutterOpenGLTexture*. + * + * Attempts to populate the specified |opengl_texture| with texture details + * such as the name, width, height and the pixel format upon successfully + * copying the buffer provided by |texture_callback_|. See + * |fl_external_texture_gl_copy_pixel_buffer|. + * + * Returns true on success or false if the pixel buffer could not be copied. + */ +bool fl_external_texture_gl_populate_texture( + FlExternalTextureGl* self, + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture); + +/** + * fl_external_texture_gl_texture_id: + * + * Retrieves the unique id of this texture. + * + * Returns an int64_t, which is the unique id of this texture. + */ +int64_t fl_external_texture_gl_texture_id(FlExternalTextureGl* self); + +/** + * fl_external_texture_gl_copy_pixel_buffer: + * @width: a size_t. + * @height: a size_t. + * + * Attempts to copy the pixel buffer returned by |texture_callback_| to + * OpenGL. The |width| and |height| will be set to the actual bounds of the + * copied pixel buffer. + * + * Returns true on success or false if the pixel buffer returned by + * |texture_callback_| was invalid. + */ +bool fl_external_texture_gl_copy_pixel_buffer(FlExternalTextureGl* self, + size_t* width, + size_t* height); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_EXTERNAL_TEXURE_GL_H diff --git a/shell/platform/linux/fl_plugin_registrar.cc b/shell/platform/linux/fl_plugin_registrar.cc index 9ca72258b6e73..6be2049510f26 100644 --- a/shell/platform/linux/fl_plugin_registrar.cc +++ b/shell/platform/linux/fl_plugin_registrar.cc @@ -15,6 +15,8 @@ struct _FlPluginRegistrar { // Messenger to communicate on. FlBinaryMessenger* messenger; + + FlTextureRegistrar* texture_registrar; }; // Added here to stop the compiler from optimising this function away. @@ -36,6 +38,7 @@ static void fl_plugin_registrar_dispose(GObject* object) { } g_clear_object(&self->messenger); + g_clear_object(&self->texture_registrar); G_OBJECT_CLASS(fl_plugin_registrar_parent_class)->dispose(object); } @@ -46,8 +49,10 @@ static void fl_plugin_registrar_class_init(FlPluginRegistrarClass* klass) { static void fl_plugin_registrar_init(FlPluginRegistrar* self) {} -FlPluginRegistrar* fl_plugin_registrar_new(FlView* view, - FlBinaryMessenger* messenger) { +FlPluginRegistrar* fl_plugin_registrar_new( + FlView* view, + FlBinaryMessenger* messenger, + FlTextureRegistrar* texture_registrar) { g_return_val_if_fail(view == nullptr || FL_IS_VIEW(view), nullptr); g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr); @@ -58,6 +63,8 @@ FlPluginRegistrar* fl_plugin_registrar_new(FlView* view, if (view != nullptr) g_object_weak_ref(G_OBJECT(view), view_weak_notify_cb, self); self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger)); + self->texture_registrar = + FL_TEXTURE_REGISTRAR(g_object_ref(texture_registrar)); return self; } @@ -69,6 +76,13 @@ G_MODULE_EXPORT FlBinaryMessenger* fl_plugin_registrar_get_messenger( return self->messenger; } +G_MODULE_EXPORT FlTextureRegistrar* fl_plugin_registrar_get_texture_registrar( + FlPluginRegistrar* self) { + g_return_val_if_fail(FL_IS_PLUGIN_REGISTRAR(self), nullptr); + + return self->texture_registrar; +} + G_MODULE_EXPORT FlView* fl_plugin_registrar_get_view(FlPluginRegistrar* self) { g_return_val_if_fail(FL_IS_PLUGIN_REGISTRAR(self), nullptr); diff --git a/shell/platform/linux/fl_plugin_registrar_private.h b/shell/platform/linux/fl_plugin_registrar_private.h index 712f32a3d98c3..90e3f8378b197 100644 --- a/shell/platform/linux/fl_plugin_registrar_private.h +++ b/shell/platform/linux/fl_plugin_registrar_private.h @@ -15,13 +15,16 @@ G_BEGIN_DECLS * @view: (allow-none): the #FlView that is being plugged into or %NULL for * headless mode. * @messenger: the #FlBinaryMessenger to communicate with. + * @texture_registrar: The #FlTextureRegistrar to communicate with. * * Creates a new #FlPluginRegistrar. * * Returns: a new #FlPluginRegistrar. */ -FlPluginRegistrar* fl_plugin_registrar_new(FlView* view, - FlBinaryMessenger* messenger); +FlPluginRegistrar* fl_plugin_registrar_new( + FlView* view, + FlBinaryMessenger* messenger, + FlTextureRegistrar* texture_registrar); G_END_DECLS diff --git a/shell/platform/linux/fl_texture_registrar.cc b/shell/platform/linux/fl_texture_registrar.cc new file mode 100644 index 0000000000000..0d7ec7f98d4e4 --- /dev/null +++ b/shell/platform/linux/fl_texture_registrar.cc @@ -0,0 +1,93 @@ +// Copyright 2020 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 "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/fl_engine_private.h" +#include "flutter/shell/platform/linux/fl_external_texture_gl.h" +#include "flutter/shell/platform/linux/fl_texture_registrar_private.h" + +#include + +struct _FlTextureRegistrar { + GObject parent_instance; + + FlEngine* engine; + + GHashTable* textures; +}; + +// Added here to stop the compiler from optimising this function away. +G_MODULE_EXPORT GType fl_texture_registrar_get_type(); + +G_DEFINE_TYPE(FlTextureRegistrar, fl_texture_registrar, G_TYPE_OBJECT) + +static void fl_texture_registrar_dispose(GObject* object) { + FlTextureRegistrar* self = FL_TEXTURE_REGISTRAR(object); + + if (self->textures != nullptr) { + g_hash_table_destroy(self->textures); + self->textures = nullptr; + } + + g_clear_object(&self->engine); + + G_OBJECT_CLASS(fl_texture_registrar_parent_class)->dispose(object); +} + +static void fl_texture_registrar_class_init(FlTextureRegistrarClass* klass) { + G_OBJECT_CLASS(klass)->dispose = fl_texture_registrar_dispose; +} + +static void fl_texture_registrar_init(FlTextureRegistrar* self) { + self->textures = g_hash_table_new(nullptr, nullptr); +} + +G_MODULE_EXPORT int64_t +fl_texture_registrar_register_texture(FlTextureRegistrar* self, + FlTextureCallback texture_callback, + void* user_data) { + FlExternalTextureGl* texture = + fl_external_texture_gl_new(texture_callback, user_data); + int64_t id = fl_external_texture_gl_texture_id(texture); + g_hash_table_insert(self->textures, reinterpret_cast(id), texture); + fl_engine_register_external_texture(self->engine, id); + return id; +} + +G_MODULE_EXPORT void fl_texture_registrar_mark_texture_frame_available( + FlTextureRegistrar* self, + int64_t texture_id) { + fl_engine_mark_texture_frame_available(self->engine, texture_id); +} + +bool fl_texture_registrar_populate_texture( + FlTextureRegistrar* self, + int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + FlExternalTextureGl* texture = FL_EXTERNAL_TEXTURE_GL(g_hash_table_lookup( + self->textures, reinterpret_cast(texture_id))); + if (texture == nullptr) + return false; + return fl_external_texture_gl_populate_texture(texture, width, height, + opengl_texture); +} + +G_MODULE_EXPORT void fl_texture_registrar_unregister_texture( + FlTextureRegistrar* self, + int64_t texture_id) { + g_hash_table_remove(self->textures, reinterpret_cast(texture_id)); + fl_engine_unregister_external_texture(self->engine, texture_id); +} + +FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) { + FlTextureRegistrar* self = FL_TEXTURE_REGISTRAR( + g_object_new(fl_texture_registrar_get_type(), nullptr)); + + self->engine = FL_ENGINE(g_object_ref(engine)); + + return self; +} diff --git a/shell/platform/linux/fl_texture_registrar_private.h b/shell/platform/linux/fl_texture_registrar_private.h new file mode 100644 index 0000000000000..20c6b9f56b9c3 --- /dev/null +++ b/shell/platform/linux/fl_texture_registrar_private.h @@ -0,0 +1,46 @@ +// Copyright 2020 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_TEXTURE_REGISTRAR_PRIVATE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_PRIVATE_H_ + +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h" + +G_BEGIN_DECLS + +/** + * fl_texture_registrar_new: + * @engine: An #FlEngine. + * + * Creates a new #FlTextureRegistrar. + * + * Returns: a new #FlTextureRegistrar. + */ +FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine); + +/** + * fl_texture_registrar_populate_texture: + * @registrar: an #FlTextureRegistrar. + * @texture_id: an int64_t. + * @width: a size_t. + * @height: a size_t. + * @opengl_texture: an FlutterOpenGLTexture*. + * + * Attempts to populate the given |texture| by copying the contents of the + * texture identified by |texture_id|. + * + * Returns true on success. + */ +bool fl_texture_registrar_populate_texture( + FlTextureRegistrar* registrar, + int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_PRIVATE_H_ diff --git a/shell/platform/linux/fl_view.cc b/shell/platform/linux/fl_view.cc index fa9bea13f00a6..923970662ec99 100644 --- a/shell/platform/linux/fl_view.cc +++ b/shell/platform/linux/fl_view.cc @@ -120,7 +120,8 @@ static FlPluginRegistrar* fl_view_get_registrar_for_plugin( FlView* self = FL_VIEW(registry); return fl_plugin_registrar_new(self, - fl_engine_get_binary_messenger(self->engine)); + fl_engine_get_binary_messenger(self->engine), + fl_engine_get_texture_registrar(self->engine)); } static void fl_view_plugin_registry_iface_init( diff --git a/shell/platform/linux/public/flutter_linux/fl_engine.h b/shell/platform/linux/public/flutter_linux/fl_engine.h index 201c38f4a06d2..6740c0bd8cd81 100644 --- a/shell/platform/linux/public/flutter_linux/fl_engine.h +++ b/shell/platform/linux/public/flutter_linux/fl_engine.h @@ -13,6 +13,7 @@ #include "fl_binary_messenger.h" #include "fl_dart_project.h" +#include "fl_texture_registrar.h" G_BEGIN_DECLS @@ -44,6 +45,16 @@ FlEngine* fl_engine_new_headless(FlDartProject* project); */ FlBinaryMessenger* fl_engine_get_binary_messenger(FlEngine* engine); +/** + * fl_engine_get_texture_registrar: + * @engine: an #FlEngine. + * + * Gets the texture registrar for registering textures. + * + * Returns: an #FlTextureRegistrar. + */ +FlTextureRegistrar* fl_engine_get_texture_registrar(FlEngine* engine); + G_END_DECLS #endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_H_ diff --git a/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h b/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h index 1d5dc14db9299..11fa238089337 100644 --- a/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h +++ b/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h @@ -38,6 +38,17 @@ G_DECLARE_FINAL_TYPE(FlPluginRegistrar, FlBinaryMessenger* fl_plugin_registrar_get_messenger( FlPluginRegistrar* registrar); +/** + * fl_plugin_registrar_get_texture_registrar: + * @registrar: an #FlPluginRegistrar. + * + * Gets the texture registrar this plugin can communicate with. + * + * Returns: an #FlTextureRegistrar. + */ +FlTextureRegistrar* fl_plugin_registrar_get_texture_registrar( + FlPluginRegistrar* registrar); + /** * fl_plugin_registrar_get_view: * @registrar: an #FlPluginRegistrar. diff --git a/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h b/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h new file mode 100644 index 0000000000000..15746d32caffe --- /dev/null +++ b/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h @@ -0,0 +1,84 @@ +// Copyright 2020 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_TEXTURE_REGISTRAR_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_H_ + +#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/** + * An image buffer object. + */ +typedef struct { + const uint8_t* buffer; + size_t width; + size_t height; +} FlPixelBuffer; + +/** + * The pixel buffer copy callback provided to the Flutter engine to copy the + * texture. + */ +typedef const FlPixelBuffer* (*FlTextureCallback)(size_t width, + size_t height, + void* user_data); + +G_DECLARE_FINAL_TYPE(FlTextureRegistrar, + fl_texture_registrar, + FL, + TEXTURE_REGISTRAR, + GObject) + +/** + * FlTextureRegistrar: + * + * #FlTextureRegistrar is used when registering textures. + */ + +/** + * fl_texture_registrar_register_texture: + * @registrar: an #FlTextureRegistrar. + * @texture: an #FlTexture. + * + * Registers a texture callback and returns the ID for that texture. + * + * Returns: an int64_t. + */ +int64_t fl_texture_registrar_register_texture( + FlTextureRegistrar* registrar, + FlTextureCallback texture_callback, + void* user_data); + +/** + * fl_texture_registrar_mark_texture_frame_available: + * @registrar: an #FlTextureRegistrar. + * @texture_id: an int64_t. + * + * Notifies the flutter engine that the texture object corresponding + * to texture_id needs to render a new texture. + */ +void fl_texture_registrar_mark_texture_frame_available( + FlTextureRegistrar* registrar, + int64_t texture_id); + +/** + * fl_texture_registrar_unregister_texture: + * @registrar: an #FlTextureRegistrar. + * @texture_id: an int64_t. + * + * Unregisters an existing texture object. + */ +void fl_texture_registrar_unregister_texture(FlTextureRegistrar* registrar, + int64_t texture_id); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_H_ diff --git a/shell/platform/linux/public/flutter_linux/flutter_linux.h b/shell/platform/linux/public/flutter_linux/flutter_linux.h index aeaef59aead42..9479c83a2f19f 100644 --- a/shell/platform/linux/public/flutter_linux/flutter_linux.h +++ b/shell/platform/linux/public/flutter_linux/flutter_linux.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/shell/platform/linux/testing/mock_engine.cc b/shell/platform/linux/testing/mock_engine.cc index f82394bdd4ca3..31a46ee2b6e32 100644 --- a/shell/platform/linux/testing/mock_engine.cc +++ b/shell/platform/linux/testing/mock_engine.cc @@ -389,3 +389,21 @@ FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine) size_t locales_count) { return kSuccess; } + +FlutterEngineResult FlutterEngineRegisterExternalTexture( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier) { + return kSuccess; +} + +FlutterEngineResult FlutterEngineUnregisterExternalTexture( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t texture_identifier) { + return kSuccess; +}