From ce8c67b3d5f25b1beeff97427e53b84d26e30d12 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 30 Apr 2021 08:50:33 +0200 Subject: [PATCH] Add support for running flutter engine without UI (#66) * Add support for running flutter engine without UI Signed-off-by: Rafal Walczyna * Change surface_present_callback to lambda function Signed-off-by: Rafal Walczyna * Fix nullptr exception when TIZEN_RENDERER_EVAS_GL was used 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 | 138 ++++++++++-------- shell/platform/tizen/tizen_embedder_engine.h | 5 +- 4 files changed, 99 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..7e8ac9217bc0c 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,48 @@ 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; + FlutterTaskRunnerDescription render_task_runner = {}; + if (HasTizenRenderer()) { + 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 = + [](void* user_data, const void* allocation, size_t row_bytes, + size_t height) -> bool { return true; }; + } FlutterProjectArgs args = {}; args.struct_size = sizeof(FlutterProjectArgs); @@ -181,8 +190,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 +215,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; } @@ -427,3 +443,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..bf0643fcc0439 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(); @@ -134,6 +135,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_;