Add benchmark for loading modules at startup.
This will let us track startup times, and inform decisions on whether
it's worth keeping the Rehydrator system or not.
Change-Id: I4fc52a4d88380d4e396c9fe1138335320eed084d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/585148
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/bench/SkSLBench.cpp b/bench/SkSLBench.cpp
index 2086fc38..e2f15d5 100644
--- a/bench/SkSLBench.cpp
+++ b/bench/SkSLBench.cpp
@@ -12,6 +12,7 @@
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/mock/GrMockCaps.h"
#include "src/sksl/SkSLCompiler.h"
+#include "src/sksl/SkSLModuleLoader.h"
#include "src/sksl/SkSLParser.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/ir/SkSLProgram.h"
@@ -569,3 +570,61 @@
int compilerComputeBinarySize = std::size(SKSL_INCLUDE_sksl_compute);
bench(log, "sksl_binary_size_compute", compilerComputeBinarySize);
}
+
+class SkSLModuleLoaderBench : public Benchmark {
+public:
+ SkSLModuleLoaderBench(const char* name, std::vector<SkSL::ProgramKind> moduleList)
+ : fName(name), fModuleList(std::move(moduleList)) {}
+
+ const char* onGetName() override {
+ return fName;
+ }
+
+ bool isSuitableFor(Backend backend) override {
+ return backend == kNonRendering_Backend;
+ }
+
+ int calculateLoops(int defaultLoops) const override {
+ return 1;
+ }
+
+ void onPreDraw(SkCanvas*) override {
+ SkSL::ModuleLoader::Get().unloadModules();
+ }
+
+ void onDraw(int loops, SkCanvas*) override {
+ SkASSERT(loops == 1);
+ GrShaderCaps caps;
+ SkSL::Compiler compiler(&caps);
+ for (SkSL::ProgramKind kind : fModuleList) {
+ compiler.moduleForProgramKind(kind);
+ }
+ }
+
+ const char* fName;
+ std::vector<SkSL::ProgramKind> fModuleList;
+};
+
+DEF_BENCH(return new SkSLModuleLoaderBench("sksl_module_loader_ganesh",
+ {
+ SkSL::ProgramKind::kVertex,
+ SkSL::ProgramKind::kFragment,
+ SkSL::ProgramKind::kRuntimeColorFilter,
+ SkSL::ProgramKind::kRuntimeShader,
+ SkSL::ProgramKind::kRuntimeBlender,
+ SkSL::ProgramKind::kPrivateRuntimeShader,
+ SkSL::ProgramKind::kCompute,
+ });)
+
+DEF_BENCH(return new SkSLModuleLoaderBench("sksl_module_loader_graphite",
+ {
+ SkSL::ProgramKind::kVertex,
+ SkSL::ProgramKind::kFragment,
+ SkSL::ProgramKind::kRuntimeColorFilter,
+ SkSL::ProgramKind::kRuntimeShader,
+ SkSL::ProgramKind::kRuntimeBlender,
+ SkSL::ProgramKind::kPrivateRuntimeShader,
+ SkSL::ProgramKind::kCompute,
+ SkSL::ProgramKind::kGraphiteVertex,
+ SkSL::ProgramKind::kGraphiteFragment,
+ });)
diff --git a/src/sksl/SkSLModuleLoader.cpp b/src/sksl/SkSLModuleLoader.cpp
index ea840ad..c44ba3b 100644
--- a/src/sksl/SkSLModuleLoader.cpp
+++ b/src/sksl/SkSLModuleLoader.cpp
@@ -157,6 +157,18 @@
fModuleLoader.fMutex.release();
}
+void ModuleLoader::unloadModules() {
+ fModuleLoader.fSharedModule = ParsedModule{};
+ fModuleLoader.fGPUModule = ParsedModule{};
+ fModuleLoader.fVertexModule = ParsedModule{};
+ fModuleLoader.fFragmentModule = ParsedModule{};
+ fModuleLoader.fComputeModule = ParsedModule{};
+ fModuleLoader.fGraphiteVertexModule = ParsedModule{};
+ fModuleLoader.fGraphiteFragmentModule = ParsedModule{};
+ fModuleLoader.fPublicModule = ParsedModule{};
+ fModuleLoader.fRuntimeShaderModule = ParsedModule{};
+}
+
ModuleLoader::Impl::Impl() {
this->makeRootSymbolTable();
}
diff --git a/src/sksl/SkSLModuleLoader.h b/src/sksl/SkSLModuleLoader.h
index 3877665..5a5dc35 100644
--- a/src/sksl/SkSLModuleLoader.h
+++ b/src/sksl/SkSLModuleLoader.h
@@ -58,6 +58,9 @@
const ParsedModule& loadPublicModule(SkSL::Compiler* compiler);
const ParsedModule& loadPrivateRTShaderModule(SkSL::Compiler* compiler);
+
+ // This unloads every module. It's useful primarily for benchmarking purposes.
+ void unloadModules();
};
} // namespace SkSL