Flutter Engine
embedder_config_builder.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
6 
7 #include "flutter/runtime/dart_vm.h"
8 #include "flutter/shell/platform/embedder/embedder.h"
9 #include "third_party/skia/include/core/SkBitmap.h"
10 
11 #ifdef SHELL_ENABLE_GL
12 #include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h"
13 #include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h"
14 #endif
15 
16 namespace flutter {
17 namespace testing {
18 
20  EmbedderTestContext& context,
21  InitializationPreference preference)
22  : context_(context) {
23  project_args_.struct_size = sizeof(project_args_);
24  project_args_.shutdown_dart_vm_when_done = true;
25  project_args_.platform_message_callback =
26  [](const FlutterPlatformMessage* message, void* context) {
27  reinterpret_cast<EmbedderTestContext*>(context)
28  ->PlatformMessageCallback(message);
29  };
30 
31  custom_task_runners_.struct_size = sizeof(FlutterCustomTaskRunners);
32 
33 #ifdef SHELL_ENABLE_GL
34  opengl_renderer_config_.struct_size = sizeof(FlutterOpenGLRendererConfig);
35  opengl_renderer_config_.make_current = [](void* context) -> bool {
36  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLMakeCurrent();
37  };
38  opengl_renderer_config_.clear_current = [](void* context) -> bool {
39  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLClearCurrent();
40  };
41  opengl_renderer_config_.present_with_info =
42  [](void* context, const FlutterPresentInfo* present_info) -> bool {
43  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(
44  present_info->fbo_id);
45  };
46  opengl_renderer_config_.fbo_with_frame_info_callback =
47  [](void* context, const FlutterFrameInfo* frame_info) -> uint32_t {
48  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
49  *frame_info);
50  };
51  opengl_renderer_config_.make_resource_current = [](void* context) -> bool {
52  return reinterpret_cast<EmbedderTestContextGL*>(context)
53  ->GLMakeResourceCurrent();
54  };
55  opengl_renderer_config_.gl_proc_resolver = [](void* context,
56  const char* name) -> void* {
57  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetProcAddress(
58  name);
59  };
60  opengl_renderer_config_.fbo_reset_after_present = true;
61  opengl_renderer_config_.surface_transformation =
62  [](void* context) -> FlutterTransformation {
63  return reinterpret_cast<EmbedderTestContext*>(context)
64  ->GetRootSurfaceTransformation();
65  };
66 #endif
67 
68  software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig);
69  software_renderer_config_.surface_present_callback =
70  [](void* context, const void* allocation, size_t row_bytes,
71  size_t height) {
72  auto image_info =
73  SkImageInfo::MakeN32Premul(SkISize::Make(row_bytes / 4, height));
74  SkBitmap bitmap;
75  if (!bitmap.installPixels(image_info, const_cast<void*>(allocation),
76  row_bytes)) {
77  FML_LOG(ERROR) << "Could not copy pixels for the software "
78  "composition from the engine.";
79  return false;
80  }
81  bitmap.setImmutable();
82  return reinterpret_cast<EmbedderTestContextSoftware*>(context)->Present(
83  SkImage::MakeFromBitmap(bitmap));
84  };
85 
86  // The first argument is treated as the executable name. Don't make tests have
87  // to do this manually.
88  AddCommandLineArgument("embedder_unittest");
89 
90  if (preference != InitializationPreference::kNoInitialize) {
91  SetAssetsPath();
95  AddCommandLineArgument("--disable-observatory");
96 
99  SetSnapshots();
100  }
103  SetAOTDataElf();
104  }
105  }
106 }
107 
109 
111  return project_args_;
112 }
113 
115  renderer_config_.type = FlutterRendererType::kSoftware;
116  renderer_config_.software = software_renderer_config_;
117  context_.SetupSurface(surface_size);
118 }
119 
121 #ifdef SHELL_ENABLE_GL
122  // SetOpenGLRendererConfig must be called before this.
123  FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
124  renderer_config_.open_gl.fbo_callback = [](void* context) -> uint32_t {
125  FlutterFrameInfo frame_info = {};
126  // fbo_callback doesn't use the frame size information, only
127  // fbo_callback_with_frame_info does.
128  frame_info.struct_size = sizeof(FlutterFrameInfo);
129  frame_info.size.width = 0;
130  frame_info.size.height = 0;
131  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
132  frame_info);
133  };
134 #endif
135 }
136 
138 #ifdef SHELL_ENABLE_GL
139  // SetOpenGLRendererConfig must be called before this.
140  FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
141  renderer_config_.open_gl.present = [](void* context) -> bool {
142  // passing a placeholder fbo_id.
143  return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(0);
144  };
145 #endif
146 }
147 
149 #ifdef SHELL_ENABLE_GL
150  renderer_config_.type = FlutterRendererType::kOpenGL;
151  renderer_config_.open_gl = opengl_renderer_config_;
152  context_.SetupSurface(surface_size);
153 #endif
154 }
155 
157  project_args_.assets_path = context_.GetAssetsPath().c_str();
158 }
159 
161  if (auto mapping = context_.GetVMSnapshotData()) {
162  project_args_.vm_snapshot_data = mapping->GetMapping();
163  project_args_.vm_snapshot_data_size = mapping->GetSize();
164  }
165 
166  if (auto mapping = context_.GetVMSnapshotInstructions()) {
167  project_args_.vm_snapshot_instructions = mapping->GetMapping();
168  project_args_.vm_snapshot_instructions_size = mapping->GetSize();
169  }
170 
171  if (auto mapping = context_.GetIsolateSnapshotData()) {
172  project_args_.isolate_snapshot_data = mapping->GetMapping();
173  project_args_.isolate_snapshot_data_size = mapping->GetSize();
174  }
175 
176  if (auto mapping = context_.GetIsolateSnapshotInstructions()) {
177  project_args_.isolate_snapshot_instructions = mapping->GetMapping();
178  project_args_.isolate_snapshot_instructions_size = mapping->GetSize();
179  }
180 }
181 
183  project_args_.aot_data = context_.GetAOTData();
184 }
185 
187  project_args_.root_isolate_create_callback =
189 }
190 
192  project_args_.update_semantics_node_callback =
196 }
197 
201 }
202 
203 void EmbedderConfigBuilder::SetDartEntrypoint(std::string entrypoint) {
204  if (entrypoint.size() == 0) {
205  return;
206  }
207 
208  dart_entrypoint_ = std::move(entrypoint);
209  project_args_.custom_dart_entrypoint = dart_entrypoint_.c_str();
210 }
211 
213  if (arg.size() == 0) {
214  return;
215  }
216 
217  command_line_arguments_.emplace_back(std::move(arg));
218 }
219 
221  if (arg.size() == 0) {
222  return;
223  }
224 
225  dart_entrypoint_arguments_.emplace_back(std::move(arg));
226 }
227 
229  const FlutterTaskRunnerDescription* runner) {
230  if (runner == nullptr) {
231  return;
232  }
233  custom_task_runners_.platform_task_runner = runner;
234  project_args_.custom_task_runners = &custom_task_runners_;
235 }
236 
238  const FlutterTaskRunnerDescription* runner) {
239  if (runner == nullptr) {
240  return;
241  }
242 
243  custom_task_runners_.render_task_runner = runner;
244  project_args_.custom_task_runners = &custom_task_runners_;
245 }
246 
248  const std::function<void(const FlutterPlatformMessage*)>& callback) {
249  context_.SetPlatformMessageCallback(callback);
250 }
251 
253  context_.SetupCompositor();
254  auto& compositor = context_.GetCompositor();
255  compositor_.struct_size = sizeof(compositor_);
256  compositor_.user_data = &compositor;
257  compositor_.create_backing_store_callback =
258  [](const FlutterBackingStoreConfig* config, //
259  FlutterBackingStore* backing_store_out, //
260  void* user_data //
261  ) {
262  return reinterpret_cast<EmbedderTestCompositor*>(user_data)
263  ->CreateBackingStore(config, backing_store_out);
264  };
265  compositor_.collect_backing_store_callback =
266  [](const FlutterBackingStore* backing_store, //
267  void* user_data //
268  ) {
269  return reinterpret_cast<EmbedderTestCompositor*>(user_data)
270  ->CollectBackingStore(backing_store);
271  };
272  compositor_.present_layers_callback = [](const FlutterLayer** layers, //
273  size_t layers_count, //
274  void* user_data //
275  ) {
276  return reinterpret_cast<EmbedderTestCompositor*>(user_data)->Present(
277  layers, //
278  layers_count //
279 
280  );
281  };
282  project_args_.compositor = &compositor_;
283 }
284 
286  return compositor_;
287 }
288 
291  auto& compositor = context_.GetCompositor();
292  // TODO(wrightgeorge): figure out a better way of plumbing through the
293  // GrDirectContext
294  compositor.SetBackingStoreProducer(
295  std::make_unique<EmbedderTestBackingStoreProducer>(
296  compositor.GetGrContext(), type));
297 }
298 
300  return SetupEngine(true);
301 }
302 
304  return SetupEngine(false);
305 }
306 
307 UniqueEngine EmbedderConfigBuilder::SetupEngine(bool run) const {
308  FlutterEngine engine = nullptr;
309  FlutterProjectArgs project_args = project_args_;
310 
311  std::vector<const char*> args;
312  args.reserve(command_line_arguments_.size());
313 
314  for (const auto& arg : command_line_arguments_) {
315  args.push_back(arg.c_str());
316  }
317 
318  if (args.size() > 0) {
319  project_args.command_line_argv = args.data();
320  project_args.command_line_argc = args.size();
321  } else {
322  // Clear it out in case this is not the first engine launch from the
323  // embedder config builder.
324  project_args.command_line_argv = nullptr;
325  project_args.command_line_argc = 0;
326  }
327 
328  std::vector<const char*> dart_args;
329  dart_args.reserve(dart_entrypoint_arguments_.size());
330 
331  for (const auto& arg : dart_entrypoint_arguments_) {
332  dart_args.push_back(arg.c_str());
333  }
334 
335  if (dart_args.size() > 0) {
336  project_args.dart_entrypoint_argv = dart_args.data();
337  project_args.dart_entrypoint_argc = dart_args.size();
338  } else {
339  // Clear it out in case this is not the first engine launch from the
340  // embedder config builder.
341  project_args.dart_entrypoint_argv = nullptr;
342  project_args.dart_entrypoint_argc = 0;
343  }
344 
345  auto result =
346  run ? FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config_,
347  &project_args, &context_, &engine)
348  : FlutterEngineInitialize(FLUTTER_ENGINE_VERSION, &renderer_config_,
349  &project_args, &context_, &engine);
350 
351  if (result != kSuccess) {
352  return {};
353  }
354 
355  return UniqueEngine{engine};
356 }
357 
358 } // namespace testing
359 } // namespace flutter
const FlutterCompositor * compositor
Definition: embedder.h:1344
FlutterSoftwareRendererConfig software
Definition: embedder.h:451
const uint8_t * isolate_snapshot_data
Definition: embedder.h:1239
FlutterComputePlatformResolvedLocaleCallback compute_platform_resolved_locale_callback
Definition: embedder.h:1370
uint32_t width
Definition: embedder.h:319
const FlutterTaskRunnerDescription * render_task_runner
Definition: embedder.h:753
const FlutterCustomTaskRunners * custom_task_runners
Definition: embedder.h:1309
size_t vm_snapshot_instructions_size
Definition: embedder.h:1234
EmbedderConfigBuilder(EmbedderTestContext &context, InitializationPreference preference=InitializationPreference::kSnapshotsInitialize)
Dart_NativeFunction function
Definition: fuchsia.cc:51
void * user_data
Definition: embedder.h:921
#define FML_LOG(severity)
Definition: logging.h:65
void SetPlatformMessageCallback(const std::function< void(const FlutterPlatformMessage *)> &callback)
FlutterPlatformMessageCallback platform_message_callback
Definition: embedder.h:1218
static FlutterUpdateSemanticsNodeCallback GetUpdateSemanticsNodeCallbackHook()
const char *const * command_line_argv
Definition: embedder.h:1213
const fml::Mapping * GetVMSnapshotInstructions() const
uint32_t height
Definition: embedder.h:320
bool shutdown_dart_vm_when_done
Definition: embedder.h:1328
const char *const * dart_entrypoint_argv
Definition: embedder.h:1382
const fml::Mapping * GetVMSnapshotData() const
FlutterUIntSize size
The size of the surface that will be backed by the fbo.
Definition: embedder.h:354
virtual void SetupSurface(SkISize surface_size)=0
size_t struct_size
The size of this struct. Must be sizeof(FlutterFrameInfo).
Definition: embedder.h:352
#define FLUTTER_ENGINE_VERSION
Definition: embedder.h:63
FlutterRendererType type
Definition: embedder.h:448
void SetPlatformMessageCallback(const std::function< void(const FlutterPlatformMessage *)> &callback)
FlutterEngineResult FlutterEngineRun(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize and run a Flutter engine instance and return a handle to it. This is a convenience method ...
Definition: embedder.cc:717
FlutterEngineAOTData GetAOTData() const
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback
Definition: embedder.h:1262
void SetRenderTaskRunner(const FlutterTaskRunnerDescription *runner)
int32_t height
void SetPlatformTaskRunner(const FlutterTaskRunnerDescription *runner)
FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback
Definition: embedder.h:1273
const uint8_t * vm_snapshot_data
Definition: embedder.h:1223
static FlutterUpdateSemanticsCustomActionCallback GetUpdateSemanticsCustomActionCallbackHook()
const uint8_t * vm_snapshot_instructions
Definition: embedder.h:1231
G_BEGIN_DECLS FlMethodCall gpointer user_data
FlutterEngineResult FlutterEngineInitialize(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize a Flutter engine instance. This does not run the Flutter application code till the Flutter...
Definition: embedder.cc:733
const char * custom_dart_entrypoint
Definition: embedder.h:1304
FlutterBackingStoreCollectCallback collect_backing_store_callback
Definition: embedder.h:932
const char * assets_path
Definition: embedder.h:1171
FlutterOpenGLRendererConfig open_gl
Definition: embedder.h:450
size_t isolate_snapshot_instructions_size
Definition: embedder.h:1250
size_t struct_size
The size of this struct. Must be sizeof(FlutterProjectArgs).
Definition: embedder.h:1167
FlutterLayersPresentCallback present_layers_callback
Definition: embedder.h:935
const char * name
Definition: fuchsia.cc:50
#define FML_CHECK(condition)
Definition: logging.h:68
const std::string & GetAssetsPath() const
UIntCallback fbo_callback
Definition: embedder.h:391
const FlutterTaskRunnerDescription * platform_task_runner
Definition: embedder.h:748
size_t struct_size
This size of this struct. Must be sizeof(FlutterCompositor).
Definition: embedder.h:916
void SetBackingStoreProducer(std::unique_ptr< EmbedderTestBackingStoreProducer > backingstore_producer)
size_t isolate_snapshot_data_size
Definition: embedder.h:1242
static FlutterComputePlatformResolvedLocaleCallback GetComputePlatformResolvedLocaleCallbackHook()
FlutterEngineAOTData aot_data
Definition: embedder.h:1359
const fml::Mapping * GetIsolateSnapshotInstructions() const
const uint8_t * isolate_snapshot_instructions
Definition: embedder.h:1247
size_t struct_size
The size of this struct. Must be sizeof(FlutterCustomTaskRunners).
Definition: embedder.h:743
VoidCallback root_isolate_create_callback
Definition: embedder.h:1253
size_t vm_snapshot_data_size
Definition: embedder.h:1226
int command_line_argc
The command line argument count used to initialize the project.
Definition: embedder.h:1197
size_t struct_size
The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig).
Definition: embedder.h:439
void SetRenderTargetType(EmbedderTestBackingStoreProducer::RenderTargetType type)
SoftwareSurfacePresentCallback surface_present_callback
Definition: embedder.h:444
void SetSoftwareRendererConfig(SkISize surface_size=SkISize::Make(1, 1))
const fml::Mapping * GetIsolateSnapshotData() const
FlutterBackingStoreCreateCallback create_backing_store_callback
Definition: embedder.h:929