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