Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e449541

Browse files
committed
a round of comments and docs
1 parent 25fadba commit e449541

File tree

8 files changed

+77
-22
lines changed

8 files changed

+77
-22
lines changed

shell/common/shell.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ class Shell final : public PlatformView::Delegate,
218218
/// This results is a Shell that has a smaller startup time cost
219219
/// and a smaller memory footprint than an Shell created with a
220220
/// Create function.
221+
///
222+
/// The new Shell is returned in a running state so RunEngine
223+
/// shouldn't be called again on the Shell. Once running, the
224+
/// second Shell is mostly independent from the original Shell
225+
/// and the original Shell doesn't need to keep running for the
226+
/// spawned Shell to keep functioning.
221227
/// @param[in] run_configuration A RunConfiguration used to run the Isolate
222228
/// associated with this new Shell. It doesn't have to be the same
223229
/// configuration as the current Shell but it needs to be in the

shell/common/shell_unittests.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2444,11 +2444,13 @@ TEST_F(ShellTest, Spawn) {
24442444

24452445
fml::AutoResetWaitableEvent main_latch;
24462446
std::string last_entry_point;
2447+
// Fulfill native function for the first Shell's entrypoint.
24472448
AddNativeCallback(
24482449
"SayHiFromFixturesAreFunctionalMain", CREATE_NATIVE_ENTRY([&](auto args) {
24492450
last_entry_point = shell->GetEngine()->GetLastEntrypoint();
24502451
main_latch.Signal();
24512452
}));
2453+
// Fulfill native function for the second Shell's entrypoint.
24522454
AddNativeCallback(
24532455
// The Dart native function names aren't very consistent but this is just
24542456
// the native function name of the second vm entrypoint in the fixture.
@@ -2457,6 +2459,7 @@ TEST_F(ShellTest, Spawn) {
24572459
RunEngine(shell.get(), std::move(configuration));
24582460
main_latch.Wait();
24592461
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
2462+
// Check first Shell ran the first entrypoint.
24602463
ASSERT_EQ("fixturesAreFunctionalMain", last_entry_point);
24612464

24622465
PostSync(
@@ -2478,6 +2481,7 @@ TEST_F(ShellTest, Spawn) {
24782481
ASSERT_TRUE(ValidateShell(spawn.get()));
24792482

24802483
PostSync(spawner->GetTaskRunners().GetUITaskRunner(), [&spawn] {
2484+
// Check second shell ran the second entrypoint.
24812485
ASSERT_EQ("testCanLaunchSecondaryIsolate",
24822486
spawn->GetEngine()->GetLastEntrypoint());
24832487
});

shell/platform/android/android_shell_holder.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <pthread.h>
1010
#include <sys/resource.h>
1111
#include <sys/time.h>
12-
#include <cstddef>
1312
#include <memory>
1413
#include <optional>
1514

@@ -150,7 +149,9 @@ AndroidShellHolder::AndroidShellHolder(
150149
shell_(std::move(shell)) {
151150
FML_DCHECK(jni_facade);
152151
FML_DCHECK(shell_);
152+
FML_DCHECK(shell_->IsSetup());
153153
FML_DCHECK(platform_view_);
154+
FML_DCHECK(thread_host_);
154155
is_valid_ = shell_ != nullptr;
155156
}
156157

@@ -171,10 +172,16 @@ std::unique_ptr<AndroidShellHolder> AndroidShellHolder::Spawn(
171172
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
172173
std::string entrypoint,
173174
std::string libraryUrl) const {
174-
FML_DCHECK(shell_) << "A new Shell can only be spawned if the current Shell "
175-
"is properly constructed";
175+
FML_DCHECK(shell_ && shell_->IsSetup())
176+
<< "A new Shell can only be spawned "
177+
"if the current Shell is properly constructed";
176178

179+
// Pull out the new PlatformViewAndroid from the new Shell to feed to it to
180+
// the new AndroidShellHolder.
177181
fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
182+
183+
// Take out the old AndroidContext to reuse inside the PlatformViewAndroid
184+
// of the new Shell.
178185
PlatformViewAndroid* android_platform_view = platform_view_.get();
179186
// There's some indirection with platform_view_ being a weak pointer but
180187
// we just checked that the shell_ exists above and a valid shell is the
@@ -192,8 +199,7 @@ std::unique_ptr<AndroidShellHolder> AndroidShellHolder::Spawn(
192199
shell, // delegate
193200
shell.GetTaskRunners(), // task runners
194201
jni_facade, // JNI interop
195-
shell.GetSettings()
196-
.enable_software_rendering // use software rendering
202+
android_context // Android context
197203
);
198204
weak_platform_view = platform_view_android->GetWeakPtr();
199205
shell.OnDisplayUpdates(DisplayUpdateType::kStartup,
@@ -205,9 +211,12 @@ std::unique_ptr<AndroidShellHolder> AndroidShellHolder::Spawn(
205211
return std::make_unique<Rasterizer>(shell);
206212
};
207213

208-
FML_DLOG(ERROR) << "Spawned run";
214+
// TODO(xster): could be worth tracing this to investigate whether
215+
// the IsolateConfiguration could be cached somewhere.
209216
auto config = BuildRunConfiguration(asset_manager_, entrypoint, libraryUrl);
210217
if (!config) {
218+
// If the RunConfiguration was null, the kernel blob wasn't readable.
219+
// Fail the whole thing.
211220
return nullptr;
212221
}
213222

shell/platform/android/android_shell_holder.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include <memory>
99

10-
#include "assets/asset_manager.h"
10+
#include "flutter/assets/asset_manager.h"
1111
#include "flutter/fml/macros.h"
1212
#include "flutter/fml/unique_fd.h"
1313
#include "flutter/lib/ui/window/viewport_metrics.h"
@@ -49,11 +49,16 @@ class AndroidShellHolder {
4949
/// This is similar to the standard constructor, except its
5050
/// members were constructed elsewhere and injected.
5151
///
52+
/// All injected components must be non-null and valid.
53+
///
54+
/// Used when constructing the Shell from the inside out when
55+
/// spawning from an existing Shell.
56+
///
5257
AndroidShellHolder(flutter::Settings settings,
5358
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
5459
std::shared_ptr<ThreadHost> thread_host,
5560
std::unique_ptr<Shell> shell,
56-
fml::WeakPtr<PlatformViewAndroid>);
61+
fml::WeakPtr<PlatformViewAndroid> platform_view);
5762

5863
~AndroidShellHolder();
5964

@@ -80,6 +85,9 @@ class AndroidShellHolder {
8085
/// makes, the JNI instance holding this AndroidShellHolder should
8186
/// be created first to supply the jni_facade callback.
8287
///
88+
/// @param[in] jni_facade this argument should be the JNI callback facade of
89+
/// a new JNI instance meant to hold this AndroidShellHolder.
90+
///
8391
std::unique_ptr<AndroidShellHolder> Spawn(
8492
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
8593
std::string entrypoint,
@@ -99,6 +107,7 @@ class AndroidShellHolder {
99107
void UpdateAssetManager(fml::RefPtr<flutter::AssetManager> asset_manager);
100108

101109
void NotifyLowMemoryWarning();
110+
;
102111

103112
private:
104113
const flutter::Settings settings_;

shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,7 @@ private boolean isAttachedToJni() {
370370
* AOT or snapshot.
371371
* @return a new {@link FlutterEngine}.
372372
*/
373-
// This method is package private because it's non-ideal. The method on FlutterEngine should
374-
// ideally just create a second engine and a call to its DartExecutor should then run a
375-
// DartEntrypoint.
373+
@NonNull
376374
/*package*/ FlutterEngine spawn(@NonNull DartEntrypoint dartEntrypoint) {
377375
if (!isAttachedToJni()) {
378376
throw new IllegalStateException(

shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public class FlutterJNI {
106106
* <p>This must be called before any other native methods, and can be overridden by tests to avoid
107107
* loading native libraries.
108108
*
109-
* <p>This method should only be called once.
109+
* <p>This method should only be called once across all FlutterJNI instances.
110110
*/
111111
public void loadLibrary() {
112112
if (loadLibraryCalled = true) {
@@ -124,7 +124,7 @@ public void loadLibrary() {
124124
* singleton owned by Skia. Note that, the first call to SkFontMgr::RefDefault() will take
125125
* noticeable time, but later calls will return a reference to the preexisting font manager.
126126
*
127-
* <p>This method should only be called once.
127+
* <p>This method should only be called once across all FlutterJNI instances.
128128
*/
129129
public void prefetchDefaultFontManager() {
130130
if (prefetchDefaultFontManagerCalled = true) {
@@ -332,6 +332,7 @@ public long performNativeAttach(@NonNull FlutterJNI flutterJNI, boolean isBackgr
332332
* on the spawned FlutterJNI instance.
333333
*/
334334
@UiThread
335+
@NonNull
335336
public FlutterJNI spawn(
336337
@Nullable String entrypointFunctionName, @Nullable String pathToEntrypointFunction) {
337338
ensureRunningOnMainThread();

shell/platform/android/platform_view_android.cc

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,19 @@ PlatformViewAndroid::PlatformViewAndroid(
7474
fml::MakeRefCounted<AndroidEnvironmentGL>());
7575
#endif // SHELL_ENABLE_VULKAN
7676
}
77-
FML_CHECK(android_context_ && android_context_->IsValid())
78-
<< "Could not create an Android context.";
79-
80-
surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
81-
*android_context_, jni_facade);
77+
InitSurface();
78+
}
8279

83-
android_surface_ = surface_factory_->CreateSurface();
84-
FML_CHECK(android_surface_ && android_surface_->IsValid())
85-
<< "Could not create an OpenGL, Vulkan or Software surface to setup "
86-
"rendering.";
80+
PlatformViewAndroid::PlatformViewAndroid(
81+
PlatformView::Delegate& delegate,
82+
flutter::TaskRunners task_runners,
83+
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
84+
std::shared_ptr<flutter::AndroidContext> android_context)
85+
: PlatformView(delegate, std::move(task_runners)),
86+
jni_facade_(jni_facade),
87+
android_context_(android_context),
88+
platform_view_android_delegate_(jni_facade) {
89+
InitSurface();
8790
}
8891

8992
PlatformViewAndroid::PlatformViewAndroid(
@@ -96,6 +99,19 @@ PlatformViewAndroid::PlatformViewAndroid(
9699

97100
PlatformViewAndroid::~PlatformViewAndroid() = default;
98101

102+
void PlatformViewAndroid::InitSurface() {
103+
FML_CHECK(android_context_ && android_context_->IsValid())
104+
<< "Could not create an Android context.";
105+
106+
surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
107+
*android_context_, jni_facade_);
108+
109+
android_surface_ = surface_factory_->CreateSurface();
110+
FML_CHECK(android_surface_ && android_surface_->IsValid())
111+
<< "Could not create an OpenGL, Vulkan or Software surface to setup "
112+
"rendering.";
113+
}
114+
99115
void PlatformViewAndroid::NotifyCreated(
100116
fml::RefPtr<AndroidNativeWindow> native_window) {
101117
if (android_surface_) {

shell/platform/android/platform_view_android.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ class PlatformViewAndroid final : public PlatformView {
5353
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
5454
bool use_software_rendering);
5555

56+
//----------------------------------------------------------------------------
57+
/// @brief Creates a new PlatformViewAndroid but using an existing
58+
/// Android GPU context to create new surfaces. This maximizes
59+
/// resource sharing between 2 PlatformViewAndroids of 2 Shells.
60+
///
61+
PlatformViewAndroid(PlatformView::Delegate& delegate,
62+
flutter::TaskRunners task_runners,
63+
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
64+
std::shared_ptr<flutter::AndroidContext> android_context);
65+
5666
~PlatformViewAndroid() override;
5767

5868
void NotifyCreated(fml::RefPtr<AndroidNativeWindow> native_window);
@@ -159,6 +169,8 @@ class PlatformViewAndroid final : public PlatformView {
159169
// |PlatformView|
160170
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override;
161171

172+
void InitSurface();
173+
162174
void InstallFirstFrameCallback();
163175

164176
void FireFirstFrameCallback();

0 commit comments

Comments
 (0)