Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ bool ExternalViewEmbedder::SupportsDynamicThreadMerging() {
return false;
}

void ExternalViewEmbedder::Teardown() {}

} // namespace flutter
5 changes: 5 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@ class ExternalViewEmbedder {
// |RasterThreadMerger| instance.
virtual bool SupportsDynamicThreadMerging();

// Called when the rasterizer is being torn down.
// This method provides a way to release resources associated with the current
// embedder.
virtual void Teardown();

FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder);

}; // ExternalViewEmbedder
Expand Down
4 changes: 4 additions & 0 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ void Rasterizer::Teardown() {
raster_thread_merger_->UnMergeNowIfLastOne();
raster_thread_merger_->SetMergeUnmergeCallback(nullptr);
}

if (external_view_embedder_) {
external_view_embedder_->Teardown();
}
}

void Rasterizer::EnableThreadMergerIfNeeded() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,9 @@ bool AndroidExternalViewEmbedder::SupportsDynamicThreadMerging() {
return true;
}

// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::Teardown() {
surface_pool_->DestroyLayers(jni_facade_);
}

} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {

bool SupportsDynamicThreadMerging() override;

void Teardown() override;

// Gets the rect based on the device pixel ratio of a platform view displayed
// on the screen.
SkRect GetViewRect(int view_id) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -883,5 +883,70 @@ TEST(AndroidExternalViewEmbedder, DisableThreadMerger) {
ASSERT_FALSE(raster_thread_merger->IsMerged());
}

TEST(AndroidExternalViewEmbedder, Teardown) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context =
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
auto gr_context = GrDirectContext::MakeMock(nullptr);
auto frame_size = SkISize::Make(1000, 1000);
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
[&android_context, gr_context, window, frame_size]() {
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
SkSurface::MakeNull(1000, 1000), false,
[](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
return true;
});

auto surface_mock = std::make_unique<SurfaceMock>();
EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
.WillOnce(Return(ByMove(std::move(surface_frame_1))));

auto android_surface_mock =
std::make_unique<AndroidSurfaceMock>(android_context);
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
.WillOnce(Return(ByMove(std::move(surface_mock))));

return android_surface_mock;
});

auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);

embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger);

// Add an Android view.
MutatorsStack stack;
auto view_params = std::make_unique<EmbeddedViewParams>(
SkMatrix(), SkSize::Make(200, 200), stack);

embedder->PrerollCompositeEmbeddedView(0, std::move(view_params));

// This simulates Flutter UI that intersects with the Android view.
embedder->CompositeEmbeddedView(0)->drawRect(
SkRect::MakeXYWH(50, 50, 200, 200), SkPaint());

// Create a new overlay surface.
EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
.WillOnce(Return(
ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
0, window))));

auto surface_frame = std::make_unique<SurfaceFrame>(
SkSurface::MakeNull(1000, 1000), false,
[](const SurfaceFrame& surface_frame, SkCanvas* canvas) { return true; });
embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));

embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);

EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces());
// Teardown.
embedder->Teardown();
}

} // namespace testing
} // namespace flutter