Teardown external view embedder prior to unmerging threads (flutter/engine#30893)

This commit is contained in:
Emmanuel Garcia
2022-01-26 12:25:10 -08:00
committed by GitHub
parent 8662accbf0
commit a3ea78de97
4 changed files with 68 additions and 31 deletions

View File

@@ -4,6 +4,8 @@
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/task_runner.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/platform/android/surface/android_surface.h"
@@ -12,12 +14,14 @@ namespace flutter {
AndroidExternalViewEmbedder::AndroidExternalViewEmbedder(
const AndroidContext& android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
std::shared_ptr<AndroidSurfaceFactory> surface_factory)
std::shared_ptr<AndroidSurfaceFactory> surface_factory,
TaskRunners task_runners)
: ExternalViewEmbedder(),
android_context_(android_context),
jni_facade_(jni_facade),
surface_factory_(surface_factory),
surface_pool_(std::make_unique<SurfacePool>()) {}
surface_pool_(std::make_unique<SurfacePool>()),
task_runners_(task_runners) {}
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView(
@@ -264,8 +268,8 @@ void AndroidExternalViewEmbedder::BeginFrame(
// The surface size changed. Therefore, destroy existing surfaces as
// the existing surfaces in the pool can't be recycled.
if (frame_size_ != frame_size && raster_thread_merger->IsOnPlatformThread()) {
surface_pool_->DestroyLayers(jni_facade_);
if (frame_size_ != frame_size) {
DestroySurfaces();
}
surface_pool_->SetFrameSize(frame_size);
// JNI method must be called on the platform thread.
@@ -300,7 +304,18 @@ bool AndroidExternalViewEmbedder::SupportsDynamicThreadMerging() {
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::Teardown() {
surface_pool_->DestroyLayers(jni_facade_);
DestroySurfaces();
}
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::DestroySurfaces() {
fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(task_runners_.GetPlatformTaskRunner(),
[&]() {
surface_pool_->DestroyLayers(jni_facade_);
latch.Signal();
});
latch.Wait();
}
} // namespace flutter

View File

@@ -7,6 +7,7 @@
#include <unordered_map>
#include "flutter/common/task_runners.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/rtree.h"
#include "flutter/shell/platform/android/context/android_context.h"
@@ -32,7 +33,8 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
AndroidExternalViewEmbedder(
const AndroidContext& android_context,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
std::shared_ptr<AndroidSurfaceFactory> surface_factory);
std::shared_ptr<AndroidSurfaceFactory> surface_factory,
TaskRunners task_runners);
// |ExternalViewEmbedder|
void PrerollCompositeEmbeddedView(
@@ -99,6 +101,9 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
// Holds surfaces. Allows to recycle surfaces or allocate new ones.
const std::unique_ptr<SurfacePool> surface_pool_;
// The task runners.
const TaskRunners task_runners_;
// The size of the root canvas.
SkISize frame_size_;
@@ -126,6 +131,11 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
// The number of platform views in the previous frame.
int64_t previous_frame_view_count_;
// Destroys the surfaces created from the surface factory.
// This method schedules a task on the platform thread, and waits for
// the task until it completes.
void DestroySurfaces();
// Resets the state.
void Reset();

View File

@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define FML_USED_ON_EMBEDDER
#include <memory>
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
@@ -87,12 +89,24 @@ fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromRasterThread(
rasterizer_queue_id);
}
TaskRunners GetTaskRunnersForFixture() {
fml::MessageLoop::EnsureInitializedForCurrentThread();
auto& loop = fml::MessageLoop::GetCurrent();
return {
"test",
loop.GetTaskRunner(), // platform
loop.GetTaskRunner(), // raster
loop.GetTaskRunner(), // ui
loop.GetTaskRunner() // io
};
}
TEST(AndroidExternalViewEmbedder, GetCurrentCanvases) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);
@@ -117,7 +131,7 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvasesCompositeOrder) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);
@@ -140,7 +154,7 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvasesCompositeOrder) {
TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, nullptr, nullptr);
android_context, nullptr, nullptr, GetTaskRunnersForFixture());
ASSERT_EQ(nullptr, embedder->CompositeEmbeddedView(0));
embedder->PrerollCompositeEmbeddedView(
@@ -156,7 +170,7 @@ TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
TEST(AndroidExternalViewEmbedder, CancelFrame) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, nullptr, nullptr);
android_context, nullptr, nullptr, GetTaskRunnersForFixture());
embedder->PrerollCompositeEmbeddedView(
0, std::make_unique<EmbeddedViewParams>());
@@ -170,7 +184,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
@@ -204,7 +218,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
@@ -225,7 +239,7 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRect) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);
@@ -253,7 +267,7 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRectChangedParams) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);
@@ -328,7 +342,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
return android_surface_mock;
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
@@ -521,7 +535,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
return android_surface_mock;
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
@@ -623,7 +637,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) {
return android_surface_mock;
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
auto raster_thread_merger = GetThreadMergerFromPlatformThread();
@@ -662,7 +676,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) {
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
// While on the raster thread, don't make JNI calls as these methods can only
// run on the platform thread.
@@ -711,7 +725,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);
@@ -798,7 +812,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
// ------------------ First frame ------------------ //
{
@@ -843,9 +857,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
}
// Changing the frame size from the raster thread does not make JNI calls.
EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(1);
EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
fml::Thread platform_thread("platform");
@@ -857,7 +869,7 @@ TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
ASSERT_TRUE(embedder->SupportsDynamicThreadMerging());
}
@@ -865,7 +877,7 @@ TEST(AndroidExternalViewEmbedder, DisableThreadMerger) {
auto jni_mock = std::make_shared<JNIMock>();
auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, nullptr);
android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
fml::Thread platform_thread("platform");
auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread);
@@ -921,7 +933,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) {
});
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
*android_context, jni_mock, surface_factory);
*android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
fml::Thread rasterizer_thread("rasterizer");
auto raster_thread_merger =
GetThreadMergerFromPlatformThread(&rasterizer_thread);

View File

@@ -14,13 +14,12 @@
#include "flutter/shell/platform/android/android_external_texture_gl.h"
#include "flutter/shell/platform/android/android_surface_gl.h"
#include "flutter/shell/platform/android/android_surface_software.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/shell/platform/android/surface/android_surface.h"
#include "flutter/shell/platform/android/surface/snapshot_surface_producer.h"
#include "flutter/shell/platform/android/context/android_context.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_message_response_android.h"
#include "flutter/shell/platform/android/surface/android_surface.h"
#include "flutter/shell/platform/android/surface/snapshot_surface_producer.h"
#include "flutter/shell/platform/android/vsync_waiter_android.h"
namespace flutter {
@@ -255,7 +254,8 @@ std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
std::shared_ptr<ExternalViewEmbedder>
PlatformViewAndroid::CreateExternalViewEmbedder() {
return std::make_shared<AndroidExternalViewEmbedder>(
*android_context_, jni_facade_, surface_factory_);
*android_context_, jni_facade_, surface_factory_,
std::move(task_runners_));
}
// |PlatformView|