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