Flutter Engine
flutter::RuntimeController Class Reference

#include <runtime_controller.h>

Inheritance diagram for flutter::RuntimeController:
flutter::PlatformConfigurationClient

Public Member Functions

 RuntimeController (RuntimeDelegate &client, DartVM *vm, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, const std::function< void(int64_t)> &idle_notification_callback, const PlatformData &platform_data, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::shared_ptr< const fml::Mapping > persistent_isolate_data)
 Creates a new instance of a runtime controller. This is usually only done by the engine instance associated with the shell. More...
 
 ~RuntimeController () override
 
bool LaunchRootIsolate (const Settings &settings, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, std::unique_ptr< IsolateConfiguration > isolate_configuration)
 Launches the isolate using the window data associated with this runtime controller. Before this call, the Dart isolate has not been initialized. On successful return, the caller can assume that the isolate is in the DartIsolate::Phase::Running phase. More...
 
std::unique_ptr< RuntimeControllerClone () const
 Clone the the runtime controller. Launching an isolate with a cloned runtime controller will use the same snapshots and copies all window data to the new instance. This is usually only used in the debug runtime mode to support the cold-restart scenario. More...
 
bool SetViewportMetrics (const ViewportMetrics &metrics)
 Forward the specified viewport metrics to the running isolate. If the isolate is not running, these metrics will be saved and flushed to the isolate when it starts. More...
 
bool SetLocales (const std::vector< std::string > &locale_data)
 Forward the specified locale data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetUserSettingsData (const std::string &data)
 Forward the user settings data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetLifecycleState (const std::string &data)
 Forward the lifecycle state data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetSemanticsEnabled (bool enabled)
 Notifies the running isolate about whether the semantics tree should be generated or not. If the isolate is not running, this preference will be saved and flushed to the isolate when it starts running. More...
 
bool SetAccessibilityFeatures (int32_t flags)
 Forward the preference of accessibility features that must be enabled in the semantics tree to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool BeginFrame (fml::TimePoint frame_time)
 Notifies the running isolate that it should start generating a new frame. More...
 
bool ReportTimings (std::vector< int64_t > timings)
 Dart code cannot fully measure the time it takes for a specific frame to be rendered. This is because Dart code only runs on the UI task runner. That is only a small part of the overall frame workload. The GPU task runner frame workload is executed on a thread where Dart code cannot run (and hence instrument). Besides, due to the pipelined nature of rendering in Flutter, there may be multiple frame workloads being processed at any given time. However, for non-Timeline based profiling, it is useful for trace collection and processing to happen in Dart. To do this, the GPU task runner frame workloads need to be instrumented separately. After a set number of these profiles have been gathered, they need to be reported back to Dart code. The engine reports this extra instrumentation information back to Dart code running on the engine by invoking this method at predefined intervals. More...
 
bool NotifyIdle (int64_t deadline, size_t freed_hint)
 Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified deadline. The VM uses this opportunity to perform garbage collection operations is a manner that interferes as little as possible with frame rendering. More...
 
virtual bool IsRootIsolateRunning ()
 Returns if the root isolate is running. The isolate must be transitioned to the running phase manually. The isolate can stop running if it terminates execution on its own. More...
 
virtual bool DispatchPlatformMessage (fml::RefPtr< PlatformMessage > message)
 Dispatch the specified platform message to running root isolate. More...
 
bool DispatchPointerDataPacket (const PointerDataPacket &packet)
 Dispatch the specified pointer data message to the running root isolate. More...
 
bool DispatchSemanticsAction (int32_t id, SemanticsAction action, std::vector< uint8_t > args)
 Dispatch the semantics action to the specified accessibility node. More...
 
Dart_Port GetMainPort ()
 Gets the main port identifier of the root isolate. More...
 
std::string GetIsolateName ()
 Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from its advisory script URI, advisory main entrypoint and its main port name. For example, "main.dart$main-1234" where the script URI is "main.dart", the entrypoint is "main" and the port name "1234". Once launched, the isolate may re-christen itself using a name it selects via setIsolateDebugName in window.dart. This name is purely advisory and only used by instrumentation and reporting purposes. More...
 
bool HasLivePorts ()
 Returns if the root isolate has any live receive ports. More...
 
tonic::DartErrorHandleType GetLastError ()
 Get the last error encountered by the microtask queue. More...
 
std::optional< std::string > GetRootIsolateServiceID () const
 Get the service ID of the root isolate if the root isolate is running. More...
 
std::optional< uint32_t > GetRootIsolateReturnCode ()
 Get the return code specified by the root isolate (if one is present). More...
 

Protected Member Functions

 RuntimeController (RuntimeDelegate &client, TaskRunners p_task_runners)
 Constructor for Mocks. More...
 
- Protected Member Functions inherited from flutter::PlatformConfigurationClient
virtual ~PlatformConfigurationClient ()
 

Detailed Description

Represents an instance of a running root isolate with window bindings. In normal operation, a single instance of this object is owned by the engine per shell. This object may only be created, used, and collected on the UI task runner. Window state queried by the root isolate is stored by this object. In cold-restart scenarios, the engine may collect this before installing a new runtime controller in its place. The Clone method may be used by the engine to copy the currently accumulated window state so it can be referenced by the new runtime controller.

Definition at line 42 of file runtime_controller.h.

Constructor & Destructor Documentation

◆ RuntimeController() [1/2]

flutter::RuntimeController::RuntimeController ( RuntimeDelegate client,
DartVM vm,
fml::RefPtr< const DartSnapshot isolate_snapshot,
TaskRunners  task_runners,
fml::WeakPtr< SnapshotDelegate snapshot_delegate,
fml::WeakPtr< HintFreedDelegate hint_freed_delegate,
fml::WeakPtr< IOManager io_manager,
fml::RefPtr< SkiaUnrefQueue unref_queue,
fml::WeakPtr< ImageDecoder image_decoder,
std::string  advisory_script_uri,
std::string  advisory_script_entrypoint,
const std::function< void(int64_t)> &  idle_notification_callback,
const PlatformData platform_data,
const fml::closure isolate_create_callback,
const fml::closure isolate_shutdown_callback,
std::shared_ptr< const fml::Mapping persistent_isolate_data 
)

Creates a new instance of a runtime controller. This is usually only done by the engine instance associated with the shell.

Parameters
clientThe runtime delegate. This is usually the Engine instance.
vmA reference to a running Dart VM. The runtime controller must be collected before the VM is destroyed (this order is guaranteed by the shell).
[in]isolate_snapshotThe isolate snapshot used to start the root isolate managed by this runtime controller. The isolate must be transitioned into the running phase manually by the caller.
[in]task_runnersThe task runners used by the shell hosting this runtime controller. This may be used by the isolate to scheduled asynchronous texture uploads or post tasks to the platform task runner.
[in]snapshot_delegateThe snapshot delegate used by the isolate to gather raster snapshots of Flutter view hierarchies.
[in]hint_freed_delegateThe delegate used by the isolate to hint the Dart VM when additional memory may be freed if a GC ran at the next NotifyIdle.
[in]io_managerThe IO manager used by the isolate for asynchronous texture uploads.
[in]unref_queueThe unref queue used by the isolate to collect resources that may reference resources on the GPU.
[in]image_decoderThe image decoder
[in]advisory_script_uriThe advisory script URI (only used for debugging). This does not affect the code being run in the isolate in any way.
[in]advisory_script_entrypointThe advisory script entrypoint (only used for debugging). This does not affect the code being run in the isolate in any way. The isolate must be transitioned to the running state explicitly by the caller.
[in]idle_notification_callbackThe idle notification callback. This allows callers to run native code in isolate scope when the VM is about to be notified that the engine is going to be idle.
[in]platform_dataThe window data (if exists).
[in]isolate_create_callbackThe isolate create callback. This allows callers to run native code in isolate scope on the UI task runner as soon as the root isolate has been created.
[in]isolate_shutdown_callbackThe isolate shutdown callback. This allows callers to run native code in isolate scoped on the UI task runner just as the root isolate is about to be torn down.
[in]persistent_isolate_dataUnstructured persistent read-only data that the root isolate can access in a synchronous manner.

Definition at line 24 of file runtime_controller.cc.

Referenced by Clone().

41  : client_(p_client),
42  vm_(p_vm),
43  isolate_snapshot_(std::move(p_isolate_snapshot)),
44  task_runners_(p_task_runners),
45  snapshot_delegate_(p_snapshot_delegate),
46  hint_freed_delegate_(p_hint_freed_delegate),
47  io_manager_(p_io_manager),
48  unref_queue_(p_unref_queue),
49  image_decoder_(p_image_decoder),
50  advisory_script_uri_(p_advisory_script_uri),
51  advisory_script_entrypoint_(p_advisory_script_entrypoint),
52  idle_notification_callback_(idle_notification_callback),
53  platform_data_(std::move(p_platform_data)),
54  isolate_create_callback_(p_isolate_create_callback),
55  isolate_shutdown_callback_(p_isolate_shutdown_callback),
56  persistent_isolate_data_(std::move(p_persistent_isolate_data)) {}

◆ ~RuntimeController()

flutter::RuntimeController::~RuntimeController ( )
override

Definition at line 58 of file runtime_controller.cc.

References FML_DCHECK, and FML_DLOG.

58  {
59  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
60  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
61  if (root_isolate) {
62  root_isolate->SetReturnCodeCallback(nullptr);
63  auto result = root_isolate->Shutdown();
64  if (!result) {
65  FML_DLOG(ERROR) << "Could not shutdown the root isolate.";
66  }
67  root_isolate_ = {};
68  }
69 }
#define FML_DCHECK(condition)
Definition: logging.h:86
#define FML_DLOG(severity)
Definition: logging.h:85

◆ RuntimeController() [2/2]

flutter::RuntimeController::RuntimeController ( RuntimeDelegate client,
TaskRunners  p_task_runners 
)
protected

Constructor for Mocks.

Definition at line 20 of file runtime_controller.cc.

22  : client_(client), vm_(nullptr), task_runners_(p_task_runners) {}

Member Function Documentation

◆ BeginFrame()

bool flutter::RuntimeController::BeginFrame ( fml::TimePoint  frame_time)

Notifies the running isolate that it should start generating a new frame.

See also
Engine::BeginFrame for more context.
Parameters
[in]frame_timeThe point at which the current frame interval began. May be used by animation interpolators, physics simulations, etc.
Returns
If notification to begin frame rendering was delivered to the running isolate.

Definition at line 180 of file runtime_controller.cc.

180  {
181  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
182  platform_configuration->BeginFrame(frame_time);
183  return true;
184  }
185 
186  return false;
187 }

◆ Clone()

std::unique_ptr< RuntimeController > flutter::RuntimeController::Clone ( ) const

Clone the the runtime controller. Launching an isolate with a cloned runtime controller will use the same snapshots and copies all window data to the new instance. This is usually only used in the debug runtime mode to support the cold-restart scenario.

Returns
A clone of the existing runtime controller.

Definition at line 79 of file runtime_controller.cc.

References flutter::PlatformData::accessibility_feature_flags_, flutter::PlatformData::lifecycle_state, flutter::PlatformData::locale_data, RuntimeController(), flutter::PlatformData::semantics_enabled, SetAccessibilityFeatures(), SetLifecycleState(), SetLocales(), SetSemanticsEnabled(), SetUserSettingsData(), SetViewportMetrics(), flutter::PlatformData::user_settings_data, and flutter::PlatformData::viewport_metrics.

79  {
80  return std::unique_ptr<RuntimeController>(new RuntimeController(
81  client_, //
82  vm_, //
83  isolate_snapshot_, //
84  task_runners_, //
85  snapshot_delegate_, //
86  hint_freed_delegate_, //
87  io_manager_, //
88  unref_queue_, //
89  image_decoder_, //
90  advisory_script_uri_, //
91  advisory_script_entrypoint_, //
92  idle_notification_callback_, //
93  platform_data_, //
94  isolate_create_callback_, //
95  isolate_shutdown_callback_, //
96  persistent_isolate_data_ //
97  ));
98 }
RuntimeController(RuntimeDelegate &client, DartVM *vm, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, const std::function< void(int64_t)> &idle_notification_callback, const PlatformData &platform_data, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::shared_ptr< const fml::Mapping > persistent_isolate_data)
Creates a new instance of a runtime controller. This is usually only done by the engine instance asso...

◆ DispatchPlatformMessage()

bool flutter::RuntimeController::DispatchPlatformMessage ( fml::RefPtr< PlatformMessage message)
virtual

Dispatch the specified platform message to running root isolate.

Parameters
[in]messageThe message to dispatch to the isolate.
Returns
If the message was dispatched to the running root isolate. This may fail is an isolate is not running.

Definition at line 219 of file runtime_controller.cc.

References TRACE_EVENT1.

220  {
221  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
222  TRACE_EVENT1("flutter", "RuntimeController::DispatchPlatformMessage",
223  "mode", "basic");
224  platform_configuration->DispatchPlatformMessage(std::move(message));
225  return true;
226  }
227 
228  return false;
229 }
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:79

◆ DispatchPointerDataPacket()

bool flutter::RuntimeController::DispatchPointerDataPacket ( const PointerDataPacket packet)

Dispatch the specified pointer data message to the running root isolate.

Parameters
[in]packetThe pointer data message to dispatch to the isolate.
Returns
If the pointer data message was dispatched. This may fail is an isolate is not running.

Definition at line 231 of file runtime_controller.cc.

References TRACE_EVENT1.

232  {
233  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
234  TRACE_EVENT1("flutter", "RuntimeController::DispatchPointerDataPacket",
235  "mode", "basic");
236  platform_configuration->get_window(0)->DispatchPointerDataPacket(packet);
237  return true;
238  }
239 
240  return false;
241 }
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:79

◆ DispatchSemanticsAction()

bool flutter::RuntimeController::DispatchSemanticsAction ( int32_t  id,
SemanticsAction  action,
std::vector< uint8_t >  args 
)

Dispatch the semantics action to the specified accessibility node.

Parameters
[in]idThe identified of the accessibility node.
[in]actionThe semantics action to perform on the specified accessibility node.
[in]argsOptional data that applies to the specified action.
Returns
If the semantics action was dispatched. This may fail if an isolate is not running.

Definition at line 243 of file runtime_controller.cc.

References flutter::RuntimeDelegate::ComputePlatformResolvedLocale(), flutter::RuntimeDelegate::DefaultRouteName(), flutter::RuntimeDelegate::GetFontCollection(), flutter::RuntimeDelegate::HandlePlatformMessage(), flutter::RuntimeDelegate::Render(), flutter::RuntimeDelegate::ScheduleFrame(), flutter::PlatformData::semantics_enabled, flutter::RuntimeDelegate::SetNeedsReportTimings(), flutter::SemanticsUpdate::takeActions(), flutter::Scene::takeLayerTree(), flutter::SemanticsUpdate::takeNodes(), TRACE_EVENT1, flutter::RuntimeDelegate::UpdateIsolateDescription(), flutter::RuntimeDelegate::UpdateSemantics(), and value.

245  {
246  TRACE_EVENT1("flutter", "RuntimeController::DispatchSemanticsAction", "mode",
247  "basic");
248  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
249  platform_configuration->DispatchSemanticsAction(id, action,
250  std::move(args));
251  return true;
252  }
253 
254  return false;
255 }
G_BEGIN_DECLS FlValue * args
SemanticsAction action
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:79

◆ GetIsolateName()

std::string flutter::RuntimeController::GetIsolateName ( )

Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from its advisory script URI, advisory main entrypoint and its main port name. For example, "main.dart$main-1234" where the script URI is "main.dart", the entrypoint is "main" and the port name "1234". Once launched, the isolate may re-christen itself using a name it selects via setIsolateDebugName in window.dart. This name is purely advisory and only used by instrumentation and reporting purposes.

Returns
The debug name of the root isolate.

Definition at line 325 of file runtime_controller.cc.

325  {
326  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
327  return root_isolate ? root_isolate->debug_name() : "";
328 }

◆ GetLastError()

tonic::DartErrorHandleType flutter::RuntimeController::GetLastError ( )

Get the last error encountered by the microtask queue.

Returns
The last error encountered by the microtask queue.

Definition at line 339 of file runtime_controller.cc.

References tonic::kNoError.

339  {
340  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
341  return root_isolate ? root_isolate->GetLastError() : tonic::kNoError;
342 }

◆ GetMainPort()

Dart_Port flutter::RuntimeController::GetMainPort ( )

Gets the main port identifier of the root isolate.

Returns
The main port identifier. If no root isolate is running, returns ILLEGAL_PORT.

Definition at line 320 of file runtime_controller.cc.

320  {
321  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
322  return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
323 }

◆ GetRootIsolateReturnCode()

std::optional< uint32_t > flutter::RuntimeController::GetRootIsolateReturnCode ( )

Get the return code specified by the root isolate (if one is present).

Returns
The root isolate return code if the isolate has specified one.

Definition at line 423 of file runtime_controller.cc.

423  {
424  return root_isolate_return_code_;
425 }

◆ GetRootIsolateServiceID()

std::optional< std::string > flutter::RuntimeController::GetRootIsolateServiceID ( ) const

Get the service ID of the root isolate if the root isolate is running.

Returns
The root isolate service id.

Definition at line 407 of file runtime_controller.cc.

407  {
408  if (auto isolate = root_isolate_.lock()) {
409  return isolate->GetServiceId();
410  }
411  return std::nullopt;
412 }

◆ HasLivePorts()

bool flutter::RuntimeController::HasLivePorts ( )

Returns if the root isolate has any live receive ports.

Returns
True if there are live receive ports, False otherwise. Return False if the root isolate is not running as well.

Definition at line 330 of file runtime_controller.cc.

330  {
331  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
332  if (!root_isolate) {
333  return false;
334  }
335  tonic::DartState::Scope scope(root_isolate);
336  return Dart_HasLivePorts();
337 }

◆ IsRootIsolateRunning()

bool flutter::RuntimeController::IsRootIsolateRunning ( )
virtual

Returns if the root isolate is running. The isolate must be transitioned to the running phase manually. The isolate can stop running if it terminates execution on its own.

Returns
True if root isolate running, False otherwise.

Definition at line 71 of file runtime_controller.cc.

References flutter::DartIsolate::Running.

71  {
72  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
73  if (root_isolate) {
74  return root_isolate->GetPhase() == DartIsolate::Phase::Running;
75  }
76  return false;
77 }

◆ LaunchRootIsolate()

bool flutter::RuntimeController::LaunchRootIsolate ( const Settings settings,
std::optional< std::string >  dart_entrypoint,
std::optional< std::string >  dart_entrypoint_library,
std::unique_ptr< IsolateConfiguration isolate_configuration 
)

Launches the isolate using the window data associated with this runtime controller. Before this call, the Dart isolate has not been initialized. On successful return, the caller can assume that the isolate is in the DartIsolate::Phase::Running phase.

This call will fail if a root isolate is already running. To re-create an isolate with the window data associated with this runtime controller, Clone this runtime controller and Launch an isolate in that runtime controller instead.

Parameters
[in]settingsThe per engine instance settings.
[in]dart_entrypointThe dart entrypoint. If std::nullopt or empty, main will be attempted.
[in]dart_entrypoint_libraryThe dart entrypoint library. If std::nullopt or empty, the core library will be attempted.
[in]isolate_configurationThe isolate configuration
Returns
If the isolate could be launched and guided to the DartIsolate::Phase::Running phase.

Definition at line 344 of file runtime_controller.cc.

References flutter::DartIsolate::CreateRunningRootIsolate(), FML_DCHECK, FML_DLOG, FML_LOG, and flutter::RuntimeDelegate::OnRootIsolateCreated().

348  {
349  if (root_isolate_.lock()) {
350  FML_LOG(ERROR) << "Root isolate was already running.";
351  return false;
352  }
353 
354  auto strong_root_isolate =
356  settings, //
357  isolate_snapshot_, //
358  task_runners_, //
359  std::make_unique<PlatformConfiguration>(this), //
360  snapshot_delegate_, //
361  hint_freed_delegate_, //
362  io_manager_, //
363  unref_queue_, //
364  image_decoder_, //
365  advisory_script_uri_, //
366  advisory_script_entrypoint_, //
367  DartIsolate::Flags{}, //
368  isolate_create_callback_, //
369  isolate_shutdown_callback_, //
370  dart_entrypoint, //
371  dart_entrypoint_library, //
372  std::move(isolate_configuration) //
373  )
374  .lock();
375 
376  if (!strong_root_isolate) {
377  FML_LOG(ERROR) << "Could not create root isolate.";
378  return false;
379  }
380 
381  // The root isolate ivar is weak.
382  root_isolate_ = strong_root_isolate;
383 
384  // Capture by `this` here is safe because the callback is made by the dart
385  // state itself. The isolate (and its Dart state) is owned by this object and
386  // it will be collected before this object.
387  strong_root_isolate->SetReturnCodeCallback(
388  [this](uint32_t code) { root_isolate_return_code_ = code; });
389 
390  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
391  tonic::DartState::Scope scope(strong_root_isolate);
392  platform_configuration->DidCreateIsolate();
393  if (!FlushRuntimeStateToIsolate()) {
394  FML_DLOG(ERROR) << "Could not setup initial isolate state.";
395  }
396  } else {
397  FML_DCHECK(false) << "RuntimeController created without window binding.";
398  }
399 
400  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
401 
402  client_.OnRootIsolateCreated();
403 
404  return true;
405 }
#define FML_DCHECK(condition)
Definition: logging.h:86
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, std::unique_ptr< PlatformConfiguration > platform_configuration, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > skia_unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, Flags flags, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, std::unique_ptr< IsolateConfiguration > isolate_configration)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
Definition: dart_isolate.cc:76
virtual void OnRootIsolateCreated()=0
#define FML_LOG(severity)
Definition: logging.h:65
#define FML_DLOG(severity)
Definition: logging.h:85

◆ NotifyIdle()

bool flutter::RuntimeController::NotifyIdle ( int64_t  deadline,
size_t  freed_hint 
)

Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified deadline. The VM uses this opportunity to perform garbage collection operations is a manner that interferes as little as possible with frame rendering.

NotifyIdle is advisory. The VM may or may not run a garbage collection when this is called, and will eventually perform garbage collections even if it is not called or it is called with insufficient deadlines.

The garbage collection mechanism and its thresholds are internal implementation details and absolutely no guarantees are made about the threshold discussed below. This discussion is also an oversimplification but hopefully serves to calibrate expectations about GC behavior:

  • When the Dart VM and its root isolate are initialized, the memory consumed upto that point are treated as a baseline.
  • A fixed percentage of the memory consumed (~20%) over the baseline is treated as the hard threshold.
  • The memory in play is divided into old space and new space. The new space is typically very small and fills up rapidly.
  • The baseline plus the threshold is considered the old space while the small new space is a separate region (typically a few pages).
  • The total old space size minus the max new space size is treated as the soft threshold.
  • In a world where there is no call to NotifyIdle, when the total allocation exceeds the soft threshold, a concurrent mark is initiated in the VM. There is a “small” pause that occurs when the concurrent mark is initiated and another pause when the mark concludes and a sweep is initiated.
  • If the total allocations exceeds the the hard threshold, a “big” stop-the-world pause is initiated.
  • If after either the sweep after the concurrent mark, or, the stop-the-world pause, the consumption returns to be below the soft threshold, the dance begins anew.
  • If after both the “small” and “big” pauses, memory usage is still over the hard threshold, i.e, the objects are still reachable, that amount of memory is treated as the new baseline and a fixed percentage of the new baseline over the new baseline is now the new hard threshold.
  • Updating the baseline will continue till memory for the updated old space can be allocated from the operating system. These allocations will typically fail due to address space exhaustion on 32-bit systems and page table exhaustion on 64-bit systems.
  • NotifyIdle initiates the concurrent mark preemptively. The deadline is used by the VM to determine if the corresponding sweep can be performed within the deadline. This way, jank due to “small” pauses can be ameliorated.
  • There is no ability to stop a “big” pause on reaching the hard threshold in the old space. The best you can do is release (by making them unreachable) objects eagerly so that the are marked as unreachable in the concurrent mark initiated by either reaching the soft threshold or an explicit NotifyIdle.
  • If you are running out of memory, its because too many large objects were allocation and remained reachable such that the the old space kept growing till it could grow no more.
  • At the edges of allocation thresholds, failures can occur gracefully if the instigating allocation was made in the Dart VM or rather gracelessly if the allocation is made by some native component.
See also
Dart_TimelineGetMicros
Parameters
[in]deadlineThe deadline measures in microseconds against the system's monotonic time. The clock can be accessed via Dart_TimelineGetMicros.
[in]freed_hintA hint of the number of bytes potentially freed since the last call to NotifyIdle if a GC were run.
Returns
If the idle notification was forwarded to the running isolate.

Definition at line 198 of file runtime_controller.cc.

References TRACE_EVENT0.

198  {
199  std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
200  if (!root_isolate) {
201  return false;
202  }
203 
204  tonic::DartState::Scope scope(root_isolate);
205 
206  // Dart will use the freed hint at the next idle notification. Make sure to
207  // Update it with our latest value before calling NotifyIdle.
208  Dart_HintFreed(freed_hint);
209  Dart_NotifyIdle(deadline);
210 
211  // Idle notifications being in isolate scope are part of the contract.
212  if (idle_notification_callback_) {
213  TRACE_EVENT0("flutter", "EmbedderIdleNotification");
214  idle_notification_callback_(deadline);
215  }
216  return true;
217 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75

◆ ReportTimings()

bool flutter::RuntimeController::ReportTimings ( std::vector< int64_t >  timings)

Dart code cannot fully measure the time it takes for a specific frame to be rendered. This is because Dart code only runs on the UI task runner. That is only a small part of the overall frame workload. The GPU task runner frame workload is executed on a thread where Dart code cannot run (and hence instrument). Besides, due to the pipelined nature of rendering in Flutter, there may be multiple frame workloads being processed at any given time. However, for non-Timeline based profiling, it is useful for trace collection and processing to happen in Dart. To do this, the GPU task runner frame workloads need to be instrumented separately. After a set number of these profiles have been gathered, they need to be reported back to Dart code. The engine reports this extra instrumentation information back to Dart code running on the engine by invoking this method at predefined intervals.

See also
Engine::ReportTimings, FrameTiming
Parameters
[in]timingsCollection of FrameTiming::kCount * n timestamps for n frames whose timings have not been reported yet. A collection of integers is reported here for easier conversions to Dart objects. The timestamps are measured against the system monotonic clock measured in microseconds.

Definition at line 189 of file runtime_controller.cc.

189  {
190  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
191  platform_configuration->ReportTimings(std::move(timings));
192  return true;
193  }
194 
195  return false;
196 }

◆ SetAccessibilityFeatures()

bool flutter::RuntimeController::SetAccessibilityFeatures ( int32_t  flags)

Forward the preference of accessibility features that must be enabled in the semantics tree to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]flagsThe accessibility features that must be generated in the semantics tree.
Returns
If the preference of accessibility features was forwarded to the running isolate.

Definition at line 169 of file runtime_controller.cc.

References flutter::PlatformData::accessibility_feature_flags_, and flutter::flags.

Referenced by Clone().

169  {
170  platform_data_.accessibility_feature_flags_ = flags;
171  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
172  platform_configuration->UpdateAccessibilityFeatures(
173  platform_data_.accessibility_feature_flags_);
174  return true;
175  }
176 
177  return false;
178 }
int32_t accessibility_feature_flags_
Definition: platform_data.h:43
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66

◆ SetLifecycleState()

bool flutter::RuntimeController::SetLifecycleState ( const std::string &  data)

Forward the lifecycle state data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]dataThe lifecycle state data.
Returns
If the lifecycle state data was forwarded to the running isolate.

Definition at line 145 of file runtime_controller.cc.

References flutter::PlatformData::lifecycle_state.

Referenced by Clone().

145  {
146  platform_data_.lifecycle_state = data;
147 
148  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
149  platform_configuration->UpdateLifecycleState(
150  platform_data_.lifecycle_state);
151  return true;
152  }
153 
154  return false;
155 }
std::string lifecycle_state
Definition: platform_data.h:40

◆ SetLocales()

bool flutter::RuntimeController::SetLocales ( const std::vector< std::string > &  locale_data)

Forward the specified locale data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]locale_dataThe locale data. This should consist of groups of 4 strings, each group representing a single locale.
Returns
If the locale data was forwarded to the running isolate.

Definition at line 121 of file runtime_controller.cc.

References flutter::PlatformData::locale_data.

Referenced by Clone().

122  {
123  platform_data_.locale_data = locale_data;
124 
125  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
126  platform_configuration->UpdateLocales(locale_data);
127  return true;
128  }
129 
130  return false;
131 }
std::vector< std::string > locale_data
Definition: platform_data.h:38

◆ SetSemanticsEnabled()

bool flutter::RuntimeController::SetSemanticsEnabled ( bool  enabled)

Notifies the running isolate about whether the semantics tree should be generated or not. If the isolate is not running, this preference will be saved and flushed to the isolate when it starts running.

Parameters
[in]enabledIndicates whether to generate the semantics tree.
Returns
If the semantics tree generation preference was forwarded to the running isolate.

Definition at line 157 of file runtime_controller.cc.

References flutter::PlatformData::semantics_enabled.

Referenced by Clone().

157  {
158  platform_data_.semantics_enabled = enabled;
159 
160  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
161  platform_configuration->UpdateSemanticsEnabled(
162  platform_data_.semantics_enabled);
163  return true;
164  }
165 
166  return false;
167 }

◆ SetUserSettingsData()

bool flutter::RuntimeController::SetUserSettingsData ( const std::string &  data)

Forward the user settings data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]dataThe user settings data.
Returns
If the user settings data was forwarded to the running isolate.

Definition at line 133 of file runtime_controller.cc.

References flutter::PlatformData::user_settings_data.

Referenced by Clone().

133  {
134  platform_data_.user_settings_data = data;
135 
136  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
137  platform_configuration->UpdateUserSettingsData(
138  platform_data_.user_settings_data);
139  return true;
140  }
141 
142  return false;
143 }
std::string user_settings_data
Definition: platform_data.h:39

◆ SetViewportMetrics()

bool flutter::RuntimeController::SetViewportMetrics ( const ViewportMetrics metrics)

Forward the specified viewport metrics to the running isolate. If the isolate is not running, these metrics will be saved and flushed to the isolate when it starts.

Parameters
[in]metricsThe window's viewport metrics.
Returns
If the window metrics were forwarded to the running isolate.

Definition at line 110 of file runtime_controller.cc.

References flutter::PlatformData::viewport_metrics.

Referenced by Clone().

110  {
111  platform_data_.viewport_metrics = metrics;
112 
113  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
114  platform_configuration->get_window(0)->UpdateWindowMetrics(metrics);
115  return true;
116  }
117 
118  return false;
119 }
ViewportMetrics viewport_metrics
Definition: platform_data.h:33

The documentation for this class was generated from the following files: