-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wire up Metal shader precompilation from offline training runs. #25644
Wire up Metal shader precompilation from offline training runs. #25644
Conversation
This commit depends on [Skia support for Metal SKSL precompilation][1]. When a new Metal onscreen context is acquired, the engine will attempt to load shaders stored in the `io.flutter.shaders.json` file packaged in the Flutter asset bundle. This file can be [obtained via offline training runs][2]. This works very similarly to the OpenGL backend. However, in the OpenGL backend, shell initialization waits for precompilation to be completed. On the other hand, in the Metal backend, precompilation happens immediately after shell initialization. This is in an attempt to parallelize SKSL precompilation with Dart isolate and framework setup. While it may be possible to parallelize precompilation of SKSLs in the future, they are processed serially today. Support for testing shells (that hold the Skia persistent cache) using the Metal backend did not exist and has been added in this patch. However, I don't believe this testing is sufficient because it only verifies that SKSLs can be dumped and subsequently reused with a Metal backed Shell. Importantly, it doesn't verify where is shell setup this precompilation happens. For that, the persistent cache interface will need to be reworked to better fit with the shell unittests. I considered it out of scope and will followup with those test updates in a later patch. I have also made tracing of precompilation consistent with OpenGL and Metal (and Vulkan when support for that is added). The `PersistentCache::PrecompileKnownSKSLs` trace will summarize the number of SKSLs being precompiled (it is a counter trace) and the time taken to precompile each. Fixes flutter/flutter#79298. [1]: https://bugs.chromium.org/p/skia/issues/detail?id=11392 [2]: https://flutter.dev/docs/perf/rendering/shader#how-to-use-sksl-warmup
common/graphics/persistent_cache.cc
Outdated
return 0; | ||
} | ||
|
||
if (known_sksls.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is harmless but redundant. The loop will do nothing if there are no shaders.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
common/graphics/persistent_cache.h
Outdated
|
||
//---------------------------------------------------------------------------- | ||
/// @brief Precompile SKSLs packaged with the application and gathered | ||
/// during during previous runs in the given context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "during during"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
TEST_F(ShellTest, CacheSkSLWorks) { | ||
static void WaitForRaster(Shell* shell) { | ||
std::promise<bool> raster_task_finished; | ||
shell->GetTaskRunners().GetIOTaskRunner()->PostTask( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be GetRasterTaskRunner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof. Good catch. I added this to prevent a potential race.
} | ||
return true; | ||
}; | ||
fml::VisitFiles(dir.fd(), remove_visitor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can fml::RemoveFilesInDirectory
be used here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right. I just copied the test right above this one which was probably written before the utility was available. Updated both.
shell/gpu/gpu_surface_metal.mm
Outdated
@@ -155,6 +168,10 @@ | |||
|
|||
// |Surface| | |||
std::unique_ptr<GLContextResult> GPUSurfaceMetal::MakeRenderContextCurrent() { | |||
// A context may be either be necessary to render to the surface or to snapshot an offscreen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "be either be"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
common/graphics/persistent_cache.cc
Outdated
@@ -191,7 +192,35 @@ sk_sp<SkData> ParseBase64(const std::string& input) { | |||
return data; | |||
} | |||
|
|||
std::vector<PersistentCache::SkSLCache> PersistentCache::LoadSkSLs() { | |||
size_t PersistentCache::PrecompileKnownSKSLs(GrDirectContext* context) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Skia and elsewhere in the engine the spelling is "SkSL". I would prefer using that spelling in this PR for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger. I gsubbed all instances in //flutter for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed all comments. PTAL. The presubmit failures were because I had assumed that GL emulation was available everywhere. This is not the case of Fuchsia. Fixed licenses which seem to be including test files as well 🤷🏽 .
common/graphics/persistent_cache.cc
Outdated
@@ -191,7 +192,35 @@ sk_sp<SkData> ParseBase64(const std::string& input) { | |||
return data; | |||
} | |||
|
|||
std::vector<PersistentCache::SkSLCache> PersistentCache::LoadSkSLs() { | |||
size_t PersistentCache::PrecompileKnownSKSLs(GrDirectContext* context) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger. I gsubbed all instances in //flutter for consistency.
common/graphics/persistent_cache.cc
Outdated
return 0; | ||
} | ||
|
||
if (known_sksls.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
common/graphics/persistent_cache.h
Outdated
|
||
//---------------------------------------------------------------------------- | ||
/// @brief Precompile SKSLs packaged with the application and gathered | ||
/// during during previous runs in the given context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
TEST_F(ShellTest, CacheSkSLWorks) { | ||
static void WaitForRaster(Shell* shell) { | ||
std::promise<bool> raster_task_finished; | ||
shell->GetTaskRunners().GetIOTaskRunner()->PostTask( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof. Good catch. I added this to prevent a potential race.
} | ||
return true; | ||
}; | ||
fml::VisitFiles(dir.fd(), remove_visitor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right. I just copied the test right above this one which was probably written before the utility was available. Updated both.
shell/gpu/gpu_surface_metal.mm
Outdated
@@ -155,6 +168,10 @@ | |||
|
|||
// |Surface| | |||
std::unique_ptr<GLContextResult> GPUSurfaceMetal::MakeRenderContextCurrent() { | |||
// A context may be either be necessary to render to the surface or to snapshot an offscreen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@chinmaygarde to use this we just need to use the same as under OpenGL with |
Right. The workflow is identical. |
Thanks @chinmaygarde - just to confirm, the latest master has it?
|
@acoutts, @chinmaygarde's flutter/engine commit is still making its way into flutter/flutter master. It's not there yet. flutter/flutter#80769 looks like it will succeed when the flutter/flutter tree turns green. |
This commit depends on Skia support for Metal SKSL precompilation.
When a new Metal onscreen context is acquired, the engine will attempt to load
shaders stored in the
io.flutter.shaders.json
file packaged in the Flutterasset bundle. This file can be obtained via offline training runs.
This works very similarly to the OpenGL backend. However, in the OpenGL backend,
shell initialization waits for precompilation to be completed. On the other
hand, in the Metal backend, precompilation happens immediately after shell
initialization. This is in an attempt to parallelize SKSL precompilation with
Dart isolate and framework setup. While it may be possible to parallelize
precompilation of SKSLs in the future, they are processed serially today.
Support for testing shells (that hold the Skia persistent cache) using the Metal
backend did not exist and has been added in this patch. However, I don't believe
this testing is sufficient because it only verifies that SKSLs can be dumped and
subsequently reused with a Metal backed Shell. Importantly, it doesn't verify
where is shell setup this precompilation happens. For that, the persistent cache
interface will need to be reworked to better fit with the shell unittests. I
considered it out of scope and will followup with those test updates in a later
patch.
I have also made tracing of precompilation consistent with OpenGL and Metal (and
Vulkan when support for that is added). The
PersistentCache::PrecompileKnownSKSLs
trace will summarize the number of SKSLsbeing precompiled (it is a counter trace) and the time taken to precompile each.
Fixes flutter/flutter#79298.
These traces show that precompilation is functional and occurs during application launch.
