From 1eb15c12fb1ffb2ef8e09aba98e26f3dad066e25 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Thu, 31 Oct 2019 16:57:52 -0700 Subject: [PATCH] Revert 78a8ca0f62b04fa49030ecdd2d91726c0639401f (#13467) Put `Picture.toImage` back on the GPU thread. Left the unit tests intact. --- ci/licenses_golden/licenses_flutter | 1 + lib/ui/BUILD.gn | 1 + lib/ui/painting/picture.cc | 83 +++++------------------------ lib/ui/snapshot_delegate.h | 21 ++++++++ lib/ui/ui_dart_state.cc | 13 +++++ lib/ui/ui_dart_state.h | 7 +++ runtime/dart_isolate.cc | 28 ++++++---- runtime/dart_isolate.h | 3 ++ runtime/dart_isolate_unittests.cc | 3 ++ runtime/dart_lifecycle_unittests.cc | 1 + runtime/runtime_controller.cc | 6 +++ runtime/runtime_controller.h | 3 ++ shell/common/engine.cc | 12 +++-- shell/common/engine.h | 4 +- shell/common/rasterizer.cc | 56 +++++++++++++++++++ shell/common/rasterizer.h | 9 +++- shell/common/shell.cc | 29 ++++++---- 17 files changed, 180 insertions(+), 100 deletions(-) create mode 100644 lib/ui/snapshot_delegate.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 3562d87114e..f80943a2418 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -317,6 +317,7 @@ FILE: ../../../flutter/lib/ui/semantics/semantics_update.cc FILE: ../../../flutter/lib/ui/semantics/semantics_update.h FILE: ../../../flutter/lib/ui/semantics/semantics_update_builder.cc FILE: ../../../flutter/lib/ui/semantics/semantics_update_builder.h +FILE: ../../../flutter/lib/ui/snapshot_delegate.h FILE: ../../../flutter/lib/ui/text.dart FILE: ../../../flutter/lib/ui/text/asset_manager_font_provider.cc FILE: ../../../flutter/lib/ui/text/asset_manager_font_provider.h diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 36c40fffdb6..003efe1cb1b 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -76,6 +76,7 @@ source_set("ui") { "semantics/semantics_update.h", "semantics/semantics_update_builder.cc", "semantics/semantics_update_builder.h", + "snapshot_delegate.h", "text/asset_manager_font_provider.cc", "text/asset_manager_font_provider.h", "text/font_collection.cc", diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 52ec4641fcb..98c37edc115 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -5,11 +5,9 @@ #include "flutter/lib/ui/painting/picture.h" #include "flutter/fml/make_copyable.h" -#include "flutter/fml/trace_event.h" #include "flutter/lib/ui/painting/canvas.h" #include "flutter/lib/ui/ui_dart_state.h" #include "third_party/skia/include/core/SkImage.h" -#include "third_party/skia/include/core/SkSurface.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" @@ -18,64 +16,6 @@ #include "third_party/tonic/logging/dart_invoke.h" namespace flutter { -namespace { - -sk_sp MakeSnapshotSurface(const SkISize& picture_size, - fml::WeakPtr resource_context) { - SkImageInfo image_info = SkImageInfo::MakeN32Premul( - picture_size.width(), picture_size.height(), SkColorSpace::MakeSRGB()); - if (resource_context) { - return SkSurface::MakeRenderTarget(resource_context.get(), // context - SkBudgeted::kNo, // budgeted - image_info // image info - ); - } else { - return SkSurface::MakeRaster(image_info); - } -} - -/// Makes a RAM backed (Raster) image of a picture. -/// @param[in] picture The picture that will get converted to an image. -/// @param[in] surface The surface tha will be used to render the picture. This -/// will be CPU or GPU based. -/// @todo Currently this creates a RAM backed image regardless of what type of -/// surface is used. In certain instances we may want a GPU backed image -/// from a GPU surface to avoid the conversion. -sk_sp MakeRasterSnapshot(sk_sp picture, - sk_sp surface) { - TRACE_EVENT0("flutter", __FUNCTION__); - - if (surface == nullptr || surface->getCanvas() == nullptr) { - return nullptr; - } - - surface->getCanvas()->drawPicture(picture.get()); - - surface->getCanvas()->flush(); - - // Here device could mean GPU or CPU (depending on the supplied surface) and - // host means CPU; this is different from use cases like Flutter driver tests - // where device means mobile devices and host means laptops/desktops. - sk_sp device_snapshot; - { - TRACE_EVENT0("flutter", "MakeDeviceSnpashot"); - device_snapshot = surface->makeImageSnapshot(); - } - - if (device_snapshot == nullptr) { - return nullptr; - } - - { - TRACE_EVENT0("flutter", "DeviceHostTransfer"); - if (auto raster_image = device_snapshot->makeRasterImage()) { - return raster_image; - } - } - - return nullptr; -} -} // namespace IMPLEMENT_WRAPPERTYPEINFO(ui, Picture); @@ -135,8 +75,8 @@ Dart_Handle Picture::RasterizeToImage(sk_sp picture, new tonic::DartPersistentValue(dart_state, raw_image_callback); auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); - auto io_task_runner = dart_state->GetTaskRunners().GetIOTaskRunner(); - fml::WeakPtr io_manager = dart_state->GetIOManager(); + auto gpu_task_runner = dart_state->GetTaskRunners().GetGPUTaskRunner(); + auto snapshot_delegate = dart_state->GetSnapshotDelegate(); // We can't create an image on this task runner because we don't have a // graphics context. Even if we did, it would be slow anyway. Also, this @@ -171,16 +111,17 @@ Dart_Handle Picture::RasterizeToImage(sk_sp picture, delete image_callback; }); - fml::TaskRunner::RunNowOrPostTask(io_task_runner, [ui_task_runner, picture, - picture_bounds, ui_task, - io_manager] { - sk_sp surface = - MakeSnapshotSurface(picture_bounds, io_manager->GetResourceContext()); - sk_sp raster_image = MakeRasterSnapshot(picture, surface); + // Kick things off on the GPU. + fml::TaskRunner::RunNowOrPostTask( + gpu_task_runner, + [ui_task_runner, snapshot_delegate, picture, picture_bounds, ui_task] { + sk_sp raster_image = + snapshot_delegate->MakeRasterSnapshot(picture, picture_bounds); - fml::TaskRunner::RunNowOrPostTask( - ui_task_runner, [ui_task, raster_image]() { ui_task(raster_image); }); - }); + fml::TaskRunner::RunNowOrPostTask( + ui_task_runner, + [ui_task, raster_image]() { ui_task(raster_image); }); + }); return Dart_Null(); } diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h new file mode 100644 index 00000000000..9a771f1219c --- /dev/null +++ b/lib/ui/snapshot_delegate.h @@ -0,0 +1,21 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_ +#define FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_ + +#include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkPicture.h" + +namespace flutter { + +class SnapshotDelegate { + public: + virtual sk_sp MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_ diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index 4b0a9b4bbf7..fa2ae24beef 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -17,6 +17,7 @@ UIDartState::UIDartState( TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr skia_unref_queue, fml::WeakPtr image_decoder, @@ -28,6 +29,7 @@ UIDartState::UIDartState( : task_runners_(std::move(task_runners)), add_callback_(std::move(add_callback)), remove_callback_(std::move(remove_callback)), + snapshot_delegate_(std::move(snapshot_delegate)), io_manager_(std::move(io_manager)), skia_unref_queue_(std::move(skia_unref_queue)), image_decoder_(std::move(image_decoder)), @@ -116,6 +118,17 @@ void UIDartState::AddOrRemoveTaskObserver(bool add) { } } +fml::WeakPtr UIDartState::GetSnapshotDelegate() const { + return snapshot_delegate_; +} + +fml::WeakPtr UIDartState::GetResourceContext() const { + if (!io_manager_) { + return {}; + } + return io_manager_->GetResourceContext(); +} + fml::WeakPtr UIDartState::GetImageDecoder() const { return image_decoder_; } diff --git a/lib/ui/ui_dart_state.h b/lib/ui/ui_dart_state.h index 0a076ce4010..2d81b6d3ebc 100644 --- a/lib/ui/ui_dart_state.h +++ b/lib/ui/ui_dart_state.h @@ -18,6 +18,7 @@ #include "flutter/lib/ui/io_manager.h" #include "flutter/lib/ui/isolate_name_server/isolate_name_server.h" #include "flutter/lib/ui/painting/image_decoder.h" +#include "flutter/lib/ui/snapshot_delegate.h" #include "third_party/dart/runtime/include/dart_api.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/tonic/dart_microtask_queue.h" @@ -52,6 +53,10 @@ class UIDartState : public tonic::DartState { fml::RefPtr GetSkiaUnrefQueue() const; + fml::WeakPtr GetSnapshotDelegate() const; + + fml::WeakPtr GetResourceContext() const; + fml::WeakPtr GetImageDecoder() const; std::shared_ptr GetIsolateNameServer() const; @@ -76,6 +81,7 @@ class UIDartState : public tonic::DartState { UIDartState(TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr skia_unref_queue, fml::WeakPtr image_decoder, @@ -99,6 +105,7 @@ class UIDartState : public tonic::DartState { const TaskRunners task_runners_; const TaskObserverAdd add_callback_; const TaskObserverRemove remove_callback_; + fml::WeakPtr snapshot_delegate_; fml::WeakPtr io_manager_; fml::RefPtr skia_unref_queue_; fml::WeakPtr image_decoder_; diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 719cc681338..50f753216e8 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -34,6 +34,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( fml::RefPtr isolate_snapshot, TaskRunners task_runners, std::unique_ptr window, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr unref_queue, fml::WeakPtr image_decoder, @@ -56,17 +57,18 @@ std::weak_ptr DartIsolate::CreateRootIsolate( // being prepared to run. auto root_embedder_data = std::make_unique>( std::shared_ptr(new DartIsolate( - settings, // settings - std::move(isolate_snapshot), // isolate snapshot - task_runners, // task runners - std::move(io_manager), // IO manager - std::move(unref_queue), // Skia unref queue - std::move(image_decoder), // Image Decoder - advisory_script_uri, // advisory URI - advisory_script_entrypoint, // advisory entrypoint - nullptr, // child isolate preparer - isolate_create_callback, // isolate create callback - isolate_shutdown_callback // isolate shutdown callback + settings, // settings + std::move(isolate_snapshot), // isolate snapshot + task_runners, // task runners + std::move(snapshot_delegate), // snapshot delegate + std::move(io_manager), // IO manager + std::move(unref_queue), // Skia unref queue + std::move(image_decoder), // Image Decoder + advisory_script_uri, // advisory URI + advisory_script_entrypoint, // advisory entrypoint + nullptr, // child isolate preparer + isolate_create_callback, // isolate create callback + isolate_shutdown_callback // isolate shutdown callback ))); std::tie(vm_isolate, embedder_isolate) = CreateDartVMAndEmbedderObjectPair( @@ -103,6 +105,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( DartIsolate::DartIsolate(const Settings& settings, fml::RefPtr isolate_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr unref_queue, fml::WeakPtr image_decoder, @@ -114,6 +117,7 @@ DartIsolate::DartIsolate(const Settings& settings, : UIDartState(std::move(task_runners), settings.task_observer_add, settings.task_observer_remove, + std::move(snapshot_delegate), std::move(io_manager), std::move(unref_queue), std::move(image_decoder), @@ -594,6 +598,7 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate( vm_data->GetIsolateSnapshot(), // isolate snapshot null_task_runners, // task runners nullptr, // window + {}, // snapshot delegate {}, // IO Manager {}, // Skia unref queue {}, // Image Decoder @@ -706,6 +711,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( (*raw_embedder_isolate)->GetSettings(), // settings (*raw_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot null_task_runners, // task_runners + fml::WeakPtr{}, // snapshot_delegate fml::WeakPtr{}, // io_manager fml::RefPtr{}, // unref_queue fml::WeakPtr{}, // image_decoder diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h index 7ee76ded305..7def5adc856 100644 --- a/runtime/dart_isolate.h +++ b/runtime/dart_isolate.h @@ -14,6 +14,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" #include "flutter/lib/ui/io_manager.h" +#include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/window.h" #include "flutter/runtime/dart_snapshot.h" @@ -191,6 +192,7 @@ class DartIsolate : public UIDartState { fml::RefPtr isolate_snapshot, TaskRunners task_runners, std::unique_ptr window, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr skia_unref_queue, fml::WeakPtr image_decoder, @@ -427,6 +429,7 @@ class DartIsolate : public UIDartState { DartIsolate(const Settings& settings, fml::RefPtr isolate_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr unref_queue, fml::WeakPtr image_decoder, diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index ccca07515d9..5dd39c5ebcc 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -40,6 +40,7 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) { vm_data->GetIsolateSnapshot(), // isolate snapshot std::move(task_runners), // task runners nullptr, // window + {}, // snapshot delegate {}, // io manager {}, // unref queue {}, // image decoder @@ -73,6 +74,7 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) { vm_data->GetIsolateSnapshot(), // isolate snapshot std::move(task_runners), // task runners nullptr, // window + {}, // snapshot delegate {}, // io manager {}, // unref queue {}, // image decoder @@ -183,6 +185,7 @@ static void RunDartCodeInIsolate(DartVMRef& vm_ref, vm_data->GetIsolateSnapshot(), // isolate snapshot std::move(task_runners), // task runners nullptr, // window + {}, // snapshot delegate {}, // io manager {}, // unref queue {}, // image decoder diff --git a/runtime/dart_lifecycle_unittests.cc b/runtime/dart_lifecycle_unittests.cc index 77b14d319ff..ffafe1bf0c2 100644 --- a/runtime/dart_lifecycle_unittests.cc +++ b/runtime/dart_lifecycle_unittests.cc @@ -55,6 +55,7 @@ static std::shared_ptr CreateAndRunRootIsolate( vm.GetIsolateSnapshot(), // isolate_snapshot runners, // task_runners {}, // window + {}, // snapshot_delegate {}, // io_manager {}, // unref_queue {}, // image_decoder diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 5ba0d375080..370ba3e9130 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -19,6 +19,7 @@ RuntimeController::RuntimeController( DartVM* p_vm, fml::RefPtr p_isolate_snapshot, TaskRunners p_task_runners, + fml::WeakPtr p_snapshot_delegate, fml::WeakPtr p_io_manager, fml::RefPtr p_unref_queue, fml::WeakPtr p_image_decoder, @@ -32,6 +33,7 @@ RuntimeController::RuntimeController( p_vm, std::move(p_isolate_snapshot), std::move(p_task_runners), + std::move(p_snapshot_delegate), std::move(p_io_manager), std::move(p_unref_queue), std::move(p_image_decoder), @@ -48,6 +50,7 @@ RuntimeController::RuntimeController( DartVM* p_vm, fml::RefPtr p_isolate_snapshot, TaskRunners p_task_runners, + fml::WeakPtr p_snapshot_delegate, fml::WeakPtr p_io_manager, fml::RefPtr p_unref_queue, fml::WeakPtr p_image_decoder, @@ -62,6 +65,7 @@ RuntimeController::RuntimeController( vm_(p_vm), isolate_snapshot_(std::move(p_isolate_snapshot)), task_runners_(p_task_runners), + snapshot_delegate_(p_snapshot_delegate), io_manager_(p_io_manager), unref_queue_(p_unref_queue), image_decoder_(p_image_decoder), @@ -80,6 +84,7 @@ RuntimeController::RuntimeController( isolate_snapshot_, // task_runners_, // std::make_unique(this), // + snapshot_delegate_, // io_manager_, // unref_queue_, // image_decoder_, // @@ -140,6 +145,7 @@ std::unique_ptr RuntimeController::Clone() const { vm_, // isolate_snapshot_, // task_runners_, // + snapshot_delegate_, // io_manager_, // unref_queue_, // image_decoder_, // diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 1418f8c1005..c0ee45d762e 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -33,6 +33,7 @@ class RuntimeController final : public WindowClient { DartVM* vm, fml::RefPtr isolate_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr unref_queue, fml::WeakPtr image_decoder, @@ -129,6 +130,7 @@ class RuntimeController final : public WindowClient { DartVM* const vm_; fml::RefPtr isolate_snapshot_; TaskRunners task_runners_; + fml::WeakPtr snapshot_delegate_; fml::WeakPtr io_manager_; fml::RefPtr unref_queue_; fml::WeakPtr image_decoder_; @@ -147,6 +149,7 @@ class RuntimeController final : public WindowClient { DartVM* vm, fml::RefPtr isolate_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, fml::RefPtr unref_queue, fml::WeakPtr image_decoder, diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 10e826577e4..38b034d52d0 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -43,7 +43,8 @@ Engine::Engine(Delegate& delegate, Settings settings, std::unique_ptr animator, fml::WeakPtr io_manager, - fml::RefPtr unref_queue) + fml::RefPtr unref_queue, + fml::WeakPtr snapshot_delegate) : delegate_(delegate), settings_(std::move(settings)), animator_(std::move(animator)), @@ -58,10 +59,11 @@ Engine::Engine(Delegate& delegate, // object as its delegate. The delegate may be called in the constructor and // we want to be fully initilazed by that point. runtime_controller_ = std::make_unique( - *this, // runtime delegate - &vm, // VM - std::move(isolate_snapshot), // isolate snapshot - task_runners_, // task runners + *this, // runtime delegate + &vm, // VM + std::move(isolate_snapshot), // isolate snapshot + task_runners_, // task runners + std::move(snapshot_delegate), std::move(io_manager), // io manager std::move(unref_queue), // Skia unref queue image_decoder_.GetWeakPtr(), // image decoder diff --git a/shell/common/engine.h b/shell/common/engine.h index 64571063208..52af0510b3e 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -15,6 +15,7 @@ #include "flutter/lib/ui/painting/image_decoder.h" #include "flutter/lib/ui/semantics/custom_accessibility_action.h" #include "flutter/lib/ui/semantics/semantics_node.h" +#include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/lib/ui/text/font_collection.h" #include "flutter/lib/ui/window/platform_message.h" #include "flutter/lib/ui/window/viewport_metrics.h" @@ -278,7 +279,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { Settings settings, std::unique_ptr animator, fml::WeakPtr io_manager, - fml::RefPtr unref_queue); + fml::RefPtr unref_queue, + fml::WeakPtr snapshot_delegate); //---------------------------------------------------------------------------- /// @brief Destroys the engine engine. Called by the shell on the UI task diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 581a7d64072..d61e1ff86dd 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -55,6 +55,10 @@ fml::WeakPtr Rasterizer::GetWeakPtr() const { return weak_factory_.GetWeakPtr(); } +fml::WeakPtr Rasterizer::GetSnapshotDelegate() const { + return weak_factory_.GetWeakPtr(); +} + void Rasterizer::Setup(std::unique_ptr surface) { surface_ = std::move(surface); if (max_cache_bytes_.has_value()) { @@ -147,6 +151,58 @@ void Rasterizer::Draw(fml::RefPtr> pipeline) { } } +sk_sp Rasterizer::MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) { + TRACE_EVENT0("flutter", __FUNCTION__); + + sk_sp surface; + SkImageInfo image_info = SkImageInfo::MakeN32Premul( + picture_size.width(), picture_size.height(), SkColorSpace::MakeSRGB()); + if (surface_ == nullptr || surface_->GetContext() == nullptr) { + // Raster surface is fine if there is no on screen surface. This might + // happen in case of software rendering. + surface = SkSurface::MakeRaster(image_info); + } else { + if (!surface_->MakeRenderContextCurrent()) { + return nullptr; + } + + // When there is an on screen surface, we need a render target SkSurface + // because we want to access texture backed images. + surface = SkSurface::MakeRenderTarget(surface_->GetContext(), // context + SkBudgeted::kNo, // budgeted + image_info // image info + ); + } + + if (surface == nullptr || surface->getCanvas() == nullptr) { + return nullptr; + } + + surface->getCanvas()->drawPicture(picture.get()); + + surface->getCanvas()->flush(); + + sk_sp device_snapshot; + { + TRACE_EVENT0("flutter", "MakeDeviceSnpashot"); + device_snapshot = surface->makeImageSnapshot(); + } + + if (device_snapshot == nullptr) { + return nullptr; + } + + { + TRACE_EVENT0("flutter", "DeviceHostTransfer"); + if (auto raster_image = device_snapshot->makeRasterImage()) { + return raster_image; + } + } + + return nullptr; +} + RasterStatus Rasterizer::DoDraw( std::unique_ptr layer_tree) { FML_DCHECK(task_runners_.GetGPUTaskRunner()->RunsTasksOnCurrentThread()); diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 42e75f44be7..097d93fd4c9 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -16,6 +16,7 @@ #include "flutter/fml/gpu_thread_merger.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/fml/synchronization/waitable_event.h" +#include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/shell/common/pipeline.h" #include "flutter/shell/common/surface.h" @@ -34,7 +35,7 @@ namespace flutter { /// and the on-screen render surface. The compositor context has all the GPU /// state necessary to render frames to the render surface. /// -class Rasterizer final { +class Rasterizer final : public SnapshotDelegate { public: //---------------------------------------------------------------------------- /// @brief Used to forward events from the rasterizer to interested @@ -174,6 +175,8 @@ class Rasterizer final { /// fml::WeakPtr GetWeakPtr() const; + fml::WeakPtr GetSnapshotDelegate() const; + //---------------------------------------------------------------------------- /// @brief Sometimes, it may be necessary to render the same frame again /// without having to wait for the framework to build a whole new @@ -419,6 +422,10 @@ class Rasterizer final { fml::WeakPtrFactory weak_factory_; fml::RefPtr gpu_thread_merger_; + // |SnapshotDelegate| + sk_sp MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) override; + RasterStatus DoDraw(std::unique_ptr layer_tree); RasterStatus DrawToSurface(flutter::LayerTree& layer_tree); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 7ead524f929..060957a74de 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -58,13 +58,18 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // Create the rasterizer on the GPU thread. std::promise> rasterizer_promise; auto rasterizer_future = rasterizer_promise.get_future(); + std::promise> snapshot_delegate_promise; + auto snapshot_delegate_future = snapshot_delegate_promise.get_future(); fml::TaskRunner::RunNowOrPostTask( - task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // + task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // + &snapshot_delegate_promise, on_create_rasterizer, // shell = shell.get() // ]() { TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); - rasterizer_promise.set_value(on_create_rasterizer(*shell)); + std::unique_ptr rasterizer(on_create_rasterizer(*shell)); + snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate()); + rasterizer_promise.set_value(std::move(rasterizer)); }); // Create the platform view on the platform thread (this thread). @@ -129,6 +134,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( isolate_snapshot = std::move(isolate_snapshot), // vsync_waiter = std::move(vsync_waiter), // &weak_io_manager_future, // + &snapshot_delegate_future, // &unref_queue_future // ]() mutable { TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); @@ -140,15 +146,16 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( std::move(vsync_waiter)); engine_promise.set_value(std::make_unique( - *shell, // - dispatcher_maker, // - *shell->GetDartVM(), // - std::move(isolate_snapshot), // - task_runners, // - shell->GetSettings(), // - std::move(animator), // - weak_io_manager_future.get(), // - unref_queue_future.get() // + *shell, // + dispatcher_maker, // + *shell->GetDartVM(), // + std::move(isolate_snapshot), // + task_runners, // + shell->GetSettings(), // + std::move(animator), // + weak_io_manager_future.get(), // + unref_queue_future.get(), // + snapshot_delegate_future.get() // )); }));