summaryrefslogtreecommitdiff
path: root/libs/hwui/pipeline/skia/ShaderCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/pipeline/skia/ShaderCache.cpp')
-rw-r--r--libs/hwui/pipeline/skia/ShaderCache.cpp56
1 files changed, 50 insertions, 6 deletions
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index 670074871c71..073b4814305e 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -18,6 +18,8 @@
#include <algorithm>
#include <log/log.h>
#include <thread>
+#include <array>
+#include <openssl/sha.h>
#include "FileBlobCache.h"
#include "Properties.h"
#include "utils/TraceUtils.h"
@@ -41,7 +43,40 @@ ShaderCache& ShaderCache::get() {
return sCache;
}
-void ShaderCache::initShaderDiskCache() {
+bool ShaderCache::validateCache(const void* identity, ssize_t size) {
+ if (nullptr == identity && size == 0)
+ return true;
+
+ if (nullptr == identity || size < 0) {
+ if (CC_UNLIKELY(Properties::debugLevel & kDebugCaches)) {
+ ALOGW("ShaderCache::validateCache invalid cache identity");
+ }
+ mBlobCache->clear();
+ return false;
+ }
+
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+
+ SHA256_Update(&ctx, identity, size);
+ mIDHash.resize(SHA256_DIGEST_LENGTH);
+ SHA256_Final(mIDHash.data(), &ctx);
+
+ std::array<uint8_t, SHA256_DIGEST_LENGTH> hash;
+ auto key = sIDKey;
+ auto loaded = mBlobCache->get(&key, sizeof(key), hash.data(), hash.size());
+
+ if (loaded && std::equal(hash.begin(), hash.end(), mIDHash.begin()))
+ return true;
+
+ if (CC_UNLIKELY(Properties::debugLevel & kDebugCaches)) {
+ ALOGW("ShaderCache::validateCache cache validation fails");
+ }
+ mBlobCache->clear();
+ return false;
+}
+
+void ShaderCache::initShaderDiskCache(const void* identity, ssize_t size) {
ATRACE_NAME("initShaderDiskCache");
std::lock_guard<std::mutex> lock(mMutex);
@@ -50,6 +85,7 @@ void ShaderCache::initShaderDiskCache() {
// desktop / laptop GPUs. Thus, disable the shader disk cache for emulator builds.
if (!Properties::runningInEmulator && mFilename.length() > 0) {
mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename));
+ validateCache(identity, size);
mInitialized = true;
}
}
@@ -104,6 +140,18 @@ sk_sp<SkData> ShaderCache::load(const SkData& key) {
return SkData::MakeFromMalloc(valueBuffer, valueSize);
}
+void ShaderCache::saveToDiskLocked() {
+ ATRACE_NAME("ShaderCache::saveToDiskLocked");
+ if (mInitialized && mBlobCache && mSavePending) {
+ if (mIDHash.size()) {
+ auto key = sIDKey;
+ mBlobCache->set(&key, sizeof(key), mIDHash.data(), mIDHash.size());
+ }
+ mBlobCache->writeToFile();
+ }
+ mSavePending = false;
+}
+
void ShaderCache::store(const SkData& key, const SkData& data) {
ATRACE_NAME("ShaderCache::store");
std::lock_guard<std::mutex> lock(mMutex);
@@ -129,11 +177,7 @@ void ShaderCache::store(const SkData& key, const SkData& data) {
std::thread deferredSaveThread([this]() {
sleep(mDeferredSaveDelay);
std::lock_guard<std::mutex> lock(mMutex);
- ATRACE_NAME("ShaderCache::saveToDisk");
- if (mInitialized && mBlobCache) {
- mBlobCache->writeToFile();
- }
- mSavePending = false;
+ saveToDiskLocked();
});
deferredSaveThread.detach();
}