|
14 | 14 | #include "flutter/fml/synchronization/waitable_event.h" |
15 | 15 | #include "flutter/fml/task_runner.h" |
16 | 16 | #include "flutter/runtime/dart_vm_lifecycle.h" |
| 17 | +#include "flutter/shell/common/persistent_cache.h" |
17 | 18 | #include "flutter/shell/common/rasterizer.h" |
18 | 19 | #include "flutter/shell/common/run_configuration.h" |
19 | | -#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" |
20 | | - |
| 20 | +#include "flutter/shell/common/serialization_callbacks.h" |
21 | 21 | #include "flutter_runner_product_configuration.h" |
22 | 22 | #include "fuchsia_external_view_embedder.h" |
23 | 23 | #include "fuchsia_intl.h" |
| 24 | +#include "include/core/SkPicture.h" |
| 25 | +#include "include/core/SkSerialProcs.h" |
24 | 26 | #include "platform_view.h" |
25 | 27 | #include "surface.h" |
26 | 28 | #include "task_runner_adapter.h" |
| 29 | +#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" |
27 | 30 | #include "thread.h" |
28 | 31 |
|
29 | 32 | #if defined(LEGACY_FUCHSIA_EMBEDDER) |
@@ -248,15 +251,23 @@ Engine::Engine(Delegate& delegate, |
248 | 251 | auto compositor_context = |
249 | 252 | std::make_unique<flutter_runner::CompositorContext>( |
250 | 253 | session_connection_.value(), surface_producer_.value(), |
251 | | - legacy_external_view_embedder_); |
| 254 | + legacy_external_view_embedder_.value()); |
| 255 | + |
252 | 256 | return std::make_unique<flutter::Rasterizer>( |
253 | 257 | shell, std::move(compositor_context)); |
254 | 258 | } else { |
255 | 259 | return std::make_unique<flutter::Rasterizer>(shell); |
256 | 260 | } |
257 | 261 | }; |
258 | 262 | #else |
259 | | - on_create_rasterizer = [](flutter::Shell& shell) { |
| 263 | + on_create_rasterizer = [this](flutter::Shell& shell) { |
| 264 | + FML_DCHECK(surface_producer_); |
| 265 | + |
| 266 | + WarmupSkps( |
| 267 | + shell.GetDartVM()->GetConcurrentMessageLoop()->GetTaskRunner().get(), |
| 268 | + shell.GetTaskRunners().GetRasterTaskRunner().get(), |
| 269 | + surface_producer_.value()); |
| 270 | + |
260 | 271 | return std::make_unique<flutter::Rasterizer>(shell); |
261 | 272 | }; |
262 | 273 | #endif |
@@ -623,4 +634,50 @@ void Engine::WriteProfileToTrace() const { |
623 | 634 | } |
624 | 635 | #endif // !defined(DART_PRODUCT) |
625 | 636 |
|
| 637 | +void Engine::WarmupSkps(fml::BasicTaskRunner* concurrent_task_runner, |
| 638 | + fml::BasicTaskRunner* raster_task_runner, |
| 639 | + VulkanSurfaceProducer& surface_producer) { |
| 640 | + SkISize size = SkISize::Make(1024, 600); |
| 641 | + auto skp_warmup_surface = surface_producer.ProduceOffscreenSurface(size); |
| 642 | + if (!skp_warmup_surface) { |
| 643 | + FML_LOG(ERROR) << "SkSurface::MakeRenderTarget returned null"; |
| 644 | + return; |
| 645 | + } |
| 646 | + |
| 647 | + // tell concurrent task runner to deserialize all skps available from |
| 648 | + // the asset manager |
| 649 | + concurrent_task_runner->PostTask([&raster_task_runner, skp_warmup_surface, |
| 650 | + &surface_producer]() { |
| 651 | + TRACE_DURATION("flutter", "DeserializeSkps"); |
| 652 | + std::vector<std::unique_ptr<fml::Mapping>> skp_mappings = |
| 653 | + flutter::PersistentCache::GetCacheForProcess() |
| 654 | + ->GetSkpsFromAssetManager(); |
| 655 | + std::vector<sk_sp<SkPicture>> pictures; |
| 656 | + int i = 0; |
| 657 | + for (auto& mapping : skp_mappings) { |
| 658 | + std::unique_ptr<SkMemoryStream> stream = |
| 659 | + SkMemoryStream::MakeDirect(mapping->GetMapping(), mapping->GetSize()); |
| 660 | + SkDeserialProcs procs = {0}; |
| 661 | + procs.fImageProc = flutter::DeserializeImageWithoutData; |
| 662 | + procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData; |
| 663 | + sk_sp<SkPicture> picture = |
| 664 | + SkPicture::MakeFromStream(stream.get(), &procs); |
| 665 | + if (!picture) { |
| 666 | + FML_LOG(ERROR) << "Failed to deserialize picture " << i; |
| 667 | + continue; |
| 668 | + } |
| 669 | + |
| 670 | + // Tell raster task runner to warmup have the compositor |
| 671 | + // context warm up the newly deserialized picture |
| 672 | + raster_task_runner->PostTask( |
| 673 | + [skp_warmup_surface, picture, &surface_producer] { |
| 674 | + TRACE_DURATION("flutter", "WarmupSkp"); |
| 675 | + skp_warmup_surface->getCanvas()->drawPicture(picture); |
| 676 | + surface_producer.gr_context()->flush(); |
| 677 | + }); |
| 678 | + i++; |
| 679 | + } |
| 680 | + }); |
| 681 | +} |
| 682 | + |
626 | 683 | } // namespace flutter_runner |
0 commit comments