diff --git a/shell/platform/tizen/external_texture.h b/shell/platform/tizen/external_texture.h index 281a055703dc9..829271b211c77 100644 --- a/shell/platform/tizen/external_texture.h +++ b/shell/platform/tizen/external_texture.h @@ -20,8 +20,11 @@ namespace flutter { +enum class ExternalTextureExtensionType { kNone, kNativeSurface, kDmaBuffer }; + struct ExternalTextureGLState { GLuint gl_texture; + ExternalTextureExtensionType gl_extention; }; static std::atomic_long next_texture_id = {1}; @@ -29,9 +32,12 @@ 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() + ExternalTexture(ExternalTextureExtensionType gl_extention = + ExternalTextureExtensionType::kNone) : state_(std::make_unique()), - texture_id_(next_texture_id++) {} + texture_id_(next_texture_id++) { + state_->gl_extention = gl_extention; + } virtual ~ExternalTexture() = default; /** diff --git a/shell/platform/tizen/external_texture_surface_gl.h b/shell/platform/tizen/external_texture_surface_gl.h index 7efd5e6b905b4..7ed5ac23c9e26 100644 --- a/shell/platform/tizen/external_texture_surface_gl.h +++ b/shell/platform/tizen/external_texture_surface_gl.h @@ -15,6 +15,7 @@ namespace flutter { class ExternalTextureSurfaceGL : public ExternalTexture { public: ExternalTextureSurfaceGL( + ExternalTextureExtensionType gl_extention, FlutterDesktopGpuBufferTextureCallback texture_callback, FlutterDesktopGpuBufferDestructionCallback destruction_callback, void* user_data); diff --git a/shell/platform/tizen/external_texture_surface_gl_linux.cc b/shell/platform/tizen/external_texture_surface_gl_linux.cc index bced5d8446036..19e0671054119 100644 --- a/shell/platform/tizen/external_texture_surface_gl_linux.cc +++ b/shell/platform/tizen/external_texture_surface_gl_linux.cc @@ -12,10 +12,11 @@ namespace flutter { ExternalTextureSurfaceGL::ExternalTextureSurfaceGL( + ExternalTextureExtensionType gl_extention, FlutterDesktopGpuBufferTextureCallback texture_callback, FlutterDesktopGpuBufferDestructionCallback destruction_callback, void* user_data) - : ExternalTexture(), + : ExternalTexture(gl_extention), texture_callback_(texture_callback), destruction_callback_(destruction_callback), user_data_(user_data) {} diff --git a/shell/platform/tizen/external_texture_surface_gl_tizen.cc b/shell/platform/tizen/external_texture_surface_gl_tizen.cc index 737e1ae57ee6c..8cff5949357d8 100644 --- a/shell/platform/tizen/external_texture_surface_gl_tizen.cc +++ b/shell/platform/tizen/external_texture_surface_gl_tizen.cc @@ -4,6 +4,8 @@ #include "external_texture_surface_gl.h" +#include + #ifdef TIZEN_RENDERER_EVAS_GL #undef EFL_BETA_API_SUPPORT #include "tizen_evas_gl_helper.h" @@ -14,9 +16,19 @@ EVAS_GL_GLOBAL_GLES3_DECLARE(); #include #include #include -#endif -#include +#include +#include +#ifndef EGL_DMA_BUF_PLANE3_FD_EXT +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#endif +#ifndef EGL_DMA_BUF_PLANE3_OFFSET_EXT +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#endif +#ifndef EGL_DMA_BUF_PLANE3_PITCH_EXT +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#endif +#endif #include "flutter/shell/platform/tizen/logger.h" @@ -33,10 +45,11 @@ static void OnCollectTexture(void* textureGL) { } ExternalTextureSurfaceGL::ExternalTextureSurfaceGL( + ExternalTextureExtensionType gl_extention, FlutterDesktopGpuBufferTextureCallback texture_callback, FlutterDesktopGpuBufferDestructionCallback destruction_callback, void* user_data) - : ExternalTexture(), + : ExternalTexture(gl_extention), texture_callback_(texture_callback), destruction_callback_(destruction_callback), user_data_(user_data) {} @@ -76,10 +89,17 @@ bool ExternalTextureSurfaceGL::PopulateTexture( } #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, tbm_surface, attribs); + EvasGLImage egl_src_image = nullptr; + if (state_->gl_extention == ExternalTextureExtensionType::kNativeSurface) { + int attribs[] = {EVAS_GL_IMAGE_PRESERVED, GL_TRUE, 0}; + egl_src_image = evasglCreateImageForContext( + g_evas_gl, evas_gl_current_context_get(g_evas_gl), + EVAS_GL_NATIVE_SURFACE_TIZEN, tbm_surface, attribs); + } else if (state_->gl_extention == ExternalTextureExtensionType::kDmaBuffer) { + FT_LOG(Error) + << "EGL_EXT_image_dma_buf_import is not supported this renderer."; + return false; + } if (!egl_src_image) { return false; } @@ -105,15 +125,60 @@ bool ExternalTextureSurfaceGL::PopulateTexture( PFNEGLCREATEIMAGEKHRPROC n_eglCreateImageKHR = reinterpret_cast( eglGetProcAddress("eglCreateImageKHR")); - const EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, - EGL_NONE}; - EGLImageKHR egl_src_image = - n_eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, - EGL_NATIVE_SURFACE_TIZEN, tbm_surface, attribs); + EGLImageKHR egl_src_image = nullptr; + + if (state_->gl_extention == ExternalTextureExtensionType::kNativeSurface) { + const EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, + EGL_NONE}; + egl_src_image = + n_eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, + EGL_NATIVE_SURFACE_TIZEN, tbm_surface, attribs); + } else if (state_->gl_extention == ExternalTextureExtensionType::kDmaBuffer) { + EGLint attribs[50]; + int atti = 0; + int plane_fd_ext[4] = {EGL_DMA_BUF_PLANE0_FD_EXT, EGL_DMA_BUF_PLANE1_FD_EXT, + EGL_DMA_BUF_PLANE2_FD_EXT, + EGL_DMA_BUF_PLANE3_FD_EXT}; + int plane_offset_ext[4] = { + EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGL_DMA_BUF_PLANE1_OFFSET_EXT, + EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGL_DMA_BUF_PLANE3_OFFSET_EXT}; + int plane_pitch_ext[4] = { + EGL_DMA_BUF_PLANE0_PITCH_EXT, EGL_DMA_BUF_PLANE1_PITCH_EXT, + EGL_DMA_BUF_PLANE2_PITCH_EXT, EGL_DMA_BUF_PLANE3_PITCH_EXT}; + + attribs[atti++] = EGL_WIDTH; + attribs[atti++] = info.width; + attribs[atti++] = EGL_HEIGHT; + attribs[atti++] = info.height; + attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; + attribs[atti++] = info.format; + + int num_planes = tbm_surface_internal_get_num_planes(info.format); + for (int i = 0; i < num_planes; i++) { + int bo_idx = tbm_surface_internal_get_plane_bo_idx(tbm_surface, i); + tbm_bo tbo = tbm_surface_internal_get_bo(tbm_surface, bo_idx); + attribs[atti++] = plane_fd_ext[i]; + attribs[atti++] = static_cast( + reinterpret_cast(tbm_bo_get_handle(tbo, TBM_DEVICE_3D).ptr)); + attribs[atti++] = plane_offset_ext[i]; + attribs[atti++] = info.planes[i].offset; + attribs[atti++] = plane_pitch_ext[i]; + attribs[atti++] = info.planes[i].stride; + } + attribs[atti++] = EGL_NONE; + egl_src_image = + n_eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, nullptr, attribs); + } if (!egl_src_image) { - FT_LOG(Error) << "eglCreateImageKHR failed with an error " << eglGetError() - << " for texture ID: " << texture_id_; + if (state_->gl_extention != ExternalTextureExtensionType::kNone) { + FT_LOG(Error) << "eglCreateImageKHR failed with an error " + << eglGetError() << " for texture ID: " << texture_id_; + } else { + FT_LOG(Error) << "Either EGL_TIZEN_image_native_surface or " + "EGL_EXT_image_dma_buf_import shoule be supported."; + } return false; } if (state_->gl_texture == 0) { diff --git a/shell/platform/tizen/flutter_tizen_texture_registrar.cc b/shell/platform/tizen/flutter_tizen_texture_registrar.cc index 5eb15ef2e0eae..e88bc7db8efcc 100644 --- a/shell/platform/tizen/flutter_tizen_texture_registrar.cc +++ b/shell/platform/tizen/flutter_tizen_texture_registrar.cc @@ -95,14 +95,20 @@ FlutterTizenTextureRegistrar::CreateExternalTexture( texture_info->pixel_buffer_config.user_data); break; case kFlutterDesktopGpuBufferTexture: + ExternalTextureExtensionType gl_extension = + ExternalTextureExtensionType::kNone; + if (engine_->renderer()->IsSupportedExtention( + "EGL_TIZEN_image_native_surface")) { + gl_extension = ExternalTextureExtensionType::kNativeSurface; + } else if (engine_->renderer()->IsSupportedExtention( + "EGL_EXT_image_dma_buf_import")) { + gl_extension = ExternalTextureExtensionType::kDmaBuffer; + } return std::make_unique( - texture_info->gpu_buffer_config.callback, + gl_extension, texture_info->gpu_buffer_config.callback, texture_info->gpu_buffer_config.destruction_callback, texture_info->gpu_buffer_config.user_data); break; - default: - FT_LOG(Error) << "Invalid texture type."; - return nullptr; } } diff --git a/shell/platform/tizen/tizen_renderer.h b/shell/platform/tizen/tizen_renderer.h index c8e2eaff0b178..06358041be9eb 100644 --- a/shell/platform/tizen/tizen_renderer.h +++ b/shell/platform/tizen/tizen_renderer.h @@ -44,6 +44,7 @@ class TizenRenderer { int32_t height, int32_t degree) = 0; virtual void SetPreferredOrientations(const std::vector& rotations) = 0; + virtual bool IsSupportedExtention(const char* name) = 0; protected: explicit TizenRenderer(WindowGeometry geometry, diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc index 4fbc9d2315389..eb9d0b1d109a1 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc @@ -359,6 +359,7 @@ bool TizenRendererEcoreWl2::SetupEglSurface() { FT_LOG(Error) << "ChooseEGLConfiguration() failed."; return false; } + egl_extention_str_ = eglQueryString(egl_display_, EGL_EXTENSIONS); const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; egl_context_ = eglCreateContext(egl_display_, egl_config_, EGL_NO_CONTEXT, @@ -556,4 +557,11 @@ void TizenRendererEcoreWl2::SetPreferredOrientations( rotations.size()); } +bool TizenRendererEcoreWl2::IsSupportedExtention(const char* name) { + if (strstr(egl_extention_str_.c_str(), name)) { + return true; + } + return false; +} + } // namespace flutter diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.h b/shell/platform/tizen/tizen_renderer_ecore_wl2.h index ea113998628b6..7924995bcf2d2 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.h +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.h @@ -8,6 +8,7 @@ #define EFL_BETA_API_SUPPORT #include #include +#include #include "flutter/shell/platform/tizen/tizen_renderer.h" @@ -40,6 +41,7 @@ class TizenRendererEcoreWl2 : public TizenRenderer { int32_t angle) override; void SetRotate(int angle) override; void SetPreferredOrientations(const std::vector& rotations) override; + bool IsSupportedExtention(const char* name) override; private: bool InitializeRenderer(); @@ -73,6 +75,8 @@ class TizenRendererEcoreWl2 : public TizenRenderer { EGLSurface egl_surface_ = EGL_NO_SURFACE; EGLContext egl_resource_context_ = EGL_NO_CONTEXT; EGLSurface egl_resource_surface_ = EGL_NO_SURFACE; + + std::string egl_extention_str_; }; } // namespace flutter diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.cc b/shell/platform/tizen/tizen_renderer_evas_gl.cc index 282d9c2fd98d2..ad8175184ea52 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.cc +++ b/shell/platform/tizen/tizen_renderer_evas_gl.cc @@ -736,4 +736,8 @@ void TizenRendererEvasGL::SetPreferredOrientations( rotations.size()); } +bool TizenRendererEvasGL::IsSupportedExtention(const char* name) { + return strcmp(name, "EGL_TIZEN_image_native_surface") == 0; +} + } // namespace flutter diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.h b/shell/platform/tizen/tizen_renderer_evas_gl.h index 401c7e0c0e0e0..af0f7bb0ec2fc 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.h +++ b/shell/platform/tizen/tizen_renderer_evas_gl.h @@ -41,6 +41,7 @@ class TizenRendererEvasGL : public TizenRenderer { int32_t angle) override; void SetRotate(int angle) override; void SetPreferredOrientations(const std::vector& rotations) override; + bool IsSupportedExtention(const char* name) override; Evas_Object* GetImageHandle();