diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 1ea9bcf30bb00..665ba21c1e5c6 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -52,6 +52,7 @@ config("tizen_rootstrap_include_dirs") { "$custom_sysroot/usr/include/emile-1", "$custom_sysroot/usr/include/eo-1", "$custom_sysroot/usr/include/evas-1", + "$custom_sysroot/usr/include/media", "$custom_sysroot/usr/include/system", "$custom_sysroot/usr/include/wayland-extension", # For Evas_GL. @@ -106,6 +107,7 @@ template("embedder_for_profile") { libs = [ "base-utils-i18n", "capi-appfw-application", + "capi-media-tool", "capi-system-info", "capi-system-system-settings", "dlog", diff --git a/shell/platform/tizen/external_texture_gl.cc b/shell/platform/tizen/external_texture_gl.cc index 668503e4eb1e2..0299492614836 100644 --- a/shell/platform/tizen/external_texture_gl.cc +++ b/shell/platform/tizen/external_texture_gl.cc @@ -30,89 +30,36 @@ struct ExternalTextureGLState { static std::atomic_long nextTextureId = {1}; -static void MarkTbmSurfaceToUse(void* surface) { -#ifndef WEARABLE_PROFILE +static void UnmarkTbmSurfaceToUse(void* surface) { FT_ASSERT(surface); tbm_surface_h tbm_surface = (tbm_surface_h)surface; - tbm_surface_internal_ref(tbm_surface); -#endif + tbm_surface_destroy(tbm_surface); } -static void UnmarkTbmSurfaceToUse(void* surface) { +static void UnmarkMediaPacketToUse(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 + media_packet_destroy((media_packet_h)surface); } ExternalTextureGL::ExternalTextureGL() : state_(std::make_unique()), - available_tbm_surface_(nullptr), texture_id_(nextTextureId++) {} ExternalTextureGL::~ExternalTextureGL() { 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_); - 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_); - return false; - } - - 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; - } - +bool ExternalTextureGL::MakeTextureFromExternalImage( + tbm_surface_h surface, void* external_image, size_t width, size_t height, + FlutterOpenGLTexture* opengl_texture, VoidCallback destruction_callback) { #ifdef TIZEN_RENDERER_EVAS_GL 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)surface, attribs); if (!egl_src_image) { return false; } @@ -141,7 +88,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)surface, attribs); if (!egl_src_image) { FT_LOGE("[texture id:%ld] egl_src_image create fail!!, errorcode == %d", @@ -176,13 +123,122 @@ 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; + opengl_texture->destruction_callback = destruction_callback; + opengl_texture->user_data = external_image; + opengl_texture->width = width; + opengl_texture->height = height; + + return true; +} + +ExternalTextureTbm::ExternalTextureTbm() + : ExternalTextureGL(), available_tbm_surface_(nullptr) {} - // Abandon ownership of tbm_surface - opengl_texture->user_data = available_tbm_surface_; +ExternalTextureTbm::~ExternalTextureTbm() { + if (available_tbm_surface_) { + UnmarkTbmSurfaceToUse(available_tbm_surface_); + } +} + +bool ExternalTextureTbm::OnFrameAvailable(void* external_image) { + if (!external_image) { + FT_LOGE("[texture id:%ld] tbm_surface is null", (long)TextureId()); + return false; + } + tbm_surface_h tbm_surface = (tbm_surface_h)external_image; + + if (available_tbm_surface_) { + FT_LOGD( + "[texture id:%ld] Discard! an available tbm surface that has not yet " + "been used exists", + (long)TextureId()); + return false; + } + + 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", (long)TextureId()); + return false; + } + available_tbm_surface_ = tbm_surface; + + return true; +} + +bool ExternalTextureTbm::PopulateTextureWithIdentifier( + size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { + if (!available_tbm_surface_) { + FT_LOGD("[texture id:%ld] available_tbm_surface_ is null", + (long)TextureId()); + 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", (long)TextureId()); + UnmarkTbmSurfaceToUse(available_tbm_surface_); + available_tbm_surface_ = nullptr; + return false; + } + MakeTextureFromExternalImage( + available_tbm_surface_, (void*)available_tbm_surface_, width, height, + opengl_texture, (VoidCallback)UnmarkTbmSurfaceToUse); available_tbm_surface_ = nullptr; + return true; +} - opengl_texture->width = width; - opengl_texture->height = height; +ExternalTextureMediaPacket::ExternalTextureMediaPacket() + : ExternalTextureGL(), available_media_packet_(nullptr) {} + +ExternalTextureMediaPacket::~ExternalTextureMediaPacket() { + if (available_media_packet_) { + UnmarkTbmSurfaceToUse(available_media_packet_); + } +} + +bool ExternalTextureMediaPacket::OnFrameAvailable(void* external_image) { + if (!external_image) { + FT_LOGE("[texture id:%ld] media_packet is null", (long)TextureId()); + return false; + } + + if (available_media_packet_) { + FT_LOGD( + "[texture id:%ld] Discard! an available media_packet that has not yet " + "been used exists", + (long)TextureId()); + // If not ready, discard media_packet. + UnmarkMediaPacketToUse(external_image); + return false; + } + + available_media_packet_ = (media_packet_h)external_image; + return true; +} + +bool ExternalTextureMediaPacket::PopulateTextureWithIdentifier( + size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { + if (!available_media_packet_) { + FT_LOGD("[texture id:%ld] available_media_packet_ is null", + (long)TextureId()); + return false; + } + + tbm_surface_h tbm_surface; + if (media_packet_get_tbm_surface(available_media_packet_, &tbm_surface) != + 0) { + FT_LOGD("[texture id:%ld] fail to get tbm_surface from media_packet", + (long)TextureId()); + return false; + } + tbm_surface_info_s info; + if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) { + FT_LOGD("[texture id:%ld] tbm_surface is invalid", (long)TextureId()); + return false; + } + MakeTextureFromExternalImage(tbm_surface, available_media_packet_, width, + height, opengl_texture, + (VoidCallback)UnmarkMediaPacketToUse); + available_media_packet_ = nullptr; return true; } diff --git a/shell/platform/tizen/external_texture_gl.h b/shell/platform/tizen/external_texture_gl.h index 988dfe387cc28..31fff21c3eac8 100644 --- a/shell/platform/tizen/external_texture_gl.h +++ b/shell/platform/tizen/external_texture_gl.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_ #define FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_ +#include #include #include #include @@ -22,7 +23,6 @@ typedef struct ExternalTextureGLState ExternalTextureGLState; class ExternalTextureGL { public: ExternalTextureGL(); - virtual ~ExternalTextureGL(); /** @@ -38,15 +38,51 @@ class ExternalTextureGL { * 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); + virtual bool PopulateTextureWithIdentifier( + size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { + // assert; + return false; + } + virtual bool OnFrameAvailable(void* external_image) { + // assert; + return false; + } - private: + protected: + bool MakeTextureFromExternalImage(tbm_surface_h surface, void* external_image, size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture, + VoidCallback destruction_callback); +private: std::unique_ptr state_; std::mutex mutex_; - tbm_surface_h available_tbm_surface_{nullptr}; const long texture_id_{0}; }; +class ExternalTextureTbm : public ExternalTextureGL { + public: + ExternalTextureTbm(); + ~ExternalTextureTbm(); + virtual bool PopulateTextureWithIdentifier( + size_t width, size_t height, + FlutterOpenGLTexture* opengl_texture) override; + virtual bool OnFrameAvailable(void* external_image) override; + + private: + tbm_surface_h available_tbm_surface_{nullptr}; +}; + +class ExternalTextureMediaPacket : public ExternalTextureGL { + public: + ExternalTextureMediaPacket(); + ~ExternalTextureMediaPacket(); + virtual bool PopulateTextureWithIdentifier( + size_t width, size_t height, + FlutterOpenGLTexture* opengl_texture) override; + virtual bool OnFrameAvailable(void* external_image) override; + + private: + media_packet_h available_media_packet_{nullptr}; +}; + #endif // FLUTTER_SHELL_PLATFORM_TIZEN_EXTERNAL_TEXTURE_GL_H_ diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index d8a92a531ab82..d04c7136f432d 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -179,10 +179,16 @@ void FlutterNotifyLowMemoryWarning(FlutterWindowControllerRef controller) { } int64_t FlutterRegisterExternalTexture( - FlutterTextureRegistrarRef texture_registrar) { + FlutterTextureRegistrarRef texture_registrar, + TizenTextureType textureType) { FT_LOGD("FlutterDesktopRegisterExternalTexture"); std::lock_guard lock(texture_registrar->mutex); - auto texture_gl = std::make_unique(); + std::unique_ptr texture_gl; + if (textureType == TbmSurface) { + texture_gl = std::make_unique(); + } else { + 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, @@ -205,15 +211,14 @@ bool FlutterUnregisterExternalTexture( bool FlutterMarkExternalTextureFrameAvailable( FlutterTextureRegistrarRef texture_registrar, int64_t texture_id, - void* tbm_surface) { + void* frame) { 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 (!texture_registrar->textures[texture_id]->OnFrameAvailable(frame)) { // If a texture that has not been used already exists, it can fail return false; } diff --git a/shell/platform/tizen/public/flutter_tizen_texture_registrar.h b/shell/platform/tizen/public/flutter_tizen_texture_registrar.h index 0d5f0e8330185..42411b1ed8810 100644 --- a/shell/platform/tizen/public/flutter_tizen_texture_registrar.h +++ b/shell/platform/tizen/public/flutter_tizen_texture_registrar.h @@ -14,6 +14,8 @@ extern "C" { #endif +enum TizenTextureType { TbmSurface = 0, MediaPacket }; + // Opaque reference to a texture registrar. typedef struct FlutterTextureRegistrar* FlutterTextureRegistrarRef; @@ -23,7 +25,8 @@ FlutterPluginRegistrarGetTexture(FlutterDesktopPluginRegistrarRef registrar); // Registers a new texture with the Flutter engine and returns the texture ID, FLUTTER_EXPORT int64_t -FlutterRegisterExternalTexture(FlutterTextureRegistrarRef texture_registrar); +FlutterRegisterExternalTexture(FlutterTextureRegistrarRef texture_registrar, + TizenTextureType textureType = TbmSurface); // Unregisters an existing texture from the Flutter engine for a |texture_id|. // Returns true on success, false on failure.