EGL: use an in-memory the blob cache

This change makes the makes the stub EGL_ANDROID_blob_cache callbacks
actually use a BlobCache object.

Bug: 5474671
Change-Id: I5cbaae2dea3aad2fe306c9f57029c3f215a0863a
This commit is contained in:
Jamie Gennis 2011-11-06 14:14:33 -08:00
parent 33e55a9545
commit 766010858e
4 changed files with 168 additions and 17 deletions

View File

@ -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

View File

@ -19,6 +19,11 @@
#include "egl_impl.h"
#include "egldefs.h"
// Cache size limits.
static const size_t maxKeySize = 1024;
static const size_t maxValueSize = 4096;
static const size_t maxTotalSize = 64 * 1024;
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@ -26,29 +31,27 @@ namespace android {
#define BC_EXT_STR "EGL_ANDROID_blob_cache"
//
// EGL_ANDROID_blob_cache types and functions
//
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);
typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy,
EGLSetBlobFunc set, EGLGetBlobFunc get);
//
// egl_cache_t definition
// Callback functions passed to EGL.
//
static void setBlob(const void* key, EGLsizei keySize, const void* value,
EGLsizei valueSize) {
egl_cache_t::get()->setBlob(key, keySize, value, valueSize);
}
static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
EGLsizei valueSize) {
return 0;
return egl_cache_t::get()->getBlob(key, keySize, value, valueSize);
}
//
// egl_cache_t definition
//
egl_cache_t::egl_cache_t() :
mInitialized(false),
mBlobCache(NULL) {
}
egl_cache_t::~egl_cache_t() {
}
egl_cache_t* egl_cache_t::get() {
@ -57,6 +60,7 @@ egl_cache_t* egl_cache_t::get() {
}
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) {
@ -79,7 +83,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",
@ -88,6 +93,61 @@ 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;
}
sp<BlobCache> egl_cache_t::getBlobCacheLocked() {
if (mBlobCache == NULL) {
mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize);
loadBlobCacheLocked();
}
return mBlobCache;
}
void egl_cache_t::saveBlobCacheLocked() {
}
void egl_cache_t::loadBlobCacheLocked() {
}
// ----------------------------------------------------------------------------

View File

@ -14,6 +14,15 @@
** 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/StrongPointer.h>
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@ -23,11 +32,77 @@ class egl_display_t;
class 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);
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;
// 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;
};
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
#endif // ANDROID_EGL_CACHE_H

View File

@ -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) {