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:
parent
33e55a9545
commit
766010858e
@ -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
|
||||
|
@ -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() {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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…
Reference in New Issue
Block a user