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