• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = -1;
33 pthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER;
34 
egl_tls_t()35 egl_tls_t::egl_tls_t()
36     : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE), dbg(0) {
37 }
38 
egl_strerror(EGLint err)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 
validateTLSKey()60 void egl_tls_t::validateTLSKey()
61 {
62     if (sKey == -1) {
63         pthread_mutex_lock(&sLockKey);
64         if (sKey == -1)
65             pthread_key_create(&sKey, NULL);
66         pthread_mutex_unlock(&sLockKey);
67     }
68 }
69 
setErrorEtcImpl(const char * caller,int line,EGLint error,bool quiet)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             LOGE("%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;
82                 stack.update();
83                 stack.dump();
84             }
85         }
86         tls->error = error;
87     }
88 }
89 
logNoContextCall()90 bool egl_tls_t::logNoContextCall() {
91     egl_tls_t* tls = getTLS();
92     if (tls->logCallWithNoContext == true) {
93         tls->logCallWithNoContext = false;
94         return true;
95     }
96     return false;
97 }
98 
getTLS()99 egl_tls_t* egl_tls_t::getTLS() {
100     egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
101     if (tls == 0) {
102         tls = new egl_tls_t;
103         pthread_setspecific(sKey, tls);
104     }
105     return tls;
106 }
107 
clearTLS()108 void egl_tls_t::clearTLS() {
109     if (sKey != -1) {
110         egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
111         if (tls) {
112             delete tls;
113             pthread_setspecific(sKey, 0);
114         }
115     }
116 }
117 
clearError()118 void egl_tls_t::clearError() {
119     // This must clear the error from all the underlying EGL implementations as
120     // well as the EGL wrapper layer.
121     eglGetError();
122 }
123 
getError()124 EGLint egl_tls_t::getError() {
125     if (sKey == -1)
126         return EGL_SUCCESS;
127     egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
128     if (!tls) return EGL_SUCCESS;
129     EGLint error = tls->error;
130     tls->error = EGL_SUCCESS;
131     return error;
132 }
133 
setContext(EGLContext ctx)134 void egl_tls_t::setContext(EGLContext ctx) {
135     validateTLSKey();
136     getTLS()->ctx = ctx;
137 }
138 
getContext()139 EGLContext egl_tls_t::getContext() {
140     if (sKey == -1)
141         return EGL_NO_CONTEXT;
142     egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey);
143     if (!tls) return EGL_NO_CONTEXT;
144     return tls->ctx;
145 }
146 
147 
148 } // namespace android
149