diff options
| -rw-r--r-- | opengl/libs/EGL/MultifileBlobCache.cpp | 23 | ||||
| -rw-r--r-- | opengl/libs/EGL/MultifileBlobCache.h | 2 | ||||
| -rw-r--r-- | opengl/tests/EGLTest/egl_cache_test.cpp | 59 |
3 files changed, 66 insertions, 18 deletions
diff --git a/opengl/libs/EGL/MultifileBlobCache.cpp b/opengl/libs/EGL/MultifileBlobCache.cpp index f1b7a5c064..1c0c045bb4 100644 --- a/opengl/libs/EGL/MultifileBlobCache.cpp +++ b/opengl/libs/EGL/MultifileBlobCache.cpp @@ -267,7 +267,7 @@ void MultifileBlobCache::set(const void* key, EGLsizeiANDROID keySize, const voi // If we're going to be over the cache limit, kick off a trim to clear space if (getTotalSize() + fileSize > mMaxTotalSize) { ALOGV("SET: Cache is full, calling trimCache to clear space"); - trimCache(mMaxTotalSize); + trimCache(); } ALOGV("SET: Add %u to cache", entryHash); @@ -589,7 +589,7 @@ bool MultifileBlobCache::applyLRU(size_t cacheLimit) { } } - ALOGV("LRU: Cache is emptry"); + ALOGV("LRU: Cache is empty"); return false; } @@ -598,24 +598,15 @@ bool MultifileBlobCache::applyLRU(size_t cacheLimit) { constexpr uint32_t kCacheLimitDivisor = 2; // Calculate the cache size and remove old entries until under the limit -void MultifileBlobCache::trimCache(size_t cacheByteLimit) { - // Start with the value provided by egl_cache - size_t limit = cacheByteLimit; - +void MultifileBlobCache::trimCache() { // Wait for all deferred writes to complete ALOGV("TRIM: Waiting for work to complete."); waitForWorkComplete(); - size_t size = getTotalSize(); - - // If size is larger than the threshold, remove files using LRU - if (size > limit) { - ALOGV("TRIM: Multifile cache size is larger than %zu, removing old entries", - cacheByteLimit); - if (!applyLRU(limit / kCacheLimitDivisor)) { - ALOGE("Error when clearing multifile shader cache"); - return; - } + ALOGV("TRIM: Reducing multifile cache size to %zu", mMaxTotalSize / kCacheLimitDivisor); + if (!applyLRU(mMaxTotalSize / kCacheLimitDivisor)) { + ALOGE("Error when clearing multifile shader cache"); + return; } } diff --git a/opengl/libs/EGL/MultifileBlobCache.h b/opengl/libs/EGL/MultifileBlobCache.h index b461ef4fc6..f266011fda 100644 --- a/opengl/libs/EGL/MultifileBlobCache.h +++ b/opengl/libs/EGL/MultifileBlobCache.h @@ -119,7 +119,7 @@ private: bool addToHotCache(uint32_t entryHash, int fd, uint8_t* entryBufer, size_t entrySize); bool removeFromHotCache(uint32_t entryHash); - void trimCache(size_t cacheByteLimit); + void trimCache(); bool applyLRU(size_t cacheLimit); bool mInitialized; diff --git a/opengl/tests/EGLTest/egl_cache_test.cpp b/opengl/tests/EGLTest/egl_cache_test.cpp index ff4022cfe5..f81c68f66e 100644 --- a/opengl/tests/EGLTest/egl_cache_test.cpp +++ b/opengl/tests/EGLTest/egl_cache_test.cpp @@ -265,11 +265,68 @@ TEST_P(EGLCacheTest, TerminatedCacheBelowCacheLimit) { // Cache should contain both the key and the value // So 8 bytes per entry, at least 24 bytes ASSERT_GE(mCache->getCacheSize(), 24); - mCache->setCacheLimit(4); + + // Set the new limit and initialize cache mCache->terminate(); + mCache->setCacheLimit(4); + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + + // Ensure the new limit is respected ASSERT_LE(mCache->getCacheSize(), 4); } +TEST_P(EGLCacheTest, TrimCacheOnOverflow) { + // Skip if not in multifile mode + if (mCacheMode == egl_cache_t::EGLCacheMode::Monolithic) { + GTEST_SKIP() << "Skipping test designed for multifile"; + } + + uint8_t buf[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + + // Set one value in the cache + mCache->setBlob("abcd", 4, "efgh", 4); + ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ('e', buf[0]); + ASSERT_EQ('f', buf[1]); + ASSERT_EQ('g', buf[2]); + ASSERT_EQ('h', buf[3]); + + // Get the size of cache with a single entry + size_t cacheEntrySize = mCache->getCacheSize(); + + // Now reinitialize the cache, using max size equal to a single entry + mCache->terminate(); + mCache->setCacheLimit(cacheEntrySize); + mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY)); + + // Ensure our cache still has original value + ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4)); + ASSERT_EQ('e', buf[0]); + ASSERT_EQ('f', buf[1]); + ASSERT_EQ('g', buf[2]); + ASSERT_EQ('h', buf[3]); + + // Set another value, which should overflow the cache and trim + mCache->setBlob("ijkl", 4, "mnop", 4); + ASSERT_EQ(4, mCache->getBlob("ijkl", 4, buf, 4)); + ASSERT_EQ('m', buf[0]); + ASSERT_EQ('n', buf[1]); + ASSERT_EQ('o', buf[2]); + ASSERT_EQ('p', buf[3]); + + // The cache should still be under the limit + ASSERT_TRUE(mCache->getCacheSize() == cacheEntrySize); + + // And no cache hit on trimmed entry + uint8_t buf2[4] = { 0xee, 0xee, 0xee, 0xee }; + mCache->getBlob("abcd", 4, buf2, 4); + ASSERT_EQ(0xee, buf2[0]); + ASSERT_EQ(0xee, buf2[1]); + ASSERT_EQ(0xee, buf2[2]); + ASSERT_EQ(0xee, buf2[3]); +} + INSTANTIATE_TEST_CASE_P(MonolithicCacheTests, EGLCacheTest, ::testing::Values(egl_cache_t::EGLCacheMode::Monolithic)); INSTANTIATE_TEST_CASE_P(MultifileCacheTests, |