Skip to content

Commit

Permalink
Discard the resubmitted layer tree of the wrong size instead of rende…
Browse files Browse the repository at this point in the history
…ring it (flutter#28474)
  • Loading branch information
ColdPaleLight authored Sep 10, 2021
1 parent 7135100 commit 825c409
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 6 deletions.
10 changes: 6 additions & 4 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void Rasterizer::DrawLastLayerTree(
RasterStatus Rasterizer::Draw(
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
LayerTreeDiscardCallback discardCallback) {
LayerTreeDiscardCallback discard_callback) {
TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter",
"GPURasterizer::Draw");
if (raster_thread_merger_ &&
Expand All @@ -170,7 +170,7 @@ RasterStatus Rasterizer::Draw(
RasterStatus raster_status = RasterStatus::kFailed;
Pipeline<flutter::LayerTree>::Consumer consumer =
[&](std::unique_ptr<LayerTree> layer_tree) {
if (discardCallback(*layer_tree.get())) {
if (discard_callback(*layer_tree.get())) {
raster_status = RasterStatus::kDiscarded;
} else {
raster_status =
Expand Down Expand Up @@ -208,9 +208,11 @@ RasterStatus Rasterizer::Draw(
delegate_.GetTaskRunners().GetRasterTaskRunner()->PostTask(
fml::MakeCopyable(
[weak_this = weak_factory_.GetWeakPtr(), pipeline,
resubmit_recorder = std::move(resubmit_recorder)]() mutable {
resubmit_recorder = std::move(resubmit_recorder),
discard_callback = std::move(discard_callback)]() mutable {
if (weak_this) {
weak_this->Draw(std::move(resubmit_recorder), pipeline);
weak_this->Draw(std::move(resubmit_recorder), pipeline,
std::move(discard_callback));
}
}));
break;
Expand Down
4 changes: 2 additions & 2 deletions shell/common/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,13 @@ class Rasterizer final : public SnapshotDelegate {
///
/// @param[in] pipeline The layer tree pipeline to take the next layer tree
/// to render from.
/// @param[in] discardCallback if specified and returns true, the layer tree
/// @param[in] discard_callback if specified and returns true, the layer tree
/// is discarded instead of being rendered
///
RasterStatus Draw(
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
std::shared_ptr<Pipeline<flutter::LayerTree>> pipeline,
LayerTreeDiscardCallback discardCallback = NoDiscard);
LayerTreeDiscardCallback discard_callback = NoDiscard);

//----------------------------------------------------------------------------
/// @brief The type of the screenshot to obtain of the previously
Expand Down
86 changes: 86 additions & 0 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,92 @@ TEST_F(ShellTest, DiscardLayerTreeOnResize) {
DestroyShell(std::move(shell));
}

TEST_F(ShellTest, DiscardResubmittedLayerTreeOnResize) {
auto settings = CreateSettingsForFixture();

SkISize origin_size = SkISize::Make(400, 100);
SkISize new_size = SkISize::Make(400, 200);

fml::AutoResetWaitableEvent end_frame_latch;

fml::AutoResetWaitableEvent resize_latch;

std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_ref;
auto end_frame_callback =
[&](bool should_merge_thread,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
if (!raster_thread_merger_ref) {
raster_thread_merger_ref = raster_thread_merger;
}
if (should_merge_thread) {
raster_thread_merger->MergeWithLease(10);
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kSuccess);
}
end_frame_latch.Signal();

if (should_merge_thread) {
resize_latch.Wait();
}
};

external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
std::move(end_frame_callback), PostPrerollResult::kResubmitFrame, true);

std::unique_ptr<Shell> shell = CreateShell(
settings, GetTaskRunnersForFixture(), false, external_view_embedder);

// Create the surface needed by rasterizer
PlatformViewNotifyCreated(shell.get());

fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &origin_size]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, static_cast<double>(origin_size.width()),
static_cast<double>(origin_size.height()), 22});
});

auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");

RunEngine(shell.get(), std::move(configuration));

PumpOneFrame(shell.get(), static_cast<double>(origin_size.width()),
static_cast<double>(origin_size.height()));

end_frame_latch.Wait();
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());

fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &new_size, &resize_latch]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, static_cast<double>(new_size.width()),
static_cast<double>(new_size.height()), 22});
resize_latch.Signal();
});

end_frame_latch.Wait();

// The frame resubmitted with origin size should be discarded after the
// viewport metrics changed.
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());

// Threads will be merged at the end of this frame.
PumpOneFrame(shell.get(), static_cast<double>(new_size.width()),
static_cast<double>(new_size.height()));

end_frame_latch.Wait();
ASSERT_TRUE(raster_thread_merger_ref->IsMerged());
ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
ASSERT_EQ(new_size, external_view_embedder->GetLastSubmittedFrameSize());

PlatformViewNotifyDestroyed(shell.get());
DestroyShell(std::move(shell));
}

TEST_F(ShellTest, IgnoresInvalidMetrics) {
fml::AutoResetWaitableEvent latch;
double last_device_pixel_ratio;
Expand Down

0 comments on commit 825c409

Please sign in to comment.