1 /*
2 * Copyright (C) 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 "GLcommon/GLDispatch.h"
18 #include "GLcommon/GLLibrary.h"
19
20 #include "aemu/base/synchronization/Lock.h"
21 #include "aemu/base/SharedLibrary.h"
22 #include "host-common/logging.h"
23
24
25 #ifdef __linux__
26 #include <GL/glx.h>
27 #elif defined(WIN32)
28 #include <windows.h>
29 #endif
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <unordered_map>
34
35 typedef GlLibrary::GlFunctionPointer GL_FUNC_PTR;
36
getGLFuncAddress(const char * funcName,GlLibrary * glLib)37 static GL_FUNC_PTR getGLFuncAddress(const char *funcName, GlLibrary* glLib) {
38 return glLib->findSymbol(funcName);
39 }
40
41 static const std::unordered_map<std::string, std::string> sAliasExtra = {
42 {"glDepthRange", "glDepthRangef"},
43 {"glDepthRangef", "glDepthRange"},
44 {"glClearDepth", "glClearDepthf"},
45 {"glClearDepthf", "glClearDepth"},
46 };
47
48 #define LOAD_GL_FUNC(return_type, func_name, signature, args) do { \
49 if (!func_name) { \
50 void* address = (void *)getGLFuncAddress(#func_name, glLib); \
51 /*Check alias*/ \
52 if (!address) { \
53 address = (void *)getGLFuncAddress(#func_name "OES", glLib); \
54 if (address) GL_LOG("%s not found, using %sOES", #func_name, #func_name); \
55 } \
56 if (!address) { \
57 address = (void *)getGLFuncAddress(#func_name "EXT", glLib); \
58 if (address) GL_LOG("%s not found, using %sEXT", #func_name, #func_name); \
59 } \
60 if (!address) { \
61 address = (void *)getGLFuncAddress(#func_name "ARB", glLib); \
62 if (address) GL_LOG("%s not found, using %sARB", #func_name, #func_name); \
63 } \
64 if (!address) { \
65 const auto& it = sAliasExtra.find(#func_name); \
66 if (it != sAliasExtra.end()) { \
67 address = (void *)getGLFuncAddress(it->second.c_str(), glLib); \
68 } \
69 } \
70 if (address) { \
71 func_name = (__typeof__(func_name))(address); \
72 } else { \
73 GL_LOG("%s not found", #func_name); \
74 func_name = nullptr; \
75 } \
76 } \
77 } while (0);
78
79 #define LOAD_GLEXT_FUNC(return_type, func_name, signature, args) do { \
80 if (!func_name) { \
81 void* address = (void *)getGLFuncAddress(#func_name, glLib); \
82 if (address) { \
83 func_name = (__typeof__(func_name))(address); \
84 } else { \
85 func_name = (__typeof__(func_name))((void*)eglGPA(#func_name)); \
86 } \
87 } \
88 } while (0);
89
90 // Define dummy functions, only for non-extensions.
91
92 #define RETURN_void return
93 #define RETURN_GLboolean return GL_FALSE
94 #define RETURN_GLint return 0
95 #define RETURN_GLuint return 0U
96 #define RETURN_GLenum return 0
97 #define RETURN_int return 0
98 #define RETURN_GLconstubyteptr return NULL
99
100 #define RETURN_(x) RETURN_ ## x
101
102 #define DEFINE_DUMMY_FUNCTION(return_type, func_name, signature, args) \
103 static return_type dummy_##func_name signature { \
104 assert(0); \
105 RETURN_(return_type); \
106 }
107
108 #define DEFINE_DUMMY_EXTENSION_FUNCTION(return_type, func_name, signature, args) \
109 // nothing here
110
111 // Initializing static GLDispatch members*/
112
113 android::base::Lock GLDispatch::s_lock;
114
115 #define GL_DISPATCH_DEFINE_POINTER(return_type, function_name, signature, args) \
116 return_type (*GLDispatch::function_name) signature = NULL;
117
LIST_GLES_FUNCTIONS(GL_DISPATCH_DEFINE_POINTER,GL_DISPATCH_DEFINE_POINTER)118 LIST_GLES_FUNCTIONS(GL_DISPATCH_DEFINE_POINTER, GL_DISPATCH_DEFINE_POINTER)
119
120 #if defined(ENABLE_DISPATCH_LOG)
121
122 // With dispatch debug logging enabled, the original loaded function pointers
123 // are moved to the "_underlying" suffixed function pointers and then the non
124 // suffixed functions pointers are updated to be the "_dispatchDebugLogWrapper"
125 // suffixed functions from the ".impl" files. For example,
126 //
127 // void glEnable_dispatchDebugLogWrapper(GLenum cap) {
128 // DISPATCH_DEBUG_LOG("glEnable(cap:%d)", cap);
129 // GLDispatch::glEnable_underlying(cap);
130 // }
131 //
132 // GLDispatch::glEnable_underlying = dlsym(lib, "glEnable");
133 // GLDispatch::glEnable = glEnable_dispatchLoggingWrapper;
134
135 #include "OpenGLESDispatch/gles_common_dispatch_logging_wrappers.impl"
136 #include "OpenGLESDispatch/gles_extensions_dispatch_logging_wrappers.impl"
137 #include "OpenGLESDispatch/gles1_only_dispatch_logging_wrappers.impl"
138 #include "OpenGLESDispatch/gles1_extensions_dispatch_logging_wrappers.impl"
139 #include "OpenGLESDispatch/gles2_only_dispatch_logging_wrappers.impl"
140 #include "OpenGLESDispatch/gles2_extensions_dispatch_logging_wrappers.impl"
141 #include "OpenGLESDispatch/gles3_only_dispatch_logging_wrappers.impl"
142 #include "OpenGLESDispatch/gles3_extensions_dispatch_logging_wrappers.impl"
143 #include "OpenGLESDispatch/gles31_only_dispatch_logging_wrappers.impl"
144 #include "OpenGLESDispatch/gles32_only_dispatch_logging_wrappers.impl"
145
146 #define LOAD_GL_FUNC_DEBUG_LOG_WRAPPER(return_type, func_name, signature, args) do { \
147 func_name##_underlying = func_name; \
148 func_name = func_name##_dispatchLoggingWrapper; \
149 } while(0);
150
151 #define LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER(return_type, func_name, signature, args) do { \
152 func_name##_underlying = func_name; \
153 func_name = func_name##_dispatchLoggingWrapper; \
154 } while (0);
155
156 #define GL_DISPATCH_DEFINE_UNDERLYING_POINTER(return_type, function_name, signature, args) \
157 return_type (*GLDispatch::function_name##_underlying) signature = NULL;
158
159 LIST_GLES_FUNCTIONS(GL_DISPATCH_DEFINE_UNDERLYING_POINTER, GL_DISPATCH_DEFINE_UNDERLYING_POINTER)
160
161 #else
162
163 #define LOAD_GL_FUNC_DEBUG_LOG_WRAPPER(return_type, func_name, signature, args)
164 #define LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER(return_type, func_name, signature, args)
165
166 #endif
167
168 // Constructor.
169 GLDispatch::GLDispatch() : m_isLoaded(false) {}
170
isInitialized() const171 bool GLDispatch::isInitialized() const {
172 return m_isLoaded;
173 }
174
getGLESVersion() const175 GLESVersion GLDispatch::getGLESVersion() const {
176 return m_version;
177 }
178
dispatchFuncs(GLESVersion version,GlLibrary * glLib,EGLGetProcAddressFunc eglGPA)179 void GLDispatch::dispatchFuncs(GLESVersion version, GlLibrary* glLib, EGLGetProcAddressFunc eglGPA) {
180 android::base::AutoLock mutex(s_lock);
181 if(m_isLoaded)
182 return;
183
184 /* Loading OpenGL functions which are needed for implementing BOTH GLES 1.1 & GLES 2.0*/
185 LIST_GLES_COMMON_FUNCTIONS(LOAD_GL_FUNC)
186 LIST_GLES_COMMON_FUNCTIONS(LOAD_GL_FUNC_DEBUG_LOG_WRAPPER)
187
188 LIST_GLES_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
189 LIST_GLES_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
190
191 /* Load both GLES1 and GLES2. On core profile, GLES 1 implementation will
192 * require GLES 3 function supports and set version to GLES_3_0. Thus
193 * we cannot really tell if the dispatcher is used for GLES1 or GLES2, so
194 * let's just load both of them.
195 */
196 LIST_GLES1_ONLY_FUNCTIONS(LOAD_GL_FUNC)
197 LIST_GLES1_ONLY_FUNCTIONS(LOAD_GL_FUNC_DEBUG_LOG_WRAPPER)
198
199 LIST_GLES1_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
200 LIST_GLES1_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
201
202 LIST_GLES2_ONLY_FUNCTIONS(LOAD_GL_FUNC)
203 LIST_GLES2_ONLY_FUNCTIONS(LOAD_GL_FUNC_DEBUG_LOG_WRAPPER)
204
205 LIST_GLES2_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
206 LIST_GLES2_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
207
208 /* Load OpenGL ES 3.x functions through 3.1. Not all are supported;
209 * leave it up to EGL to determine support level. */
210
211 if (version >= GLES_3_0) {
212 LIST_GLES3_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC)
213 LIST_GLES3_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
214
215 LIST_GLES3_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
216 LIST_GLES3_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
217 }
218
219 if (version >= GLES_3_1) {
220 LIST_GLES31_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC)
221 LIST_GLES31_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC_DEBUG_LOG_WRAPPER)
222 }
223
224 const char* kAngleName = "ANGLE";
225 const char* glString = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
226 if (glString && 0 == strncmp(glString, kAngleName, strlen(kAngleName))) {
227 // ANGLE loads a bad glGetTexImage. (No it is not the dummy.)
228 // Overwrite it.
229 void* _glGetTexImageANGLE =
230 (void*)getGLFuncAddress("glGetTexImageANGLE", glLib);
231 if (_glGetTexImageANGLE) {
232 glGetTexImage = (__typeof__(
233 glGetTexImage))_glGetTexImageANGLE;
234 }
235 }
236
237 m_isLoaded = true;
238 m_version = version;
239 }
240