From 540b1f62c2bd2c46922b36db10250d9d8c446c00 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Mon, 14 Dec 2020 20:30:19 +0900 Subject: [PATCH] Refactor tizen surface * Add TizenNativeWindow, TizenNativeEGLWindow, TizenWl2Display * Add TizenEGLContext, TizenEGLSurface, TizenEGLSurface * TizenEmbedderEngine has TizenNativeWindow as a public member * Release EGLSurface, EGLDisplay, EGLContext Signed-off-by: Boram Bae --- shell/platform/tizen/BUILD.gn | 1 + .../tizen/channels/text_input_channel.cc | 19 +- shell/platform/tizen/proc_resolver_macro.h | 117 +++++ shell/platform/tizen/tizen_embedder_engine.cc | 10 +- shell/platform/tizen/tizen_embedder_engine.h | 1 + shell/platform/tizen/tizen_event_loop.cc | 2 + shell/platform/tizen/tizen_native_window.cc | 112 +++++ shell/platform/tizen/tizen_native_window.h | 53 ++ shell/platform/tizen/tizen_surface.cc | 9 +- shell/platform/tizen/tizen_surface.h | 9 - shell/platform/tizen/tizen_surface_gl.cc | 469 +++++++----------- shell/platform/tizen/tizen_surface_gl.h | 68 ++- shell/platform/tizen/touch_event_handler.cc | 5 +- 13 files changed, 525 insertions(+), 350 deletions(-) create mode 100644 shell/platform/tizen/proc_resolver_macro.h create mode 100644 shell/platform/tizen/tizen_native_window.cc create mode 100644 shell/platform/tizen/tizen_native_window.h diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 62e4603bfc525..795cd2eaefc3c 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -46,6 +46,7 @@ source_set("flutter_tizen") { "tizen_surface.cc", "tizen_surface_gl.cc", "tizen_vsync_waiter.cc", + "tizen_native_window.cc", "touch_event_handler.cc", ] diff --git a/shell/platform/tizen/channels/text_input_channel.cc b/shell/platform/tizen/channels/text_input_channel.cc index a158c74e8a902..42258a4aa9945 100644 --- a/shell/platform/tizen/channels/text_input_channel.cc +++ b/shell/platform/tizen/channels/text_input_channel.cc @@ -105,9 +105,11 @@ void TextInputChannel::InputPanelStateChangedCallback( 0.25, [](void* data) -> Eina_Bool { TextInputChannel* self = (TextInputChannel*)data; - int32_t surface_w = self->engine_->tizen_surface->GetWidth(); - int32_t surface_h = self->engine_->tizen_surface->GetHeight() - - self->current_keyboard_geometry_.h; + auto window_geometry = + self->engine_->tizen_native_window->GetGeometry(); + int32_t surface_w = window_geometry.w; + int32_t surface_h = + window_geometry.h - self->current_keyboard_geometry_.h; self->engine_->tizen_surface->SetSize(surface_w, surface_h); if (self->rotation == 90 || self->rotation == 270) { self->engine_->SendWindowMetrics(surface_h, surface_w, 0); @@ -293,7 +295,7 @@ TextInputChannel::TextInputChannel(flutter::BinaryMessenger* messenger, } if (imfContext_) { Ecore_Wl2_Window* ecoreWindow = - ((TizenSurfaceGL*)engine_->tizen_surface.get())->wl2_window(); + engine_->tizen_native_window->GetWindowHandle(); ecore_imf_context_client_window_set( imfContext_, (void*)ecore_wl2_window_id_get(ecoreWindow)); RegisterIMFCallback(ecoreWindow); @@ -604,15 +606,14 @@ void TextInputChannel::HideSoftwareKeyboard() { if (engine_->device_profile == "mobile") { // FIXME : Needs improvement on other devices. - auto w = engine_->tizen_surface->GetWidth(); - auto h = engine_->tizen_surface->GetHeight(); + auto window_geometry = engine_->tizen_native_window->GetGeometry(); if (rotation == 90 || rotation == 270) { - engine_->SendWindowMetrics(h, w, 0); + engine_->SendWindowMetrics(window_geometry.h, window_geometry.w, 0); } else { - engine_->SendWindowMetrics(w, h, 0); + engine_->SendWindowMetrics(window_geometry.w, window_geometry.h, 0); } - engine_->tizen_surface->SetSize(w, h); + engine_->tizen_surface->SetSize(window_geometry.w, window_geometry.h); ecore_timer_add( 0.05, [](void* data) -> Eina_Bool { diff --git a/shell/platform/tizen/proc_resolver_macro.h b/shell/platform/tizen/proc_resolver_macro.h new file mode 100644 index 0000000000000..2710eb868795a --- /dev/null +++ b/shell/platform/tizen/proc_resolver_macro.h @@ -0,0 +1,117 @@ +// 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. + +#define GL_FUNC(FunctionName) \ + else if (strcmp(name, #FunctionName) == 0) { \ + return reinterpret_cast(FunctionName); \ + } + +GL_FUNC(eglGetCurrentDisplay) +GL_FUNC(eglQueryString) +GL_FUNC(glActiveTexture) +GL_FUNC(glAttachShader) +GL_FUNC(glBindAttribLocation) +GL_FUNC(glBindBuffer) +GL_FUNC(glBindFramebuffer) +GL_FUNC(glBindRenderbuffer) +GL_FUNC(glBindTexture) +GL_FUNC(glBlendColor) +GL_FUNC(glBlendEquation) +GL_FUNC(glBlendFunc) +GL_FUNC(glBufferData) +GL_FUNC(glBufferSubData) +GL_FUNC(glCheckFramebufferStatus) +GL_FUNC(glClear) +GL_FUNC(glClearColor) +GL_FUNC(glClearStencil) +GL_FUNC(glColorMask) +GL_FUNC(glCompileShader) +GL_FUNC(glCompressedTexImage2D) +GL_FUNC(glCompressedTexSubImage2D) +GL_FUNC(glCopyTexSubImage2D) +GL_FUNC(glCreateProgram) +GL_FUNC(glCreateShader) +GL_FUNC(glCullFace) +GL_FUNC(glDeleteBuffers) +GL_FUNC(glDeleteFramebuffers) +GL_FUNC(glDeleteProgram) +GL_FUNC(glDeleteRenderbuffers) +GL_FUNC(glDeleteShader) +GL_FUNC(glDeleteTextures) +GL_FUNC(glDepthMask) +GL_FUNC(glDisable) +GL_FUNC(glDisableVertexAttribArray) +GL_FUNC(glDrawArrays) +GL_FUNC(glDrawElements) +GL_FUNC(glEnable) +GL_FUNC(glEnableVertexAttribArray) +GL_FUNC(glFinish) +GL_FUNC(glFlush) +GL_FUNC(glFramebufferRenderbuffer) +GL_FUNC(glFramebufferTexture2D) +GL_FUNC(glFrontFace) +GL_FUNC(glGenBuffers) +GL_FUNC(glGenerateMipmap) +GL_FUNC(glGenFramebuffers) +GL_FUNC(glGenRenderbuffers) +GL_FUNC(glGenTextures) +GL_FUNC(glGetBufferParameteriv) +GL_FUNC(glGetError) +GL_FUNC(glGetFramebufferAttachmentParameteriv) +GL_FUNC(glGetIntegerv) +GL_FUNC(glGetProgramInfoLog) +GL_FUNC(glGetProgramiv) +GL_FUNC(glGetRenderbufferParameteriv) +GL_FUNC(glGetShaderInfoLog) +GL_FUNC(glGetShaderiv) +GL_FUNC(glGetShaderPrecisionFormat) +GL_FUNC(glGetString) +GL_FUNC(glGetUniformLocation) +GL_FUNC(glIsTexture) +GL_FUNC(glLineWidth) +GL_FUNC(glLinkProgram) +GL_FUNC(glPixelStorei) +GL_FUNC(glReadPixels) +GL_FUNC(glRenderbufferStorage) +GL_FUNC(glScissor) +GL_FUNC(glShaderSource) +GL_FUNC(glStencilFunc) +GL_FUNC(glStencilFuncSeparate) +GL_FUNC(glStencilMask) +GL_FUNC(glStencilMaskSeparate) +GL_FUNC(glStencilOp) +GL_FUNC(glStencilOpSeparate) +GL_FUNC(glTexImage2D) +GL_FUNC(glTexParameterf) +GL_FUNC(glTexParameterfv) +GL_FUNC(glTexParameteri) +GL_FUNC(glTexParameteriv) +GL_FUNC(glTexSubImage2D) +GL_FUNC(glUniform1f) +GL_FUNC(glUniform1fv) +GL_FUNC(glUniform1i) +GL_FUNC(glUniform1iv) +GL_FUNC(glUniform2f) +GL_FUNC(glUniform2fv) +GL_FUNC(glUniform2i) +GL_FUNC(glUniform2iv) +GL_FUNC(glUniform3f) +GL_FUNC(glUniform3fv) +GL_FUNC(glUniform3i) +GL_FUNC(glUniform3iv) +GL_FUNC(glUniform4f) +GL_FUNC(glUniform4fv) +GL_FUNC(glUniform4i) +GL_FUNC(glUniform4iv) +GL_FUNC(glUniformMatrix2fv) +GL_FUNC(glUniformMatrix3fv) +GL_FUNC(glUniformMatrix4fv) +GL_FUNC(glUseProgram) +GL_FUNC(glVertexAttrib1f) +GL_FUNC(glVertexAttrib2fv) +GL_FUNC(glVertexAttrib3fv) +GL_FUNC(glVertexAttrib4fv) +GL_FUNC(glVertexAttribPointer) +GL_FUNC(glViewport) +#undef GL_FUNC diff --git a/shell/platform/tizen/tizen_embedder_engine.cc b/shell/platform/tizen/tizen_embedder_engine.cc index 05fbe02ce4e7b..6667a5ca0a426 100644 --- a/shell/platform/tizen/tizen_embedder_engine.cc +++ b/shell/platform/tizen/tizen_embedder_engine.cc @@ -35,9 +35,10 @@ static double GetDeviceDpi() { TizenEmbedderEngine::TizenEmbedderEngine( const FlutterWindowProperties& window_properties) : device_profile(GetDeviceProfile()), device_dpi(GetDeviceDpi()) { - tizen_surface = std::make_unique( + tizen_native_window = std::make_unique( window_properties.x, window_properties.y, window_properties.width, window_properties.height); + tizen_surface = std::make_unique(tizen_native_window.get()); // Run flutter task on Tizen main loop. // Tizen engine has four threads (GPU thread, UI thread, IO thread, platform @@ -58,7 +59,7 @@ TizenEmbedderEngine::TizenEmbedderEngine( tizen_vsync_waiter_ = std::make_unique(); } -TizenEmbedderEngine::~TizenEmbedderEngine() {} +TizenEmbedderEngine::~TizenEmbedderEngine() { LoggerD("Destroy"); } // Attempts to load AOT data from the given path, which must be absolute and // non-empty. Logs and returns nullptr on failure. @@ -262,8 +263,9 @@ void TizenEmbedderEngine::SetWindowOrientation(int32_t degree) { // Compute renderer transformation based on the angle of rotation. double rad = (360 - degree) * M_PI / 180; - double width = tizen_surface->GetWidth(); - double height = tizen_surface->GetHeight(); + auto geometry = tizen_native_window->GetGeometry(); + double width = geometry.w; + double height = geometry.h; if (text_input_channel->isSoftwareKeyboardShowing()) { height -= text_input_channel->GetCurrentKeyboardGeometry().h; diff --git a/shell/platform/tizen/tizen_embedder_engine.h b/shell/platform/tizen/tizen_embedder_engine.h index 882d3072dbf7a..087da45b75369 100644 --- a/shell/platform/tizen/tizen_embedder_engine.h +++ b/shell/platform/tizen/tizen_embedder_engine.h @@ -95,6 +95,7 @@ class TizenEmbedderEngine { // The interface between the Flutter rasterizer and the platform. std::unique_ptr tizen_surface; + std::unique_ptr tizen_native_window; // The system channels for communicating between Flutter and the platform. std::unique_ptr key_event_channel; diff --git a/shell/platform/tizen/tizen_event_loop.cc b/shell/platform/tizen/tizen_event_loop.cc index 876818f05815d..e9f42f1c0a868 100644 --- a/shell/platform/tizen/tizen_event_loop.cc +++ b/shell/platform/tizen/tizen_event_loop.cc @@ -8,6 +8,8 @@ #include #include +#include "flutter/shell/platform/tizen/logger.h" + TizenEventLoop::TizenEventLoop(std::thread::id main_thread_id, TaskExpiredCallback on_task_expired) : main_thread_id_(main_thread_id), diff --git a/shell/platform/tizen/tizen_native_window.cc b/shell/platform/tizen/tizen_native_window.cc new file mode 100644 index 0000000000000..4d4d4c9ed78d1 --- /dev/null +++ b/shell/platform/tizen/tizen_native_window.cc @@ -0,0 +1,112 @@ +// 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 "tizen_native_window.h" + +#include "flutter/shell/platform/tizen/logger.h" + +class TizenWl2Display { + public: + TizenWl2Display() { + if (!ecore_wl2_init()) { + LoggerE("Could not initialize ecore_wl2"); + abort(); + return; + } + // ecore_wl2 DISPLAY + wl2_display_ = ecore_wl2_display_connect(nullptr); + if (wl2_display_ == nullptr) { + LoggerE("Display not found"); + abort(); + return; + } + ecore_wl2_sync(); + } + + ~TizenWl2Display() { + if (wl2_display_) { + ecore_wl2_display_destroy(wl2_display_); + wl2_display_ = nullptr; + } + ecore_wl2_shutdown(); + } + Ecore_Wl2_Display* GetHandle() { return wl2_display_; } + + private: + Ecore_Wl2_Display* wl2_display_{nullptr}; +}; +TizenWl2Display g_tizen_wl2_display; + +TizenNativeEGLWindow::TizenNativeEGLWindow( + TizenNativeWindow* tizen_native_window, int32_t w, int32_t h) { + egl_window_ = + ecore_wl2_egl_window_create(tizen_native_window->GetWindowHandle(), w, h); + + egl_display_ = eglGetDisplay((EGLNativeDisplayType)ecore_wl2_display_get( + g_tizen_wl2_display.GetHandle())); + if (egl_display_ == EGL_NO_DISPLAY) { + LoggerE("Could not access EGL display"); + return; + } + + EGLint majorVersion; + EGLint minorVersion; + if (eglInitialize(egl_display_, &majorVersion, &minorVersion) != EGL_TRUE) { + LoggerE("Could not initialize EGL display"); + return; + } + + if (eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { + LoggerE("Could not bind API"); + return; + } +} + +TizenNativeEGLWindow::~TizenNativeEGLWindow() { + if (egl_window_) { + ecore_wl2_egl_window_destroy(egl_window_); + egl_window_ = nullptr; + } + if (egl_display_ != EGL_NO_CONTEXT) { + eglTerminate(egl_display_); + } +} + +TizenNativeWindow::TizenNativeWindow(int32_t x, int32_t y, int32_t w, + int32_t h) { + if (g_tizen_wl2_display.GetHandle() == nullptr) { + LoggerE("Faild to get display handle"); + return; + } + if (w == 0 || h == 0) { + LoggerE("Failed to create because of the wrong size"); + return; + } + + wl2_window_ = ecore_wl2_window_new(g_tizen_wl2_display.GetHandle(), nullptr, + x, y, w, h); + + ecore_wl2_window_type_set(wl2_window_, ECORE_WL2_WINDOW_TYPE_TOPLEVEL); + ecore_wl2_window_alpha_set(wl2_window_, EINA_FALSE); + ecore_wl2_window_aux_hint_add(wl2_window_, 0, "wm.policy.win.user.geometry", + "1"); + ecore_wl2_window_show(wl2_window_); + + tizen_native_egl_window_ = std::make_unique(this, w, h); + isValid_ = true; +} + +TizenNativeWindow::~TizenNativeWindow() { + if (wl2_window_) { + ecore_wl2_window_free(wl2_window_); + wl2_window_ = nullptr; + } +} + +TizenNativeWindow::TizenNativeWindowGeometry TizenNativeWindow::GetGeometry() { + TizenNativeWindowGeometry result; + ecore_wl2_window_geometry_get(wl2_window_, &result.x, &result.y, &result.w, + &result.h); + return result; +} diff --git a/shell/platform/tizen/tizen_native_window.h b/shell/platform/tizen/tizen_native_window.h new file mode 100644 index 0000000000000..08c6c17f8d55a --- /dev/null +++ b/shell/platform/tizen/tizen_native_window.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_TIZEN_WINDOW_H_ +#define EMBEDDER_TIZEN_WINDOW_H_ +#include +#include +#define EFL_BETA_API_SUPPORT +#include + +#include +class TizenNativeWindow; + +class TizenNativeEGLWindow { + public: + TizenNativeEGLWindow(TizenNativeWindow* tizen_native_window, int32_t w, + int32_t h); + ~TizenNativeEGLWindow(); + bool IsValid() { + return egl_window_ != nullptr && egl_display_ != EGL_NO_DISPLAY; + }; + + Ecore_Wl2_Egl_Window* GetEglWindowHandle() { return egl_window_; }; + EGLDisplay GetEGLDisplayHandle() { return egl_display_; } + + private: + Ecore_Wl2_Egl_Window* egl_window_ = nullptr; + EGLDisplay egl_display_ = EGL_NO_DISPLAY; +}; + +class TizenNativeWindow { + public: + struct TizenNativeWindowGeometry { + int32_t x{0}, y{0}, w{0}, h{0}; + }; + + TizenNativeWindow(int32_t x, int32_t y, int32_t w, int32_t h); + ~TizenNativeWindow(); + bool IsValid() { return isValid_; } + Ecore_Wl2_Window* GetWindowHandle() { return wl2_window_; } + TizenNativeEGLWindow* GetTizenNativeEGLWindow() { + return tizen_native_egl_window_.get(); + }; + TizenNativeWindowGeometry GetGeometry(); + + private: + std::unique_ptr tizen_native_egl_window_; + Ecore_Wl2_Window* wl2_window_{nullptr}; + bool isValid_{false}; +}; + +#endif diff --git a/shell/platform/tizen/tizen_surface.cc b/shell/platform/tizen/tizen_surface.cc index 55926b3097c5d..62e0432825ab4 100644 --- a/shell/platform/tizen/tizen_surface.cc +++ b/shell/platform/tizen/tizen_surface.cc @@ -4,11 +4,4 @@ #include "tizen_surface.h" -TizenSurface::TizenSurface(int32_t x, int32_t y, int32_t width, int32_t height) - : window_width_(width), window_height_(height), x_(x), y_(y) {} - -TizenSurface::~TizenSurface() {} - -int32_t TizenSurface::GetWidth() { return window_width_; } - -int32_t TizenSurface::GetHeight() { return window_height_; } +TizenSurface::~TizenSurface() = default; diff --git a/shell/platform/tizen/tizen_surface.h b/shell/platform/tizen/tizen_surface.h index 29bf6a34d5320..267300dbc3ba6 100644 --- a/shell/platform/tizen/tizen_surface.h +++ b/shell/platform/tizen/tizen_surface.h @@ -9,7 +9,6 @@ class TizenSurface { public: - TizenSurface(int32_t x, int32_t y, int32_t width, int32_t height); virtual ~TizenSurface(); virtual bool OnMakeCurrent() = 0; virtual bool OnClearCurrent() = 0; @@ -19,14 +18,6 @@ class TizenSurface { virtual void* OnProcResolver(const char* name) = 0; virtual bool IsValid() = 0; virtual void SetSize(int32_t width, int32_t height) = 0; - int32_t GetWidth(); - int32_t GetHeight(); - - protected: - const int32_t window_width_; - const int32_t window_height_; - int32_t x_; - int32_t y_; }; #endif // EMBEDDER_TIZEN_SURFACE_H_ diff --git a/shell/platform/tizen/tizen_surface_gl.cc b/shell/platform/tizen/tizen_surface_gl.cc index 7e1769a3583a9..af223214110c8 100644 --- a/shell/platform/tizen/tizen_surface_gl.cc +++ b/shell/platform/tizen/tizen_surface_gl.cc @@ -9,22 +9,154 @@ #include "flutter/shell/platform/tizen/logger.h" -TizenSurfaceGL::TizenSurfaceGL(int32_t x, int32_t y, int32_t width, - int32_t height) - : TizenSurface(x, y, width, height) { - LoggerD("x =[%d] y = [%d], width = [%d], height = [%d]", x, y, width, height); - InitalizeDisplay(); +template +using EGLResult = std::pair; + +static EGLResult CreateContext(EGLDisplay display, EGLConfig config, + EGLContext share = EGL_NO_CONTEXT) { + EGLint attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + + EGLContext context = eglCreateContext(display, config, share, attributes); + + return {context != EGL_NO_CONTEXT, context}; +} + +static EGLResult ChooseEGLConfiguration(EGLDisplay display) { + EGLint attributes[] = { + // clang-format off + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 0, + EGL_NONE, // termination sentinel + // clang-format on + }; + + EGLint config_count = 0; + EGLConfig egl_config = nullptr; + + if (eglChooseConfig(display, attributes, &egl_config, 1, &config_count) != + EGL_TRUE) { + return {false, nullptr}; + } + + bool success = config_count > 0 && egl_config != nullptr; + + return {success, success ? egl_config : nullptr}; +} + +TizenEGLSurface::~TizenEGLSurface() { + eglDestroySurface(tizen_native_egl_window_->GetEGLDisplayHandle(), + egl_surface_); +} + +TizenEGLContext::TizenEGLContext(TizenNativeEGLWindow* tizen_native_egl_window) + : tizen_native_egl_window_(tizen_native_egl_window) { + EGLDisplay egl_display = tizen_native_egl_window_->GetEGLDisplayHandle(); + auto config = ChooseEGLConfiguration(egl_display); + if (!config.first) { + LoggerE("Failed to ChooseEGLConfiguration"); + return; + } + egl_config_ = config.second; + + auto ctx = CreateContext(egl_display, egl_config_, EGL_NO_CONTEXT); + if (!ctx.first) { + LoggerE("Failed to create egl context"); + return; + } + egl_context_ = ctx.second; + + auto resource_ctx = CreateContext(egl_display, egl_config_, egl_context_); + if (!resource_ctx.first) { + LoggerE("Failed to create egl resource context"); + return; + } + egl_resource_context_ = resource_ctx.second; +} + +std::unique_ptr +TizenEGLContext::CreateTizenEGLWindowSurface() { + const EGLint attribs[] = {EGL_NONE}; + EGLSurface surface = eglCreateWindowSurface( + tizen_native_egl_window_->GetEGLDisplayHandle(), egl_config_, + ecore_wl2_egl_window_native_get( + tizen_native_egl_window_->GetEglWindowHandle()), + attribs); + + return std::make_unique(tizen_native_egl_window_, surface); +} + +TizenEGLContext::~TizenEGLContext() { + if (eglDestroyContext(tizen_native_egl_window_->GetEGLDisplayHandle(), + egl_context_) != EGL_TRUE) { + LoggerE("Failed to destroy egl context"); + } + if (eglDestroyContext(tizen_native_egl_window_->GetEGLDisplayHandle(), + egl_resource_context_) != EGL_TRUE) { + LoggerE("Failed to destroy egl resource context"); + } +} + +std::unique_ptr +TizenEGLContext::CreateTizenEGLPbufferSurface() { + const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; + EGLSurface surface = eglCreatePbufferSurface( + tizen_native_egl_window_->GetEGLDisplayHandle(), egl_config_, attribs); + + return std::make_unique(tizen_native_egl_window_, surface); +} + +bool TizenEGLContext::IsValid() { + return tizen_native_egl_window_ && tizen_native_egl_window_->IsValid() && + egl_config_ != nullptr && egl_context_ != EGL_NO_CONTEXT && + egl_resource_context_ != EGL_NO_CONTEXT; } -bool TizenSurfaceGL::IsValid() { return display_valid_; } +TizenSurfaceGL::TizenSurfaceGL(TizenNativeWindow* tizen_native_window) + : tizen_native_window_(tizen_native_window) { + if (!tizen_native_window_->IsValid()) { + LoggerE("Invalid native window"); + return; + } + + tizen_context_gl_ = std::make_unique( + tizen_native_window_->GetTizenNativeEGLWindow()); + if (!tizen_context_gl_->IsValid()) { + LoggerE("Invalid context gl"); + return; + } + + tizen_egl_window_surface_ = tizen_context_gl_->CreateTizenEGLWindowSurface(); + if (!tizen_egl_window_surface_->IsValid()) { + LoggerE("Invalid egl window surface"); + return; + } + + tizen_egl_pbuffer_surface_ = + tizen_context_gl_->CreateTizenEGLPbufferSurface(); + if (!tizen_egl_pbuffer_surface_->IsValid()) { + LoggerE("Invalid egl puffer surface"); + return; + } + + isValid_ = true; +} bool TizenSurfaceGL::OnMakeCurrent() { - if (!display_valid_) { - LoggerE("Invalid Display"); + if (!isValid_) { + LoggerE("Invalid TizenSurfaceGL"); return false; } - if (eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_) != - EGL_TRUE) { + if (eglMakeCurrent(tizen_native_window_->GetTizenNativeEGLWindow() + ->GetEGLDisplayHandle(), + tizen_egl_window_surface_->GetEGLSurfaceHandle(), + tizen_egl_window_surface_->GetEGLSurfaceHandle(), + tizen_context_gl_->GetEGLContextHandle()) != EGL_TRUE) { LoggerE("Could not make the onscreen context current"); return false; } @@ -32,12 +164,16 @@ bool TizenSurfaceGL::OnMakeCurrent() { } bool TizenSurfaceGL::OnMakeResourceCurrent() { - if (!display_valid_) { - LoggerE("Invalid Display"); + if (!isValid_) { + LoggerE("Invalid TizenSurfaceGL"); return false; } - if (eglMakeCurrent(egl_display_, egl_resource_surface_, egl_resource_surface_, - egl_resource_context_) != EGL_TRUE) { + if (eglMakeCurrent(tizen_native_window_->GetTizenNativeEGLWindow() + ->GetEGLDisplayHandle(), + tizen_egl_pbuffer_surface_->GetEGLSurfaceHandle(), + tizen_egl_pbuffer_surface_->GetEGLSurfaceHandle(), + tizen_context_gl_->GetEGLResourceContextHandle()) != + EGL_TRUE) { LoggerE("Could not make the offscreen context current"); return false; } @@ -45,12 +181,14 @@ bool TizenSurfaceGL::OnMakeResourceCurrent() { } bool TizenSurfaceGL::OnClearCurrent() { - if (!display_valid_) { - LoggerE("Invalid display"); + if (!isValid_) { + LoggerE("Invalid TizenSurfaceGL"); return false; } - if (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, + if (eglMakeCurrent(tizen_native_window_->GetTizenNativeEGLWindow() + ->GetEGLDisplayHandle(), + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { LoggerE("Could not clear context"); return false; @@ -59,12 +197,15 @@ bool TizenSurfaceGL::OnClearCurrent() { } bool TizenSurfaceGL::OnPresent() { - if (!display_valid_) { - LoggerE("Invalid display"); + if (!isValid_) { + LoggerE("Invalid TizenSurfaceGL"); return false; } - if (eglSwapBuffers(egl_display_, egl_surface_) != EGL_TRUE) { + if (eglSwapBuffers(tizen_native_window_->GetTizenNativeEGLWindow() + ->GetEGLDisplayHandle(), + tizen_egl_window_surface_->GetEGLSurfaceHandle()) != + EGL_TRUE) { LoggerE("Could not swap EGl buffer"); return false; } @@ -72,307 +213,39 @@ bool TizenSurfaceGL::OnPresent() { } uint32_t TizenSurfaceGL::OnGetFBO() { - if (!display_valid_) { - LoggerE("Invalid display"); + if (!isValid_) { + LoggerE("Invalid TizenSurfaceGL"); return 999; } LoggerD("OnApplicationGetOnscreenFBO"); return 0; // FBO0 } -#define GL_FUNC(FunctionName) \ - else if (strcmp(name, #FunctionName) == 0) { \ - return reinterpret_cast(FunctionName); \ - } void* TizenSurfaceGL::OnProcResolver(const char* name) { auto address = eglGetProcAddress(name); if (address != nullptr) { return reinterpret_cast(address); } - GL_FUNC(eglGetCurrentDisplay) - GL_FUNC(eglQueryString) - GL_FUNC(glActiveTexture) - GL_FUNC(glAttachShader) - GL_FUNC(glBindAttribLocation) - GL_FUNC(glBindBuffer) - GL_FUNC(glBindFramebuffer) - GL_FUNC(glBindRenderbuffer) - GL_FUNC(glBindTexture) - GL_FUNC(glBlendColor) - GL_FUNC(glBlendEquation) - GL_FUNC(glBlendFunc) - GL_FUNC(glBufferData) - GL_FUNC(glBufferSubData) - GL_FUNC(glCheckFramebufferStatus) - GL_FUNC(glClear) - GL_FUNC(glClearColor) - GL_FUNC(glClearStencil) - GL_FUNC(glColorMask) - GL_FUNC(glCompileShader) - GL_FUNC(glCompressedTexImage2D) - GL_FUNC(glCompressedTexSubImage2D) - GL_FUNC(glCopyTexSubImage2D) - GL_FUNC(glCreateProgram) - GL_FUNC(glCreateShader) - GL_FUNC(glCullFace) - GL_FUNC(glDeleteBuffers) - GL_FUNC(glDeleteFramebuffers) - GL_FUNC(glDeleteProgram) - GL_FUNC(glDeleteRenderbuffers) - GL_FUNC(glDeleteShader) - GL_FUNC(glDeleteTextures) - GL_FUNC(glDepthMask) - GL_FUNC(glDisable) - GL_FUNC(glDisableVertexAttribArray) - GL_FUNC(glDrawArrays) - GL_FUNC(glDrawElements) - GL_FUNC(glEnable) - GL_FUNC(glEnableVertexAttribArray) - GL_FUNC(glFinish) - GL_FUNC(glFlush) - GL_FUNC(glFramebufferRenderbuffer) - GL_FUNC(glFramebufferTexture2D) - GL_FUNC(glFrontFace) - GL_FUNC(glGenBuffers) - GL_FUNC(glGenerateMipmap) - GL_FUNC(glGenFramebuffers) - GL_FUNC(glGenRenderbuffers) - GL_FUNC(glGenTextures) - GL_FUNC(glGetBufferParameteriv) - GL_FUNC(glGetError) - GL_FUNC(glGetFramebufferAttachmentParameteriv) - GL_FUNC(glGetIntegerv) - GL_FUNC(glGetProgramInfoLog) - GL_FUNC(glGetProgramiv) - GL_FUNC(glGetRenderbufferParameteriv) - GL_FUNC(glGetShaderInfoLog) - GL_FUNC(glGetShaderiv) - GL_FUNC(glGetShaderPrecisionFormat) - GL_FUNC(glGetString) - GL_FUNC(glGetUniformLocation) - GL_FUNC(glIsTexture) - GL_FUNC(glLineWidth) - GL_FUNC(glLinkProgram) - GL_FUNC(glPixelStorei) - GL_FUNC(glReadPixels) - GL_FUNC(glRenderbufferStorage) - GL_FUNC(glScissor) - GL_FUNC(glShaderSource) - GL_FUNC(glStencilFunc) - GL_FUNC(glStencilFuncSeparate) - GL_FUNC(glStencilMask) - GL_FUNC(glStencilMaskSeparate) - GL_FUNC(glStencilOp) - GL_FUNC(glStencilOpSeparate) - GL_FUNC(glTexImage2D) - GL_FUNC(glTexParameterf) - GL_FUNC(glTexParameterfv) - GL_FUNC(glTexParameteri) - GL_FUNC(glTexParameteriv) - GL_FUNC(glTexSubImage2D) - GL_FUNC(glUniform1f) - GL_FUNC(glUniform1fv) - GL_FUNC(glUniform1i) - GL_FUNC(glUniform1iv) - GL_FUNC(glUniform2f) - GL_FUNC(glUniform2fv) - GL_FUNC(glUniform2i) - GL_FUNC(glUniform2iv) - GL_FUNC(glUniform3f) - GL_FUNC(glUniform3fv) - GL_FUNC(glUniform3i) - GL_FUNC(glUniform3iv) - GL_FUNC(glUniform4f) - GL_FUNC(glUniform4fv) - GL_FUNC(glUniform4i) - GL_FUNC(glUniform4iv) - GL_FUNC(glUniformMatrix2fv) - GL_FUNC(glUniformMatrix3fv) - GL_FUNC(glUniformMatrix4fv) - GL_FUNC(glUseProgram) - GL_FUNC(glVertexAttrib1f) - GL_FUNC(glVertexAttrib2fv) - GL_FUNC(glVertexAttrib3fv) - GL_FUNC(glVertexAttrib4fv) - GL_FUNC(glVertexAttribPointer) - GL_FUNC(glViewport) +// FIXME +#include "flutter/shell/platform/tizen/proc_resolver_macro.h" LoggerW("Could not resolve: %s", name); return nullptr; } -#undef GL_FUNC TizenSurfaceGL::~TizenSurfaceGL() { if (IsValid()) { - display_valid_ = false; + isValid_ = false; Destroy(); } } -bool TizenSurfaceGL::InitalizeDisplay() { - LoggerD("x =[%d] y = [%d], width = [%d], height = [%d]", x_, y_, - window_width_, window_height_); - if (window_width_ == 0 || window_height_ == 0) { - return false; - } - - // ecore_wl2 INIT - if (!ecore_wl2_init()) { - LoggerE("Could not initialize ecore_wl2"); - return false; - } - - // ecore_wl2 DISPLAY - wl2_display_ = ecore_wl2_display_connect(nullptr); - if (nullptr == wl2_display_) { - LoggerE("Display not found"); - return false; - } - LoggerD("wl2_display_: %p", wl2_display_); - ecore_wl2_sync(); - - // ecore_wl2 WINDOW - wl2_window_ = ecore_wl2_window_new(wl2_display_, nullptr, x_, y_, - window_width_, window_height_); - LoggerD("wl2_window_: %p", wl2_window_); - - ecore_wl2_window_type_set(wl2_window_, ECORE_WL2_WINDOW_TYPE_TOPLEVEL); - ecore_wl2_window_alpha_set(wl2_window_, EINA_FALSE); - // ecore_wl2_sync(); - - // ecore_wl2 SHOW - ecore_wl2_window_show(wl2_window_); - - ecore_wl2_window_aux_hint_add(wl2_window_, 0, "wm.policy.win.user.geometry", - "1"); - ecore_wl2_window_position_set(wl2_window_, x_, y_); - ecore_wl2_window_geometry_set(wl2_window_, x_, y_, window_width_, - window_height_); - - // egl WINDOW - egl_window_ = - ecore_wl2_egl_window_create(wl2_window_, window_width_, window_height_); - LoggerD("egl_window_: %p", egl_window_); - - if (!egl_window_) { - LoggerE("Could not create EGL window"); - return false; - } - - // egl DISPLAY - egl_display_ = - eglGetDisplay((EGLNativeDisplayType)ecore_wl2_display_get(wl2_display_)); - if (egl_display_ == EGL_NO_DISPLAY) { - LoggerE("Could not access EGL display"); - return false; - } - LoggerD("egl_display_: %p", egl_display_); - - // egl INTIALIZE - EGLint majorVersion; - EGLint minorVersion; - if (eglInitialize(egl_display_, &majorVersion, &minorVersion) != EGL_TRUE) { - LoggerE("Could not initialize EGL display"); - return false; - } - LoggerD("eglInitialized: %d.%d", majorVersion, minorVersion); - - // egl BINDAPI - if (eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { - LoggerE("Could not bind API"); - return false; - } - - // egl CONFIG - EGLint config_count; - eglGetConfigs(egl_display_, NULL, 0, &config_count); - LoggerD("config_count: %d", config_count); - - EGLConfig egl_config = nullptr; - - { - EGLint attribs[] = { - // clang-format off - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 0, - EGL_STENCIL_SIZE, 0, - EGL_NONE, // termination sentinel - // clang-format on - }; - - if (eglChooseConfig(egl_display_, attribs, &egl_config, 1, &config_count) != - EGL_TRUE) { - LoggerE("Error when attempting to choose an EGL surface config"); - return false; - } - - if (config_count == 0 || egl_config == nullptr) { - LoggerE("No matching config"); - return false; - } - } - - // egl CONTEXT - const EGLint attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - - egl_context_ = eglCreateContext(egl_display_, egl_config, nullptr, attribs); - if (egl_context_ == EGL_NO_CONTEXT) { - LoggerE("Could not create an onscreen context"); - return false; - } - - egl_resource_context_ = - eglCreateContext(egl_display_, egl_config, EGL_NO_CONTEXT, attribs); - if (egl_resource_context_ == EGL_NO_CONTEXT) { - LoggerE("Could not create an resource context"); - return false; - } - - // egl SURFACE - { - egl_surface_ = eglCreateWindowSurface( - egl_display_, egl_config, ecore_wl2_egl_window_native_get(egl_window_), - nullptr); - - if (egl_surface_ == EGL_NO_SURFACE) { - return false; - } - - const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; - egl_resource_surface_ = - eglCreatePbufferSurface(egl_display_, egl_config, attribs); - if (egl_resource_surface_ == EGL_NO_SURFACE) { - return false; - } - } - LoggerD("egl_surface_: %p", egl_surface_); - display_valid_ = true; - return true; -} - -void TizenSurfaceGL::Destroy() { - if (egl_window_) { - ecore_wl2_egl_window_destroy(egl_window_); - egl_window_ = nullptr; - } - if (wl2_window_) { - ecore_wl2_window_free(wl2_window_); - wl2_window_ = nullptr; - } - if (wl2_display_) { - ecore_wl2_display_destroy(wl2_display_); - wl2_display_ = nullptr; - } - ecore_wl2_shutdown(); -} +void TizenSurfaceGL::Destroy() { LoggerE("Destroy"); } void TizenSurfaceGL::SetSize(int32_t width, int32_t height) { + // FIXME : I think we have to find another way. LoggerD("Resize egl window %d %d", width, height); - ecore_wl2_egl_window_resize_with_rotation(egl_window_, 0, 0, width, height, - 0); + ecore_wl2_egl_window_resize_with_rotation( + tizen_native_window_->GetTizenNativeEGLWindow()->GetEglWindowHandle(), 0, + 0, width, height, 0); } diff --git a/shell/platform/tizen/tizen_surface_gl.h b/shell/platform/tizen/tizen_surface_gl.h index 257512753901c..a610ce075210e 100644 --- a/shell/platform/tizen/tizen_surface_gl.h +++ b/shell/platform/tizen/tizen_surface_gl.h @@ -18,34 +18,62 @@ #include #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/tizen_native_window.h" #include "flutter/shell/platform/tizen/tizen_surface.h" +class TizenEGLSurface { + public: + TizenEGLSurface(TizenNativeEGLWindow* tizen_native_egl_window, + EGLSurface egl_surface) + : tizen_native_egl_window_(tizen_native_egl_window), + egl_surface_(egl_surface){}; + ~TizenEGLSurface(); + bool IsValid() { return egl_surface_ != EGL_NO_SURFACE; } + EGLSurface GetEGLSurfaceHandle() { return egl_surface_; }; + + private: + TizenNativeEGLWindow* tizen_native_egl_window_; + EGLSurface egl_surface_{EGL_NO_SURFACE}; +}; + +class TizenEGLContext { + public: + TizenEGLContext(TizenNativeEGLWindow* tizen_native_egl_window); + ~TizenEGLContext(); + bool IsValid(); + std::unique_ptr CreateTizenEGLWindowSurface(); + std::unique_ptr CreateTizenEGLPbufferSurface(); + EGLContext GetEGLContextHandle() { return egl_context_; } + EGLContext GetEGLResourceContextHandle() { return egl_resource_context_; } + + public: + TizenNativeEGLWindow* tizen_native_egl_window_; + EGLConfig egl_config_{nullptr}; + EGLContext egl_context_{EGL_NO_CONTEXT}; + EGLContext egl_resource_context_{EGL_NO_CONTEXT}; +}; + class TizenSurfaceGL : public TizenSurface { public: - TizenSurfaceGL(int32_t x, int32_t y, int32_t width, int32_t height); + TizenSurfaceGL(TizenNativeWindow* tizen_native_window); ~TizenSurfaceGL(); - bool OnMakeCurrent(); - bool OnClearCurrent(); - bool OnMakeResourceCurrent(); - bool OnPresent(); - uint32_t OnGetFBO(); - void* OnProcResolver(const char* name); - bool IsValid(); - bool InitalizeDisplay(); + bool OnMakeCurrent() override; + bool OnClearCurrent() override; + bool OnMakeResourceCurrent() override; + bool OnPresent() override; + uint32_t OnGetFBO() override; + void* OnProcResolver(const char* name) override; + bool IsValid() override { return isValid_; }; + void SetSize(int32_t width, int32_t height) override; + void Destroy(); - void SetSize(int32_t width, int32_t height); - Ecore_Wl2_Window* wl2_window() { return wl2_window_; } private: - bool display_valid_ = false; - EGLDisplay egl_display_ = EGL_NO_DISPLAY; - EGLSurface egl_surface_ = EGL_NO_SURFACE; - EGLSurface egl_resource_surface_ = EGL_NO_SURFACE; - EGLContext egl_context_ = EGL_NO_CONTEXT; - EGLContext egl_resource_context_ = EGL_NO_CONTEXT; - Ecore_Wl2_Egl_Window* egl_window_ = nullptr; - Ecore_Wl2_Display* wl2_display_ = nullptr; - Ecore_Wl2_Window* wl2_window_ = nullptr; + bool isValid_{false}; + TizenNativeWindow* tizen_native_window_; + std::unique_ptr tizen_context_gl_; + std::unique_ptr tizen_egl_window_surface_; + std::unique_ptr tizen_egl_pbuffer_surface_; }; #endif // EMBEDDER_TIZEN_SURFACE_GL_H_ diff --git a/shell/platform/tizen/touch_event_handler.cc b/shell/platform/tizen/touch_event_handler.cc index 5ea8f713ef459..46e7fb0869944 100644 --- a/shell/platform/tizen/touch_event_handler.cc +++ b/shell/platform/tizen/touch_event_handler.cc @@ -41,8 +41,9 @@ void TouchEventHandler::SendFlutterPointerEvent(FlutterPointerPhase phase, } // Correct errors caused by window rotation. - double width = engine_->tizen_surface->GetWidth(); - double height = engine_->tizen_surface->GetHeight(); + auto window_geometry = engine_->tizen_native_window->GetGeometry(); + double width = window_geometry.w; + double height = window_geometry.h; double new_x = x, new_y = y; if (rotation == 90) { new_x = height - y;