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 "base/Lock.h"
21 #include "base/SharedLibrary.h"
22
23 #include "ErrorLog.h"
24
25 // #define GL_LOG(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
26 #define GL_LOG(fmt,...)
27
28 #ifdef __linux__
29 #include <GL/glx.h>
30 #elif defined(WIN32)
31 #include <windows.h>
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <unordered_map>
37
38 typedef GlLibrary::GlFunctionPointer GL_FUNC_PTR;
39
getGLFuncAddress(const char * funcName,GlLibrary * glLib)40 static GL_FUNC_PTR getGLFuncAddress(const char *funcName, GlLibrary* glLib) {
41 return glLib->findSymbol(funcName);
42 }
43
44 static const std::unordered_map<std::string, std::string> sAliasExtra = {
45 {"glDepthRange", "glDepthRangef"},
46 {"glDepthRangef", "glDepthRange"},
47 {"glClearDepth", "glClearDepthf"},
48 {"glClearDepthf", "glClearDepth"},
49 };
50
51 #define LOAD_GL_FUNC(return_type, func_name, signature, args) do { \
52 if (!func_name) { \
53 void* address = (void *)getGLFuncAddress(#func_name, glLib); \
54 /*Check alias*/ \
55 if (!address) { \
56 address = (void *)getGLFuncAddress(#func_name "OES", glLib); \
57 if (address) GL_LOG("%s not found, using %sOES", #func_name, #func_name); \
58 } \
59 if (!address) { \
60 address = (void *)getGLFuncAddress(#func_name "EXT", glLib); \
61 if (address) GL_LOG("%s not found, using %sEXT", #func_name, #func_name); \
62 } \
63 if (!address) { \
64 address = (void *)getGLFuncAddress(#func_name "ARB", glLib); \
65 if (address) GL_LOG("%s not found, using %sARB", #func_name, #func_name); \
66 } \
67 if (!address) { \
68 const auto& it = sAliasExtra.find(#func_name); \
69 if (it != sAliasExtra.end()) { \
70 address = (void *)getGLFuncAddress(it->second.c_str(), glLib); \
71 } \
72 } \
73 if (address) { \
74 func_name = (__typeof__(func_name))(address); \
75 } else { \
76 GL_LOG("%s not found", #func_name); \
77 func_name = nullptr; \
78 } \
79 } \
80 } while (0);
81
82 #define LOAD_GLEXT_FUNC(return_type, func_name, signature, args) do { \
83 if (!func_name) { \
84 void* address = (void *)getGLFuncAddress(#func_name, glLib); \
85 if (address) { \
86 func_name = (__typeof__(func_name))(address); \
87 } else { \
88 func_name = (__typeof__(func_name))((void*)eglGPA(#func_name)); \
89 } \
90 } \
91 } while (0);
92
93 // Define dummy functions, only for non-extensions.
94
95 #define RETURN_void return
96 #define RETURN_GLboolean return GL_FALSE
97 #define RETURN_GLint return 0
98 #define RETURN_GLuint return 0U
99 #define RETURN_GLenum return 0
100 #define RETURN_int return 0
101 #define RETURN_GLconstubyteptr return NULL
102
103 #define RETURN_(x) RETURN_ ## x
104
105 #define DEFINE_DUMMY_FUNCTION(return_type, func_name, signature, args) \
106 static return_type dummy_##func_name signature { \
107 assert(0); \
108 RETURN_(return_type); \
109 }
110
111 #define DEFINE_DUMMY_EXTENSION_FUNCTION(return_type, func_name, signature, args) \
112 // nothing here
113
114 // Initializing static GLDispatch members*/
115
116 android::base::Lock GLDispatch::s_lock;
117
118 #define GL_DISPATCH_DEFINE_POINTER(return_type, function_name, signature, args) \
119 return_type (*GLDispatch::function_name) signature = NULL;
120
LIST_GLES_FUNCTIONS(GL_DISPATCH_DEFINE_POINTER,GL_DISPATCH_DEFINE_POINTER)121 LIST_GLES_FUNCTIONS(GL_DISPATCH_DEFINE_POINTER, GL_DISPATCH_DEFINE_POINTER)
122
123 // Constructor.
124 GLDispatch::GLDispatch() : m_isLoaded(false) {}
125
isInitialized() const126 bool GLDispatch::isInitialized() const {
127 return m_isLoaded;
128 }
129
getGLESVersion() const130 GLESVersion GLDispatch::getGLESVersion() const {
131 return m_version;
132 }
133
dispatchFuncs(GLESVersion version,GlLibrary * glLib,EGLGetProcAddressFunc eglGPA)134 void GLDispatch::dispatchFuncs(GLESVersion version, GlLibrary* glLib, EGLGetProcAddressFunc eglGPA) {
135 android::base::AutoLock mutex(s_lock);
136 if(m_isLoaded)
137 return;
138
139 /* Loading OpenGL functions which are needed for implementing BOTH GLES 1.1 & GLES 2.0*/
140 LIST_GLES_COMMON_FUNCTIONS(LOAD_GL_FUNC)
141 LIST_GLES_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
142
143 /* Load both GLES1 and GLES2. On core profile, GLES 1 implementation will
144 * require GLES 3 function supports and set version to GLES_3_0. Thus
145 * we cannot really tell if the dispatcher is used for GLES1 or GLES2, so
146 * let's just load both of them.
147 */
148 LIST_GLES1_ONLY_FUNCTIONS(LOAD_GL_FUNC)
149 LIST_GLES1_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
150 LIST_GLES2_ONLY_FUNCTIONS(LOAD_GL_FUNC)
151 LIST_GLES2_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
152
153 /* Load OpenGL ES 3.x functions through 3.1. Not all are supported;
154 * leave it up to EGL to determine support level. */
155
156 if (version >= GLES_3_0) {
157 LIST_GLES3_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC)
158 LIST_GLES3_EXTENSIONS_FUNCTIONS(LOAD_GLEXT_FUNC)
159 }
160
161 if (version >= GLES_3_1) {
162 LIST_GLES31_ONLY_FUNCTIONS(LOAD_GLEXT_FUNC)
163 }
164
165 m_isLoaded = true;
166 m_version = version;
167 }
168