1 /*
2 ** Copyright 2007, 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 #ifndef ANDROID_GLES_CM_HOOKS_H
18 #define ANDROID_GLES_CM_HOOKS_H
19
20 #include <ctype.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <pthread.h>
25
26 #include <EGL/egl.h>
27 #include <EGL/eglext.h>
28 #include <GLES/gl.h>
29 #include <GLES/glext.h>
30 #include <GLES2/gl2.h>
31 #include <GLES2/gl2ext.h>
32
33 #if !defined(__arm__)
34 #define USE_SLOW_BINDING 1
35 #else
36 #define USE_SLOW_BINDING 0
37 #endif
38 #undef NELEM
39 #define NELEM(x) (sizeof(x)/sizeof(*(x)))
40 #define MAX_NUMBER_OF_GL_EXTENSIONS 64
41
42
43 #if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
44 #define USE_FAST_TLS_KEY 1
45 #else
46 #define USE_FAST_TLS_KEY 0
47 #endif
48
49 #if USE_FAST_TLS_KEY
50 # include <bionic_tls.h> /* special private C library header */
51 #endif
52
53 // ----------------------------------------------------------------------------
54 namespace android {
55 // ----------------------------------------------------------------------------
56
57 // EGLDisplay are global, not attached to a given thread
58 const unsigned int NUM_DISPLAYS = 1;
59
60 enum {
61 IMPL_HARDWARE = 0,
62 IMPL_SOFTWARE,
63 IMPL_NUM_IMPLEMENTATIONS
64 };
65
66 enum {
67 GLESv1_INDEX = 0,
68 GLESv2_INDEX = 1,
69 };
70
71 // ----------------------------------------------------------------------------
72
73 // GL / EGL hooks
74
75 #undef GL_ENTRY
76 #undef EGL_ENTRY
77 #define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
78 #define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
79
80 struct egl_t {
81 #include "EGL/egl_entries.in"
82 };
83
84 struct gl_hooks_t {
85 struct gl_t {
86 #include "entries.in"
87 } gl;
88 struct gl_ext_t {
89 __eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
90 } ext;
91 };
92 #undef GL_ENTRY
93 #undef EGL_ENTRY
94
95
96 // ----------------------------------------------------------------------------
97
98 extern gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
99 extern gl_hooks_t gHooksNoContext;
100 extern pthread_key_t gGLWrapperKey;
101 extern "C" void gl_unimplemented();
102
103 extern char const * const gl_names[];
104 extern char const * const egl_names[];
105
106 // ----------------------------------------------------------------------------
107
108 #if USE_FAST_TLS_KEY
109
110 // We have a dedicated TLS slot in bionic
get_tls_hooks()111 static inline gl_hooks_t const * volatile * get_tls_hooks() {
112 volatile void *tls_base = __get_tls();
113 gl_hooks_t const * volatile * tls_hooks =
114 reinterpret_cast<gl_hooks_t const * volatile *>(tls_base);
115 return tls_hooks;
116 }
117
setGlThreadSpecific(gl_hooks_t const * value)118 static inline void setGlThreadSpecific(gl_hooks_t const *value) {
119 gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
120 tls_hooks[TLS_SLOT_OPENGL_API] = value;
121 }
122
getGlThreadSpecific()123 static gl_hooks_t const* getGlThreadSpecific() {
124 gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
125 gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API];
126 if (hooks) return hooks;
127 return &gHooksNoContext;
128 }
129
130 #else
131
setGlThreadSpecific(gl_hooks_t const * value)132 static inline void setGlThreadSpecific(gl_hooks_t const *value) {
133 pthread_setspecific(gGLWrapperKey, value);
134 }
135
getGlThreadSpecific()136 static gl_hooks_t const* getGlThreadSpecific() {
137 gl_hooks_t const* hooks = static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
138 if (hooks) return hooks;
139 return &gHooksNoContext;
140 }
141
142 #endif
143
144
145 // ----------------------------------------------------------------------------
146 }; // namespace android
147 // ----------------------------------------------------------------------------
148
149 #endif /* ANDROID_GLES_CM_HOOKS_H */
150