Loading opengl/libs/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ cc_library_shared { srcs: [ "EGL/egl_tls.cpp", "EGL/egl_cache.cpp", "EGL/egl_cache_multifile.cpp", "EGL/egl_display.cpp", "EGL/egl_object.cpp", "EGL/egl_layers.cpp", Loading opengl/libs/EGL/FileBlobCache.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -185,4 +185,10 @@ void FileBlobCache::writeToFile() { } } size_t FileBlobCache::getSize() { if (mFilename.length() > 0) { return getFlattenedSize() + cacheFileHeaderSize; } return 0; } } opengl/libs/EGL/FileBlobCache.h +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ public: // disk. void writeToFile(); // Return the total size of the cache size_t getSize(); private: // mFilename is the name of the file for storing cache contents. std::string mFilename; Loading opengl/libs/EGL/egl_cache.cpp +94 −21 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include "egl_cache.h" #include <android-base/properties.h> #include <inttypes.h> #include <log/log.h> #include <private/EGL/cache.h> #include <unistd.h> Loading @@ -23,16 +25,23 @@ #include <thread> #include "../egl_impl.h" #include "egl_cache_multifile.h" #include "egl_display.h" // Cache size limits. // Monolithic cache size limits. static const size_t maxKeySize = 12 * 1024; static const size_t maxValueSize = 64 * 1024; static const size_t maxTotalSize = 32 * 1024 * 1024; // The time in seconds to wait before saving newly inserted cache entries. // The time in seconds to wait before saving newly inserted monolithic cache entries. static const unsigned int deferredSaveDelay = 4; // Multifile cache size limit constexpr size_t kMultifileCacheByteLimit = 64 * 1024 * 1024; // Delay before cleaning up multifile cache entries static const unsigned int deferredMultifileCleanupDelaySeconds = 1; namespace android { #define BC_EXT_STR "EGL_ANDROID_blob_cache" Loading @@ -58,7 +67,8 @@ static EGLsizeiANDROID getBlob(const void* key, EGLsizeiANDROID keySize, void* v // // egl_cache_t definition // egl_cache_t::egl_cache_t() : mInitialized(false) {} egl_cache_t::egl_cache_t() : mInitialized(false), mMultifileMode(true), mCacheByteLimit(maxTotalSize) {} egl_cache_t::~egl_cache_t() {} Loading Loading @@ -101,6 +111,18 @@ void egl_cache_t::initialize(egl_display_t* display) { } } mMultifileMode = true; // Allow forcing monolithic cache for debug purposes if (base::GetProperty("debug.egl.blobcache.multifilemode", "") == "false") { ALOGD("Forcing monolithic cache due to debug.egl.blobcache.multifilemode == \"false\""); mMultifileMode = false; } if (mMultifileMode) { mCacheByteLimit = kMultifileCacheByteLimit; } mInitialized = true; } Loading @@ -110,6 +132,11 @@ void egl_cache_t::terminate() { mBlobCache->writeToFile(); } mBlobCache = nullptr; if (mMultifileMode) { checkMultifileCacheSize(mCacheByteLimit); } mMultifileMode = false; mInitialized = false; } void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* value, Loading @@ -122,6 +149,22 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* } if (mInitialized) { if (mMultifileMode) { setBlobMultifile(key, keySize, value, valueSize, mFilename); if (!mMultifileCleanupPending) { mMultifileCleanupPending = true; // Kick off a thread to cull cache files below limit std::thread deferredMultifileCleanupThread([this]() { sleep(deferredMultifileCleanupDelaySeconds); std::lock_guard<std::mutex> lock(mMutex); // Check the size of cache and remove entries to stay under limit checkMultifileCacheSize(mCacheByteLimit); mMultifileCleanupPending = false; }); deferredMultifileCleanupThread.detach(); } } else { BlobCache* bc = getBlobCacheLocked(); bc->set(key, keySize, value, valueSize); Loading @@ -139,20 +182,25 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* } } } } EGLsizeiANDROID egl_cache_t::getBlob(const void* key, EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize) { std::lock_guard<std::mutex> lock(mMutex); if (keySize < 0 || valueSize < 0) { ALOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); ALOGW("EGL_ANDROID_blob_cache get: negative sizes are not allowed"); return 0; } if (mInitialized) { if (mMultifileMode) { return getBlobMultifile(key, keySize, value, valueSize, mFilename); } else { BlobCache* bc = getBlobCacheLocked(); return bc->get(key, keySize, value, valueSize); } } return 0; } Loading @@ -161,9 +209,34 @@ void egl_cache_t::setCacheFilename(const char* filename) { mFilename = filename; } void egl_cache_t::setCacheLimit(int64_t cacheByteLimit) { std::lock_guard<std::mutex> lock(mMutex); if (!mMultifileMode) { // If we're not in multifile mode, ensure the cache limit is only being lowered, // not increasing above the hard coded platform limit if (cacheByteLimit > maxTotalSize) { return; } } mCacheByteLimit = cacheByteLimit; } size_t egl_cache_t::getCacheSize() { std::lock_guard<std::mutex> lock(mMutex); if (mMultifileMode) { return getMultifileCacheSize(); } if (mBlobCache) { return mBlobCache->getSize(); } return 0; } BlobCache* egl_cache_t::getBlobCacheLocked() { if (mBlobCache == nullptr) { mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename)); mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, mCacheByteLimit, mFilename)); } return mBlobCache.get(); } Loading opengl/libs/EGL/egl_cache.h +16 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,12 @@ public: // cache contents from one program invocation to another. void setCacheFilename(const char* filename); // Allow the fixed cache limit to be overridden void setCacheLimit(int64_t cacheByteLimit); // Return the byte total for cache file(s) size_t getCacheSize(); private: // Creation and (the lack of) destruction is handled internally. egl_cache_t(); Loading Loading @@ -112,6 +118,16 @@ private: // sCache is the singleton egl_cache_t object. static egl_cache_t sCache; // Whether to use multiple files to store cache entries bool mMultifileMode; // Cache limit int64_t mCacheByteLimit; // Whether we've kicked off a side thread that will check the multifile // cache size and remove entries if needed. bool mMultifileCleanupPending; }; }; // namespace android Loading Loading
opengl/libs/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ cc_library_shared { srcs: [ "EGL/egl_tls.cpp", "EGL/egl_cache.cpp", "EGL/egl_cache_multifile.cpp", "EGL/egl_display.cpp", "EGL/egl_object.cpp", "EGL/egl_layers.cpp", Loading
opengl/libs/EGL/FileBlobCache.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -185,4 +185,10 @@ void FileBlobCache::writeToFile() { } } size_t FileBlobCache::getSize() { if (mFilename.length() > 0) { return getFlattenedSize() + cacheFileHeaderSize; } return 0; } }
opengl/libs/EGL/FileBlobCache.h +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,9 @@ public: // disk. void writeToFile(); // Return the total size of the cache size_t getSize(); private: // mFilename is the name of the file for storing cache contents. std::string mFilename; Loading
opengl/libs/EGL/egl_cache.cpp +94 −21 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include "egl_cache.h" #include <android-base/properties.h> #include <inttypes.h> #include <log/log.h> #include <private/EGL/cache.h> #include <unistd.h> Loading @@ -23,16 +25,23 @@ #include <thread> #include "../egl_impl.h" #include "egl_cache_multifile.h" #include "egl_display.h" // Cache size limits. // Monolithic cache size limits. static const size_t maxKeySize = 12 * 1024; static const size_t maxValueSize = 64 * 1024; static const size_t maxTotalSize = 32 * 1024 * 1024; // The time in seconds to wait before saving newly inserted cache entries. // The time in seconds to wait before saving newly inserted monolithic cache entries. static const unsigned int deferredSaveDelay = 4; // Multifile cache size limit constexpr size_t kMultifileCacheByteLimit = 64 * 1024 * 1024; // Delay before cleaning up multifile cache entries static const unsigned int deferredMultifileCleanupDelaySeconds = 1; namespace android { #define BC_EXT_STR "EGL_ANDROID_blob_cache" Loading @@ -58,7 +67,8 @@ static EGLsizeiANDROID getBlob(const void* key, EGLsizeiANDROID keySize, void* v // // egl_cache_t definition // egl_cache_t::egl_cache_t() : mInitialized(false) {} egl_cache_t::egl_cache_t() : mInitialized(false), mMultifileMode(true), mCacheByteLimit(maxTotalSize) {} egl_cache_t::~egl_cache_t() {} Loading Loading @@ -101,6 +111,18 @@ void egl_cache_t::initialize(egl_display_t* display) { } } mMultifileMode = true; // Allow forcing monolithic cache for debug purposes if (base::GetProperty("debug.egl.blobcache.multifilemode", "") == "false") { ALOGD("Forcing monolithic cache due to debug.egl.blobcache.multifilemode == \"false\""); mMultifileMode = false; } if (mMultifileMode) { mCacheByteLimit = kMultifileCacheByteLimit; } mInitialized = true; } Loading @@ -110,6 +132,11 @@ void egl_cache_t::terminate() { mBlobCache->writeToFile(); } mBlobCache = nullptr; if (mMultifileMode) { checkMultifileCacheSize(mCacheByteLimit); } mMultifileMode = false; mInitialized = false; } void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* value, Loading @@ -122,6 +149,22 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* } if (mInitialized) { if (mMultifileMode) { setBlobMultifile(key, keySize, value, valueSize, mFilename); if (!mMultifileCleanupPending) { mMultifileCleanupPending = true; // Kick off a thread to cull cache files below limit std::thread deferredMultifileCleanupThread([this]() { sleep(deferredMultifileCleanupDelaySeconds); std::lock_guard<std::mutex> lock(mMutex); // Check the size of cache and remove entries to stay under limit checkMultifileCacheSize(mCacheByteLimit); mMultifileCleanupPending = false; }); deferredMultifileCleanupThread.detach(); } } else { BlobCache* bc = getBlobCacheLocked(); bc->set(key, keySize, value, valueSize); Loading @@ -139,20 +182,25 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void* } } } } EGLsizeiANDROID egl_cache_t::getBlob(const void* key, EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize) { std::lock_guard<std::mutex> lock(mMutex); if (keySize < 0 || valueSize < 0) { ALOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); ALOGW("EGL_ANDROID_blob_cache get: negative sizes are not allowed"); return 0; } if (mInitialized) { if (mMultifileMode) { return getBlobMultifile(key, keySize, value, valueSize, mFilename); } else { BlobCache* bc = getBlobCacheLocked(); return bc->get(key, keySize, value, valueSize); } } return 0; } Loading @@ -161,9 +209,34 @@ void egl_cache_t::setCacheFilename(const char* filename) { mFilename = filename; } void egl_cache_t::setCacheLimit(int64_t cacheByteLimit) { std::lock_guard<std::mutex> lock(mMutex); if (!mMultifileMode) { // If we're not in multifile mode, ensure the cache limit is only being lowered, // not increasing above the hard coded platform limit if (cacheByteLimit > maxTotalSize) { return; } } mCacheByteLimit = cacheByteLimit; } size_t egl_cache_t::getCacheSize() { std::lock_guard<std::mutex> lock(mMutex); if (mMultifileMode) { return getMultifileCacheSize(); } if (mBlobCache) { return mBlobCache->getSize(); } return 0; } BlobCache* egl_cache_t::getBlobCacheLocked() { if (mBlobCache == nullptr) { mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename)); mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, mCacheByteLimit, mFilename)); } return mBlobCache.get(); } Loading
opengl/libs/EGL/egl_cache.h +16 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,12 @@ public: // cache contents from one program invocation to another. void setCacheFilename(const char* filename); // Allow the fixed cache limit to be overridden void setCacheLimit(int64_t cacheByteLimit); // Return the byte total for cache file(s) size_t getCacheSize(); private: // Creation and (the lack of) destruction is handled internally. egl_cache_t(); Loading Loading @@ -112,6 +118,16 @@ private: // sCache is the singleton egl_cache_t object. static egl_cache_t sCache; // Whether to use multiple files to store cache entries bool mMultifileMode; // Cache limit int64_t mCacheByteLimit; // Whether we've kicked off a side thread that will check the multifile // cache size and remove entries if needed. bool mMultifileCleanupPending; }; }; // namespace android Loading