Skip to content

Commit

Permalink
Linux texture support (flutter#24916)
Browse files Browse the repository at this point in the history
  • Loading branch information
huanghongxun authored Sep 23, 2021
1 parent 7d023e8 commit 6179c81
Show file tree
Hide file tree
Showing 27 changed files with 1,304 additions and 7 deletions.
15 changes: 15 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,9 @@ FILE: ../../../flutter/shell/platform/linux/fl_method_response.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_response_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_pixel_buffer_texture.cc
FILE: ../../../flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h
FILE: ../../../flutter/shell/platform/linux/fl_pixel_buffer_texture_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registrar.cc
Expand All @@ -1603,6 +1606,14 @@ FILE: ../../../flutter/shell/platform/linux/fl_task_runner.cc
FILE: ../../../flutter/shell/platform/linux/fl_task_runner.h
FILE: ../../../flutter/shell/platform/linux/fl_text_input_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_text_input_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_texture.cc
FILE: ../../../flutter/shell/platform/linux/fl_texture_gl.cc
FILE: ../../../flutter/shell/platform/linux/fl_texture_gl_private.h
FILE: ../../../flutter/shell/platform/linux/fl_texture_gl_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_texture_private.h
FILE: ../../../flutter/shell/platform/linux/fl_texture_registrar.cc
FILE: ../../../flutter/shell/platform/linux/fl_texture_registrar_private.h
FILE: ../../../flutter/shell/platform/linux/fl_texture_registrar_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
Expand All @@ -1624,11 +1635,15 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_call.
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_response.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_pixel_buffer_texture.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registrar.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_texture.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_texture_gl.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,15 @@ _public_headers = [
"public/flutter_linux/fl_method_channel.h",
"public/flutter_linux/fl_method_codec.h",
"public/flutter_linux/fl_method_response.h",
"public/flutter_linux/fl_pixel_buffer_texture.h",
"public/flutter_linux/fl_plugin_registrar.h",
"public/flutter_linux/fl_plugin_registry.h",
"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.h",
"public/flutter_linux/fl_texture_gl.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",
Expand Down Expand Up @@ -114,6 +118,7 @@ source_set("flutter_linux_sources") {
"fl_method_codec.cc",
"fl_method_response.cc",
"fl_mouse_cursor_plugin.cc",
"fl_pixel_buffer_texture.cc",
"fl_platform_plugin.cc",
"fl_plugin_registrar.cc",
"fl_plugin_registry.cc",
Expand All @@ -127,6 +132,9 @@ source_set("flutter_linux_sources") {
"fl_task_runner.cc",
"fl_task_runner.h",
"fl_text_input_plugin.cc",
"fl_texture.cc",
"fl_texture_gl.cc",
"fl_texture_registrar.cc",
"fl_value.cc",
"fl_view.cc",
"fl_view_accessible.cc",
Expand Down Expand Up @@ -184,9 +192,12 @@ executable("flutter_linux_unittests") {
"fl_method_channel_test.cc",
"fl_method_codec_test.cc",
"fl_method_response_test.cc",
"fl_pixel_buffer_texture_test.cc",
"fl_standard_message_codec_test.cc",
"fl_standard_method_codec_test.cc",
"fl_string_codec_test.cc",
"fl_texture_gl_test.cc",
"fl_texture_registrar_test.cc",
"fl_value_test.cc",
"testing/fl_test.cc",
"testing/mock_engine.cc",
Expand Down
57 changes: 56 additions & 1 deletion shell/platform/linux/fl_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

#include <cstring>

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
#include "flutter/shell/platform/linux/fl_engine_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_settings_plugin.h"
#include "flutter/shell/platform/linux/fl_texture_registrar_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"

// Unique number associated with platform tasks.
Expand All @@ -30,6 +32,7 @@ struct _FlEngine {
FlRenderer* renderer;
FlBinaryMessenger* binary_messenger;
FlSettingsPlugin* settings_plugin;
FlTextureRegistrar* texture_registrar;
FlTaskRunner* task_runner;
FlutterEngineAOTData aot_data;
FLUTTER_API_SYMBOL(FlutterEngine) engine;
Expand Down Expand Up @@ -214,6 +217,26 @@ static bool fl_engine_gl_make_resource_current(void* user_data) {
return result;
}

// Called by the engine to retrieve an external texture.
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<FlEngine*>(user_data);
if (!self->texture_registrar) {
return false;
}
g_autoptr(GError) error = nullptr;
gboolean result = fl_texture_registrar_populate_gl_external_texture(
self->texture_registrar, texture_id, width, height, texture, &error);
if (!result) {
g_warning("%s", error->message);
}
return result;
}

// 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<FlEngine*>(user_data);
Expand Down Expand Up @@ -276,7 +299,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(
Expand All @@ -299,6 +323,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);
g_clear_object(&self->settings_plugin);
g_clear_object(&self->task_runner);
Expand Down Expand Up @@ -330,6 +355,7 @@ static void fl_engine_init(FlEngine* self) {
self->embedder_api.struct_size = sizeof(FlutterEngineProcTable);
FlutterEngineGetProcAddresses(&self->embedder_api);

self->texture_registrar = fl_texture_registrar_new(self);
self->binary_messenger = fl_binary_messenger_new(self);
}

Expand Down Expand Up @@ -362,6 +388,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);
Expand Down Expand Up @@ -673,6 +701,27 @@ void fl_engine_dispatch_semantics_action(FlEngine* self,
action_data, action_data_length);
}

gboolean fl_engine_mark_texture_frame_available(FlEngine* self,
int64_t texture_id) {
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
return self->embedder_api.MarkExternalTextureFrameAvailable(
self->engine, texture_id) == kSuccess;
}

gboolean fl_engine_register_external_texture(FlEngine* self,
int64_t texture_id) {
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
return self->embedder_api.RegisterExternalTexture(self->engine, texture_id) ==
kSuccess;
}

gboolean fl_engine_unregister_external_texture(FlEngine* self,
int64_t texture_id) {
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
return self->embedder_api.UnregisterExternalTexture(self->engine,
texture_id) == kSuccess;
}

G_MODULE_EXPORT FlBinaryMessenger* fl_engine_get_binary_messenger(
FlEngine* self) {
g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
Expand All @@ -688,3 +737,9 @@ void fl_engine_execute_task(FlEngine* self, FlutterTask* task) {
g_return_if_fail(FL_IS_ENGINE(self));
self->embedder_api.RunTask(self->engine, task);
}

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;
}
38 changes: 38 additions & 0 deletions shell/platform/linux/fl_engine_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,44 @@ FlTaskRunner* fl_engine_get_task_runner(FlEngine* engine);
*/
void fl_engine_execute_task(FlEngine* engine, FlutterTask* task);

/**
* fl_engine_mark_texture_frame_available:
* @engine: an #FlEngine.
* @texture_id: the identifier of the texture whose frame has been updated.
*
* Tells the Flutter engine that a new texture frame is available for the given
* texture.
*
* Returns: %TRUE on success.
*/
gboolean fl_engine_mark_texture_frame_available(FlEngine* engine,
int64_t texture_id);

/**
* fl_engine_register_external_texture:
* @engine: an #FlEngine.
* @texture_id: the identifier of the texture that is available.
*
* Tells the Flutter engine that a new external texture is available.
*
* Returns: %TRUE on success.
*/
gboolean fl_engine_register_external_texture(FlEngine* engine,
int64_t texture_id);

/**
* fl_engine_unregister_external_texture:
* @engine: an #FlEngine.
* @texture_id: the identifier of the texture that is not available anymore.
*
* Tells the Flutter engine that an existing external texture is not available
* anymore.
*
* Returns: %TRUE on success.
*/
gboolean fl_engine_unregister_external_texture(FlEngine* engine,
int64_t texture_id);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_
103 changes: 103 additions & 0 deletions shell/platform/linux/fl_pixel_buffer_texture.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// 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 "flutter/shell/platform/linux/public/flutter_linux/fl_pixel_buffer_texture.h"

#include <epoxy/gl.h>
#include <gmodule.h>

#include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h"

typedef struct {
GLuint texture_id;
} FlPixelBufferTexturePrivate;

// Added here to stop the compiler from optimising this function away.
G_MODULE_EXPORT GType fl_pixel_buffer_texture_get_type();

static void fl_pixel_buffer_texture_iface_init(FlTextureInterface* iface) {}

G_DEFINE_TYPE_WITH_CODE(
FlPixelBufferTexture,
fl_pixel_buffer_texture,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(fl_texture_get_type(),
fl_pixel_buffer_texture_iface_init);
G_ADD_PRIVATE(FlPixelBufferTexture))

static void fl_pixel_buffer_texture_dispose(GObject* object) {
FlPixelBufferTexture* self = FL_PIXEL_BUFFER_TEXTURE(object);
FlPixelBufferTexturePrivate* priv =
reinterpret_cast<FlPixelBufferTexturePrivate*>(
fl_pixel_buffer_texture_get_instance_private(self));

if (priv->texture_id) {
glDeleteTextures(1, &priv->texture_id);
priv->texture_id = 0;
}

G_OBJECT_CLASS(fl_pixel_buffer_texture_parent_class)->dispose(object);
}

static void check_gl_error(int line) {
GLenum err = glGetError();
if (err) {
g_warning("glGetError %x (%s:%d)\n", err, __FILE__, line);
}
}

gboolean fl_pixel_buffer_texture_populate(FlPixelBufferTexture* texture,
uint32_t width,
uint32_t height,
FlutterOpenGLTexture* opengl_texture,
GError** error) {
FlPixelBufferTexture* self = FL_PIXEL_BUFFER_TEXTURE(texture);
FlPixelBufferTexturePrivate* priv =
reinterpret_cast<FlPixelBufferTexturePrivate*>(
fl_pixel_buffer_texture_get_instance_private(self));

const uint8_t* buffer = nullptr;
if (!FL_PIXEL_BUFFER_TEXTURE_GET_CLASS(self)->copy_pixels(
self, &buffer, &width, &height, error)) {
return FALSE;
}

if (priv->texture_id == 0) {
glGenTextures(1, &priv->texture_id);
check_gl_error(__LINE__);
glBindTexture(GL_TEXTURE_2D, priv->texture_id);
check_gl_error(__LINE__);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
check_gl_error(__LINE__);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
check_gl_error(__LINE__);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
check_gl_error(__LINE__);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
check_gl_error(__LINE__);
} else {
glBindTexture(GL_TEXTURE_2D, priv->texture_id);
check_gl_error(__LINE__);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, buffer);
check_gl_error(__LINE__);

opengl_texture->target = GL_TEXTURE_2D;
opengl_texture->name = priv->texture_id;
opengl_texture->format = GL_RGBA8;
opengl_texture->destruction_callback = nullptr;
opengl_texture->user_data = nullptr;
opengl_texture->width = width;
opengl_texture->height = height;

return TRUE;
}

static void fl_pixel_buffer_texture_class_init(
FlPixelBufferTextureClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_pixel_buffer_texture_dispose;
}

static void fl_pixel_buffer_texture_init(FlPixelBufferTexture* self) {}
36 changes: 36 additions & 0 deletions shell/platform/linux/fl_pixel_buffer_texture_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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_PIXEL_BUFFER_TEXTURE_PRIVATE_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_PIXEL_BUFFER_TEXTURE_PRIVATE_H_

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_pixel_buffer_texture.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h"

G_BEGIN_DECLS

/**
* fl_pixel_buffer_texture_populate:
* @texture: an #FlPixelBufferTexture.
* @width: width of the texture.
* @height: height of the texture.
* @opengl_texture: (out): return an #FlutterOpenGLTexture.
* @error: (allow-none): #GError location to store the error occurring, or
* %NULL to ignore.
*
* Attempts to populate the specified @opengl_texture with texture details
* such as the name, width, height and the pixel format.
*
* Returns: %TRUE on success.
*/
gboolean fl_pixel_buffer_texture_populate(FlPixelBufferTexture* texture,
uint32_t width,
uint32_t height,
FlutterOpenGLTexture* opengl_texture,
GError** error);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_PIXEL_BUFFER_TEXTURE_PRIVATE_H_
Loading

0 comments on commit 6179c81

Please sign in to comment.