• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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