Skip to content

Commit

Permalink
Add support for running flutter engine without UI (flutter-tizen#66)
Browse files Browse the repository at this point in the history
* Add support for running flutter engine without UI

Signed-off-by: Rafal Walczyna <[email protected]>

* Change surface_present_callback to lambda function

Signed-off-by: Rafal Walczyna <[email protected]>

* Fix nullptr exception when TIZEN_RENDERER_EVAS_GL was used

Signed-off-by: Rafal Walczyna <[email protected]>
  • Loading branch information
rwalczyna authored and swift-kim committed Nov 14, 2021
1 parent d98e894 commit ce8c67b
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 60 deletions.
13 changes: 13 additions & 0 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ FlutterWindowControllerRef FlutterCreateWindow(
return state.release();
}

FlutterWindowControllerRef FlutterRunEngine(
const FlutterEngineProperties& engine_properties) {
StartLogging();
auto state = std::make_unique<FlutterWindowControllerState>();
state->engine = std::make_unique<TizenEmbedderEngine>(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();
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/tizen/public/flutter_tizen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
138 changes: 79 additions & 59 deletions shell/platform/tizen/tizen_embedder_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<TizenRendererEvasGL>(*this);
#else
tizen_renderer = std::make_unique<TizenRendererEcoreWl2>(*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.
Expand All @@ -58,7 +52,20 @@ TizenEmbedderEngine::TizenEmbedderEngine()
}
});

messenger = std::make_unique<FlutterDesktopMessenger>();
messenger->engine = this;
message_dispatcher =
std::make_unique<flutter::IncomingMessageDispatcher>(messenger.get());

if (initialize_tizen_renderer) {
InitializeTizenRenderer();
}
}

void TizenEmbedderEngine::InitializeTizenRenderer() {
#ifdef TIZEN_RENDERER_EVAS_GL
tizen_renderer = std::make_unique<TizenRendererEvasGL>(*this);

render_loop_ = std::make_unique<TizenRenderEventLoop>(
std::this_thread::get_id(), // main thread
[this](const auto* task) {
Expand All @@ -67,14 +74,8 @@ TizenEmbedderEngine::TizenEmbedderEngine()
}
},
tizen_renderer.get());
#endif

messenger = std::make_unique<FlutterDesktopMessenger>();
messenger->engine = this;
message_dispatcher =
std::make_unique<flutter::IncomingMessageDispatcher>(messenger.get());

#ifndef TIZEN_RENDERER_EVAS_GL
#else
tizen_renderer = std::make_unique<TizenRendererEcoreWl2>(*this);
tizen_vsync_waiter_ = std::make_unique<TizenVsyncWaiter>(this);
#endif
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -138,40 +139,48 @@ bool TizenEmbedderEngine::RunEngine(
static_cast<TizenEventLoop*>(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<TizenEventLoop*>(data)->RunsTasksOnCurrentThread();
};
render_task_runner.post_task_callback =
[](FlutterTask task, uint64_t target_time_nanos, void* data) -> void {
static_cast<TizenEventLoop*>(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<TizenEventLoop*>(data)->RunsTasksOnCurrentThread();
};
render_task_runner.post_task_callback =
[](FlutterTask task, uint64_t target_time_nanos, void* data) -> void {
static_cast<TizenEventLoop*>(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);
Expand All @@ -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()) {
Expand All @@ -203,36 +215,40 @@ bool TizenEmbedderEngine::RunEngine(
return false;
}

std::unique_ptr<FlutterTextureRegistrar> textures =
std::make_unique<FlutterTextureRegistrar>();
textures->flutter_engine = flutter_engine;
plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
plugin_registrar_->engine = this;
plugin_registrar_->texture_registrar = std::move(textures);

internal_plugin_registrar_ =
std::make_unique<flutter::PluginRegistrar>(plugin_registrar_.get());

key_event_channel = std::make_unique<KeyEventChannel>(
internal_plugin_registrar_->messenger());
navigation_channel = std::make_unique<NavigationChannel>(
internal_plugin_registrar_->messenger());
platform_channel = std::make_unique<PlatformChannel>(
internal_plugin_registrar_->messenger());
settings_channel = std::make_unique<SettingsChannel>(
internal_plugin_registrar_->messenger());
text_input_channel = std::make_unique<TextInputChannel>(
internal_plugin_registrar_->messenger(), this);
localization_channel = std::make_unique<LocalizationChannel>(flutter_engine);
localization_channel->SendLocales();
lifecycle_channel = std::make_unique<LifecycleChannel>(flutter_engine);
platform_view_channel = std::make_unique<PlatformViewChannel>(
internal_plugin_registrar_->messenger(), this);

key_event_handler_ = std::make_unique<KeyEventHandler>(this);
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);
if (HasTizenRenderer()) {
std::unique_ptr<FlutterTextureRegistrar> textures =
std::make_unique<FlutterTextureRegistrar>();
textures->flutter_engine = flutter_engine;
plugin_registrar_->texture_registrar = std::move(textures);

key_event_channel = std::make_unique<KeyEventChannel>(
internal_plugin_registrar_->messenger());
navigation_channel = std::make_unique<NavigationChannel>(
internal_plugin_registrar_->messenger());
text_input_channel = std::make_unique<TextInputChannel>(
internal_plugin_registrar_->messenger(), this);
platform_view_channel = std::make_unique<PlatformViewChannel>(
internal_plugin_registrar_->messenger(), this);
key_event_handler_ = std::make_unique<KeyEventHandler>(this);
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);

SetWindowOrientation(0);
}

SetWindowOrientation(0);
return true;
}

Expand Down Expand Up @@ -427,3 +443,7 @@ void* TizenEmbedderEngine::GlProcResolver(void* user_data, const char* name) {
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
->tizen_renderer->OnProcResolver(name);
}

bool TizenEmbedderEngine::HasTizenRenderer() {
return tizen_renderer != nullptr;
}
5 changes: 4 additions & 1 deletion shell/platform/tizen/tizen_embedder_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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<KeyEventHandler> key_event_handler_;
std::unique_ptr<TouchEventHandler> touch_event_handler_;
Expand Down

0 comments on commit ce8c67b

Please sign in to comment.