mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make sure that 'BeginFrame' and 'EndFrame' of the 'ExternalViewEmbedder' are paired (flutter/engine#32058)
This commit is contained in:
parent
a80ab445ee
commit
5850d41dd0
@ -335,6 +335,19 @@ class ExternalViewEmbedder {
|
||||
// embedder.
|
||||
virtual void Teardown();
|
||||
|
||||
// Change the flag about whether it is used in this frame, it will be set to
|
||||
// true when 'BeginFrame' and false when 'EndFrame'.
|
||||
void SetUsedThisFrame(bool used_this_frame) {
|
||||
used_this_frame_ = used_this_frame;
|
||||
}
|
||||
|
||||
// Whether it is used in this frame, returns true between 'BeginFrame' and
|
||||
// 'EndFrame', otherwise returns false.
|
||||
bool GetUsedThisFrame() const { return used_this_frame_; }
|
||||
|
||||
private:
|
||||
bool used_this_frame_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder);
|
||||
|
||||
}; // ExternalViewEmbedder
|
||||
|
||||
@ -151,10 +151,11 @@ void Rasterizer::DrawLastLayerTree(
|
||||
DrawToSurface(*frame_timings_recorder, *last_layer_tree_);
|
||||
|
||||
// EndFrame should perform cleanups for the external_view_embedder.
|
||||
if (external_view_embedder_) {
|
||||
if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
|
||||
bool should_resubmit_frame = ShouldResubmitFrame(raster_status);
|
||||
external_view_embedder_->EndFrame(should_resubmit_frame,
|
||||
raster_thread_merger_);
|
||||
external_view_embedder_->SetUsedThisFrame(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,9 +209,11 @@ RasterStatus Rasterizer::Draw(
|
||||
}
|
||||
|
||||
// EndFrame should perform cleanups for the external_view_embedder.
|
||||
if (surface_ && external_view_embedder_) {
|
||||
if (surface_ && external_view_embedder_ &&
|
||||
external_view_embedder_->GetUsedThisFrame()) {
|
||||
external_view_embedder_->EndFrame(should_resubmit_frame,
|
||||
raster_thread_merger_);
|
||||
external_view_embedder_->SetUsedThisFrame(false);
|
||||
}
|
||||
|
||||
// Consume as many pipeline items as possible. But yield the event loop
|
||||
@ -521,6 +524,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe(
|
||||
|
||||
SkCanvas* embedder_root_canvas = nullptr;
|
||||
if (external_view_embedder_) {
|
||||
FML_DCHECK(!external_view_embedder_->GetUsedThisFrame());
|
||||
external_view_embedder_->SetUsedThisFrame(true);
|
||||
external_view_embedder_->BeginFrame(
|
||||
layer_tree.frame_size(), surface_->GetContext(),
|
||||
layer_tree.device_pixel_ratio(), raster_thread_merger_);
|
||||
|
||||
@ -419,6 +419,60 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) {
|
||||
latch.Wait();
|
||||
}
|
||||
|
||||
TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) {
|
||||
std::string test_name =
|
||||
::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
ThreadHost thread_host("io.flutter.test." + test_name + ".",
|
||||
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
|
||||
ThreadHost::Type::IO | ThreadHost::Type::UI);
|
||||
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
|
||||
thread_host.raster_thread->GetTaskRunner(),
|
||||
thread_host.ui_thread->GetTaskRunner(),
|
||||
thread_host.io_thread->GetTaskRunner());
|
||||
MockDelegate delegate;
|
||||
EXPECT_CALL(delegate, GetTaskRunners())
|
||||
.WillRepeatedly(ReturnRef(task_runners));
|
||||
|
||||
auto rasterizer = std::make_unique<Rasterizer>(delegate);
|
||||
auto surface = std::make_unique<MockSurface>();
|
||||
EXPECT_CALL(*surface, MakeRenderContextCurrent())
|
||||
.WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(true))));
|
||||
|
||||
std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
|
||||
std::make_shared<MockExternalViewEmbedder>();
|
||||
rasterizer->SetExternalViewEmbedder(external_view_embedder);
|
||||
rasterizer->Setup(std::move(surface));
|
||||
|
||||
EXPECT_CALL(*external_view_embedder,
|
||||
BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr,
|
||||
/*device_pixel_ratio=*/2.0,
|
||||
/*raster_thread_merger=*/_))
|
||||
.Times(0);
|
||||
EXPECT_CALL(
|
||||
*external_view_embedder,
|
||||
EndFrame(/*should_resubmit_frame=*/false,
|
||||
/*raster_thread_merger=*/fml::RefPtr<fml::RasterThreadMerger>(
|
||||
nullptr)))
|
||||
.Times(0);
|
||||
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
thread_host.raster_thread->GetTaskRunner()->PostTask([&] {
|
||||
auto pipeline = std::make_shared<Pipeline<LayerTree>>(/*depth=*/10);
|
||||
auto layer_tree = std::make_unique<LayerTree>(/*frame_size=*/SkISize(),
|
||||
/*device_pixel_ratio=*/2.0f);
|
||||
PipelineProduceResult result =
|
||||
pipeline->Produce().Complete(std::move(layer_tree));
|
||||
EXPECT_TRUE(result.success);
|
||||
// Always discard the layer tree.
|
||||
auto discard_callback = [](LayerTree&) { return true; };
|
||||
RasterStatus status = rasterizer->Draw(CreateFinishedBuildRecorder(),
|
||||
pipeline, discard_callback);
|
||||
EXPECT_EQ(status, RasterStatus::kDiscarded);
|
||||
latch.Signal();
|
||||
});
|
||||
latch.Wait();
|
||||
}
|
||||
|
||||
TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) {
|
||||
std::string test_name =
|
||||
::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
|
||||
@ -2396,6 +2396,8 @@ TEST_F(ShellTest, OnServiceProtocolEstimateRasterCacheMemoryWorks) {
|
||||
|
||||
// TODO(https://github.com/flutter/flutter/issues/100273): Disabled due to
|
||||
// flakiness.
|
||||
// TODO(https://github.com/flutter/flutter/issues/100299): Fix it when
|
||||
// re-enabling.
|
||||
TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) {
|
||||
auto settings = CreateSettingsForFixture();
|
||||
|
||||
@ -2448,6 +2450,8 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) {
|
||||
|
||||
// TODO(https://github.com/flutter/flutter/issues/100273): Disabled due to
|
||||
// flakiness.
|
||||
// TODO(https://github.com/flutter/flutter/issues/100299): Fix it when
|
||||
// re-enabling.
|
||||
TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) {
|
||||
auto settings = CreateSettingsForFixture();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user