Skip to content

Commit ce8c67b

Browse files
rwalczynaswift-kim
authored andcommitted
Add support for running flutter engine without UI (#66)
* 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]>
1 parent d98e894 commit ce8c67b

File tree

4 files changed

+99
-60
lines changed

4 files changed

+99
-60
lines changed

shell/platform/tizen/flutter_tizen.cc

+13
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ FlutterWindowControllerRef FlutterCreateWindow(
3535
return state.release();
3636
}
3737

38+
FlutterWindowControllerRef FlutterRunEngine(
39+
const FlutterEngineProperties& engine_properties) {
40+
StartLogging();
41+
auto state = std::make_unique<FlutterWindowControllerState>();
42+
state->engine = std::make_unique<TizenEmbedderEngine>(false);
43+
44+
if (!state->engine->RunEngine(engine_properties)) {
45+
FT_LOGE("Failed to run the Flutter engine.");
46+
return nullptr;
47+
}
48+
return state.release();
49+
}
50+
3851
void FlutterDestroyWindow(FlutterWindowControllerRef controller) {
3952
if (controller->engine) {
4053
controller->engine->StopEngine();

shell/platform/tizen/public/flutter_tizen.h

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ typedef struct {
4040
FLUTTER_EXPORT FlutterWindowControllerRef
4141
FlutterCreateWindow(const FlutterEngineProperties& engine_properties);
4242

43+
FLUTTER_EXPORT FlutterWindowControllerRef
44+
FlutterRunEngine(const FlutterEngineProperties& engine_properties);
45+
4346
// Returns the plugin registrar handle for the plugin with the given name.
4447
//
4548
// The name must be unique across the application.

shell/platform/tizen/tizen_embedder_engine.cc

+79-59
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,8 @@ static DeviceProfile GetDeviceProfile() {
3939
return DeviceProfile::kUnknown;
4040
}
4141

42-
TizenEmbedderEngine::TizenEmbedderEngine()
42+
TizenEmbedderEngine::TizenEmbedderEngine(bool initialize_tizen_renderer)
4343
: device_profile(GetDeviceProfile()) {
44-
#ifdef TIZEN_RENDERER_EVAS_GL
45-
tizen_renderer = std::make_unique<TizenRendererEvasGL>(*this);
46-
#else
47-
tizen_renderer = std::make_unique<TizenRendererEcoreWl2>(*this);
48-
#endif
49-
5044
// Run flutter task on Tizen main loop.
5145
// Tizen engine has four threads (GPU thread, UI thread, IO thread, platform
5246
// thread). UI threads need to send flutter task to platform thread.
@@ -58,7 +52,20 @@ TizenEmbedderEngine::TizenEmbedderEngine()
5852
}
5953
});
6054

55+
messenger = std::make_unique<FlutterDesktopMessenger>();
56+
messenger->engine = this;
57+
message_dispatcher =
58+
std::make_unique<flutter::IncomingMessageDispatcher>(messenger.get());
59+
60+
if (initialize_tizen_renderer) {
61+
InitializeTizenRenderer();
62+
}
63+
}
64+
65+
void TizenEmbedderEngine::InitializeTizenRenderer() {
6166
#ifdef TIZEN_RENDERER_EVAS_GL
67+
tizen_renderer = std::make_unique<TizenRendererEvasGL>(*this);
68+
6269
render_loop_ = std::make_unique<TizenRenderEventLoop>(
6370
std::this_thread::get_id(), // main thread
6471
[this](const auto* task) {
@@ -67,14 +74,8 @@ TizenEmbedderEngine::TizenEmbedderEngine()
6774
}
6875
},
6976
tizen_renderer.get());
70-
#endif
71-
72-
messenger = std::make_unique<FlutterDesktopMessenger>();
73-
messenger->engine = this;
74-
message_dispatcher =
75-
std::make_unique<flutter::IncomingMessageDispatcher>(messenger.get());
76-
77-
#ifndef TIZEN_RENDERER_EVAS_GL
77+
#else
78+
tizen_renderer = std::make_unique<TizenRendererEcoreWl2>(*this);
7879
tizen_vsync_waiter_ = std::make_unique<TizenVsyncWaiter>(this);
7980
#endif
8081
}
@@ -111,7 +112,7 @@ UniqueAotDataPtr LoadAotData(std::string aot_data_path) {
111112

112113
bool TizenEmbedderEngine::RunEngine(
113114
const FlutterEngineProperties& engine_properties) {
114-
if (!tizen_renderer->IsValid()) {
115+
if (HasTizenRenderer() && !tizen_renderer->IsValid()) {
115116
FT_LOGE("The display was not valid.");
116117
return false;
117118
}
@@ -138,40 +139,48 @@ bool TizenEmbedderEngine::RunEngine(
138139
static_cast<TizenEventLoop*>(data)->PostTask(task, target_time_nanos);
139140
};
140141
platform_task_runner.identifier = kPlatformTaskRunnerIdentifier;
141-
142-
#ifdef TIZEN_RENDERER_EVAS_GL
143-
FlutterTaskRunnerDescription render_task_runner = {};
144-
render_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription);
145-
render_task_runner.user_data = render_loop_.get();
146-
render_task_runner.runs_task_on_current_thread_callback =
147-
[](void* data) -> bool {
148-
return static_cast<TizenEventLoop*>(data)->RunsTasksOnCurrentThread();
149-
};
150-
render_task_runner.post_task_callback =
151-
[](FlutterTask task, uint64_t target_time_nanos, void* data) -> void {
152-
static_cast<TizenEventLoop*>(data)->PostTask(task, target_time_nanos);
153-
};
154-
render_task_runner.identifier = kRenderTaskRunnerIdentifier;
155-
#endif
156-
157142
FlutterCustomTaskRunners custom_task_runners = {};
158143
custom_task_runners.struct_size = sizeof(FlutterCustomTaskRunners);
159144
custom_task_runners.platform_task_runner = &platform_task_runner;
145+
160146
#ifdef TIZEN_RENDERER_EVAS_GL
161-
custom_task_runners.render_task_runner = &render_task_runner;
147+
FlutterTaskRunnerDescription render_task_runner = {};
148+
if (HasTizenRenderer()) {
149+
render_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription);
150+
render_task_runner.user_data = render_loop_.get();
151+
render_task_runner.runs_task_on_current_thread_callback =
152+
[](void* data) -> bool {
153+
return static_cast<TizenEventLoop*>(data)->RunsTasksOnCurrentThread();
154+
};
155+
render_task_runner.post_task_callback =
156+
[](FlutterTask task, uint64_t target_time_nanos, void* data) -> void {
157+
static_cast<TizenEventLoop*>(data)->PostTask(task, target_time_nanos);
158+
};
159+
render_task_runner.identifier = kRenderTaskRunnerIdentifier;
160+
custom_task_runners.render_task_runner = &render_task_runner;
161+
}
162162
#endif
163163

164164
FlutterRendererConfig config = {};
165-
config.type = kOpenGL;
166-
config.open_gl.struct_size = sizeof(config.open_gl);
167-
config.open_gl.make_current = MakeContextCurrent;
168-
config.open_gl.make_resource_current = MakeResourceCurrent;
169-
config.open_gl.clear_current = ClearContext;
170-
config.open_gl.present = Present;
171-
config.open_gl.fbo_callback = GetActiveFbo;
172-
config.open_gl.surface_transformation = Transformation;
173-
config.open_gl.gl_proc_resolver = GlProcResolver;
174-
config.open_gl.gl_external_texture_frame_callback = OnAcquireExternalTexture;
165+
if (HasTizenRenderer()) {
166+
config.type = kOpenGL;
167+
config.open_gl.struct_size = sizeof(config.open_gl);
168+
config.open_gl.make_current = MakeContextCurrent;
169+
config.open_gl.make_resource_current = MakeResourceCurrent;
170+
config.open_gl.clear_current = ClearContext;
171+
config.open_gl.present = Present;
172+
config.open_gl.fbo_callback = GetActiveFbo;
173+
config.open_gl.surface_transformation = Transformation;
174+
config.open_gl.gl_proc_resolver = GlProcResolver;
175+
config.open_gl.gl_external_texture_frame_callback =
176+
OnAcquireExternalTexture;
177+
} else {
178+
config.type = kSoftware;
179+
config.software.struct_size = sizeof(config.software);
180+
config.software.surface_present_callback =
181+
[](void* user_data, const void* allocation, size_t row_bytes,
182+
size_t height) -> bool { return true; };
183+
}
175184

176185
FlutterProjectArgs args = {};
177186
args.struct_size = sizeof(FlutterProjectArgs);
@@ -181,8 +190,11 @@ bool TizenEmbedderEngine::RunEngine(
181190
args.command_line_argv = &argv[0];
182191
args.platform_message_callback = OnFlutterPlatformMessage;
183192
args.custom_task_runners = &custom_task_runners;
193+
184194
#ifndef TIZEN_RENDERER_EVAS_GL
185-
args.vsync_callback = OnVsyncCallback;
195+
if (HasTizenRenderer()) {
196+
args.vsync_callback = OnVsyncCallback;
197+
}
186198
#endif
187199

188200
if (FlutterEngineRunsAOTCompiledDartCode()) {
@@ -203,36 +215,40 @@ bool TizenEmbedderEngine::RunEngine(
203215
return false;
204216
}
205217

206-
std::unique_ptr<FlutterTextureRegistrar> textures =
207-
std::make_unique<FlutterTextureRegistrar>();
208-
textures->flutter_engine = flutter_engine;
209218
plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
210219
plugin_registrar_->engine = this;
211-
plugin_registrar_->texture_registrar = std::move(textures);
212220

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

216-
key_event_channel = std::make_unique<KeyEventChannel>(
217-
internal_plugin_registrar_->messenger());
218-
navigation_channel = std::make_unique<NavigationChannel>(
219-
internal_plugin_registrar_->messenger());
220224
platform_channel = std::make_unique<PlatformChannel>(
221225
internal_plugin_registrar_->messenger());
222226
settings_channel = std::make_unique<SettingsChannel>(
223227
internal_plugin_registrar_->messenger());
224-
text_input_channel = std::make_unique<TextInputChannel>(
225-
internal_plugin_registrar_->messenger(), this);
226228
localization_channel = std::make_unique<LocalizationChannel>(flutter_engine);
227229
localization_channel->SendLocales();
228230
lifecycle_channel = std::make_unique<LifecycleChannel>(flutter_engine);
229-
platform_view_channel = std::make_unique<PlatformViewChannel>(
230-
internal_plugin_registrar_->messenger(), this);
231231

232-
key_event_handler_ = std::make_unique<KeyEventHandler>(this);
233-
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);
232+
if (HasTizenRenderer()) {
233+
std::unique_ptr<FlutterTextureRegistrar> textures =
234+
std::make_unique<FlutterTextureRegistrar>();
235+
textures->flutter_engine = flutter_engine;
236+
plugin_registrar_->texture_registrar = std::move(textures);
237+
238+
key_event_channel = std::make_unique<KeyEventChannel>(
239+
internal_plugin_registrar_->messenger());
240+
navigation_channel = std::make_unique<NavigationChannel>(
241+
internal_plugin_registrar_->messenger());
242+
text_input_channel = std::make_unique<TextInputChannel>(
243+
internal_plugin_registrar_->messenger(), this);
244+
platform_view_channel = std::make_unique<PlatformViewChannel>(
245+
internal_plugin_registrar_->messenger(), this);
246+
key_event_handler_ = std::make_unique<KeyEventHandler>(this);
247+
touch_event_handler_ = std::make_unique<TouchEventHandler>(this);
248+
249+
SetWindowOrientation(0);
250+
}
234251

235-
SetWindowOrientation(0);
236252
return true;
237253
}
238254

@@ -427,3 +443,7 @@ void* TizenEmbedderEngine::GlProcResolver(void* user_data, const char* name) {
427443
return reinterpret_cast<TizenEmbedderEngine*>(user_data)
428444
->tizen_renderer->OnProcResolver(name);
429445
}
446+
447+
bool TizenEmbedderEngine::HasTizenRenderer() {
448+
return tizen_renderer != nullptr;
449+
}

shell/platform/tizen/tizen_embedder_engine.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ enum DeviceProfile { kUnknown, kMobile, kWearable, kTV, kCommon };
6969
// Manages state associated with the underlying FlutterEngine.
7070
class TizenEmbedderEngine : public TizenRenderer::Delegate {
7171
public:
72-
explicit TizenEmbedderEngine();
72+
explicit TizenEmbedderEngine(bool initialize_tizen_renderer = true);
7373
virtual ~TizenEmbedderEngine();
74+
void InitializeTizenRenderer();
7475
bool RunEngine(const FlutterEngineProperties& engine_properties);
7576
bool StopEngine();
7677

@@ -134,6 +135,8 @@ class TizenEmbedderEngine : public TizenRenderer::Delegate {
134135
size_t width, size_t height,
135136
FlutterOpenGLTexture* texture);
136137

138+
bool HasTizenRenderer();
139+
137140
// The handlers listening to platform events.
138141
std::unique_ptr<KeyEventHandler> key_event_handler_;
139142
std::unique_ptr<TouchEventHandler> touch_event_handler_;

0 commit comments

Comments
 (0)