diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 36eee5e174d06..55bd1d2fd1782 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -156,7 +156,8 @@ void Rasterizer::DrawLastLayerTree() { DrawToSurface(*last_layer_tree_); } -void Rasterizer::Draw(fml::RefPtr> pipeline) { +void Rasterizer::Draw(fml::RefPtr> pipeline, + DiscardCallback discardCallback) { TRACE_EVENT0("flutter", "GPURasterizer::Draw"); if (raster_thread_merger_ && !raster_thread_merger_->IsOnRasterizingThread()) { @@ -170,7 +171,11 @@ void Rasterizer::Draw(fml::RefPtr> pipeline) { RasterStatus raster_status = RasterStatus::kFailed; Pipeline::Consumer consumer = [&](std::unique_ptr layer_tree) { - raster_status = DoDraw(std::move(layer_tree)); + if (discardCallback && discardCallback(*layer_tree.get())) { + raster_status = RasterStatus::kSuccess; + } else { + raster_status = DoDraw(std::move(layer_tree)); + } }; PipelineConsumeResult consume_result = pipeline->Consume(consumer); diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index e400ff16b2e23..0aee48dc6b39c 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -204,6 +204,8 @@ class Rasterizer final : public SnapshotDelegate { /// flutter::TextureRegistry* GetTextureRegistry(); + using DiscardCallback = std::function; + //---------------------------------------------------------------------------- /// @brief Takes the next item from the layer tree pipeline and executes /// the raster thread frame workload for that pipeline item to @@ -232,8 +234,11 @@ 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 + // is discarded instead of being rendered /// - void Draw(fml::RefPtr> pipeline); + void Draw(fml::RefPtr> pipeline, + DiscardCallback discardCallback = nullptr); //---------------------------------------------------------------------------- /// @brief The type of the screenshot to obtain of the previously diff --git a/shell/common/shell.cc b/shell/common/shell.cc index ff576e4358c2b..e3eaac2fc1050 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -822,13 +822,8 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { // This is the formula Android uses. // https://android.googlesource.com/platform/frameworks/base/+/master/libs/hwui/renderthread/CacheManager.cpp#41 - size_t max_bytes = metrics.physical_width * metrics.physical_height * 12 * 4; - task_runners_.GetRasterTaskRunner()->PostTask( - [rasterizer = rasterizer_->GetWeakPtr(), max_bytes] { - if (rasterizer) { - rasterizer->SetResourceCacheMaxBytes(max_bytes, false); - } - }); + resource_cache_max_bytes_update_ = + metrics.physical_width * metrics.physical_height * 12 * 4; task_runners_.GetUITaskRunner()->PostTask( [engine = engine_->GetWeakPtr(), metrics]() { @@ -836,6 +831,10 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { engine->SetViewportMetrics(metrics); } }); + + std::scoped_lock lock(resize_mutex_); + expected_frame_size_ = + SkISize::Make(metrics.physical_width, metrics.physical_height); } // |PlatformView::Delegate| @@ -1025,13 +1024,22 @@ void Shell::OnAnimatorDraw(fml::RefPtr> pipeline, } } + size_t max_bytes = resource_cache_max_bytes_update_; + resource_cache_max_bytes_update_ = 0; + task_runners_.GetRasterTaskRunner()->PostTask( [&waiting_for_first_frame = waiting_for_first_frame_, &waiting_for_first_frame_condition = waiting_for_first_frame_condition_, - rasterizer = rasterizer_->GetWeakPtr(), - pipeline = std::move(pipeline)]() { + rasterizer = rasterizer_->GetWeakPtr(), max_bytes, + pipeline = std::move(pipeline), this]() { if (rasterizer) { - rasterizer->Draw(pipeline); + if (max_bytes != 0) { + rasterizer->SetResourceCacheMaxBytes(max_bytes, false); + } + rasterizer->Draw(pipeline, [this](flutter::LayerTree& tree) { + std::scoped_lock lock(resize_mutex_); + return tree.frame_size() != expected_frame_size_; + }); if (waiting_for_first_frame.load()) { waiting_for_first_frame.store(false); diff --git a/shell/common/shell.h b/shell/common/shell.h index c8dad14e02193..4f3722343f14c 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -425,6 +425,10 @@ class Shell final : public PlatformView::Delegate, // and read from the raster thread. std::atomic display_refresh_rate_ = 0.0f; + std::mutex resize_mutex_; + SkISize expected_frame_size_ = SkISize::MakeEmpty(); + size_t resource_cache_max_bytes_update_ = 0; + // How many frames have been timed since last report. size_t UnreportedFramesCount() const;