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 17311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian#include "egl_tls.h" 18311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian 19a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <stdlib.h> 20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 21ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian#include <cutils/properties.h> 227823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 235f1af0457a8a6c2922a0d5e55cb6c248ec539f7fMathias Agopian#include "CallStack.h" 24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android { 26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 274e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopianpthread_key_t egl_tls_t::sKey = TLS_KEY_NOT_INITIALIZED; 284e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopianpthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT; 29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_tls_t::egl_tls_t() 31311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(true) { 32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianconst char *egl_tls_t::egl_strerror(EGLint err) { 35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian switch (err) { 36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_SUCCESS: return "EGL_SUCCESS"; 37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; 38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; 39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; 40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; 41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; 42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; 43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; 44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; 46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; 47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; 48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; 49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; 50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; 51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian default: return "UNKNOWN"; 52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 54518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::validateTLSKey() 56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{ 574e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian struct TlsKeyInitializer { 584e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian static void create() { 594e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian pthread_key_create(&sKey, (void (*)(void*))&eglReleaseThread); 604e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian } 614e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian }; 624e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian pthread_once(&sOnceKey, TlsKeyInitializer::create); 63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 650e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopianvoid egl_tls_t::setErrorEtcImpl( 660e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian const char* caller, int line, EGLint error, bool quiet) { 67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian validateTLSKey(); 68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = getTLS(); 69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls->error != error) { 700e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian if (!quiet) { 71e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s:%d error %x (%s)", 720e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian caller, line, error, egl_strerror(error)); 730e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian char value[PROPERTY_VALUE_MAX]; 740e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian property_get("debug.egl.callstack", value, "0"); 750e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian if (atoi(value)) { 765f1af0457a8a6c2922a0d5e55cb6c248ec539f7fMathias Agopian CallStack::log(LOG_TAG); 770e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian } 78ecfe091af3e3e5d7165fe64a5f9c84c4576a6c06Mathias Agopian } 790e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian tls->error = error; 80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianbool egl_tls_t::logNoContextCall() { 84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = getTLS(); 85311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian if (tls->logCallWithNoContext) { 86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls->logCallWithNoContext = false; 87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return true; 88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return false; 90311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian 91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_tls_t* egl_tls_t::getTLS() { 94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls == 0) { 96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls = new egl_tls_t; 97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_setspecific(sKey, tls); 98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return tls; 100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::clearTLS() { 1034e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian if (sKey != TLS_KEY_NOT_INITIALIZED) { 104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (tls) { 106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian pthread_setspecific(sKey, 0); 1074e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian delete tls; 108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian } 110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::clearError() { 113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // This must clear the error from all the underlying EGL implementations as 114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian // well as the EGL wrapper layer. 115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian eglGetError(); 116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint egl_tls_t::getError() { 1194e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian if (sKey == TLS_KEY_NOT_INITIALIZED) { 120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return EGL_SUCCESS; 1214e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian } 122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); 1234e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian if (!tls) { 1244e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian return EGL_SUCCESS; 1254e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian } 126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian EGLint error = tls->error; 127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian tls->error = EGL_SUCCESS; 128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return error; 129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_tls_t::setContext(EGLContext ctx) { 132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian validateTLSKey(); 133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian getTLS()->ctx = ctx; 134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext egl_tls_t::getContext() { 1374e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian if (sKey == TLS_KEY_NOT_INITIALIZED) { 138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return EGL_NO_CONTEXT; 1394e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian } 140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey); 141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian if (!tls) return EGL_NO_CONTEXT; 142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian return tls->ctx; 143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} 144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian 146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} // namespace android 147