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_tls.h" 18 19 #include <stdlib.h> 20 21 #include <cutils/properties.h> 22 #include <log/log.h> 23 #include "CallStack.h" 24 25 namespace android { 26 27 pthread_key_t egl_tls_t::sKey = TLS_KEY_NOT_INITIALIZED; 28 pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT; 29 30 egl_tls_t::egl_tls_t() 31 : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(true) { 32 } 33 34 const char *egl_tls_t::egl_strerror(EGLint err) { 35 switch (err) { 36 case EGL_SUCCESS: return "EGL_SUCCESS"; 37 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; 38 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; 39 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; 40 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; 41 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; 42 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; 43 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; 44 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 45 case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; 46 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; 47 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; 48 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; 49 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; 50 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; 51 default: return "UNKNOWN"; 52 } 53 } 54 55 void egl_tls_t::validateTLSKey() 56 { 57 struct TlsKeyInitializer { 58 static void create() { 59 pthread_key_create(&sKey, (void (*)(void*))&eglReleaseThread); 60 } 61 }; 62 pthread_once(&sOnceKey, TlsKeyInitializer::create); 63 } 64 65 void egl_tls_t::setErrorEtcImpl( 66 const char* caller, int line, EGLint error, bool quiet) { 67 validateTLSKey(); 68 egl_tls_t* tls = getTLS(); 69 if (tls->error != error) { 70 if (!quiet) { 71 ALOGE("%s:%d error %x (%s)", 72 caller, line, error, egl_strerror(error)); 73 char value[PROPERTY_VALUE_MAX]; 74 property_get("debug.egl.callstack", value, "0"); 75 if (atoi(value)) { 76 CallStack::log(LOG_TAG); 77 } 78 } 79 tls->error = error; 80 } 81 } 82 83 bool egl_tls_t::logNoContextCall() { 84 egl_tls_t* tls = getTLS(); 85 if (tls->logCallWithNoContext) { 86 tls->logCallWithNoContext = false; 87 return true; 88 } 89 return false; 90 91 } 92 93 egl_tls_t* egl_tls_t::getTLS() { 94 egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 95 if (tls == 0) { 96 tls = new egl_tls_t; 97 pthread_setspecific(sKey, tls); 98 } 99 return tls; 100 } 101 102 void egl_tls_t::clearTLS() { 103 if (sKey != TLS_KEY_NOT_INITIALIZED) { 104 egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 105 if (tls) { 106 pthread_setspecific(sKey, 0); 107 delete tls; 108 } 109 } 110 } 111 112 void egl_tls_t::clearError() { 113 // This must clear the error from all the underlying EGL implementations as 114 // well as the EGL wrapper layer. 115 eglGetError(); 116 } 117 118 EGLint egl_tls_t::getError() { 119 if (sKey == TLS_KEY_NOT_INITIALIZED) { 120 return EGL_SUCCESS; 121 } 122 egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 123 if (!tls) { 124 return EGL_SUCCESS; 125 } 126 EGLint error = tls->error; 127 tls->error = EGL_SUCCESS; 128 return error; 129 } 130 131 void egl_tls_t::setContext(EGLContext ctx) { 132 validateTLSKey(); 133 getTLS()->ctx = ctx; 134 } 135 136 EGLContext egl_tls_t::getContext() { 137 if (sKey == TLS_KEY_NOT_INITIALIZED) { 138 return EGL_NO_CONTEXT; 139 } 140 egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey); 141 if (!tls) return EGL_NO_CONTEXT; 142 return tls->ctx; 143 } 144 145 146 } // namespace android 147