未验证 提交 66fdeb16 编写于 作者: L liyuqian 提交者: GitHub

Add dump-shader-skp switch to help ShaderWarmUp (#8148)

Allow Flutter to automatically dump the skp that triggers new shader compilations. This is useful for writing custom ShaderWarmUp to reduce jank. By default, it's not enabled to reduce the overhead. This is only available in profile or debug build.

Later, we can add service protocol support to pull the skp from the client to the host. Currently, it works fine for Android-based devices (including our urgent internal clients) where we can `adb shell` into the cache directory.
上级 403337eb
......@@ -33,6 +33,9 @@ std::string Settings::ToString() const {
stream << "start_paused: " << start_paused << std::endl;
stream << "trace_skia: " << trace_skia << std::endl;
stream << "trace_startup: " << trace_startup << std::endl;
stream << "trace_systrace: " << trace_systrace << std::endl;
stream << "dump_skp_on_shader_compilation: " << dump_skp_on_shader_compilation
<< std::endl;
stream << "endless_trace_buffer: " << endless_trace_buffer << std::endl;
stream << "enable_dart_profiling: " << enable_dart_profiling << std::endl;
stream << "disable_dart_asserts: " << disable_dart_asserts << std::endl;
......
......@@ -64,6 +64,7 @@ struct Settings {
bool trace_skia = false;
bool trace_startup = false;
bool trace_systrace = false;
bool dump_skp_on_shader_compilation = false;
bool endless_trace_buffer = false;
bool enable_dart_profiling = false;
bool disable_dart_asserts = false;
......
......@@ -134,6 +134,8 @@ static void PersistentCacheStore(fml::RefPtr<fml::TaskRunner> worker,
// |GrContextOptions::PersistentCache|
void PersistentCache::store(const SkData& key, const SkData& data) {
stored_new_shaders_ = true;
if (is_read_only_) {
return;
}
......@@ -159,6 +161,24 @@ void PersistentCache::store(const SkData& key, const SkData& data) {
std::move(file_name), std::move(mapping));
}
void PersistentCache::DumpSkp(const SkData& data) {
if (is_read_only_ || !IsValid()) {
FML_LOG(ERROR) << "Could not dump SKP from read-only or invalid persistent "
"cache.";
return;
}
std::stringstream name_stream;
auto ticks = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds();
name_stream << "shader_dump_" << std::to_string(ticks) << ".skp";
std::string file_name = name_stream.str();
FML_LOG(ERROR) << "Dumping " << file_name;
auto mapping = std::make_unique<fml::DataMapping>(
std::vector<uint8_t>{data.bytes(), data.bytes() + data.size()});
PersistentCacheStore(GetWorkerTaskRunner(), cache_directory_,
std::move(file_name), std::move(mapping));
}
void PersistentCache::AddWorkerTaskRunner(
fml::RefPtr<fml::TaskRunner> task_runner) {
std::lock_guard<std::mutex> lock(worker_task_runners_mutex_);
......
......@@ -36,6 +36,15 @@ class PersistentCache : public GrContextOptions::PersistentCache {
void RemoveWorkerTaskRunner(fml::RefPtr<fml::TaskRunner> task_runner);
// Whether Skia tries to store any shader into this persistent cache after
// |ResetStoredNewShaders| is called. This flag is usually reset before each
// frame so we can know if Skia tries to compile new shaders in that frame.
bool StoredNewShaders() const { return stored_new_shaders_; }
void ResetStoredNewShaders() { stored_new_shaders_ = false; }
void DumpSkp(const SkData& data);
bool IsDumpingSkp() const { return is_dumping_skp_; }
void SetIsDumpingSkp(bool value) { is_dumping_skp_ = value; }
private:
static std::string cache_base_path_;
......@@ -45,6 +54,9 @@ class PersistentCache : public GrContextOptions::PersistentCache {
std::multiset<fml::RefPtr<fml::TaskRunner>> worker_task_runners_
FML_GUARDED_BY(worker_task_runners_mutex_);
bool stored_new_shaders_ = false;
bool is_dumping_skp_ = false;
bool IsValid() const;
PersistentCache(bool read_only = false);
......
......@@ -4,6 +4,8 @@
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/persistent_cache.h"
#include <utility>
#include "third_party/skia/include/core/SkEncodedImageFormat.h"
......@@ -150,9 +152,19 @@ void Rasterizer::DoDraw(std::unique_ptr<flow::LayerTree> layer_tree) {
return;
}
PersistentCache* persistent_cache = PersistentCache::GetCacheForProcess();
persistent_cache->ResetStoredNewShaders();
if (DrawToSurface(*layer_tree)) {
last_layer_tree_ = std::move(layer_tree);
}
if (persistent_cache->IsDumpingSkp() &&
persistent_cache->StoredNewShaders()) {
auto screenshot =
ScreenshotLastLayerTree(ScreenshotType::SkiaPicture, false);
persistent_cache->DumpSkp(*screenshot.data);
}
}
bool Rasterizer::DrawToSurface(flow::LayerTree& layer_tree) {
......
......@@ -382,6 +382,9 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
task_runners_.GetIOTaskRunner());
PersistentCache::GetCacheForProcess()->SetIsDumpingSkp(
settings_.dump_skp_on_shader_compilation);
return true;
}
......
......@@ -276,6 +276,9 @@ blink::Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
command_line.HasOption(FlagForSwitch(Switch::TraceSystrace));
#endif
settings.dump_skp_on_shader_compilation =
command_line.HasOption(FlagForSwitch(Switch::DumpSkpOnShaderCompilation));
return settings;
}
......
......@@ -109,8 +109,13 @@ DEF_SWITCH(TraceStartup,
DEF_SWITCH(TraceSkia,
"trace-skia",
"Trace Skia calls. This is useful when debugging the GPU threed."
"By default, Skia tracing is not enable to reduce the number of "
"By default, Skia tracing is not enabled to reduce the number of "
"traced events")
DEF_SWITCH(DumpSkpOnShaderCompilation,
"dump-skp-on-shader-compilation",
"Automatically dump the skp that triggers new shader compilations. "
"This is useful for writing custom ShaderWarmUp to reduce jank. "
"By default, this is not enabled to reduce the overhead. ")
DEF_SWITCH(
TraceSystrace,
"trace-systrace",
......
......@@ -315,6 +315,9 @@ public final class FlutterActivityDelegate
if (intent.getBooleanExtra("trace-systrace", false)) {
args.add("--trace-systrace");
}
if (intent.getBooleanExtra("dump-skp-on-shader-compilation", false)) {
args.add("--dump-skp-on-shader-compilation");
}
if (intent.getBooleanExtra("verbose-logging", false)) {
args.add("--verbose-logging");
}
......
......@@ -37,6 +37,8 @@ public class FlutterShellArgs {
public static final String ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering";
public static final String ARG_KEY_TRACE_SKIA = "trace-skia";
public static final String ARG_TRACE_SKIA = "--trace-skia";
public static final String ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = "dump-skp-on-shader-compilation";
public static final String ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = "--dump-skp-on-shader-compilation";
public static final String ARG_KEY_VERBOSE_LOGGING = "verbose-logging";
public static final String ARG_VERBOSE_LOGGING = "--verbose-logging";
......@@ -69,6 +71,9 @@ public class FlutterShellArgs {
if (intent.getBooleanExtra(ARG_KEY_TRACE_SKIA, false)) {
args.add(ARG_TRACE_SKIA);
}
if (intent.getBooleanExtra(ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION, false)) {
args.add(ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION);
}
if (intent.getBooleanExtra(ARG_KEY_VERBOSE_LOGGING, false)) {
args.add(ARG_VERBOSE_LOGGING);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册