Skip to content

Commit 9cf8b6e

Browse files
author
Jamie Gennis
committed
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
1 parent 2ab7ec9 commit 9cf8b6e

File tree

4 files changed

+167
-16
lines changed

4 files changed

+167
-16
lines changed

opengl/include/EGL/eglext.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,21 @@ typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)(void);
256256
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC)(void);
257257
#endif
258258

259+
260+
/* EGL_ANDROID_blob_cache
261+
*/
262+
#ifndef EGL_ANDROID_blob_cache
263+
#define EGL_ANDROID_blob_cache 1
264+
typedef khronos_ssize_t EGLsizei;
265+
typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize);
266+
typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize);
267+
#ifdef EGL_EGLEXT_PROTOTYPES
268+
EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncs(EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get);
269+
#endif /* EGL_EGLEXT_PROTOTYPES */
270+
typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy,
271+
EGLSetBlobFunc set, EGLGetBlobFunc get);
272+
#endif
273+
259274
#ifdef __cplusplus
260275
}
261276
#endif

opengl/libs/EGL/egl_cache.cpp

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,39 @@
1919
#include "egl_impl.h"
2020
#include "egldefs.h"
2121

22+
// Cache size limits.
23+
static const size_t maxKeySize = 1024;
24+
static const size_t maxValueSize = 4096;
25+
static const size_t maxTotalSize = 64 * 1024;
26+
2227
// ----------------------------------------------------------------------------
2328
namespace android {
2429
// ----------------------------------------------------------------------------
2530

2631
#define BC_EXT_STR "EGL_ANDROID_blob_cache"
2732

2833
//
29-
// EGL_ANDROID_blob_cache types and functions
34+
// Callback functions passed to EGL.
3035
//
31-
typedef khronos_ssize_t EGLsizei;
32-
33-
typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize,
34-
const void* value, EGLsizei valueSize);
35-
36-
typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize,
37-
void* value, EGLsizei valueSize);
36+
static void setBlob(const void* key, EGLsizei keySize, const void* value,
37+
EGLsizei valueSize) {
38+
egl_cache_t::get()->setBlob(key, keySize, value, valueSize);
39+
}
3840

39-
typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy,
40-
EGLSetBlobFunc set, EGLGetBlobFunc get);
41+
static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
42+
EGLsizei valueSize) {
43+
return egl_cache_t::get()->getBlob(key, keySize, value, valueSize);
44+
}
4145

4246
//
4347
// egl_cache_t definition
4448
//
45-
static void setBlob(const void* key, EGLsizei keySize, const void* value,
46-
EGLsizei valueSize) {
49+
egl_cache_t::egl_cache_t() :
50+
mInitialized(false),
51+
mBlobCache(NULL) {
4752
}
4853

49-
static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
50-
EGLsizei valueSize) {
51-
return 0;
54+
egl_cache_t::~egl_cache_t() {
5255
}
5356

5457
egl_cache_t* egl_cache_t::get() {
@@ -57,6 +60,7 @@ egl_cache_t* egl_cache_t::get() {
5760
}
5861

5962
void egl_cache_t::initialize(egl_display_t *display) {
63+
Mutex::Autolock lock(mMutex);
6064
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
6165
egl_connection_t* const cnx = &gEGLImpl[i];
6266
if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
@@ -79,7 +83,8 @@ void egl_cache_t::initialize(egl_display_t *display) {
7983
continue;
8084
}
8185

82-
eglSetBlobCacheFuncs(display->disp[i].dpy, setBlob, getBlob);
86+
eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob,
87+
android::getBlob);
8388
EGLint err = cnx->egl.eglGetError();
8489
if (err != EGL_SUCCESS) {
8590
LOGE("eglSetBlobCacheFuncs resulted in an error: %#x",
@@ -88,6 +93,61 @@ void egl_cache_t::initialize(egl_display_t *display) {
8893
}
8994
}
9095
}
96+
mInitialized = true;
97+
}
98+
99+
void egl_cache_t::terminate() {
100+
Mutex::Autolock lock(mMutex);
101+
if (mBlobCache != NULL) {
102+
saveBlobCacheLocked();
103+
mBlobCache = NULL;
104+
}
105+
mInitialized = false;
106+
}
107+
108+
void egl_cache_t::setBlob(const void* key, EGLsizei keySize, const void* value,
109+
EGLsizei valueSize) {
110+
Mutex::Autolock lock(mMutex);
111+
112+
if (keySize < 0 || valueSize < 0) {
113+
LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed");
114+
return;
115+
}
116+
117+
if (mInitialized) {
118+
sp<BlobCache> bc = getBlobCacheLocked();
119+
bc->set(key, keySize, value, valueSize);
120+
}
121+
}
122+
123+
EGLsizei egl_cache_t::getBlob(const void* key, EGLsizei keySize, void* value,
124+
EGLsizei valueSize) {
125+
Mutex::Autolock lock(mMutex);
126+
127+
if (keySize < 0 || valueSize < 0) {
128+
LOGW("EGL_ANDROID_blob_cache set: negative sizes are not allowed");
129+
return 0;
130+
}
131+
132+
if (mInitialized) {
133+
sp<BlobCache> bc = getBlobCacheLocked();
134+
return bc->get(key, keySize, value, valueSize);
135+
}
136+
return 0;
137+
}
138+
139+
sp<BlobCache> egl_cache_t::getBlobCacheLocked() {
140+
if (mBlobCache == NULL) {
141+
mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize);
142+
loadBlobCacheLocked();
143+
}
144+
return mBlobCache;
145+
}
146+
147+
void egl_cache_t::saveBlobCacheLocked() {
148+
}
149+
150+
void egl_cache_t::loadBlobCacheLocked() {
91151
}
92152

93153
// ----------------------------------------------------------------------------

opengl/libs/EGL/egl_cache.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
** limitations under the License.
1515
*/
1616

17+
#ifndef ANDROID_EGL_CACHE_H
18+
#define ANDROID_EGL_CACHE_H
19+
20+
#include <EGL/egl.h>
21+
#include <EGL/eglext.h>
22+
23+
#include <utils/BlobCache.h>
24+
#include <utils/StrongPointer.h>
25+
1726
// ----------------------------------------------------------------------------
1827
namespace android {
1928
// ----------------------------------------------------------------------------
@@ -23,11 +32,77 @@ class egl_display_t;
2332
class egl_cache_t {
2433
public:
2534

35+
// get returns a pointer to the singleton egl_cache_t object. This
36+
// singleton object will never be destroyed.
2637
static egl_cache_t* get();
2738

39+
// initialize puts the egl_cache_t into an initialized state, such that it
40+
// is able to insert and retrieve entries from the cache. This should be
41+
// called when EGL is initialized. When not in the initialized state the
42+
// getBlob and setBlob methods will return without performing any cache
43+
// operations.
2844
void initialize(egl_display_t* display);
45+
46+
// terminate puts the egl_cache_t back into the uninitialized state. When
47+
// in this state the getBlob and setBlob methods will return without
48+
// performing any cache operations.
49+
void terminate();
50+
51+
// setBlob attempts to insert a new key/value blob pair into the cache.
52+
// This will be called by the hardware vendor's EGL implementation via the
53+
// EGL_ANDROID_blob_cache extension.
54+
void setBlob(const void* key, EGLsizei keySize, const void* value,
55+
EGLsizei valueSize);
56+
57+
// getBlob attempts to retrieve the value blob associated with a given key
58+
// blob from cache. This will be called by the hardware vendor's EGL
59+
// implementation via the EGL_ANDROID_blob_cache extension.
60+
EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
61+
EGLsizei valueSize);
62+
63+
private:
64+
// Creation and (the lack of) destruction is handled internally.
65+
egl_cache_t();
66+
~egl_cache_t();
67+
68+
// Copying is disallowed.
69+
egl_cache_t(const egl_cache_t&); // not implemented
70+
void operator=(const egl_cache_t&); // not implemented
71+
72+
// getBlobCacheLocked returns the BlobCache object being used to store the
73+
// key/value blob pairs. If the BlobCache object has not yet been created,
74+
// this will do so, loading the serialized cache contents from disk if
75+
// possible.
76+
sp<BlobCache> getBlobCacheLocked();
77+
78+
// saveBlobCache attempts to save the current contents of mBlobCache to
79+
// disk.
80+
void saveBlobCacheLocked();
81+
82+
// loadBlobCache attempts to load the saved cache contents from disk into
83+
// mBlobCache.
84+
void loadBlobCacheLocked();
85+
86+
// mInitialized indicates whether the egl_cache_t is in the initialized
87+
// state. It is initialized to false at construction time, and gets set to
88+
// true when initialize is called. It is set back to false when terminate
89+
// is called. When in this state, the cache behaves as normal. When not,
90+
// the getBlob and setBlob methods will return without performing any cache
91+
// operations.
92+
bool mInitialized;
93+
94+
// mBlobCache is the cache in which the key/value blob pairs are stored. It
95+
// is initially NULL, and will be initialized by getBlobCacheLocked the
96+
// first time it's needed.
97+
sp<BlobCache> mBlobCache;
98+
99+
// mMutex is the mutex used to prevent concurrent access to the member
100+
// variables. It must be locked whenever the member variables are accessed.
101+
mutable Mutex mMutex;
29102
};
30103

31104
// ----------------------------------------------------------------------------
32105
}; // namespace android
33106
// ----------------------------------------------------------------------------
107+
108+
#endif // ANDROID_EGL_CACHE_H

opengl/libs/EGL/egl_display.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ egl_display_t::egl_display_t() :
4444

4545
egl_display_t::~egl_display_t() {
4646
magic = 0;
47+
egl_cache_t::get()->terminate();
4748
}
4849

4950
egl_display_t* egl_display_t::get(EGLDisplay dpy) {

0 commit comments

Comments
 (0)