|
13 | 13 | #include "flutter/fml/synchronization/waitable_event.h" |
14 | 14 | #include "flutter/fml/task_runner.h" |
15 | 15 | #include "flutter/runtime/dart_vm_lifecycle.h" |
| 16 | +#include "flutter/shell/common/persistent_cache.h" |
16 | 17 | #include "flutter/shell/common/rasterizer.h" |
17 | 18 | #include "flutter/shell/common/run_configuration.h" |
18 | 19 | #include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" |
19 | | - |
| 20 | +#include "flutter/shell/common/serialization_callbacks.h" |
20 | 21 | #include "flutter_runner_product_configuration.h" |
21 | 22 | #include "fuchsia_external_view_embedder.h" |
22 | 23 | #include "fuchsia_intl.h" |
| 24 | +#include "include/core/SkPicture.h" |
| 25 | +#include "include/core/SkSerialProcs.h" |
23 | 26 | #include "platform_view.h" |
24 | 27 | #include "surface.h" |
25 | 28 | #include "task_runner_adapter.h" |
@@ -237,14 +240,95 @@ Engine::Engine(Delegate& delegate, |
237 | 240 | std::make_unique<flutter_runner::CompositorContext>( |
238 | 241 | session_connection_.value(), surface_producer_.value(), |
239 | 242 | legacy_external_view_embedder_.value()); |
| 243 | + |
| 244 | + // tell concurrent task runner to deserialize all skps available from |
| 245 | + // the asset manager |
| 246 | + shell.GetDartVM()->GetConcurrentMessageLoop()->GetTaskRunner()->PostTask([raster_task_runner = |
| 247 | + shell.GetTaskRunners().GetRasterTaskRunner(), |
| 248 | + compositor_context = compositor_context.get()]() { |
| 249 | + TRACE_DURATION("flutter", "DeserializeSkps"); |
| 250 | + std::vector<std::unique_ptr<fml::Mapping>> skp_mappings = |
| 251 | + flutter::PersistentCache::GetCacheForProcess() |
| 252 | + ->GetSkpsFromAssetManager(); |
| 253 | + std::vector<sk_sp<SkPicture>> pictures; |
| 254 | + int i = 0; |
| 255 | + for (auto& mapping : skp_mappings) { |
| 256 | + |
| 257 | + std::unique_ptr<SkMemoryStream> stream = |
| 258 | + SkMemoryStream::MakeDirect(mapping->GetMapping(), |
| 259 | + mapping->GetSize()); |
| 260 | + SkDeserialProcs procs = {0}; |
| 261 | + procs.fImageProc = flutter::DeserializeImageWithoutData; |
| 262 | + procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData; |
| 263 | + sk_sp<SkPicture> picture = |
| 264 | + SkPicture::MakeFromStream(stream.get(), &procs); |
| 265 | + if (!picture) { |
| 266 | + FML_LOG(ERROR) << "Failed to deserialize picture " << i; |
| 267 | + continue; |
| 268 | + } |
| 269 | + |
| 270 | + // Tell raster task runner to warmup have the compositor |
| 271 | + // context warm up the newly deserialized picture |
| 272 | + raster_task_runner->PostTask([compositor_context, picture] { |
| 273 | + TRACE_DURATION("flutter", "WarmupSkp"); |
| 274 | + compositor_context->WarmupSkp(picture); |
| 275 | + }); |
| 276 | + i++; |
| 277 | + } |
| 278 | + }); |
| 279 | + |
240 | 280 | return std::make_unique<flutter::Rasterizer>( |
241 | 281 | shell, std::move(compositor_context)); |
242 | 282 | } else { |
243 | 283 | return std::make_unique<flutter::Rasterizer>(shell); |
244 | 284 | } |
245 | 285 | }; |
246 | 286 | #else |
247 | | - on_create_rasterizer = [](flutter::Shell& shell) { |
| 287 | + on_create_rasterizer = [this](flutter::Shell& shell) { |
| 288 | + FML_DCHECK(surface_producer_); |
| 289 | + |
| 290 | + SkISize size = SkISize::Make(1024, 600); |
| 291 | + auto skp_warmup_surface = surface_producer_->ProduceOffscreenSurface(size); |
| 292 | + if (!skp_warmup_surface) { |
| 293 | + FML_LOG(ERROR) << "SkSurface::MakeRenderTarget returned null"; |
| 294 | + return std::make_unique<flutter::Rasterizer>(shell); |
| 295 | + } |
| 296 | + |
| 297 | + // tell concurrent task runner to deserialize all skps available from |
| 298 | + // the asset manager |
| 299 | + shell.GetDartVM()->GetConcurrentMessageLoop()->GetTaskRunner()->PostTask([raster_task_runner = |
| 300 | + shell.GetTaskRunners().GetRasterTaskRunner(), skp_warmup_surface, this]() { |
| 301 | + TRACE_DURATION("flutter", "DeserializeSkps"); |
| 302 | + std::vector<std::unique_ptr<fml::Mapping>> skp_mappings = |
| 303 | + flutter::PersistentCache::GetCacheForProcess() |
| 304 | + ->GetSkpsFromAssetManager(); |
| 305 | + std::vector<sk_sp<SkPicture>> pictures; |
| 306 | + int i = 0; |
| 307 | + for (auto& mapping : skp_mappings) { |
| 308 | + std::unique_ptr<SkMemoryStream> stream = |
| 309 | + SkMemoryStream::MakeDirect(mapping->GetMapping(), |
| 310 | + mapping->GetSize()); |
| 311 | + SkDeserialProcs procs = {0}; |
| 312 | + procs.fImageProc = flutter::DeserializeImageWithoutData; |
| 313 | + procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData; |
| 314 | + sk_sp<SkPicture> picture = |
| 315 | + SkPicture::MakeFromStream(stream.get(), &procs); |
| 316 | + if (!picture) { |
| 317 | + FML_LOG(ERROR) << "Failed to deserialize picture " << i; |
| 318 | + continue; |
| 319 | + } |
| 320 | + |
| 321 | + // Tell raster task runner to warmup have the compositor |
| 322 | + // context warm up the newly deserialized picture |
| 323 | + raster_task_runner->PostTask([skp_warmup_surface, picture, this] { |
| 324 | + TRACE_DURATION("flutter", "WarmupSkp"); |
| 325 | + skp_warmup_surface->getCanvas()->drawPicture(picture); |
| 326 | + surface_producer_->gr_context()->flush(); |
| 327 | + }); |
| 328 | + i++; |
| 329 | + } |
| 330 | + }); |
| 331 | + |
248 | 332 | return std::make_unique<flutter::Rasterizer>(shell); |
249 | 333 | }; |
250 | 334 | #endif |
|
0 commit comments