diff --git a/shell/platform/common/client_wrapper/core_implementations.cc b/shell/platform/common/client_wrapper/core_implementations.cc index 1412db7c939f2..78efc6b3ad92b 100644 --- a/shell/platform/common/client_wrapper/core_implementations.cc +++ b/shell/platform/common/client_wrapper/core_implementations.cc @@ -169,6 +169,26 @@ int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) { return buffer; }; + int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture( + texture_registrar_ref_, &info); + return texture_id; + } else if (auto gpu_buffer_texture = std::get_if(texture)) { + FlutterDesktopTextureInfo info = {}; + info.type = kFlutterDesktopGpuBufferTexture; + info.gpu_buffer_config.user_data = gpu_buffer_texture; + info.gpu_buffer_config.callback = + [](size_t width, size_t height, + void* user_data) -> const FlutterDesktopGpuBuffer* { + auto texture = static_cast(user_data); + auto buffer = texture->ObtainGpuBuffer(width, height); + return buffer; + }; + + info.gpu_buffer_config.destruction_callback = [](void* user_data) -> void { + auto texture = static_cast(user_data); + texture->Destruct(); + }; + int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture( texture_registrar_ref_, &info); return texture_id; diff --git a/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 5b59829f24283..c187ace4ab1c4 100644 --- a/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -42,10 +42,50 @@ class PixelBufferTexture { const CopyBufferCallback copy_buffer_callback_; }; +// A gpu buffer texture. +class GpuBufferTexture { + public: + // A callback used for retrieving gpu buffers. + typedef std::function + ObtainGpuBufferCallback; + + typedef std::function DestructGpuBufferCallback; + + // Creates a gpu buffer texture that uses the provided |obtain_buffer_cb| to + // retrieve the buffer. + // As the callback is usually invoked from the render thread, the callee must + // take care of proper synchronization. It also needs to be ensured that the + // returned buffer isn't released prior to unregistering this texture. + GpuBufferTexture(ObtainGpuBufferCallback obtain_buffer_callback, + DestructGpuBufferCallback destruction_callback) + : obtain_gpu_buffer_callback_(obtain_buffer_callback), + destruct_gpu_buffer_callback_(destruction_callback), + buffer_(nullptr) {} + + // Returns the callback-provided FlutterDesktopGpuBuffer that contains the + // actual gpu buffer pointer. The intended surface size is specified by + // |width| and |height|. + const FlutterDesktopGpuBuffer* ObtainGpuBuffer(size_t width, size_t height) { + const FlutterDesktopGpuBuffer* flutter_buffer = + obtain_gpu_buffer_callback_(width, height); + if (flutter_buffer) { + buffer_ = const_cast(flutter_buffer->buffer); + } + return flutter_buffer; + } + + void Destruct() { destruct_gpu_buffer_callback_(buffer_); } + + private: + const ObtainGpuBufferCallback obtain_gpu_buffer_callback_; + const DestructGpuBufferCallback destruct_gpu_buffer_callback_; + void* buffer_; +}; + // The available texture variants. -// Only PixelBufferTexture is currently implemented. -// Other variants are expected to be added in the future. -typedef std::variant TextureVariant; +// Only PixelBufferTexture and GpuBufferTexture are currently implemented. +typedef std::variant TextureVariant; // An object keeping track of external textures. // diff --git a/shell/platform/common/public/flutter_texture_registrar.h b/shell/platform/common/public/flutter_texture_registrar.h index b115234e273de..e2bfcfb6bfdf8 100644 --- a/shell/platform/common/public/flutter_texture_registrar.h +++ b/shell/platform/common/public/flutter_texture_registrar.h @@ -23,7 +23,9 @@ typedef struct FlutterDesktopTextureRegistrar* // Additional types may be added in the future. typedef enum { // A Pixel buffer-based texture. - kFlutterDesktopPixelBufferTexture + kFlutterDesktopPixelBufferTexture, + // A Gpu buffer-based texture. + kFlutterDesktopGpuBufferTexture } FlutterDesktopTextureType; // An image buffer object. @@ -36,6 +38,16 @@ typedef struct { size_t height; } FlutterDesktopPixelBuffer; +// An image buffer object. +typedef struct { + // The gpu data buffer. + const void* buffer; + // Width of the gpu buffer. + size_t width; + // Height of the gpu buffer. + size_t height; +} FlutterDesktopGpuBuffer; + // The pixel buffer copy callback definition provided to // the Flutter engine to copy the texture. // It is invoked with the intended surface size specified by |width| and @@ -50,6 +62,13 @@ typedef const FlutterDesktopPixelBuffer* ( size_t height, void* user_data); +typedef const FlutterDesktopGpuBuffer* ( + *FlutterDesktopGpuBufferTextureCallback)(size_t width, + size_t height, + void* user_data); + +typedef void (*FlutterDesktopGpuBufferDestructionCallback)(void* user_data); + // An object used to configure pixel buffer textures. typedef struct { // The callback used by the engine to copy the pixel buffer object. @@ -58,10 +77,21 @@ typedef struct { void* user_data; } FlutterDesktopPixelBufferTextureConfig; +// An object used to configure GPU buffer textures. +typedef struct { + // The callback used by the engine to obtain the GPU buffer object. + FlutterDesktopGpuBufferTextureCallback callback; + // The callback used by the engine to destruct the GPU buffer object. + FlutterDesktopGpuBufferDestructionCallback destruction_callback; + // Opaque data that will get passed to the provided |callback|. + void* user_data; +} FlutterDesktopGPUBufferTextureConfig; + typedef struct { FlutterDesktopTextureType type; union { FlutterDesktopPixelBufferTextureConfig pixel_buffer_config; + FlutterDesktopGPUBufferTextureConfig gpu_buffer_config; }; } FlutterDesktopTextureInfo; diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 9bf20bc81c2b0..8094743719a05 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -26,7 +26,6 @@ source_set("flutter_engine") { _public_headers = [ "public/flutter_platform_view.h", - "public/flutter_tizen_texture_registrar.h", "public/flutter_tizen.h", ] @@ -95,9 +94,11 @@ template("embedder_for_profile") { "channels/platform_view_channel.cc", "channels/settings_channel.cc", "channels/text_input_channel.cc", - "external_texture_gl.cc", + "external_texture_pixel_gl.cc", + "external_texture_surface_gl.cc", "flutter_tizen.cc", "flutter_tizen_engine.cc", + "flutter_tizen_texture_registrar.cc", "key_event_handler.cc", "tizen_event_loop.cc", "tizen_log.cc", diff --git a/shell/platform/tizen/external_texture.h b/shell/platform/tizen/external_texture.h new file mode 100644 index 0000000000000..ba01cc7ff0e4e --- /dev/null +++ b/shell/platform/tizen/external_texture.h @@ -0,0 +1,49 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EMBEDDER_EXTERNAL_TEXTURE_H_ +#define EMBEDDER_EXTERNAL_TEXTURE_H_ + +#include +#include +#include "flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" + +#ifdef TIZEN_RENDERER_EVAS_GL +#undef EFL_BETA_API_SUPPORT +#include +#else +#include +#endif + +struct ExternalTextureGLState { + GLuint gl_texture; +}; + +static std::atomic_long next_texture_id = {1}; + +// An adaptation class of flutter engine and external texture interface. +class ExternalTexture : public std::enable_shared_from_this { + public: + ExternalTexture() + : state_(std::make_unique()), + texture_id_(next_texture_id++) {} + virtual ~ExternalTexture() = default; + + /** + * Returns the unique id for the ExternalTextureGL instance. + */ + int64_t TextureId() { return (int64_t)texture_id_; } + + virtual bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) = 0; + virtual void OnDestruction(){}; + + protected: + std::unique_ptr state_; + const long texture_id_{0}; +}; + +#endif // EMBEDDER_EXTERNAL_TEXTURE_H_ diff --git a/shell/platform/tizen/external_texture_gl.h b/shell/platform/tizen/external_texture_gl.h deleted file mode 100644 index 0f52da1ebea9d..0000000000000 --- a/shell/platform/tizen/external_texture_gl.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2020 Samsung Electronics Co., Ltd. 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_TIZEN_EXTERNAL_TEXTURE_GL_H_ -#define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_ - -#include -#include -#include -#include -#include - -#include -#include - -#include "flutter/shell/platform/embedder/embedder.h" - -typedef struct ExternalTextureGLState ExternalTextureGLState; - -// An adaptation class of flutter engine and external texture interface. -class ExternalTextureGL { - public: - ExternalTextureGL(); - - virtual ~ExternalTextureGL(); - - /** - * Returns the unique id for the ExternalTextureGL instance. - */ - int64_t TextureId() { return (int64_t)texture_id_; } - - /** - * Accepts texture buffer copy request from the Flutter engine. - * When the user side marks the texture_id as available, the Flutter engine - * will callback to this method and ask for populate the |opengl_texture| - * object, such as the texture type and the format of the pixel buffer and the - * texture object. - * Returns true on success, false on failure. - */ - bool PopulateTextureWithIdentifier(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture); - bool OnFrameAvailable(tbm_surface_h tbm_surface); - - private: - std::unique_ptr state_; - std::mutex mutex_; - tbm_surface_h available_tbm_surface_{nullptr}; - const long texture_id_{0}; -}; - -#endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_ diff --git a/shell/platform/tizen/external_texture_pixel_gl.cc b/shell/platform/tizen/external_texture_pixel_gl.cc new file mode 100644 index 0000000000000..3ec90031d966d --- /dev/null +++ b/shell/platform/tizen/external_texture_pixel_gl.cc @@ -0,0 +1,70 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. 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/tizen/external_texture_pixel_gl.h" + +#ifdef TIZEN_RENDERER_EVAS_GL +#undef EFL_BETA_API_SUPPORT +#include +extern Evas_GL* g_evas_gl; +EVAS_GL_GLOBAL_GLES3_DECLARE(); +#else +#include +#include +#include +#include +#endif + +bool ExternalTexturePixelGL::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + if (!CopyPixelBuffer(width, height)) { + return false; + } + + // Populate the texture object used by the engine. + opengl_texture->target = GL_TEXTURE_2D; + opengl_texture->name = state_->gl_texture; + 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; +} + +ExternalTexturePixelGL::ExternalTexturePixelGL( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data) + : ExternalTexture(), + texture_callback_(texture_callback), + user_data_(user_data) {} + +bool ExternalTexturePixelGL::CopyPixelBuffer(size_t& width, size_t& height) { + const FlutterDesktopPixelBuffer* pixel_buffer = + texture_callback_(width, height, user_data_); + + if (!pixel_buffer || !pixel_buffer->buffer) { + return false; + } + + width = pixel_buffer->width; + height = pixel_buffer->height; + + if (state_->gl_texture == 0) { + glGenTextures(1, &state_->gl_texture); + glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, + pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixel_buffer->buffer); + return true; +} diff --git a/shell/platform/tizen/external_texture_pixel_gl.h b/shell/platform/tizen/external_texture_pixel_gl.h new file mode 100644 index 0000000000000..39c156c363687 --- /dev/null +++ b/shell/platform/tizen/external_texture_pixel_gl.h @@ -0,0 +1,34 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EMBEDDER_EXTERNAL_TEXTURE_PIXEL_GL_H +#define EMBEDDER_EXTERNAL_TEXTURE_PIXEL_GL_H + +#include + +#include "flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/external_texture.h" + +// An adaptation class of flutter engine and external texture interface. +class ExternalTexturePixelGL : public ExternalTexture { + public: + ExternalTexturePixelGL( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data); + + ~ExternalTexturePixelGL() = default; + + bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; + + bool CopyPixelBuffer(size_t& width, size_t& height); + + private: + FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; + void* user_data_ = nullptr; +}; + +#endif // EMBEDDER_EXTERNAL_TEXTURE_PIXEL_GL_H diff --git a/shell/platform/tizen/external_texture_gl.cc b/shell/platform/tizen/external_texture_surface_gl.cc similarity index 62% rename from shell/platform/tizen/external_texture_gl.cc rename to shell/platform/tizen/external_texture_surface_gl.cc index f8f5d6d05b4f7..680a1ec102918 100644 --- a/shell/platform/tizen/external_texture_gl.cc +++ b/shell/platform/tizen/external_texture_surface_gl.cc @@ -2,110 +2,73 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "external_texture_gl.h" +#include "external_texture_surface_gl.h" + +#include "flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h" #ifdef TIZEN_RENDERER_EVAS_GL #undef EFL_BETA_API_SUPPORT -#include -#include #include extern Evas_GL* g_evas_gl; EVAS_GL_GLOBAL_GLES3_DECLARE(); #else #include #include -#include #include #include #endif -#include -#include +#include #include "flutter/shell/platform/tizen/tizen_log.h" -struct ExternalTextureGLState { - GLuint gl_texture; -}; - -static std::atomic_long nextTextureId = {1}; - -static void MarkTbmSurfaceToUse(void* surface) { -#ifndef WEARABLE_PROFILE - FT_ASSERT(surface); - tbm_surface_h tbm_surface = (tbm_surface_h)surface; - tbm_surface_internal_ref(tbm_surface); -#endif -} - -static void UnmarkTbmSurfaceToUse(void* surface) { - FT_ASSERT(surface); - tbm_surface_h tbm_surface = (tbm_surface_h)surface; -#ifndef WEARABLE_PROFILE - tbm_surface_internal_unref(tbm_surface); -#else - tbm_surface_destroy(tbm_surface); -#endif +static void OnCollectTexture(void* textureGL) { + auto* weak_texture = + reinterpret_cast*>(textureGL); + auto strong_texture = weak_texture->lock(); + delete weak_texture; + if (strong_texture) { + strong_texture->OnDestruction(); + } } -ExternalTextureGL::ExternalTextureGL() - : state_(std::make_unique()), - available_tbm_surface_(nullptr), - texture_id_(nextTextureId++) {} +ExternalTextureSurfaceGL::ExternalTextureSurfaceGL( + FlutterDesktopGpuBufferTextureCallback texture_callback, + FlutterDesktopGpuBufferDestructionCallback destruction_callback, + void* user_data) + : ExternalTexture(), + texture_callback_(texture_callback), + destruction_callback_(destruction_callback), + user_data_(user_data) {} -ExternalTextureGL::~ExternalTextureGL() { +ExternalTextureSurfaceGL::~ExternalTextureSurfaceGL() { if (state_->gl_texture != 0) { glDeleteTextures(1, &state_->gl_texture); } - - // If there is a available_tbm_surface_ that is not populated, remove it - if (available_tbm_surface_) { - UnmarkTbmSurfaceToUse(available_tbm_surface_); - } - state_.release(); } -bool ExternalTextureGL::OnFrameAvailable(tbm_surface_h tbm_surface) { - if (!tbm_surface) { - FT_LOGE("[texture id:%ld] tbm_surface is null", texture_id_); +bool ExternalTextureSurfaceGL::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + const FlutterDesktopGpuBuffer* gpu_buffer = + texture_callback_(width, height, user_data_); + if (!gpu_buffer) { + FT_LOGD("[texture id:%ld] gpu_buffer is null", texture_id_); return false; } - if (available_tbm_surface_) { - FT_LOGD( - "[texture id:%ld] Discard! an available tbm surface that has not yet " - "been used exists", - texture_id_); + if (!gpu_buffer->buffer) { + FT_LOGD("[texture id:%ld] tbm_surface_ is null", texture_id_); return false; } + const tbm_surface_h tbm_surface = + reinterpret_cast(const_cast(gpu_buffer->buffer)); tbm_surface_info_s info; if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) { - FT_LOGD("[texture id:%ld] tbm_surface not valid, pass", texture_id_); - return false; - } - - available_tbm_surface_ = tbm_surface; - MarkTbmSurfaceToUse(available_tbm_surface_); - - return true; -} - -bool ExternalTextureGL::PopulateTextureWithIdentifier( - size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) { - if (!available_tbm_surface_) { - FT_LOGD("[texture id:%ld] available_tbm_surface_ is null", texture_id_); - return false; - } - tbm_surface_info_s info; - if (tbm_surface_get_info(available_tbm_surface_, &info) != - TBM_SURFACE_ERROR_NONE) { FT_LOGD("[texture id:%ld] tbm_surface is invalid", texture_id_); - UnmarkTbmSurfaceToUse(available_tbm_surface_); - available_tbm_surface_ = nullptr; return false; } @@ -113,8 +76,7 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier( int attribs[] = {EVAS_GL_IMAGE_PRESERVED, GL_TRUE, 0}; EvasGLImage egl_src_image = evasglCreateImageForContext( g_evas_gl, evas_gl_current_context_get(g_evas_gl), - EVAS_GL_NATIVE_SURFACE_TIZEN, (void*)(intptr_t)available_tbm_surface_, - attribs); + EVAS_GL_NATIVE_SURFACE_TIZEN, (void*)(intptr_t)tbm_surface, attribs); if (!egl_src_image) { return false; } @@ -143,7 +105,7 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier( EGL_NONE}; EGLImageKHR egl_src_image = n_eglCreateImageKHR( eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_SURFACE_TIZEN, - (EGLClientBuffer)available_tbm_surface_, attribs); + (EGLClientBuffer)tbm_surface, attribs); if (!egl_src_image) { FT_LOGE("[texture id:%ld] egl_src_image create fail!!, errorcode == %d", @@ -178,13 +140,14 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier( opengl_texture->target = GL_TEXTURE_EXTERNAL_OES; opengl_texture->name = state_->gl_texture; opengl_texture->format = GL_RGBA8; - opengl_texture->destruction_callback = (VoidCallback)UnmarkTbmSurfaceToUse; - - // Abandon ownership of tbm_surface - opengl_texture->user_data = available_tbm_surface_; - available_tbm_surface_ = nullptr; - + opengl_texture->destruction_callback = (VoidCallback)OnCollectTexture; + auto* weak_texture = new std::weak_ptr(shared_from_this()); + opengl_texture->user_data = weak_texture; opengl_texture->width = width; opengl_texture->height = height; return true; } + +void ExternalTextureSurfaceGL::OnDestruction() { + destruction_callback_(user_data_); +} diff --git a/shell/platform/tizen/external_texture_surface_gl.h b/shell/platform/tizen/external_texture_surface_gl.h new file mode 100644 index 0000000000000..b7f5e56d10b33 --- /dev/null +++ b/shell/platform/tizen/external_texture_surface_gl.h @@ -0,0 +1,41 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EMBEDDER_EXTERNAL_TEXTURE_SURFACE_GL_H_ +#define EMBEDDER_EXTERNAL_TEXTURE_SURFACE_GL_H_ + +#include "flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/external_texture.h" + +// An adaptation class of flutter engine and external texture interface. +class ExternalTextureSurfaceGL : public ExternalTexture { + public: + ExternalTextureSurfaceGL( + FlutterDesktopGpuBufferTextureCallback texture_callback, + FlutterDesktopGpuBufferDestructionCallback destruction_callback, + void* user_data); + + virtual ~ExternalTextureSurfaceGL(); + + /** + * Accepts texture buffer copy request from the Flutter engine. + * When the user side marks the texture_id as available, the Flutter engine + * will callback to this method and ask for populate the |opengl_texture| + * object, such as the texture type and the format of the pixel buffer and the + * texture object. + * Returns true on success, false on failure. + */ + bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; + void OnDestruction() override; + + private: + FlutterDesktopGpuBufferTextureCallback texture_callback_ = nullptr; + FlutterDesktopGpuBufferDestructionCallback destruction_callback_ = nullptr; + void* user_data_ = nullptr; +}; + +#endif // EMBEDDER_EXTERNAL_TEXTURE_SURFACE_GL_H_ diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index f7bf08884fa07..76e0241722f29 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -12,7 +12,6 @@ #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" #include "flutter/shell/platform/tizen/flutter_tizen_engine.h" #include "flutter/shell/platform/tizen/public/flutter_platform_view.h" -#include "flutter/shell/platform/tizen/public/flutter_tizen_texture_registrar.h" #include "flutter/shell/platform/tizen/tizen_log.h" // Returns the engine corresponding to the given opaque API handle. @@ -75,11 +74,6 @@ void FlutterDesktopPluginRegistrarSetDestructionHandler( registrar->engine->SetPluginRegistrarDestructionCallback(callback); } -FlutterTextureRegistrarRef FlutterPluginRegistrarGetTexture( - FlutterDesktopPluginRegistrarRef registrar) { - return registrar->texture_registrar.get(); -} - bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, @@ -161,52 +155,6 @@ void FlutterDesktopNotifyLowMemoryWarning(FlutterDesktopEngineRef engine) { FlutterEngineNotifyLowMemoryWarning(flutter_engine); } -int64_t FlutterRegisterExternalTexture( - FlutterTextureRegistrarRef texture_registrar) { - FT_LOGD("FlutterDesktopRegisterExternalTexture"); - std::lock_guard lock(texture_registrar->mutex); - auto texture_gl = std::make_unique(); - int64_t texture_id = texture_gl->TextureId(); - texture_registrar->textures[texture_id] = std::move(texture_gl); - if (FlutterEngineRegisterExternalTexture(texture_registrar->flutter_engine, - texture_id) == kSuccess) { - return texture_id; - } - return -1; -} - -bool FlutterUnregisterExternalTexture( - FlutterTextureRegistrarRef texture_registrar, - int64_t texture_id) { - std::lock_guard lock(texture_registrar->mutex); - auto it = texture_registrar->textures.find(texture_id); - if (it != texture_registrar->textures.end()) - texture_registrar->textures.erase(it); - bool ret = FlutterEngineUnregisterExternalTexture( - texture_registrar->flutter_engine, texture_id) == kSuccess; - return ret; -} - -bool FlutterMarkExternalTextureFrameAvailable( - FlutterTextureRegistrarRef texture_registrar, - int64_t texture_id, - void* tbm_surface) { - std::lock_guard lock(texture_registrar->mutex); - auto it = texture_registrar->textures.find(texture_id); - if (it == texture_registrar->textures.end()) { - FT_LOGE("can't find texture texture_id = %" PRId64, texture_id); - return false; - } - if (!texture_registrar->textures[texture_id]->OnFrameAvailable( - (tbm_surface_h)tbm_surface)) { - // If a texture that has not been used already exists, it can fail - return false; - } - bool ret = FlutterEngineMarkExternalTextureFrameAvailable( - texture_registrar->flutter_engine, texture_id) == kSuccess; - return ret; -} - void FlutterRegisterViewFactory( FlutterDesktopPluginRegistrarRef registrar, const char* view_type, @@ -216,29 +164,40 @@ void FlutterRegisterViewFactory( view_type, std::move(view_factory))); } +// Returns the texture registrar corresponding to the given opaque API handle. +static FlutterTizenTextureRegistrar* TextureRegistrarFromHandle( + FlutterDesktopTextureRegistrarRef ref) { + return reinterpret_cast(ref); +} + +// Returns the opaque API handle for the given texture registrar instance. +static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar( + FlutterTizenTextureRegistrar* registrar) { + return reinterpret_cast(registrar); +} + FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar( FlutterDesktopPluginRegistrarRef registrar) { - FT_UNIMPLEMENTED(); - return nullptr; + return HandleForTextureRegistrar(registrar->engine->GetTextureRegistrar()); } int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo* texture_info) { - FT_UNIMPLEMENTED(); - return -1; + return TextureRegistrarFromHandle(texture_registrar) + ->RegisterTexture(texture_info); } bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id) { - FT_UNIMPLEMENTED(); - return false; + return TextureRegistrarFromHandle(texture_registrar) + ->UnregisterTexture(texture_id); } bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id) { - FT_UNIMPLEMENTED(); - return false; + return TextureRegistrarFromHandle(texture_registrar) + ->MarkTextureFrameAvailable(texture_id); } diff --git a/shell/platform/tizen/flutter_tizen_engine.cc b/shell/platform/tizen/flutter_tizen_engine.cc index db4ae07be0c4e..c6b9d706ea706 100644 --- a/shell/platform/tizen/flutter_tizen_engine.cc +++ b/shell/platform/tizen/flutter_tizen_engine.cc @@ -210,12 +210,8 @@ bool FlutterTizenEngine::RunEngine( localization_channel = std::make_unique(flutter_engine); localization_channel->SendLocales(); lifecycle_channel = std::make_unique(flutter_engine); - if (IsHeaded()) { - auto texture_registrar = std::make_unique(); - texture_registrar->flutter_engine = flutter_engine; - plugin_registrar_->texture_registrar = std::move(texture_registrar); - + texture_registrar_ = std::make_unique(this); key_event_channel = std::make_unique( internal_plugin_registrar_->messenger()); navigation_channel = std::make_unique( @@ -252,6 +248,10 @@ FlutterDesktopPluginRegistrarRef FlutterTizenEngine::GetPluginRegistrar() { return plugin_registrar_.get(); } +FlutterTizenTextureRegistrar* FlutterTizenEngine::GetTextureRegistrar() { + return texture_registrar_.get(); +} + void FlutterTizenEngine::SetPluginRegistrarDestructionCallback( FlutterDesktopOnPluginRegistrarDestroyed callback) { plugin_registrar_destruction_callback_ = callback; @@ -396,15 +396,11 @@ FlutterRendererConfig FlutterTizenEngine::GetRendererConfig() { [](void* user_data, int64_t texture_id, size_t width, size_t height, FlutterOpenGLTexture* texture) -> bool { auto engine = reinterpret_cast(user_data); - auto texture_registrar = - engine->plugin_registrar_->texture_registrar.get(); - std::lock_guard lock(texture_registrar->mutex); - auto it = texture_registrar->textures.find(texture_id); - int ret = false; - if (it != texture_registrar->textures.end()) { - ret = it->second->PopulateTextureWithIdentifier(width, height, texture); + if (!engine->GetTextureRegistrar()) { + return false; } - return ret; + return engine->GetTextureRegistrar()->PopulateTexture(texture_id, width, + height, texture); }; } else { config.type = kSoftware; diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index 9b556220a54e5..094b46d786cfb 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -19,10 +19,9 @@ #include "flutter/shell/platform/tizen/channels/platform_view_channel.h" #include "flutter/shell/platform/tizen/channels/settings_channel.h" #include "flutter/shell/platform/tizen/channels/text_input_channel.h" -#include "flutter/shell/platform/tizen/external_texture_gl.h" +#include "flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h" #include "flutter/shell/platform/tizen/key_event_handler.h" #include "flutter/shell/platform/tizen/public/flutter_tizen.h" -#include "flutter/shell/platform/tizen/public/flutter_tizen_texture_registrar.h" #include "flutter/shell/platform/tizen/tizen_event_loop.h" #include "flutter/shell/platform/tizen/tizen_renderer.h" #ifdef TIZEN_RENDERER_EVAS_GL @@ -37,9 +36,6 @@ struct FlutterDesktopPluginRegistrar { // The engine that owns this state object. FlutterTizenEngine* engine; - - // The plugin texture registrar handle given to API clients. - std::unique_ptr texture_registrar; }; // State associated with the messenger used to communicate with the engine. @@ -55,15 +51,6 @@ struct AOTDataDeleter { } }; -// State associated with the texture registrar. -struct FlutterTextureRegistrar { - FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine; - - // The texture registrar managing external texture adapters. - std::map> textures; - std::mutex mutex; -}; - using UniqueAotDataPtr = std::unique_ptr<_FlutterEngineAOTData, AOTDataDeleter>; enum DeviceProfile { kUnknown, kMobile, kWearable, kTV, kCommon }; @@ -86,6 +73,8 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { // Returns the currently configured Plugin Registrar. FlutterDesktopPluginRegistrarRef GetPluginRegistrar(); + FlutterTizenTextureRegistrar* GetTextureRegistrar(); + // Sets |callback| to be called when the plugin registrar is destroyed. void SetPluginRegistrarDestructionCallback( FlutterDesktopOnPluginRegistrarDestroyed callback); @@ -135,6 +124,9 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { // The plugin registrar handle given to API clients. std::unique_ptr plugin_registrar_; + // The texture registrar. + std::unique_ptr texture_registrar_; + // A callback to be called when the engine (and thus the plugin registrar) // is being destroyed. FlutterDesktopOnPluginRegistrarDestroyed diff --git a/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/shell/platform/tizen/flutter_tizen_texture_registrar.cc new file mode 100644 index 0000000000000..92714edd5bff5 --- /dev/null +++ b/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -0,0 +1,108 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. 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/tizen/flutter_tizen_texture_registrar.h" + +#include +#include + +#include "flutter/shell/platform/tizen/external_texture_pixel_gl.h" +#include "flutter/shell/platform/tizen/external_texture_surface_gl.h" +#include "flutter/shell/platform/tizen/flutter_tizen_engine.h" +#include "flutter/shell/platform/tizen/tizen_log.h" + +FlutterTizenTextureRegistrar::FlutterTizenTextureRegistrar( + FlutterTizenEngine* engine) + : engine_(engine) {} + +int64_t FlutterTizenTextureRegistrar::RegisterTexture( + const FlutterDesktopTextureInfo* texture_info) { + if (texture_info->type != kFlutterDesktopPixelBufferTexture && + texture_info->type != kFlutterDesktopGpuBufferTexture) { + FT_LOGE("Attempted to register texture of unsupport type."); + return -1; + } + + if (texture_info->type == kFlutterDesktopPixelBufferTexture) { + if (!texture_info->pixel_buffer_config.callback) { + FT_LOGE("Invalid pixel buffer texture callback."); + return -1; + } + } + + if (texture_info->type == kFlutterDesktopGpuBufferTexture) { + if (!texture_info->gpu_buffer_config.callback) { + FT_LOGE("Invalid gpu buffer texture callback."); + return -1; + } + } + auto texture_gl = CreateExternalTexture(texture_info); + int64_t texture_id = texture_gl->TextureId(); + + { + std::lock_guard lock(map_mutex_); + textures_[texture_id] = std::move(texture_gl); + } + + FlutterEngineRegisterExternalTexture(engine_->flutter_engine, texture_id); + return texture_id; +} + +bool FlutterTizenTextureRegistrar::UnregisterTexture(int64_t texture_id) { + { + std::lock_guard lock(map_mutex_); + auto it = textures_.find(texture_id); + if (it == textures_.end()) { + return false; + } + textures_.erase(it); + } + + return FlutterEngineUnregisterExternalTexture(engine_->flutter_engine, + texture_id) == kSuccess; +} + +bool FlutterTizenTextureRegistrar::MarkTextureFrameAvailable( + int64_t texture_id) { + return FlutterEngineMarkExternalTextureFrameAvailable(engine_->flutter_engine, + texture_id) == kSuccess; +} + +bool FlutterTizenTextureRegistrar::PopulateTexture( + int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + ExternalTexture* texture; + { + std::lock_guard lock(map_mutex_); + auto it = textures_.find(texture_id); + if (it == textures_.end()) { + return false; + } + texture = it->second.get(); + } + return texture->PopulateTexture(width, height, opengl_texture); +} + +std::unique_ptr +FlutterTizenTextureRegistrar::CreateExternalTexture( + const FlutterDesktopTextureInfo* texture_info) { + switch (texture_info->type) { + case kFlutterDesktopPixelBufferTexture: + return std::make_unique( + texture_info->pixel_buffer_config.callback, + texture_info->pixel_buffer_config.user_data); + break; + case kFlutterDesktopGpuBufferTexture: + return std::make_unique( + texture_info->gpu_buffer_config.callback, + texture_info->gpu_buffer_config.destruction_callback, + texture_info->gpu_buffer_config.user_data); + break; + default: + FT_LOGE("Invalid texture type."); + return nullptr; + } +} diff --git a/shell/platform/tizen/flutter_tizen_texture_registrar.h b/shell/platform/tizen/flutter_tizen_texture_registrar.h new file mode 100644 index 0000000000000..f2b6d048107a4 --- /dev/null +++ b/shell/platform/tizen/flutter_tizen_texture_registrar.h @@ -0,0 +1,53 @@ +// Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EMBEDDER_FLUTTER_TIZEN_TEXTURE_REGISTRAR_H_ +#define EMBEDDER_FLUTTER_TIZEN_TEXTURE_REGISTRAR_H_ + +#include +#include +#include + +#include "flutter/shell/platform/tizen/external_texture.h" + +class FlutterTizenEngine; + +// An object managing the registration of an external texture. +// Thread safety: All member methods are thread safe. +class FlutterTizenTextureRegistrar { + public: + explicit FlutterTizenTextureRegistrar(FlutterTizenEngine* engine); + + // Registers a texture described by the given |texture_info| object. + // Returns the non-zero, positive texture id or -1 on error. + int64_t RegisterTexture(const FlutterDesktopTextureInfo* texture_info); + + // Attempts to unregister the texture identified by |texture_id|. + // Returns true if the texture was successfully unregistered. + bool UnregisterTexture(int64_t texture_id); + + // Notifies the engine about a new frame being available. + // Returns true on success. + bool MarkTextureFrameAvailable(int64_t texture_id); + + // Attempts to populate the given |texture| by copying the + // contents of the texture identified by |texture_id|. + // Returns true on success. + bool PopulateTexture(int64_t texture_id, + size_t width, + size_t height, + FlutterOpenGLTexture* texture); + + std::unique_ptr CreateExternalTexture( + const FlutterDesktopTextureInfo* info); + + private: + FlutterTizenEngine* engine_ = nullptr; + + // All registered textures, keyed by their IDs. + std::unordered_map> textures_; + std::mutex map_mutex_; +}; + +#endif // EMBEDDER_FLUTTER_TIZEN_TEXTURE_REGISTRAR_H_ diff --git a/shell/platform/tizen/public/flutter_tizen_texture_registrar.h b/shell/platform/tizen/public/flutter_tizen_texture_registrar.h deleted file mode 100644 index 36672612cec5d..0000000000000 --- a/shell/platform/tizen/public/flutter_tizen_texture_registrar.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2020 Samsung Electronics Co., Ltd. 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_TIZEN_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_ -#define FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_ - -#include -#include - -#include "flutter_export.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -// Opaque reference to a texture registrar. -typedef struct FlutterTextureRegistrar* FlutterTextureRegistrarRef; - -// Returns the texture registrar associated with this registrar. -FLUTTER_EXPORT FlutterTextureRegistrarRef -FlutterPluginRegistrarGetTexture(FlutterDesktopPluginRegistrarRef registrar); - -// Registers a new texture with the Flutter engine and returns the texture ID, -FLUTTER_EXPORT int64_t -FlutterRegisterExternalTexture(FlutterTextureRegistrarRef texture_registrar); - -// Unregisters an existing texture from the Flutter engine for a |texture_id|. -// Returns true on success, false on failure. -FLUTTER_EXPORT bool FlutterUnregisterExternalTexture( - FlutterTextureRegistrarRef texture_registrar, - int64_t texture_id); - -// Marks that a new texture frame is available for a given |texture_id|. -// Returns true on success, false on failure. -FLUTTER_EXPORT bool FlutterMarkExternalTextureFrameAvailable( - FlutterTextureRegistrarRef texture_registrar, - int64_t texture_id, - void* tbm_surface); - -#if defined(__cplusplus) -} // extern "C" -#endif - -#endif // FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_