Loading opengl/include/EGL/eglext.h +15 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,21 @@ typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void); typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void); #endif /* EGL_ANDROID_blob_cache */ #ifndef EGL_ANDROID_blob_cache #define EGL_ANDROID_blob_cache 1 typedef khronos_ssize_t EGLsizei; typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncs(EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); #endif /* EGL_EGLEXT_PROTOTYPES */ typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); #endif #ifdef __cplusplus } #endif Loading opengl/libs/EGL/egl_cache.cpp +238 −18 Original line number Diff line number Diff line Loading @@ -19,6 +19,21 @@ #include "egl_impl.h" #include "egldefs.h" #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> // Cache size limits. static const size_t maxKeySize = 1024; static const size_t maxValueSize = 4096; static const size_t maxTotalSize = 64 * 1024; // Cache file header static const char* cacheFileMagic = "EGL$"; static const size_t cacheFileHeaderSize = 8; // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- Loading @@ -26,37 +41,37 @@ namespace android { #define BC_EXT_STR "EGL_ANDROID_blob_cache" // // EGL_ANDROID_blob_cache types and functions // Callback functions passed to EGL. // typedef khronos_ssize_t EGLsizei; typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); static void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { egl_cache_t::get()->setBlob(key, keySize, value, valueSize); } typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { return egl_cache_t::get()->getBlob(key, keySize, value, valueSize); } // // egl_cache_t definition // static void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { egl_cache_t::egl_cache_t() : mInitialized(false), mBlobCache(NULL) { } static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { return 0; egl_cache_t::~egl_cache_t() { } egl_cache_t egl_cache_t::sCache; egl_cache_t* egl_cache_t::get() { static egl_cache_t theCache; return &theCache; return &sCache; } void egl_cache_t::initialize(egl_display_t *display) { Mutex::Autolock lock(mMutex); for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) { Loading @@ -79,7 +94,8 @@ void egl_cache_t::initialize(egl_display_t *display) { continue; } eglSetBlobCacheFuncs(display->disp[i].dpy, setBlob, getBlob); eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob, android::getBlob); EGLint err = cnx->egl.eglGetError(); if (err != EGL_SUCCESS) { LOGE("eglSetBlobCacheFuncs resulted in an error: %#x", Loading @@ -88,6 +104,210 @@ void egl_cache_t::initialize(egl_display_t *display) { } } } mInitialized = true; } void egl_cache_t::terminate() { Mutex::Autolock lock(mMutex); if (mBlobCache != NULL) { saveBlobCacheLocked(); mBlobCache = NULL; } mInitialized = false; } void egl_cache_t::setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { Mutex::Autolock lock(mMutex); if (keySize < 0 || valueSize < 0) { LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); return; } if (mInitialized) { sp<BlobCache> bc = getBlobCacheLocked(); bc->set(key, keySize, value, valueSize); } } EGLsizei egl_cache_t::getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { Mutex::Autolock lock(mMutex); if (keySize < 0 || valueSize < 0) { LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); return 0; } if (mInitialized) { sp<BlobCache> bc = getBlobCacheLocked(); return bc->get(key, keySize, value, valueSize); } return 0; } void egl_cache_t::setCacheFilename(const char* filename) { Mutex::Autolock lock(mMutex); mFilename = filename; } sp<BlobCache> egl_cache_t::getBlobCacheLocked() { if (mBlobCache == NULL) { mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize); loadBlobCacheLocked(); } return mBlobCache; } static uint32_t crc32c(const uint8_t* buf, size_t len) { const uint32_t polyBits = 0x82F63B78; uint32_t r = 0; for (size_t i = 0; i < len; i++) { r ^= buf[i]; for (int j = 0; j < 8; j++) { if (r & 1) { r = (r >> 1) ^ polyBits; } else { r >>= 1; } } } return r; } void egl_cache_t::saveBlobCacheLocked() { if (mFilename.length() > 0) { size_t cacheSize = mBlobCache->getFlattenedSize(); size_t headerSize = cacheFileHeaderSize; const char* fname = mFilename.string(); // Try to create the file with no permissions so we can write it // without anyone trying to read it. int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); if (fd == -1) { if (errno == EEXIST) { // The file exists, delete it and try again. if (unlink(fname) == -1) { // No point in retrying if the unlink failed. LOGE("error unlinking cache file %s: %s (%d)", fname, strerror(errno), errno); return; } // Retry now that we've unlinked the file. fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); } if (fd == -1) { LOGE("error creating cache file %s: %s (%d)", fname, strerror(errno), errno); return; } } size_t fileSize = headerSize + cacheSize; if (ftruncate(fd, fileSize) == -1) { LOGE("error setting cache file size: %s (%d)", strerror(errno), errno); close(fd); unlink(fname); return; } uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, PROT_WRITE, MAP_SHARED, fd, 0)); if (buf == MAP_FAILED) { LOGE("error mmaping cache file: %s (%d)", strerror(errno), errno); close(fd); unlink(fname); return; } status_t err = mBlobCache->flatten(buf + headerSize, cacheSize, NULL, 0); if (err != OK) { LOGE("error writing cache contents: %s (%d)", strerror(-err), -err); munmap(buf, fileSize); close(fd); unlink(fname); return; } // Write the file magic and CRC memcpy(buf, cacheFileMagic, 4); uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); *crc = crc32c(buf + headerSize, cacheSize); munmap(buf, fileSize); fchmod(fd, S_IRUSR); close(fd); } } void egl_cache_t::loadBlobCacheLocked() { if (mFilename.length() > 0) { size_t headerSize = cacheFileHeaderSize; int fd = open(mFilename.string(), O_RDONLY, 0); if (fd == -1) { if (errno != ENOENT) { LOGE("error opening cache file %s: %s (%d)", mFilename.string(), strerror(errno), errno); } return; } struct stat statBuf; if (fstat(fd, &statBuf) == -1) { LOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno); close(fd); return; } // Sanity check the size before trying to mmap it. size_t fileSize = statBuf.st_size; if (fileSize > maxTotalSize * 2) { LOGE("cache file is too large: %#llx", statBuf.st_size); close(fd); return; } uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fd, 0)); if (buf == MAP_FAILED) { LOGE("error mmaping cache file: %s (%d)", strerror(errno), errno); close(fd); return; } // Check the file magic and CRC size_t cacheSize = fileSize - headerSize; if (memcmp(buf, cacheFileMagic, 4) != 0) { LOGE("cache file has bad mojo"); close(fd); return; } uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); if (crc32c(buf + headerSize, cacheSize) != *crc) { LOGE("cache file failed CRC check"); close(fd); return; } status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL, 0); if (err != OK) { LOGE("error reading cache contents: %s (%d)", strerror(-err), -err); munmap(buf, fileSize); close(fd); return; } munmap(buf, fileSize); close(fd); } } // ---------------------------------------------------------------------------- Loading opengl/libs/EGL/egl_cache.h +91 −1 Original line number Diff line number Diff line Loading @@ -14,20 +14,110 @@ ** limitations under the License. */ #ifndef ANDROID_EGL_CACHE_H #define ANDROID_EGL_CACHE_H #include <EGL/egl.h> #include <EGL/eglext.h> #include <utils/BlobCache.h> #include <utils/String8.h> #include <utils/StrongPointer.h> // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- class egl_display_t; class egl_cache_t { class EGLAPI egl_cache_t { public: // get returns a pointer to the singleton egl_cache_t object. This // singleton object will never be destroyed. static egl_cache_t* get(); // initialize puts the egl_cache_t into an initialized state, such that it // is able to insert and retrieve entries from the cache. This should be // called when EGL is initialized. When not in the initialized state the // getBlob and setBlob methods will return without performing any cache // operations. void initialize(egl_display_t* display); // terminate puts the egl_cache_t back into the uninitialized state. When // in this state the getBlob and setBlob methods will return without // performing any cache operations. void terminate(); // setBlob attempts to insert a new key/value blob pair into the cache. // This will be called by the hardware vendor's EGL implementation via the // EGL_ANDROID_blob_cache extension. void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); // getBlob attempts to retrieve the value blob associated with a given key // blob from cache. This will be called by the hardware vendor's EGL // implementation via the EGL_ANDROID_blob_cache extension. EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); // setCacheFilename sets the name of the file that should be used to store // cache contents from one program invocation to another. void setCacheFilename(const char* filename); private: // Creation and (the lack of) destruction is handled internally. egl_cache_t(); ~egl_cache_t(); // Copying is disallowed. egl_cache_t(const egl_cache_t&); // not implemented void operator=(const egl_cache_t&); // not implemented // getBlobCacheLocked returns the BlobCache object being used to store the // key/value blob pairs. If the BlobCache object has not yet been created, // this will do so, loading the serialized cache contents from disk if // possible. sp<BlobCache> getBlobCacheLocked(); // saveBlobCache attempts to save the current contents of mBlobCache to // disk. void saveBlobCacheLocked(); // loadBlobCache attempts to load the saved cache contents from disk into // mBlobCache. void loadBlobCacheLocked(); // mInitialized indicates whether the egl_cache_t is in the initialized // state. It is initialized to false at construction time, and gets set to // true when initialize is called. It is set back to false when terminate // is called. When in this state, the cache behaves as normal. When not, // the getBlob and setBlob methods will return without performing any cache // operations. bool mInitialized; // mBlobCache is the cache in which the key/value blob pairs are stored. It // is initially NULL, and will be initialized by getBlobCacheLocked the // first time it's needed. sp<BlobCache> mBlobCache; // mFilename is the name of the file for storing cache contents in between // program invocations. It is initialized to an empty string at // construction time, and can be set with the setCacheFilename method. An // empty string indicates that the cache should not be saved to or restored // from disk. String8 mFilename; // mMutex is the mutex used to prevent concurrent access to the member // variables. It must be locked whenever the member variables are accessed. mutable Mutex mMutex; // sCache is the singleton egl_cache_t object. static egl_cache_t sCache; }; // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- #endif // ANDROID_EGL_CACHE_H opengl/libs/EGL/egl_display.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ egl_display_t::egl_display_t() : egl_display_t::~egl_display_t() { magic = 0; egl_cache_t::get()->terminate(); } egl_display_t* egl_display_t::get(EGLDisplay dpy) { Loading opengl/libs/EGL/egl_display.h +1 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ struct egl_config_t { // ---------------------------------------------------------------------------- class egl_display_t { class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes static egl_display_t sDisplay[NUM_DISPLAYS]; EGLDisplay getDisplay(EGLNativeDisplayType display); Loading Loading @@ -141,4 +141,3 @@ EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface); // ---------------------------------------------------------------------------- #endif // ANDROID_EGL_DISPLAY_H Loading
opengl/include/EGL/eglext.h +15 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,21 @@ typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void); typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void); #endif /* EGL_ANDROID_blob_cache */ #ifndef EGL_ANDROID_blob_cache #define EGL_ANDROID_blob_cache 1 typedef khronos_ssize_t EGLsizei; typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncs(EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); #endif /* EGL_EGLEXT_PROTOTYPES */ typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); #endif #ifdef __cplusplus } #endif Loading
opengl/libs/EGL/egl_cache.cpp +238 −18 Original line number Diff line number Diff line Loading @@ -19,6 +19,21 @@ #include "egl_impl.h" #include "egldefs.h" #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> // Cache size limits. static const size_t maxKeySize = 1024; static const size_t maxValueSize = 4096; static const size_t maxTotalSize = 64 * 1024; // Cache file header static const char* cacheFileMagic = "EGL$"; static const size_t cacheFileHeaderSize = 8; // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- Loading @@ -26,37 +41,37 @@ namespace android { #define BC_EXT_STR "EGL_ANDROID_blob_cache" // // EGL_ANDROID_blob_cache types and functions // Callback functions passed to EGL. // typedef khronos_ssize_t EGLsizei; typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); static void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { egl_cache_t::get()->setBlob(key, keySize, value, valueSize); } typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get); static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { return egl_cache_t::get()->getBlob(key, keySize, value, valueSize); } // // egl_cache_t definition // static void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { egl_cache_t::egl_cache_t() : mInitialized(false), mBlobCache(NULL) { } static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { return 0; egl_cache_t::~egl_cache_t() { } egl_cache_t egl_cache_t::sCache; egl_cache_t* egl_cache_t::get() { static egl_cache_t theCache; return &theCache; return &sCache; } void egl_cache_t::initialize(egl_display_t *display) { Mutex::Autolock lock(mMutex); for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) { Loading @@ -79,7 +94,8 @@ void egl_cache_t::initialize(egl_display_t *display) { continue; } eglSetBlobCacheFuncs(display->disp[i].dpy, setBlob, getBlob); eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob, android::getBlob); EGLint err = cnx->egl.eglGetError(); if (err != EGL_SUCCESS) { LOGE("eglSetBlobCacheFuncs resulted in an error: %#x", Loading @@ -88,6 +104,210 @@ void egl_cache_t::initialize(egl_display_t *display) { } } } mInitialized = true; } void egl_cache_t::terminate() { Mutex::Autolock lock(mMutex); if (mBlobCache != NULL) { saveBlobCacheLocked(); mBlobCache = NULL; } mInitialized = false; } void egl_cache_t::setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize) { Mutex::Autolock lock(mMutex); if (keySize < 0 || valueSize < 0) { LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); return; } if (mInitialized) { sp<BlobCache> bc = getBlobCacheLocked(); bc->set(key, keySize, value, valueSize); } } EGLsizei egl_cache_t::getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize) { Mutex::Autolock lock(mMutex); if (keySize < 0 || valueSize < 0) { LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed"); return 0; } if (mInitialized) { sp<BlobCache> bc = getBlobCacheLocked(); return bc->get(key, keySize, value, valueSize); } return 0; } void egl_cache_t::setCacheFilename(const char* filename) { Mutex::Autolock lock(mMutex); mFilename = filename; } sp<BlobCache> egl_cache_t::getBlobCacheLocked() { if (mBlobCache == NULL) { mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize); loadBlobCacheLocked(); } return mBlobCache; } static uint32_t crc32c(const uint8_t* buf, size_t len) { const uint32_t polyBits = 0x82F63B78; uint32_t r = 0; for (size_t i = 0; i < len; i++) { r ^= buf[i]; for (int j = 0; j < 8; j++) { if (r & 1) { r = (r >> 1) ^ polyBits; } else { r >>= 1; } } } return r; } void egl_cache_t::saveBlobCacheLocked() { if (mFilename.length() > 0) { size_t cacheSize = mBlobCache->getFlattenedSize(); size_t headerSize = cacheFileHeaderSize; const char* fname = mFilename.string(); // Try to create the file with no permissions so we can write it // without anyone trying to read it. int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); if (fd == -1) { if (errno == EEXIST) { // The file exists, delete it and try again. if (unlink(fname) == -1) { // No point in retrying if the unlink failed. LOGE("error unlinking cache file %s: %s (%d)", fname, strerror(errno), errno); return; } // Retry now that we've unlinked the file. fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0); } if (fd == -1) { LOGE("error creating cache file %s: %s (%d)", fname, strerror(errno), errno); return; } } size_t fileSize = headerSize + cacheSize; if (ftruncate(fd, fileSize) == -1) { LOGE("error setting cache file size: %s (%d)", strerror(errno), errno); close(fd); unlink(fname); return; } uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, PROT_WRITE, MAP_SHARED, fd, 0)); if (buf == MAP_FAILED) { LOGE("error mmaping cache file: %s (%d)", strerror(errno), errno); close(fd); unlink(fname); return; } status_t err = mBlobCache->flatten(buf + headerSize, cacheSize, NULL, 0); if (err != OK) { LOGE("error writing cache contents: %s (%d)", strerror(-err), -err); munmap(buf, fileSize); close(fd); unlink(fname); return; } // Write the file magic and CRC memcpy(buf, cacheFileMagic, 4); uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); *crc = crc32c(buf + headerSize, cacheSize); munmap(buf, fileSize); fchmod(fd, S_IRUSR); close(fd); } } void egl_cache_t::loadBlobCacheLocked() { if (mFilename.length() > 0) { size_t headerSize = cacheFileHeaderSize; int fd = open(mFilename.string(), O_RDONLY, 0); if (fd == -1) { if (errno != ENOENT) { LOGE("error opening cache file %s: %s (%d)", mFilename.string(), strerror(errno), errno); } return; } struct stat statBuf; if (fstat(fd, &statBuf) == -1) { LOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno); close(fd); return; } // Sanity check the size before trying to mmap it. size_t fileSize = statBuf.st_size; if (fileSize > maxTotalSize * 2) { LOGE("cache file is too large: %#llx", statBuf.st_size); close(fd); return; } uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize, PROT_READ, MAP_PRIVATE, fd, 0)); if (buf == MAP_FAILED) { LOGE("error mmaping cache file: %s (%d)", strerror(errno), errno); close(fd); return; } // Check the file magic and CRC size_t cacheSize = fileSize - headerSize; if (memcmp(buf, cacheFileMagic, 4) != 0) { LOGE("cache file has bad mojo"); close(fd); return; } uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4); if (crc32c(buf + headerSize, cacheSize) != *crc) { LOGE("cache file failed CRC check"); close(fd); return; } status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL, 0); if (err != OK) { LOGE("error reading cache contents: %s (%d)", strerror(-err), -err); munmap(buf, fileSize); close(fd); return; } munmap(buf, fileSize); close(fd); } } // ---------------------------------------------------------------------------- Loading
opengl/libs/EGL/egl_cache.h +91 −1 Original line number Diff line number Diff line Loading @@ -14,20 +14,110 @@ ** limitations under the License. */ #ifndef ANDROID_EGL_CACHE_H #define ANDROID_EGL_CACHE_H #include <EGL/egl.h> #include <EGL/eglext.h> #include <utils/BlobCache.h> #include <utils/String8.h> #include <utils/StrongPointer.h> // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- class egl_display_t; class egl_cache_t { class EGLAPI egl_cache_t { public: // get returns a pointer to the singleton egl_cache_t object. This // singleton object will never be destroyed. static egl_cache_t* get(); // initialize puts the egl_cache_t into an initialized state, such that it // is able to insert and retrieve entries from the cache. This should be // called when EGL is initialized. When not in the initialized state the // getBlob and setBlob methods will return without performing any cache // operations. void initialize(egl_display_t* display); // terminate puts the egl_cache_t back into the uninitialized state. When // in this state the getBlob and setBlob methods will return without // performing any cache operations. void terminate(); // setBlob attempts to insert a new key/value blob pair into the cache. // This will be called by the hardware vendor's EGL implementation via the // EGL_ANDROID_blob_cache extension. void setBlob(const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize); // getBlob attempts to retrieve the value blob associated with a given key // blob from cache. This will be called by the hardware vendor's EGL // implementation via the EGL_ANDROID_blob_cache extension. EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, EGLsizei valueSize); // setCacheFilename sets the name of the file that should be used to store // cache contents from one program invocation to another. void setCacheFilename(const char* filename); private: // Creation and (the lack of) destruction is handled internally. egl_cache_t(); ~egl_cache_t(); // Copying is disallowed. egl_cache_t(const egl_cache_t&); // not implemented void operator=(const egl_cache_t&); // not implemented // getBlobCacheLocked returns the BlobCache object being used to store the // key/value blob pairs. If the BlobCache object has not yet been created, // this will do so, loading the serialized cache contents from disk if // possible. sp<BlobCache> getBlobCacheLocked(); // saveBlobCache attempts to save the current contents of mBlobCache to // disk. void saveBlobCacheLocked(); // loadBlobCache attempts to load the saved cache contents from disk into // mBlobCache. void loadBlobCacheLocked(); // mInitialized indicates whether the egl_cache_t is in the initialized // state. It is initialized to false at construction time, and gets set to // true when initialize is called. It is set back to false when terminate // is called. When in this state, the cache behaves as normal. When not, // the getBlob and setBlob methods will return without performing any cache // operations. bool mInitialized; // mBlobCache is the cache in which the key/value blob pairs are stored. It // is initially NULL, and will be initialized by getBlobCacheLocked the // first time it's needed. sp<BlobCache> mBlobCache; // mFilename is the name of the file for storing cache contents in between // program invocations. It is initialized to an empty string at // construction time, and can be set with the setCacheFilename method. An // empty string indicates that the cache should not be saved to or restored // from disk. String8 mFilename; // mMutex is the mutex used to prevent concurrent access to the member // variables. It must be locked whenever the member variables are accessed. mutable Mutex mMutex; // sCache is the singleton egl_cache_t object. static egl_cache_t sCache; }; // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- #endif // ANDROID_EGL_CACHE_H
opengl/libs/EGL/egl_display.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ egl_display_t::egl_display_t() : egl_display_t::~egl_display_t() { magic = 0; egl_cache_t::get()->terminate(); } egl_display_t* egl_display_t::get(EGLDisplay dpy) { Loading
opengl/libs/EGL/egl_display.h +1 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ struct egl_config_t { // ---------------------------------------------------------------------------- class egl_display_t { class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes static egl_display_t sDisplay[NUM_DISPLAYS]; EGLDisplay getDisplay(EGLNativeDisplayType display); Loading Loading @@ -141,4 +141,3 @@ EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface); // ---------------------------------------------------------------------------- #endif // ANDROID_EGL_DISPLAY_H