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.
This commit is contained in:
liyuqian 2019-03-14 12:58:09 -07:00 committed by GitHub
parent 403337ebb8
commit 66fdeb163e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 68 additions and 1 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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_);

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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",

View File

@ -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");
}

View File

@ -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);
}