summaryrefslogtreecommitdiff
path: root/libs/hwui/tests/unit/ShaderCacheTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/tests/unit/ShaderCacheTests.cpp')
-rw-r--r--libs/hwui/tests/unit/ShaderCacheTests.cpp143
1 files changed, 127 insertions, 16 deletions
diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp
index 43080a9460b3..1433aa0349f4 100644
--- a/libs/hwui/tests/unit/ShaderCacheTests.cpp
+++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp
@@ -48,11 +48,18 @@ public:
*/
static void terminate(ShaderCache& cache, bool saveContent) {
std::lock_guard<std::mutex> lock(cache.mMutex);
- if (cache.mInitialized && cache.mBlobCache && saveContent) {
- cache.mBlobCache->writeToFile();
- }
+ cache.mSavePending = saveContent;
+ cache.saveToDiskLocked();
cache.mBlobCache = NULL;
}
+
+ /**
+ *
+ */
+ template <typename T>
+ static bool validateCache(ShaderCache& cache, std::vector<T> hash) {
+ return cache.validateCache(hash.data(), hash.size() * sizeof(T));
+ }
};
} /* namespace skiapipeline */
@@ -75,26 +82,39 @@ bool folderExist(const std::string& folderName) {
return false;
}
-bool checkShader(const sk_sp<SkData>& shader, const char* program) {
+inline bool
+checkShader(const sk_sp<SkData>& shader1, const sk_sp<SkData>& shader2) {
+ return nullptr != shader1 && nullptr != shader2 && shader1->size() == shader2->size()
+ && 0 == memcmp(shader1->data(), shader2->data(), shader1->size());
+}
+
+inline bool
+checkShader(const sk_sp<SkData>& shader, const char* program) {
sk_sp<SkData> shader2 = SkData::MakeWithCString(program);
- return shader->size() == shader2->size()
- && 0 == memcmp(shader->data(), shader2->data(), shader->size());
+ return checkShader(shader, shader2);
}
-bool checkShader(const sk_sp<SkData>& shader, std::vector<char>& program) {
- sk_sp<SkData> shader2 = SkData::MakeWithCopy(program.data(), program.size());
- return shader->size() == shader2->size()
- && 0 == memcmp(shader->data(), shader2->data(), shader->size());
+template <typename T>
+bool checkShader(const sk_sp<SkData>& shader, std::vector<T>& program) {
+ sk_sp<SkData> shader2 = SkData::MakeWithCopy(program.data(), program.size() * sizeof(T));
+ return checkShader(shader, shader2);
}
void setShader(sk_sp<SkData>& shader, const char* program) {
shader = SkData::MakeWithCString(program);
}
-void setShader(sk_sp<SkData>& shader, std::vector<char>& program) {
- shader = SkData::MakeWithCopy(program.data(), program.size());
+template <typename T>
+void setShader(sk_sp<SkData>& shader, std::vector<T>& buffer) {
+ shader = SkData::MakeWithCopy(buffer.data(), buffer.size() * sizeof(T));
}
+template <typename T>
+void genRandomData(std::vector<T>& buffer) {
+ for (auto& data : buffer) {
+ data = T(std::rand());
+ }
+}
#define GrProgramDescTest(a) (*SkData::MakeWithCString(#a).get())
@@ -110,6 +130,7 @@ TEST(ShaderCacheTest, testWriteAndRead) {
//remove any test files from previous test run
int deleteFile = remove(cacheFile1.c_str());
ASSERT_TRUE(0 == deleteFile || ENOENT == errno);
+ std::srand(0);
//read the cache from a file that does not exist
ShaderCache::get().setFilename(cacheFile1.c_str());
@@ -158,10 +179,8 @@ TEST(ShaderCacheTest, testWriteAndRead) {
//write and read big data chunk (50K)
size_t dataSize = 50*1024;
- std::vector<char> dataBuffer(dataSize);
- for (size_t i = 0; i < dataSize; i++) {
- dataBuffer[0] = dataSize % 256;
- }
+ std::vector<uint8_t> dataBuffer(dataSize);
+ genRandomData(dataBuffer);
setShader(inVS, dataBuffer);
ShaderCache::get().store(GrProgramDescTest(432), *inVS.get());
ShaderCacheTestUtils::terminate(ShaderCache::get(), true);
@@ -173,4 +192,96 @@ TEST(ShaderCacheTest, testWriteAndRead) {
remove(cacheFile1.c_str());
}
+TEST(ShaderCacheTest, testCacheValidation) {
+ if (!folderExist(getExternalStorageFolder())) {
+ //don't run the test if external storage folder is not available
+ return;
+ }
+ std::string cacheFile1 = getExternalStorageFolder() + "/shaderCacheTest1";
+ std::string cacheFile2 = getExternalStorageFolder() + "/shaderCacheTest2";
+
+ //remove any test files from previous test run
+ int deleteFile = remove(cacheFile1.c_str());
+ ASSERT_TRUE(0 == deleteFile || ENOENT == errno);
+ std::srand(0);
+
+ //generate identity and read the cache from a file that does not exist
+ ShaderCache::get().setFilename(cacheFile1.c_str());
+ ShaderCacheTestUtils::setSaveDelay(ShaderCache::get(), 0); //disable deferred save
+ std::vector<uint8_t> identity(1024);
+ genRandomData(identity);
+ ShaderCache::get().initShaderDiskCache(identity.data(), identity.size() *
+ sizeof(decltype(identity)::value_type));
+
+ // generate random content in cache and store to disk
+ constexpr size_t numBlob(10);
+ constexpr size_t keySize(1024);
+ constexpr size_t dataSize(50 * 1024);
+
+ std::vector< std::pair<sk_sp<SkData>, sk_sp<SkData>> > blobVec(numBlob);
+ for (auto& blob : blobVec) {
+ std::vector<uint8_t> keyBuffer(keySize);
+ std::vector<uint8_t> dataBuffer(dataSize);
+ genRandomData(keyBuffer);
+ genRandomData(dataBuffer);
+
+ sk_sp<SkData> key, data;
+ setShader(key, keyBuffer);
+ setShader(data, dataBuffer);
+
+ blob = std::make_pair(key, data);
+ ShaderCache::get().store(*key.get(), *data.get());
+ }
+ ShaderCacheTestUtils::terminate(ShaderCache::get(), true);
+
+ // change to a file that does not exist and verify validation fails
+ ShaderCache::get().setFilename(cacheFile2.c_str());
+ ShaderCache::get().initShaderDiskCache();
+ ASSERT_FALSE( ShaderCacheTestUtils::validateCache(ShaderCache::get(), identity) );
+ ShaderCacheTestUtils::terminate(ShaderCache::get(), false);
+
+ // restore the original file and verify validation succeeds
+ ShaderCache::get().setFilename(cacheFile1.c_str());
+ ShaderCache::get().initShaderDiskCache(identity.data(), identity.size() *
+ sizeof(decltype(identity)::value_type));
+ ASSERT_TRUE( ShaderCacheTestUtils::validateCache(ShaderCache::get(), identity) );
+ for (const auto& blob : blobVec) {
+ auto outVS = ShaderCache::get().load(*blob.first.get());
+ ASSERT_TRUE( checkShader(outVS, blob.second) );
+ }
+
+ // generate error identity and verify load fails
+ ShaderCache::get().initShaderDiskCache(identity.data(), -1);
+ for (const auto& blob : blobVec) {
+ ASSERT_EQ( ShaderCache::get().load(*blob.first.get()), sk_sp<SkData>() );
+ }
+ ShaderCache::get().initShaderDiskCache(nullptr, identity.size() *
+ sizeof(decltype(identity)::value_type));
+ for (const auto& blob : blobVec) {
+ ASSERT_EQ( ShaderCache::get().load(*blob.first.get()), sk_sp<SkData>() );
+ }
+
+ // verify the cache validation again after load fails
+ ShaderCache::get().initShaderDiskCache(identity.data(), identity.size() *
+ sizeof(decltype(identity)::value_type));
+ ASSERT_TRUE( ShaderCacheTestUtils::validateCache(ShaderCache::get(), identity) );
+ for (const auto& blob : blobVec) {
+ auto outVS = ShaderCache::get().load(*blob.first.get());
+ ASSERT_TRUE( checkShader(outVS, blob.second) );
+ }
+
+ // generate another identity and verify load fails
+ for (auto& data : identity) {
+ data += std::rand();
+ }
+ ShaderCache::get().initShaderDiskCache(identity.data(), identity.size() *
+ sizeof(decltype(identity)::value_type));
+ for (const auto& blob : blobVec) {
+ ASSERT_EQ( ShaderCache::get().load(*blob.first.get()), sk_sp<SkData>() );
+ }
+
+ ShaderCacheTestUtils::terminate(ShaderCache::get(), false);
+ remove(cacheFile1.c_str());
+}
+
} // namespace