diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b8ed161045e70..8e8e683d1acf5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -68,39 +68,21 @@ jobs: --runtime-mode $(mode) \ --embedder-for-target \ --disable-desktop-embeddings \ - --build-tizen-shell \ - --out-dir output/default - ninja -C output/default/out/linux_$(mode)_$(arch) + --build-tizen-shell + ninja -C out/linux_$(mode)_$(arch) displayName: Build workingDirectory: $(buildroot) failOnStderr: true - - bash: | - flutter/tools/gn \ - --target-os linux \ - --linux-cpu $(arch) \ - --target-toolchain `pwd`/tizen_tools/toolchains \ - --target-sysroot `pwd`/tizen_tools/sysroot/$(arch)_40 \ - --target-triple $(targetTriple) \ - --runtime-mode $(mode) \ - --embedder-for-target \ - --disable-desktop-embeddings \ - --build-tizen-shell \ - --tizen-sdk-4 \ - --out-dir output/tizen40 - ninja -C output/tizen40/out/linux_$(mode)_$(arch) - displayName: Build for Tizen 4.0 - workingDirectory: $(buildroot) - condition: ne(variables['arch'], 'arm64') - failOnStderr: true - bash: | OUTDIR=$(Build.StagingDirectory) - cp default/out/linux_$(mode)_$(arch)/libflutter_engine.so $OUTDIR - cp default/out/linux_$(mode)_$(arch)/libflutter_tizen.so $OUTDIR - if [[ "$(arch)" != "arm64" ]]; then - cp tizen40/out/linux_$(mode)_$(arch)/libflutter_tizen.so $OUTDIR/libflutter_tizen40.so + cp out/linux_$(mode)_$(arch)/libflutter_*.so $OUTDIR + if [[ $(System.JobName) == "tizen-arm-release" ]]; then + mkdir $OUTDIR/common + cp -r out/linux_$(mode)_$(arch)/{cpp_client_wrapper,icu,public} $OUTDIR/common + rm $OUTDIR/common/cpp_client_wrapper/engine_method_result.cc fi displayName: Copy artifacts - workingDirectory: $(buildroot)/output + workingDirectory: $(buildroot) failOnStderr: true - publish: $(Build.StagingDirectory) artifact: $(System.JobName) @@ -119,19 +101,7 @@ jobs: path: src/flutter - download: current - bash: | - mkdir -p common/client_wrapper - ROOT=$(Pipeline.Workspace)/src/flutter/shell/platform - cp $ROOT/common/cpp/client_wrapper/*.{h,cc} common/client_wrapper - rm common/client_wrapper/{*_unittests.*,engine_method_result.cc} - cp -r $ROOT/common/cpp/public common - cp -r $ROOT/common/cpp/client_wrapper/include common/client_wrapper - cp $ROOT/tizen/public/*.h common/public - cp $ROOT/tizen/LICENSE . - displayName: Copy headers - workingDirectory: $(Build.BinariesDirectory) - failOnStderr: true - - bash: | - cp $(Pipeline.Workspace)/src/third_party/icu/flutter/icudtl.dat common + mv $(Pipeline.Workspace)/tizen-arm-release/common . mv $(Pipeline.Workspace)/tizen-* . for platform in linux windows darwin; do for arch in arm arm64; do diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 5cdac760a2ac3..1ea9bcf30bb00 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -1,73 +1,39 @@ # Copyright 2020 Samsung Electronics Co., Ltd. All rights reserved. -# Copyright 2013 The Flutter Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//flutter/shell/platform/tizen/config.gni") - -group("tizen") { - deps = [ ":flutter_tizen_library" ] -} -shared_library("flutter_tizen_library") { - output_name = "flutter_tizen" +import("//flutter/shell/platform/common/cpp/client_wrapper/publish.gni") +import("//flutter/shell/platform/tizen/config.gni") +# Sets the rpath of dependent targets (shared libs) to $ORIGIN. +# We assume that the flutter_engine library exists next to the embedder library +# when they are deployed on Tizen devices. +config("tizen_embedder_rpath") { ldflags = [ "-Wl,-rpath,\$ORIGIN" ] - - deps = [ ":flutter_tizen" ] - - public_configs = [ "//flutter:config" ] } -source_set("flutter_tizen_headers") { - public = [ - "public/flutter_platform_view.h", - "public/flutter_tizen_texture_registrar.h", - "public/flutter_tizen.h", - ] +source_set("flutter_engine") { + visibility = [ ":*" ] - public_deps = - [ "//flutter/shell/platform/common/cpp:common_cpp_library_headers" ] + libs = [ "flutter_engine" ] - configs += - [ "//flutter/shell/platform/common/cpp:desktop_library_implementation" ] + lib_dirs = [ root_out_dir ] - public_configs = - [ "//flutter/shell/platform/common/cpp:relative_flutter_library_headers" ] -} - -source_set("flutter_tizen") { - sources = [ - "channels/key_event_channel.cc", - "channels/lifecycle_channel.cc", - "channels/localization_channel.cc", - "channels/navigation_channel.cc", - "channels/platform_channel.cc", - "channels/platform_view_channel.cc", - "channels/settings_channel.cc", - "channels/text_input_channel.cc", - "external_texture_gl.cc", - "flutter_tizen.cc", - "key_event_handler.cc", - "tizen_embedder_engine.cc", - "tizen_event_loop.cc", - "tizen_log.cc", - "tizen_renderer.cc", - "tizen_vsync_waiter.cc", - "touch_event_handler.cc", - ] + public_configs = [ ":tizen_embedder_rpath" ] - configs += - [ "//flutter/shell/platform/common/cpp:desktop_library_implementation" ] + deps = [ "//flutter/shell/platform/embedder:flutter_engine" ] +} - deps = [ - ":flutter_tizen_headers", - "//flutter/shell/platform/common/cpp:common_cpp", - "//flutter/shell/platform/common/cpp:common_cpp_input", - "//flutter/shell/platform/common/cpp/client_wrapper:client_wrapper", - "//flutter/shell/platform/embedder:flutter_engine", - "//third_party/rapidjson", - ] +_public_headers = [ + "public/flutter_platform_view.h", + "public/flutter_tizen_texture_registrar.h", + "public/flutter_tizen.h", +] +# Tizen native headers assume that the following include dirs are already +# added to the compiler's search paths. Since we are not using the Tizen CLI +# builder, we have to add them manually. +config("tizen_rootstrap_include_dirs") { include_dirs = [ "$custom_sysroot/usr/include", "$custom_sysroot/usr/include/appfw", @@ -87,41 +53,169 @@ source_set("flutter_tizen") { "$custom_sysroot/usr/include/eo-1", "$custom_sysroot/usr/include/evas-1", "$custom_sysroot/usr/include/system", - "$custom_sysroot/usr/include/wayland-extension" + "$custom_sysroot/usr/include/wayland-extension", + # For Evas_GL. + "$custom_sysroot/usr/include/ecore-con-1", + "$custom_sysroot/usr/include/ecore-file-1", + "$custom_sysroot/usr/include/edje-1", + "$custom_sysroot/usr/include/eet-1", + "$custom_sysroot/usr/include/efl-1/interfaces", + "$custom_sysroot/usr/include/efreet-1", + "$custom_sysroot/usr/include/elementary-1", + "$custom_sysroot/usr/include/ethumb-1", + "$custom_sysroot/usr/include/ethumb-client-1", ] - - lib_dirs = [ root_out_dir, "$custom_sysroot/usr/lib" ] - cflags_cc = [ - "-Wno-newline-eof", - "-Wno-macro-redefined", - ] + lib_dirs = [ "$custom_sysroot/usr/lib" ] +} - libs = [ - "base-utils-i18n", - "capi-appfw-application", - "capi-system-info", - "capi-system-system-settings", - "dlog", - "ecore", - "ecore_imf", - "ecore_input", - "eina", - "EGL", - "evas", - "flutter_engine", - "GLESv2", - "tbm", - "tdm-client", - "wayland-client", - ] +# Template for the embedder build. Used to generate embedders for different +# device profiles. The output library name is "flutter_tizen_[profile]". +# +# If use_evas_gl_renderer is provided as true, the Evas_GL renderer is used, +# otherwise the Ecore_Wl2 renderer is used. +template("embedder_for_profile") { + forward_variables_from(invoker, [ "use_evas_gl_renderer" ]) - if (tizen_sdk_4) { - sources += [ "tizen_renderer_ecore_wl.cc" ] - libs += [ "ecore_wayland", "wayland-egl" ] - defines = [ "FLUTTER_TIZEN_4" ] - } else { - sources += [ "tizen_renderer_ecore_wl2.cc" ] - libs += [ "ecore_wl2" ] + if (!defined(use_evas_gl_renderer)) { + use_evas_gl_renderer = false } + + shared_library("flutter_tizen_${target_name}") { + public = _public_headers + + sources = [ + "channels/key_event_channel.cc", + "channels/lifecycle_channel.cc", + "channels/localization_channel.cc", + "channels/navigation_channel.cc", + "channels/platform_channel.cc", + "channels/platform_view_channel.cc", + "channels/settings_channel.cc", + "channels/text_input_channel.cc", + "external_texture_gl.cc", + "flutter_tizen.cc", + "key_event_handler.cc", + "tizen_embedder_engine.cc", + "tizen_event_loop.cc", + "tizen_log.cc", + "tizen_renderer.cc", + "touch_event_handler.cc", + ] + + libs = [ + "base-utils-i18n", + "capi-appfw-application", + "capi-system-info", + "capi-system-system-settings", + "dlog", + "ecore", + "ecore_imf", + "ecore_input", + "eina", + "evas", + "EGL", + "GLESv2", + "tbm", + "tdm-client", + "wayland-client", + ] + + defines = invoker.defines + + if (use_evas_gl_renderer) { + sources += [ "tizen_renderer_evas_gl.cc" ] + + libs += [ + "ecore_evas", + "elementary", + ] + + defines += [ "TIZEN_RENDERER_EVAS_GL" ] + } else { + sources += [ + "tizen_renderer_ecore_wl2.cc", + "tizen_vsync_waiter.cc", + ] + + libs += [ "ecore_wl2" ] + } + + cflags_cc = [ + "-Wno-newline-eof", + "-Wno-macro-redefined", + ] + + configs += [ + ":tizen_rootstrap_include_dirs", + "//flutter/shell/platform/common/cpp:desktop_library_implementation" + ] + + public_configs = [ "//flutter:config" ] + + public_deps = [ ":flutter_engine" ] + + deps = [ + "//flutter/shell/platform/common/cpp:common_cpp", + "//flutter/shell/platform/common/cpp:common_cpp_input", + "//flutter/shell/platform/common/cpp:common_cpp_library_headers", + "//flutter/shell/platform/common/cpp/client_wrapper:client_wrapper", + "//third_party/rapidjson", + ] + } +} + +embedder_for_profile("mobile") { + defines = [ "MOBILE_PROFILE" ] +} + +embedder_for_profile("wearable") { + defines = [ "WEARABLE_PROFILE" ] + + use_evas_gl_renderer = true +} + +embedder_for_profile("tv") { + defines = [ "TV_PROFILE" ] +} + +embedder_for_profile("common") { + defines = [ "COMMON_PROFILE" ] +} + +publish_client_wrapper_core("publish_cpp_client_wrapper") { + visibility = [ ":*" ] +} + +_common_cpp_public_headers = [ + "//flutter/shell/platform/common/cpp/public/flutter_export.h", + "//flutter/shell/platform/common/cpp/public/flutter_messenger.h", + "//flutter/shell/platform/common/cpp/public/flutter_plugin_registrar.h", + "//flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h", +] + +copy("publish_headers_tizen") { + sources = _public_headers + _common_cpp_public_headers + + outputs = [ "$root_out_dir/public/{{source_file_part}}" ] +} + +copy("copy_icu") { + visibility = [ ":*" ] + + sources = [ "//third_party/icu/flutter/icudtl.dat" ] + + outputs = [ "$root_out_dir/icu/{{source_file_part}}" ] +} + +group("tizen") { + deps = [ + ":flutter_tizen_mobile", + ":flutter_tizen_wearable", + ":flutter_tizen_tv", + ":flutter_tizen_common", + ":publish_cpp_client_wrapper", + ":publish_headers_tizen", + ":copy_icu", + ] } diff --git a/shell/platform/tizen/channels/text_input_channel.cc b/shell/platform/tizen/channels/text_input_channel.cc index 5692ba3726356..663722b184a4e 100644 --- a/shell/platform/tizen/channels/text_input_channel.cc +++ b/shell/platform/tizen/channels/text_input_channel.cc @@ -202,61 +202,6 @@ Ecore_IMF_Keyboard_Locks EcoreInputModifierToEcoreIMFLock( return static_cast(lock); } -Ecore_IMF_Device_Class EoreDeviceClassToEcoreIMFDeviceClass( - Ecore_Device_Class ecoreDeviceClass) { - switch (ecoreDeviceClass) { - case ECORE_DEVICE_CLASS_SEAT: - return ECORE_IMF_DEVICE_CLASS_SEAT; - case ECORE_DEVICE_CLASS_KEYBOARD: - return ECORE_IMF_DEVICE_CLASS_KEYBOARD; - case ECORE_DEVICE_CLASS_MOUSE: - return ECORE_IMF_DEVICE_CLASS_MOUSE; - case ECORE_DEVICE_CLASS_TOUCH: - return ECORE_IMF_DEVICE_CLASS_TOUCH; - case ECORE_DEVICE_CLASS_PEN: - return ECORE_IMF_DEVICE_CLASS_PEN; - case ECORE_DEVICE_CLASS_POINTER: - return ECORE_IMF_DEVICE_CLASS_POINTER; - case ECORE_DEVICE_CLASS_GAMEPAD: - return ECORE_IMF_DEVICE_CLASS_GAMEPAD; - case ECORE_DEVICE_CLASS_NONE: - default: - return ECORE_IMF_DEVICE_CLASS_NONE; - } -} - -Ecore_IMF_Device_Subclass EoreDeviceSubClassToEcoreIMFDeviceSubClass( - Ecore_Device_Subclass ecoreDeviceSubclass) { - switch (ecoreDeviceSubclass) { - case ECORE_DEVICE_SUBCLASS_FINGER: - return ECORE_IMF_DEVICE_SUBCLASS_FINGER; - case ECORE_DEVICE_SUBCLASS_FINGERNAIL: - return ECORE_IMF_DEVICE_SUBCLASS_FINGERNAIL; - case ECORE_DEVICE_SUBCLASS_KNUCKLE: - return ECORE_IMF_DEVICE_SUBCLASS_KNUCKLE; - case ECORE_DEVICE_SUBCLASS_PALM: - return ECORE_IMF_DEVICE_SUBCLASS_PALM; - case ECORE_DEVICE_SUBCLASS_HAND_SIZE: - return ECORE_IMF_DEVICE_SUBCLASS_HAND_SIZE; - case ECORE_DEVICE_SUBCLASS_HAND_FLAT: - return ECORE_IMF_DEVICE_SUBCLASS_HAND_FLAT; - case ECORE_DEVICE_SUBCLASS_PEN_TIP: - return ECORE_IMF_DEVICE_SUBCLASS_PEN_TIP; - case ECORE_DEVICE_SUBCLASS_TRACKPAD: - return ECORE_IMF_DEVICE_SUBCLASS_TRACKPAD; - case ECORE_DEVICE_SUBCLASS_TRACKPOINT: - return ECORE_IMF_DEVICE_SUBCLASS_TRACKPOINT; - case ECORE_DEVICE_SUBCLASS_TRACKBALL: - return ECORE_IMF_DEVICE_SUBCLASS_TRACKBALL; - case ECORE_DEVICE_SUBCLASS_REMOCON: - case ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD: - // FT_LOGW("There is no corresponding type"); - case ECORE_DEVICE_SUBCLASS_NONE: - default: - return ECORE_IMF_DEVICE_SUBCLASS_NONE; - } -} - TextInputChannel::TextInputChannel(flutter::BinaryMessenger* messenger, TizenEmbedderEngine* engine) : channel_(std::make_unique>( @@ -277,10 +222,8 @@ TextInputChannel::TextInputChannel(flutter::BinaryMessenger* messenger, imf_context_ = ecore_imf_context_add(GetImfMethod()); } if (imf_context_) { - // Caution: Conversion between incompatible types (int to void*). ecore_imf_context_client_window_set( - imf_context_, - (void*)(intptr_t)(engine_->tizen_renderer->GetEcoreWindowId())); + imf_context_, (void*)engine_->tizen_renderer->GetWindowId()); RegisterIMFCallback(); } else { FT_LOGE("Failed to create imfContext"); @@ -418,7 +361,14 @@ void TextInputChannel::SendStateUpdate(const flutter::TextInputModel& model) { bool TextInputChannel::FilterEvent(Ecore_Event_Key* keyDownEvent) { bool handled = false; - const char* device = ecore_device_name_get(keyDownEvent->dev); + +#ifdef TIZEN_RENDERER_EVAS_GL + // TODO: Hardware keyboard not supported when running in Evas GL mode. + bool isIME = true; +#else + bool isIME = ecore_imf_context_keyboard_mode_get(imf_context_) == + ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE; +#endif Ecore_IMF_Event_Key_Down ecoreKeyDownEvent; ecoreKeyDownEvent.keyname = keyDownEvent->keyname; @@ -430,16 +380,8 @@ bool TextInputChannel::FilterEvent(Ecore_Event_Key* keyDownEvent) { EcoreInputModifierToEcoreIMFModifier(keyDownEvent->modifiers); ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock(keyDownEvent->modifiers); - ecoreKeyDownEvent.dev_name = device; - ecoreKeyDownEvent.dev_class = EoreDeviceClassToEcoreIMFDeviceClass( - ecore_device_class_get(keyDownEvent->dev)); - ecoreKeyDownEvent.dev_subclass = EoreDeviceSubClassToEcoreIMFDeviceSubClass( - ecore_device_subclass_get(keyDownEvent->dev)); -#ifndef FLUTTER_TIZEN_4 + ecoreKeyDownEvent.dev_name = isIME ? "ime" : ""; ecoreKeyDownEvent.keycode = keyDownEvent->keycode; -#endif - - bool isIME = strcmp(device, "ime") == 0; if (isIME && strcmp(keyDownEvent->key, "Select") == 0) { if (engine_->device_profile == DeviceProfile::kWearable) { diff --git a/shell/platform/tizen/external_texture_gl.cc b/shell/platform/tizen/external_texture_gl.cc index d7078978f5685..2bf6784f7969d 100644 --- a/shell/platform/tizen/external_texture_gl.cc +++ b/shell/platform/tizen/external_texture_gl.cc @@ -4,11 +4,20 @@ #include "external_texture_gl.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 @@ -48,13 +57,13 @@ bool ExternalTextureGL::OnFrameAvailable(tbm_surface_h tbm_surface) { mutex_.unlock(); return false; } - if (!tbm_surface_internal_is_valid(tbm_surface)) { + tbm_surface_info_s info; + if (tbm_surface_get_info(tbm_surface, &info) != TBM_SURFACE_ERROR_NONE) { FT_LOGD("tbm_surface not valid, pass"); mutex_.unlock(); return false; } texture_tbm_surface_ = tbm_surface; - tbm_surface_internal_ref(texture_tbm_surface_); mutex_.unlock(); return true; } @@ -67,22 +76,53 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier( mutex_.unlock(); return false; } - if (!tbm_surface_internal_is_valid(texture_tbm_surface_)) { + tbm_surface_info_s info; + if (tbm_surface_get_info(texture_tbm_surface_, &info) != + TBM_SURFACE_ERROR_NONE) { FT_LOGD("tbm_surface not valid"); DestructionTbmSurface(); mutex_.unlock(); return false; } +#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)texture_tbm_surface_, + attribs); + if (!egl_src_image) { + mutex_.unlock(); + return false; + } + if (state_->gl_texture == 0) { + glGenTextures(1, &state_->gl_texture); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, state_->gl_texture); + // set the texture wrapping parameters + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_BORDER); + // set texture filtering parameters + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glBindTexture(GL_TEXTURE_EXTERNAL_OES, state_->gl_texture); + } + glEvasGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_src_image); + if (egl_src_image) { + evasglDestroyImage(egl_src_image); + } +#else PFNEGLCREATEIMAGEKHRPROC n_eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); - const EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, - EGL_NONE}; - EGLImageKHR eglSrcImage = n_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, - (EGLClientBuffer)texture_tbm_surface_, attrs); - if (!eglSrcImage) { - FT_LOGE("eglSrcImage create fail!!, errorcode == %d", eglGetError()); + (EGLClientBuffer)texture_tbm_surface_, attribs); + if (!egl_src_image) { + FT_LOGE("egl_src_image create fail!!, errorcode == %d", eglGetError()); mutex_.unlock(); return false; } @@ -103,12 +143,14 @@ bool ExternalTextureGL::PopulateTextureWithIdentifier( PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress( "glEGLImageTargetTexture2DOES"); - glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglSrcImage); - if (eglSrcImage) { - PFNEGLDESTROYIMAGEKHRPROC n_eglDestoryImageKHR = + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_src_image); + if (egl_src_image) { + PFNEGLDESTROYIMAGEKHRPROC n_eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR"); - n_eglDestoryImageKHR(eglGetCurrentDisplay(), eglSrcImage); + n_eglDestroyImageKHR(eglGetCurrentDisplay(), egl_src_image); } +#endif + opengl_texture->target = GL_TEXTURE_EXTERNAL_OES; opengl_texture->name = state_->gl_texture; opengl_texture->format = GL_RGBA8; @@ -131,7 +173,7 @@ void ExternalTextureGL::DestructionTbmSurface() { FT_LOGE("tbm_surface_h is NULL"); return; } - tbm_surface_internal_unref(texture_tbm_surface_); + tbm_surface_destroy(texture_tbm_surface_); texture_tbm_surface_ = NULL; } diff --git a/shell/platform/tizen/tizen_embedder_engine.cc b/shell/platform/tizen/tizen_embedder_engine.cc index 4d4c5105905b1..aaaa4946c7337 100644 --- a/shell/platform/tizen/tizen_embedder_engine.cc +++ b/shell/platform/tizen/tizen_embedder_engine.cc @@ -15,6 +15,9 @@ // Unique number associated with platform tasks. static constexpr size_t kPlatformTaskRunnerIdentifier = 1; +#ifdef TIZEN_RENDERER_EVAS_GL +static constexpr size_t kRenderTaskRunnerIdentifier = 2; +#endif static DeviceProfile GetDeviceProfile() { char* feature_profile; @@ -46,8 +49,8 @@ static double GetDeviceDpi() { TizenEmbedderEngine::TizenEmbedderEngine( const FlutterWindowProperties& window_properties) : device_profile(GetDeviceProfile()), device_dpi(GetDeviceDpi()) { -#ifdef FLUTTER_TIZEN_4 - tizen_renderer = std::make_unique( +#ifdef TIZEN_RENDERER_EVAS_GL + tizen_renderer = std::make_unique( *this, window_properties.x, window_properties.y, window_properties.width, window_properties.height); #else @@ -59,7 +62,7 @@ TizenEmbedderEngine::TizenEmbedderEngine( // Run flutter task on Tizen main loop. // Tizen engine has four threads (GPU thread, UI thread, IO thread, platform // thread). UI threads need to send flutter task to platform thread. - event_loop_ = std::make_unique( + event_loop_ = std::make_unique( std::this_thread::get_id(), // main thread [this](const auto* task) { if (FlutterEngineRunTask(this->flutter_engine, task) != kSuccess) { @@ -67,12 +70,25 @@ TizenEmbedderEngine::TizenEmbedderEngine( } }); +#ifdef TIZEN_RENDERER_EVAS_GL + render_loop_ = std::make_unique( + std::this_thread::get_id(), // main thread + [this](const auto* task) { + if (FlutterEngineRunTask(this->flutter_engine, task) != kSuccess) { + FT_LOGE("Could not post an engine task."); + } + }, + tizen_renderer.get()); +#endif + messenger = std::make_unique(); messenger->engine = this; message_dispatcher = std::make_unique(messenger.get()); +#ifndef TIZEN_RENDERER_EVAS_GL tizen_vsync_waiter_ = std::make_unique(this); +#endif } TizenEmbedderEngine::~TizenEmbedderEngine() { @@ -135,9 +151,27 @@ bool TizenEmbedderEngine::RunEngine( }; platform_task_runner.identifier = kPlatformTaskRunnerIdentifier; +#ifdef TIZEN_RENDERER_EVAS_GL + FlutterTaskRunnerDescription render_task_runner = {}; + render_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription); + render_task_runner.user_data = render_loop_.get(); + render_task_runner.runs_task_on_current_thread_callback = + [](void* data) -> bool { + return static_cast(data)->RunsTasksOnCurrentThread(); + }; + render_task_runner.post_task_callback = + [](FlutterTask task, uint64_t target_time_nanos, void* data) -> void { + static_cast(data)->PostTask(task, target_time_nanos); + }; + render_task_runner.identifier = kRenderTaskRunnerIdentifier; +#endif + FlutterCustomTaskRunners custom_task_runners = {}; custom_task_runners.struct_size = sizeof(FlutterCustomTaskRunners); custom_task_runners.platform_task_runner = &platform_task_runner; +#ifdef TIZEN_RENDERER_EVAS_GL + custom_task_runners.render_task_runner = &render_task_runner; +#endif FlutterRendererConfig config = {}; config.type = kOpenGL; @@ -159,7 +193,9 @@ bool TizenEmbedderEngine::RunEngine( args.command_line_argv = &argv[0]; args.platform_message_callback = OnFlutterPlatformMessage; args.custom_task_runners = &custom_task_runners; +#ifndef TIZEN_RENDERER_EVAS_GL args.vsync_callback = OnVsyncCallback; +#endif if (FlutterEngineRunsAOTCompiledDartCode()) { aot_data_ = LoadAotData(engine_properties.aot_library_path); @@ -349,11 +385,13 @@ void TizenEmbedderEngine::OnFlutterPlatformMessage( tizen_embedder_engine->message_dispatcher->HandleMessage(message); } +#ifndef TIZEN_RENDERER_EVAS_GL void TizenEmbedderEngine::OnVsyncCallback(void* user_data, intptr_t baton) { TizenEmbedderEngine* tizen_embedder_engine = reinterpret_cast(user_data); tizen_embedder_engine->tizen_vsync_waiter_->AsyncWaitForVsync(baton); } +#endif // Converts a FlutterPlatformMessage to an equivalent FlutterDesktopMessage. FlutterDesktopMessage TizenEmbedderEngine::ConvertToDesktopMessage( diff --git a/shell/platform/tizen/tizen_embedder_engine.h b/shell/platform/tizen/tizen_embedder_engine.h index 93d19fa266263..654d2a76405bf 100644 --- a/shell/platform/tizen/tizen_embedder_engine.h +++ b/shell/platform/tizen/tizen_embedder_engine.h @@ -24,12 +24,12 @@ #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 FLUTTER_TIZEN_4 -#include "flutter/shell/platform/tizen/tizen_renderer_ecore_wl.h" +#ifdef TIZEN_RENDERER_EVAS_GL +#include "flutter/shell/platform/tizen/tizen_renderer_evas_gl.h" #else #include "flutter/shell/platform/tizen/tizen_renderer_ecore_wl2.h" -#endif #include "flutter/shell/platform/tizen/tizen_vsync_waiter.h" +#endif #include "flutter/shell/platform/tizen/touch_event_handler.h" // State associated with the plugin registrar. @@ -126,7 +126,9 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate { static void* GlProcResolver(void* user_data, const char* name); static void OnFlutterPlatformMessage( const FlutterPlatformMessage* engine_message, void* user_data); +#ifndef TIZEN_RENDERER_EVAS_GL static void OnVsyncCallback(void* user_data, intptr_t baton); +#endif FlutterDesktopMessage ConvertToDesktopMessage( const FlutterPlatformMessage& engine_message); @@ -150,10 +152,16 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate { std::unique_ptr internal_plugin_registrar_; // The event loop for the main thread that allows for delayed task execution. - std::unique_ptr event_loop_; + std::unique_ptr event_loop_; +#ifdef TIZEN_RENDERER_EVAS_GL + std::unique_ptr render_loop_; +#endif + +#ifndef TIZEN_RENDERER_EVAS_GL // The vsync waiter for the embedder. std::unique_ptr tizen_vsync_waiter_; +#endif // AOT data for this engine instance, if applicable. UniqueAotDataPtr aot_data_; diff --git a/shell/platform/tizen/tizen_event_loop.cc b/shell/platform/tizen/tizen_event_loop.cc index 876818f05815d..ec69bb61c1580 100644 --- a/shell/platform/tizen/tizen_event_loop.cc +++ b/shell/platform/tizen/tizen_event_loop.cc @@ -8,6 +8,10 @@ #include #include +#ifdef TIZEN_RENDERER_EVAS_GL +#include "flutter/shell/platform/tizen/tizen_renderer_evas_gl.h" +#endif + TizenEventLoop::TizenEventLoop(std::thread::id main_thread_id, TaskExpiredCallback on_task_expired) : main_thread_id_(main_thread_id), @@ -27,22 +31,21 @@ bool TizenEventLoop::RunsTasksOnCurrentThread() const { void TizenEventLoop::ExcuteTaskEvents(std::chrono::nanoseconds max_wait) { const auto now = TaskTimePoint::clock::now(); - std::vector expired_tasks; { - std::lock_guard lock(task_queue_mutex_); + std::lock_guard lock1(task_queue_mutex_); + std::lock_guard lock2(expired_tasks_mutex_); while (!task_queue_.empty()) { const auto& top = task_queue_.top(); if (top.fire_time > now) { break; } - expired_tasks.push_back(task_queue_.top().task); + + expired_tasks_.push_back(task_queue_.top().task); task_queue_.pop(); } } - for (const auto& task : expired_tasks) { - on_task_expired_(&task); - } + OnTaskExpired(); } TizenEventLoop::TaskTimePoint TizenEventLoop::TimePointFromFlutterTime( @@ -55,9 +58,8 @@ TizenEventLoop::TaskTimePoint TizenEventLoop::TimePointFromFlutterTime( void TizenEventLoop::PostTask(FlutterTask flutter_task, uint64_t flutter_target_time_nanos) { - static std::atomic sGlobalTaskOrder(0); Task task; - task.order = ++sGlobalTaskOrder; + task.order = ++task_order_; task.fire_time = TimePointFromFlutterTime(flutter_target_time_nanos); task.task = flutter_task; if (ecore_pipe_) { @@ -66,15 +68,15 @@ void TizenEventLoop::PostTask(FlutterTask flutter_task, } Eina_Bool TizenEventLoop::TaskTimerCallback(void* data) { - TizenEventLoop* tizenEventLoop = reinterpret_cast(data); - tizenEventLoop->ExcuteTaskEvents(); + auto* self = reinterpret_cast(data); + self->ExcuteTaskEvents(); return EINA_FALSE; } void TizenEventLoop::ExcuteTaskEvents(void* data, void* buffer, unsigned int nbyte) { - TizenEventLoop* tizenEventLoop = reinterpret_cast(data); - Task* p_task = reinterpret_cast(buffer); + auto* self = reinterpret_cast(data); + auto* p_task = reinterpret_cast(buffer); const double flutter_duration = ((double)(p_task->fire_time.time_since_epoch().count()) - @@ -82,11 +84,69 @@ void TizenEventLoop::ExcuteTaskEvents(void* data, void* buffer, 1000000000.0; if (flutter_duration > 0) { { - std::lock_guard lock(tizenEventLoop->task_queue_mutex_); - tizenEventLoop->task_queue_.push(*p_task); + std::lock_guard lock(self->task_queue_mutex_); + self->task_queue_.push(*p_task); + } + ecore_timer_add(flutter_duration, TaskTimerCallback, self); + } else { + { + std::lock_guard lock(self->expired_tasks_mutex_); + self->expired_tasks_.push_back(p_task->task); } - ecore_timer_add(flutter_duration, TaskTimerCallback, tizenEventLoop); + self->OnTaskExpired(); + } +} + +TizenPlatformEventLoop::TizenPlatformEventLoop( + std::thread::id main_thread_id, TaskExpiredCallback on_task_expired) + : TizenEventLoop(main_thread_id, on_task_expired) {} + +TizenPlatformEventLoop::~TizenPlatformEventLoop() {} + +void TizenPlatformEventLoop::OnTaskExpired() { + for (const auto& task : expired_tasks_) { + on_task_expired_(&task); + } + expired_tasks_.clear(); +} + +#ifdef TIZEN_RENDERER_EVAS_GL +TizenRenderEventLoop::TizenRenderEventLoop(std::thread::id main_thread_id, + TaskExpiredCallback on_task_expired, + TizenRenderer* tizen_renderer) + : TizenEventLoop(main_thread_id, on_task_expired), + tizen_renderer_(tizen_renderer) { + evas_object_image_pixels_get_callback_set( + (Evas_Object*)static_cast(tizen_renderer_) + ->GetImageHandle(), + [](void* data, Evas_Object* o) { // Render callback + TizenRenderEventLoop* self = (TizenRenderEventLoop*)data; + { + std::lock_guard lock(self->expired_tasks_mutex_); + for (const auto& task : self->expired_tasks_) { + self->on_task_expired_(&task); + } + self->expired_tasks_.clear(); + } + self->has_pending_renderer_callback_ = false; + }, + this); +} + +TizenRenderEventLoop::~TizenRenderEventLoop() {} + +void TizenRenderEventLoop::OnTaskExpired() { + size_t expired_tasks_count = 0; + std::lock_guard lock(expired_tasks_mutex_); + expired_tasks_count = expired_tasks_.size(); + if (!has_pending_renderer_callback_ && expired_tasks_count) { + evas_object_image_pixels_dirty_set( + (Evas_Object*)static_cast(tizen_renderer_) + ->GetImageHandle(), + EINA_TRUE); + has_pending_renderer_callback_ = true; } else { - tizenEventLoop->on_task_expired_(&(p_task->task)); + // Do nothing } } +#endif diff --git a/shell/platform/tizen/tizen_event_loop.h b/shell/platform/tizen/tizen_event_loop.h index 56b41fae27e34..9aaf58ff12a61 100644 --- a/shell/platform/tizen/tizen_event_loop.h +++ b/shell/platform/tizen/tizen_event_loop.h @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -18,12 +19,14 @@ #include "flutter/shell/platform/embedder/embedder.h" +class TizenRenderer; + class TizenEventLoop { public: using TaskExpiredCallback = std::function; TizenEventLoop(std::thread::id main_thread_id, TaskExpiredCallback on_task_expired); - ~TizenEventLoop(); + virtual ~TizenEventLoop(); bool RunsTasksOnCurrentThread() const; void ExcuteTaskEvents( @@ -32,7 +35,9 @@ class TizenEventLoop { // Post a Flutter engine tasks to the event loop for delayed execution. void PostTask(FlutterTask flutter_task, uint64_t flutter_target_time_nanos); - private: + virtual void OnTaskExpired() = 0; + + protected: using TaskTimePoint = std::chrono::steady_clock::time_point; struct Task { uint64_t order; @@ -53,6 +58,11 @@ class TizenEventLoop { std::mutex task_queue_mutex_; std::priority_queue, Task::Comparer> task_queue_; std::condition_variable task_queue_cv_; + std::vector expired_tasks_; + std::mutex expired_tasks_mutex_; + std::atomic task_order_{0}; + + private: Ecore_Pipe* ecore_pipe_; TizenEventLoop(const TizenEventLoop&) = delete; @@ -66,4 +76,27 @@ class TizenEventLoop { uint64_t flutter_target_time_nanos); }; +class TizenPlatformEventLoop : public TizenEventLoop { + public: + TizenPlatformEventLoop(std::thread::id main_thread_id, + TaskExpiredCallback on_task_expired); + virtual ~TizenPlatformEventLoop(); + virtual void OnTaskExpired() override; +}; + +#ifdef TIZEN_RENDERER_EVAS_GL +class TizenRenderEventLoop : public TizenEventLoop { + public: + TizenRenderEventLoop(std::thread::id main_thread_id, + TaskExpiredCallback on_task_expired, + TizenRenderer* tizen_renderer); + virtual ~TizenRenderEventLoop(); + virtual void OnTaskExpired() override; + + private: + TizenRenderer* tizen_renderer_{nullptr}; + std::atomic_bool has_pending_renderer_callback_{false}; +}; +#endif + #endif // TIZEN_EVENT_LOOP_H_ diff --git a/shell/platform/tizen/tizen_log.cc b/shell/platform/tizen/tizen_log.cc index 83ec8af0c0425..0439dfefa204e 100644 --- a/shell/platform/tizen/tizen_log.cc +++ b/shell/platform/tizen/tizen_log.cc @@ -15,14 +15,14 @@ static bool is_running = false; static void* LoggingFunction(void* arg) { int* pipe = (int*)arg; - int priority = pipe == stdout_pipe ? DLOG_INFO : DLOG_ERROR; + auto priority = pipe == stdout_pipe ? DLOG_INFO : DLOG_ERROR; ssize_t size; char buffer[1024]; while ((size = read(pipe[0], buffer, sizeof(buffer) - 1)) > 0) { buffer[size] = 0; - __dlog_print(LOG_ID_MAIN, priority, LOG_TAG, "%s", buffer); + __LOG(priority, "%s", buffer); } close(pipe[0]); diff --git a/shell/platform/tizen/tizen_log.h b/shell/platform/tizen/tizen_log.h index c1236d925d949..7e543b435ab23 100644 --- a/shell/platform/tizen/tizen_log.h +++ b/shell/platform/tizen/tizen_log.h @@ -10,22 +10,29 @@ #include #include -// Start logging threads which constantly redirect stdout/stderr to dlog. +// Starts logging threads which constantly redirect stdout/stderr to dlog. // The threads can be started only once per process. void StartLogging(); #ifdef LOG_TAG #undef LOG_TAG #endif +// This is the only valid log tag that TV devices can understand. #define LOG_TAG "ConsoleMessage" #undef __LOG -#define __LOG(id, prio, tag, fmt, arg...) \ - __dlog_print(id, prio, tag, "%s: %s(%d) > " fmt, __FILE__, __func__, \ - __LINE__, ##arg); +#ifdef TV_PROFILE +// dlog_print() cannot be used because it implicitly passes LOG_ID_APPS as +// a log id, which is ignored by TV devices. Instead, an internal function +// __dlog_print() that takes a log id as a parameter is used. +#define __LOG(prio, fmt, args...) \ + __dlog_print(LOG_ID_MAIN, prio, LOG_TAG, fmt, ##args) +#else +#define __LOG(prio, fmt, args...) dlog_print(prio, LOG_TAG, fmt, ##args) +#endif #define __FT_LOG(prio, fmt, args...) \ - __LOG(LOG_ID_MAIN, prio, LOG_TAG, fmt, ##args) + __LOG(prio, "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##args) #define FT_LOGD(fmt, args...) __FT_LOG(DLOG_DEBUG, fmt, ##args) #define FT_LOGI(fmt, args...) __FT_LOG(DLOG_INFO, fmt, ##args) diff --git a/shell/platform/tizen/tizen_renderer.cc b/shell/platform/tizen/tizen_renderer.cc index 1354a7648b119..5c47b9c5a9ea8 100644 --- a/shell/platform/tizen/tizen_renderer.cc +++ b/shell/platform/tizen/tizen_renderer.cc @@ -4,457 +4,7 @@ #include "tizen_renderer.h" -#include -#include - -#include "flutter/shell/platform/tizen/tizen_log.h" - TizenRenderer::TizenRenderer(TizenRenderer::Delegate& delegate) : delegate_(delegate) {} TizenRenderer::~TizenRenderer() = default; - -bool TizenRenderer::OnMakeCurrent() { - if (!IsValid()) { - FT_LOGE("Invalid TizenRenderer"); - return false; - } - if (eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_) != - EGL_TRUE) { - FT_LOGE("Could not make the onscreen context current"); - PrintEGLError(); - return false; - } - return true; -} - -bool TizenRenderer::OnClearCurrent() { - if (!IsValid()) { - FT_LOGE("Invalid TizenRenderer"); - return false; - } - if (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT) != EGL_TRUE) { - FT_LOGE("Could not clear context"); - PrintEGLError(); - return false; - } - return true; -} - -bool TizenRenderer::OnMakeResourceCurrent() { - if (!IsValid()) { - FT_LOGE("Invalid TizenRenderer"); - return false; - } - if (eglMakeCurrent(egl_display_, egl_resource_surface_, egl_resource_surface_, - egl_resource_context_) != EGL_TRUE) { - FT_LOGE("Could not make the offscreen context current"); - PrintEGLError(); - return false; - } - return true; -} - -bool TizenRenderer::OnPresent() { - if (!is_valid_) { - FT_LOGE("Invalid TizenRenderer"); - return false; - } - - if (received_rotation) { - SendRotationChangeDone(); - received_rotation = false; - } - - if (eglSwapBuffers(egl_display_, egl_surface_) != EGL_TRUE) { - FT_LOGE("Could not swap EGl buffer"); - PrintEGLError(); - return false; - } - return true; -} - -uint32_t TizenRenderer::OnGetFBO() { - if (!is_valid_) { - FT_LOGE("Invalid TizenRenderer"); - return 999; - } - FT_LOGD("OnGetFBO"); - return 0; -} - -#define GL_FUNC(FunctionName) \ - else if (strcmp(name, #FunctionName) == 0) { \ - return reinterpret_cast(FunctionName); \ - } -void* TizenRenderer::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) - - FT_LOGW("Could not resolve: %s", name); - return nullptr; -} -#undef GL_FUNC - -bool TizenRenderer::InitializeRenderer(int32_t x, int32_t y, int32_t w, - int32_t h) { - if (!SetupDisplay()) { - FT_LOGE("setupDisplay fail"); - return false; - } - if (!SetupEcoreWlWindow(x, y, w, h)) { - FT_LOGE("SetupEcoreWlWindow fail"); - return false; - } - - if (!SetupEglWindow(w, h)) { - FT_LOGE("SetupEglWindow fail"); - return false; - } - - if (!SetupEglSurface()) { - FT_LOGE("setupEglSurface fail"); - return false; - } - Show(); - is_valid_ = true; - return true; -} - -bool TizenRenderer::IsValid() { return is_valid_; } - -bool TizenRenderer::SetupEglSurface() { - if (!ChooseEGLConfiguration()) { - FT_LOGE("ChooseEGLConfiguration fail"); - return false; - } - const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - egl_context_ = eglCreateContext(egl_display_, egl_config_, EGL_NO_CONTEXT, - contextAttribs); - if (EGL_NO_CONTEXT == egl_context_) { - PrintEGLError(); - return false; - } - - egl_resource_context_ = - eglCreateContext(egl_display_, egl_config_, egl_context_, contextAttribs); - if (EGL_NO_CONTEXT == egl_resource_context_) { - PrintEGLError(); - return false; - } - EGLint* ptr = nullptr; - const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; - egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_, - GetEGLNativeWindowType(), ptr); - if (egl_surface_ == EGL_NO_SURFACE) { - FT_LOGE("eglCreateWindowSurface failed"); - return false; - } - egl_resource_surface_ = - eglCreatePbufferSurface(egl_display_, egl_config_, attribs); - if (egl_resource_surface_ == EGL_NO_SURFACE) { - FT_LOGE("eglCreatePbufferSurface is Failed"); - return false; - } - return true; -} - -bool TizenRenderer::ChooseEGLConfiguration() { - // egl CONTEXT - EGLint configAttribs[] = { - // clang-format off - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, EGL_DONT_CARE, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_SAMPLE_BUFFERS, EGL_DONT_CARE, - EGL_SAMPLES, EGL_DONT_CARE, - EGL_NONE - // clang-format on - }; - - EGLint major = 0; - EGLint minor = 0; - int bufferSize = 32; - egl_display_ = GetEGLDisplay(); - if (EGL_NO_DISPLAY == egl_display_) { - FT_LOGE("EGL Get Display is failed"); - return false; - } - - if (!eglInitialize(egl_display_, &major, &minor)) { - FT_LOGE("EGL Intialize is Failed major [%d] minor [%d]", major, minor); - PrintEGLError(); - return false; - } - - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - PrintEGLError(); - return false; - } - - EGLint numOfConfig = 0; - // Query all framebuffer configurations - if (!eglGetConfigs(egl_display_, NULL, 0, &numOfConfig)) { - FT_LOGE("eglGetConfigs is Failed!!"); - PrintEGLError(); - return false; - } - EGLConfig* configs = (EGLConfig*)calloc(numOfConfig, sizeof(EGLConfig)); - EGLint n; - // Get the List of EGL framebuffer configuration matches with configAttribs in - // list "configs" - if (!eglChooseConfig(egl_display_, configAttribs, configs, numOfConfig, &n)) { - free(configs); - configs = NULL; - PrintEGLError(); - return false; - } - - EGLint size; - for (int i = 0; i < n; i++) { - eglGetConfigAttrib(egl_display_, configs[i], EGL_BUFFER_SIZE, &size); - if (bufferSize == size) { - egl_config_ = configs[i]; - break; - } - } - free(configs); - configs = NULL; - return true; -} - -void TizenRenderer::PrintEGLError() { - EGLint error = eglGetError(); - switch (error) { - case EGL_BAD_DISPLAY: { - FT_LOGE("EGL_BAD_DISPLAY : Display is not an EGL display connection"); - break; - } - case EGL_NOT_INITIALIZED: { - FT_LOGE("EGL_NOT_INITIALIZED : Display has not been initialized"); - break; - } - case EGL_BAD_SURFACE: { - FT_LOGE("EGL_BAD_SURFACE : Draw or read is not an EGL surface"); - break; - } - case EGL_BAD_CONTEXT: { - FT_LOGE("EGL_BAD_CONTEXT : Context is not an EGL rendering context"); - break; - } - case EGL_BAD_CONFIG: { - FT_LOGE( - "EGL_BAD_CONFIG : Config is not an EGL frame buffer configuration"); - break; - } - case EGL_BAD_MATCH: { - FT_LOGE( - "EGL_BAD_MATCH : Draw or read are not compatible with context, or if " - "context is set to EGL_NO_CONTEXT and draw or read are not set to " - "EGL_NO_SURFACE, or if draw or read are set to EGL_NO_SURFACE and " - "context is not set to EGL_NO_CONTEXT\n"); - break; - } - case EGL_BAD_ACCESS: { - FT_LOGE("EGL_BAD_ACCESS : Context is current to some other thread"); - break; - } - case EGL_BAD_NATIVE_PIXMAP: { - FT_LOGE( - "EGL_BAD_NATIVE_PIXMAP : A native pixmap underlying either draw or " - "read is no longer valid"); - break; - } - case EGL_BAD_NATIVE_WINDOW: { - FT_LOGE( - "EGL_BAD_NATIVE_WINDOW : A native window underlying either draw or " - "read is no longer valid"); - break; - } - case EGL_BAD_CURRENT_SURFACE: { - FT_LOGE( - "EGL_BAD_CURRENT_SURFACE : The previous context has unflushed " - "commands and the previous surface is no longer valid"); - break; - } - case EGL_BAD_ALLOC: { - FT_LOGE( - "EGL_BAD_ALLOC : Allocation of ancillary buffers for draw or read " - "were delayed until eglMakeCurrent is called, and there are not " - "enough resources to allocate them"); - break; - } - case EGL_CONTEXT_LOST: { - FT_LOGE( - "EGL_CONTEXT_LOST : A power management event has occurred. The " - "application must destroy all contexts and reinitialise OpenGL ES " - "state and objects to continue rendering"); - break; - } - case EGL_BAD_PARAMETER: { - FT_LOGE("Invalid parameter is passed"); - break; - } - case EGL_BAD_ATTRIBUTE: { - FT_LOGE( - "The parameter configAttribs contains an invalid frame buffer " - "configuration attribute or an attribute value that is unrecognized " - "or out of range"); - break; - } - default: { - FT_LOGE("Unknown error with code: %d", error); - break; - } - } -} - -void TizenRenderer::DestoryRenderer() { - DestoryEglSurface(); - DestoryEglWindow(); - DestoryEcoreWlWindow(); - ShutdownDisplay(); -} - -void TizenRenderer::DestoryEglSurface() { - if (EGL_NO_DISPLAY != egl_display_) { - eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - - if (EGL_NO_SURFACE != egl_surface_) { - eglDestroySurface(egl_display_, egl_surface_); - egl_surface_ = EGL_NO_SURFACE; - } - - if (EGL_NO_CONTEXT != egl_context_) { - eglDestroyContext(egl_display_, egl_context_); - egl_context_ = EGL_NO_CONTEXT; - } - - if (EGL_NO_SURFACE != egl_resource_surface_) { - eglDestroySurface(egl_display_, egl_resource_surface_); - egl_resource_surface_ = EGL_NO_SURFACE; - } - - if (EGL_NO_CONTEXT != egl_resource_context_) { - eglDestroyContext(egl_display_, egl_resource_context_); - egl_resource_context_ = EGL_NO_CONTEXT; - } - - eglTerminate(egl_display_); - egl_display_ = EGL_NO_DISPLAY; - } -} diff --git a/shell/platform/tizen/tizen_renderer.h b/shell/platform/tizen/tizen_renderer.h index d4cddfe4a2b4d..d100495a110af 100644 --- a/shell/platform/tizen/tizen_renderer.h +++ b/shell/platform/tizen/tizen_renderer.h @@ -5,7 +5,7 @@ #ifndef EMBEDDER_TIZEN_RENDERER_H #define EMBEDDER_TIZEN_RENDERER_H -#include +#include class TizenRenderer { public: @@ -18,50 +18,31 @@ class TizenRenderer { virtual void OnRotationChange(int angle) = 0; }; - TizenRenderer(TizenRenderer::Delegate& deleget); virtual ~TizenRenderer(); - bool OnMakeCurrent(); - bool OnClearCurrent(); - bool OnMakeResourceCurrent(); - bool OnPresent(); - uint32_t OnGetFBO(); - void* OnProcResolver(const char* name); + + bool IsValid() { return is_valid_; } + + virtual bool OnMakeCurrent() = 0; + virtual bool OnClearCurrent() = 0; + virtual bool OnMakeResourceCurrent() = 0; + virtual bool OnPresent() = 0; + virtual uint32_t OnGetFBO() = 0; + virtual void* OnProcResolver(const char* name) = 0; + virtual TizenWindowGeometry GetGeometry() = 0; - bool IsValid(); - virtual void Show() = 0; + virtual uintptr_t GetWindowId() = 0; + virtual void SetRotate(int angle) = 0; - virtual int GetEcoreWindowId() = 0; virtual void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, int32_t degree) = 0; protected: - bool received_rotation{false}; - TizenRenderer::Delegate& delegate_; - bool InitializeRenderer(int32_t x, int32_t y, int32_t w, int32_t h); - virtual bool SetupDisplay() = 0; - virtual bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, - int32_t h) = 0; - virtual bool SetupEglWindow(int32_t w, int32_t h) = 0; - bool SetupEglSurface(); - virtual EGLDisplay GetEGLDisplay() = 0; - virtual EGLNativeWindowType GetEGLNativeWindowType() = 0; - void DestoryRenderer(); - void DestoryEglSurface(); - virtual void DestoryEglWindow() = 0; - virtual void DestoryEcoreWlWindow() = 0; - virtual void ShutdownDisplay() = 0; - virtual void SendRotationChangeDone() = 0; + explicit TizenRenderer(TizenRenderer::Delegate& delegate); - private: bool is_valid_ = false; - EGLConfig egl_config_; - EGLDisplay egl_display_ = EGL_NO_DISPLAY; - EGLContext egl_context_ = EGL_NO_CONTEXT; - EGLSurface egl_surface_ = EGL_NO_SURFACE; - EGLContext egl_resource_context_ = EGL_NO_CONTEXT; - EGLSurface egl_resource_surface_ = EGL_NO_SURFACE; - bool ChooseEGLConfiguration(); - void PrintEGLError(); + + bool received_rotation_{false}; + TizenRenderer::Delegate& delegate_; }; #endif // EMBEDDER_TIZEN_RENDERER_H diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl.cc b/shell/platform/tizen/tizen_renderer_ecore_wl.cc deleted file mode 100644 index 997163d52550e..0000000000000 --- a/shell/platform/tizen/tizen_renderer_ecore_wl.cc +++ /dev/null @@ -1,133 +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. - -#include "tizen_renderer_ecore_wl.h" - -#include "flutter/shell/platform/tizen/tizen_log.h" - -TizenRendererEcoreWl::TizenRendererEcoreWl(TizenRenderer::Delegate &delegate, - int32_t x, int32_t y, int32_t w, - int32_t h) - : TizenRenderer(delegate) { - InitializeRenderer(x, y, w, h); -} - -TizenRendererEcoreWl::~TizenRendererEcoreWl() { DestoryRenderer(); } - -bool TizenRendererEcoreWl::SetupDisplay() { - // ecore_wl INIT - if (!ecore_wl_init(NULL)) { - FT_LOGE("Could not initialize ecore_wl"); - return false; - } - wl_display_ = ecore_wl_display_get(); - if (nullptr == wl_display_) { - FT_LOGE("ecore_wl_display_get failed"); - return false; - } - return true; -} - -bool TizenRendererEcoreWl::SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, - int32_t h) { - if (w == 0 || h == 0) { - FT_LOGE("Failed to create because of the wrong size"); - return false; - } - - ecore_wl_window_ = ecore_wl_window_new( - nullptr, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW); - FT_LOGD("ecore_wl_window_: %p", ecore_wl_window_); - if (ecore_wl_window_ == nullptr) { - FT_LOGE("ecore_wl_window_new fail"); - return false; - } - ecore_wl_window_type_set(ecore_wl_window_, ECORE_WL_WINDOW_TYPE_TOPLEVEL); - // ecore_wl_window_alpha_set(ecore_wl_window_, EINA_FALSE); - ecore_wl_window_aux_hint_add(ecore_wl_window_, 0, - "wm.policy.win.user.geometry", "1"); - ecore_wl_window_show(ecore_wl_window_); - int rotations[4] = {0, 90, 180, 270}; - ecore_wl_window_rotation_available_rotations_set( - ecore_wl_window_, rotations, sizeof(rotations) / sizeof(int)); - ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE, RotationEventCb, this); - return true; -} - -Eina_Bool TizenRendererEcoreWl::RotationEventCb(void *data, int type, - void *event) { - auto *self = reinterpret_cast(data); - Ecore_Wl_Event_Window_Rotate *ev = - reinterpret_cast(event); - self->delegate_.OnRotationChange(ev->angle); - return ECORE_CALLBACK_PASS_ON; -} - -void TizenRendererEcoreWl::Show() { ecore_wl_window_show(ecore_wl_window_); } - -void TizenRendererEcoreWl::SetRotate(int degree) { - ecore_wl_window_rotation_set(ecore_wl_window_, degree); - received_rotation = true; -} - -void TizenRendererEcoreWl::ResizeWithRotation(int32_t x, int32_t y, - int32_t width, int32_t height, - int32_t degree) { - wl_egl_window_set_buffer_transform(wl_egl_window_, degree / 90); - wl_egl_window_set_window_transform(wl_egl_window_, degree / 90); - - if ((degree == 90) || (degree == 270)) - wl_egl_window_resize(wl_egl_window_, height, width, x, y); - else - wl_egl_window_resize(wl_egl_window_, width, height, x, y); -} - -void TizenRendererEcoreWl::SendRotationChangeDone() { - ecore_wl_window_rotation_change_done_send(ecore_wl_window_); -} - -bool TizenRendererEcoreWl::SetupEglWindow(int32_t w, int32_t h) { - wl_egl_window_ = - wl_egl_window_create(ecore_wl_window_surface_get(ecore_wl_window_), w, h); - if (nullptr == wl_egl_window_) { - FT_LOGE("wl_egl_window_create is Failed"); - return false; - } - return true; -} - -EGLDisplay TizenRendererEcoreWl::GetEGLDisplay() { - return eglGetDisplay((EGLNativeDisplayType)wl_display_); -} - -EGLNativeWindowType TizenRendererEcoreWl::GetEGLNativeWindowType() { - return (EGLNativeWindowType)wl_egl_window_; -} - -void TizenRendererEcoreWl::DestoryEglWindow() { - if (wl_egl_window_) { - wl_egl_window_destroy(wl_egl_window_); - wl_egl_window_ = nullptr; - } -} - -void TizenRendererEcoreWl::DestoryEcoreWlWindow() { - if (ecore_wl_window_) { - ecore_wl_window_free(ecore_wl_window_); - ecore_wl_window_ = nullptr; - } -} - -void TizenRendererEcoreWl::ShutdownDisplay() { ecore_wl_shutdown(); } - -TizenRenderer::TizenWindowGeometry TizenRendererEcoreWl::GetGeometry() { - TizenWindowGeometry result; - ecore_wl_window_geometry_get(ecore_wl_window_, &result.x, &result.y, - &result.w, &result.h); - return result; -} - -int TizenRendererEcoreWl::GetEcoreWindowId() { - return ecore_wl_window_id_get(ecore_wl_window_); -} diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl.h b/shell/platform/tizen/tizen_renderer_ecore_wl.h deleted file mode 100644 index 7e9c6f1fb0bbf..0000000000000 --- a/shell/platform/tizen/tizen_renderer_ecore_wl.h +++ /dev/null @@ -1,46 +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 EMBEDDER_TIZEN_RENDERER_ECORE_WL_H -#define EMBEDDER_TIZEN_RENDERER_ECORE_WL_H - -#include -#include - -#define EFL_BETA_API_SUPPORT -#include - -#include "flutter/shell/platform/tizen/tizen_renderer.h" - -class TizenRendererEcoreWl : public TizenRenderer { - public: - TizenRendererEcoreWl(TizenRenderer::Delegate& delegate, int32_t x, int32_t y, - int32_t w, int32_t h); - ~TizenRendererEcoreWl(); - TizenRenderer::TizenWindowGeometry GetGeometry() override; - void Show() override; - void SetRotate(int angle) override; - void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, - int32_t degree) override; - int GetEcoreWindowId() override; - - protected: - void DestoryEglWindow() override; - void DestoryEcoreWlWindow() override; - EGLDisplay GetEGLDisplay() override; - EGLNativeWindowType GetEGLNativeWindowType() override; - bool SetupDisplay() override; - bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, int32_t h) override; - bool SetupEglWindow(int32_t w, int32_t h) override; - void ShutdownDisplay() override; - void SendRotationChangeDone() override; - - private: - Ecore_Wl_Window* ecore_wl_window_ = nullptr; - wl_egl_window* wl_egl_window_ = nullptr; - wl_display* wl_display_ = nullptr; - static Eina_Bool RotationEventCb(void* data, int type, void* event); -}; - -#endif // EMBEDDER_TIZEN_RENDERER_ECORE_WL_H diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc index 4d99b1ca5312e..4b0140450fcd2 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc @@ -4,6 +4,9 @@ #include "tizen_renderer_ecore_wl2.h" +#include +#include + #include "flutter/shell/platform/tizen/tizen_log.h" TizenRendererEcoreWl2::TizenRendererEcoreWl2(TizenRenderer::Delegate &delegate, @@ -13,7 +16,242 @@ TizenRendererEcoreWl2::TizenRendererEcoreWl2(TizenRenderer::Delegate &delegate, InitializeRenderer(x, y, w, h); } -TizenRendererEcoreWl2::~TizenRendererEcoreWl2() { DestoryRenderer(); } +TizenRendererEcoreWl2::~TizenRendererEcoreWl2() { DestroyRenderer(); } + +bool TizenRendererEcoreWl2::OnMakeCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_) != + EGL_TRUE) { + FT_LOGE("Could not make the onscreen context current"); + PrintEGLError(); + return false; + } + return true; +} + +bool TizenRendererEcoreWl2::OnClearCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT) != EGL_TRUE) { + FT_LOGE("Could not clear context"); + PrintEGLError(); + return false; + } + return true; +} + +bool TizenRendererEcoreWl2::OnMakeResourceCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (eglMakeCurrent(egl_display_, egl_resource_surface_, egl_resource_surface_, + egl_resource_context_) != EGL_TRUE) { + FT_LOGE("Could not make the offscreen context current"); + PrintEGLError(); + return false; + } + return true; +} + +bool TizenRendererEcoreWl2::OnPresent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + + if (received_rotation_) { + SendRotationChangeDone(); + received_rotation_ = false; + } + + if (eglSwapBuffers(egl_display_, egl_surface_) != EGL_TRUE) { + FT_LOGE("Could not swap EGl buffer"); + PrintEGLError(); + return false; + } + return true; +} + +uint32_t TizenRendererEcoreWl2::OnGetFBO() { + if (!is_valid_) { + FT_LOGE("Invalid TizenRenderer"); + return 999; + } + FT_LOGD("OnGetFBO"); + return 0; +} + +void *TizenRendererEcoreWl2::OnProcResolver(const char *name) { + auto address = eglGetProcAddress(name); + if (address != nullptr) { + return reinterpret_cast(address); + } +#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 + + FT_LOGW("Could not resolve: %s", name); + return nullptr; +} + +TizenRenderer::TizenWindowGeometry TizenRendererEcoreWl2::GetGeometry() { + TizenWindowGeometry result; + ecore_wl2_window_geometry_get(ecore_wl2_window_, &result.x, &result.y, + &result.w, &result.h); + return result; +} + +uintptr_t TizenRendererEcoreWl2::GetWindowId() { + return (uintptr_t)ecore_wl2_window_id_get(ecore_wl2_window_); +} + +bool TizenRendererEcoreWl2::InitializeRenderer(int32_t x, int32_t y, int32_t w, + int32_t h) { + if (!SetupDisplay()) { + FT_LOGE("SetupDisplay fail"); + return false; + } + if (!SetupEcoreWlWindow(x, y, w, h)) { + FT_LOGE("SetupEcoreWlWindow fail"); + return false; + } + if (!SetupEglWindow(w, h)) { + FT_LOGE("SetupEglWindow fail"); + return false; + } + if (!SetupEglSurface()) { + FT_LOGE("SetupEglSurface fail"); + return false; + } + Show(); + is_valid_ = true; + return true; +} + +void TizenRendererEcoreWl2::Show() { ecore_wl2_window_show(ecore_wl2_window_); } + +void TizenRendererEcoreWl2::DestroyRenderer() { + DestroyEglSurface(); + DestroyEglWindow(); + DestroyEcoreWlWindow(); + ShutdownDisplay(); +} bool TizenRendererEcoreWl2::SetupDisplay() { if (!ecore_wl2_init()) { @@ -22,7 +260,7 @@ bool TizenRendererEcoreWl2::SetupDisplay() { } ecore_wl2_display_ = ecore_wl2_display_connect(nullptr); if (ecore_wl2_display_ == nullptr) { - FT_LOGE("Disyplay not found"); + FT_LOGE("Display not found"); return false; } FT_LOGD("ecore_wl2_display_: %p", ecore_wl2_display_); @@ -50,37 +288,6 @@ bool TizenRendererEcoreWl2::SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, return true; } -Eina_Bool TizenRendererEcoreWl2::RotationEventCb(void *data, int type, - void *event) { - auto *self = reinterpret_cast(data); - Ecore_Wl2_Event_Window_Rotation *ev = - reinterpret_cast(event); - self->delegate_.OnRotationChange(ev->angle); - return ECORE_CALLBACK_PASS_ON; -} - -void TizenRendererEcoreWl2::Show() { ecore_wl2_window_show(ecore_wl2_window_); } - -void TizenRendererEcoreWl2::SetRotate(int angle) { - ecore_wl2_window_rotation_set(ecore_wl2_window_, angle); - received_rotation = true; -} - -void TizenRendererEcoreWl2::ResizeWithRotation(int32_t x, int32_t y, - int32_t width, int32_t height, - int32_t angle) { - ecore_wl2_egl_window_resize_with_rotation(ecore_wl2_egl_window_, x, y, width, - height, angle); -} - -void TizenRendererEcoreWl2::SendRotationChangeDone() { - int x, y, w, h; - ecore_wl2_window_geometry_get(ecore_wl2_window_, &x, &y, &w, &h); - ecore_wl2_window_rotation_change_done_send( - ecore_wl2_window_, ecore_wl2_window_rotation_get(ecore_wl2_window_), w, - h); -} - bool TizenRendererEcoreWl2::SetupEglWindow(int32_t w, int32_t h) { ecore_wl2_egl_window_ = ecore_wl2_egl_window_create(ecore_wl2_window_, w, h); return ecore_wl2_egl_window_ != nullptr; @@ -96,14 +303,14 @@ EGLNativeWindowType TizenRendererEcoreWl2::GetEGLNativeWindowType() { ecore_wl2_egl_window_); } -void TizenRendererEcoreWl2::DestoryEglWindow() { +void TizenRendererEcoreWl2::DestroyEglWindow() { if (ecore_wl2_egl_window_) { ecore_wl2_egl_window_destroy(ecore_wl2_egl_window_); ecore_wl2_egl_window_ = nullptr; } } -void TizenRendererEcoreWl2::DestoryEcoreWlWindow() { +void TizenRendererEcoreWl2::DestroyEcoreWlWindow() { if (ecore_wl2_window_) { ecore_wl2_window_free(ecore_wl2_window_); ecore_wl2_window_ = nullptr; @@ -118,13 +325,255 @@ void TizenRendererEcoreWl2::ShutdownDisplay() { ecore_wl2_shutdown(); } -TizenRenderer::TizenWindowGeometry TizenRendererEcoreWl2::GetGeometry() { - TizenWindowGeometry result; - ecore_wl2_window_geometry_get(ecore_wl2_window_, &result.x, &result.y, - &result.w, &result.h); - return result; +bool TizenRendererEcoreWl2::SetupEglSurface() { + if (!ChooseEGLConfiguration()) { + FT_LOGE("ChooseEGLConfiguration fail"); + return false; + } + + const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; + egl_context_ = eglCreateContext(egl_display_, egl_config_, EGL_NO_CONTEXT, + context_attribs); + if (EGL_NO_CONTEXT == egl_context_) { + PrintEGLError(); + return false; + } + + egl_resource_context_ = eglCreateContext(egl_display_, egl_config_, + egl_context_, context_attribs); + if (EGL_NO_CONTEXT == egl_resource_context_) { + PrintEGLError(); + return false; + } + + EGLint *ptr = nullptr; + egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_, + GetEGLNativeWindowType(), ptr); + if (egl_surface_ == EGL_NO_SURFACE) { + FT_LOGE("eglCreateWindowSurface failed"); + 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) { + FT_LOGE("eglCreatePbufferSurface is Failed"); + return false; + } + + return true; +} + +bool TizenRendererEcoreWl2::ChooseEGLConfiguration() { + // egl CONTEXT + EGLint config_attribs[] = { + // clang-format off + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, EGL_DONT_CARE, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_SAMPLE_BUFFERS, EGL_DONT_CARE, + EGL_SAMPLES, EGL_DONT_CARE, + EGL_NONE + // clang-format on + }; + + EGLint major = 0; + EGLint minor = 0; + int buffer_size = 32; + egl_display_ = GetEGLDisplay(); + if (EGL_NO_DISPLAY == egl_display_) { + FT_LOGE("EGL Get Display is failed"); + return false; + } + + if (!eglInitialize(egl_display_, &major, &minor)) { + FT_LOGE("EGL Intialize is Failed major [%d] minor [%d]", major, minor); + PrintEGLError(); + return false; + } + + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + PrintEGLError(); + return false; + } + + EGLint num_config = 0; + // Query all framebuffer configurations + if (!eglGetConfigs(egl_display_, NULL, 0, &num_config)) { + FT_LOGE("eglGetConfigs is Failed!!"); + PrintEGLError(); + return false; + } + EGLConfig *configs = (EGLConfig *)calloc(num_config, sizeof(EGLConfig)); + EGLint num; + // Get the List of EGL framebuffer configuration matches with config_attribs + // in list "configs" + if (!eglChooseConfig(egl_display_, config_attribs, configs, num_config, + &num)) { + free(configs); + configs = NULL; + PrintEGLError(); + return false; + } + + EGLint size; + for (int i = 0; i < num; i++) { + eglGetConfigAttrib(egl_display_, configs[i], EGL_BUFFER_SIZE, &size); + if (buffer_size == size) { + egl_config_ = configs[i]; + break; + } + } + free(configs); + configs = NULL; + return true; +} + +void TizenRendererEcoreWl2::PrintEGLError() { + EGLint error = eglGetError(); + switch (error) { + case EGL_BAD_DISPLAY: { + FT_LOGE("EGL_BAD_DISPLAY : Display is not an EGL display connection"); + break; + } + case EGL_NOT_INITIALIZED: { + FT_LOGE("EGL_NOT_INITIALIZED : Display has not been initialized"); + break; + } + case EGL_BAD_SURFACE: { + FT_LOGE("EGL_BAD_SURFACE : Draw or read is not an EGL surface"); + break; + } + case EGL_BAD_CONTEXT: { + FT_LOGE("EGL_BAD_CONTEXT : Context is not an EGL rendering context"); + break; + } + case EGL_BAD_CONFIG: { + FT_LOGE( + "EGL_BAD_CONFIG : Config is not an EGL frame buffer configuration"); + break; + } + case EGL_BAD_MATCH: { + FT_LOGE( + "EGL_BAD_MATCH : Draw or read are not compatible with context, or if " + "context is set to EGL_NO_CONTEXT and draw or read are not set to " + "EGL_NO_SURFACE, or if draw or read are set to EGL_NO_SURFACE and " + "context is not set to EGL_NO_CONTEXT"); + break; + } + case EGL_BAD_ACCESS: { + FT_LOGE("EGL_BAD_ACCESS : Context is current to some other thread"); + break; + } + case EGL_BAD_NATIVE_PIXMAP: { + FT_LOGE( + "EGL_BAD_NATIVE_PIXMAP : A native pixmap underlying either draw or " + "read is no longer valid"); + break; + } + case EGL_BAD_NATIVE_WINDOW: { + FT_LOGE( + "EGL_BAD_NATIVE_WINDOW : A native window underlying either draw or " + "read is no longer valid"); + break; + } + case EGL_BAD_CURRENT_SURFACE: { + FT_LOGE( + "EGL_BAD_CURRENT_SURFACE : The previous context has unflushed " + "commands and the previous surface is no longer valid"); + break; + } + case EGL_BAD_ALLOC: { + FT_LOGE( + "EGL_BAD_ALLOC : Allocation of ancillary buffers for draw or read " + "were delayed until eglMakeCurrent is called, and there are not " + "enough resources to allocate them"); + break; + } + case EGL_CONTEXT_LOST: { + FT_LOGE( + "EGL_CONTEXT_LOST : A power management event has occurred. The " + "application must destroy all contexts and reinitialise OpenGL ES " + "state and objects to continue rendering"); + break; + } + case EGL_BAD_PARAMETER: { + FT_LOGE("Invalid parameter is passed"); + break; + } + case EGL_BAD_ATTRIBUTE: { + FT_LOGE( + "The parameter configAttribs contains an invalid frame buffer " + "configuration attribute or an attribute value that is unrecognized " + "or out of range"); + break; + } + default: { + FT_LOGE("Unknown error with code: %d", error); + break; + } + } +} + +void TizenRendererEcoreWl2::DestroyEglSurface() { + if (EGL_NO_DISPLAY != egl_display_) { + eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + if (EGL_NO_SURFACE != egl_surface_) { + eglDestroySurface(egl_display_, egl_surface_); + egl_surface_ = EGL_NO_SURFACE; + } + + if (EGL_NO_CONTEXT != egl_context_) { + eglDestroyContext(egl_display_, egl_context_); + egl_context_ = EGL_NO_CONTEXT; + } + + if (EGL_NO_SURFACE != egl_resource_surface_) { + eglDestroySurface(egl_display_, egl_resource_surface_); + egl_resource_surface_ = EGL_NO_SURFACE; + } + + if (EGL_NO_CONTEXT != egl_resource_context_) { + eglDestroyContext(egl_display_, egl_resource_context_); + egl_resource_context_ = EGL_NO_CONTEXT; + } + + eglTerminate(egl_display_); + egl_display_ = EGL_NO_DISPLAY; + } } -int TizenRendererEcoreWl2::GetEcoreWindowId() { - return ecore_wl2_window_id_get(ecore_wl2_window_); +Eina_Bool TizenRendererEcoreWl2::RotationEventCb(void *data, int type, + void *event) { + auto *self = reinterpret_cast(data); + Ecore_Wl2_Event_Window_Rotation *ev = + reinterpret_cast(event); + self->delegate_.OnRotationChange(ev->angle); + return ECORE_CALLBACK_PASS_ON; +} + +void TizenRendererEcoreWl2::SetRotate(int angle) { + ecore_wl2_window_rotation_set(ecore_wl2_window_, angle); + received_rotation_ = true; +} + +void TizenRendererEcoreWl2::ResizeWithRotation(int32_t x, int32_t y, + int32_t width, int32_t height, + int32_t angle) { + ecore_wl2_egl_window_resize_with_rotation(ecore_wl2_egl_window_, x, y, width, + height, angle); +} + +void TizenRendererEcoreWl2::SendRotationChangeDone() { + int x, y, w, h; + ecore_wl2_window_geometry_get(ecore_wl2_window_, &x, &y, &w, &h); + ecore_wl2_window_rotation_change_done_send( + ecore_wl2_window_, ecore_wl2_window_rotation_get(ecore_wl2_window_), w, + h); } diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.h b/shell/platform/tizen/tizen_renderer_ecore_wl2.h index 42803086ea184..1f885c49f77ec 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.h +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.h @@ -6,38 +6,63 @@ #define EMBEDDER_TIZEN_RENDERER_ECORE_WL2_H #define EFL_BETA_API_SUPPORT +#include #include #include "flutter/shell/platform/tizen/tizen_renderer.h" class TizenRendererEcoreWl2 : public TizenRenderer { public: - TizenRendererEcoreWl2(TizenRenderer::Delegate &delegate, int32_t x, int32_t y, - int32_t w, int32_t h); - ~TizenRendererEcoreWl2(); + explicit TizenRendererEcoreWl2(TizenRenderer::Delegate &delegate, int32_t x, + int32_t y, int32_t w, int32_t h); + virtual ~TizenRendererEcoreWl2(); + + bool OnMakeCurrent() override; + bool OnClearCurrent() override; + bool OnMakeResourceCurrent() override; + bool OnPresent() override; + uint32_t OnGetFBO() override; + void *OnProcResolver(const char *name) override; + TizenWindowGeometry GetGeometry() override; - int GetEcoreWindowId() override; + uintptr_t GetWindowId() override; + void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, int32_t angle) override; - void Show() override; void SetRotate(int angle) override; - protected: - void DestoryEglWindow() override; - void DestoryEcoreWlWindow() override; - EGLDisplay GetEGLDisplay() override; - EGLNativeWindowType GetEGLNativeWindowType() override; - bool SetupDisplay() override; - bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, int32_t h) override; - bool SetupEglWindow(int32_t w, int32_t h) override; - void ShutdownDisplay() override; - void SendRotationChangeDone() override; - private: + bool InitializeRenderer(int32_t x, int32_t y, int32_t w, int32_t h); + void Show(); + void DestroyRenderer(); + + bool SetupDisplay(); + bool SetupEcoreWlWindow(int32_t x, int32_t y, int32_t w, int32_t h); + bool SetupEglWindow(int32_t w, int32_t h); + EGLDisplay GetEGLDisplay(); + EGLNativeWindowType GetEGLNativeWindowType(); + void DestroyEglWindow(); + void DestroyEcoreWlWindow(); + void ShutdownDisplay(); + + bool SetupEglSurface(); + bool ChooseEGLConfiguration(); + void PrintEGLError(); + void DestroyEglSurface(); + + static Eina_Bool RotationEventCb(void *data, int type, void *event); + void SendRotationChangeDone(); + Ecore_Wl2_Display *ecore_wl2_display_ = nullptr; Ecore_Wl2_Window *ecore_wl2_window_ = nullptr; Ecore_Wl2_Egl_Window *ecore_wl2_egl_window_ = nullptr; - static Eina_Bool RotationEventCb(void *data, int type, void *event); + + EGLConfig egl_config_; + EGLDisplay egl_display_ = EGL_NO_DISPLAY; + EGLContext egl_context_ = EGL_NO_CONTEXT; + EGLSurface egl_surface_ = EGL_NO_SURFACE; + EGLContext egl_resource_context_ = EGL_NO_CONTEXT; + EGLSurface egl_resource_surface_ = EGL_NO_SURFACE; }; #endif // EMBEDDER_TIZEN_RENDERER_ECORE_WL2_H diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.cc b/shell/platform/tizen/tizen_renderer_evas_gl.cc new file mode 100644 index 0000000000000..8d2910e471283 --- /dev/null +++ b/shell/platform/tizen/tizen_renderer_evas_gl.cc @@ -0,0 +1,702 @@ +// Copyright 2021 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_renderer_evas_gl.h" + +#include +Evas_GL* g_evas_gl = nullptr; +EVAS_GL_GLOBAL_GLES3_DEFINE(); + +#include "flutter/shell/platform/tizen/tizen_log.h" + +TizenRendererEvasGL::TizenRendererEvasGL(TizenRenderer::Delegate& delegate, + int32_t x, int32_t y, int32_t w, + int32_t h) + : TizenRenderer(delegate) { + InitializeRenderer(x, y, w, h); + + // Clear once to remove noise. + OnMakeCurrent(); + ClearColor(0, 0, 0, 0); + OnPresent(); +} + +TizenRendererEvasGL::~TizenRendererEvasGL() { DestroyRenderer(); } + +void TizenRendererEvasGL::ClearColor(float r, float g, float b, float a) { + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); +} + +bool TizenRendererEvasGL::OnMakeCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (evas_gl_make_current(evas_gl_, gl_surface_, gl_context_) != EINA_TRUE) { + return false; + } + + return true; +} + +bool TizenRendererEvasGL::OnClearCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (evas_gl_make_current(evas_gl_, NULL, NULL) != EINA_TRUE) { + return false; + } + return true; +} + +bool TizenRendererEvasGL::OnMakeResourceCurrent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + if (evas_gl_make_current(evas_gl_, gl_resource_surface_, + gl_resource_context_) != EINA_TRUE) { + return false; + } + return true; +} + +bool TizenRendererEvasGL::OnPresent() { + if (!IsValid()) { + FT_LOGE("Invalid TizenRenderer"); + return false; + } + + if (received_rotation_) { + SendRotationChangeDone(); + received_rotation_ = false; + } + + return true; +} + +uint32_t TizenRendererEvasGL::OnGetFBO() { + if (!is_valid_) { + FT_LOGE("Invalid TizenRenderer"); + return 999; + } + FT_LOGD("OnGetFBO"); + return 0; +} + +void* TizenRendererEvasGL::OnProcResolver(const char* name) { + auto address = evas_gl_proc_address_get(evas_gl_, name); + if (address != nullptr) { + return reinterpret_cast(address); + } +#define GL_FUNC(FunctionName) \ + else if (strcmp(name, #FunctionName) == 0) { \ + return reinterpret_cast(FunctionName); \ + } + 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(glBlendEquationSeparate) + GL_FUNC(glBlendFunc) + GL_FUNC(glBlendFuncSeparate) + GL_FUNC(glBufferData) + GL_FUNC(glBufferSubData) + GL_FUNC(glCheckFramebufferStatus) + GL_FUNC(glClear) + GL_FUNC(glClearColor) + GL_FUNC(glClearDepthf) + GL_FUNC(glClearStencil) + GL_FUNC(glColorMask) + GL_FUNC(glCompileShader) + GL_FUNC(glCompressedTexImage2D) + GL_FUNC(glCompressedTexSubImage2D) + GL_FUNC(glCopyTexImage2D) + 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(glDepthFunc) + GL_FUNC(glDepthMask) + GL_FUNC(glDepthRangef) + GL_FUNC(glDetachShader) + 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(glGetActiveAttrib) + GL_FUNC(glGetActiveUniform) + GL_FUNC(glGetAttachedShaders) + GL_FUNC(glGetAttribLocation) + GL_FUNC(glGetBooleanv) + GL_FUNC(glGetBufferParameteriv) + GL_FUNC(glGetError) + GL_FUNC(glGetFloatv) + GL_FUNC(glGetFramebufferAttachmentParameteriv) + GL_FUNC(glGetIntegerv) + GL_FUNC(glGetProgramiv) + GL_FUNC(glGetProgramInfoLog) + GL_FUNC(glGetRenderbufferParameteriv) + GL_FUNC(glGetShaderiv) + GL_FUNC(glGetShaderInfoLog) + GL_FUNC(glGetShaderPrecisionFormat) + GL_FUNC(glGetShaderSource) + GL_FUNC(glGetString) + GL_FUNC(glGetTexParameterfv) + GL_FUNC(glGetTexParameteriv) + GL_FUNC(glGetUniformfv) + GL_FUNC(glGetUniformiv) + GL_FUNC(glGetUniformLocation) + GL_FUNC(glGetVertexAttribfv) + GL_FUNC(glGetVertexAttribiv) + GL_FUNC(glGetVertexAttribPointerv) + GL_FUNC(glHint) + GL_FUNC(glIsBuffer) + GL_FUNC(glIsEnabled) + GL_FUNC(glIsFramebuffer) + GL_FUNC(glIsProgram) + GL_FUNC(glIsRenderbuffer) + GL_FUNC(glIsShader) + GL_FUNC(glIsTexture) + GL_FUNC(glLineWidth) + GL_FUNC(glLinkProgram) + GL_FUNC(glPixelStorei) + GL_FUNC(glPolygonOffset) + GL_FUNC(glReadPixels) + GL_FUNC(glReleaseShaderCompiler) + GL_FUNC(glRenderbufferStorage) + GL_FUNC(glSampleCoverage) + GL_FUNC(glScissor) + GL_FUNC(glShaderBinary) + 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(glValidateProgram) + GL_FUNC(glVertexAttrib1f) + GL_FUNC(glVertexAttrib1fv) + GL_FUNC(glVertexAttrib2f) + GL_FUNC(glVertexAttrib2fv) + GL_FUNC(glVertexAttrib3f) + GL_FUNC(glVertexAttrib3fv) + GL_FUNC(glVertexAttrib4f) + GL_FUNC(glVertexAttrib4fv) + GL_FUNC(glVertexAttribPointer) + GL_FUNC(glViewport) + GL_FUNC(glGetProgramBinaryOES) + GL_FUNC(glProgramBinaryOES) + GL_FUNC(glMapBufferOES) + GL_FUNC(glUnmapBufferOES) + GL_FUNC(glGetBufferPointervOES) + GL_FUNC(glTexImage3DOES) + GL_FUNC(glTexSubImage3DOES) + GL_FUNC(glCopyTexSubImage3DOES) + GL_FUNC(glCompressedTexImage3DOES) + GL_FUNC(glCompressedTexSubImage3DOES) + GL_FUNC(glFramebufferTexture3DOES) + GL_FUNC(glBindVertexArrayOES) + GL_FUNC(glDeleteVertexArraysOES) + GL_FUNC(glGenVertexArraysOES) + GL_FUNC(glIsVertexArrayOES) + GL_FUNC(glGetPerfMonitorGroupsAMD) + GL_FUNC(glGetPerfMonitorCountersAMD) + GL_FUNC(glGetPerfMonitorGroupStringAMD) + GL_FUNC(glGetPerfMonitorCounterStringAMD) + GL_FUNC(glGetPerfMonitorCounterInfoAMD) + GL_FUNC(glGenPerfMonitorsAMD) + GL_FUNC(glDeletePerfMonitorsAMD) + GL_FUNC(glSelectPerfMonitorCountersAMD) + GL_FUNC(glBeginPerfMonitorAMD) + GL_FUNC(glEndPerfMonitorAMD) + GL_FUNC(glGetPerfMonitorCounterDataAMD) + GL_FUNC(glCopyTextureLevelsAPPLE) + GL_FUNC(glRenderbufferStorageMultisampleAPPLE) + GL_FUNC(glResolveMultisampleFramebufferAPPLE) + GL_FUNC(glFenceSyncAPPLE) + GL_FUNC(glIsSyncAPPLE) + GL_FUNC(glDeleteSyncAPPLE) + GL_FUNC(glClientWaitSyncAPPLE) + GL_FUNC(glWaitSyncAPPLE) + GL_FUNC(glGetInteger64vAPPLE) + GL_FUNC(glGetSyncivAPPLE) + GL_FUNC(glDiscardFramebufferEXT) + GL_FUNC(glMapBufferRangeEXT) + GL_FUNC(glFlushMappedBufferRangeEXT) + GL_FUNC(glMultiDrawArraysEXT) + GL_FUNC(glMultiDrawElementsEXT) + GL_FUNC(glRenderbufferStorageMultisampleEXT) + GL_FUNC(glFramebufferTexture2DMultisampleEXT) + GL_FUNC(glGetGraphicsResetStatusEXT) + GL_FUNC(glReadnPixelsEXT) + GL_FUNC(glGetnUniformfvEXT) + GL_FUNC(glGetnUniformivEXT) + GL_FUNC(glTexStorage1DEXT) + GL_FUNC(glTexStorage2DEXT) + GL_FUNC(glTexStorage3DEXT) + GL_FUNC(glTextureStorage1DEXT) + GL_FUNC(glTextureStorage2DEXT) + GL_FUNC(glTextureStorage3DEXT) + GL_FUNC(glRenderbufferStorageMultisampleIMG) + GL_FUNC(glFramebufferTexture2DMultisampleIMG) + GL_FUNC(glDeleteFencesNV) + GL_FUNC(glGenFencesNV) + GL_FUNC(glIsFenceNV) + GL_FUNC(glTestFenceNV) + GL_FUNC(glGetFenceivNV) + GL_FUNC(glFinishFenceNV) + GL_FUNC(glSetFenceNV) + GL_FUNC(glGetDriverControlsQCOM) + GL_FUNC(glGetDriverControlStringQCOM) + GL_FUNC(glEnableDriverControlQCOM) + GL_FUNC(glDisableDriverControlQCOM) + GL_FUNC(glExtGetTexturesQCOM) + GL_FUNC(glExtGetBuffersQCOM) + GL_FUNC(glExtGetRenderbuffersQCOM) + GL_FUNC(glExtGetFramebuffersQCOM) + GL_FUNC(glExtGetTexLevelParameterivQCOM) + GL_FUNC(glExtTexObjectStateOverrideiQCOM) + GL_FUNC(glExtGetTexSubImageQCOM) + GL_FUNC(glExtGetBufferPointervQCOM) + GL_FUNC(glExtGetShadersQCOM) + GL_FUNC(glExtGetProgramsQCOM) + GL_FUNC(glExtIsProgramBinaryQCOM) + GL_FUNC(glExtGetProgramBinarySourceQCOM) + GL_FUNC(glStartTilingQCOM) + GL_FUNC(glEndTilingQCOM) + GL_FUNC(glEvasGLImageTargetTexture2DOES) + GL_FUNC(glEvasGLImageTargetRenderbufferStorageOES) + GL_FUNC(glBeginQuery) + GL_FUNC(glBeginTransformFeedback) + GL_FUNC(glBindBufferBase) + GL_FUNC(glBindBufferRange) + GL_FUNC(glBindSampler) + GL_FUNC(glBindTransformFeedback) + GL_FUNC(glBindVertexArray) + GL_FUNC(glBlitFramebuffer) + GL_FUNC(glClearBufferfi) + GL_FUNC(glClearBufferfv) + GL_FUNC(glClearBufferiv) + GL_FUNC(glClearBufferuiv) + GL_FUNC(glClientWaitSync) + GL_FUNC(glCompressedTexImage3D) + GL_FUNC(glCompressedTexSubImage3D) + GL_FUNC(glCopyBufferSubData) + GL_FUNC(glCopyTexSubImage3D) + GL_FUNC(glDeleteQueries) + GL_FUNC(glDeleteSamplers) + GL_FUNC(glDeleteSync) + GL_FUNC(glDeleteTransformFeedbacks) + GL_FUNC(glDeleteVertexArrays) + GL_FUNC(glDrawArraysInstanced) + GL_FUNC(glDrawBuffers) + GL_FUNC(glDrawElementsInstanced) + GL_FUNC(glDrawRangeElements) + GL_FUNC(glEndQuery) + GL_FUNC(glEndTransformFeedback) + GL_FUNC(glFenceSync) + GL_FUNC(glFlushMappedBufferRange) + GL_FUNC(glFramebufferTextureLayer) + GL_FUNC(glGenQueries) + GL_FUNC(glGenSamplers) + GL_FUNC(glGenTransformFeedbacks) + GL_FUNC(glGenVertexArrays) + GL_FUNC(glGetActiveUniformBlockiv) + GL_FUNC(glGetActiveUniformBlockName) + GL_FUNC(glGetActiveUniformsiv) + GL_FUNC(glGetBufferParameteri64v) + GL_FUNC(glGetBufferPointerv) + GL_FUNC(glGetFragDataLocation) + GL_FUNC(glGetInteger64i_v) + GL_FUNC(glGetInteger64v) + GL_FUNC(glGetIntegeri_v) + GL_FUNC(glGetInternalformativ) + GL_FUNC(glGetProgramBinary) + GL_FUNC(glGetQueryiv) + GL_FUNC(glGetQueryObjectuiv) + GL_FUNC(glGetSamplerParameterfv) + GL_FUNC(glGetSamplerParameteriv) + GL_FUNC(glGetStringi) + GL_FUNC(glGetSynciv) + GL_FUNC(glGetTransformFeedbackVarying) + GL_FUNC(glGetUniformBlockIndex) + GL_FUNC(glGetUniformIndices) + GL_FUNC(glGetUniformuiv) + GL_FUNC(glGetVertexAttribIiv) + GL_FUNC(glGetVertexAttribIuiv) + GL_FUNC(glInvalidateFramebuffer) + GL_FUNC(glInvalidateSubFramebuffer) + GL_FUNC(glIsQuery) + GL_FUNC(glIsSampler) + GL_FUNC(glIsSync) + GL_FUNC(glIsTransformFeedback) + GL_FUNC(glIsVertexArray) + GL_FUNC(glMapBufferRange) + GL_FUNC(glPauseTransformFeedback) + GL_FUNC(glProgramBinary) + GL_FUNC(glProgramParameteri) + GL_FUNC(glReadBuffer) + GL_FUNC(glRenderbufferStorageMultisample) + GL_FUNC(glResumeTransformFeedback) + GL_FUNC(glSamplerParameterf) + GL_FUNC(glSamplerParameterfv) + GL_FUNC(glSamplerParameteri) + GL_FUNC(glSamplerParameteriv) + GL_FUNC(glTexImage3D) + GL_FUNC(glTexStorage2D) + GL_FUNC(glTexStorage3D) + GL_FUNC(glTexSubImage3D) + GL_FUNC(glTransformFeedbackVaryings) + GL_FUNC(glUniform1ui) + GL_FUNC(glUniform1uiv) + GL_FUNC(glUniform2ui) + GL_FUNC(glUniform2uiv) + GL_FUNC(glUniform3ui) + GL_FUNC(glUniform3uiv) + GL_FUNC(glUniform4ui) + GL_FUNC(glUniform4uiv) + GL_FUNC(glUniformBlockBinding) + GL_FUNC(glUniformMatrix2x3fv) + GL_FUNC(glUniformMatrix3x2fv) + GL_FUNC(glUniformMatrix2x4fv) + GL_FUNC(glUniformMatrix4x2fv) + GL_FUNC(glUniformMatrix3x4fv) + GL_FUNC(glUniformMatrix4x3fv) + GL_FUNC(glUnmapBuffer) + GL_FUNC(glVertexAttribDivisor) + GL_FUNC(glVertexAttribI4i) + GL_FUNC(glVertexAttribI4iv) + GL_FUNC(glVertexAttribI4ui) + GL_FUNC(glVertexAttribI4uiv) + GL_FUNC(glVertexAttribIPointer) + GL_FUNC(glWaitSync) + GL_FUNC(glDispatchCompute) + GL_FUNC(glDispatchComputeIndirect) + GL_FUNC(glDrawArraysIndirect) + GL_FUNC(glDrawElementsIndirect) + GL_FUNC(glFramebufferParameteri) + GL_FUNC(glGetFramebufferParameteriv) + GL_FUNC(glGetProgramInterfaceiv) + GL_FUNC(glGetProgramResourceIndex) + GL_FUNC(glGetProgramResourceName) + GL_FUNC(glGetProgramResourceiv) + GL_FUNC(glGetProgramResourceLocation) + GL_FUNC(glUseProgramStages) + GL_FUNC(glActiveShaderProgram) + GL_FUNC(glCreateShaderProgramv) + GL_FUNC(glBindProgramPipeline) + GL_FUNC(glDeleteProgramPipelines) + GL_FUNC(glGenProgramPipelines) + GL_FUNC(glIsProgramPipeline) + GL_FUNC(glGetProgramPipelineiv) + GL_FUNC(glProgramUniform1i) + GL_FUNC(glProgramUniform2i) + GL_FUNC(glProgramUniform3i) + GL_FUNC(glProgramUniform4i) + GL_FUNC(glProgramUniform1ui) + GL_FUNC(glProgramUniform2ui) + GL_FUNC(glProgramUniform3ui) + GL_FUNC(glProgramUniform4ui) + GL_FUNC(glProgramUniform1f) + GL_FUNC(glProgramUniform2f) + GL_FUNC(glProgramUniform3f) + GL_FUNC(glProgramUniform4f) + GL_FUNC(glProgramUniform1iv) + GL_FUNC(glProgramUniform2iv) + GL_FUNC(glProgramUniform3iv) + GL_FUNC(glProgramUniform4iv) + GL_FUNC(glProgramUniform1uiv) + GL_FUNC(glProgramUniform2uiv) + GL_FUNC(glProgramUniform3uiv) + GL_FUNC(glProgramUniform4uiv) + GL_FUNC(glProgramUniform1fv) + GL_FUNC(glProgramUniform2fv) + GL_FUNC(glProgramUniform3fv) + GL_FUNC(glProgramUniform4fv) + GL_FUNC(glProgramUniformMatrix2fv) + GL_FUNC(glProgramUniformMatrix3fv) + GL_FUNC(glProgramUniformMatrix4fv) + GL_FUNC(glProgramUniformMatrix2x3fv) + GL_FUNC(glProgramUniformMatrix3x2fv) + GL_FUNC(glProgramUniformMatrix2x4fv) + GL_FUNC(glProgramUniformMatrix4x2fv) + GL_FUNC(glProgramUniformMatrix3x4fv) + GL_FUNC(glProgramUniformMatrix4x3fv) + GL_FUNC(glValidateProgramPipeline) + GL_FUNC(glGetProgramPipelineInfoLog) + GL_FUNC(glBindImageTexture) + GL_FUNC(glGetBooleani_v) + GL_FUNC(glMemoryBarrier) + GL_FUNC(glMemoryBarrierByRegion) + GL_FUNC(glTexStorage2DMultisample) + GL_FUNC(glGetMultisamplefv) + GL_FUNC(glSampleMaski) + GL_FUNC(glGetTexLevelParameteriv) + GL_FUNC(glGetTexLevelParameterfv) + GL_FUNC(glBindVertexBuffer) + GL_FUNC(glVertexAttribFormat) + GL_FUNC(glVertexAttribIFormat) + GL_FUNC(glVertexAttribBinding) + GL_FUNC(glVertexBindingDivisor) + GL_FUNC(glBlendBarrier) + GL_FUNC(glCopyImageSubData) + GL_FUNC(glDebugMessageControl) + GL_FUNC(glDebugMessageInsert) + GL_FUNC(glDebugMessageCallback) + GL_FUNC(glGetDebugMessageLog) + GL_FUNC(glPushDebugGroup) + GL_FUNC(glPopDebugGroup) + GL_FUNC(glObjectLabel) + GL_FUNC(glGetObjectLabel) + GL_FUNC(glObjectPtrLabel) + GL_FUNC(glGetObjectPtrLabel) + GL_FUNC(glGetPointerv) + GL_FUNC(glEnablei) + GL_FUNC(glDisablei) + GL_FUNC(glBlendEquationi) + GL_FUNC(glBlendEquationSeparatei) + GL_FUNC(glBlendFunci) + GL_FUNC(glBlendFuncSeparatei) + GL_FUNC(glColorMaski) + GL_FUNC(glIsEnabledi) + GL_FUNC(glDrawElementsBaseVertex) + GL_FUNC(glDrawRangeElementsBaseVertex) + GL_FUNC(glDrawElementsInstancedBaseVertex) + GL_FUNC(glFramebufferTexture) + GL_FUNC(glPrimitiveBoundingBox) + GL_FUNC(glGetGraphicsResetStatus) + GL_FUNC(glReadnPixels) + GL_FUNC(glGetnUniformfv) + GL_FUNC(glGetnUniformiv) + GL_FUNC(glGetnUniformuiv) + GL_FUNC(glMinSampleShading) + GL_FUNC(glPatchParameteri) + GL_FUNC(glTexParameterIiv) + GL_FUNC(glTexParameterIuiv) + GL_FUNC(glGetTexParameterIiv) + GL_FUNC(glGetTexParameterIuiv) + GL_FUNC(glSamplerParameterIiv) + GL_FUNC(glSamplerParameterIuiv) + GL_FUNC(glGetSamplerParameterIiv) + GL_FUNC(glGetSamplerParameterIuiv) + GL_FUNC(glTexBuffer) + GL_FUNC(glTexBufferRange) + GL_FUNC(glTexStorage3DMultisample) +#undef GL_FUNC + + FT_LOGD("Could not resolve: %s", name); + return nullptr; +} + +TizenRenderer::TizenWindowGeometry TizenRendererEvasGL::GetGeometry() { + TizenWindowGeometry result; + evas_object_geometry_get(evas_window_, &result.x, &result.y, &result.w, + &result.h); + return result; +} + +uintptr_t TizenRendererEvasGL::GetWindowId() { + return ecore_evas_window_get( + ecore_evas_ecore_evas_get(evas_object_evas_get(evas_window_))); +} + +void* TizenRendererEvasGL::GetImageHandle() { return (void*)graphics_adapter_; } + +bool TizenRendererEvasGL::InitializeRenderer(int32_t x, int32_t y, int32_t w, + int32_t h) { + if (!SetupEvasGL(x, y, w, h)) { + FT_LOGE("SetupEvasGL fail"); + return false; + } + Show(); + is_valid_ = true; + return true; +} + +void TizenRendererEvasGL::Show() { + evas_object_show((Evas_Object*)GetImageHandle()); + evas_object_show(evas_window_); +} + +void TizenRendererEvasGL::DestroyRenderer() { + DestroyEvasGL(); + DestroyEvasWindow(); +} + +bool TizenRendererEvasGL::SetupEvasGL(int32_t x, int32_t y, int32_t w, + int32_t h) { + evas_gl_ = evas_gl_new( + evas_object_evas_get((Evas_Object*)SetupEvasWindow(x, y, w, h))); + if (!evas_gl_) { + FT_LOGE("SetupEvasWindow fail"); + return false; + } + + g_evas_gl = evas_gl_; + gl_config_ = evas_gl_config_new(); + gl_config_->color_format = EVAS_GL_RGBA_8888; + gl_config_->depth_bits = EVAS_GL_DEPTH_NONE; + gl_config_->stencil_bits = EVAS_GL_STENCIL_NONE; + + gl_context_ = + evas_gl_context_version_create(evas_gl_, NULL, EVAS_GL_GLES_3_X); + gl_resource_context_ = + evas_gl_context_version_create(evas_gl_, gl_context_, EVAS_GL_GLES_3_X); + + if (gl_context_ == nullptr) { + FT_LOGW( + "Failed to create evas gl context with EVAS_GL_GLES_3_X, try to use " + "EVAS_GL_GLES_2_X,"); + gl_context_ = + evas_gl_context_version_create(evas_gl_, NULL, EVAS_GL_GLES_2_X); + gl_resource_context_ = + evas_gl_context_version_create(evas_gl_, gl_context_, EVAS_GL_GLES_2_X); + } + if (gl_context_ == nullptr) { + FT_LOGE("Failed to create evas gl context!"); + FT_RELEASE_ASSERT_NOT_REACHED(); + } + + EVAS_GL_GLOBAL_GLES3_USE(g_evas_gl, gl_context_); + gl_surface_ = evas_gl_surface_create(evas_gl_, gl_config_, w, h); + + gl_resource_surface_ = + evas_gl_pbuffer_surface_create(evas_gl_, gl_config_, w, h, NULL); + + Evas_Native_Surface ns; + evas_gl_native_surface_get(evas_gl_, gl_surface_, &ns); + evas_object_image_native_surface_set((Evas_Object*)GetImageHandle(), &ns); + + return true; +} + +void* TizenRendererEvasGL::SetupEvasWindow(int32_t x, int32_t y, int32_t w, + int32_t h) { + if (w == 0 || h == 0) { + FT_LOGE("Failed to create because of the wrong size"); + return nullptr; + } + elm_config_accel_preference_set("hw:opengl"); + + evas_window_ = elm_win_add(NULL, NULL, ELM_WIN_BASIC); + elm_win_alpha_set(evas_window_, EINA_FALSE); + evas_object_move(evas_window_, x, y); + evas_object_resize(evas_window_, w, h); + evas_object_raise(evas_window_); + + Evas_Object* bg = elm_bg_add(evas_window_); + evas_object_color_set(bg, 0x00, 0x00, 0x00, 0x00); + + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(evas_window_, bg); + + graphics_adapter_ = + evas_object_image_filled_add(evas_object_evas_get(evas_window_)); + evas_object_resize(graphics_adapter_, w, h); + evas_object_move(graphics_adapter_, x, y); + evas_object_image_size_set(graphics_adapter_, w, h); + evas_object_image_alpha_set(graphics_adapter_, EINA_TRUE); + elm_win_resize_object_add(evas_window_, graphics_adapter_); + + int rotations[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(evas_window_, + (const int*)(&rotations), 4); + evas_object_smart_callback_add(evas_window_, "rotation,changed", + RotationEventCb, this); + return (void*)evas_window_; +} + +void TizenRendererEvasGL::DestroyEvasGL() { + evas_gl_surface_destroy(evas_gl_, gl_surface_); + evas_gl_surface_destroy(evas_gl_, gl_resource_surface_); + + evas_gl_context_destroy(evas_gl_, gl_context_); + evas_gl_context_destroy(evas_gl_, gl_resource_context_); + + evas_gl_config_free(gl_config_); + evas_gl_free(evas_gl_); +} + +void TizenRendererEvasGL::DestroyEvasWindow() { + evas_object_del(evas_window_); + evas_object_del(graphics_adapter_); +} + +void TizenRendererEvasGL::RotationEventCb(void* data, Evas_Object* obj, + void* event_info) { + auto* self = reinterpret_cast(data); + // TODO : Use current window rotation degree + FT_UNIMPLEMENTED(); + self->delegate_.OnRotationChange(0); +} + +void TizenRendererEvasGL::SetRotate(int angle) { + elm_win_rotation_set(evas_window_, angle); + received_rotation_ = true; +} + +void TizenRendererEvasGL::ResizeWithRotation(int32_t x, int32_t y, + int32_t width, int32_t height, + int32_t angle) { + evas_object_move(evas_window_, x, y); + evas_object_resize(evas_window_, width, height); + SetRotate(angle); +} + +void TizenRendererEvasGL::SendRotationChangeDone() { + elm_win_wm_rotation_manual_rotation_done(evas_window_); +} diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.h b/shell/platform/tizen/tizen_renderer_evas_gl.h new file mode 100644 index 0000000000000..fe30fe8cb0b86 --- /dev/null +++ b/shell/platform/tizen/tizen_renderer_evas_gl.h @@ -0,0 +1,65 @@ +// Copyright 2021 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_RENDERER_EVAS_GL_H +#define EMBEDDER_TIZEN_RENDERER_EVAS_GL_H + +#undef EFL_BETA_API_SUPPORT +#include +#include +#include + +#include "flutter/shell/platform/tizen/tizen_renderer.h" + +class TizenRendererEvasGL : public TizenRenderer { + public: + explicit TizenRendererEvasGL(TizenRenderer::Delegate& delegate, int32_t x, + int32_t y, int32_t w, int32_t h); + virtual ~TizenRendererEvasGL(); + + bool OnMakeCurrent() override; + bool OnClearCurrent() override; + bool OnMakeResourceCurrent() override; + bool OnPresent() override; + uint32_t OnGetFBO() override; + void* OnProcResolver(const char* name) override; + + TizenWindowGeometry GetGeometry() override; + uintptr_t GetWindowId() override; + + void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, + int32_t angle) override; + void SetRotate(int angle) override; + + void* GetImageHandle(); + + private: + void ClearColor(float r, float g, float b, float a); + + bool InitializeRenderer(int32_t x, int32_t y, int32_t w, int32_t h); + void Show(); + void DestroyRenderer(); + + bool SetupEvasGL(int32_t x, int32_t y, int32_t w, int32_t h); + void* SetupEvasWindow(int32_t x, int32_t y, int32_t w, int32_t h); + void DestroyEvasGL(); + void DestroyEvasWindow(); + + static void RotationEventCb(void* data, Evas_Object* obj, void* event_info); + void SendRotationChangeDone(); + + Evas_Object* evas_window_{nullptr}; + Evas_Object* graphics_adapter_{nullptr}; + + Evas_GL_Config* gl_config_{nullptr}; + Evas_GL* evas_gl_{nullptr}; + + Evas_GL_Context* gl_context_{nullptr}; + Evas_GL_Context* gl_resource_context_{nullptr}; + + Evas_GL_Surface* gl_surface_{nullptr}; + Evas_GL_Surface* gl_resource_surface_{nullptr}; +}; + +#endif // EMBEDDER_TIZEN_RENDERER_ECORE_WL2_H diff --git a/shell/platform/tizen/tizen_vsync_waiter.cc b/shell/platform/tizen/tizen_vsync_waiter.cc index bb88d0fe09180..5dc73529262c2 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.cc +++ b/shell/platform/tizen/tizen_vsync_waiter.cc @@ -23,7 +23,7 @@ TizenVsyncWaiter::TizenVsyncWaiter(TizenEmbedderEngine* engine) : engine_(engine) { if (!CreateTDMVblank()) { FT_LOGE("Failed to create TDM vblank"); - DestoryTDMVblank(); + DestroyTDMVblank(); } else { vblank_thread_queue = eina_thread_queue_new(); vblank_thread_ = @@ -38,7 +38,7 @@ TizenVsyncWaiter::~TizenVsyncWaiter() { ecore_thread_cancel(vblank_thread_); vblank_thread_ = nullptr; } - DestoryTDMVblank(); + DestroyTDMVblank(); } void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { @@ -127,7 +127,7 @@ bool TizenVsyncWaiter::CreateTDMVblank() { return true; } -void TizenVsyncWaiter::DestoryTDMVblank() { +void TizenVsyncWaiter::DestroyTDMVblank() { if (vblank_) { tdm_client_vblank_destroy(vblank_); vblank_ = nullptr; diff --git a/shell/platform/tizen/tizen_vsync_waiter.h b/shell/platform/tizen/tizen_vsync_waiter.h index eb4826d4e7feb..ae1a8e6b94f65 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.h +++ b/shell/platform/tizen/tizen_vsync_waiter.h @@ -20,7 +20,7 @@ class TizenVsyncWaiter { private: bool CreateTDMVblank(); - void DestoryTDMVblank(); + void DestroyTDMVblank(); bool TDMValid(); void SendMessage(int val); static void TdmClientVblankCallback(tdm_client_vblank* vblank, diff --git a/tools/gn b/tools/gn index 98a3e38a44941..5c410216231cb 100755 --- a/tools/gn +++ b/tools/gn @@ -166,7 +166,6 @@ def to_gn_args(args): gn_args['embedder_for_target'] = args.embedder_for_target gn_args['build_tizen_shell'] = args.build_tizen_shell - gn_args['tizen_sdk_4'] = args.tizen_sdk_4 gn_args['enable_coverage'] = args.coverage @@ -454,7 +453,6 @@ def parse_args(args): parser.add_argument('--embedder-for-target', dest='embedder_for_target', action='store_true', default=False) parser.add_argument('--build-tizen-shell', dest='build_tizen_shell', action='store_true', default=False) - parser.add_argument('--tizen-sdk-4', dest='tizen_sdk_4', action='store_true', default=False) parser.add_argument('--coverage', default=False, action='store_true')