SkiaGLRE caching: monitor the caching of shaders
Bug: 178661709
Test: adb shell setprop debug.renderengine.backend skiagl
adb shell stop && adb shell start
adb shell dumpsys SurfaceFlinger
Add an implementation of PersistentCache that allows us to monitor
whether a shader was generated when we expected one to be. This can be
repurposed in the future (i.e. once we've generated all the shaders we
expect) to verify that we do *not* generate shaders after primeCache
finishes.
Add the number of recently cached shaders (i.e. since the last call, or
primeCache, if this is the first call) to the output of dumpsys.
Change-Id: I6f177b7ad78fef166d529e918447395629673f47
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 4fdae74..f8dd7f5 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -55,6 +55,7 @@
// generate the slower (more general case) version. If we also need a
// slow version without color correction, we should use this matrix with
// display.outputDataspace set to SRGB.
+ bool identity = true;
for (const mat4 transform : { mat4(), mat4(0.728872f, 0.f, 0.f, 0.f,
0.f, 0.727627f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
@@ -62,6 +63,8 @@
layer.geometry.positionTransform = transform;
renderengine->drawLayers(display, layers, dstBuffer, false /* useFrameBufferCache*/,
base::unique_fd(), nullptr);
+ renderengine->assertShadersCompiled(identity ? 1 : 2);
+ identity = false;
}
}
@@ -105,6 +108,7 @@
renderengine->drawLayers(display, layers, dstBuffer,
false /* useFrameBufferCache*/, base::unique_fd(),
nullptr);
+ renderengine->assertShadersCompiled(1);
}
}
}
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index afdcd76..7d711c1 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -268,6 +268,23 @@
return config;
}
+sk_sp<SkData> SkiaGLRenderEngine::SkSLCacheMonitor::load(const SkData& key) {
+ // This "cache" does not actually cache anything. It just allows us to
+ // monitor Skia's internal cache. So this method always returns null.
+ return nullptr;
+}
+
+void SkiaGLRenderEngine::SkSLCacheMonitor::store(const SkData& key, const SkData& data,
+ const SkString& description) {
+ mShadersCachedSinceLastCall++;
+}
+
+void SkiaGLRenderEngine::assertShadersCompiled(int numShaders) {
+ const int cached = mSkSLCacheMonitor.shadersCachedSinceLastCall();
+ LOG_ALWAYS_FATAL_IF(cached != numShaders, "Attempted to cache %i shaders; cached %i",
+ numShaders, cached);
+}
+
SkiaGLRenderEngine::SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display,
EGLContext ctxt, EGLSurface placeholder,
EGLContext protectedContext, EGLSurface protectedPlaceholder)
@@ -284,6 +301,7 @@
GrContextOptions options;
options.fPreferExternalImagesOverES3 = true;
options.fDisableDistanceFieldPaths = true;
+ options.fPersistentCache = &mSkSLCacheMonitor;
mGrContext = GrDirectContext::MakeGL(glInterface, options);
if (useProtectedContext(true)) {
mProtectedGrContext = GrDirectContext::MakeGL(glInterface, options);
@@ -1168,6 +1186,8 @@
StringAppendF(&result, "RenderEngine supports protected context: %d\n",
supportsProtectedContent());
StringAppendF(&result, "RenderEngine is in protected context: %d\n", mInProtectedContext);
+ StringAppendF(&result, "RenderEngine shaders cached since last dump/primeCache: %d\n",
+ mSkSLCacheMonitor.shadersCachedSinceLastCall());
{
std::lock_guard<std::mutex> lock(mRenderingMutex);
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 15d834d..7605df9 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -31,6 +31,7 @@
#include "AutoBackendTexture.h"
#include "EGL/egl.h"
+#include "GrContextOptions.h"
#include "SkImageInfo.h"
#include "SkiaRenderEngine.h"
#include "android-base/macros.h"
@@ -63,6 +64,7 @@
bool supportsProtectedContent() const override;
bool useProtectedContext(bool useProtectedContext) override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
+ void assertShadersCompiled(int numShaders) override;
protected:
void dump(std::string& result) override;
@@ -131,6 +133,29 @@
bool mInProtectedContext = false;
// Object to capture commands send to Skia.
std::unique_ptr<SkiaCapture> mCapture;
+
+ // Implements PersistentCache as a way to monitor what SkSL shaders Skia has
+ // cached.
+ class SkSLCacheMonitor : public GrContextOptions::PersistentCache {
+ public:
+ SkSLCacheMonitor() = default;
+ ~SkSLCacheMonitor() override = default;
+
+ sk_sp<SkData> load(const SkData& key) override;
+
+ void store(const SkData& key, const SkData& data, const SkString& description) override;
+
+ int shadersCachedSinceLastCall() {
+ const int shadersCachedSinceLastCall = mShadersCachedSinceLastCall;
+ mShadersCachedSinceLastCall = 0;
+ return shadersCachedSinceLastCall;
+ }
+
+ private:
+ int mShadersCachedSinceLastCall = 0;
+ };
+
+ SkSLCacheMonitor mSkSLCacheMonitor;
};
} // namespace skia
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index f403725..59d7e2f 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -58,6 +58,7 @@
};
virtual bool cleanupPostRender(CleanupMode) override { return true; };
virtual int getContextPriority() override { return 0; }
+ virtual void assertShadersCompiled(int numShaders) {}
};
} // namespace skia