diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 905c8dcdf24de..acefd7e4a9672 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -507,6 +507,7 @@ FILE: ../../../flutter/lib/ui/isolate_name_server/isolate_name_server_natives.cc FILE: ../../../flutter/lib/ui/isolate_name_server/isolate_name_server_natives.h FILE: ../../../flutter/lib/ui/plugins/callback_cache.cc FILE: ../../../flutter/lib/ui/plugins/callback_cache.h +FILE: ../../../flutter/lib/ui/snapshot_delegate.h FILE: ../../../flutter/runtime/dart_service_isolate_unittests.cc FILE: ../../../flutter/shell/common/isolate_configuration.cc FILE: ../../../flutter/shell/common/isolate_configuration.h diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 28791a35af619..06c46bc37f1c8 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -23,8 +23,8 @@ source_set("ui") { "painting/canvas.h", "painting/codec.cc", "painting/codec.h", - "painting/engine_layer.h", "painting/engine_layer.cc", + "painting/engine_layer.h", "painting/frame_info.cc", "painting/frame_info.h", "painting/gradient.cc", @@ -65,6 +65,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/compositing/scene.cc b/lib/ui/compositing/scene.cc index 735ce44197921..3629637688a2a 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -53,46 +53,6 @@ void Scene::dispose() { ClearDartWrapper(); } -static sk_sp CreateSceneSnapshot(GrContext* context, - sk_sp picture, - const SkSize& size) { - TRACE_EVENT0("flutter", "CreateSceneSnapshot"); - auto image_info = - SkImageInfo::MakeN32Premul(SkISize::Make(size.width(), size.height())); - - sk_sp surface; - - if (context) { - surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, image_info); - } - - if (!surface) { - surface = SkSurface::MakeRaster(image_info); - } - - if (!surface) { - return nullptr; - } - - auto canvas = surface->getCanvas(); - - if (!canvas) { - return nullptr; - } - - if (picture) { - canvas->drawPicture(picture.get()); - } - - auto snapshot = surface->makeImageSnapshot(); - - if (!snapshot) { - return nullptr; - } - - return snapshot->makeRasterImage(); -} - Dart_Handle Scene::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { @@ -110,67 +70,70 @@ Dart_Handle Scene::toImage(uint32_t width, } auto dart_state = UIDartState::Current(); - auto image_callback = std::make_unique( dart_state, raw_image_callback); + auto unref_queue = dart_state->GetSkiaUnrefQueue(); + auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); + 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 // thread owns the sole reference to the layer tree. So we flatten the layer // tree into a picture and use that as the thread transport mechanism. - auto bounds_size = SkSize::Make(width, height); - auto picture = m_layerTree->Flatten(SkRect::MakeSize(bounds_size)); + auto picture_bounds = SkISize::Make(width, height); + auto picture = m_layerTree->Flatten(SkRect::MakeWH(width, height)); + if (!picture) { // Already in Dart scope. return tonic::ToDart("Could not flatten scene into a layer tree."); } - auto resource_context = dart_state->GetResourceContext(); - auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); - auto unref_queue = dart_state->GetSkiaUnrefQueue(); - - // The picture has been prepared on the UI thread. - dart_state->GetTaskRunners().GetIOTaskRunner()->PostTask( - fml::MakeCopyable([picture = std::move(picture), // - bounds_size, // - resource_context = std::move(resource_context), // - ui_task_runner = std::move(ui_task_runner), // - image_callback = std::move(image_callback), // - unref_queue = std::move(unref_queue) // - ]() mutable { - // Snapshot the picture on the IO thread that contains an optional - // GrContext. - auto image = CreateSceneSnapshot(resource_context.get(), - std::move(picture), bounds_size); - - // Send the image back to the UI thread for submission back to the - // framework. - ui_task_runner->PostTask( - fml::MakeCopyable([image = std::move(image), // - image_callback = std::move(image_callback), // - unref_queue = std::move(unref_queue) // - ]() mutable { - auto dart_state = image_callback->dart_state().lock(); - if (!dart_state) { - // The root isolate could have died in the meantime. - return; - } - tonic::DartState::Scope scope(dart_state); - - if (!image) { - tonic::DartInvoke(image_callback->Get(), {Dart_Null()}); - return; - } - - auto dart_image = CanvasImage::Create(); - dart_image->set_image({std::move(image), std::move(unref_queue)}); - auto raw_dart_image = tonic::ToDart(std::move(dart_image)); - - // All done! - tonic::DartInvoke(image_callback->Get(), {raw_dart_image}); - })); - })); + auto ui_task = fml::MakeCopyable([ui_task_runner, + image_callback = std::move(image_callback), + unref_queue]( + sk_sp raster_image) mutable { + // Send the raster image back to the UI thread for submission to the + // framework. + ui_task_runner->PostTask(fml::MakeCopyable([raster_image, + image_callback = + std::move(image_callback), + unref_queue]() mutable { + auto dart_state = image_callback->dart_state().lock(); + if (!dart_state) { + // The root isolate could have died in the meantime. + return; + } + tonic::DartState::Scope scope(dart_state); + + if (!raster_image) { + tonic::DartInvoke(image_callback->Get(), {Dart_Null()}); + return; + } + + auto dart_image = CanvasImage::Create(); + dart_image->set_image({std::move(raster_image), std::move(unref_queue)}); + auto raw_dart_image = tonic::ToDart(std::move(dart_image)); + + // All done! + tonic::DartInvoke(image_callback->Get(), {raw_dart_image}); + })); + }); + + auto gpu_task = fml::MakeCopyable([gpu_task_runner, picture, picture_bounds, + snapshot_delegate, ui_task]() { + gpu_task_runner->PostTask([snapshot_delegate, picture, picture_bounds, + ui_task]() { + // Snapshot the picture on the GPU thread. This thread has access to the + // GPU contexts that may contain the sole references to texture backed + // images in the picture. + ui_task(snapshot_delegate->MakeRasterSnapshot(picture, picture_bounds)); + }); + }); + + // Kick things off on the GPU. + gpu_task(); return Dart_Null(); } diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h new file mode 100644 index 0000000000000..ceca0e7b35cd7 --- /dev/null +++ b/lib/ui/snapshot_delegate.h @@ -0,0 +1,21 @@ +// Copyright 2018 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 blink { + +class SnapshotDelegate { + public: + virtual sk_sp MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) = 0; +}; + +} // namespace blink + +#endif // FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_ diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index 0d762f785262d..3903b4b23c736 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -16,6 +16,7 @@ namespace blink { UIDartState::UIDartState(TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr skia_unref_queue, std::string advisory_script_uri, @@ -25,6 +26,7 @@ UIDartState::UIDartState(TaskRunners task_runners, : task_runners_(std::move(task_runners)), add_callback_(std::move(add_callback)), remove_callback_(std::move(remove_callback)), + snapshot_delegate_(std::move(snapshot_delegate)), resource_context_(std::move(resource_context)), advisory_script_uri_(std::move(advisory_script_uri)), advisory_script_entrypoint_(std::move(advisory_script_entrypoint)), @@ -99,6 +101,10 @@ void UIDartState::AddOrRemoveTaskObserver(bool add) { } } +fml::WeakPtr UIDartState::GetSnapshotDelegate() const { + return snapshot_delegate_; +} + fml::WeakPtr UIDartState::GetResourceContext() const { return resource_context_; } diff --git a/lib/ui/ui_dart_state.h b/lib/ui/ui_dart_state.h index dea3e9b650447..2fafb0537ae30 100644 --- a/lib/ui/ui_dart_state.h +++ b/lib/ui/ui_dart_state.h @@ -15,6 +15,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/lib/ui/isolate_name_server/isolate_name_server.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" @@ -47,6 +48,8 @@ class UIDartState : public tonic::DartState { fml::RefPtr GetSkiaUnrefQueue() const; + fml::WeakPtr GetSnapshotDelegate() const; + fml::WeakPtr GetResourceContext() const; IsolateNameServer* GetIsolateNameServer(); @@ -68,6 +71,7 @@ class UIDartState : public tonic::DartState { UIDartState(TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr skia_unref_queue, std::string advisory_script_uri, @@ -89,6 +93,7 @@ class UIDartState : public tonic::DartState { const TaskRunners task_runners_; const TaskObserverAdd add_callback_; const TaskObserverRemove remove_callback_; + fml::WeakPtr snapshot_delegate_; fml::WeakPtr resource_context_; const std::string advisory_script_uri_; const std::string advisory_script_entrypoint_; diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index ef62d141b3e77..784f650f6fdb0 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -38,6 +38,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( fml::RefPtr shared_snapshot, TaskRunners task_runners, std::unique_ptr window, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, @@ -54,14 +55,15 @@ std::weak_ptr DartIsolate::CreateRootIsolate( // isolate lifecycle is entirely managed by the VM). auto root_embedder_data = std::make_unique>( std::make_shared( - vm, // VM - std::move(isolate_snapshot), // isolate snapshot - std::move(shared_snapshot), // shared snapshot - task_runners, // task runners - std::move(resource_context), // resource context - std::move(unref_queue), // skia unref queue - advisory_script_uri, // advisory URI - advisory_script_entrypoint, // advisory entrypoint + vm, // VM + std::move(isolate_snapshot), // isolate snapshot + std::move(shared_snapshot), // shared snapshot + task_runners, // task runners + std::move(snapshot_delegate), // snapshot delegate + std::move(resource_context), // resource context + std::move(unref_queue), // skia unref queue + advisory_script_uri, // advisory URI + advisory_script_entrypoint, // advisory entrypoint nullptr // child isolate preparer will be set when this isolate is // prepared to run )); @@ -101,6 +103,7 @@ DartIsolate::DartIsolate(DartVM* vm, fml::RefPtr isolate_snapshot, fml::RefPtr shared_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, @@ -109,6 +112,7 @@ DartIsolate::DartIsolate(DartVM* vm, : UIDartState(std::move(task_runners), vm->GetSettings().task_observer_add, vm->GetSettings().task_observer_remove, + std::move(snapshot_delegate), std::move(resource_context), std::move(unref_queue), advisory_script_uri, @@ -520,6 +524,7 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate( vm->GetSharedSnapshot(), // shared snapshot null_task_runners, // task runners nullptr, // window + {}, // snapshot delegate {}, // resource context {}, // unref queue advisory_script_uri == nullptr ? "" @@ -630,6 +635,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( (*raw_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot (*raw_embedder_isolate)->GetSharedSnapshot(), // shared_snapshot null_task_runners, // task_runners + fml::WeakPtr{}, // snapshot_delegate fml::WeakPtr{}, // resource_context nullptr, // unref_queue advisory_script_uri, // advisory_script_uri diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h index f2167364effdd..e17ba08c66be0 100644 --- a/runtime/dart_isolate.h +++ b/runtime/dart_isolate.h @@ -12,6 +12,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" #include "flutter/fml/mapping.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" @@ -44,6 +45,7 @@ class DartIsolate : public UIDartState { fml::RefPtr shared_snapshot, TaskRunners task_runners, std::unique_ptr window, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, @@ -54,6 +56,7 @@ class DartIsolate : public UIDartState { fml::RefPtr isolate_snapshot, fml::RefPtr shared_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index f876d349a2648..44547d3190139 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -35,6 +35,7 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) { vm->GetSharedSnapshot(), // shared snapshot std::move(task_runners), // task runners nullptr, // window + {}, // snapshot delegate {}, // resource context nullptr, // unref qeueue "main.dart", // advisory uri @@ -64,6 +65,7 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) { vm->GetSharedSnapshot(), // shared snapshot std::move(task_runners), // task runners nullptr, // window + {}, // snapshot delegate {}, // resource context nullptr, // unref qeueue "main.dart", // advisory uri diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 956a6a6a862c7..ace1b9b7a2183 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -24,6 +24,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_isolate_snapshot, fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, + fml::WeakPtr p_snapshot_delegate, fml::WeakPtr p_resource_context, fml::RefPtr p_unref_queue, std::string p_advisory_script_uri, @@ -33,6 +34,7 @@ RuntimeController::RuntimeController( std::move(p_isolate_snapshot), std::move(p_shared_snapshot), std::move(p_task_runners), + std::move(p_snapshot_delegate), std::move(p_resource_context), std::move(p_unref_queue), std::move(p_advisory_script_uri), @@ -45,6 +47,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_isolate_snapshot, fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, + fml::WeakPtr p_snapshot_delegate, fml::WeakPtr p_resource_context, fml::RefPtr p_unref_queue, std::string p_advisory_script_uri, @@ -55,6 +58,7 @@ RuntimeController::RuntimeController( isolate_snapshot_(std::move(p_isolate_snapshot)), shared_snapshot_(std::move(p_shared_snapshot)), task_runners_(p_task_runners), + snapshot_delegate_(p_snapshot_delegate), resource_context_(p_resource_context), unref_queue_(p_unref_queue), advisory_script_uri_(p_advisory_script_uri), @@ -66,6 +70,7 @@ RuntimeController::RuntimeController( shared_snapshot_, task_runners_, std::make_unique(this), + snapshot_delegate_, resource_context_, unref_queue_, p_advisory_script_uri, @@ -114,6 +119,7 @@ std::unique_ptr RuntimeController::Clone() const { isolate_snapshot_, // shared_snapshot_, // task_runners_, // + snapshot_delegate_, // resource_context_, // unref_queue_, // advisory_script_uri_, // diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index ac1bfca1f9333..839fcd6a327e0 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -32,6 +32,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr isolate_snapshot, fml::RefPtr shared_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, @@ -112,6 +113,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr isolate_snapshot_; fml::RefPtr shared_snapshot_; TaskRunners task_runners_; + fml::WeakPtr snapshot_delegate_; fml::WeakPtr resource_context_; fml::RefPtr unref_queue_; std::string advisory_script_uri_; @@ -125,6 +127,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr isolate_snapshot, fml::RefPtr shared_snapshot, TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue, std::string advisory_script_uri, diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 3ab484c46f37c..59cff299b7ab0 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -45,6 +45,7 @@ Engine::Engine(Delegate& delegate, blink::TaskRunners task_runners, blink::Settings settings, std::unique_ptr animator, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue) : delegate_(delegate), @@ -62,6 +63,7 @@ Engine::Engine(Delegate& delegate, std::move(isolate_snapshot), // isolate snapshot std::move(shared_snapshot), // shared snapshot std::move(task_runners), // task runners + std::move(snapshot_delegate), // snapshot delegate std::move(resource_context), // resource context std::move(unref_queue), // skia unref queue settings_.advisory_script_uri, // advisory script uri diff --git a/shell/common/engine.h b/shell/common/engine.h index 06436ce3683d0..0f79eeeb31c00 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -14,6 +14,7 @@ #include "flutter/fml/memory/weak_ptr.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" @@ -56,6 +57,7 @@ class Engine final : public blink::RuntimeDelegate { blink::TaskRunners task_runners, blink::Settings settings, std::unique_ptr animator, + fml::WeakPtr snapshot_delegate, fml::WeakPtr resource_context, fml::RefPtr unref_queue); diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 6f08b2afd0b7e..9a870326dd2d5 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -39,6 +39,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); compositor_context_->OnGrContextCreated(); @@ -89,6 +93,53 @@ void Rasterizer::Draw( } } +sk_sp Rasterizer::MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) { + TRACE_EVENT0("flutter", __FUNCTION__); + + sk_sp surface; + 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(SkImageInfo::MakeN32Premul(picture_size)); + } else { + // 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 + SkImageInfo::MakeN32Premul(picture_size) // 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; +} + void Rasterizer::DoDraw(std::unique_ptr layer_tree) { if (!layer_tree || !surface_) { return; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 1d3c03d8953df..5bffb104f8519 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -13,12 +13,13 @@ #include "flutter/fml/closure.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/surface.h" #include "flutter/synchronization/pipeline.h" namespace shell { -class Rasterizer final { +class Rasterizer final : public blink::SnapshotDelegate { public: Rasterizer(blink::TaskRunners task_runners); @@ -33,6 +34,8 @@ class Rasterizer final { fml::WeakPtr GetWeakPtr() const; + fml::WeakPtr GetSnapshotDelegate() const; + flow::LayerTree* GetLastLayerTree(); void DrawLastLayerTree(); @@ -75,6 +78,10 @@ class Rasterizer final { fml::closure next_frame_callback_; fml::WeakPtrFactory weak_factory_; + // |blink::SnapshotDelegate| + sk_sp MakeRasterSnapshot(sk_sp picture, + SkISize picture_size) override; + void DoDraw(std::unique_ptr layer_tree); bool DrawToSurface(flow::LayerTree& layer_tree); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 8f07f500588a4..1139be8531c94 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -92,31 +92,37 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // Create the rasterizer on the GPU thread. fml::AutoResetWaitableEvent gpu_latch; std::unique_ptr rasterizer; + fml::WeakPtr snapshot_delegate; fml::TaskRunner::RunNowOrPostTask( task_runners.GetGPUTaskRunner(), [&gpu_latch, // &rasterizer, // on_create_rasterizer, // - shell = shell.get() // + shell = shell.get(), // + &snapshot_delegate // ]() { if (auto new_rasterizer = on_create_rasterizer(*shell)) { rasterizer = std::move(new_rasterizer); + snapshot_delegate = rasterizer->GetSnapshotDelegate(); } gpu_latch.Signal(); }); + gpu_latch.Wait(); + // Create the engine on the UI thread. fml::AutoResetWaitableEvent ui_latch; std::unique_ptr engine; fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetUITaskRunner(), - fml::MakeCopyable([&ui_latch, // - &engine, // - shell = shell.get(), // - isolate_snapshot = std::move(isolate_snapshot), // - shared_snapshot = std::move(shared_snapshot), // - vsync_waiter = std::move(vsync_waiter), // - resource_context = std::move(resource_context), // - unref_queue = std::move(unref_queue) // + fml::MakeCopyable([&ui_latch, // + &engine, // + shell = shell.get(), // + isolate_snapshot = std::move(isolate_snapshot), // + shared_snapshot = std::move(shared_snapshot), // + vsync_waiter = std::move(vsync_waiter), // + snapshot_delegate = std::move(snapshot_delegate), // + resource_context = std::move(resource_context), // + unref_queue = std::move(unref_queue) // ]() mutable { const auto& task_runners = shell->GetTaskRunners(); @@ -125,20 +131,20 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( auto animator = std::make_unique(*shell, task_runners, std::move(vsync_waiter)); - engine = std::make_unique(*shell, // - shell->GetDartVM(), // - std::move(isolate_snapshot), // - std::move(shared_snapshot), // - task_runners, // - shell->GetSettings(), // - std::move(animator), // - std::move(resource_context), // - std::move(unref_queue) // + engine = std::make_unique(*shell, // + shell->GetDartVM(), // + std::move(isolate_snapshot), // + std::move(shared_snapshot), // + task_runners, // + shell->GetSettings(), // + std::move(animator), // + std::move(snapshot_delegate), // + std::move(resource_context), // + std::move(unref_queue) // ); ui_latch.Signal(); })); - gpu_latch.Wait(); ui_latch.Wait(); // We are already on the platform thread. So there is no platform latch to // wait on.