Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8cd322f

Browse files
committed
[WIP] integrated skp shader warmup
1 parent aff58e3 commit 8cd322f

13 files changed

+170
-34
lines changed

assets/asset_manager.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ std::unique_ptr<fml::Mapping> AssetManager::GetAsMapping(
4747
return nullptr;
4848
}
4949

50+
// |AssetResolver|
51+
std::vector<std::unique_ptr<fml::Mapping>> AssetManager::GetAsMappings(
52+
const std::string& asset_pattern) const {
53+
std::vector<std::unique_ptr<fml::Mapping>> mappings;
54+
if (asset_pattern.size() == 0) {
55+
return mappings;
56+
}
57+
TRACE_EVENT1("flutter", "AssetManager::GetAsMappings", "pattern",
58+
asset_pattern.c_str());
59+
for (const auto& resolver : resolvers_) {
60+
auto resolver_mappings = resolver->GetAsMappings(asset_pattern);
61+
mappings.insert(mappings.end(),
62+
std::make_move_iterator(resolver_mappings.begin()),
63+
std::make_move_iterator(resolver_mappings.end()));
64+
}
65+
return mappings;
66+
}
67+
5068
// |AssetResolver|
5169
bool AssetManager::IsValid() const {
5270
return resolvers_.size() > 0;

assets/asset_manager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class AssetManager final : public AssetResolver {
3232
std::unique_ptr<fml::Mapping> GetAsMapping(
3333
const std::string& asset_name) const override;
3434

35+
// |AssetResolver|
36+
std::vector<std::unique_ptr<fml::Mapping>> GetAsMappings(
37+
const std::string& asset_pattern) const override;
38+
3539
private:
3640
std::deque<std::unique_ptr<AssetResolver>> resolvers_;
3741

assets/asset_resolver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class AssetResolver {
2424
[[nodiscard]] virtual std::unique_ptr<fml::Mapping> GetAsMapping(
2525
const std::string& asset_name) const = 0;
2626

27+
// Same as GetAsMapping() but returns mappings for all files who's name
28+
// matches |pattern|. Returns empty vector if no matching assets are found
29+
[[nodiscard]] virtual std::vector<std::unique_ptr<fml::Mapping>>
30+
GetAsMappings(const std::string& asset_pattern) const = 0;
31+
2732
private:
2833
FML_DISALLOW_COPY_AND_ASSIGN(AssetResolver);
2934
};

assets/directory_asset_bundle.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "flutter/assets/directory_asset_bundle.h"
66

7+
#include <regex>
78
#include <utility>
89

910
#include "flutter/fml/eintr_wrapper.h"
@@ -45,4 +46,32 @@ std::unique_ptr<fml::Mapping> DirectoryAssetBundle::GetAsMapping(
4546
return mapping;
4647
}
4748

49+
std::vector<std::unique_ptr<fml::Mapping>> DirectoryAssetBundle::GetAsMappings(
50+
const std::string& asset_pattern) const {
51+
std::vector<std::unique_ptr<fml::Mapping>> mappings;
52+
if (!is_valid_) {
53+
FML_DLOG(WARNING) << "Asset bundle was not valid.";
54+
return mappings;
55+
}
56+
57+
std::regex asset_regex(asset_pattern);
58+
fml::FileVisitor visitor = [&](const fml::UniqueFD& directory,
59+
const std::string& filename) {
60+
if (std::regex_match(filename, asset_regex)) {
61+
auto mapping = std::make_unique<fml::FileMapping>(fml::OpenFile(
62+
directory, filename.c_str(), false, fml::FilePermission::kRead));
63+
64+
if (mapping && mapping->IsValid()) {
65+
mappings.push_back(std::move(mapping));
66+
} else {
67+
FML_LOG(ERROR) << "Mapping " << filename << " failed";
68+
}
69+
}
70+
return true;
71+
};
72+
fml::VisitFilesRecursively(descriptor_, visitor);
73+
74+
return mappings;
75+
}
76+
4877
} // namespace flutter

assets/directory_asset_bundle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class DirectoryAssetBundle : public AssetResolver {
2929
std::unique_ptr<fml::Mapping> GetAsMapping(
3030
const std::string& asset_name) const override;
3131

32+
// |AssetResolver|
33+
std::vector<std::unique_ptr<fml::Mapping>> GetAsMappings(
34+
const std::string& asset_pattern) const override;
35+
3236
FML_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle);
3337
};
3438

shell/common/persistent_cache.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,14 @@ void PersistentCache::SetAssetManager(std::shared_ptr<AssetManager> value) {
361361
asset_manager_ = value;
362362
}
363363

364+
std::vector<std::unique_ptr<fml::Mapping>>
365+
PersistentCache::GetSkpsFromAssetManager() const {
366+
if (!asset_manager_) {
367+
FML_LOG(ERROR)
368+
<< "PersistentCache::GetSkpsFromAssetManager: Asset manager not set!";
369+
return std::vector<std::unique_ptr<fml::Mapping>>();
370+
}
371+
return asset_manager_->GetAsMappings(".*\\.skp$");
372+
}
373+
364374
} // namespace flutter

shell/common/persistent_cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class PersistentCache : public GrContextOptions::PersistentCache {
6666
/// Load all the SkSL shader caches in the right directory.
6767
std::vector<SkSLCache> LoadSkSLs();
6868

69+
// Return mappings for all skp's accessible through the AssetManager
70+
std::vector<std::unique_ptr<fml::Mapping>> GetSkpsFromAssetManager() const;
71+
6972
/// Set the asset manager from which PersistentCache can load SkLSs. A nullptr
7073
/// can be provided to clear the asset manager.
7174
static void SetAssetManager(std::shared_ptr<AssetManager> value);

shell/platform/fuchsia/flutter/compositor_context.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ CompositorContext::CompositorContext(
7878
std::move(session),
7979
session_error_callback,
8080
[](auto) {},
81-
vsync_event_handle) {}
81+
vsync_event_handle) {
82+
SkISize size = SkISize::Make(1024, 600);
83+
skp_warmup_surface_ = session_connection_.vulkan_surface_producer()->ProduceOffscreenSurface(size);
84+
if (!skp_warmup_surface_) {
85+
FML_LOG(ERROR) << "SkSurface::MakeRenderTarget returned null";
86+
}
87+
}
8288

8389
void CompositorContext::OnSessionMetricsDidChange(
8490
const fuchsia::ui::gfx::Metrics& metrics) {
@@ -131,4 +137,9 @@ CompositorContext::AcquireFrame(
131137
);
132138
}
133139

140+
void CompositorContext::WarmupSkp(const sk_sp<SkPicture> picture) {
141+
skp_warmup_surface_->getCanvas()->drawPicture(picture);
142+
session_connection_.vulkan_surface_producer()->gr_context()->flush();
143+
}
144+
134145
} // namespace flutter_runner

shell/platform/fuchsia/flutter/compositor_context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class CompositorContext final : public flutter::CompositorContext {
3838
void OnCreateView(int64_t view_id, bool hit_testable, bool focusable);
3939
void OnDestroyView(int64_t view_id);
4040

41+
void WarmupSkp(sk_sp<SkPicture> picture);
42+
4143
flutter::ExternalViewEmbedder* GetViewEmbedder() {
4244
return &session_connection_.scene_update_context();
4345
}
@@ -46,6 +48,7 @@ class CompositorContext final : public flutter::CompositorContext {
4648
const std::string debug_label_;
4749
scenic::ViewRefPair view_ref_pair_;
4850
SessionConnection session_connection_;
51+
sk_sp<SkSurface> skp_warmup_surface_;
4952

5053
// |flutter::CompositorContext|
5154
std::unique_ptr<ScopedFrame> AcquireFrame(

shell/platform/fuchsia/flutter/engine.cc

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515
#include "flutter/fml/synchronization/waitable_event.h"
1616
#include "flutter/fml/task_runner.h"
1717
#include "flutter/runtime/dart_vm_lifecycle.h"
18+
#include "flutter/shell/common/persistent_cache.h"
1819
#include "flutter/shell/common/rasterizer.h"
1920
#include "flutter/shell/common/run_configuration.h"
21+
#include "flutter/shell/common/serialization_callbacks.h"
2022
#include "flutter_runner_product_configuration.h"
2123
#include "fuchsia_intl.h"
24+
#include "include/core/SkPicture.h"
25+
#include "include/core/SkSerialProcs.h"
2226
#include "platform_view.h"
2327
#include "runtime/dart/utils/files.h"
2428
#include "task_runner_adapter.h"
@@ -198,34 +202,6 @@ Engine::Engine(Delegate& delegate,
198202
CreateFMLTaskRunner(threads_[2]->dispatcher()) // io
199203
);
200204

201-
// Setup the callback that will instantiate the rasterizer.
202-
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
203-
fml::MakeCopyable([thread_label = thread_label_, //
204-
view_token = std::move(view_token), //
205-
view_ref_pair = std::move(view_ref_pair), //
206-
session = std::move(session), //
207-
on_session_error_callback, //
208-
vsync_event = vsync_event_.get() //
209-
](flutter::Shell& shell) mutable {
210-
std::unique_ptr<flutter_runner::CompositorContext> compositor_context;
211-
{
212-
TRACE_DURATION("flutter", "CreateCompositorContext");
213-
compositor_context =
214-
std::make_unique<flutter_runner::CompositorContext>(
215-
thread_label, // debug label
216-
std::move(view_token), // scenic view we attach our tree to
217-
std::move(view_ref_pair), // scenic view ref/view ref control
218-
std::move(session), // scenic session
219-
on_session_error_callback, // session did encounter error
220-
vsync_event); // vsync event handle
221-
}
222-
223-
return std::make_unique<flutter::Rasterizer>(
224-
/*task_runners=*/shell.GetTaskRunners(),
225-
/*compositor_context=*/std::move(compositor_context),
226-
/*is_gpu_disabled_sync_switch=*/shell.GetIsGpuDisabledSyncSwitch());
227-
});
228-
229205
UpdateNativeThreadLabelNames(thread_label_, task_runners);
230206

231207
settings_.verbose_logging = true;
@@ -247,6 +223,76 @@ Engine::Engine(Delegate& delegate,
247223
});
248224
});
249225

226+
// Launch the engine in the appropriate configuration.
227+
auto run_configuration = flutter::RunConfiguration::InferFromSettings(
228+
settings_, task_runners.GetIOTaskRunner());
229+
230+
// Setup the callback that will instantiate the rasterizer.
231+
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
232+
fml::MakeCopyable([thread_label = thread_label_, //
233+
view_token = std::move(view_token), //
234+
view_ref_pair = std::move(view_ref_pair), //
235+
session = std::move(session), //
236+
on_session_error_callback, //
237+
vsync_event = vsync_event_.get() //
238+
](flutter::Shell& shell) mutable {
239+
std::unique_ptr<flutter_runner::CompositorContext> compositor_context;
240+
{
241+
{
242+
TRACE_DURATION("flutter", "CreateCompositorContext");
243+
compositor_context =
244+
std::make_unique<flutter_runner::CompositorContext>(
245+
thread_label, // debug label
246+
std::move(view_token), // scenic view we attach our tree to
247+
std::move(view_ref_pair), // scenic view ref/view ref control
248+
std::move(session), // scenic session
249+
on_session_error_callback, // session did encounter error
250+
vsync_event); // vsync event handle
251+
}
252+
253+
254+
// tell concurrent task runner to deserialize all skps available from
255+
// the asset manager
256+
shell.GetDartVM()->GetConcurrentMessageLoop()->GetTaskRunner()->PostTask([raster_task_runner =
257+
shell.GetTaskRunners().GetRasterTaskRunner(),
258+
compositor_context = compositor_context.get()]() {
259+
TRACE_DURATION("flutter", "DeserializeSkps");
260+
std::vector<std::unique_ptr<fml::Mapping>> skp_mappings =
261+
flutter::PersistentCache::GetCacheForProcess()
262+
->GetSkpsFromAssetManager();
263+
std::vector<sk_sp<SkPicture>> pictures;
264+
int i = 0;
265+
for (auto& mapping : skp_mappings) {
266+
267+
std::unique_ptr<SkMemoryStream> stream =
268+
SkMemoryStream::MakeDirect(mapping->GetMapping(),
269+
mapping->GetSize());
270+
SkDeserialProcs procs = {0};
271+
procs.fImageProc = flutter::DeserializeImageWithoutData;
272+
procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData;
273+
sk_sp<SkPicture> picture =
274+
SkPicture::MakeFromStream(stream.get(), &procs);
275+
if (!picture) {
276+
FML_LOG(ERROR) << "Failed to deserialize picture " << i++;
277+
continue;
278+
}
279+
280+
// Tell raster task runner to warmup have the compositor
281+
// context warm up the newly deserialized picture
282+
raster_task_runner->PostTask([compositor_context, picture] {
283+
TRACE_DURATION("flutter", "WarmupSkp");
284+
compositor_context->WarmupSkp(picture);
285+
});
286+
}
287+
});
288+
}
289+
290+
return std::make_unique<flutter::Rasterizer>(
291+
/*task_runners=*/shell.GetTaskRunners(),
292+
/*compositor_context=*/std::move(compositor_context),
293+
/*is_gpu_disabled_sync_switch=*/shell.GetIsGpuDisabledSyncSwitch());
294+
});
295+
250296
auto vm = flutter::DartVMRef::Create(settings_);
251297

252298
if (!isolate_snapshot) {
@@ -337,10 +383,6 @@ Engine::Engine(Delegate& delegate,
337383
};
338384
}
339385

340-
// Launch the engine in the appropriate configuration.
341-
auto run_configuration = flutter::RunConfiguration::InferFromSettings(
342-
settings_, task_runners.GetIOTaskRunner());
343-
344386
auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() {
345387
// The engine could have been killed by the caller right after the
346388
// constructor was called but before it could run on the UI thread.

0 commit comments

Comments
 (0)