mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This PR refactors `Rasterizer` so that it's more suitable for multi-view. Design doc: [flutter.dev/go/multi-view-pipeline-and-rasterizer](http://flutter.dev/go/multi-view-pipeline-and-rasterizer) With this change, `Rasterizer::DrawToSurfaces` has a structure that can handle drawing to multiple views, although the lack of some functionality still blocks it, mostly related to `ExternalViewEmbedder` and `RasterCache`. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
610 lines
21 KiB
C++
610 lines
21 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/shell/common/engine.h"
|
|
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "flutter/common/settings.h"
|
|
#include "flutter/fml/make_copyable.h"
|
|
#include "flutter/fml/trace_event.h"
|
|
#include "flutter/lib/snapshot/snapshot.h"
|
|
#include "flutter/lib/ui/text/font_collection.h"
|
|
#include "flutter/shell/common/animator.h"
|
|
#include "flutter/shell/common/platform_view.h"
|
|
#include "flutter/shell/common/shell.h"
|
|
#include "rapidjson/document.h"
|
|
#include "third_party/dart/runtime/include/dart_tools_api.h"
|
|
|
|
namespace flutter {
|
|
|
|
static constexpr char kAssetChannel[] = "flutter/assets";
|
|
static constexpr char kLifecycleChannel[] = "flutter/lifecycle";
|
|
static constexpr char kNavigationChannel[] = "flutter/navigation";
|
|
static constexpr char kLocalizationChannel[] = "flutter/localization";
|
|
static constexpr char kSettingsChannel[] = "flutter/settings";
|
|
static constexpr char kIsolateChannel[] = "flutter/isolate";
|
|
|
|
namespace {
|
|
fml::MallocMapping MakeMapping(const std::string& str) {
|
|
return fml::MallocMapping::Copy(str.c_str(), str.length());
|
|
}
|
|
} // namespace
|
|
|
|
Engine::Engine(
|
|
Delegate& delegate,
|
|
const PointerDataDispatcherMaker& dispatcher_maker,
|
|
std::shared_ptr<fml::ConcurrentTaskRunner> image_decoder_task_runner,
|
|
const TaskRunners& task_runners,
|
|
const Settings& settings,
|
|
std::unique_ptr<Animator> animator,
|
|
fml::WeakPtr<IOManager> io_manager,
|
|
const std::shared_ptr<FontCollection>& font_collection,
|
|
std::unique_ptr<RuntimeController> runtime_controller,
|
|
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
|
|
: delegate_(delegate),
|
|
settings_(settings),
|
|
animator_(std::move(animator)),
|
|
runtime_controller_(std::move(runtime_controller)),
|
|
font_collection_(font_collection),
|
|
image_decoder_(ImageDecoder::Make(settings_,
|
|
task_runners,
|
|
std::move(image_decoder_task_runner),
|
|
std::move(io_manager),
|
|
gpu_disabled_switch)),
|
|
task_runners_(task_runners),
|
|
weak_factory_(this) {
|
|
pointer_data_dispatcher_ = dispatcher_maker(*this);
|
|
}
|
|
|
|
Engine::Engine(Delegate& delegate,
|
|
const PointerDataDispatcherMaker& dispatcher_maker,
|
|
DartVM& vm,
|
|
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
|
const TaskRunners& task_runners,
|
|
const PlatformData& platform_data,
|
|
const Settings& settings,
|
|
std::unique_ptr<Animator> animator,
|
|
fml::WeakPtr<IOManager> io_manager,
|
|
fml::RefPtr<SkiaUnrefQueue> unref_queue,
|
|
fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
|
|
std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
|
|
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
|
|
: Engine(delegate,
|
|
dispatcher_maker,
|
|
vm.GetConcurrentWorkerTaskRunner(),
|
|
task_runners,
|
|
settings,
|
|
std::move(animator),
|
|
io_manager,
|
|
std::make_shared<FontCollection>(),
|
|
nullptr,
|
|
gpu_disabled_switch) {
|
|
runtime_controller_ = std::make_unique<RuntimeController>(
|
|
*this, // runtime delegate
|
|
&vm, // VM
|
|
std::move(isolate_snapshot), // isolate snapshot
|
|
settings_.idle_notification_callback, // idle notification callback
|
|
platform_data, // platform data
|
|
settings_.isolate_create_callback, // isolate create callback
|
|
settings_.isolate_shutdown_callback, // isolate shutdown callback
|
|
settings_.persistent_isolate_data, // persistent isolate data
|
|
UIDartState::Context{
|
|
task_runners_, // task runners
|
|
std::move(snapshot_delegate), // snapshot delegate
|
|
std::move(io_manager), // io manager
|
|
std::move(unref_queue), // Skia unref queue
|
|
image_decoder_->GetWeakPtr(), // image decoder
|
|
image_generator_registry_.GetWeakPtr(), // image generator registry
|
|
settings_.advisory_script_uri, // advisory script uri
|
|
settings_.advisory_script_entrypoint, // advisory script entrypoint
|
|
std::move(volatile_path_tracker), // volatile path tracker
|
|
vm.GetConcurrentWorkerTaskRunner(), // concurrent task runner
|
|
settings_.enable_impeller, // enable impeller
|
|
});
|
|
}
|
|
|
|
std::unique_ptr<Engine> Engine::Spawn(
|
|
Delegate& delegate,
|
|
const PointerDataDispatcherMaker& dispatcher_maker,
|
|
const Settings& settings,
|
|
std::unique_ptr<Animator> animator,
|
|
const std::string& initial_route,
|
|
const fml::WeakPtr<IOManager>& io_manager,
|
|
fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
|
|
const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch) const {
|
|
auto result = std::make_unique<Engine>(
|
|
/*delegate=*/delegate,
|
|
/*dispatcher_maker=*/dispatcher_maker,
|
|
/*image_decoder_task_runner=*/
|
|
runtime_controller_->GetDartVM()->GetConcurrentWorkerTaskRunner(),
|
|
/*task_runners=*/task_runners_,
|
|
/*settings=*/settings,
|
|
/*animator=*/std::move(animator),
|
|
/*io_manager=*/io_manager,
|
|
/*font_collection=*/font_collection_,
|
|
/*runtime_controller=*/nullptr,
|
|
/*gpu_disabled_switch=*/gpu_disabled_switch);
|
|
result->runtime_controller_ = runtime_controller_->Spawn(
|
|
/*p_client=*/*result,
|
|
/*advisory_script_uri=*/settings.advisory_script_uri,
|
|
/*advisory_script_entrypoint=*/settings.advisory_script_entrypoint,
|
|
/*idle_notification_callback=*/settings.idle_notification_callback,
|
|
/*isolate_create_callback=*/settings.isolate_create_callback,
|
|
/*isolate_shutdown_callback=*/settings.isolate_shutdown_callback,
|
|
/*persistent_isolate_data=*/settings.persistent_isolate_data,
|
|
/*io_manager=*/io_manager,
|
|
/*image_decoder=*/result->GetImageDecoderWeakPtr(),
|
|
/*image_generator_registry=*/result->GetImageGeneratorRegistry(),
|
|
/*snapshot_delegate=*/std::move(snapshot_delegate));
|
|
result->initial_route_ = initial_route;
|
|
return result;
|
|
}
|
|
|
|
Engine::~Engine() = default;
|
|
|
|
fml::WeakPtr<Engine> Engine::GetWeakPtr() const {
|
|
return weak_factory_.GetWeakPtr();
|
|
}
|
|
|
|
void Engine::SetupDefaultFontManager() {
|
|
TRACE_EVENT0("flutter", "Engine::SetupDefaultFontManager");
|
|
font_collection_->SetupDefaultFontManager(settings_.font_initialization_data);
|
|
}
|
|
|
|
std::shared_ptr<AssetManager> Engine::GetAssetManager() {
|
|
return asset_manager_;
|
|
}
|
|
|
|
fml::WeakPtr<ImageDecoder> Engine::GetImageDecoderWeakPtr() {
|
|
return image_decoder_->GetWeakPtr();
|
|
}
|
|
|
|
fml::WeakPtr<ImageGeneratorRegistry> Engine::GetImageGeneratorRegistry() {
|
|
return image_generator_registry_.GetWeakPtr();
|
|
}
|
|
|
|
bool Engine::UpdateAssetManager(
|
|
const std::shared_ptr<AssetManager>& new_asset_manager) {
|
|
if (asset_manager_ == new_asset_manager) {
|
|
return false;
|
|
}
|
|
|
|
asset_manager_ = new_asset_manager;
|
|
|
|
if (!asset_manager_) {
|
|
return false;
|
|
}
|
|
|
|
// Using libTXT as the text engine.
|
|
if (settings_.use_asset_fonts) {
|
|
font_collection_->RegisterFonts(asset_manager_);
|
|
}
|
|
|
|
if (settings_.use_test_fonts) {
|
|
font_collection_->RegisterTestFonts();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Engine::Restart(RunConfiguration configuration) {
|
|
TRACE_EVENT0("flutter", "Engine::Restart");
|
|
if (!configuration.IsValid()) {
|
|
FML_LOG(ERROR) << "Engine run configuration was invalid.";
|
|
return false;
|
|
}
|
|
delegate_.OnPreEngineRestart();
|
|
runtime_controller_ = runtime_controller_->Clone();
|
|
UpdateAssetManager(nullptr);
|
|
return Run(std::move(configuration)) == Engine::RunStatus::Success;
|
|
}
|
|
|
|
Engine::RunStatus Engine::Run(RunConfiguration configuration) {
|
|
if (!configuration.IsValid()) {
|
|
FML_LOG(ERROR) << "Engine run configuration was invalid.";
|
|
return RunStatus::Failure;
|
|
}
|
|
|
|
last_entry_point_ = configuration.GetEntrypoint();
|
|
last_entry_point_library_ = configuration.GetEntrypointLibrary();
|
|
#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
|
|
// This is only used to support restart.
|
|
last_entry_point_args_ = configuration.GetEntrypointArgs();
|
|
#endif
|
|
|
|
UpdateAssetManager(configuration.GetAssetManager());
|
|
|
|
if (runtime_controller_->IsRootIsolateRunning()) {
|
|
return RunStatus::FailureAlreadyRunning;
|
|
}
|
|
|
|
// If the embedding prefetched the default font manager, then set up the
|
|
// font manager later in the engine launch process. This makes it less
|
|
// likely that the setup will need to wait for the prefetch to complete.
|
|
auto root_isolate_create_callback = [&]() {
|
|
if (settings_.prefetched_default_font_manager) {
|
|
SetupDefaultFontManager();
|
|
}
|
|
};
|
|
|
|
if (!runtime_controller_->LaunchRootIsolate(
|
|
settings_, //
|
|
root_isolate_create_callback, //
|
|
configuration.GetEntrypoint(), //
|
|
configuration.GetEntrypointLibrary(), //
|
|
configuration.GetEntrypointArgs(), //
|
|
configuration.TakeIsolateConfiguration()) //
|
|
) {
|
|
return RunStatus::Failure;
|
|
}
|
|
|
|
auto service_id = runtime_controller_->GetRootIsolateServiceID();
|
|
if (service_id.has_value()) {
|
|
std::unique_ptr<PlatformMessage> service_id_message =
|
|
std::make_unique<flutter::PlatformMessage>(
|
|
kIsolateChannel, MakeMapping(service_id.value()), nullptr);
|
|
HandlePlatformMessage(std::move(service_id_message));
|
|
}
|
|
|
|
return Engine::RunStatus::Success;
|
|
}
|
|
|
|
void Engine::BeginFrame(fml::TimePoint frame_time, uint64_t frame_number) {
|
|
runtime_controller_->BeginFrame(frame_time, frame_number);
|
|
}
|
|
|
|
void Engine::ReportTimings(std::vector<int64_t> timings) {
|
|
runtime_controller_->ReportTimings(std::move(timings));
|
|
}
|
|
|
|
void Engine::NotifyIdle(fml::TimeDelta deadline) {
|
|
runtime_controller_->NotifyIdle(deadline);
|
|
}
|
|
|
|
void Engine::NotifyDestroyed() {
|
|
TRACE_EVENT0("flutter", "Engine::NotifyDestroyed");
|
|
runtime_controller_->NotifyDestroyed();
|
|
}
|
|
|
|
std::optional<uint32_t> Engine::GetUIIsolateReturnCode() {
|
|
return runtime_controller_->GetRootIsolateReturnCode();
|
|
}
|
|
|
|
Dart_Port Engine::GetUIIsolateMainPort() {
|
|
return runtime_controller_->GetMainPort();
|
|
}
|
|
|
|
std::string Engine::GetUIIsolateName() {
|
|
return runtime_controller_->GetIsolateName();
|
|
}
|
|
|
|
bool Engine::UIIsolateHasLivePorts() {
|
|
return runtime_controller_->HasLivePorts();
|
|
}
|
|
|
|
tonic::DartErrorHandleType Engine::GetUIIsolateLastError() {
|
|
return runtime_controller_->GetLastError();
|
|
}
|
|
|
|
void Engine::AddView(int64_t view_id, const ViewportMetrics& view_metrics) {
|
|
runtime_controller_->AddView(view_id, view_metrics);
|
|
}
|
|
|
|
void Engine::RemoveView(int64_t view_id) {
|
|
runtime_controller_->RemoveView(view_id);
|
|
}
|
|
|
|
void Engine::SetViewportMetrics(int64_t view_id,
|
|
const ViewportMetrics& metrics) {
|
|
runtime_controller_->SetViewportMetrics(view_id, metrics);
|
|
ScheduleFrame();
|
|
}
|
|
|
|
void Engine::DispatchPlatformMessage(std::unique_ptr<PlatformMessage> message) {
|
|
std::string channel = message->channel();
|
|
if (channel == kLifecycleChannel) {
|
|
if (HandleLifecyclePlatformMessage(message.get())) {
|
|
return;
|
|
}
|
|
} else if (channel == kLocalizationChannel) {
|
|
if (HandleLocalizationPlatformMessage(message.get())) {
|
|
return;
|
|
}
|
|
} else if (channel == kSettingsChannel) {
|
|
HandleSettingsPlatformMessage(message.get());
|
|
return;
|
|
} else if (!runtime_controller_->IsRootIsolateRunning() &&
|
|
channel == kNavigationChannel) {
|
|
// If there's no runtime_, we may still need to set the initial route.
|
|
HandleNavigationPlatformMessage(std::move(message));
|
|
return;
|
|
}
|
|
|
|
if (runtime_controller_->IsRootIsolateRunning() &&
|
|
runtime_controller_->DispatchPlatformMessage(std::move(message))) {
|
|
return;
|
|
}
|
|
|
|
FML_DLOG(WARNING) << "Dropping platform message on channel: " << channel;
|
|
}
|
|
|
|
bool Engine::HandleLifecyclePlatformMessage(PlatformMessage* message) {
|
|
const auto& data = message->data();
|
|
std::string state(reinterpret_cast<const char*>(data.GetMapping()),
|
|
data.GetSize());
|
|
|
|
// Always schedule a frame when the app does become active as per API
|
|
// recommendation
|
|
// https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive?language=objc
|
|
if (state == "AppLifecycleState.resumed" ||
|
|
state == "AppLifecycleState.inactive") {
|
|
ScheduleFrame();
|
|
}
|
|
runtime_controller_->SetInitialLifecycleState(state);
|
|
// Always forward these messages to the framework by returning false.
|
|
return false;
|
|
}
|
|
|
|
bool Engine::HandleNavigationPlatformMessage(
|
|
std::unique_ptr<PlatformMessage> message) {
|
|
const auto& data = message->data();
|
|
|
|
rapidjson::Document document;
|
|
document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
|
|
data.GetSize());
|
|
if (document.HasParseError() || !document.IsObject()) {
|
|
return false;
|
|
}
|
|
auto root = document.GetObject();
|
|
auto method = root.FindMember("method");
|
|
if (method->value != "setInitialRoute") {
|
|
return false;
|
|
}
|
|
auto route = root.FindMember("args");
|
|
initial_route_ = route->value.GetString();
|
|
return true;
|
|
}
|
|
|
|
bool Engine::HandleLocalizationPlatformMessage(PlatformMessage* message) {
|
|
const auto& data = message->data();
|
|
|
|
rapidjson::Document document;
|
|
document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
|
|
data.GetSize());
|
|
if (document.HasParseError() || !document.IsObject()) {
|
|
return false;
|
|
}
|
|
auto root = document.GetObject();
|
|
auto method = root.FindMember("method");
|
|
if (method == root.MemberEnd()) {
|
|
return false;
|
|
}
|
|
const size_t strings_per_locale = 4;
|
|
if (method->value == "setLocale") {
|
|
// Decode and pass the list of locale data onwards to dart.
|
|
auto args = root.FindMember("args");
|
|
if (args == root.MemberEnd() || !args->value.IsArray()) {
|
|
return false;
|
|
}
|
|
|
|
if (args->value.Size() % strings_per_locale != 0) {
|
|
return false;
|
|
}
|
|
std::vector<std::string> locale_data;
|
|
for (size_t locale_index = 0; locale_index < args->value.Size();
|
|
locale_index += strings_per_locale) {
|
|
if (!args->value[locale_index].IsString() ||
|
|
!args->value[locale_index + 1].IsString()) {
|
|
return false;
|
|
}
|
|
locale_data.push_back(args->value[locale_index].GetString());
|
|
locale_data.push_back(args->value[locale_index + 1].GetString());
|
|
locale_data.push_back(args->value[locale_index + 2].GetString());
|
|
locale_data.push_back(args->value[locale_index + 3].GetString());
|
|
}
|
|
|
|
return runtime_controller_->SetLocales(locale_data);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Engine::HandleSettingsPlatformMessage(PlatformMessage* message) {
|
|
const auto& data = message->data();
|
|
std::string jsonData(reinterpret_cast<const char*>(data.GetMapping()),
|
|
data.GetSize());
|
|
if (runtime_controller_->SetUserSettingsData(jsonData)) {
|
|
ScheduleFrame();
|
|
}
|
|
}
|
|
|
|
void Engine::DispatchPointerDataPacket(
|
|
std::unique_ptr<PointerDataPacket> packet,
|
|
uint64_t trace_flow_id) {
|
|
TRACE_EVENT0_WITH_FLOW_IDS("flutter", "Engine::DispatchPointerDataPacket",
|
|
/*flow_id_count=*/1,
|
|
/*flow_ids=*/&trace_flow_id);
|
|
TRACE_FLOW_STEP("flutter", "PointerEvent", trace_flow_id);
|
|
pointer_data_dispatcher_->DispatchPacket(std::move(packet), trace_flow_id);
|
|
}
|
|
|
|
void Engine::DispatchSemanticsAction(int node_id,
|
|
SemanticsAction action,
|
|
fml::MallocMapping args) {
|
|
runtime_controller_->DispatchSemanticsAction(node_id, action,
|
|
std::move(args));
|
|
}
|
|
|
|
void Engine::SetSemanticsEnabled(bool enabled) {
|
|
runtime_controller_->SetSemanticsEnabled(enabled);
|
|
}
|
|
|
|
void Engine::SetAccessibilityFeatures(int32_t flags) {
|
|
runtime_controller_->SetAccessibilityFeatures(flags);
|
|
}
|
|
|
|
std::string Engine::DefaultRouteName() {
|
|
if (!initial_route_.empty()) {
|
|
return initial_route_;
|
|
}
|
|
return "/";
|
|
}
|
|
|
|
void Engine::ScheduleFrame(bool regenerate_layer_trees) {
|
|
animator_->RequestFrame(regenerate_layer_trees);
|
|
}
|
|
|
|
void Engine::Render(std::unique_ptr<flutter::LayerTree> layer_tree,
|
|
float device_pixel_ratio) {
|
|
if (!layer_tree) {
|
|
return;
|
|
}
|
|
|
|
// Ensure frame dimensions are sane.
|
|
if (layer_tree->frame_size().isEmpty() || device_pixel_ratio <= 0.0f) {
|
|
return;
|
|
}
|
|
|
|
animator_->Render(std::move(layer_tree), device_pixel_ratio);
|
|
}
|
|
|
|
void Engine::UpdateSemantics(SemanticsNodeUpdates update,
|
|
CustomAccessibilityActionUpdates actions) {
|
|
delegate_.OnEngineUpdateSemantics(std::move(update), std::move(actions));
|
|
}
|
|
|
|
void Engine::HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) {
|
|
if (message->channel() == kAssetChannel) {
|
|
HandleAssetPlatformMessage(std::move(message));
|
|
} else {
|
|
delegate_.OnEngineHandlePlatformMessage(std::move(message));
|
|
}
|
|
}
|
|
|
|
void Engine::OnRootIsolateCreated() {
|
|
delegate_.OnRootIsolateCreated();
|
|
}
|
|
|
|
void Engine::UpdateIsolateDescription(const std::string isolate_name,
|
|
int64_t isolate_port) {
|
|
delegate_.UpdateIsolateDescription(isolate_name, isolate_port);
|
|
}
|
|
|
|
std::unique_ptr<std::vector<std::string>> Engine::ComputePlatformResolvedLocale(
|
|
const std::vector<std::string>& supported_locale_data) {
|
|
return delegate_.ComputePlatformResolvedLocale(supported_locale_data);
|
|
}
|
|
|
|
double Engine::GetScaledFontSize(double unscaled_font_size,
|
|
int configuration_id) const {
|
|
return delegate_.GetScaledFontSize(unscaled_font_size, configuration_id);
|
|
}
|
|
|
|
void Engine::SetNeedsReportTimings(bool needs_reporting) {
|
|
delegate_.SetNeedsReportTimings(needs_reporting);
|
|
}
|
|
|
|
FontCollection& Engine::GetFontCollection() {
|
|
return *font_collection_;
|
|
}
|
|
|
|
void Engine::DoDispatchPacket(std::unique_ptr<PointerDataPacket> packet,
|
|
uint64_t trace_flow_id) {
|
|
animator_->EnqueueTraceFlowId(trace_flow_id);
|
|
if (runtime_controller_) {
|
|
runtime_controller_->DispatchPointerDataPacket(*packet);
|
|
}
|
|
}
|
|
|
|
void Engine::ScheduleSecondaryVsyncCallback(uintptr_t id,
|
|
const fml::closure& callback) {
|
|
animator_->ScheduleSecondaryVsyncCallback(id, callback);
|
|
}
|
|
|
|
void Engine::HandleAssetPlatformMessage(
|
|
std::unique_ptr<PlatformMessage> message) {
|
|
fml::RefPtr<PlatformMessageResponse> response = message->response();
|
|
if (!response) {
|
|
return;
|
|
}
|
|
const auto& data = message->data();
|
|
std::string asset_name(reinterpret_cast<const char*>(data.GetMapping()),
|
|
data.GetSize());
|
|
|
|
if (asset_manager_) {
|
|
std::unique_ptr<fml::Mapping> asset_mapping =
|
|
asset_manager_->GetAsMapping(asset_name);
|
|
if (asset_mapping) {
|
|
response->Complete(std::move(asset_mapping));
|
|
return;
|
|
}
|
|
}
|
|
|
|
response->CompleteEmpty();
|
|
}
|
|
|
|
const std::string& Engine::GetLastEntrypoint() const {
|
|
return last_entry_point_;
|
|
}
|
|
|
|
const std::string& Engine::GetLastEntrypointLibrary() const {
|
|
return last_entry_point_library_;
|
|
}
|
|
|
|
const std::vector<std::string>& Engine::GetLastEntrypointArgs() const {
|
|
return last_entry_point_args_;
|
|
}
|
|
|
|
// |RuntimeDelegate|
|
|
void Engine::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
|
|
return delegate_.RequestDartDeferredLibrary(loading_unit_id);
|
|
}
|
|
|
|
std::weak_ptr<PlatformMessageHandler> Engine::GetPlatformMessageHandler()
|
|
const {
|
|
return delegate_.GetPlatformMessageHandler();
|
|
}
|
|
|
|
void Engine::SendChannelUpdate(std::string name, bool listening) {
|
|
delegate_.OnEngineChannelUpdate(std::move(name), listening);
|
|
}
|
|
|
|
void Engine::LoadDartDeferredLibrary(
|
|
intptr_t loading_unit_id,
|
|
std::unique_ptr<const fml::Mapping> snapshot_data,
|
|
std::unique_ptr<const fml::Mapping> snapshot_instructions) {
|
|
if (runtime_controller_->IsRootIsolateRunning()) {
|
|
runtime_controller_->LoadDartDeferredLibrary(
|
|
loading_unit_id, std::move(snapshot_data),
|
|
std::move(snapshot_instructions));
|
|
} else {
|
|
LoadDartDeferredLibraryError(loading_unit_id, "No running root isolate.",
|
|
true);
|
|
}
|
|
}
|
|
|
|
void Engine::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
|
|
const std::string& error_message,
|
|
bool transient) {
|
|
if (runtime_controller_->IsRootIsolateRunning()) {
|
|
runtime_controller_->LoadDartDeferredLibraryError(loading_unit_id,
|
|
error_message, transient);
|
|
}
|
|
}
|
|
|
|
const std::weak_ptr<VsyncWaiter> Engine::GetVsyncWaiter() const {
|
|
return animator_->GetVsyncWaiter();
|
|
}
|
|
|
|
void Engine::SetDisplays(const std::vector<DisplayData>& displays) {
|
|
runtime_controller_->SetDisplays(displays);
|
|
ScheduleFrame();
|
|
}
|
|
|
|
} // namespace flutter
|