From d934818d22754f38ff95317b1682f5aed5b3cc90 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 14:58:44 -0700 Subject: [PATCH 01/15] Create layer tree on taking --- flow/layers/layer_tree.cc | 14 ++-- flow/layers/layer_tree.h | 32 ++++----- flow/layers/layer_tree_unittests.cc | 55 +++++++++------ lib/ui/compositing/scene.cc | 55 +++++++++------ lib/ui/compositing/scene.h | 17 +++-- ...isplay_list_deferred_image_gpu_impeller.cc | 14 ++-- ...display_list_deferred_image_gpu_impeller.h | 6 +- .../display_list_deferred_image_gpu_skia.cc | 12 ++-- .../display_list_deferred_image_gpu_skia.h | 6 +- lib/ui/painting/picture.cc | 27 ++++---- lib/ui/painting/picture.h | 12 ++-- runtime/runtime_delegate.h | 2 +- shell/common/animator.cc | 2 +- shell/common/animator.h | 2 +- shell/common/animator_unittests.cc | 8 +-- shell/common/engine.cc | 2 +- shell/common/engine.h | 2 +- shell/common/engine_unittests.cc | 2 +- shell/common/pipeline.h | 4 +- shell/common/rasterizer.cc | 4 +- shell/common/rasterizer.h | 6 +- shell/common/rasterizer_unittests.cc | 69 +++++++++++-------- shell/common/shell_test.cc | 10 +-- 23 files changed, 202 insertions(+), 161 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index d01b243ab3eb8..8a0cb890acef8 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -20,12 +20,16 @@ namespace flutter { -LayerTree::LayerTree(const SkISize& frame_size, float device_pixel_ratio) - : frame_size_(frame_size), +LayerTree::LayerTree(const Config& config, + const SkISize& frame_size, + float device_pixel_ratio) + : root_layer_(config.root_layer), + frame_size_(frame_size), device_pixel_ratio_(device_pixel_ratio), - rasterizer_tracing_threshold_(0), - checkerboard_raster_cache_images_(false), - checkerboard_offscreen_layers_(false) { + rasterizer_tracing_threshold_(config.rasterizer_tracing_threshold), + checkerboard_raster_cache_images_( + config.checkerboard_raster_cache_images), + checkerboard_offscreen_layers_(config.checkerboard_offscreen_layers) { FML_CHECK(device_pixel_ratio_ != 0.0f); } diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index a39cc2360076f..f01c1c80044ad 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -23,7 +23,16 @@ namespace flutter { class LayerTree { public: - LayerTree(const SkISize& frame_size, float device_pixel_ratio); + struct Config { + std::shared_ptr root_layer; + uint32_t rasterizer_tracing_threshold = 0; + bool checkerboard_raster_cache_images = false; + bool checkerboard_offscreen_layers = false; + }; + + LayerTree(const Config& config, + const SkISize& frame_size, + float device_pixel_ratio); // Perform a preroll pass on the tree and return information about // the tree that affects rendering this frame. @@ -50,11 +59,6 @@ class LayerTree { GrDirectContext* gr_context = nullptr); Layer* root_layer() const { return root_layer_.get(); } - - void set_root_layer(std::shared_ptr root_layer) { - root_layer_ = std::move(root_layer); - } - const SkISize& frame_size() const { return frame_size_; } float device_pixel_ratio() const { return device_pixel_ratio_; } @@ -62,24 +66,12 @@ class LayerTree { PaintRegionMap& paint_region_map() { return paint_region_map_; } // The number of frame intervals missed after which the compositor must - // trace the rasterized picture to a trace file. Specify 0 to disable all - // tracing - void set_rasterizer_tracing_threshold(uint32_t interval) { - rasterizer_tracing_threshold_ = interval; - } - + // trace the rasterized picture to a trace file. 0 stands for disabling all + // tracing. uint32_t rasterizer_tracing_threshold() const { return rasterizer_tracing_threshold_; } - void set_checkerboard_raster_cache_images(bool checkerboard) { - checkerboard_raster_cache_images_ = checkerboard; - } - - void set_checkerboard_offscreen_layers(bool checkerboard) { - checkerboard_offscreen_layers_ = checkerboard; - } - /// When `Paint` is called, if leaf layer tracing is enabled, additional /// metadata around raterization of leaf layers is collected. /// diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index ea655b5b44ae8..47673b8eb764b 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -19,8 +19,7 @@ namespace testing { class LayerTreeTest : public CanvasTest { public: LayerTreeTest() - : layer_tree_(SkISize::Make(64, 64), 1.0f), - root_transform_(SkMatrix::Translate(1.0f, 1.0f)), + : root_transform_(SkMatrix::Translate(1.0f, 1.0f)), scoped_frame_(compositor_context_.AcquireFrame(nullptr, &mock_canvas(), nullptr, @@ -31,12 +30,14 @@ class LayerTreeTest : public CanvasTest { nullptr, nullptr)) {} - LayerTree& layer_tree() { return layer_tree_; } CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); } const SkMatrix& root_transform() { return root_transform_; } + std::unique_ptr BuildLayerTree(LayerTree::Config config) { + return std::make_unique(config, SkISize::Make(64, 64), 1.0f); + } + private: - LayerTree layer_tree_; CompositorContext compositor_context_; SkMatrix root_transform_; std::unique_ptr scoped_frame_; @@ -45,12 +46,14 @@ class LayerTreeTest : public CanvasTest { TEST_F(LayerTreeTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_TRUE(layer->is_empty()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); } TEST_F(LayerTreeTest, PaintBeforePrerollDies) { @@ -61,13 +64,15 @@ TEST_F(LayerTreeTest, PaintBeforePrerollDies) { auto layer = std::make_shared(); layer->Add(mock_layer); - layer_tree().set_root_layer(layer); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_TRUE(mock_layer->is_empty()); EXPECT_TRUE(layer->is_empty()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); } @@ -79,15 +84,17 @@ TEST_F(LayerTreeTest, Simple) { auto layer = std::make_shared(); layer->Add(mock_layer); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); EXPECT_FALSE(mock_layer->is_empty()); EXPECT_FALSE(layer->is_empty()); EXPECT_EQ(mock_layer->parent_matrix(), root_transform()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ 0, MockCanvas::DrawPathData{child_path, child_paint}}})); @@ -107,8 +114,10 @@ TEST_F(LayerTreeTest, Multiple) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); @@ -121,7 +130,7 @@ TEST_F(LayerTreeTest, Multiple) { EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); // Siblings are independent - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ( mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ @@ -140,8 +149,10 @@ TEST_F(LayerTreeTest, MultipleWithEmpty) { layer->Add(mock_layer1); layer->Add(mock_layer2); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds()); EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds()); @@ -153,7 +164,7 @@ TEST_F(LayerTreeTest, MultipleWithEmpty) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ 0, MockCanvas::DrawPathData{child_path1, child_paint1}}})); @@ -172,8 +183,10 @@ TEST_F(LayerTreeTest, NeedsSystemComposite) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); @@ -185,7 +198,7 @@ TEST_F(LayerTreeTest, NeedsSystemComposite) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ( mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index c5070c6376091..f85397ac881b5 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -45,22 +45,23 @@ Scene::Scene(std::shared_ptr rootLayer, ->platform_configuration() ->get_window(0) ->viewport_metrics(); - - layer_tree_ = std::make_shared( - SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); - layer_tree_->set_root_layer(std::move(rootLayer)); - layer_tree_->set_rasterizer_tracing_threshold(rasterizerTracingThreshold); - layer_tree_->set_checkerboard_raster_cache_images( - checkerboardRasterCacheImages); - layer_tree_->set_checkerboard_offscreen_layers(checkerboardOffscreenLayers); + device_width_ = viewport_metrics.physical_width; + device_height_ = viewport_metrics.physical_height; + device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); + + layer_tree_config_ = std::make_unique(); + layer_tree_config_->root_layer = std::move(rootLayer); + layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; + layer_tree_config_->checkerboard_raster_cache_images = + checkerboardRasterCacheImages; + layer_tree_config_->checkerboard_offscreen_layers = + checkerboardOffscreenLayers; } Scene::~Scene() {} void Scene::dispose() { - layer_tree_.reset(); + layer_tree_config_.reset(); ClearDartWrapper(); } @@ -69,8 +70,8 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - if (!layer_tree_) { - return tonic::ToDart("Scene did not contain a layer tree."); + if (!layer_tree_config_) { + return tonic::ToDart("Scene's layer tree has been taken away."); } Scene::RasterizeToImage(width, height, raw_image_handle); @@ -82,17 +83,18 @@ Dart_Handle Scene::toImage(uint32_t width, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - if (!layer_tree_) { - return tonic::ToDart("Scene did not contain a layer tree."); + if (!layer_tree_config_) { + return tonic::ToDart("Scene's layer tree has been taken away."); } - return Picture::RasterizeLayerTreeToImage(std::move(layer_tree_), width, - height, raw_image_callback); + return Picture::RasterizeLayerTreeToImage( + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, + height, raw_image_callback); } static sk_sp CreateDeferredImage( bool impeller, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, fml::TaskRunnerAffineWeakPtr snapshot_delegate, @@ -126,15 +128,24 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( - dart_state->IsImpellerEnabled(), layer_tree_, width, height, - std::move(snapshot_delegate), std::move(raster_task_runner), + dart_state->IsImpellerEnabled(), + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, + height, std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } -std::shared_ptr Scene::takeLayerTree() { - return std::move(layer_tree_); +std::unique_ptr Scene::takeLayerTree() { + return BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); +} + +std::unique_ptr Scene::BuildLayerTree(uint32_t width, + uint32_t height, + float pixel_ratio) { + FML_CHECK(layer_tree_config_ != nullptr); + return std::make_unique(*layer_tree_config_, + SkISize::Make(width, height), pixel_ratio); } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index aca797836fcb1..e8b8c0cf0d2ff 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -26,7 +26,7 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); - std::shared_ptr takeLayerTree(); + std::unique_ptr takeLayerTree(); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -48,12 +48,15 @@ class Scene : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_handle); - // This is a shared_ptr to support flattening the layer tree from the UI - // thread onto the raster thread - allowing access to the texture registry - // required to render TextureLayers. - // - // No longer valid after calling `takeLayerTree`. - std::shared_ptr layer_tree_; + std::unique_ptr BuildLayerTree(uint32_t width, + uint32_t height, + float pixel_ratio); + + // No longer valid after calling `takeLayerTreeConfig`. + std::unique_ptr layer_tree_config_; + float device_pixel_ratio_; + uint32_t device_width_; + uint32_t device_height_; }; } // namespace flutter diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc index 40d09b8ff00c6..ffe33c079ebaa 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc @@ -3,14 +3,15 @@ // found in the LICENSE file. #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h" -#include "display_list_deferred_image_gpu_impeller.h" #include +#include "flutter/fml/make_copyable.h" + namespace flutter { sk_sp DlDeferredImageGPUImpeller::Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { @@ -106,7 +107,7 @@ DlDeferredImageGPUImpeller::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUImpeller::ImageWrapper::Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { @@ -152,10 +153,11 @@ bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const { } void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList( - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { fml::TaskRunner::RunNowOrPostTask( raster_task_runner_, - [weak_this = weak_from_this(), layer_tree = std::move(layer_tree)] { + fml::MakeCopyable([weak_this = weak_from_this(), + layer_tree = std::move(layer_tree)]() { TRACE_EVENT0("flutter", "SnapshotDisplayList (impeller)"); auto wrapper = weak_this.lock(); if (!wrapper) { @@ -183,7 +185,7 @@ void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList( return; } wrapper->texture_ = snapshot->impeller_texture(); - }); + })); } std::optional diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h index 664818da8a0fc..bad93600cd395 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h @@ -18,7 +18,7 @@ namespace flutter { class DlDeferredImageGPUImpeller final : public DlImage { public: static sk_sp Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -71,7 +71,7 @@ class DlDeferredImageGPUImpeller final : public DlImage { fml::RefPtr raster_task_runner); static std::shared_ptr Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -107,7 +107,7 @@ class DlDeferredImageGPUImpeller final : public DlImage { // thread task spwaned by this method. After being flattened into a display // list, the image wrapper will be updated to hold this display list and the // layer tree can be dropped. - void SnapshotDisplayList(std::shared_ptr layer_tree = nullptr); + void SnapshotDisplayList(std::unique_ptr layer_tree = nullptr); // |ContextListener| void OnGrContextCreated() override; diff --git a/lib/ui/painting/display_list_deferred_image_gpu_skia.cc b/lib/ui/painting/display_list_deferred_image_gpu_skia.cc index a2bb4c0b94cda..0cec39c737a5d 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_skia.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_skia.cc @@ -4,6 +4,7 @@ #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h" +#include "flutter/fml/make_copyable.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" @@ -25,7 +26,7 @@ sk_sp DlDeferredImageGPUSkia::Make( sk_sp DlDeferredImageGPUSkia::MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, const fml::RefPtr& raster_task_runner, fml::RefPtr unref_queue) { @@ -114,7 +115,7 @@ DlDeferredImageGPUSkia::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUSkia::ImageWrapper::MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { @@ -164,10 +165,11 @@ bool DlDeferredImageGPUSkia::ImageWrapper::isTextureBacked() const { } void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList( - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { fml::TaskRunner::RunNowOrPostTask( raster_task_runner_, - [weak_this = weak_from_this(), layer_tree = std::move(layer_tree)]() { + fml::MakeCopyable([weak_this = weak_from_this(), + layer_tree = std::move(layer_tree)]() mutable { auto wrapper = weak_this.lock(); if (!wrapper) { return; @@ -199,7 +201,7 @@ void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList( std::scoped_lock lock(wrapper->error_mutex_); wrapper->error_ = result->error; } - }); + })); } std::optional DlDeferredImageGPUSkia::ImageWrapper::get_error() { diff --git a/lib/ui/painting/display_list_deferred_image_gpu_skia.h b/lib/ui/painting/display_list_deferred_image_gpu_skia.h index 2d6c9b53c5cf9..4e3558fbe9348 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_skia.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_skia.h @@ -30,7 +30,7 @@ class DlDeferredImageGPUSkia final : public DlImage { static sk_sp MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, const fml::RefPtr& raster_task_runner, fml::RefPtr unref_queue); @@ -85,7 +85,7 @@ class DlDeferredImageGPUSkia final : public DlImage { static std::shared_ptr MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -125,7 +125,7 @@ class DlDeferredImageGPUSkia final : public DlImage { // thread task spwaned by this method. After being flattened into a display // list, the image wrapper will be updated to hold this display list and the // layer tree can be dropped. - void SnapshotDisplayList(std::shared_ptr layer_tree = nullptr); + void SnapshotDisplayList(std::unique_ptr layer_tree = nullptr); // |ContextListener| void OnGrContextCreated() override; diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 53a9371277555..47318f7bb74f8 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -118,24 +118,24 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - return RasterizeToImage(display_list, nullptr, width, height, - raw_image_callback); + return DoRasterizeToImage(display_list, nullptr, width, height, + raw_image_callback); } Dart_Handle Picture::RasterizeLayerTreeToImage( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - return RasterizeToImage(nullptr, std::move(layer_tree), width, height, - raw_image_callback); + return DoRasterizeToImage(nullptr, std::move(layer_tree), width, height, + raw_image_callback); } -Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, - std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback) { +Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback) { if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) { return tonic::ToDart("Image callback was invalid"); } @@ -198,8 +198,9 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - [ui_task_runner, snapshot_delegate, display_list, picture_bounds, ui_task, - layer_tree = std::move(layer_tree)] { + fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, + picture_bounds, ui_task, + layer_tree = std::move(layer_tree)]() mutable { sk_sp image; if (layer_tree) { auto display_list = layer_tree->Flatten( @@ -216,7 +217,7 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, fml::TaskRunner::RunNowOrPostTask( ui_task_runner, [ui_task, image]() { ui_task(image); }); - }); + })); return Dart_Null(); } diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index d0c2a0123fa1d..df8c17e6113f1 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -49,7 +49,7 @@ class Picture : public RefCountedDartWrappable { Dart_Handle raw_image_callback); static Dart_Handle RasterizeLayerTreeToImage( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback); @@ -57,11 +57,11 @@ class Picture : public RefCountedDartWrappable { // Callers may provide either a display list or a layer tree. If a layer tree // is provided, it will be flattened on the raster thread. In this case the // display list will be ignored. - static Dart_Handle RasterizeToImage(const sk_sp& display_list, - std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback); + static Dart_Handle DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); private: explicit Picture(sk_sp display_list); diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 0fbb43391e113..6724085515abd 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -27,7 +27,7 @@ class RuntimeDelegate { virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; - virtual void Render(std::shared_ptr layer_tree) = 0; + virtual void Render(std::unique_ptr layer_tree) = 0; virtual void UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) = 0; diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 0b969c2ccbc0b..83498bc1535ba 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -128,7 +128,7 @@ void Animator::BeginFrame( } } -void Animator::Render(std::shared_ptr layer_tree) { +void Animator::Render(std::unique_ptr layer_tree) { has_rendered_ = true; last_layer_tree_size_ = layer_tree->frame_size(); diff --git a/shell/common/animator.h b/shell/common/animator.h index dfacb4a786bf3..c96a0f5536abb 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -54,7 +54,7 @@ class Animator final { void RequestFrame(bool regenerate_layer_tree = true); - void Render(std::shared_ptr layer_tree); + void Render(std::unique_ptr layer_tree); const std::weak_ptr GetVsyncWaiter() const; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 05c728c57ae16..b37de4fa0ccd5 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -155,8 +155,8 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { task_runners.GetUITaskRunner()->PostDelayedTask( [&] { ASSERT_FALSE(delegate.notify_idle_called_); - auto layer_tree = - std::make_shared(SkISize::Make(600, 800), 1.0); + auto layer_tree = std::make_unique( + LayerTree::Config(), SkISize::Make(600, 800), 1.0); animator->Render(std::move(layer_tree)); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, @@ -238,8 +238,8 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { begin_frame_latch.Wait(); PostTaskSync(task_runners.GetUITaskRunner(), [&] { - auto layer_tree = - std::make_shared(SkISize::Make(600, 800), 1.0); + auto layer_tree = std::make_unique( + LayerTree::Config(), SkISize::Make(600, 800), 1.0); animator->Render(std::move(layer_tree)); }); } diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 522ee89a52a7b..3e3613cef02e5 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -450,7 +450,7 @@ void Engine::ScheduleFrame(bool regenerate_layer_tree) { animator_->RequestFrame(regenerate_layer_tree); } -void Engine::Render(std::shared_ptr layer_tree) { +void Engine::Render(std::unique_ptr layer_tree) { if (!layer_tree) { return; } diff --git a/shell/common/engine.h b/shell/common/engine.h index c6ff37eae37a5..2b43b11932286 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -895,7 +895,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::string DefaultRouteName() override; // |RuntimeDelegate| - void Render(std::shared_ptr layer_tree) override; + void Render(std::unique_ptr layer_tree) override; // |RuntimeDelegate| void UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 3bfdd000c37eb..c2b2dccb9948b 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -51,7 +51,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { MOCK_METHOD0(ImplicitViewEnabled, bool()); MOCK_METHOD0(DefaultRouteName, std::string()); MOCK_METHOD1(ScheduleFrame, void(bool)); - MOCK_METHOD1(Render, void(std::shared_ptr)); + MOCK_METHOD1(Render, void(std::unique_ptr)); MOCK_METHOD2(UpdateSemantics, void(SemanticsNodeUpdates, CustomAccessibilityActionUpdates)); MOCK_METHOD1(HandlePlatformMessage, void(std::unique_ptr)); diff --git a/shell/common/pipeline.h b/shell/common/pipeline.h index 1de4498e7f08c..df0acc6479a33 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -252,11 +252,11 @@ class Pipeline { }; struct LayerTreeItem { - LayerTreeItem(std::shared_ptr layer_tree, + LayerTreeItem(std::unique_ptr layer_tree, std::unique_ptr frame_timings_recorder) : layer_tree(std::move(layer_tree)), frame_timings_recorder(std::move(frame_timings_recorder)) {} - std::shared_ptr layer_tree; + std::unique_ptr layer_tree; std::unique_ptr frame_timings_recorder; }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 3b01c5c9bb0a9..3326a7dc6e547 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -195,7 +195,7 @@ RasterStatus Rasterizer::Draw( RasterStatus raster_status = RasterStatus::kFailed; LayerTreePipeline::Consumer consumer = [&](std::unique_ptr item) { - std::shared_ptr layer_tree = std::move(item->layer_tree); + std::unique_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); if (discard_callback(*layer_tree.get())) { @@ -375,7 +375,7 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { RasterStatus Rasterizer::DoDraw( std::unique_ptr frame_timings_recorder, - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", "Rasterizer::DoDraw"); FML_DCHECK(delegate_.GetTaskRunners() diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 23227f5d67618..fbb9386b19c3a 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -556,7 +556,7 @@ class Rasterizer final : public SnapshotDelegate, RasterStatus DoDraw( std::unique_ptr frame_timings_recorder, - std::shared_ptr layer_tree); + std::unique_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree& layer_tree); @@ -576,11 +576,11 @@ class Rasterizer final : public SnapshotDelegate, std::unique_ptr snapshot_surface_producer_; std::unique_ptr compositor_context_; // This is the last successfully rasterized layer tree. - std::shared_ptr last_layer_tree_; + std::unique_ptr last_layer_tree_; // Set when we need attempt to rasterize the layer tree again. This layer_tree // has not successfully rasterized. This can happen due to the change in the // thread configuration. This will be inserted to the front of the pipeline. - std::shared_ptr resubmitted_layer_tree_; + std::unique_ptr resubmitted_layer_tree_; std::unique_ptr resubmitted_recorder_; fml::closure next_frame_callback_; bool user_override_resource_cache_bytes_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 6ab77b53401ba..c9d9edc6bb707 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -185,8 +185,10 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = + std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -250,8 +252,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -321,7 +324,8 @@ TEST( rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), + auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -395,7 +399,8 @@ TEST(RasterizerTest, rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), + auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -444,8 +449,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -499,8 +505,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -601,8 +608,9 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -658,8 +666,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -715,8 +724,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -771,8 +781,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -826,8 +837,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -904,9 +916,9 @@ TEST(RasterizerTest, rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { - auto layer_tree = - std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = @@ -1075,9 +1087,9 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { - auto layer_tree = - std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = @@ -1155,8 +1167,9 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp)); PipelineProduceResult result = diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index a799e6bcb4811..215919ef82ae7 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -197,14 +197,14 @@ void ShellTest::PumpOneFrame(Shell* shell, fml::WeakPtr runtime_delegate = shell->weak_engine_; shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, runtime_delegate, &builder, viewport_metrics]() { - auto layer_tree = std::make_shared( - SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); SkMatrix identity; identity.setIdentity(); auto root_layer = std::make_shared(identity); - layer_tree->set_root_layer(root_layer); + auto layer_tree = std::make_unique( + LayerTree::Config{.root_layer = root_layer}, + SkISize::Make(viewport_metrics.physical_width, + viewport_metrics.physical_height), + static_cast(viewport_metrics.device_pixel_ratio)); if (builder) { builder(root_layer); } From 474b357f8c45b9611e31969ddcc4f6f49d2c78e6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:23:27 -0700 Subject: [PATCH 02/15] Let takeLayerTree remove config for now --- lib/ui/compositing/scene.cc | 11 +++++++++-- lib/ui/compositing/scene.h | 1 - 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index f85397ac881b5..77f4dc4a0f1b1 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -137,13 +137,20 @@ void Scene::RasterizeToImage(uint32_t width, } std::unique_ptr Scene::takeLayerTree() { - return BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + if (layer_tree_config_ != nullptr) { + auto layer_tree = BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test it. + // Let's keep it this way for now. + layer_tree_config_.reset(); + return layer_tree; + } else { + return nullptr; + } } std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { - FML_CHECK(layer_tree_config_ != nullptr); return std::make_unique(*layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e8b8c0cf0d2ff..4f8c240d6c447 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -52,7 +52,6 @@ class Scene : public RefCountedDartWrappable { uint32_t height, float pixel_ratio); - // No longer valid after calling `takeLayerTreeConfig`. std::unique_ptr layer_tree_config_; float device_pixel_ratio_; uint32_t device_width_; From 39a3a0927ea9a38692c99f9e30d3e1cec948d1f3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:23:55 -0700 Subject: [PATCH 03/15] Format --- lib/ui/compositing/scene.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 77f4dc4a0f1b1..084b4ea5f03f5 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -138,9 +138,10 @@ void Scene::RasterizeToImage(uint32_t width, std::unique_ptr Scene::takeLayerTree() { if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); - // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test it. - // Let's keep it this way for now. + auto layer_tree = + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test + // it. Let's keep it this way for now. layer_tree_config_.reset(); return layer_tree; } else { From ba4b01adf913dfa32273038e1e1863261b5807e2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:46:55 -0700 Subject: [PATCH 04/15] lint --- flow/layers/layer_tree_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index 47673b8eb764b..6d45d39bdefbb 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -33,7 +33,7 @@ class LayerTreeTest : public CanvasTest { CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); } const SkMatrix& root_transform() { return root_transform_; } - std::unique_ptr BuildLayerTree(LayerTree::Config config) { + std::unique_ptr BuildLayerTree(const LayerTree::Config& config) { return std::make_unique(config, SkISize::Make(64, 64), 1.0f); } From c8bd69b1be2a9f25866cc377fccaf2498f681e14 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 17:15:58 -0700 Subject: [PATCH 05/15] Compute layer tree size in RuntimeConfiguration --- lib/ui/compositing/scene.cc | 16 +++++++--------- lib/ui/compositing/scene.h | 5 ++--- lib/ui/compositing/scene_builder_unittests.cc | 2 +- runtime/runtime_controller.cc | 11 ++++++++++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 084b4ea5f03f5..b7e71fe66ebc2 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -45,8 +45,6 @@ Scene::Scene(std::shared_ptr rootLayer, ->platform_configuration() ->get_window(0) ->viewport_metrics(); - device_width_ = viewport_metrics.physical_width; - device_height_ = viewport_metrics.physical_height; device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); layer_tree_config_ = std::make_unique(); @@ -88,8 +86,8 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, - height, raw_image_callback); + BuildLayerTree(width, height, device_pixel_ratio_), width, height, + raw_image_callback); } static sk_sp CreateDeferredImage( @@ -129,17 +127,17 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, - height, std::move(snapshot_delegate), std::move(raster_task_runner), + BuildLayerTree(width, height, device_pixel_ratio_), width, height, + std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } -std::unique_ptr Scene::takeLayerTree() { +std::unique_ptr Scene::takeLayerTree(uint64_t width, + uint64_t height) { if (layer_tree_config_ != nullptr) { - auto layer_tree = - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + auto layer_tree = BuildLayerTree(width, height, device_pixel_ratio_); // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test // it. Let's keep it this way for now. layer_tree_config_.reset(); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 4f8c240d6c447..5c9bf791135f8 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -26,7 +26,8 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); - std::unique_ptr takeLayerTree(); + std::unique_ptr takeLayerTree(uint64_t width, + uint64_t height); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -54,8 +55,6 @@ class Scene : public RefCountedDartWrappable { std::unique_ptr layer_tree_config_; float device_pixel_ratio_; - uint32_t device_width_; - uint32_t device_height_; }; } // namespace flutter diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 41efcdc64efd5..702d83bf61417 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -59,7 +59,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { auto validate_scene_has_no_layers = [message_latch, &retained_scene](Dart_NativeArguments args) { - EXPECT_FALSE(retained_scene->takeLayerTree()); + EXPECT_FALSE(retained_scene->takeLayerTree(100, 100)); retained_scene->Release(); retained_scene = nullptr; message_latch->Signal(); diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 97664325fe4a0..50417a52ce797 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -316,7 +316,16 @@ void RuntimeController::ScheduleFrame() { // |PlatformConfigurationClient| void RuntimeController::Render(Scene* scene) { - client_.Render(scene->takeLayerTree()); + // TODO(dkwingsmt): Currently only supports a single window. + int64_t view_id = 0ll; + auto window = + UIDartState::Current()->platform_configuration()->get_window(view_id); + if (window == nullptr) { + return; + } + const auto& viewport_metrics = window->viewport_metrics(); + client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, + viewport_metrics.physical_height)); } // |PlatformConfigurationClient| From 6a03556ddfa86305381f3b5b70ad061a4a63ea77 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 17:58:11 -0700 Subject: [PATCH 06/15] Resolve toImageSync --- lib/ui/compositing/scene.cc | 16 ++++++++-------- .../display_list_deferred_image_gpu_impeller.cc | 10 ++++------ .../display_list_deferred_image_gpu_impeller.h | 2 -- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index b7e71fe66ebc2..7d7bc4dd5acba 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -93,21 +93,21 @@ Dart_Handle Scene::toImage(uint32_t width, static sk_sp CreateDeferredImage( bool impeller, std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { #if IMPELLER_SUPPORTS_RENDERING if (impeller) { - return DlDeferredImageGPUImpeller::Make( - std::move(layer_tree), SkISize::Make(width, height), - std::move(snapshot_delegate), std::move(raster_task_runner)); + return DlDeferredImageGPUImpeller::Make(std::move(layer_tree), + std::move(snapshot_delegate), + std::move(raster_task_runner)); } #endif // IMPELLER_SUPPORTS_RENDERING - const SkImageInfo image_info = SkImageInfo::Make( - width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + const auto& frame_size = layer_tree->frame_size(); + const SkImageInfo image_info = + SkImageInfo::Make(frame_size.width(), frame_size.height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); return DlDeferredImageGPUSkia::MakeFromLayerTree( image_info, std::move(layer_tree), std::move(snapshot_delegate), raster_task_runner, std::move(unref_queue)); @@ -127,7 +127,7 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(width, height, device_pixel_ratio_), width, height, + BuildLayerTree(width, height, device_pixel_ratio_), std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc index ffe33c079ebaa..0c2a7de57cca4 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc @@ -12,12 +12,11 @@ namespace flutter { sk_sp DlDeferredImageGPUImpeller::Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { return sk_sp(new DlDeferredImageGPUImpeller( DlDeferredImageGPUImpeller::ImageWrapper::Make( - std::move(layer_tree), size, std::move(snapshot_delegate), + std::move(layer_tree), std::move(snapshot_delegate), std::move(raster_task_runner)))); } @@ -108,12 +107,11 @@ DlDeferredImageGPUImpeller::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUImpeller::ImageWrapper::Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { - auto wrapper = std::shared_ptr( - new ImageWrapper(nullptr, size, std::move(snapshot_delegate), - std::move(raster_task_runner))); + auto wrapper = std::shared_ptr(new ImageWrapper( + nullptr, layer_tree->frame_size(), std::move(snapshot_delegate), + std::move(raster_task_runner))); wrapper->SnapshotDisplayList(std::move(layer_tree)); return wrapper; } diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h index bad93600cd395..7bcb27922423e 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h @@ -19,7 +19,6 @@ class DlDeferredImageGPUImpeller final : public DlImage { public: static sk_sp Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -72,7 +71,6 @@ class DlDeferredImageGPUImpeller final : public DlImage { static std::shared_ptr Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); From 30b95c67683d07d3f53bcf4489a7dd0fab2b244f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 18:55:51 -0700 Subject: [PATCH 07/15] Convert toImage --- lib/ui/compositing/scene.cc | 3 +-- lib/ui/painting/picture.cc | 7 +++---- lib/ui/painting/picture.h | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 7d7bc4dd5acba..3dfffc0e6d0dc 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -86,8 +86,7 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, device_pixel_ratio_), width, height, - raw_image_callback); + BuildLayerTree(width, height, device_pixel_ratio_), raw_image_callback); } static sk_sp CreateDeferredImage( diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 47318f7bb74f8..c8cf17c9c511e 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -124,11 +124,10 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, Dart_Handle Picture::RasterizeLayerTreeToImage( std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, Dart_Handle raw_image_callback) { - return DoRasterizeToImage(nullptr, std::move(layer_tree), width, height, - raw_image_callback); + auto frame_size = layer_tree->frame_size(); + return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(), + frame_size.height(), raw_image_callback); } Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index df8c17e6113f1..14934eecded6a 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -50,8 +50,6 @@ class Picture : public RefCountedDartWrappable { static Dart_Handle RasterizeLayerTreeToImage( std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, Dart_Handle raw_image_callback); // Callers may provide either a display list or a layer tree. If a layer tree From ae2c065b2266be09b43937ae55689a51c1dc827a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 20:51:14 -0700 Subject: [PATCH 08/15] Right before dart_ui.cc --- lib/ui/compositing/scene.cc | 27 +++++++++---------- lib/ui/compositing/scene.h | 6 +++-- lib/ui/compositing/scene_builder_unittests.cc | 2 +- lib/ui/painting/picture.cc | 7 ++++- lib/ui/painting/picture.h | 7 ++--- runtime/runtime_controller.cc | 3 ++- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 3dfffc0e6d0dc..6424e1b1eb237 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,13 +40,6 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - // Currently only supports a single window. - auto viewport_metrics = UIDartState::Current() - ->platform_configuration() - ->get_window(0) - ->viewport_metrics(); - device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); - layer_tree_config_ = std::make_unique(); layer_tree_config_->root_layer = std::move(rootLayer); layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; @@ -67,12 +60,14 @@ Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); + double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); } - Scene::RasterizeToImage(width, height, raw_image_handle); + Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), + raw_image_handle); return Dart_Null(); } @@ -80,13 +75,15 @@ Dart_Handle Scene::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); + double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, device_pixel_ratio_), raw_image_callback); + BuildLayerTree(width, height, static_cast(pixel_ratio)), + raw_image_callback); } static sk_sp CreateDeferredImage( @@ -114,6 +111,7 @@ static sk_sp CreateDeferredImage( void Scene::RasterizeToImage(uint32_t width, uint32_t height, + float pixel_ratio, Dart_Handle raw_image_handle) { auto* dart_state = UIDartState::Current(); if (!dart_state) { @@ -126,17 +124,17 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(width, height, device_pixel_ratio_), - std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue)); + BuildLayerTree(width, height, pixel_ratio), std::move(snapshot_delegate), + std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } std::unique_ptr Scene::takeLayerTree(uint64_t width, - uint64_t height) { + uint64_t height, + float pixel_ratio) { if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(width, height, device_pixel_ratio_); + auto layer_tree = BuildLayerTree(width, height, pixel_ratio); // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test // it. Let's keep it this way for now. layer_tree_config_.reset(); @@ -149,6 +147,7 @@ std::unique_ptr Scene::takeLayerTree(uint64_t width, std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { + FML_CHECK(layer_tree_config_ != nullptr); return std::make_unique(*layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 5c9bf791135f8..14fecc9a5ec2d 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -27,7 +27,8 @@ class Scene : public RefCountedDartWrappable { bool checkerboardOffscreenLayers); std::unique_ptr takeLayerTree(uint64_t width, - uint64_t height); + uint64_t height, + float pixel_ratio); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -47,14 +48,15 @@ class Scene : public RefCountedDartWrappable { void RasterizeToImage(uint32_t width, uint32_t height, + float pixel_ratio, Dart_Handle raw_image_handle); std::unique_ptr BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio); + // No longer valid after calling `takeLayerTreeConfig`. std::unique_ptr layer_tree_config_; - float device_pixel_ratio_; }; } // namespace flutter diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 702d83bf61417..93060ea6025c8 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -59,7 +59,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { auto validate_scene_has_no_layers = [message_latch, &retained_scene](Dart_NativeArguments args) { - EXPECT_FALSE(retained_scene->takeLayerTree(100, 100)); + EXPECT_FALSE(retained_scene->takeLayerTree(100, 100, 1.0f)); retained_scene->Release(); retained_scene = nullptr; message_latch->Signal(); diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index c8cf17c9c511e..21104e2e41328 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -125,6 +125,7 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, Dart_Handle Picture::RasterizeLayerTreeToImage( std::unique_ptr layer_tree, Dart_Handle raw_image_callback) { + FML_DCHECK(layer_tree != nullptr); auto frame_size = layer_tree->frame_size(); return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(), frame_size.height(), raw_image_callback); @@ -135,6 +136,9 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { + // Either display_list or layer_tree should be provided. + FML_DCHECK((display_list == nullptr) != (layer_tree == nullptr)); + if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) { return tonic::ToDart("Image callback was invalid"); } @@ -198,10 +202,11 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, fml::TaskRunner::RunNowOrPostTask( raster_task_runner, fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, - picture_bounds, ui_task, + &picture_bounds, ui_task, layer_tree = std::move(layer_tree)]() mutable { sk_sp image; if (layer_tree) { + FML_DCHECK(picture_bounds == layer_tree->frame_size()); auto display_list = layer_tree->Flatten( SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), snapshot_delegate->GetTextureRegistry(), diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 14934eecded6a..89c84095336ed 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -52,9 +52,10 @@ class Picture : public RefCountedDartWrappable { std::unique_ptr layer_tree, Dart_Handle raw_image_callback); - // Callers may provide either a display list or a layer tree. If a layer tree - // is provided, it will be flattened on the raster thread. In this case the - // display list will be ignored. + // Callers may provide either a display list or a layer tree, but not both. + // + // If a layer tree is provided, it will be flattened on the raster thread, and + // picture_bounds should be the layer tree's frame_size(). static Dart_Handle DoRasterizeToImage(const sk_sp& display_list, std::unique_ptr layer_tree, uint32_t width, diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 50417a52ce797..b53832ecb4bb5 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -325,7 +325,8 @@ void RuntimeController::Render(Scene* scene) { } const auto& viewport_metrics = window->viewport_metrics(); client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, - viewport_metrics.physical_height)); + viewport_metrics.physical_height, + viewport_metrics.device_pixel_ratio)); } // |PlatformConfigurationClient| From d7fa9d67f6408dc075d8c950b86348b755fdf33d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 00:58:10 -0700 Subject: [PATCH 09/15] Fix crash --- lib/ui/painting/picture.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 21104e2e41328..74c7b0dc78141 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -160,8 +160,6 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, // thread owns the sole reference to the layer tree. So we do it in the // raster thread. - auto picture_bounds = SkISize::Make(width, height); - auto ui_task = // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) @@ -201,16 +199,17 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, - &picture_bounds, ui_task, + fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, width, + height, ui_task, layer_tree = std::move(layer_tree)]() mutable { + auto picture_bounds = SkISize::Make(width, height); sk_sp image; if (layer_tree) { FML_DCHECK(picture_bounds == layer_tree->frame_size()); - auto display_list = layer_tree->Flatten( - SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), - snapshot_delegate->GetTextureRegistry(), - snapshot_delegate->GetGrContext()); + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(width, height), + snapshot_delegate->GetTextureRegistry(), + snapshot_delegate->GetGrContext()); image = snapshot_delegate->MakeRasterSnapshot(display_list, picture_bounds); From 2ccc86975d839c9ccb7fb6411c035c3aa25a90a0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 04:10:16 -0700 Subject: [PATCH 10/15] To dart:ui --- lib/ui/compositing.dart | 32 ++++++++++++++++++++++++-------- lib/ui/compositing/scene.cc | 4 ++-- lib/ui/compositing/scene.h | 2 ++ lib/ui/dart_ui.cc | 4 ++-- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index f20ecff7349c6..e2e0cb11159f1 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -21,21 +21,27 @@ class Scene extends NativeFieldWrapperClass1 { /// Synchronously creates a handle to an image from this scene. /// /// {@macro dart.ui.painting.Picture.toImageSync} - Image toImageSync(int width, int height) { + /// + /// The value of `pixelRatio` does not affect the dimension of the resulting + /// image. Instead, it is used to calculate the device's physical dimension + /// (for example, the device's physical width will be `width` / `pixelRatio`), + /// which is used by some deprecated shapes (see + /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. + Image toImageSync(int width, int height, [double pixelRatio = 1.0]) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } final _Image image = _Image._(); - final String? result = _toImageSync(width, height, image); + final String? result = _toImageSync(width, height, pixelRatio, image); if (result != null) { throw PictureRasterizationException._(result); } return Image._(image, image.width, image.height); } - @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImageSync') - external String? _toImageSync(int width, int height, _Image outImage); + @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImageSync') + external String? _toImageSync(int width, int height, double pixelRatio, _Image outImage); /// Creates a raster image representation of the current state of the scene. /// @@ -44,11 +50,21 @@ class Scene extends NativeFieldWrapperClass1 { /// Callers must dispose the [Image] when they are done with it. If the result /// will be shared with other methods or classes, [Image.clone] should be used /// and each handle created must be disposed. - Future toImage(int width, int height) { + /// + /// The returned image will be `width` pixels wide and `height` pixels high. + /// The picture is rasterized within the 0 (left), 0 (top), `width` (right), + /// `height` (bottom) bounds. Content outside these bounds is clipped. + /// + /// The value of `pixelRatio` does not affect the dimension of the resulting + /// image. Instead, it is used to calculate the device's physical dimension + /// (for example, the device's physical width will be `width` / `pixelRatio`), + /// which is used by some deprecated shapes (see + /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. + Future toImage(int width, int height, [double pixelRatio = 1.0]) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { + return _futurize((_Callback callback) => _toImage(width, height, pixelRatio, (_Image? image) { if (image == null) { callback(null); } else { @@ -58,8 +74,8 @@ class Scene extends NativeFieldWrapperClass1 { ); } - @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImage') - external String? _toImage(int width, int height, _Callback<_Image?> callback); + @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImage') + external String? _toImage(int width, int height, double pixelRatio, _Callback<_Image?> callback); /// Releases the resources used by this scene. /// diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 6424e1b1eb237..f28c00adafedf 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -58,9 +58,9 @@ void Scene::dispose() { Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); @@ -73,9 +73,9 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle Scene::toImage(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 14fecc9a5ec2d..e2494011e7d76 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -32,10 +32,12 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImageSync(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle); Dart_Handle toImage(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle); void dispose(); diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 57242c11ac9aa..7c6768497c666 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -293,8 +293,8 @@ typedef CanvasPath Path; V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ V(SceneBuilder, setRasterizerTracingThreshold, 2) \ V(Scene, dispose, 1) \ - V(Scene, toImage, 4) \ - V(Scene, toImageSync, 4) \ + V(Scene, toImage, 5) \ + V(Scene, toImageSync, 5) \ V(SemanticsUpdateBuilder, build, 2) \ V(SemanticsUpdateBuilder, updateCustomAction, 5) \ V(SemanticsUpdateBuilder, updateNode, 36) \ From 99bfd249a01f9ea8f786d125786529475a2bad51 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 12:21:24 -0700 Subject: [PATCH 11/15] config is no longer a ptr --- lib/ui/compositing/scene.cc | 39 +++++++++++++++++-------------------- lib/ui/compositing/scene.h | 6 ++++-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index f28c00adafedf..ca56375627139 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,19 +40,22 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - layer_tree_config_ = std::make_unique(); - layer_tree_config_->root_layer = std::move(rootLayer); - layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; - layer_tree_config_->checkerboard_raster_cache_images = + layer_tree_config_.root_layer = std::move(rootLayer); + layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; + layer_tree_config_.checkerboard_raster_cache_images = checkerboardRasterCacheImages; - layer_tree_config_->checkerboard_offscreen_layers = + layer_tree_config_.checkerboard_offscreen_layers = checkerboardOffscreenLayers; } Scene::~Scene() {} +bool Scene::valid() { + return layer_tree_config_.root_layer != nullptr; +} + void Scene::dispose() { - layer_tree_config_.reset(); + layer_tree_config_.root_layer.reset(); ClearDartWrapper(); } @@ -62,8 +65,8 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - if (!layer_tree_config_) { - return tonic::ToDart("Scene's layer tree has been taken away."); + if (!valid()) { + return tonic::ToDart("Scene has been disposed."); } Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), @@ -77,8 +80,8 @@ Dart_Handle Scene::toImage(uint32_t width, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - if (!layer_tree_config_) { - return tonic::ToDart("Scene's layer tree has been taken away."); + if (!valid()) { + return tonic::ToDart("Scene has been disposed."); } return Picture::RasterizeLayerTreeToImage( @@ -133,22 +136,16 @@ void Scene::RasterizeToImage(uint32_t width, std::unique_ptr Scene::takeLayerTree(uint64_t width, uint64_t height, float pixel_ratio) { - if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(width, height, pixel_ratio); - // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test - // it. Let's keep it this way for now. - layer_tree_config_.reset(); - return layer_tree; - } else { - return nullptr; - } + return BuildLayerTree(width, height, pixel_ratio); } std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { - FML_CHECK(layer_tree_config_ != nullptr); - return std::make_unique(*layer_tree_config_, + if (!valid()) { + return nullptr; + } + return std::make_unique(layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e2494011e7d76..c8b9883de7e40 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -48,6 +48,9 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); + // Returns true if `dispose()` has not been called. + bool valid(); + void RasterizeToImage(uint32_t width, uint32_t height, float pixel_ratio, @@ -57,8 +60,7 @@ class Scene : public RefCountedDartWrappable { uint32_t height, float pixel_ratio); - // No longer valid after calling `takeLayerTreeConfig`. - std::unique_ptr layer_tree_config_; + flutter::LayerTree::Config layer_tree_config_; }; } // namespace flutter From 768aa5ef8f4c595dab8cd540564025262dd36397 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 12:56:16 -0700 Subject: [PATCH 12/15] Implicit ratio --- lib/ui/compositing.dart | 32 ++++++++------------------------ lib/ui/compositing/scene.cc | 28 ++++++++++++++++++++++++---- lib/ui/compositing/scene.h | 15 +++++++++++++-- lib/ui/dart_ui.cc | 4 ++-- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index e2e0cb11159f1..f20ecff7349c6 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -21,27 +21,21 @@ class Scene extends NativeFieldWrapperClass1 { /// Synchronously creates a handle to an image from this scene. /// /// {@macro dart.ui.painting.Picture.toImageSync} - /// - /// The value of `pixelRatio` does not affect the dimension of the resulting - /// image. Instead, it is used to calculate the device's physical dimension - /// (for example, the device's physical width will be `width` / `pixelRatio`), - /// which is used by some deprecated shapes (see - /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. - Image toImageSync(int width, int height, [double pixelRatio = 1.0]) { + Image toImageSync(int width, int height) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } final _Image image = _Image._(); - final String? result = _toImageSync(width, height, pixelRatio, image); + final String? result = _toImageSync(width, height, image); if (result != null) { throw PictureRasterizationException._(result); } return Image._(image, image.width, image.height); } - @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImageSync') - external String? _toImageSync(int width, int height, double pixelRatio, _Image outImage); + @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImageSync') + external String? _toImageSync(int width, int height, _Image outImage); /// Creates a raster image representation of the current state of the scene. /// @@ -50,21 +44,11 @@ class Scene extends NativeFieldWrapperClass1 { /// Callers must dispose the [Image] when they are done with it. If the result /// will be shared with other methods or classes, [Image.clone] should be used /// and each handle created must be disposed. - /// - /// The returned image will be `width` pixels wide and `height` pixels high. - /// The picture is rasterized within the 0 (left), 0 (top), `width` (right), - /// `height` (bottom) bounds. Content outside these bounds is clipped. - /// - /// The value of `pixelRatio` does not affect the dimension of the resulting - /// image. Instead, it is used to calculate the device's physical dimension - /// (for example, the device's physical width will be `width` / `pixelRatio`), - /// which is used by some deprecated shapes (see - /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. - Future toImage(int width, int height, [double pixelRatio = 1.0]) { + Future toImage(int width, int height) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - return _futurize((_Callback callback) => _toImage(width, height, pixelRatio, (_Image? image) { + return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { if (image == null) { callback(null); } else { @@ -74,8 +58,8 @@ class Scene extends NativeFieldWrapperClass1 { ); } - @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImage') - external String? _toImage(int width, int height, double pixelRatio, _Callback<_Image?> callback); + @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImage') + external String? _toImage(int width, int height, _Callback<_Image?> callback); /// Releases the resources used by this scene. /// diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index ca56375627139..cdffbd1211c5f 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,6 +40,7 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { + initializeDefaultViewPixelRatioIfNecessary(); layer_tree_config_.root_layer = std::move(rootLayer); layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; layer_tree_config_.checkerboard_raster_cache_images = @@ -61,7 +62,6 @@ void Scene::dispose() { Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); @@ -69,14 +69,13 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene has been disposed."); } - Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), + Scene::RasterizeToImage(width, height, defaultViewPixelRatio(), raw_image_handle); return Dart_Null(); } Dart_Handle Scene::toImage(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); @@ -85,7 +84,7 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, static_cast(pixel_ratio)), + BuildLayerTree(width, height, defaultViewPixelRatio()), raw_image_callback); } @@ -149,4 +148,25 @@ std::unique_ptr Scene::BuildLayerTree(uint32_t width, SkISize::Make(width, height), pixel_ratio); } +float Scene::default_view_pixel_ratio_ = -1.0f; + +void Scene::initializeDefaultViewPixelRatioIfNecessary() { + if (default_view_pixel_ratio_ > 0) { + return; + } + auto window = UIDartState::Current()->platform_configuration()->get_window(0); + if (window != nullptr) { + default_view_pixel_ratio_ = + static_cast(window->viewport_metrics().device_pixel_ratio); + } +} + +float Scene::defaultViewPixelRatio() { + if (default_view_pixel_ratio_ > 0) { + return default_view_pixel_ratio_; + } + // A default value. + return 2.0f; +} + } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index c8b9883de7e40..5ede01fec0438 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -32,12 +32,10 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImageSync(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle); Dart_Handle toImage(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle); void dispose(); @@ -61,6 +59,19 @@ class Scene : public RefCountedDartWrappable { float pixel_ratio); flutter::LayerTree::Config layer_tree_config_; + + static void initializeDefaultViewPixelRatioIfNecessary(); + static float defaultViewPixelRatio(); + + // The pixel ratio of window #0. + // + // Pixel ratio is used to render physical shapes (`PhysicalShapeLayer`), + // which have been deprecated. This field is used to keep backward + // compatibility, where physical shapes are drawn with the pixel ratio + // of window #0. Once `PhysicalShapeLayer` is removed as well as + // `{Preroll,Paint}Context.frame_device_pixel_ratio`, we should remove + // this field. + static float default_view_pixel_ratio_; }; } // namespace flutter diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 7c6768497c666..57242c11ac9aa 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -293,8 +293,8 @@ typedef CanvasPath Path; V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ V(SceneBuilder, setRasterizerTracingThreshold, 2) \ V(Scene, dispose, 1) \ - V(Scene, toImage, 5) \ - V(Scene, toImageSync, 5) \ + V(Scene, toImage, 4) \ + V(Scene, toImageSync, 4) \ V(SemanticsUpdateBuilder, build, 2) \ V(SemanticsUpdateBuilder, updateCustomAction, 5) \ V(SemanticsUpdateBuilder, updateNode, 36) \ From 332f86aeee4ec7993a954c8a9ae7d6d174f5ea44 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 13:00:11 -0700 Subject: [PATCH 13/15] An easier way --- lib/ui/compositing/scene.cc | 22 +++++----------------- lib/ui/compositing/scene.h | 11 ----------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index cdffbd1211c5f..1e59056be56c2 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -23,6 +23,8 @@ namespace flutter { +static constexpr float kFallbackPixelRatio = 2.0f; + IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); void Scene::create(Dart_Handle scene_handle, @@ -40,7 +42,6 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - initializeDefaultViewPixelRatioIfNecessary(); layer_tree_config_.root_layer = std::move(rootLayer); layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; layer_tree_config_.checkerboard_raster_cache_images = @@ -148,25 +149,12 @@ std::unique_ptr Scene::BuildLayerTree(uint32_t width, SkISize::Make(width, height), pixel_ratio); } -float Scene::default_view_pixel_ratio_ = -1.0f; - -void Scene::initializeDefaultViewPixelRatioIfNecessary() { - if (default_view_pixel_ratio_ > 0) { - return; - } +float Scene::defaultViewPixelRatio() { auto window = UIDartState::Current()->platform_configuration()->get_window(0); if (window != nullptr) { - default_view_pixel_ratio_ = - static_cast(window->viewport_metrics().device_pixel_ratio); - } -} - -float Scene::defaultViewPixelRatio() { - if (default_view_pixel_ratio_ > 0) { - return default_view_pixel_ratio_; + return static_cast(window->viewport_metrics().device_pixel_ratio); } - // A default value. - return 2.0f; + return kFallbackPixelRatio; } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 5ede01fec0438..ac4967b79bd96 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -60,18 +60,7 @@ class Scene : public RefCountedDartWrappable { flutter::LayerTree::Config layer_tree_config_; - static void initializeDefaultViewPixelRatioIfNecessary(); static float defaultViewPixelRatio(); - - // The pixel ratio of window #0. - // - // Pixel ratio is used to render physical shapes (`PhysicalShapeLayer`), - // which have been deprecated. This field is used to keep backward - // compatibility, where physical shapes are drawn with the pixel ratio - // of window #0. Once `PhysicalShapeLayer` is removed as well as - // `{Preroll,Paint}Context.frame_device_pixel_ratio`, we should remove - // this field. - static float default_view_pixel_ratio_; }; } // namespace flutter From c829f37c97e13c38d5f7ba9d2fab81cc59b839a3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 15:29:44 -0700 Subject: [PATCH 14/15] Add TODO and comment --- lib/ui/compositing/scene.h | 15 +++++++++++++++ runtime/runtime_controller.cc | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index ac4967b79bd96..ed529b27a705a 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -60,6 +60,21 @@ class Scene : public RefCountedDartWrappable { flutter::LayerTree::Config layer_tree_config_; + // Fetches the pixel ratio from view 0, or if the window doesn't exist, + // fallback to 2.0f. + // + // The pixel ratio is used in toImage() and toImageSync(), and its only effect + // is to calculate the device's physical dimension, which is used by some + // physical shapes (see PhysicalShapeLayer). + // + // Physical shapes have been deprecated and should be removed soon. This + // method aims to keep the legacy behavior in single-window Flutter, which + // feeds the toImage and toImageSync with the pixel ratio of the only window. + // + // TODO(dkwingsmt): If PhysicalShapeLayer has been removed as well as + // {Preroll,Paint}Context.frame_device_pixel_ratio, remove this method and its + // related logic. + // https://github.com/flutter/flutter/issues/125720 static float defaultViewPixelRatio(); }; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index b53832ecb4bb5..d85bdaa4326ed 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -20,6 +20,8 @@ namespace flutter { +const uint64_t kFlutterDefaultViewId = 0llu; + RuntimeController::RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners) : client_(p_client), vm_(nullptr), context_(task_runners) {} @@ -317,7 +319,7 @@ void RuntimeController::ScheduleFrame() { // |PlatformConfigurationClient| void RuntimeController::Render(Scene* scene) { // TODO(dkwingsmt): Currently only supports a single window. - int64_t view_id = 0ll; + int64_t view_id = kFlutterDefaultViewId; auto window = UIDartState::Current()->platform_configuration()->get_window(view_id); if (window == nullptr) { From 3917b1049ff7e3a0dcda9c1b9c94aa98eefb290f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 4 May 2023 16:47:52 -0700 Subject: [PATCH 15/15] Move device pixel ratio --- flow/layers/layer_tree.cc | 9 +- flow/layers/layer_tree.h | 6 +- flow/layers/layer_tree_unittests.cc | 2 +- lib/ui/compositing/scene.cc | 35 +++----- lib/ui/compositing/scene.h | 25 +----- lib/ui/compositing/scene_builder_unittests.cc | 2 +- runtime/runtime_controller.cc | 4 +- runtime/runtime_delegate.h | 3 +- shell/common/animator.cc | 6 +- shell/common/animator.h | 3 +- shell/common/animator_unittests.cc | 12 +-- shell/common/engine.cc | 8 +- shell/common/engine.h | 3 +- shell/common/engine_unittests.cc | 2 +- shell/common/pipeline.h | 7 +- shell/common/rasterizer.cc | 36 ++++---- shell/common/rasterizer.h | 11 ++- shell/common/rasterizer_unittests.cc | 84 +++++++++---------- shell/common/shell_test.cc | 7 +- 19 files changed, 121 insertions(+), 144 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index c07343c2f6bb1..4fefac4eee79f 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -20,18 +20,13 @@ namespace flutter { -LayerTree::LayerTree(const Config& config, - const SkISize& frame_size, - float device_pixel_ratio) +LayerTree::LayerTree(const Config& config, const SkISize& frame_size) : root_layer_(config.root_layer), frame_size_(frame_size), - device_pixel_ratio_(device_pixel_ratio), rasterizer_tracing_threshold_(config.rasterizer_tracing_threshold), checkerboard_raster_cache_images_( config.checkerboard_raster_cache_images), - checkerboard_offscreen_layers_(config.checkerboard_offscreen_layers) { - FML_CHECK(device_pixel_ratio_ != 0.0f); -} + checkerboard_offscreen_layers_(config.checkerboard_offscreen_layers) {} inline SkColorSpace* GetColorSpace(DlCanvas* canvas) { return canvas ? canvas->GetImageInfo().colorSpace() : nullptr; diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index f01c1c80044ad..4e55953bee05a 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -30,9 +30,7 @@ class LayerTree { bool checkerboard_offscreen_layers = false; }; - LayerTree(const Config& config, - const SkISize& frame_size, - float device_pixel_ratio); + LayerTree(const Config& config, const SkISize& frame_size); // Perform a preroll pass on the tree and return information about // the tree that affects rendering this frame. @@ -60,7 +58,6 @@ class LayerTree { Layer* root_layer() const { return root_layer_.get(); } const SkISize& frame_size() const { return frame_size_; } - float device_pixel_ratio() const { return device_pixel_ratio_; } const PaintRegionMap& paint_region_map() const { return paint_region_map_; } PaintRegionMap& paint_region_map() { return paint_region_map_; } @@ -87,7 +84,6 @@ class LayerTree { private: std::shared_ptr root_layer_; SkISize frame_size_ = SkISize::MakeEmpty(); // Physical pixels. - const float device_pixel_ratio_; // Logical / Physical pixels ratio. uint32_t rasterizer_tracing_threshold_; bool checkerboard_raster_cache_images_; bool checkerboard_offscreen_layers_; diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index be43fc055bc92..9fbcd4cd729ed 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -34,7 +34,7 @@ class LayerTreeTest : public CanvasTest { const SkMatrix& root_transform() { return root_transform_; } std::unique_ptr BuildLayerTree(const LayerTree::Config& config) { - return std::make_unique(config, SkISize::Make(64, 64), 1.0f); + return std::make_unique(config, SkISize::Make(64, 64)); } private: diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 1e59056be56c2..17d00ea794c2a 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -23,8 +23,6 @@ namespace flutter { -static constexpr float kFallbackPixelRatio = 2.0f; - IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); void Scene::create(Dart_Handle scene_handle, @@ -70,8 +68,7 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene has been disposed."); } - Scene::RasterizeToImage(width, height, defaultViewPixelRatio(), - raw_image_handle); + Scene::RasterizeToImage(width, height, raw_image_handle); return Dart_Null(); } @@ -84,9 +81,8 @@ Dart_Handle Scene::toImage(uint32_t width, return tonic::ToDart("Scene has been disposed."); } - return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, defaultViewPixelRatio()), - raw_image_callback); + return Picture::RasterizeLayerTreeToImage(BuildLayerTree(width, height), + raw_image_callback); } static sk_sp CreateDeferredImage( @@ -114,7 +110,6 @@ static sk_sp CreateDeferredImage( void Scene::RasterizeToImage(uint32_t width, uint32_t height, - float pixel_ratio, Dart_Handle raw_image_handle) { auto* dart_state = UIDartState::Current(); if (!dart_state) { @@ -126,35 +121,25 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( - dart_state->IsImpellerEnabled(), - BuildLayerTree(width, height, pixel_ratio), std::move(snapshot_delegate), - std::move(raster_task_runner), std::move(unref_queue)); + dart_state->IsImpellerEnabled(), BuildLayerTree(width, height), + std::move(snapshot_delegate), std::move(raster_task_runner), + std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } std::unique_ptr Scene::takeLayerTree(uint64_t width, - uint64_t height, - float pixel_ratio) { - return BuildLayerTree(width, height, pixel_ratio); + uint64_t height) { + return BuildLayerTree(width, height); } std::unique_ptr Scene::BuildLayerTree(uint32_t width, - uint32_t height, - float pixel_ratio) { + uint32_t height) { if (!valid()) { return nullptr; } return std::make_unique(layer_tree_config_, - SkISize::Make(width, height), pixel_ratio); -} - -float Scene::defaultViewPixelRatio() { - auto window = UIDartState::Current()->platform_configuration()->get_window(0); - if (window != nullptr) { - return static_cast(window->viewport_metrics().device_pixel_ratio); - } - return kFallbackPixelRatio; + SkISize::Make(width, height)); } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index ed529b27a705a..a8a3614f64977 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -27,8 +27,7 @@ class Scene : public RefCountedDartWrappable { bool checkerboardOffscreenLayers); std::unique_ptr takeLayerTree(uint64_t width, - uint64_t height, - float pixel_ratio); + uint64_t height); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -51,31 +50,11 @@ class Scene : public RefCountedDartWrappable { void RasterizeToImage(uint32_t width, uint32_t height, - float pixel_ratio, Dart_Handle raw_image_handle); - std::unique_ptr BuildLayerTree(uint32_t width, - uint32_t height, - float pixel_ratio); + std::unique_ptr BuildLayerTree(uint32_t width, uint32_t height); flutter::LayerTree::Config layer_tree_config_; - - // Fetches the pixel ratio from view 0, or if the window doesn't exist, - // fallback to 2.0f. - // - // The pixel ratio is used in toImage() and toImageSync(), and its only effect - // is to calculate the device's physical dimension, which is used by some - // physical shapes (see PhysicalShapeLayer). - // - // Physical shapes have been deprecated and should be removed soon. This - // method aims to keep the legacy behavior in single-window Flutter, which - // feeds the toImage and toImageSync with the pixel ratio of the only window. - // - // TODO(dkwingsmt): If PhysicalShapeLayer has been removed as well as - // {Preroll,Paint}Context.frame_device_pixel_ratio, remove this method and its - // related logic. - // https://github.com/flutter/flutter/issues/125720 - static float defaultViewPixelRatio(); }; } // namespace flutter diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 93060ea6025c8..702d83bf61417 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -59,7 +59,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { auto validate_scene_has_no_layers = [message_latch, &retained_scene](Dart_NativeArguments args) { - EXPECT_FALSE(retained_scene->takeLayerTree(100, 100, 1.0f)); + EXPECT_FALSE(retained_scene->takeLayerTree(100, 100)); retained_scene->Release(); retained_scene = nullptr; message_latch->Signal(); diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 27b77ab6901d1..e384f96ec3aee 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -327,8 +327,8 @@ void RuntimeController::Render(Scene* scene) { } const auto& viewport_metrics = window->viewport_metrics(); client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, - viewport_metrics.physical_height, - viewport_metrics.device_pixel_ratio)); + viewport_metrics.physical_height), + viewport_metrics.device_pixel_ratio); } // |PlatformConfigurationClient| diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 6724085515abd..18e4dbfdfd31c 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -27,7 +27,8 @@ class RuntimeDelegate { virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; - virtual void Render(std::unique_ptr layer_tree) = 0; + virtual void Render(std::unique_ptr layer_tree, + float device_pixel_ratio) = 0; virtual void UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) = 0; diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 83498bc1535ba..bb4c131cdff68 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -128,7 +128,8 @@ void Animator::BeginFrame( } } -void Animator::Render(std::unique_ptr layer_tree) { +void Animator::Render(std::unique_ptr layer_tree, + float device_pixel_ratio) { has_rendered_ = true; last_layer_tree_size_ = layer_tree->frame_size(); @@ -148,7 +149,8 @@ void Animator::Render(std::unique_ptr layer_tree) { frame_timings_recorder_->GetVsyncTargetTime()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), std::move(frame_timings_recorder_)); + std::move(layer_tree), std::move(frame_timings_recorder_), + device_pixel_ratio); // Commit the pending continuation. PipelineProduceResult result = producer_continuation_.Complete(std::move(layer_tree_item)); diff --git a/shell/common/animator.h b/shell/common/animator.h index c96a0f5536abb..4e6295957bdcc 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -54,7 +54,8 @@ class Animator final { void RequestFrame(bool regenerate_layer_tree = true); - void Render(std::unique_ptr layer_tree); + void Render(std::unique_ptr layer_tree, + float device_pixel_ratio); const std::weak_ptr GetVsyncWaiter() const; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index b37de4fa0ccd5..a3d814e298daa 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -155,9 +155,9 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { task_runners.GetUITaskRunner()->PostDelayedTask( [&] { ASSERT_FALSE(delegate.notify_idle_called_); - auto layer_tree = std::make_unique( - LayerTree::Config(), SkISize::Make(600, 800), 1.0); - animator->Render(std::move(layer_tree)); + auto layer_tree = std::make_unique(LayerTree::Config(), + SkISize::Make(600, 800)); + animator->Render(std::move(layer_tree), 1.0); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, // See kNotifyIdleTaskWaitTime in animator.cc. @@ -238,9 +238,9 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { begin_frame_latch.Wait(); PostTaskSync(task_runners.GetUITaskRunner(), [&] { - auto layer_tree = std::make_unique( - LayerTree::Config(), SkISize::Make(600, 800), 1.0); - animator->Render(std::move(layer_tree)); + auto layer_tree = std::make_unique(LayerTree::Config(), + SkISize::Make(600, 800)); + animator->Render(std::move(layer_tree), 1.0); }); } diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 3e3613cef02e5..e63a19352f095 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -450,18 +450,18 @@ void Engine::ScheduleFrame(bool regenerate_layer_tree) { animator_->RequestFrame(regenerate_layer_tree); } -void Engine::Render(std::unique_ptr layer_tree) { +void Engine::Render(std::unique_ptr layer_tree, + float device_pixel_ratio) { if (!layer_tree) { return; } // Ensure frame dimensions are sane. - if (layer_tree->frame_size().isEmpty() || - layer_tree->device_pixel_ratio() <= 0.0f) { + if (layer_tree->frame_size().isEmpty() || device_pixel_ratio <= 0.0f) { return; } - animator_->Render(std::move(layer_tree)); + animator_->Render(std::move(layer_tree), device_pixel_ratio); } void Engine::UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine.h b/shell/common/engine.h index 2b43b11932286..04bbae3e7c1b9 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -895,7 +895,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::string DefaultRouteName() override; // |RuntimeDelegate| - void Render(std::unique_ptr layer_tree) override; + void Render(std::unique_ptr layer_tree, + float device_pixel_ratio) override; // |RuntimeDelegate| void UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index c2b2dccb9948b..6d181b2773595 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -51,7 +51,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { MOCK_METHOD0(ImplicitViewEnabled, bool()); MOCK_METHOD0(DefaultRouteName, std::string()); MOCK_METHOD1(ScheduleFrame, void(bool)); - MOCK_METHOD1(Render, void(std::unique_ptr)); + MOCK_METHOD2(Render, void(std::unique_ptr, float)); MOCK_METHOD2(UpdateSemantics, void(SemanticsNodeUpdates, CustomAccessibilityActionUpdates)); MOCK_METHOD1(HandlePlatformMessage, void(std::unique_ptr)); diff --git a/shell/common/pipeline.h b/shell/common/pipeline.h index df0acc6479a33..00e67d1a4261f 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -253,11 +253,14 @@ class Pipeline { struct LayerTreeItem { LayerTreeItem(std::unique_ptr layer_tree, - std::unique_ptr frame_timings_recorder) + std::unique_ptr frame_timings_recorder, + float device_pixel_ratio) : layer_tree(std::move(layer_tree)), - frame_timings_recorder(std::move(frame_timings_recorder)) {} + frame_timings_recorder(std::move(frame_timings_recorder)), + device_pixel_ratio(device_pixel_ratio) {} std::unique_ptr layer_tree; std::unique_ptr frame_timings_recorder; + float device_pixel_ratio; }; using LayerTreePipeline = Pipeline; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 3326a7dc6e547..3041e84d2706c 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -167,8 +167,8 @@ void Rasterizer::DrawLastLayerTree( if (!last_layer_tree_ || !surface_) { return; } - RasterStatus raster_status = - DrawToSurface(*frame_timings_recorder, *last_layer_tree_); + RasterStatus raster_status = DrawToSurface( + *frame_timings_recorder, *last_layer_tree_, last_device_pixel_ratio_); // EndFrame should perform cleanups for the external_view_embedder. if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) { @@ -198,11 +198,12 @@ RasterStatus Rasterizer::Draw( std::unique_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); + float device_pixel_ratio = item->device_pixel_ratio; if (discard_callback(*layer_tree.get())) { raster_status = RasterStatus::kDiscarded; } else { - raster_status = - DoDraw(std::move(frame_timings_recorder), std::move(layer_tree)); + raster_status = DoDraw(std::move(frame_timings_recorder), + std::move(layer_tree), device_pixel_ratio); } }; @@ -216,7 +217,8 @@ RasterStatus Rasterizer::Draw( bool should_resubmit_frame = ShouldResubmitFrame(raster_status); if (should_resubmit_frame) { auto resubmitted_layer_tree_item = std::make_unique( - std::move(resubmitted_layer_tree_), std::move(resubmitted_recorder_)); + std::move(resubmitted_layer_tree_), std::move(resubmitted_recorder_), + resubmitted_pixel_ratio_); auto front_continuation = pipeline->ProduceIfEmpty(); PipelineProduceResult result = front_continuation.Complete(std::move(resubmitted_layer_tree_item)); @@ -375,7 +377,8 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { RasterStatus Rasterizer::DoDraw( std::unique_ptr frame_timings_recorder, - std::unique_ptr layer_tree) { + std::unique_ptr layer_tree, + float device_pixel_ratio) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", "Rasterizer::DoDraw"); FML_DCHECK(delegate_.GetTaskRunners() @@ -390,10 +393,12 @@ RasterStatus Rasterizer::DoDraw( persistent_cache->ResetStoredNewShaders(); RasterStatus raster_status = - DrawToSurface(*frame_timings_recorder, *layer_tree); + DrawToSurface(*frame_timings_recorder, *layer_tree, device_pixel_ratio); if (raster_status == RasterStatus::kSuccess) { last_layer_tree_ = std::move(layer_tree); + last_device_pixel_ratio_ = device_pixel_ratio; } else if (ShouldResubmitFrame(raster_status)) { + resubmitted_pixel_ratio_ = device_pixel_ratio; resubmitted_layer_tree_ = std::move(layer_tree); resubmitted_recorder_ = frame_timings_recorder->CloneUntil( FrameTimingsRecorder::State::kBuildEnd); @@ -476,20 +481,22 @@ RasterStatus Rasterizer::DoDraw( RasterStatus Rasterizer::DrawToSurface( FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree) { + flutter::LayerTree& layer_tree, + float device_pixel_ratio) { TRACE_EVENT0("flutter", "Rasterizer::DrawToSurface"); FML_DCHECK(surface_); RasterStatus raster_status; if (surface_->AllowsDrawingWhenGpuDisabled()) { - raster_status = DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree); + raster_status = DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree, + device_pixel_ratio); } else { delegate_.GetIsGpuDisabledSyncSwitch()->Execute( fml::SyncSwitch::Handlers() .SetIfTrue([&] { raster_status = RasterStatus::kDiscarded; }) .SetIfFalse([&] { - raster_status = - DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree); + raster_status = DrawToSurfaceUnsafe( + frame_timings_recorder, layer_tree, device_pixel_ratio); })); } @@ -501,7 +508,8 @@ RasterStatus Rasterizer::DrawToSurface( /// \see Rasterizer::DrawToSurface RasterStatus Rasterizer::DrawToSurfaceUnsafe( FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree) { + flutter::LayerTree& layer_tree, + float device_pixel_ratio) { FML_DCHECK(surface_); compositor_context_->ui_time().SetLapTime( @@ -512,8 +520,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( 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_); + layer_tree.frame_size(), surface_->GetContext(), device_pixel_ratio, + raster_thread_merger_); embedder_root_canvas = external_view_embedder_->GetRootCanvas(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index fbb9386b19c3a..b17242342c084 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -556,13 +556,16 @@ class Rasterizer final : public SnapshotDelegate, RasterStatus DoDraw( std::unique_ptr frame_timings_recorder, - std::unique_ptr layer_tree); + std::unique_ptr layer_tree, + float device_pixel_ratio); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree); + flutter::LayerTree& layer_tree, + float device_pixel_ratio); RasterStatus DrawToSurfaceUnsafe(FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree); + flutter::LayerTree& layer_tree, + float device_pixel_ratio); void FireNextFrameCallbackIfPresent(); @@ -577,11 +580,13 @@ class Rasterizer final : public SnapshotDelegate, std::unique_ptr compositor_context_; // This is the last successfully rasterized layer tree. std::unique_ptr last_layer_tree_; + float last_device_pixel_ratio_; // Set when we need attempt to rasterize the layer tree again. This layer_tree // has not successfully rasterized. This can happen due to the change in the // thread configuration. This will be inserted to the front of the pipeline. std::unique_ptr resubmitted_layer_tree_; std::unique_ptr resubmitted_recorder_; + float resubmitted_pixel_ratio_; fml::closure next_frame_callback_; bool user_override_resource_cache_bytes_; std::optional max_cache_bytes_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index c9d9edc6bb707..a7b3429e45fad 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -27,6 +27,8 @@ using testing::ReturnRef; namespace flutter { namespace { +constexpr float kDevicePixelRatio = 2.0f; + class MockDelegate : public Rasterizer::Delegate { public: MOCK_METHOD1(OnFrameRasterized, void(const FrameTiming& frame_timing)); @@ -187,10 +189,10 @@ TEST(RasterizerTest, auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), - /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -253,10 +255,10 @@ TEST( thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -325,10 +327,9 @@ TEST( auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), - /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -400,10 +401,9 @@ TEST(RasterizerTest, auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), - /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -450,10 +450,10 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -506,10 +506,10 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -609,10 +609,10 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -667,10 +667,10 @@ TEST( thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -725,10 +725,10 @@ TEST( thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -782,10 +782,10 @@ TEST( thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -838,10 +838,10 @@ TEST( thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + std::move(layer_tree), CreateFinishedBuildRecorder(), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -917,10 +917,10 @@ TEST(RasterizerTest, auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); + std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i]), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -1088,10 +1088,10 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); + std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i]), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -1168,10 +1168,10 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp)); + std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp), + kDevicePixelRatio); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 215919ef82ae7..6cef594385a6c 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -203,12 +203,13 @@ void ShellTest::PumpOneFrame(Shell* shell, auto layer_tree = std::make_unique( LayerTree::Config{.root_layer = root_layer}, SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); + viewport_metrics.physical_height)); + float device_pixel_ratio = + static_cast(viewport_metrics.device_pixel_ratio); if (builder) { builder(root_layer); } - runtime_delegate->Render(std::move(layer_tree)); + runtime_delegate->Render(std::move(layer_tree), device_pixel_ratio); latch.Signal(); }); latch.Wait();