egl_cache.cpp revision 766010858ea7696d64f1b559413670bdd8627595
1/* 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 22// Cache size limits. 23static const size_t maxKeySize = 1024; 24static const size_t maxValueSize = 4096; 25static const size_t maxTotalSize = 64 * 1024; 26 27// ---------------------------------------------------------------------------- 28namespace android { 29// ---------------------------------------------------------------------------- 30 31#define BC_EXT_STR "EGL_ANDROID_blob_cache" 32 33// 34// Callback functions passed to EGL. 35// 36static void setBlob(const void* key, EGLsizei keySize, const void* value, 37 EGLsizei valueSize) { 38 egl_cache_t::get()->setBlob(key, keySize, value, valueSize); 39} 40 41static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value, 42 EGLsizei valueSize) { 43 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() { 55} 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) { 63 Mutex::Autolock lock(mMutex); 64 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 86 eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob, 87 android::getBlob); 88 EGLint err = cnx->egl.eglGetError(); 89 if (err != EGL_SUCCESS) { 90 LOGE("eglSetBlobCacheFuncs resulted in an error: %#x", 91 err); 92 } 93 } 94 } 95 } 96 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() { 151} 152 153// ---------------------------------------------------------------------------- 154}; // namespace android 155// ---------------------------------------------------------------------------- 156