mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Plumbing refactor to allow the usage of Dart_CreateIsolateInGroup (flutter/engine#23549)
Did the plumbing refactor that allows us to call Dart_CreateIsolateInGroup when applicable.
This commit is contained in:
parent
fbd0f1df95
commit
dbc486213c
@ -73,6 +73,29 @@ Dart_IsolateFlags DartIsolate::Flags::Get() const {
|
||||
return flags_;
|
||||
}
|
||||
|
||||
std::weak_ptr<DartIsolate> DartIsolate::SpawnIsolate(
|
||||
const Settings& settings,
|
||||
std::unique_ptr<PlatformConfiguration> platform_configuration,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
|
||||
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) const {
|
||||
return CreateRunningRootIsolate(
|
||||
settings, GetIsolateGroupData().GetIsolateSnapshot(), GetTaskRunners(),
|
||||
std::move(platform_configuration), snapshot_delegate, hint_freed_delegate,
|
||||
GetIOManager(), GetSkiaUnrefQueue(), GetImageDecoder(),
|
||||
advisory_script_uri, advisory_script_entrypoint, flags,
|
||||
isolate_create_callback, isolate_shutdown_callback, dart_entrypoint,
|
||||
dart_entrypoint_library, std::move(isolate_configration),
|
||||
GetVolatilePathTracker(), this);
|
||||
}
|
||||
|
||||
std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
|
||||
const Settings& settings,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
@ -91,7 +114,8 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
|
||||
std::optional<std::string> dart_entrypoint,
|
||||
std::optional<std::string> dart_entrypoint_library,
|
||||
std::unique_ptr<IsolateConfiguration> isolate_configration,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker) {
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
|
||||
const DartIsolate* spawning_isolate) {
|
||||
if (!isolate_snapshot) {
|
||||
FML_LOG(ERROR) << "Invalid isolate snapshot.";
|
||||
return {};
|
||||
@ -135,7 +159,8 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
|
||||
});
|
||||
|
||||
if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
|
||||
FML_LOG(ERROR) << "Root isolate was created in an incorrect phase.";
|
||||
FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
|
||||
<< static_cast<int>(isolate->GetPhase());
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -190,7 +215,8 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
|
||||
Flags flags,
|
||||
const fml::closure& isolate_create_callback,
|
||||
const fml::closure& isolate_shutdown_callback,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker) {
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
|
||||
const DartIsolate* spawning_isolate) {
|
||||
TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
|
||||
|
||||
// The child isolate preparer is null but will be set when the isolate is
|
||||
@ -223,13 +249,28 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
|
||||
)));
|
||||
|
||||
DartErrorString error;
|
||||
Dart_Isolate vm_isolate = nullptr;
|
||||
auto isolate_flags = flags.Get();
|
||||
Dart_Isolate vm_isolate = CreateDartIsolateGroup(
|
||||
/// TODO(b/72025) This will be where we call Dart_CreateIsolateInGroup if
|
||||
/// spawning_isolate != nullptr.
|
||||
vm_isolate = CreateDartIsolateGroup(
|
||||
std::move(isolate_group_data), std::move(isolate_data), &isolate_flags,
|
||||
error.error());
|
||||
error.error(),
|
||||
[](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
|
||||
std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
|
||||
char** error) {
|
||||
return Dart_CreateIsolateGroup(
|
||||
(*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
|
||||
(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
|
||||
(*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
|
||||
(*isolate_group_data)
|
||||
->GetIsolateSnapshot()
|
||||
->GetInstructionsMapping(),
|
||||
flags, isolate_group_data, isolate_data, error);
|
||||
});
|
||||
|
||||
if (error) {
|
||||
FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error.str();
|
||||
FML_LOG(ERROR) << "CreateRootIsolate failed: " << error.str();
|
||||
}
|
||||
|
||||
if (vm_isolate == nullptr) {
|
||||
@ -809,6 +850,11 @@ DartIsolateGroupData& DartIsolate::GetIsolateGroupData() {
|
||||
return **isolate_group_data;
|
||||
}
|
||||
|
||||
const DartIsolateGroupData& DartIsolate::GetIsolateGroupData() const {
|
||||
DartIsolate* non_const_this = const_cast<DartIsolate*>(this);
|
||||
return non_const_this->GetIsolateGroupData();
|
||||
}
|
||||
|
||||
// |Dart_IsolateGroupCreateCallback|
|
||||
Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
|
||||
const char* advisory_script_uri,
|
||||
@ -871,7 +917,19 @@ Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
|
||||
nullptr))); // volatile path tracker
|
||||
|
||||
Dart_Isolate vm_isolate = CreateDartIsolateGroup(
|
||||
std::move(isolate_group_data), std::move(isolate_data), flags, error);
|
||||
std::move(isolate_group_data), std::move(isolate_data), flags, error,
|
||||
[](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
|
||||
std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
|
||||
char** error) {
|
||||
return Dart_CreateIsolateGroup(
|
||||
(*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
|
||||
(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
|
||||
(*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
|
||||
(*isolate_group_data)
|
||||
->GetIsolateSnapshot()
|
||||
->GetInstructionsMapping(),
|
||||
flags, isolate_group_data, isolate_data, error);
|
||||
});
|
||||
|
||||
if (*error) {
|
||||
FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error;
|
||||
@ -933,16 +991,16 @@ Dart_Isolate DartIsolate::CreateDartIsolateGroup(
|
||||
std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
|
||||
std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
|
||||
Dart_IsolateFlags* flags,
|
||||
char** error) {
|
||||
char** error,
|
||||
std::function<Dart_Isolate(std::shared_ptr<DartIsolateGroupData>*,
|
||||
std::shared_ptr<DartIsolate>*,
|
||||
Dart_IsolateFlags*,
|
||||
char**)> make_isolate) {
|
||||
TRACE_EVENT0("flutter", "DartIsolate::CreateDartIsolateGroup");
|
||||
|
||||
// Create the Dart VM isolate and give it the embedder object as the baton.
|
||||
Dart_Isolate isolate = Dart_CreateIsolateGroup(
|
||||
(*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
|
||||
(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
|
||||
(*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
|
||||
(*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
|
||||
flags, isolate_group_data.get(), isolate_data.get(), error);
|
||||
Dart_Isolate isolate =
|
||||
make_isolate(isolate_group_data.get(), isolate_data.get(), flags, error);
|
||||
|
||||
if (isolate == nullptr) {
|
||||
return nullptr;
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "flutter/lib/ui/io_manager.h"
|
||||
#include "flutter/lib/ui/snapshot_delegate.h"
|
||||
#include "flutter/lib/ui/ui_dart_state.h"
|
||||
#include "flutter/lib/ui/volatile_path_tracker.h"
|
||||
#include "flutter/lib/ui/window/platform_configuration.h"
|
||||
#include "flutter/runtime/dart_snapshot.h"
|
||||
#include "third_party/dart/runtime/include/dart_api.h"
|
||||
@ -207,7 +206,9 @@ class DartIsolate : public UIDartState {
|
||||
/// for all isolate shutdowns
|
||||
/// (including the children of the
|
||||
/// root isolate).
|
||||
///
|
||||
/// @param[in] spawning_isolate The isolate that is spawning the
|
||||
/// new isolate. See also
|
||||
/// DartIsolate::SpawnIsolate.
|
||||
/// @return A weak pointer to the root Dart isolate. The caller must
|
||||
/// ensure that the isolate is not referenced for long periods of
|
||||
/// time as it prevents isolate collection when the isolate
|
||||
@ -232,7 +233,37 @@ class DartIsolate : public UIDartState {
|
||||
std::optional<std::string> dart_entrypoint,
|
||||
std::optional<std::string> dart_entrypoint_library,
|
||||
std::unique_ptr<IsolateConfiguration> isolate_configration,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker);
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
|
||||
const DartIsolate* spawning_isolate = nullptr);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Creates a running DartIsolate who shares as many resources as
|
||||
/// possible with the caller DartIsolate. This allows them to
|
||||
/// occupy less memory together and to be created faster.
|
||||
/// @details Shared components will be destroyed when the last live
|
||||
/// DartIsolate is destroyed. SpawnIsolate can only be used to
|
||||
/// create DartIsolates whose executable code is shared with the
|
||||
/// calling DartIsolate.
|
||||
/// @attention Only certain setups can take advantage of the most savings
|
||||
/// currently, AOT specifically.
|
||||
/// @return A weak pointer to a new running DartIsolate. The caller must
|
||||
/// ensure that the isolate is not referenced for long periods of
|
||||
/// time as it prevents isolate collection when the isolate
|
||||
/// terminates itself. The caller may also only use the isolate on
|
||||
/// the thread on which the isolate was created.
|
||||
std::weak_ptr<DartIsolate> SpawnIsolate(
|
||||
const Settings& settings,
|
||||
std::unique_ptr<PlatformConfiguration> platform_configuration,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
|
||||
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) const;
|
||||
|
||||
// |UIDartState|
|
||||
~DartIsolate() override;
|
||||
@ -433,7 +464,8 @@ class DartIsolate : public UIDartState {
|
||||
Flags flags,
|
||||
const fml::closure& isolate_create_callback,
|
||||
const fml::closure& isolate_shutdown_callback,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker);
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
|
||||
const DartIsolate* spawning_isolate = nullptr);
|
||||
|
||||
DartIsolate(const Settings& settings,
|
||||
TaskRunners task_runners,
|
||||
@ -463,6 +495,8 @@ class DartIsolate : public UIDartState {
|
||||
|
||||
DartIsolateGroupData& GetIsolateGroupData();
|
||||
|
||||
const DartIsolateGroupData& GetIsolateGroupData() const;
|
||||
|
||||
// |Dart_IsolateGroupCreateCallback|
|
||||
static Dart_Isolate DartIsolateGroupCreateCallback(
|
||||
const char* advisory_script_uri,
|
||||
@ -487,7 +521,11 @@ class DartIsolate : public UIDartState {
|
||||
std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
|
||||
std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
|
||||
Dart_IsolateFlags* flags,
|
||||
char** error);
|
||||
char** error,
|
||||
std::function<Dart_Isolate(std::shared_ptr<DartIsolateGroupData>*,
|
||||
std::shared_ptr<DartIsolate>*,
|
||||
Dart_IsolateFlags*,
|
||||
char**)> make_isolate);
|
||||
|
||||
static bool InitializeIsolate(std::shared_ptr<DartIsolate> embedder_isolate,
|
||||
Dart_Isolate isolate,
|
||||
|
||||
@ -77,6 +77,69 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
|
||||
ASSERT_TRUE(root_isolate->Shutdown());
|
||||
}
|
||||
|
||||
TEST_F(DartIsolateTest, SpawnIsolate) {
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
auto settings = CreateSettingsForFixture();
|
||||
auto vm_ref = DartVMRef::Create(settings);
|
||||
ASSERT_TRUE(vm_ref);
|
||||
auto vm_data = vm_ref.GetVMData();
|
||||
ASSERT_TRUE(vm_data);
|
||||
TaskRunners task_runners(GetCurrentTestName(), //
|
||||
GetCurrentTaskRunner(), //
|
||||
GetCurrentTaskRunner(), //
|
||||
GetCurrentTaskRunner(), //
|
||||
GetCurrentTaskRunner() //
|
||||
);
|
||||
|
||||
auto isolate_configuration =
|
||||
IsolateConfiguration::InferFromSettings(settings);
|
||||
|
||||
auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
|
||||
vm_data->GetSettings(), // settings
|
||||
vm_data->GetIsolateSnapshot(), // isolate snapshot
|
||||
std::move(task_runners), // task runners
|
||||
nullptr, // window
|
||||
{}, // snapshot delegate
|
||||
{}, // hint freed delegate
|
||||
{}, // io manager
|
||||
{}, // unref queue
|
||||
{}, // image decoder
|
||||
"main.dart", // advisory uri
|
||||
"main", // advisory entrypoint,
|
||||
DartIsolate::Flags{}, // flags
|
||||
settings.isolate_create_callback, // isolate create callback
|
||||
settings.isolate_shutdown_callback, // isolate shutdown callback
|
||||
"main", // dart entrypoint
|
||||
std::nullopt, // dart entrypoint library
|
||||
std::move(isolate_configuration), // isolate configuration
|
||||
nullptr // Volatile path tracker
|
||||
);
|
||||
auto root_isolate = weak_isolate.lock();
|
||||
ASSERT_TRUE(root_isolate);
|
||||
ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
|
||||
|
||||
auto spawn_configuration = IsolateConfiguration::InferFromSettings(settings);
|
||||
|
||||
auto weak_spawn = root_isolate->SpawnIsolate(
|
||||
/*settings=*/vm_data->GetSettings(),
|
||||
/*platform_configuration=*/nullptr,
|
||||
/*snapshot_delegate=*/{},
|
||||
/*hint_freed_delegate=*/{},
|
||||
/*advisory_script_uri=*/"main.dart",
|
||||
/*advisory_script_entrypoint=*/"main",
|
||||
/*flags=*/DartIsolate::Flags{},
|
||||
/*isolate_create_callback=*/settings.isolate_create_callback,
|
||||
/*isolate_shutdown_callback=*/settings.isolate_shutdown_callback,
|
||||
/*dart_entrypoint=*/"main",
|
||||
/*dart_entrypoint_library=*/std::nullopt,
|
||||
/*isolate_configration=*/std::move(spawn_configuration));
|
||||
auto spawn = weak_spawn.lock();
|
||||
ASSERT_TRUE(spawn);
|
||||
ASSERT_EQ(spawn->GetPhase(), DartIsolate::Phase::Running);
|
||||
ASSERT_TRUE(spawn->Shutdown());
|
||||
ASSERT_TRUE(root_isolate->Shutdown());
|
||||
}
|
||||
|
||||
TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
auto settings = CreateSettingsForFixture();
|
||||
|
||||
@ -31,6 +31,8 @@ class DartVMRef {
|
||||
fml::RefPtr<DartSnapshot> vm_snapshot = nullptr,
|
||||
fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr);
|
||||
|
||||
DartVMRef(const DartVMRef&) = default;
|
||||
|
||||
DartVMRef(DartVMRef&&);
|
||||
|
||||
~DartVMRef();
|
||||
@ -53,11 +55,21 @@ class DartVMRef {
|
||||
return vm_.get();
|
||||
}
|
||||
|
||||
const DartVM* get() const {
|
||||
FML_DCHECK(vm_);
|
||||
return vm_.get();
|
||||
}
|
||||
|
||||
DartVM* operator->() {
|
||||
FML_DCHECK(vm_);
|
||||
return vm_.get();
|
||||
}
|
||||
|
||||
const DartVM* operator->() const {
|
||||
FML_DCHECK(vm_);
|
||||
return vm_.get();
|
||||
}
|
||||
|
||||
DartVM* operator&() {
|
||||
FML_DCHECK(vm_);
|
||||
return vm_.get();
|
||||
@ -72,8 +84,6 @@ class DartVMRef {
|
||||
|
||||
// Only used by Dart Isolate to register itself with the VM.
|
||||
static DartVM* GetRunningVM();
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DartVMRef);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -57,6 +57,25 @@ RuntimeController::RuntimeController(
|
||||
persistent_isolate_data_(std::move(p_persistent_isolate_data)),
|
||||
volatile_path_tracker_(std::move(p_volatile_path_tracker)) {}
|
||||
|
||||
std::unique_ptr<RuntimeController> RuntimeController::Spawn(
|
||||
RuntimeDelegate& client,
|
||||
std::string advisory_script_uri,
|
||||
std::string advisory_script_entrypoint,
|
||||
const std::function<void(int64_t)>& idle_notification_callback,
|
||||
const fml::closure& isolate_create_callback,
|
||||
const fml::closure& isolate_shutdown_callback,
|
||||
std::shared_ptr<const fml::Mapping> persistent_isolate_data) const {
|
||||
auto result = std::make_unique<RuntimeController>(
|
||||
client, vm_, isolate_snapshot_, task_runners_, snapshot_delegate_,
|
||||
hint_freed_delegate_, io_manager_, unref_queue_, image_decoder_,
|
||||
advisory_script_uri, advisory_script_entrypoint,
|
||||
idle_notification_callback, platform_data_, isolate_create_callback,
|
||||
isolate_shutdown_callback, persistent_isolate_data,
|
||||
volatile_path_tracker_);
|
||||
result->spawning_isolate_ = root_isolate_;
|
||||
return result;
|
||||
}
|
||||
|
||||
RuntimeController::~RuntimeController() {
|
||||
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
|
||||
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
|
||||
|
||||
@ -133,6 +133,22 @@ class RuntimeController : public PlatformConfigurationClient {
|
||||
std::shared_ptr<const fml::Mapping> persistent_isolate_data,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Create a RuntimeController that shares as many resources as
|
||||
/// possible with the calling RuntimeController such that together
|
||||
/// they occupy less memory.
|
||||
/// @return A RuntimeController with a running isolate.
|
||||
/// @see RuntimeController::RuntimeController
|
||||
///
|
||||
std::unique_ptr<RuntimeController> Spawn(
|
||||
RuntimeDelegate& client,
|
||||
std::string advisory_script_uri,
|
||||
std::string advisory_script_entrypoint,
|
||||
const std::function<void(int64_t)>& idle_notification_callback,
|
||||
const fml::closure& isolate_create_callback,
|
||||
const fml::closure& isolate_shutdown_callback,
|
||||
std::shared_ptr<const fml::Mapping> persistent_isolate_data) const;
|
||||
|
||||
// |PlatformConfigurationClient|
|
||||
~RuntimeController() override;
|
||||
|
||||
@ -542,6 +558,23 @@ class RuntimeController : public PlatformConfigurationClient {
|
||||
|
||||
// |PlatformConfigurationClient|
|
||||
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override;
|
||||
const fml::WeakPtr<IOManager>& GetIOManager() const { return io_manager_; }
|
||||
|
||||
DartVM* GetDartVM() const { return vm_; }
|
||||
|
||||
const fml::RefPtr<const DartSnapshot>& GetIsolateSnapshot() const {
|
||||
return isolate_snapshot_;
|
||||
}
|
||||
|
||||
const PlatformData& GetPlatformData() const { return platform_data_; }
|
||||
|
||||
const fml::RefPtr<SkiaUnrefQueue>& GetSkiaUnrefQueue() const {
|
||||
return unref_queue_;
|
||||
}
|
||||
|
||||
const fml::WeakPtr<SnapshotDelegate>& GetSnapshotDelegate() const {
|
||||
return snapshot_delegate_;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Constructor for Mocks.
|
||||
@ -576,6 +609,7 @@ class RuntimeController : public PlatformConfigurationClient {
|
||||
std::function<void(int64_t)> idle_notification_callback_;
|
||||
PlatformData platform_data_;
|
||||
std::weak_ptr<DartIsolate> root_isolate_;
|
||||
std::weak_ptr<DartIsolate> spawning_isolate_;
|
||||
std::optional<uint32_t> root_isolate_return_code_;
|
||||
const fml::closure isolate_create_callback_;
|
||||
const fml::closure isolate_shutdown_callback_;
|
||||
|
||||
@ -97,6 +97,33 @@ Engine::Engine(Delegate& delegate,
|
||||
);
|
||||
}
|
||||
|
||||
std::unique_ptr<Engine> Engine::Spawn(
|
||||
Delegate& delegate,
|
||||
const PointerDataDispatcherMaker& dispatcher_maker,
|
||||
Settings settings,
|
||||
std::unique_ptr<Animator> animator) 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=*/runtime_controller_->GetIOManager(),
|
||||
/*runtime_controller=*/nullptr);
|
||||
result->runtime_controller_ = runtime_controller_->Spawn(
|
||||
*result, // runtime delegate
|
||||
settings_.advisory_script_uri, // advisory script uri
|
||||
settings_.advisory_script_entrypoint, // advisory script entrypoint
|
||||
settings_.idle_notification_callback, // idle notification callback
|
||||
settings_.isolate_create_callback, // isolate create callback
|
||||
settings_.isolate_shutdown_callback, // isolate shutdown callback
|
||||
settings_.persistent_isolate_data // persistent isolate data
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
Engine::~Engine() = default;
|
||||
|
||||
fml::WeakPtr<Engine> Engine::GetWeakPtr() const {
|
||||
|
||||
@ -354,6 +354,23 @@ class Engine final : public RuntimeDelegate,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Create a Engine that shares as many resources as
|
||||
/// possible with the calling Engine such that together
|
||||
/// they occupy less memory and be created faster.
|
||||
/// @details This method ultimately calls DartIsolate::SpawnIsolate to make
|
||||
/// sure resources are shared. This should only be called on
|
||||
/// running Engines.
|
||||
/// @return A new Engine with a running isolate.
|
||||
/// @see Engine::Engine
|
||||
/// @see DartIsolate::SpawnIsolate
|
||||
///
|
||||
std::unique_ptr<Engine> Spawn(
|
||||
Delegate& delegate,
|
||||
const PointerDataDispatcherMaker& dispatcher_maker,
|
||||
Settings settings,
|
||||
std::unique_ptr<Animator> animator) const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Destroys the engine engine. Called by the shell on the UI task
|
||||
/// runner. The running root isolate is terminated and will no
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "flutter/fml/paths.h"
|
||||
#include "flutter/fml/trace_event.h"
|
||||
#include "flutter/fml/unique_fd.h"
|
||||
#include "flutter/lib/ui/painting/path.h"
|
||||
#include "flutter/runtime/dart_vm.h"
|
||||
#include "flutter/shell/common/engine.h"
|
||||
#include "flutter/shell/common/skia_event_tracer_impl.h"
|
||||
@ -40,6 +39,35 @@ constexpr char kSystemChannel[] = "flutter/system";
|
||||
constexpr char kTypeKey[] = "type";
|
||||
constexpr char kFontChange[] = "fontsChange";
|
||||
|
||||
namespace {
|
||||
std::unique_ptr<Engine> CreateEngine(
|
||||
Engine::Delegate& delegate,
|
||||
const PointerDataDispatcherMaker& dispatcher_maker,
|
||||
DartVM& vm,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
TaskRunners task_runners,
|
||||
const PlatformData platform_data,
|
||||
Settings settings,
|
||||
std::unique_ptr<Animator> animator,
|
||||
fml::WeakPtr<IOManager> io_manager,
|
||||
fml::RefPtr<SkiaUnrefQueue> unref_queue,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker) {
|
||||
return std::make_unique<Engine>(delegate, //
|
||||
dispatcher_maker, //
|
||||
vm, //
|
||||
isolate_snapshot, //
|
||||
task_runners, //
|
||||
platform_data, //
|
||||
settings, //
|
||||
std::move(animator), //
|
||||
io_manager, //
|
||||
unref_queue, //
|
||||
snapshot_delegate, //
|
||||
volatile_path_tracker);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
|
||||
DartVMRef vm,
|
||||
TaskRunners task_runners,
|
||||
@ -47,7 +75,8 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
|
||||
Settings settings,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
|
||||
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
|
||||
const Shell::EngineCreateCallback& on_create_engine) {
|
||||
if (!task_runners.IsValid()) {
|
||||
FML_LOG(ERROR) << "Task runners to run the shell were invalid.";
|
||||
return nullptr;
|
||||
@ -142,8 +171,8 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
|
||||
vsync_waiter = std::move(vsync_waiter), //
|
||||
&weak_io_manager_future, //
|
||||
&snapshot_delegate_future, //
|
||||
&unref_queue_future //
|
||||
]() mutable {
|
||||
&unref_queue_future, //
|
||||
&on_create_engine]() mutable {
|
||||
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
|
||||
const auto& task_runners = shell->GetTaskRunners();
|
||||
|
||||
@ -152,20 +181,19 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
|
||||
auto animator = std::make_unique<Animator>(*shell, task_runners,
|
||||
std::move(vsync_waiter));
|
||||
|
||||
engine_promise.set_value(std::make_unique<Engine>(
|
||||
*shell, //
|
||||
dispatcher_maker, //
|
||||
*shell->GetDartVM(), //
|
||||
std::move(isolate_snapshot), //
|
||||
task_runners, //
|
||||
platform_data, //
|
||||
shell->GetSettings(), //
|
||||
std::move(animator), //
|
||||
weak_io_manager_future.get(), //
|
||||
unref_queue_future.get(), //
|
||||
snapshot_delegate_future.get(), //
|
||||
shell->volatile_path_tracker_ //
|
||||
));
|
||||
engine_promise.set_value(
|
||||
on_create_engine(*shell, //
|
||||
dispatcher_maker, //
|
||||
*shell->GetDartVM(), //
|
||||
std::move(isolate_snapshot), //
|
||||
task_runners, //
|
||||
platform_data, //
|
||||
shell->GetSettings(), //
|
||||
std::move(animator), //
|
||||
weak_io_manager_future.get(), //
|
||||
unref_queue_future.get(), //
|
||||
snapshot_delegate_future.get(), //
|
||||
shell->volatile_path_tracker_));
|
||||
}));
|
||||
|
||||
if (!shell->Setup(std::move(platform_view), //
|
||||
@ -265,14 +293,40 @@ std::unique_ptr<Shell> Shell::Create(
|
||||
|
||||
TRACE_EVENT0("flutter", "Shell::Create");
|
||||
|
||||
auto vm = DartVMRef::Create(settings);
|
||||
FML_CHECK(vm) << "Must be able to initialize the VM.";
|
||||
|
||||
auto vm_data = vm->GetVMData();
|
||||
|
||||
return Shell::Create(std::move(task_runners), //
|
||||
std::move(platform_data), //
|
||||
std::move(settings), //
|
||||
vm_data->GetIsolateSnapshot(), // isolate snapshot
|
||||
on_create_platform_view, //
|
||||
on_create_rasterizer, //
|
||||
std::move(vm), //
|
||||
CreateEngine);
|
||||
}
|
||||
|
||||
std::unique_ptr<Shell> Shell::Create(
|
||||
TaskRunners task_runners,
|
||||
const PlatformData platform_data,
|
||||
Settings settings,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
|
||||
DartVMRef vm,
|
||||
const Shell::EngineCreateCallback& on_create_engine) {
|
||||
PerformInitializationTasks(settings);
|
||||
PersistentCache::SetCacheSkSL(settings.cache_sksl);
|
||||
|
||||
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
|
||||
|
||||
if (!task_runners.IsValid() || !on_create_platform_view ||
|
||||
!on_create_rasterizer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto vm = DartVMRef::Create(settings);
|
||||
FML_CHECK(vm) << "Must be able to initialize the VM.";
|
||||
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
std::unique_ptr<Shell> shell;
|
||||
fml::TaskRunner::RunNowOrPostTask(
|
||||
@ -284,8 +338,8 @@ std::unique_ptr<Shell> Shell::Create(
|
||||
platform_data, //
|
||||
settings, //
|
||||
on_create_platform_view, //
|
||||
on_create_rasterizer //
|
||||
]() mutable {
|
||||
on_create_rasterizer, //
|
||||
&on_create_engine]() mutable {
|
||||
auto isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
|
||||
shell = CreateShellOnPlatformThread(std::move(vm),
|
||||
std::move(task_runners), //
|
||||
@ -293,8 +347,8 @@ std::unique_ptr<Shell> Shell::Create(
|
||||
settings, //
|
||||
std::move(isolate_snapshot), //
|
||||
on_create_platform_view, //
|
||||
on_create_rasterizer //
|
||||
);
|
||||
on_create_rasterizer, //
|
||||
on_create_engine);
|
||||
latch.Signal();
|
||||
}));
|
||||
latch.Wait();
|
||||
@ -423,14 +477,29 @@ Shell::~Shell() {
|
||||
std::unique_ptr<Shell> Shell::Spawn(
|
||||
Settings settings,
|
||||
const CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const CreateCallback<Rasterizer>& on_create_rasterizer) {
|
||||
const CreateCallback<Rasterizer>& on_create_rasterizer) const {
|
||||
FML_DCHECK(task_runners_.IsValid());
|
||||
std::unique_ptr<Shell> result(Shell::Create(
|
||||
task_runners_, PlatformData{}, settings,
|
||||
vm_->GetVMData()->GetIsolateSnapshot(), on_create_platform_view,
|
||||
on_create_rasterizer, vm_,
|
||||
[engine = this->engine_.get()](
|
||||
Engine::Delegate& delegate,
|
||||
const PointerDataDispatcherMaker& dispatcher_maker, DartVM& vm,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
TaskRunners task_runners, const PlatformData platform_data,
|
||||
Settings settings, std::unique_ptr<Animator> animator,
|
||||
fml::WeakPtr<IOManager> io_manager,
|
||||
fml::RefPtr<SkiaUnrefQueue> unref_queue,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker) {
|
||||
return engine->Spawn(/*delegate=*/delegate,
|
||||
/*dispatcher_maker=*/dispatcher_maker,
|
||||
/*settings=*/settings,
|
||||
/*animator=*/std::move(animator));
|
||||
}));
|
||||
RunConfiguration configuration =
|
||||
RunConfiguration::InferFromSettings(settings);
|
||||
TaskRunners task_runners = task_runners_;
|
||||
FML_DCHECK(task_runners.IsValid());
|
||||
std::unique_ptr<Shell> result(Shell::Create(std::move(task_runners), settings,
|
||||
on_create_platform_view,
|
||||
on_create_rasterizer));
|
||||
result->RunEngine(std::move(configuration));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -98,6 +98,20 @@ class Shell final : public PlatformView::Delegate,
|
||||
public:
|
||||
template <class T>
|
||||
using CreateCallback = std::function<std::unique_ptr<T>(Shell&)>;
|
||||
typedef std::function<std::unique_ptr<Engine>(
|
||||
Engine::Delegate& delegate,
|
||||
const PointerDataDispatcherMaker& dispatcher_maker,
|
||||
DartVM& vm,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
TaskRunners task_runners,
|
||||
const PlatformData platform_data,
|
||||
Settings settings,
|
||||
std::unique_ptr<Animator> animator,
|
||||
fml::WeakPtr<IOManager> io_manager,
|
||||
fml::RefPtr<SkiaUnrefQueue> unref_queue,
|
||||
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
|
||||
std::shared_ptr<VolatilePathTracker> volatile_path_tracker)>
|
||||
EngineCreateCallback;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Creates a shell instance using the provided settings. The
|
||||
@ -169,6 +183,27 @@ class Shell final : public PlatformView::Delegate,
|
||||
CreateCallback<PlatformView> on_create_platform_view,
|
||||
CreateCallback<Rasterizer> on_create_rasterizer);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Creates a shell instance using the provided settings.
|
||||
/// @details This version of Create can take in a running DartVMRef and a
|
||||
/// function that defines how the Shell's Engine should be
|
||||
/// created.
|
||||
/// @param[in] vm A running DartVMRef where this Shell's Dart
|
||||
/// code will be executed.
|
||||
/// @param[in] on_create_engine A function that creates an Engine during
|
||||
/// initialization.
|
||||
/// @see Shell::Create
|
||||
///
|
||||
static std::unique_ptr<Shell> Create(
|
||||
TaskRunners task_runners,
|
||||
const PlatformData platform_data,
|
||||
Settings settings,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
const CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const CreateCallback<Rasterizer>& on_create_rasterizer,
|
||||
DartVMRef vm,
|
||||
const EngineCreateCallback& on_create_engine);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Destroys the shell. This is a synchronous operation and
|
||||
/// synchronous barrier blocks are introduced on the various
|
||||
@ -188,7 +223,7 @@ class Shell final : public PlatformView::Delegate,
|
||||
std::unique_ptr<Shell> Spawn(
|
||||
Settings settings,
|
||||
const CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const CreateCallback<Rasterizer>& on_create_rasterizer);
|
||||
const CreateCallback<Rasterizer>& on_create_rasterizer) const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Starts an isolate for the given RunConfiguration.
|
||||
@ -429,7 +464,8 @@ class Shell final : public PlatformView::Delegate,
|
||||
Settings settings,
|
||||
fml::RefPtr<const DartSnapshot> isolate_snapshot,
|
||||
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
|
||||
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer);
|
||||
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
|
||||
const EngineCreateCallback& on_create_engine);
|
||||
|
||||
bool Setup(std::unique_ptr<PlatformView> platform_view,
|
||||
std::unique_ptr<Engine> engine,
|
||||
|
||||
@ -78,6 +78,9 @@ class DartState : public std::enable_shared_from_this<DartState> {
|
||||
Dart_Handle library,
|
||||
Dart_Handle url);
|
||||
|
||||
protected:
|
||||
Dart_Isolate isolate() const { return isolate_; }
|
||||
|
||||
private:
|
||||
Dart_Isolate isolate_;
|
||||
DartPersistentValue private_constructor_name_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user