1518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/* 2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2011, The Android Open Source Project 3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** 4518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License"); 5518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** you may not use this file except in compliance with the License. 6518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** You may obtain a copy of the License at 7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** 8518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** http://www.apache.org/licenses/LICENSE-2.0 9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** 10518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Unless required by applicable law or agreed to in writing, software 11518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS, 12518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** See the License for the specific language governing permissions and 14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License. 15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */ 16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 17ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian#include <stdlib.h> 18518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <pthread.h> 19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <cutils/log.h> 21ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian#include <cutils/properties.h> 22ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian 23ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian#include <utils/CallStack.h> 24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/egl.h> 26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h" 28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android { 31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpthread_key_t egl_tls_t::sKey = -1; 33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianpthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER; 34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_tls_t::egl_tls_t() 360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) { 37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianconst char *egl_tls_t::egl_strerror(EGLint err) { 40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switch (err) { 41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_SUCCESS: return "EGL_SUCCESS"; 42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; 43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; 44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; 45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; 46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; 47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; 48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; 49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; 51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; 52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; 53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; 54518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; 55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; 56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian default: return "UNKNOWN"; 57518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::validateTLSKey() 61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{ 62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (sKey == -1) { 63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_mutex_lock(&sLockKey); 64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (sKey == -1) 65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_key_create(&sKey, NULL); 66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_mutex_unlock(&sLockKey); 67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 700e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopianvoid egl_tls_t::setErrorEtcImpl( 710e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian const char* caller, int line, EGLint error, bool quiet) { 72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian validateTLSKey(); 73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = getTLS(); 74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls->error != error) { 750e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian if (!quiet) { 76e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s:%d error %x (%s)", 770e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian caller, line, error, egl_strerror(error)); 780e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian char value[PROPERTY_VALUE_MAX]; 790e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian property_get("debug.egl.callstack", value, "0"); 800e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian if (atoi(value)) { 810e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian CallStack stack; 820e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian stack.update(); 830e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian stack.dump(); 840e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian } 85ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian } 860e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian tls->error = error; 87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianbool egl_tls_t::logNoContextCall() { 91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = getTLS(); 92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls->logCallWithNoContext == true) { 93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls->logCallWithNoContext = false; 94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return true; 95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return false; 97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_tls_t* egl_tls_t::getTLS() { 100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls == 0) { 102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls = new egl_tls_t; 103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_setspecific(sKey, tls); 104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return tls; 106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::clearTLS() { 109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (sKey != -1) { 110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls) { 112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian delete tls; 113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_setspecific(sKey, 0); 114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::clearError() { 119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // This must clear the error from all the underlying EGL implementations as 120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // well as the EGL wrapper layer. 121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian eglGetError(); 122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint egl_tls_t::getError() { 125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (sKey == -1) 126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return EGL_SUCCESS; 127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!tls) return EGL_SUCCESS; 129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian EGLint error = tls->error; 130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls->error = EGL_SUCCESS; 131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return error; 132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::setContext(EGLContext ctx) { 135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian validateTLSKey(); 136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getTLS()->ctx = ctx; 137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext egl_tls_t::getContext() { 140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (sKey == -1) 141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return EGL_NO_CONTEXT; 142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey); 143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!tls) return EGL_NO_CONTEXT; 144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return tls->ctx; 145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} // namespace android 149