From c82840f2a6988c9c7c1cadf0f52c1fe52f9249b0 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 7 Jul 2022 15:36:50 -0700 Subject: [PATCH 01/30] delete dl flag from allowlist --- shell/common/switches.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/common/switches.cc b/shell/common/switches.cc index 7eb3aa9568c87..b3ce13c7da3af 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -64,8 +64,6 @@ static const std::string kAllowedDartFlags[] = { "--write-service-info", "--null_assertions", "--strict_null_safety_checks", - "--enable-display-list", - "--no-enable-display-list", "--max_subtype_cache_entries", }; // clang-format on From 856069a408e49519ac6fe99a710ec93dd3d731ad Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 12 Jul 2022 18:14:56 -0700 Subject: [PATCH 02/30] hhacky --- flow/layers/layer_tree.cc | 65 +++++++++++++++++++++++++++++++++++++ flow/layers/layer_tree.h | 5 +++ lib/ui/compositing/scene.cc | 12 +++++-- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 79cf6cc13ecd3..c1175e5ab47ac 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -223,4 +223,69 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return builder.Build(); } +sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, CompositorContext* compositor_context) { + TRACE_EVENT0("flutter", "LayerTree::FlattenWithContext"); + + DisplayListCanvasRecorder builder(bounds); + + MutatorsStack unused_stack; + const FixedRefreshRateStopwatch unused_stopwatch; + TextureRegistry unused_texture_registry; + SkMatrix root_surface_transformation; + // No root surface transformation. So assume identity. + root_surface_transformation.reset(); + + PrerollContext preroll_context{ + // clang-format off + .raster_cache = nullptr, + .gr_context = nullptr, + .view_embedder = nullptr, + .mutators_stack = unused_stack, + .dst_color_space = nullptr, + .cull_rect = kGiantRect, + .surface_needs_readback = false, + .raster_time = unused_stopwatch, + .ui_time = unused_stopwatch, + .texture_registry = compositor_context->texture_registry(), + .checkerboard_offscreen_layers = false, + .frame_device_pixel_ratio = device_pixel_ratio_ + // clang-format on + }; + + SkISize canvas_size = builder.getBaseLayerSize(); + SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height()); + internal_nodes_canvas.addCanvas(&builder); + + PaintContext paint_context = { + // clang-format off + .internal_nodes_canvas = &internal_nodes_canvas, + .leaf_nodes_canvas = &builder, + .gr_context = nullptr, + .dst_color_space = nullptr, + .view_embedder = nullptr, + .raster_time = unused_stopwatch, + .ui_time = unused_stopwatch, + .texture_registry = compositor_context->texture_registry(), + .raster_cache = nullptr, + .checkerboard_offscreen_layers = false, + .frame_device_pixel_ratio = device_pixel_ratio_, + .layer_snapshot_store = nullptr, + .enable_leaf_layer_tracing = false, + .leaf_nodes_builder = builder.builder().get(), + // clang-format on + }; + + // Even if we don't have a root layer, we still need to create an empty + // picture. + if (root_layer_) { + root_layer_->Preroll(&preroll_context, root_surface_transformation); + // The needs painting flag may be set after the preroll. So check it after. + if (root_layer_->needs_painting(paint_context)) { + root_layer_->Paint(paint_context); + } + } + + return builder.Build(); +} + } // namespace flutter diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index c7daa5f809e9f..8c2fcc426ec7b 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -43,6 +43,11 @@ class LayerTree { sk_sp Flatten(const SkRect& bounds); + sk_sp FlattenWithContext( + const SkRect& bounds, + CompositorContext* compositor_context + ); + Layer* root_layer() const { return root_layer_.get(); } void set_root_layer(std::shared_ptr root_layer) { diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index e42ec7c8d60ac..845ce190b10e9 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -10,6 +10,7 @@ #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/lib/ui/window/window.h" +#include "flutter/shell/common/rasterizer.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/tonic/converter/dart_converter.h" @@ -71,12 +72,15 @@ Dart_Handle Scene::toGpuImage(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toGpuImage"); + auto* dart_state = UIDartState::Current(); + auto snapshot_delegate = dart_state->GetSnapshotDelegate(); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); + auto context = (static_cast(snapshot_delegate.get()))->compositor_context(); + auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), context); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } @@ -89,12 +93,14 @@ Dart_Handle Scene::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); + auto* dart_state = UIDartState::Current(); + auto snapshot_delegate = dart_state->GetSnapshotDelegate(); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - - auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); + auto context = (static_cast(snapshot_delegate.get()))->compositor_context(); + auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), context); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } From 614836d9c17b7a0b9b3d9dafa9d8eaa68ec6f0c2 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 12 Jul 2022 23:06:18 -0700 Subject: [PATCH 03/30] Re-arrange interface --- flow/layers/layer_tree.cc | 8 ++++---- flow/layers/layer_tree.h | 3 ++- lib/ui/BUILD.gn | 1 + lib/ui/compositing/scene.cc | 7 ++----- lib/ui/snapshot_delegate.h | 12 ++++++++++++ shell/common/rasterizer.h | 12 ++---------- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index c1175e5ab47ac..5cf738795d796 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -223,17 +223,17 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return builder.Build(); } -sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, CompositorContext* compositor_context) { +sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, SnapshotDelegate* snapshot_delegate) { TRACE_EVENT0("flutter", "LayerTree::FlattenWithContext"); DisplayListCanvasRecorder builder(bounds); MutatorsStack unused_stack; const FixedRefreshRateStopwatch unused_stopwatch; - TextureRegistry unused_texture_registry; SkMatrix root_surface_transformation; // No root surface transformation. So assume identity. root_surface_transformation.reset(); + auto* texture_registry = snapshot_delegate->GetTextureRegistry(); PrerollContext preroll_context{ // clang-format off @@ -246,7 +246,7 @@ sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, Composito .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = compositor_context->texture_registry(), + .texture_registry = *texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on @@ -265,7 +265,7 @@ sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, Composito .view_embedder = nullptr, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = compositor_context->texture_registry(), + .texture_registry = *texture_registry, .raster_cache = nullptr, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_, diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 8c2fcc426ec7b..24304b8542613 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -11,6 +11,7 @@ #include "flutter/flow/compositor_context.h" #include "flutter/flow/layers/layer.h" #include "flutter/flow/raster_cache.h" +#include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/fml/macros.h" #include "flutter/fml/time/time_delta.h" #include "third_party/skia/include/core/SkPicture.h" @@ -45,7 +46,7 @@ class LayerTree { sk_sp FlattenWithContext( const SkRect& bounds, - CompositorContext* compositor_context + SnapshotDelegate* snapshot_delegate ); Layer* root_layer() const { return root_layer_.get(); } diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 80b4f773f9bf2..392d9ad25748d 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -146,6 +146,7 @@ source_set("ui") { deps = [ "//flutter/assets", "//flutter/common", + "//flutter/common/graphics", "//flutter/display_list", "//flutter/fml", "//flutter/runtime:dart_plugin_registrant", diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 47078f321e9c5..0104fb471fb74 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -10,7 +10,6 @@ #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/lib/ui/window/window.h" -#include "flutter/shell/common/rasterizer.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/tonic/converter/dart_converter.h" @@ -79,8 +78,7 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - auto context = (static_cast(snapshot_delegate.get()))->compositor_context(); - auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), context); + auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), snapshot_delegate.get()); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } @@ -99,8 +97,7 @@ Dart_Handle Scene::toImage(uint32_t width, if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - auto context = (static_cast(snapshot_delegate.get()))->compositor_context(); - auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), context); + auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), snapshot_delegate.get()); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h index 7c87a01c865d9..028d6e047929e 100644 --- a/lib/ui/snapshot_delegate.h +++ b/lib/ui/snapshot_delegate.h @@ -8,6 +8,7 @@ #include #include "flutter/display_list/display_list.h" +#include "flutter/common/graphics/texture.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" @@ -28,6 +29,17 @@ class SnapshotDelegate { SkISize picture_size) = 0; virtual sk_sp ConvertToRasterImage(sk_sp image) = 0; + + //---------------------------------------------------------------------------- + /// @brief Gets the registry of external textures currently in use by the + /// rasterizer. These textures may be updated at a cadence + /// different from that of the Flutter application. When an + /// external texture is referenced in the Flutter layer tree, that + /// texture is composited within the Flutter layer tree. + /// + /// @return A pointer to the external texture registry. + /// + virtual TextureRegistry* GetTextureRegistry() = 0; }; } // namespace flutter diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 425b8214e5bd4..a964e4487d3a9 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -212,16 +212,8 @@ class Rasterizer final : public SnapshotDelegate, void DrawLastLayerTree( std::unique_ptr frame_timings_recorder); - //---------------------------------------------------------------------------- - /// @brief Gets the registry of external textures currently in use by the - /// rasterizer. These textures may be updated at a cadence - /// different from that of the Flutter application. When an - /// external texture is referenced in the Flutter layer tree, that - /// texture is composited within the Flutter layer tree. - /// - /// @return A pointer to the external texture registry. - /// - flutter::TextureRegistry* GetTextureRegistry(); + // |SnapshotDelegate| + flutter::TextureRegistry* GetTextureRegistry() override; using LayerTreeDiscardCallback = std::function; From 73197e9fb64e3019ee00b6cbdd18b4a40b4cabb5 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 12 Jul 2022 23:36:35 -0700 Subject: [PATCH 04/30] ++ --- flow/layers/layer_tree.cc | 5 +++-- flow/layers/layer_tree.h | 8 +++----- lib/ui/compositing/scene.cc | 8 ++++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 5cf738795d796..052d00f5928f3 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -223,7 +223,9 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return builder.Build(); } -sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, SnapshotDelegate* snapshot_delegate) { +sk_sp LayerTree::FlattenWithContext( + const SkRect& bounds, + TextureRegistry* texture_registry) { TRACE_EVENT0("flutter", "LayerTree::FlattenWithContext"); DisplayListCanvasRecorder builder(bounds); @@ -233,7 +235,6 @@ sk_sp LayerTree::FlattenWithContext(const SkRect& bounds, SnapshotD SkMatrix root_surface_transformation; // No root surface transformation. So assume identity. root_surface_transformation.reset(); - auto* texture_registry = snapshot_delegate->GetTextureRegistry(); PrerollContext preroll_context{ // clang-format off diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 24304b8542613..ad4bad6c9d8da 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -8,10 +8,10 @@ #include #include +#include "flutter/common/graphics/texture.h" #include "flutter/flow/compositor_context.h" #include "flutter/flow/layers/layer.h" #include "flutter/flow/raster_cache.h" -#include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/fml/macros.h" #include "flutter/fml/time/time_delta.h" #include "third_party/skia/include/core/SkPicture.h" @@ -44,10 +44,8 @@ class LayerTree { sk_sp Flatten(const SkRect& bounds); - sk_sp FlattenWithContext( - const SkRect& bounds, - SnapshotDelegate* snapshot_delegate - ); + sk_sp FlattenWithContext(const SkRect& bounds, + TextureRegistry* texture_registry); Layer* root_layer() const { return root_layer_.get(); } diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 0104fb471fb74..e0ec082fb27b3 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -78,7 +78,9 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), snapshot_delegate.get()); + auto picture = layer_tree_->FlattenWithContext( + SkRect::MakeWH(width, height), + snapshot_delegate.get()->GetTextureRegistry()); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } @@ -97,7 +99,9 @@ Dart_Handle Scene::toImage(uint32_t width, if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->FlattenWithContext(SkRect::MakeWH(width, height), snapshot_delegate.get()); + auto picture = layer_tree_->FlattenWithContext( + SkRect::MakeWH(width, height), + snapshot_delegate.get()->GetTextureRegistry()); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } From 8ba46b23c3f114da40337377290d11046620e6d5 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 12 Jul 2022 23:46:57 -0700 Subject: [PATCH 05/30] Update snapshot_delegate.h --- lib/ui/snapshot_delegate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h index 028d6e047929e..a9de1e17c6878 100644 --- a/lib/ui/snapshot_delegate.h +++ b/lib/ui/snapshot_delegate.h @@ -7,8 +7,8 @@ #include -#include "flutter/display_list/display_list.h" #include "flutter/common/graphics/texture.h" +#include "flutter/display_list/display_list.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" From 11d18440ae7b89a54f74138637358b3c67f5f316 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 13:34:10 -0700 Subject: [PATCH 06/30] run flatten on raster thread --- lib/ui/compositing/scene.cc | 51 ++++++++++++++++++++++++++++--------- lib/ui/compositing/scene.h | 4 +++ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index e0ec082fb27b3..6ada6932ec25d 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -5,6 +5,7 @@ #include "flutter/lib/ui/compositing/scene.h" #include "flutter/fml/trace_event.h" +#include "flutter/lib/ui/painting/display_list_deferred_image_gpu.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/lib/ui/painting/picture.h" #include "flutter/lib/ui/ui_dart_state.h" @@ -78,14 +79,8 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->FlattenWithContext( - SkRect::MakeWH(width, height), - snapshot_delegate.get()->GetTextureRegistry()); - if (!picture) { - return tonic::ToDart("Could not flatten scene into a layer tree."); - } + Scene::RasterizeToImageSync(width, height, raw_image_handle); - Picture::RasterizeToImageSync(picture, width, height, raw_image_handle); return Dart_Null(); } @@ -93,15 +88,11 @@ Dart_Handle Scene::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - auto* dart_state = UIDartState::Current(); - auto snapshot_delegate = dart_state->GetSnapshotDelegate(); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->FlattenWithContext( - SkRect::MakeWH(width, height), - snapshot_delegate.get()->GetTextureRegistry()); + auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); if (!picture) { return tonic::ToDart("Could not flatten scene into a layer tree."); } @@ -109,6 +100,42 @@ Dart_Handle Scene::toImage(uint32_t width, return Picture::RasterizeToImage(picture, width, height, raw_image_callback); } +void Scene::RasterizeToImageSync(uint32_t width, + uint32_t height, + Dart_Handle raw_image_handle) { + auto* dart_state = UIDartState::Current(); + auto unref_queue = dart_state->GetSkiaUnrefQueue(); + auto snapshot_delegate = dart_state->GetSnapshotDelegate(); + auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); + + auto image = CanvasImage::Create(); + auto dl_image = DlDeferredImageGPU::Make(SkISize::Make(width, height)); + image->set_image(dl_image); + + auto layer_tree = takeLayerTree(); + + fml::TaskRunner::RunNowOrPostTask( + raster_task_runner, + [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), + layer_tree = std::move(layer_tree.get()), width, height]() { + auto display_list = layer_tree->FlattenWithContext( + SkRect::MakeWH(width, height), + snapshot_delegate.get()->GetTextureRegistry()); + + sk_sp sk_image; + std::string error; + std::tie(sk_image, error) = snapshot_delegate->MakeGpuImage( + display_list, dl_image->dimensions()); + if (sk_image) { + dl_image->set_image(std::move(sk_image)); + } else { + dl_image->set_error(std::move(error)); + } + }); + + image->AssociateWithDartWrapper(raw_image_handle); +} + std::unique_ptr Scene::takeLayerTree() { return std::move(layer_tree_); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index d550eac484ab6..a120f931d309a 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -50,6 +50,10 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); + void RasterizeToImageSync(uint32_t width, + uint32_t height, + Dart_Handle raw_image_handle); + std::unique_ptr layer_tree_; }; From 68bb76465526afa474ea7056f981cd260905b919 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 13:54:31 -0700 Subject: [PATCH 07/30] make FlattenWithContext an optional parameter on Flatten --- flow/layers/layer_tree.cc | 76 +++---------------------------------- flow/layers/layer_tree.h | 3 +- lib/ui/compositing/scene.cc | 6 +-- 3 files changed, 11 insertions(+), 74 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 052d00f5928f3..c68e7552913c5 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -158,74 +158,8 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, } } -sk_sp LayerTree::Flatten(const SkRect& bounds) { - TRACE_EVENT0("flutter", "LayerTree::Flatten"); - - DisplayListCanvasRecorder builder(bounds); - - MutatorsStack unused_stack; - const FixedRefreshRateStopwatch unused_stopwatch; - TextureRegistry unused_texture_registry; - SkMatrix root_surface_transformation; - // No root surface transformation. So assume identity. - root_surface_transformation.reset(); - - PrerollContext preroll_context{ - // clang-format off - .raster_cache = nullptr, - .gr_context = nullptr, - .view_embedder = nullptr, - .mutators_stack = unused_stack, - .dst_color_space = nullptr, - .cull_rect = kGiantRect, - .surface_needs_readback = false, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = unused_texture_registry, - .checkerboard_offscreen_layers = false, - .frame_device_pixel_ratio = device_pixel_ratio_ - // clang-format on - }; - - SkISize canvas_size = builder.getBaseLayerSize(); - SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height()); - internal_nodes_canvas.addCanvas(&builder); - - PaintContext paint_context = { - // clang-format off - .internal_nodes_canvas = &internal_nodes_canvas, - .leaf_nodes_canvas = &builder, - .gr_context = nullptr, - .dst_color_space = nullptr, - .view_embedder = nullptr, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = unused_texture_registry, - .raster_cache = nullptr, - .checkerboard_offscreen_layers = false, - .frame_device_pixel_ratio = device_pixel_ratio_, - .layer_snapshot_store = nullptr, - .enable_leaf_layer_tracing = false, - .leaf_nodes_builder = builder.builder().get(), - // clang-format on - }; - - // Even if we don't have a root layer, we still need to create an empty - // picture. - if (root_layer_) { - root_layer_->Preroll(&preroll_context, root_surface_transformation); - // The needs painting flag may be set after the preroll. So check it after. - if (root_layer_->needs_painting(paint_context)) { - root_layer_->Paint(paint_context); - } - } - - return builder.Build(); -} - -sk_sp LayerTree::FlattenWithContext( - const SkRect& bounds, - TextureRegistry* texture_registry) { +sk_sp LayerTree::Flatten(const SkRect& bounds, + TextureRegistry* texture_registry) { TRACE_EVENT0("flutter", "LayerTree::FlattenWithContext"); DisplayListCanvasRecorder builder(bounds); @@ -233,6 +167,8 @@ sk_sp LayerTree::FlattenWithContext( MutatorsStack unused_stack; const FixedRefreshRateStopwatch unused_stopwatch; SkMatrix root_surface_transformation; + TextureRegistry unused_texture_registry; + // No root surface transformation. So assume identity. root_surface_transformation.reset(); @@ -247,7 +183,7 @@ sk_sp LayerTree::FlattenWithContext( .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = *texture_registry, +.texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on @@ -266,7 +202,7 @@ sk_sp LayerTree::FlattenWithContext( .view_embedder = nullptr, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = *texture_registry, + .texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, .raster_cache = nullptr, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_, diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index ad4bad6c9d8da..0241c91ed5d90 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -42,7 +42,8 @@ class LayerTree { void Paint(CompositorContext::ScopedFrame& frame, bool ignore_raster_cache = false) const; - sk_sp Flatten(const SkRect& bounds); + sk_sp Flatten(const SkRect& bounds, + TextureRegistry* texture_registry = nullptr); sk_sp FlattenWithContext(const SkRect& bounds, TextureRegistry* texture_registry); diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 6ada6932ec25d..dae3acedad11b 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -118,9 +118,9 @@ void Scene::RasterizeToImageSync(uint32_t width, raster_task_runner, [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), layer_tree = std::move(layer_tree.get()), width, height]() { - auto display_list = layer_tree->FlattenWithContext( - SkRect::MakeWH(width, height), - snapshot_delegate.get()->GetTextureRegistry()); + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(width, height), + snapshot_delegate.get()->GetTextureRegistry()); sk_sp sk_image; std::string error; From 36bed16342a7d145f9b33a5556af619cd550d20d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 13:56:23 -0700 Subject: [PATCH 08/30] ++ --- flow/layers/layer_tree.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index c68e7552913c5..227c40a47a369 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -183,7 +183,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, -.texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, +.texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on From 550a907643af1c1ac30e9ec7950b41b4ad3c8e6d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 14:08:42 -0700 Subject: [PATCH 09/30] Update layer_tree.h --- flow/layers/layer_tree.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 0241c91ed5d90..200240068c33a 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -45,9 +45,6 @@ class LayerTree { sk_sp Flatten(const SkRect& bounds, TextureRegistry* texture_registry = nullptr); - sk_sp FlattenWithContext(const SkRect& bounds, - TextureRegistry* texture_registry); - Layer* root_layer() const { return root_layer_.get(); } void set_root_layer(std::shared_ptr root_layer) { From a8c43a04a952e916079eba3385bf55ec0c19a1fb Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 15:03:45 -0700 Subject: [PATCH 10/30] amost works --- lib/ui/compositing/scene.cc | 10 +++------- lib/ui/compositing/scene.h | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index dae3acedad11b..0fef2d4ab78e6 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -50,7 +50,7 @@ Scene::Scene(std::shared_ptr rootLayer, ->get_window(0) ->viewport_metrics(); - layer_tree_ = std::make_unique( + layer_tree_ = std::make_shared( SkISize::Make(viewport_metrics.physical_width, viewport_metrics.physical_height), static_cast(viewport_metrics.device_pixel_ratio)); @@ -72,8 +72,6 @@ Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - auto* dart_state = UIDartState::Current(); - auto snapshot_delegate = dart_state->GetSnapshotDelegate(); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); @@ -112,12 +110,10 @@ void Scene::RasterizeToImageSync(uint32_t width, auto dl_image = DlDeferredImageGPU::Make(SkISize::Make(width, height)); image->set_image(dl_image); - auto layer_tree = takeLayerTree(); - fml::TaskRunner::RunNowOrPostTask( raster_task_runner, [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), - layer_tree = std::move(layer_tree.get()), width, height]() { + layer_tree = layer_tree_, width, height]() { auto display_list = layer_tree->Flatten(SkRect::MakeWH(width, height), snapshot_delegate.get()->GetTextureRegistry()); @@ -137,7 +133,7 @@ void Scene::RasterizeToImageSync(uint32_t width, } std::unique_ptr Scene::takeLayerTree() { - return std::move(layer_tree_); + // TODO } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index a120f931d309a..f60029866ebf9 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -54,7 +54,7 @@ class Scene : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_handle); - std::unique_ptr layer_tree_; + std::shared_ptr layer_tree_; }; } // namespace flutter From 87c2edb828aeedc2df92f7e90b12534b7fefc1bf Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 15:09:06 -0700 Subject: [PATCH 11/30] almost --- lib/ui/compositing/scene.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 0fef2d4ab78e6..944cac697f3f4 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -133,7 +133,7 @@ void Scene::RasterizeToImageSync(uint32_t width, } std::unique_ptr Scene::takeLayerTree() { - // TODO + return nullptr; } } // namespace flutter From 1fb2718b0be75f41a3754cb121b570892e574aeb Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 16:59:36 -0700 Subject: [PATCH 12/30] change to shared_ptr --- lib/ui/compositing/scene.cc | 4 ++-- lib/ui/compositing/scene.h | 2 +- runtime/runtime_delegate.h | 2 +- shell/common/animator.cc | 2 +- shell/common/animator.h | 2 +- shell/common/animator_unittests.cc | 4 ++-- 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 | 26 +++++++++++++------------- shell/common/shell_test.cc | 2 +- 14 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 944cac697f3f4..3a0c9d156d681 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -132,8 +132,8 @@ void Scene::RasterizeToImageSync(uint32_t width, image->AssociateWithDartWrapper(raw_image_handle); } -std::unique_ptr Scene::takeLayerTree() { - return nullptr; +std::shared_ptr Scene::takeLayerTree() { + return std::move(layer_tree_); } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index f60029866ebf9..e6b3c72320528 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -30,7 +30,7 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); - std::unique_ptr takeLayerTree(); + std::shared_ptr takeLayerTree(); Dart_Handle toImageSync(uint32_t width, uint32_t height, diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 540e47dd09ba4..ad680677338e0 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -24,7 +24,7 @@ class RuntimeDelegate { virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; - virtual void Render(std::unique_ptr layer_tree) = 0; + virtual void Render(std::shared_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 31bd0cdfb5eb5..d8614dc22f69c 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -144,7 +144,7 @@ void Animator::BeginFrame( } } -void Animator::Render(std::unique_ptr layer_tree) { +void Animator::Render(std::shared_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 d822935307ac8..6550452ba481e 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::unique_ptr layer_tree); + void Render(std::shared_ptr layer_tree); const std::weak_ptr GetVsyncWaiter() const; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 628d7eb9afbc0..91c2bad1b033f 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -157,7 +157,7 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { [&] { ASSERT_FALSE(delegate.notify_idle_called_); auto layer_tree = - std::make_unique(SkISize::Make(600, 800), 1.0); + std::make_shared(SkISize::Make(600, 800), 1.0); animator->Render(std::move(layer_tree)); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, @@ -240,7 +240,7 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { PostTaskSync(task_runners.GetUITaskRunner(), [&] { auto layer_tree = - std::make_unique(SkISize::Make(600, 800), 1.0); + std::make_shared(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 9a0e5d03e4883..c2cbc9f512b98 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -439,7 +439,7 @@ void Engine::ScheduleFrame(bool regenerate_layer_tree) { animator_->RequestFrame(regenerate_layer_tree); } -void Engine::Render(std::unique_ptr layer_tree) { +void Engine::Render(std::shared_ptr layer_tree) { if (!layer_tree) { return; } diff --git a/shell/common/engine.h b/shell/common/engine.h index 491ec4f0e5fe3..04b968f106c41 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -879,7 +879,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::string DefaultRouteName() override; // |RuntimeDelegate| - void Render(std::unique_ptr layer_tree) override; + void Render(std::shared_ptr layer_tree) override; // |RuntimeDelegate| void UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 62674947f9e87..6dfc93c555c36 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -48,7 +48,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { public: MOCK_METHOD0(DefaultRouteName, std::string()); MOCK_METHOD1(ScheduleFrame, void(bool)); - MOCK_METHOD1(Render, void(std::unique_ptr)); + MOCK_METHOD1(Render, void(std::shared_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 35f90f39f2c6a..f9546d0816125 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -222,11 +222,11 @@ class Pipeline { }; struct LayerTreeItem { - LayerTreeItem(std::unique_ptr layer_tree, + LayerTreeItem(std::shared_ptr layer_tree, std::unique_ptr frame_timings_recorder) : layer_tree(std::move(layer_tree)), frame_timings_recorder(std::move(frame_timings_recorder)) {} - std::unique_ptr layer_tree; + std::shared_ptr layer_tree; std::unique_ptr frame_timings_recorder; }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 8587d253d1f4d..f797ec90c7b63 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -181,7 +181,7 @@ RasterStatus Rasterizer::Draw(std::shared_ptr pipeline, RasterStatus raster_status = RasterStatus::kFailed; LayerTreePipeline::Consumer consumer = [&](std::unique_ptr item) { - std::unique_ptr layer_tree = std::move(item->layer_tree); + std::shared_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())) { @@ -466,7 +466,7 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { RasterStatus Rasterizer::DoDraw( std::unique_ptr frame_timings_recorder, - std::unique_ptr layer_tree) { + std::shared_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 a964e4487d3a9..a563449563f4c 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -496,7 +496,7 @@ class Rasterizer final : public SnapshotDelegate, RasterStatus DoDraw( std::unique_ptr frame_timings_recorder, - std::unique_ptr layer_tree); + std::shared_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree& layer_tree); @@ -515,11 +515,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::unique_ptr last_layer_tree_; + std::shared_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::unique_ptr resubmitted_layer_tree_; + std::shared_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 4ae9beb937396..32fdcf381d4bb 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -175,7 +175,7 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -237,7 +237,7 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -305,7 +305,7 @@ TEST( rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -375,7 +375,7 @@ TEST(RasterizerTest, rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -422,7 +422,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -475,7 +475,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -572,7 +572,7 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -626,7 +626,7 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -680,7 +680,7 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -733,7 +733,7 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -810,7 +810,7 @@ TEST(RasterizerTest, auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = - std::make_unique(/*frame_size=*/SkISize(), + std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); @@ -971,7 +971,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = - std::make_unique(/*frame_size=*/SkISize(), + std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); @@ -1044,7 +1044,7 @@ 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_unique(/*frame_size=*/SkISize(), + auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp)); diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 27f6b0f65f527..eca345058787f 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -197,7 +197,7 @@ 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_unique( + auto layer_tree = std::make_shared( SkISize::Make(viewport_metrics.physical_width, viewport_metrics.physical_height), static_cast(viewport_metrics.device_pixel_ratio)); From b3c0e00941c9261a19a2bce5a55924cc5d638a1a Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 17:00:44 -0700 Subject: [PATCH 13/30] ++ --- flow/layers/layer_tree.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 227c40a47a369..1cb088535324e 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -183,7 +183,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, -.texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, + .texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on From f7c8de4a2540b425d1dbd5d87db487b787ed32ee Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 18 Jul 2022 11:53:36 -0700 Subject: [PATCH 14/30] add nullchecks and texture test --- lib/ui/compositing/scene.cc | 10 +++++++++- lib/ui/compositing/scene.h | 5 +++++ testing/dart/compositing_test.dart | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 3a0c9d156d681..09493a579da26 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -101,7 +101,11 @@ Dart_Handle Scene::toImage(uint32_t width, void Scene::RasterizeToImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { + FML_DCHECK(layer_tree_); auto* dart_state = UIDartState::Current(); + if (!dart_state) { + return; + } auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto snapshot_delegate = dart_state->GetSnapshotDelegate(); auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); @@ -112,8 +116,12 @@ void Scene::RasterizeToImageSync(uint32_t width, fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), + [snapshot_delegate = std::move(snapshot_delegate), + unref_queue = std::move(unref_queue), dl_image = std::move(dl_image), layer_tree = layer_tree_, width, height]() { + if (!snapshot_delegate) { + return; + } auto display_list = layer_tree->Flatten(SkRect::MakeWH(width, height), snapshot_delegate.get()->GetTextureRegistry()); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e6b3c72320528..e1ae676c19528 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -54,6 +54,11 @@ 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_; }; diff --git a/testing/dart/compositing_test.dart b/testing/dart/compositing_test.dart index 7815fa2aaaf57..985c1e929aa9d 100644 --- a/testing/dart/compositing_test.dart +++ b/testing/dart/compositing_test.dart @@ -36,6 +36,28 @@ void main() { expect(data.buffer.asUint8List()[3], 0xFF); }); + test('Scene.toImageSync succeeds with texture layer', () async { + final SceneBuilder builder = SceneBuilder(); + builder.pushOffset(10, 10); + builder.addTexture(0, width: 10, height: 10); + + final Scene scene = builder.build(); + final Image image = scene.toImageSync(10, 10); + scene.dispose(); + + expect(image.width, 10); + expect(image.height, 10); + + final ByteData? data = await image.toByteData(); + + expect(data, isNotNull); + expect(data!.lengthInBytes, 6 * 8 * 4); + expect(data.buffer.asUint8List()[0], 0); + expect(data.buffer.asUint8List()[1], 0); + expect(data.buffer.asUint8List()[2], 0); + expect(data.buffer.asUint8List()[3], 0); + }); + test('addPicture with disposed picture does not crash', () { bool assertsEnabled = false; assert(() { From 3d215284bfdb3ef12cee5e1653681105f112b632 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 18 Jul 2022 12:08:11 -0700 Subject: [PATCH 15/30] ++ --- lib/ui/compositing/scene.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e1ae676c19528..4b9036b9f5f04 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -54,9 +54,9 @@ 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. + // 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_; From abdf5b8f6b940a5d6fa6ece428eb1979ef618508 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 18 Jul 2022 12:33:07 -0700 Subject: [PATCH 16/30] Update compositing_test.dart --- testing/dart/compositing_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/dart/compositing_test.dart b/testing/dart/compositing_test.dart index 985c1e929aa9d..f7192b1217278 100644 --- a/testing/dart/compositing_test.dart +++ b/testing/dart/compositing_test.dart @@ -51,7 +51,7 @@ void main() { final ByteData? data = await image.toByteData(); expect(data, isNotNull); - expect(data!.lengthInBytes, 6 * 8 * 4); + expect(data!.lengthInBytes, 10 * 10 * 4); expect(data.buffer.asUint8List()[0], 0); expect(data.buffer.asUint8List()[1], 0); expect(data.buffer.asUint8List()[2], 0); From bcb3f440d1d882ade4a69e0da1d10a16e9427194 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 20 Jul 2022 15:28:28 -0700 Subject: [PATCH 17/30] Work in progress unification of toImage and toImageSync --- flow/layers/layer_tree.cc | 5 ++-- lib/ui/compositing.dart | 7 +++--- lib/ui/compositing/scene.cc | 49 +++++++++++++++++++++++++++++-------- lib/ui/compositing/scene.h | 18 ++++++++------ 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 1cb088535324e..cae8995acbcfe 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -167,7 +167,6 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, MutatorsStack unused_stack; const FixedRefreshRateStopwatch unused_stopwatch; SkMatrix root_surface_transformation; - TextureRegistry unused_texture_registry; // No root surface transformation. So assume identity. root_surface_transformation.reset(); @@ -183,7 +182,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, + .texture_registry = *texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on @@ -202,7 +201,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .view_embedder = nullptr, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = texture_registry == nullptr ? unused_texture_registry : *texture_registry, + .texture_registry = *texture_registry, .raster_cache = nullptr, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_, diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index c815293abd96b..8e4f5f91d9252 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -47,7 +47,8 @@ class Scene extends NativeFieldWrapperClass1 { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { + final _Image image = _Image._(); + return _futurize((_Callback callback) => _toImage(width, height, image, (_Image? image) { if (image == null) { callback(null); } else { @@ -57,8 +58,8 @@ class Scene extends NativeFieldWrapperClass1 { ); } - @FfiNative, Uint32, Uint32, Handle)>('Scene::toImage') - external String? _toImage(int width, int height, _Callback<_Image?> callback); + @FfiNative, Uint32, Uint32, Handle, Handle)>('Scene::toImage') + external String? _toImage(int width, int height, _Image outImage, _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 226c82061d580..7f097f0032ff9 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -4,6 +4,7 @@ #include "flutter/lib/ui/compositing/scene.h" +#include "flutter/fml/make_copyable.h" #include "flutter/fml/trace_event.h" #include "flutter/lib/ui/painting/display_list_deferred_image_gpu.h" #include "flutter/lib/ui/painting/image.h" @@ -17,6 +18,8 @@ #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/dart_persistent_value.h" +#include "third_party/tonic/logging/dart_invoke.h" namespace flutter { @@ -70,35 +73,34 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - Scene::RasterizeToImageSync(width, height, raw_image_handle); - + Scene::RasterizeToImage(width, height, raw_image_handle); return Dart_Null(); } Dart_Handle Scene::toImage(uint32_t width, uint32_t height, + Dart_Handle raw_image_handle, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); - if (!picture) { - return tonic::ToDart("Could not flatten scene into a layer tree."); - } - return Picture::RasterizeToImage(picture, width, height, raw_image_callback); + Scene::RasterizeToImage(width, height, raw_image_handle, raw_image_callback); + return Dart_Null(); } -void Scene::RasterizeToImageSync(uint32_t width, - uint32_t height, - Dart_Handle raw_image_handle) { +void Scene::RasterizeToImage(uint32_t width, + uint32_t height, + Dart_Handle raw_image_handle, + Dart_Handle raw_image_callback) { FML_DCHECK(layer_tree_); auto* dart_state = UIDartState::Current(); if (!dart_state) { return; } + auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto snapshot_delegate = dart_state->GetSnapshotDelegate(); auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); @@ -107,10 +109,34 @@ void Scene::RasterizeToImageSync(uint32_t width, auto dl_image = DlDeferredImageGPU::Make(SkISize::Make(width, height)); image->set_image(dl_image); + std::function ui_task; + if (raw_image_callback) { + auto image_callback = std::make_unique( + dart_state, raw_image_callback); + auto image_handle = std::make_unique( + dart_state, raw_image_handle); + ui_task = fml::MakeCopyable( + [image_handle = std::move(image_handle), + image_callback = std::move(image_callback)]() mutable { + auto dart_state = image_handle->dart_state().lock(); + if (!dart_state) { + // The root isolate could have died in the meantime. + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::DartInvoke(image_callback->Get(), {image_handle->Get()}); + + // image_callback is associated with the Dart isolate and must be + // deleted on the UI thread. + image_callback.reset(); + }); + } + fml::TaskRunner::RunNowOrPostTask( raster_task_runner, [snapshot_delegate = std::move(snapshot_delegate), unref_queue = std::move(unref_queue), dl_image = std::move(dl_image), + ui_task_runner = std::move(ui_task_runner), ui_task = std::move(ui_task), layer_tree = layer_tree_, width, height]() { if (!snapshot_delegate) { return; @@ -128,6 +154,9 @@ void Scene::RasterizeToImageSync(uint32_t width, } else { dl_image->set_error(std::move(error)); } + if (ui_task) { + ui_task_runner->PostTask(ui_task); + } }); image->AssociateWithDartWrapper(raw_image_handle); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index b9fda285ecf12..ce6ab953c4aff 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -34,19 +34,21 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImage(uint32_t width, uint32_t height, + Dart_Handle raw_image_handle, Dart_Handle image_callback); void dispose(); private: - explicit Scene(std::shared_ptr rootLayer, - uint32_t rasterizerTracingThreshold, - bool checkerboardRasterCacheImages, - bool checkerboardOffscreenLayers); - - void RasterizeToImageSync(uint32_t width, - uint32_t height, - Dart_Handle raw_image_handle); + Scene(std::shared_ptr rootLayer, + uint32_t rasterizerTracingThreshold, + bool checkerboardRasterCacheImages, + bool checkerboardOffscreenLayers); + + void RasterizeToImage(uint32_t width, + uint32_t height, + Dart_Handle raw_image_handle, + Dart_Handle raw_image_callback = nullptr); // 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 From 535a8c8db0c0b875a52da400040ec1e9bc00cc4c Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 21 Jul 2022 15:14:20 -0700 Subject: [PATCH 18/30] ++ --- flow/layers/layer_tree.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index cae8995acbcfe..6268804038abc 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/embedded_views.h" @@ -160,7 +161,7 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, sk_sp LayerTree::Flatten(const SkRect& bounds, TextureRegistry* texture_registry) { - TRACE_EVENT0("flutter", "LayerTree::FlattenWithContext"); + TRACE_EVENT0("flutter", "LayerTree::Flatten"); DisplayListCanvasRecorder builder(bounds); From 9c0a286b6ae7bdaa316fe2496ecd1c14e11864dd Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 21 Jul 2022 16:23:14 -0700 Subject: [PATCH 19/30] include gr direct context --- flow/layers/layer_tree.cc | 7 ++++--- flow/layers/layer_tree.h | 3 ++- lib/ui/compositing/scene.cc | 3 ++- lib/ui/snapshot_delegate.h | 4 ++++ shell/common/rasterizer.cc | 4 ++++ shell/common/rasterizer.h | 4 ++++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 6268804038abc..caad500863d87 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -160,7 +160,8 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, } sk_sp LayerTree::Flatten(const SkRect& bounds, - TextureRegistry* texture_registry) { + TextureRegistry* texture_registry, + GrDirectContext* gr_context) { TRACE_EVENT0("flutter", "LayerTree::Flatten"); DisplayListCanvasRecorder builder(bounds); @@ -175,7 +176,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, PrerollContext preroll_context{ // clang-format off .raster_cache = nullptr, - .gr_context = nullptr, + .gr_context = gr_context, .view_embedder = nullptr, .mutators_stack = unused_stack, .dst_color_space = nullptr, @@ -197,7 +198,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, // clang-format off .internal_nodes_canvas = &internal_nodes_canvas, .leaf_nodes_canvas = &builder, - .gr_context = nullptr, + .gr_context = gr_context, .dst_color_space = nullptr, .view_embedder = nullptr, .raster_time = unused_stopwatch, diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 200240068c33a..0b16c6291330d 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -43,7 +43,8 @@ class LayerTree { bool ignore_raster_cache = false) const; sk_sp Flatten(const SkRect& bounds, - TextureRegistry* texture_registry = nullptr); + TextureRegistry* texture_registry = nullptr, + GrDirectContext* gr_context = nullptr); Layer* root_layer() const { return root_layer_.get(); } diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 7f097f0032ff9..1d89c3c9f21eb 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -143,7 +143,8 @@ void Scene::RasterizeToImage(uint32_t width, } auto display_list = layer_tree->Flatten(SkRect::MakeWH(width, height), - snapshot_delegate.get()->GetTextureRegistry()); + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); sk_sp sk_image; std::string error; diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h index a9de1e17c6878..0bfd5bc5964bb 100644 --- a/lib/ui/snapshot_delegate.h +++ b/lib/ui/snapshot_delegate.h @@ -13,6 +13,8 @@ #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/gpu/GrContextThreadSafeProxy.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + namespace flutter { class SnapshotDelegate { @@ -40,6 +42,8 @@ class SnapshotDelegate { /// @return A pointer to the external texture registry. /// virtual TextureRegistry* GetTextureRegistry() = 0; + + virtual GrDirectContext* GetGrContext() = 0; }; } // namespace flutter diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index f797ec90c7b63..1ad98e353255e 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -145,6 +145,10 @@ flutter::TextureRegistry* Rasterizer::GetTextureRegistry() { return &compositor_context_->texture_registry(); } +GrDirectContext* Rasterizer::GetGrContext() { + return surface_->GetContext(); +} + flutter::LayerTree* Rasterizer::GetLastLayerTree() { return last_layer_tree_.get(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index a563449563f4c..4ffa125ea47b2 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -26,6 +26,7 @@ #include "flutter/shell/common/pipeline.h" #include "flutter/shell/common/snapshot_surface_producer.h" #include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" namespace flutter { @@ -215,6 +216,9 @@ class Rasterizer final : public SnapshotDelegate, // |SnapshotDelegate| flutter::TextureRegistry* GetTextureRegistry() override; + // |SnapshotDelegate| + GrDirectContext* GetGrContext() override; + using LayerTreeDiscardCallback = std::function; //---------------------------------------------------------------------------- From 2a1a51c8f0f458d766e5e79887cc8127e84de32b Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 21 Jul 2022 16:23:57 -0700 Subject: [PATCH 20/30] ++ --- flow/layers/layer_tree.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index caad500863d87..095165d479d05 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include #include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/embedded_views.h" From fdf2f5ac046c1c50b39c6dae323dd2aee7a1a81f Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 18 Aug 2022 21:37:38 -0700 Subject: [PATCH 21/30] sync to head --- flow/layers/layer_tree.cc | 11 +-- flow/layers/layer_tree.h | 7 +- lib/ui/compositing.dart | 18 ++--- lib/ui/compositing/scene.cc | 69 +++---------------- lib/ui/compositing/scene.h | 6 +- .../display_list_deferred_image_gpu.cc | 65 ++++++++++++++--- .../display_list_deferred_image_gpu.h | 29 +++++++- shell/common/rasterizer.cc | 2 +- 8 files changed, 112 insertions(+), 95 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 9427d7b55951c..3b4907b5336bf 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -171,9 +171,10 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, } } -sk_sp LayerTree::Flatten(const SkRect& bounds, - TextureRegistry* texture_registry, - GrDirectContext* gr_context) { +sk_sp LayerTree::Flatten( + const SkRect& bounds, + std::shared_ptr texture_registry, + GrDirectContext* gr_context) { TRACE_EVENT0("flutter", "LayerTree::Flatten"); DisplayListCanvasRecorder builder(bounds); @@ -196,7 +197,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .surface_needs_readback = false, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = *texture_registry, + .texture_registry = texture_registry, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_ // clang-format on @@ -217,7 +218,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds, .view_embedder = nullptr, .raster_time = unused_stopwatch, .ui_time = unused_stopwatch, - .texture_registry = *texture_registry, + .texture_registry = texture_registry, .raster_cache = nullptr, .checkerboard_offscreen_layers = false, .frame_device_pixel_ratio = device_pixel_ratio_, diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 0b16c6291330d..167500400b758 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -42,9 +42,10 @@ class LayerTree { void Paint(CompositorContext::ScopedFrame& frame, bool ignore_raster_cache = false) const; - sk_sp Flatten(const SkRect& bounds, - TextureRegistry* texture_registry = nullptr, - GrDirectContext* gr_context = nullptr); + sk_sp Flatten( + const SkRect& bounds, + std::shared_ptr texture_registry = nullptr, + GrDirectContext* gr_context = nullptr); Layer* root_layer() const { return root_layer_.get(); } diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index f3f971f39720c..6bf4801b8ab21 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -38,7 +38,6 @@ class Scene extends NativeFieldWrapperClass1 { external String? _toImageSync(int width, int height, _Image outImage); /// Creates a raster image representation of the current state of the scene. - /// This is a slow operation that is performed on a background thread. /// /// 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 @@ -48,18 +47,15 @@ class Scene extends NativeFieldWrapperClass1 { throw Exception('Invalid image dimensions.'); } final _Image image = _Image._(); - return _futurize((_Callback callback) => _toImage(width, height, image, (_Image? image) { - if (image == null) { - callback(null); - } else { - callback(Image._(image, image.width, image.height)); - } - }), - ); + final String? result = _toImage(width, height, image); + if (result != null) { + throw PictureRasterizationException._(result); + } + return Future.value(Image._(image, image.width, image.height)); } - @FfiNative, Uint32, Uint32, Handle, Handle)>('Scene::toImage') - external String? _toImage(int width, int height, _Image outImage, _Callback<_Image?> callback); + @FfiNative, Uint32, Uint32, Handle)>('Scene::toImage') + external String? _toImage(int width, int height, _Image outImage); /// Releases the resources used by this scene. /// diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 1d89c3c9f21eb..fb6097e69d066 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -79,87 +79,36 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle Scene::toImage(uint32_t width, uint32_t height, - Dart_Handle raw_image_handle, - Dart_Handle raw_image_callback) { + Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImage"); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - Scene::RasterizeToImage(width, height, raw_image_handle, raw_image_callback); + Scene::RasterizeToImage(width, height, raw_image_handle); return Dart_Null(); } void Scene::RasterizeToImage(uint32_t width, uint32_t height, - Dart_Handle raw_image_handle, - Dart_Handle raw_image_callback) { - FML_DCHECK(layer_tree_); + Dart_Handle raw_image_handle) { auto* dart_state = UIDartState::Current(); if (!dart_state) { return; } - auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto snapshot_delegate = dart_state->GetSnapshotDelegate(); auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); auto image = CanvasImage::Create(); - auto dl_image = DlDeferredImageGPU::Make(SkISize::Make(width, height)); + const SkImageInfo image_info = SkImageInfo::Make( + width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + auto dl_image = DlDeferredImageGPU::MakeFromLayerTree( + image_info, std::move(layer_tree_), SkRect::MakeWH(width, height), + std::move(snapshot_delegate), std::move(raster_task_runner), + std::move(unref_queue)); image->set_image(dl_image); - - std::function ui_task; - if (raw_image_callback) { - auto image_callback = std::make_unique( - dart_state, raw_image_callback); - auto image_handle = std::make_unique( - dart_state, raw_image_handle); - ui_task = fml::MakeCopyable( - [image_handle = std::move(image_handle), - image_callback = std::move(image_callback)]() mutable { - auto dart_state = image_handle->dart_state().lock(); - if (!dart_state) { - // The root isolate could have died in the meantime. - return; - } - tonic::DartState::Scope scope(dart_state); - tonic::DartInvoke(image_callback->Get(), {image_handle->Get()}); - - // image_callback is associated with the Dart isolate and must be - // deleted on the UI thread. - image_callback.reset(); - }); - } - - fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, - [snapshot_delegate = std::move(snapshot_delegate), - unref_queue = std::move(unref_queue), dl_image = std::move(dl_image), - ui_task_runner = std::move(ui_task_runner), ui_task = std::move(ui_task), - layer_tree = layer_tree_, width, height]() { - if (!snapshot_delegate) { - return; - } - auto display_list = - layer_tree->Flatten(SkRect::MakeWH(width, height), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); - - sk_sp sk_image; - std::string error; - std::tie(sk_image, error) = snapshot_delegate->MakeGpuImage( - display_list, dl_image->dimensions()); - if (sk_image) { - dl_image->set_image(std::move(sk_image)); - } else { - dl_image->set_error(std::move(error)); - } - if (ui_task) { - ui_task_runner->PostTask(ui_task); - } - }); - image->AssociateWithDartWrapper(raw_image_handle); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index ce6ab953c4aff..aca797836fcb1 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -34,8 +34,7 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImage(uint32_t width, uint32_t height, - Dart_Handle raw_image_handle, - Dart_Handle image_callback); + Dart_Handle raw_image_handle); void dispose(); @@ -47,8 +46,7 @@ class Scene : public RefCountedDartWrappable { void RasterizeToImage(uint32_t width, uint32_t height, - Dart_Handle raw_image_handle, - Dart_Handle raw_image_callback = nullptr); + 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 diff --git a/lib/ui/painting/display_list_deferred_image_gpu.cc b/lib/ui/painting/display_list_deferred_image_gpu.cc index beeb0ccf80404..39f1fccd0796b 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu.cc @@ -22,6 +22,20 @@ sk_sp DlDeferredImageGPU::Make( raster_task_runner)); } +sk_sp DlDeferredImageGPU::MakeFromLayerTree( + const SkImageInfo& image_info, + std::shared_ptr layer_tree, + const SkRect& size, + fml::WeakPtr snapshot_delegate, + fml::RefPtr raster_task_runner, + fml::RefPtr unref_queue) { + return sk_sp(new DlDeferredImageGPU( + ImageWrapper::MakeFromLayerTree( + image_info, std::move(layer_tree), size, std::move(snapshot_delegate), + raster_task_runner, std::move(unref_queue)), + raster_task_runner)); +} + DlDeferredImageGPU::DlDeferredImageGPU( std::shared_ptr image_wrapper, fml::RefPtr raster_task_runner) @@ -86,23 +100,47 @@ DlDeferredImageGPU::ImageWrapper::Make( fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { auto wrapper = std::shared_ptr(new ImageWrapper( - image_info, std::move(display_list), std::move(snapshot_delegate), - std::move(raster_task_runner), std::move(unref_queue))); + image_info, + std::variant, std::shared_ptr>( + std::move(display_list)), + std::move(snapshot_delegate), std::move(raster_task_runner), + std::move(unref_queue))); + wrapper->SnapshotDisplayList(); + return wrapper; +} + +std::shared_ptr +DlDeferredImageGPU::ImageWrapper::MakeFromLayerTree( + const SkImageInfo& image_info, + std::shared_ptr layer_tree, + const SkRect& size, + fml::WeakPtr snapshot_delegate, + fml::RefPtr raster_task_runner, + fml::RefPtr unref_queue) { + auto wrapper = std::shared_ptr(new ImageWrapper( + image_info, + std::variant, std::shared_ptr>( + std::move(layer_tree)), + std::move(snapshot_delegate), std::move(raster_task_runner), + std::move(unref_queue), size)); wrapper->SnapshotDisplayList(); return wrapper; } DlDeferredImageGPU::ImageWrapper::ImageWrapper( const SkImageInfo& image_info, - sk_sp display_list, + std::variant, std::shared_ptr> + display_list_or_layer_tree, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, - fml::RefPtr unref_queue) + fml::RefPtr unref_queue, + const SkRect& size) : image_info_(image_info), - display_list_(std::move(display_list)), + display_list_or_layer_tree_(std::move(display_list_or_layer_tree)), snapshot_delegate_(std::move(snapshot_delegate)), raster_task_runner_(std::move(raster_task_runner)), - unref_queue_(std::move(unref_queue)) {} + unref_queue_(std::move(unref_queue)), + size_(size) {} void DlDeferredImageGPU::ImageWrapper::OnGrContextCreated() { FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread()); @@ -142,8 +180,19 @@ void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList() { if (!snapshot_delegate) { return; } - auto result = snapshot_delegate->MakeGpuImage(wrapper->display_list_, - wrapper->image_info_); + if (std::holds_alternative>( + wrapper->display_list_or_layer_tree_)) { + auto layer_tree = std::get>( + wrapper->display_list_or_layer_tree_); + auto display_list = layer_tree->Flatten( + wrapper->size_, snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); + wrapper->display_list_or_layer_tree_.emplace>( + display_list); + } + auto result = snapshot_delegate->MakeGpuImage( + std::get>(wrapper->display_list_or_layer_tree_), + wrapper->image_info_); if (result->texture.isValid()) { wrapper->texture_ = result->texture; wrapper->context_ = std::move(result->context); diff --git a/lib/ui/painting/display_list_deferred_image_gpu.h b/lib/ui/painting/display_list_deferred_image_gpu.h index 429dcd873a101..935647054eda2 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.h +++ b/lib/ui/painting/display_list_deferred_image_gpu.h @@ -7,10 +7,12 @@ #include #include +#include #include "flutter/common/graphics/texture.h" #include "flutter/display_list/display_list.h" #include "flutter/display_list/display_list_image.h" +#include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/skia_gpu_object.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" @@ -28,6 +30,14 @@ class DlDeferredImageGPU final : public DlImage { fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); + static sk_sp MakeFromLayerTree( + const SkImageInfo& image_info, + std::shared_ptr layer_tree, + const SkRect& size, + fml::WeakPtr snapshot_delegate, + fml::RefPtr raster_task_runner, + fml::RefPtr unref_queue); + // |DlImage| ~DlDeferredImageGPU() override; @@ -73,6 +83,14 @@ class DlDeferredImageGPU final : public DlImage { fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); + static std::shared_ptr MakeFromLayerTree( + const SkImageInfo& image_info, + std::shared_ptr layer_tree, + const SkRect& size, + fml::WeakPtr snapshot_delegate, + fml::RefPtr raster_task_runner, + fml::RefPtr unref_queue); + const SkImageInfo image_info() const { return image_info_; } const GrBackendTexture& texture() const { return texture_; } bool isTextureBacked() const; @@ -83,11 +101,14 @@ class DlDeferredImageGPU final : public DlImage { private: const SkImageInfo image_info_; - sk_sp display_list_; + std::variant, std::shared_ptr> + display_list_or_layer_tree_; fml::WeakPtr snapshot_delegate_; fml::RefPtr raster_task_runner_; fml::RefPtr unref_queue_; std::shared_ptr texture_registry_; + // Only valid if constructed via MakeFromLayerTree. + const SkRect& size_; mutable std::mutex error_mutex_; std::optional error_; @@ -98,10 +119,12 @@ class DlDeferredImageGPU final : public DlImage { sk_sp image_; ImageWrapper(const SkImageInfo& image_info, - sk_sp display_list, + std::variant, std::shared_ptr> + display_list_or_layer_tree, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, - fml::RefPtr unref_queue); + fml::RefPtr unref_queue, + const SkRect& size = {}); void SnapshotDisplayList(); diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index aefd8339ceb46..6e0b22d1ff1df 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -145,7 +145,7 @@ std::shared_ptr Rasterizer::GetTextureRegistry() { return compositor_context_->texture_registry(); } -std::shared_ptr Rasterizer::GetGrContext() { +GrDirectContext* Rasterizer::GetGrContext() { return surface_->GetContext(); } From eff89647a048297b3c51c02f58cf12e0859e3ddc Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 18 Aug 2022 23:27:58 -0700 Subject: [PATCH 22/30] I dont know cpp --- lib/ui/compositing/scene.cc | 5 +-- .../display_list_deferred_image_gpu.cc | 31 ++++++++++++------- .../display_list_deferred_image_gpu.h | 12 ++++--- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index fb6097e69d066..b341885639ece 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -4,7 +4,6 @@ #include "flutter/lib/ui/compositing/scene.h" -#include "flutter/fml/make_copyable.h" #include "flutter/fml/trace_event.h" #include "flutter/lib/ui/painting/display_list_deferred_image_gpu.h" #include "flutter/lib/ui/painting/image.h" @@ -18,8 +17,6 @@ #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" -#include "third_party/tonic/dart_persistent_value.h" -#include "third_party/tonic/logging/dart_invoke.h" namespace flutter { @@ -105,7 +102,7 @@ void Scene::RasterizeToImage(uint32_t width, const SkImageInfo image_info = SkImageInfo::Make( width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType); auto dl_image = DlDeferredImageGPU::MakeFromLayerTree( - image_info, std::move(layer_tree_), SkRect::MakeWH(width, height), + image_info, std::move(layer_tree_), width, height, 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.cc b/lib/ui/painting/display_list_deferred_image_gpu.cc index 39f1fccd0796b..de847a70f5b52 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/lib/ui/painting/display_list_deferred_image_gpu.h" +#include #include "display_list_deferred_image_gpu.h" #include "third_party/skia/include/core/SkColorSpace.h" @@ -25,14 +26,16 @@ sk_sp DlDeferredImageGPU::Make( sk_sp DlDeferredImageGPU::MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - const SkRect& size, + uint32_t width, + uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { return sk_sp(new DlDeferredImageGPU( - ImageWrapper::MakeFromLayerTree( - image_info, std::move(layer_tree), size, std::move(snapshot_delegate), - raster_task_runner, std::move(unref_queue)), + ImageWrapper::MakeFromLayerTree(image_info, std::move(layer_tree), width, + height, std::move(snapshot_delegate), + raster_task_runner, + std::move(unref_queue)), raster_task_runner)); } @@ -104,7 +107,7 @@ DlDeferredImageGPU::ImageWrapper::Make( std::variant, std::shared_ptr>( std::move(display_list)), std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue))); + std::move(unref_queue), 0, 0)); wrapper->SnapshotDisplayList(); return wrapper; } @@ -113,7 +116,8 @@ std::shared_ptr DlDeferredImageGPU::ImageWrapper::MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - const SkRect& size, + uint32_t width, + uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { @@ -122,7 +126,7 @@ DlDeferredImageGPU::ImageWrapper::MakeFromLayerTree( std::variant, std::shared_ptr>( std::move(layer_tree)), std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue), size)); + std::move(unref_queue), width, height)); wrapper->SnapshotDisplayList(); return wrapper; } @@ -134,13 +138,15 @@ DlDeferredImageGPU::ImageWrapper::ImageWrapper( fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue, - const SkRect& size) + uint32_t width, + uint32_t height) : image_info_(image_info), display_list_or_layer_tree_(std::move(display_list_or_layer_tree)), snapshot_delegate_(std::move(snapshot_delegate)), raster_task_runner_(std::move(raster_task_runner)), unref_queue_(std::move(unref_queue)), - size_(size) {} + width_(width), + height_(height) {} void DlDeferredImageGPU::ImageWrapper::OnGrContextCreated() { FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread()); @@ -184,9 +190,10 @@ void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList() { wrapper->display_list_or_layer_tree_)) { auto layer_tree = std::get>( wrapper->display_list_or_layer_tree_); - auto display_list = layer_tree->Flatten( - wrapper->size_, snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(100, 100), + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); wrapper->display_list_or_layer_tree_.emplace>( display_list); } diff --git a/lib/ui/painting/display_list_deferred_image_gpu.h b/lib/ui/painting/display_list_deferred_image_gpu.h index 935647054eda2..238e78347a53b 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.h +++ b/lib/ui/painting/display_list_deferred_image_gpu.h @@ -33,7 +33,8 @@ class DlDeferredImageGPU final : public DlImage { static sk_sp MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - const SkRect& size, + uint32_t width, + uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -86,7 +87,8 @@ class DlDeferredImageGPU final : public DlImage { static std::shared_ptr MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - const SkRect& size, + uint32_t width, + uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -108,7 +110,8 @@ class DlDeferredImageGPU final : public DlImage { fml::RefPtr unref_queue_; std::shared_ptr texture_registry_; // Only valid if constructed via MakeFromLayerTree. - const SkRect& size_; + uint32_t width_; + uint32_t height_; mutable std::mutex error_mutex_; std::optional error_; @@ -124,7 +127,8 @@ class DlDeferredImageGPU final : public DlImage { fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue, - const SkRect& size = {}); + uint32_t width, + uint32_t height); void SnapshotDisplayList(); From 8b3dd481563ffd85a1cea70d8318cebe9c065050 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 18 Aug 2022 23:53:28 -0700 Subject: [PATCH 23/30] fix size --- lib/ui/painting/display_list_deferred_image_gpu.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/ui/painting/display_list_deferred_image_gpu.cc b/lib/ui/painting/display_list_deferred_image_gpu.cc index de847a70f5b52..82609524e2f9d 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/lib/ui/painting/display_list_deferred_image_gpu.h" -#include #include "display_list_deferred_image_gpu.h" #include "third_party/skia/include/core/SkColorSpace.h" @@ -190,10 +189,10 @@ void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList() { wrapper->display_list_or_layer_tree_)) { auto layer_tree = std::get>( wrapper->display_list_or_layer_tree_); - auto display_list = - layer_tree->Flatten(SkRect::MakeWH(100, 100), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); + auto display_list = layer_tree->Flatten( + SkRect::MakeWH(wrapper->width_, wrapper->height_), + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); wrapper->display_list_or_layer_tree_.emplace>( display_list); } From da5b3a14f9926eab62ffa1a7a8549a2da9c48898 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 19 Aug 2022 10:36:27 -0700 Subject: [PATCH 24/30] revert toImage change --- lib/ui/compositing.dart | 18 +++++++++++------- lib/ui/compositing/scene.cc | 10 +++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index 6bf4801b8ab21..384d1b500ccb3 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -39,6 +39,8 @@ class Scene extends NativeFieldWrapperClass1 { /// Creates a raster image representation of the current state of the scene. /// + /// This is a slow operation that is performed on a background thread. + /// /// 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. @@ -46,16 +48,18 @@ class Scene extends NativeFieldWrapperClass1 { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - final _Image image = _Image._(); - final String? result = _toImage(width, height, image); - if (result != null) { - throw PictureRasterizationException._(result); - } - return Future.value(Image._(image, image.width, image.height)); + return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { + if (image == null) { + callback(null); + } else { + callback(Image._(image, image.width, image.height)); + } + }), + ); } @FfiNative, Uint32, Uint32, Handle)>('Scene::toImage') - external String? _toImage(int width, int height, _Image outImage); + 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 b341885639ece..fec1ecb957e41 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -76,15 +76,19 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle Scene::toImage(uint32_t width, uint32_t height, - Dart_Handle raw_image_handle) { + Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); if (!layer_tree_) { return tonic::ToDart("Scene did not contain a layer tree."); } - Scene::RasterizeToImage(width, height, raw_image_handle); - return Dart_Null(); + auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); + if (!picture) { + return tonic::ToDart("Could not flatten scene into a layer tree."); + } + + return Picture::RasterizeToImage(picture, width, height, raw_image_callback); } void Scene::RasterizeToImage(uint32_t width, From 9708ebe4cdfe8172fe96a31b5b52f8a6e2cb1528 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 19 Aug 2022 14:56:27 -0700 Subject: [PATCH 25/30] dnfield review --- lib/ui/compositing/scene.cc | 13 ++-- .../display_list_deferred_image_gpu.cc | 70 +++++++------------ .../display_list_deferred_image_gpu.h | 20 ++---- lib/ui/painting/picture.cc | 35 ++++++++-- lib/ui/painting/picture.h | 8 +++ 5 files changed, 72 insertions(+), 74 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index fec1ecb957e41..5a8601b90effe 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -83,12 +83,8 @@ Dart_Handle Scene::toImage(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); - if (!picture) { - return tonic::ToDart("Could not flatten scene into a layer tree."); - } - - return Picture::RasterizeToImage(picture, width, height, raw_image_callback); + return Picture::RasterizeLayerTreeToImage(std::move(layer_tree_), width, + height, raw_image_callback); } void Scene::RasterizeToImage(uint32_t width, @@ -106,9 +102,8 @@ void Scene::RasterizeToImage(uint32_t width, const SkImageInfo image_info = SkImageInfo::Make( width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType); auto dl_image = DlDeferredImageGPU::MakeFromLayerTree( - image_info, std::move(layer_tree_), width, height, - std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue)); + image_info, std::move(layer_tree_), std::move(snapshot_delegate), + std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } diff --git a/lib/ui/painting/display_list_deferred_image_gpu.cc b/lib/ui/painting/display_list_deferred_image_gpu.cc index 82609524e2f9d..4ea7ad7ab1666 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu.cc @@ -25,16 +25,13 @@ sk_sp DlDeferredImageGPU::Make( sk_sp DlDeferredImageGPU::MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { return sk_sp(new DlDeferredImageGPU( - ImageWrapper::MakeFromLayerTree(image_info, std::move(layer_tree), width, - height, std::move(snapshot_delegate), - raster_task_runner, - std::move(unref_queue)), + ImageWrapper::MakeFromLayerTree( + image_info, std::move(layer_tree), std::move(snapshot_delegate), + raster_task_runner, std::move(unref_queue)), raster_task_runner)); } @@ -102,11 +99,8 @@ DlDeferredImageGPU::ImageWrapper::Make( fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { auto wrapper = std::shared_ptr(new ImageWrapper( - image_info, - std::variant, std::shared_ptr>( - std::move(display_list)), - std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue), 0, 0)); + image_info, std::move(display_list), std::move(snapshot_delegate), + std::move(raster_task_runner), std::move(unref_queue))); wrapper->SnapshotDisplayList(); return wrapper; } @@ -115,37 +109,27 @@ std::shared_ptr DlDeferredImageGPU::ImageWrapper::MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { - auto wrapper = std::shared_ptr(new ImageWrapper( - image_info, - std::variant, std::shared_ptr>( - std::move(layer_tree)), - std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue), width, height)); - wrapper->SnapshotDisplayList(); + auto wrapper = std::shared_ptr( + new ImageWrapper(image_info, nullptr, std::move(snapshot_delegate), + std::move(raster_task_runner), std::move(unref_queue))); + wrapper->SnapshotDisplayList(std::move(layer_tree)); return wrapper; } DlDeferredImageGPU::ImageWrapper::ImageWrapper( const SkImageInfo& image_info, - std::variant, std::shared_ptr> - display_list_or_layer_tree, + sk_sp display_list, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, - fml::RefPtr unref_queue, - uint32_t width, - uint32_t height) + fml::RefPtr unref_queue) : image_info_(image_info), - display_list_or_layer_tree_(std::move(display_list_or_layer_tree)), + display_list_(std::move(display_list)), snapshot_delegate_(std::move(snapshot_delegate)), raster_task_runner_(std::move(raster_task_runner)), - unref_queue_(std::move(unref_queue)), - width_(width), - height_(height) {} + unref_queue_(std::move(unref_queue)) {} void DlDeferredImageGPU::ImageWrapper::OnGrContextCreated() { FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread()); @@ -174,9 +158,11 @@ bool DlDeferredImageGPU::ImageWrapper::isTextureBacked() const { return texture_.isValid(); } -void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList() { +void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList( + std::shared_ptr layer_tree) { fml::TaskRunner::RunNowOrPostTask( - raster_task_runner_, [weak_this = weak_from_this()]() { + raster_task_runner_, + [weak_this = weak_from_this(), layer_tree = std::move(layer_tree)]() { auto wrapper = weak_this.lock(); if (!wrapper) { return; @@ -185,20 +171,16 @@ void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList() { if (!snapshot_delegate) { return; } - if (std::holds_alternative>( - wrapper->display_list_or_layer_tree_)) { - auto layer_tree = std::get>( - wrapper->display_list_or_layer_tree_); - auto display_list = layer_tree->Flatten( - SkRect::MakeWH(wrapper->width_, wrapper->height_), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); - wrapper->display_list_or_layer_tree_.emplace>( - display_list); + if (layer_tree) { + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(wrapper->image_info_.width(), + wrapper->image_info_.height()), + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); + wrapper->display_list_ = std::move(display_list); } - auto result = snapshot_delegate->MakeGpuImage( - std::get>(wrapper->display_list_or_layer_tree_), - wrapper->image_info_); + auto result = snapshot_delegate->MakeGpuImage(wrapper->display_list_, + wrapper->image_info_); if (result->texture.isValid()) { wrapper->texture_ = result->texture; wrapper->context_ = std::move(result->context); diff --git a/lib/ui/painting/display_list_deferred_image_gpu.h b/lib/ui/painting/display_list_deferred_image_gpu.h index 238e78347a53b..b111289a55d17 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.h +++ b/lib/ui/painting/display_list_deferred_image_gpu.h @@ -7,7 +7,6 @@ #include #include -#include #include "flutter/common/graphics/texture.h" #include "flutter/display_list/display_list.h" @@ -33,8 +32,6 @@ class DlDeferredImageGPU final : public DlImage { static sk_sp MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -87,8 +84,6 @@ class DlDeferredImageGPU final : public DlImage { static std::shared_ptr MakeFromLayerTree( const SkImageInfo& image_info, std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -103,15 +98,11 @@ class DlDeferredImageGPU final : public DlImage { private: const SkImageInfo image_info_; - std::variant, std::shared_ptr> - display_list_or_layer_tree_; + sk_sp display_list_; fml::WeakPtr snapshot_delegate_; fml::RefPtr raster_task_runner_; fml::RefPtr unref_queue_; std::shared_ptr texture_registry_; - // Only valid if constructed via MakeFromLayerTree. - uint32_t width_; - uint32_t height_; mutable std::mutex error_mutex_; std::optional error_; @@ -122,15 +113,12 @@ class DlDeferredImageGPU final : public DlImage { sk_sp image_; ImageWrapper(const SkImageInfo& image_info, - std::variant, std::shared_ptr> - display_list_or_layer_tree, + sk_sp display_list, fml::WeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, - fml::RefPtr unref_queue, - uint32_t width, - uint32_t height); + fml::RefPtr unref_queue); - void SnapshotDisplayList(); + void SnapshotDisplayList(std::shared_ptr layer_tree = nullptr); // |ContextListener| void OnGrContextCreated() override; diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 4d5411d1830f6..849b5cc634c35 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -95,11 +95,21 @@ Dart_Handle Picture::RasterizeToImage(sk_sp display_list, Dart_Handle raw_image_callback) { return RasterizeToImage( [display_list](SkCanvas* canvas) { display_list->RenderTo(canvas); }, - width, height, raw_image_callback); + nullptr, width, height, raw_image_callback); +} + +Dart_Handle Picture::RasterizeLayerTreeToImage( + std::shared_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); } Dart_Handle Picture::RasterizeToImage( std::function draw_callback, + std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { @@ -158,10 +168,25 @@ Dart_Handle Picture::RasterizeToImage( // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, [ui_task_runner, snapshot_delegate, draw_callback, - picture_bounds, ui_task] { - sk_sp raster_image = snapshot_delegate->MakeRasterSnapshot( - draw_callback, picture_bounds); + raster_task_runner, + [ui_task_runner, snapshot_delegate, draw_callback, picture_bounds, + ui_task, layer_tree = std::move(layer_tree)] { + sk_sp raster_image; + if (layer_tree) { + auto display_list = layer_tree->Flatten( + SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); + + raster_image = snapshot_delegate->MakeRasterSnapshot( + [display_list](SkCanvas* canvas) { + display_list->RenderTo(canvas); + }, + picture_bounds); + } else { + raster_image = snapshot_delegate->MakeRasterSnapshot(draw_callback, + picture_bounds); + } fml::TaskRunner::RunNowOrPostTask( ui_task_runner, diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 1cb390a182138..ab576310d3a91 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -6,6 +6,7 @@ #define FLUTTER_LIB_UI_PAINTING_PICTURE_H_ #include "flutter/display_list/display_list.h" +#include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/skia_gpu_object.h" #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/painting/image.h" @@ -51,8 +52,15 @@ class Picture : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_callback); + static Dart_Handle RasterizeLayerTreeToImage( + std::shared_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); + static Dart_Handle RasterizeToImage( std::function draw_callback, + std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback); From a802cc5b5d3759a63e1494737e60d265076dd0f1 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 19 Aug 2022 15:18:32 -0700 Subject: [PATCH 26/30] Add some doc comments --- lib/ui/painting/display_list_deferred_image_gpu.h | 4 ++++ lib/ui/painting/picture.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/ui/painting/display_list_deferred_image_gpu.h b/lib/ui/painting/display_list_deferred_image_gpu.h index b111289a55d17..dd905423971d6 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.h +++ b/lib/ui/painting/display_list_deferred_image_gpu.h @@ -118,6 +118,10 @@ class DlDeferredImageGPU final : public DlImage { fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); + // If a layer tree is provided, it will be flattened during the raster 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); // |ContextListener| diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index ab576310d3a91..77fda55884c3d 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -58,6 +58,10 @@ class Picture : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_callback); + // Callers may provide either a draw_callback (which should reference 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 draw callback will be + // ignored. static Dart_Handle RasterizeToImage( std::function draw_callback, std::shared_ptr layer_tree, From 657902bc62ac2a66525b8c6ef9bc74f0e7316dad Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 19 Aug 2022 15:37:51 -0700 Subject: [PATCH 27/30] ++ --- lib/ui/painting/display_list_deferred_image_gpu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ui/painting/display_list_deferred_image_gpu.h b/lib/ui/painting/display_list_deferred_image_gpu.h index dd905423971d6..5f04eb25d0765 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.h +++ b/lib/ui/painting/display_list_deferred_image_gpu.h @@ -118,10 +118,10 @@ class DlDeferredImageGPU final : public DlImage { fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); - // If a layer tree is provided, it will be flattened during the raster 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. + // If a layer tree is provided, it will be flattened during the raster + // 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); // |ContextListener| From 5bf34158d8df4312f134735bfa6732a92f2e9c1e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 22 Aug 2022 09:30:50 -0700 Subject: [PATCH 28/30] revert change toImage --- lib/ui/compositing/scene.cc | 8 ++++++-- lib/ui/painting/picture.cc | 34 +++++----------------------------- lib/ui/painting/picture.h | 11 ----------- 3 files changed, 11 insertions(+), 42 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 5a8601b90effe..567093a06e34a 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -83,8 +83,12 @@ Dart_Handle Scene::toImage(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - return Picture::RasterizeLayerTreeToImage(std::move(layer_tree_), width, - height, raw_image_callback); + auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); + if (!picture) { + return tonic::ToDart("Could not flatten scene into a layer tree."); + } + + return Picture::RasterizeToImage(picture, width, height, raw_image_callback); } void Scene::RasterizeToImage(uint32_t width, diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 849b5cc634c35..6d98a77a3c0b2 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -95,21 +95,11 @@ Dart_Handle Picture::RasterizeToImage(sk_sp display_list, Dart_Handle raw_image_callback) { return RasterizeToImage( [display_list](SkCanvas* canvas) { display_list->RenderTo(canvas); }, - nullptr, width, height, raw_image_callback); -} - -Dart_Handle Picture::RasterizeLayerTreeToImage( - std::shared_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); + width, height, raw_image_callback); } Dart_Handle Picture::RasterizeToImage( std::function draw_callback, - std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { @@ -168,25 +158,11 @@ Dart_Handle Picture::RasterizeToImage( // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, - [ui_task_runner, snapshot_delegate, draw_callback, picture_bounds, - ui_task, layer_tree = std::move(layer_tree)] { + raster_task_runner, [ui_task_runner, snapshot_delegate, draw_callback, + picture_bounds, ui_task] { sk_sp raster_image; - if (layer_tree) { - auto display_list = layer_tree->Flatten( - SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); - - raster_image = snapshot_delegate->MakeRasterSnapshot( - [display_list](SkCanvas* canvas) { - display_list->RenderTo(canvas); - }, - picture_bounds); - } else { - raster_image = snapshot_delegate->MakeRasterSnapshot(draw_callback, - picture_bounds); - } + raster_image = snapshot_delegate->MakeRasterSnapshot(draw_callback, + picture_bounds); fml::TaskRunner::RunNowOrPostTask( ui_task_runner, diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 77fda55884c3d..0c49ac1e5f276 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -52,19 +52,8 @@ class Picture : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_callback); - static Dart_Handle RasterizeLayerTreeToImage( - std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback); - - // Callers may provide either a draw_callback (which should reference 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 draw callback will be - // ignored. static Dart_Handle RasterizeToImage( std::function draw_callback, - std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback); From 8c9b0b32ce99b47fde77393e6f5f68525ef46f3b Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 22 Aug 2022 09:50:03 -0700 Subject: [PATCH 29/30] Revert "revert change toImage" This reverts commit 5bf34158d8df4312f134735bfa6732a92f2e9c1e. --- lib/ui/compositing/scene.cc | 8 ++------ lib/ui/painting/picture.cc | 34 +++++++++++++++++++++++++++++----- lib/ui/painting/picture.h | 11 +++++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 567093a06e34a..5a8601b90effe 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -83,12 +83,8 @@ Dart_Handle Scene::toImage(uint32_t width, return tonic::ToDart("Scene did not contain a layer tree."); } - auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); - if (!picture) { - return tonic::ToDart("Could not flatten scene into a layer tree."); - } - - return Picture::RasterizeToImage(picture, width, height, raw_image_callback); + return Picture::RasterizeLayerTreeToImage(std::move(layer_tree_), width, + height, raw_image_callback); } void Scene::RasterizeToImage(uint32_t width, diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 6d98a77a3c0b2..849b5cc634c35 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -95,11 +95,21 @@ Dart_Handle Picture::RasterizeToImage(sk_sp display_list, Dart_Handle raw_image_callback) { return RasterizeToImage( [display_list](SkCanvas* canvas) { display_list->RenderTo(canvas); }, - width, height, raw_image_callback); + nullptr, width, height, raw_image_callback); +} + +Dart_Handle Picture::RasterizeLayerTreeToImage( + std::shared_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); } Dart_Handle Picture::RasterizeToImage( std::function draw_callback, + std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { @@ -158,11 +168,25 @@ Dart_Handle Picture::RasterizeToImage( // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, [ui_task_runner, snapshot_delegate, draw_callback, - picture_bounds, ui_task] { + raster_task_runner, + [ui_task_runner, snapshot_delegate, draw_callback, picture_bounds, + ui_task, layer_tree = std::move(layer_tree)] { sk_sp raster_image; - raster_image = snapshot_delegate->MakeRasterSnapshot(draw_callback, - picture_bounds); + if (layer_tree) { + auto display_list = layer_tree->Flatten( + SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), + snapshot_delegate.get()->GetTextureRegistry(), + snapshot_delegate.get()->GetGrContext()); + + raster_image = snapshot_delegate->MakeRasterSnapshot( + [display_list](SkCanvas* canvas) { + display_list->RenderTo(canvas); + }, + picture_bounds); + } else { + raster_image = snapshot_delegate->MakeRasterSnapshot(draw_callback, + picture_bounds); + } fml::TaskRunner::RunNowOrPostTask( ui_task_runner, diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 0c49ac1e5f276..77fda55884c3d 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -52,8 +52,19 @@ class Picture : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_callback); + static Dart_Handle RasterizeLayerTreeToImage( + std::shared_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); + + // Callers may provide either a draw_callback (which should reference 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 draw callback will be + // ignored. static Dart_Handle RasterizeToImage( std::function draw_callback, + std::shared_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback); From 3a85e348d5479be91cf7d458ac69a697b0047a3b Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 22 Aug 2022 16:13:13 -0700 Subject: [PATCH 30/30] Add more null checking of GetGrContext --- lib/ui/painting/display_list_deferred_image_gpu.cc | 4 ++-- lib/ui/painting/picture.cc | 4 ++-- shell/common/rasterizer.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ui/painting/display_list_deferred_image_gpu.cc b/lib/ui/painting/display_list_deferred_image_gpu.cc index 4ea7ad7ab1666..14391c2128a74 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu.cc @@ -175,8 +175,8 @@ void DlDeferredImageGPU::ImageWrapper::SnapshotDisplayList( auto display_list = layer_tree->Flatten(SkRect::MakeWH(wrapper->image_info_.width(), wrapper->image_info_.height()), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); + snapshot_delegate->GetTextureRegistry(), + snapshot_delegate->GetGrContext()); wrapper->display_list_ = std::move(display_list); } auto result = snapshot_delegate->MakeGpuImage(wrapper->display_list_, diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 849b5cc634c35..c79c5c08a3688 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -175,8 +175,8 @@ Dart_Handle Picture::RasterizeToImage( if (layer_tree) { auto display_list = layer_tree->Flatten( SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), - snapshot_delegate.get()->GetTextureRegistry(), - snapshot_delegate.get()->GetGrContext()); + snapshot_delegate->GetTextureRegistry(), + snapshot_delegate->GetGrContext()); raster_image = snapshot_delegate->MakeRasterSnapshot( [display_list](SkCanvas* canvas) { diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 6e0b22d1ff1df..f9d10fd3e2240 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -146,7 +146,7 @@ std::shared_ptr Rasterizer::GetTextureRegistry() { } GrDirectContext* Rasterizer::GetGrContext() { - return surface_->GetContext(); + return surface_ ? surface_->GetContext() : nullptr; } flutter::LayerTree* Rasterizer::GetLastLayerTree() {