From 1b04bca274f79904a7cea48043d71b700c8d5f2a Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 16 Apr 2021 16:18:20 +0200 Subject: [PATCH 1/3] Add support for running flutter engine without UI Signed-off-by: Rafal Walczyna --- shell/platform/tizen/flutter_tizen.cc | 13 ++ shell/platform/tizen/public/flutter_tizen.h | 3 + shell/platform/tizen/tizen_embedder_engine.cc | 144 +++++++++++------- shell/platform/tizen/tizen_embedder_engine.h | 6 +- 4 files changed, 106 insertions(+), 60 deletions(-) diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index 11723b5d55e12..9caa362519dc0 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -35,6 +35,19 @@ FlutterWindowControllerRef FlutterCreateWindow( return state.release(); } +FlutterWindowControllerRef FlutterRunEngine( + const FlutterEngineProperties& engine_properties) { + StartLogging(); + auto state = std::make_unique(); + state->engine = std::make_unique(false); + + if (!state->engine->RunEngine(engine_properties)) { + FT_LOGE("Failed to run the Flutter engine."); + return nullptr; + } + return state.release(); +} + void FlutterDestroyWindow(FlutterWindowControllerRef controller) { if (controller->engine) { controller->engine->StopEngine(); diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index aa72a88d114cc..17e0c5fc91ebe 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -40,6 +40,9 @@ typedef struct { FLUTTER_EXPORT FlutterWindowControllerRef FlutterCreateWindow(const FlutterEngineProperties& engine_properties); +FLUTTER_EXPORT FlutterWindowControllerRef +FlutterRunEngine(const FlutterEngineProperties& engine_properties); + // Returns the plugin registrar handle for the plugin with the given name. // // The name must be unique across the application. diff --git a/shell/platform/tizen/tizen_embedder_engine.cc b/shell/platform/tizen/tizen_embedder_engine.cc index ca04bf11d6f4b..b4760e1320b91 100644 --- a/shell/platform/tizen/tizen_embedder_engine.cc +++ b/shell/platform/tizen/tizen_embedder_engine.cc @@ -39,14 +39,8 @@ static DeviceProfile GetDeviceProfile() { return DeviceProfile::kUnknown; } -TizenEmbedderEngine::TizenEmbedderEngine() +TizenEmbedderEngine::TizenEmbedderEngine(bool initialize_tizen_renderer) : device_profile(GetDeviceProfile()) { -#ifdef TIZEN_RENDERER_EVAS_GL - tizen_renderer = std::make_unique(*this); -#else - tizen_renderer = std::make_unique(*this); -#endif - // 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. @@ -58,7 +52,20 @@ TizenEmbedderEngine::TizenEmbedderEngine() } }); + messenger = std::make_unique(); + messenger->engine = this; + message_dispatcher = + std::make_unique(messenger.get()); + + if (initialize_tizen_renderer) { + InitializeTizenRenderer(); + } +} + +void TizenEmbedderEngine::InitializeTizenRenderer() { #ifdef TIZEN_RENDERER_EVAS_GL + tizen_renderer = std::make_unique(*this); + render_loop_ = std::make_unique( std::this_thread::get_id(), // main thread [this](const auto* task) { @@ -67,14 +74,8 @@ TizenEmbedderEngine::TizenEmbedderEngine() } }, tizen_renderer.get()); -#endif - - messenger = std::make_unique(); - messenger->engine = this; - message_dispatcher = - std::make_unique(messenger.get()); - -#ifndef TIZEN_RENDERER_EVAS_GL +#else + tizen_renderer = std::make_unique(*this); tizen_vsync_waiter_ = std::make_unique(this); #endif } @@ -111,7 +112,7 @@ UniqueAotDataPtr LoadAotData(std::string aot_data_path) { bool TizenEmbedderEngine::RunEngine( const FlutterEngineProperties& engine_properties) { - if (!tizen_renderer->IsValid()) { + if (HasTizenRenderer() && !tizen_renderer->IsValid()) { FT_LOGE("The display was not valid."); return false; } @@ -138,40 +139,46 @@ bool TizenEmbedderEngine::RunEngine( static_cast(data)->PostTask(task, target_time_nanos); }; 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; + if (HasTizenRenderer()) { + 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; + custom_task_runners.render_task_runner = &render_task_runner; + } #endif FlutterRendererConfig config = {}; - config.type = kOpenGL; - config.open_gl.struct_size = sizeof(config.open_gl); - config.open_gl.make_current = MakeContextCurrent; - config.open_gl.make_resource_current = MakeResourceCurrent; - config.open_gl.clear_current = ClearContext; - config.open_gl.present = Present; - config.open_gl.fbo_callback = GetActiveFbo; - config.open_gl.surface_transformation = Transformation; - config.open_gl.gl_proc_resolver = GlProcResolver; - config.open_gl.gl_external_texture_frame_callback = OnAcquireExternalTexture; + if (HasTizenRenderer()) { + config.type = kOpenGL; + config.open_gl.struct_size = sizeof(config.open_gl); + config.open_gl.make_current = MakeContextCurrent; + config.open_gl.make_resource_current = MakeResourceCurrent; + config.open_gl.clear_current = ClearContext; + config.open_gl.present = Present; + config.open_gl.fbo_callback = GetActiveFbo; + config.open_gl.surface_transformation = Transformation; + config.open_gl.gl_proc_resolver = GlProcResolver; + config.open_gl.gl_external_texture_frame_callback = + OnAcquireExternalTexture; + } else { + config.type = kSoftware; + config.software.struct_size = sizeof(config.software); + config.software.surface_present_callback = SurfacePresentCallback; + } FlutterProjectArgs args = {}; args.struct_size = sizeof(FlutterProjectArgs); @@ -181,8 +188,11 @@ 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; + if (HasTizenRenderer()) { + args.vsync_callback = OnVsyncCallback; + } #endif if (FlutterEngineRunsAOTCompiledDartCode()) { @@ -203,36 +213,40 @@ bool TizenEmbedderEngine::RunEngine( return false; } - std::unique_ptr textures = - std::make_unique(); - textures->flutter_engine = flutter_engine; plugin_registrar_ = std::make_unique(); plugin_registrar_->engine = this; - plugin_registrar_->texture_registrar = std::move(textures); internal_plugin_registrar_ = std::make_unique(plugin_registrar_.get()); - key_event_channel = std::make_unique( - internal_plugin_registrar_->messenger()); - navigation_channel = std::make_unique( - internal_plugin_registrar_->messenger()); platform_channel = std::make_unique( internal_plugin_registrar_->messenger()); settings_channel = std::make_unique( internal_plugin_registrar_->messenger()); - text_input_channel = std::make_unique( - internal_plugin_registrar_->messenger(), this); localization_channel = std::make_unique(flutter_engine); localization_channel->SendLocales(); lifecycle_channel = std::make_unique(flutter_engine); - platform_view_channel = std::make_unique( - internal_plugin_registrar_->messenger(), this); - key_event_handler_ = std::make_unique(this); - touch_event_handler_ = std::make_unique(this); + if (HasTizenRenderer()) { + std::unique_ptr textures = + std::make_unique(); + textures->flutter_engine = flutter_engine; + plugin_registrar_->texture_registrar = std::move(textures); + + key_event_channel = std::make_unique( + internal_plugin_registrar_->messenger()); + navigation_channel = std::make_unique( + internal_plugin_registrar_->messenger()); + text_input_channel = std::make_unique( + internal_plugin_registrar_->messenger(), this); + platform_view_channel = std::make_unique( + internal_plugin_registrar_->messenger(), this); + key_event_handler_ = std::make_unique(this); + touch_event_handler_ = std::make_unique(this); + + SetWindowOrientation(0); + } - SetWindowOrientation(0); return true; } @@ -394,6 +408,14 @@ FlutterDesktopMessage TizenEmbedderEngine::ConvertToDesktopMessage( return message; } +bool TizenEmbedderEngine::SurfacePresentCallback(void* user_data, + const void* allocation, + size_t row_bytes, + size_t height) { + FT_LOGD("SurfacePresentCallback"); + return true; +} + bool TizenEmbedderEngine::MakeContextCurrent(void* user_data) { return reinterpret_cast(user_data) ->tizen_renderer->OnMakeCurrent(); @@ -427,3 +449,7 @@ void* TizenEmbedderEngine::GlProcResolver(void* user_data, const char* name) { return reinterpret_cast(user_data) ->tizen_renderer->OnProcResolver(name); } + +bool TizenEmbedderEngine::HasTizenRenderer() { + return tizen_renderer != nullptr; +} diff --git a/shell/platform/tizen/tizen_embedder_engine.h b/shell/platform/tizen/tizen_embedder_engine.h index 38b83699d5f03..8c97af179af79 100644 --- a/shell/platform/tizen/tizen_embedder_engine.h +++ b/shell/platform/tizen/tizen_embedder_engine.h @@ -69,8 +69,9 @@ enum DeviceProfile { kUnknown, kMobile, kWearable, kTV, kCommon }; // Manages state associated with the underlying FlutterEngine. class TizenEmbedderEngine : public TizenRenderer::Delegate { public: - explicit TizenEmbedderEngine(); + explicit TizenEmbedderEngine(bool initialize_tizen_renderer = true); virtual ~TizenEmbedderEngine(); + void InitializeTizenRenderer(); bool RunEngine(const FlutterEngineProperties& engine_properties); bool StopEngine(); @@ -115,6 +116,7 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate { const DeviceProfile device_profile; private: + static bool SurfacePresentCallback(void*, const void*, size_t, size_t); static bool MakeContextCurrent(void* user_data); static bool ClearContext(void* user_data); static bool Present(void* user_data); @@ -134,6 +136,8 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate { size_t width, size_t height, FlutterOpenGLTexture* texture); + bool HasTizenRenderer(); + // The handlers listening to platform events. std::unique_ptr key_event_handler_; std::unique_ptr touch_event_handler_; From 36ae14123e1f3a3513a7a52576407795c5233c91 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Wed, 28 Apr 2021 12:43:16 +0200 Subject: [PATCH 2/3] Change surface_present_callback to lambda function Signed-off-by: Rafal Walczyna --- shell/platform/tizen/tizen_embedder_engine.cc | 12 +++--------- shell/platform/tizen/tizen_embedder_engine.h | 1 - 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/shell/platform/tizen/tizen_embedder_engine.cc b/shell/platform/tizen/tizen_embedder_engine.cc index b4760e1320b91..afa5b00b29b65 100644 --- a/shell/platform/tizen/tizen_embedder_engine.cc +++ b/shell/platform/tizen/tizen_embedder_engine.cc @@ -177,7 +177,9 @@ bool TizenEmbedderEngine::RunEngine( } else { config.type = kSoftware; config.software.struct_size = sizeof(config.software); - config.software.surface_present_callback = SurfacePresentCallback; + config.software.surface_present_callback = + [](void* user_data, const void* allocation, size_t row_bytes, + size_t height) -> bool { return true; }; } FlutterProjectArgs args = {}; @@ -408,14 +410,6 @@ FlutterDesktopMessage TizenEmbedderEngine::ConvertToDesktopMessage( return message; } -bool TizenEmbedderEngine::SurfacePresentCallback(void* user_data, - const void* allocation, - size_t row_bytes, - size_t height) { - FT_LOGD("SurfacePresentCallback"); - return true; -} - bool TizenEmbedderEngine::MakeContextCurrent(void* user_data) { return reinterpret_cast(user_data) ->tizen_renderer->OnMakeCurrent(); diff --git a/shell/platform/tizen/tizen_embedder_engine.h b/shell/platform/tizen/tizen_embedder_engine.h index 8c97af179af79..bf0643fcc0439 100644 --- a/shell/platform/tizen/tizen_embedder_engine.h +++ b/shell/platform/tizen/tizen_embedder_engine.h @@ -116,7 +116,6 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate { const DeviceProfile device_profile; private: - static bool SurfacePresentCallback(void*, const void*, size_t, size_t); static bool MakeContextCurrent(void* user_data); static bool ClearContext(void* user_data); static bool Present(void* user_data); From 055bd47f216fa1d6ec73a6166f20a37d4d9ebc96 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Wed, 28 Apr 2021 17:05:27 +0200 Subject: [PATCH 3/3] Fix nullptr exception when TIZEN_RENDERER_EVAS_GL was used Signed-off-by: Rafal Walczyna --- shell/platform/tizen/tizen_embedder_engine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/tizen/tizen_embedder_engine.cc b/shell/platform/tizen/tizen_embedder_engine.cc index afa5b00b29b65..7e8ac9217bc0c 100644 --- a/shell/platform/tizen/tizen_embedder_engine.cc +++ b/shell/platform/tizen/tizen_embedder_engine.cc @@ -144,8 +144,8 @@ bool TizenEmbedderEngine::RunEngine( custom_task_runners.platform_task_runner = &platform_task_runner; #ifdef TIZEN_RENDERER_EVAS_GL + FlutterTaskRunnerDescription render_task_runner = {}; if (HasTizenRenderer()) { - 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 =