blob: adb2a13d64d475894e81b40f87deef2a18ca6fcc [file] [log] [blame]
Jamie Gennisaca51c02011-11-03 17:42:43 -07001/*
2 ** Copyright 2011, The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17#include "egl_cache.h"
18#include "egl_display.h"
19#include "egl_impl.h"
20#include "egldefs.h"
21
Jamie Gennis76601082011-11-06 14:14:33 -080022// Cache size limits.
23static const size_t maxKeySize = 1024;
24static const size_t maxValueSize = 4096;
25static const size_t maxTotalSize = 64 * 1024;
26
Jamie Gennisaca51c02011-11-03 17:42:43 -070027// ----------------------------------------------------------------------------
28namespace android {
29// ----------------------------------------------------------------------------
30
31#define BC_EXT_STR "EGL_ANDROID_blob_cache"
32
33//
Jamie Gennis76601082011-11-06 14:14:33 -080034// Callback functions passed to EGL.
Jamie Gennisaca51c02011-11-03 17:42:43 -070035//
36static void setBlob(const void* key, EGLsizei keySize, const void* value,
37 EGLsizei valueSize) {
Jamie Gennis76601082011-11-06 14:14:33 -080038 egl_cache_t::get()->setBlob(key, keySize, value, valueSize);
Jamie Gennisaca51c02011-11-03 17:42:43 -070039}
40
41static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
42 EGLsizei valueSize) {
Jamie Gennis76601082011-11-06 14:14:33 -080043 return egl_cache_t::get()->getBlob(key, keySize, value, valueSize);
44}
45
46//
47// egl_cache_t definition
48//
49egl_cache_t::egl_cache_t() :
50 mInitialized(false),
51 mBlobCache(NULL) {
52}
53
54egl_cache_t::~egl_cache_t() {
Jamie Gennisaca51c02011-11-03 17:42:43 -070055}
56
57egl_cache_t* egl_cache_t::get() {
58 static egl_cache_t theCache;
59 return &theCache;
60}
61
62void egl_cache_t::initialize(egl_display_t *display) {
Jamie Gennis76601082011-11-06 14:14:33 -080063 Mutex::Autolock lock(mMutex);
Jamie Gennisaca51c02011-11-03 17:42:43 -070064 for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
65 egl_connection_t* const cnx = &gEGLImpl[i];
66 if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
67 const char* exts = display->disp[i].queryString.extensions;
68 size_t bcExtLen = strlen(BC_EXT_STR);
69 size_t extsLen = strlen(exts);
70 bool equal = !strcmp(BC_EXT_STR, exts);
71 bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
72 bool atEnd = (bcExtLen+1) < extsLen &&
73 !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
74 bool inMiddle = strstr(" " BC_EXT_STR " ", exts);
75 if (equal || atStart || atEnd || inMiddle) {
76 PFNEGLSETBLOBCACHEFUNCSPROC eglSetBlobCacheFuncs;
77 eglSetBlobCacheFuncs =
78 reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSPROC>(
79 cnx->egl.eglGetProcAddress("eglSetBlobCacheFuncs"));
80 if (eglSetBlobCacheFuncs == NULL) {
81 LOGE("EGL_ANDROID_blob_cache advertised by display %d, "
82 "but unable to get eglSetBlobCacheFuncs", i);
83 continue;
84 }
85
Jamie Gennis76601082011-11-06 14:14:33 -080086 eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob,
87 android::getBlob);
Jamie Gennisaca51c02011-11-03 17:42:43 -070088 EGLint err = cnx->egl.eglGetError();
89 if (err != EGL_SUCCESS) {
90 LOGE("eglSetBlobCacheFuncs resulted in an error: %#x",
91 err);
92 }
93 }
94 }
95 }
Jamie Gennis76601082011-11-06 14:14:33 -080096 mInitialized = true;
97}
98
99void egl_cache_t::terminate() {
100 Mutex::Autolock lock(mMutex);
101 if (mBlobCache != NULL) {
102 saveBlobCacheLocked();
103 mBlobCache = NULL;
104 }
105 mInitialized = false;
106}
107
108void 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
123EGLsizei 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
139sp<BlobCache> egl_cache_t::getBlobCacheLocked() {
140 if (mBlobCache == NULL) {
141 mBlobCache = new BlobCache(maxKeySize, maxValueSize, maxTotalSize);
142 loadBlobCacheLocked();
143 }
144 return mBlobCache;
145}
146
147void egl_cache_t::saveBlobCacheLocked() {
148}
149
150void egl_cache_t::loadBlobCacheLocked() {
Jamie Gennisaca51c02011-11-03 17:42:43 -0700151}
152
153// ----------------------------------------------------------------------------
154}; // namespace android
155// ----------------------------------------------------------------------------