Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Linux texture support #24916

Merged
merged 27 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
669e0b4
Linux texture support
huanghongxun Mar 11, 2021
d305ceb
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Mar 12, 2021
2774475
fix reference loop
huanghongxun Mar 12, 2021
7e5599d
Use g_clear_pointer
robert-ancell May 6, 2021
e603f73
Take a reference to the texture
robert-ancell May 6, 2021
2b88a31
Split FlPixelBufferTexture into its own module
robert-ancell May 6, 2021
eb9e75b
Add missing comment
robert-ancell May 6, 2021
e137a94
Add missing param check
robert-ancell May 6, 2021
c62c6f1
Fix memory management with texture registrar tests
robert-ancell May 6, 2021
6adb093
Remove callback and make FlPixelBufferTexture derivable
robert-ancell May 6, 2021
c4c7822
Add some comments
huanghongxun May 7, 2021
d545cc3
fix: format
huanghongxun May 7, 2021
13c8f2f
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun May 10, 2021
50fd4ef
Add new file to licenses
robert-ancell May 12, 2021
150f012
Return correct texture ID
robert-ancell May 12, 2021
e31dfdd
Consistent boolean values
robert-ancell May 12, 2021
ef82943
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Jul 7, 2021
02e56b6
Make FlTexture more general
huanghongxun Jul 7, 2021
3fbd0c3
Fix: It should be assumed that the format of pixel buffer is RGBA.
huanghongxun Aug 20, 2021
034d281
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Aug 20, 2021
d0923e7
Include fl_texture_gl.h
huanghongxun Aug 23, 2021
bdff886
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Aug 23, 2021
877c9ad
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Sep 6, 2021
9ed4178
Add more detailed documentation
huanghongxun Sep 6, 2021
e801652
Remove concept of texture ID in the API.
huanghongxun Sep 13, 2021
84184ae
FlTexture should an interface
huanghongxun Sep 13, 2021
2f596ee
Merge branch 'master' of https://github.com/flutter/engine into dev/t…
huanghongxun Sep 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,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 @@ -1595,6 +1598,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 @@ -1616,11 +1627,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