• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 <android/log.h>
18 #include <cstring>
19 #include <EGL/egl.h>
20 #include <GLES3/gl3.h>
21 #include <string>
22 #include <string.h>
23 #include <unordered_map>
24 
25 #define xstr(a) str(a)
26 #define str(a) #a
27 
28 #define LOG_TAG "glesLayer" xstr(LAYERNAME)
29 
30 #define ALOGI(msg, ...) \
31     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
32 
33 
34 // Announce if anything loads this layer.  LAYERNAME is defined in Android.mk
35 class StaticLogMessage {
36     public:
StaticLogMessage(const char * msg)37         StaticLogMessage(const char* msg) {
38             ALOGI("%s", msg);
39     }
40 };
41 StaticLogMessage g_initMessage("glesLayer" xstr(LAYERNAME) " loaded");
42 
43 typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;
44 typedef void* (*PFNEGLGETNEXTLAYERPROCADDRESSPROC)(void*, const char*);
45 
46 namespace {
47 
48 std::unordered_map<std::string, EGLFuncPointer> funcMap;
49 
glesLayer_glCompileShaderA(GLuint shader)50 EGLAPI void EGLAPIENTRY glesLayer_glCompileShaderA (GLuint shader) {
51     ALOGI("%s%u", "glesLayer_glCompileShaderA called with parameter ", shader);
52 
53     if (funcMap.find("glCompileShader") == funcMap.end())
54         ALOGI("%s", "Unable to find funcMap entry for glCompileShader");
55 
56     EGLFuncPointer entry = funcMap["glCompileShader"];
57 
58     PFNGLCOMPILESHADERPROC next = reinterpret_cast<PFNGLCOMPILESHADERPROC>(entry);
59 
60     next(shader);
61 }
62 
glesLayer_glCompileShaderB(GLuint shader)63 EGLAPI void EGLAPIENTRY glesLayer_glCompileShaderB (GLuint shader) {
64     ALOGI("%s%u", "glesLayer_CompileShaderB called with parameter ", shader);
65 
66     if (funcMap.find("glCompileShader") == funcMap.end())
67         ALOGI("%s", "Unable to find funcMap entry for glCompileShader");
68 
69     EGLFuncPointer entry = funcMap["glCompileShader"];
70 
71     PFNGLCOMPILESHADERPROC next = reinterpret_cast<PFNGLCOMPILESHADERPROC>(entry);
72 
73     next(shader);
74 }
75 
glesLayer_glDrawArraysInstanced(GLenum mode,GLint first,GLsizei count,GLsizei instancecount)76 EGLAPI void EGLAPI glesLayer_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
77     ALOGI("%s %i, %i, %i", "glesLayer_glDrawArraysInstanced called with parameters (minus GLenum):", first, count, instancecount);
78 
79     if (funcMap.find("glDrawArraysInstanced") == funcMap.end())
80         ALOGI("%s", "Unable to find funcMap entry for glDrawArraysInstanced");
81 
82     EGLFuncPointer entry = funcMap["glDrawArraysInstanced"];
83 
84     PFNGLDRAWARRAYSINSTANCEDPROC next = reinterpret_cast<PFNGLDRAWARRAYSINSTANCEDPROC>(entry);
85 
86     next(mode, first, count, instancecount);
87 }
88 
glesLayer_glBindBuffer(GLenum target,GLuint buffer)89 EGLAPI void EGLAPIENTRY glesLayer_glBindBuffer(GLenum target, GLuint buffer) {
90     ALOGI("%s %i", "glesLayer_glBindBuffer called with parameters (minus GLenum):", buffer);
91 
92     if (funcMap.find("glBindBuffer") == funcMap.end())
93         ALOGI("%s", "Unable to find funcMap entry for glBindBuffer");
94 
95     EGLFuncPointer entry = funcMap["glBindBuffer"];
96 
97     PFNGLBINDBUFFERPROC next = reinterpret_cast<PFNGLBINDBUFFERPROC>(entry);
98 
99     next(target, buffer);
100 }
101 
glesLayer_glGetString(GLenum name)102 EGLAPI const GLubyte* EGLAPIENTRY glesLayer_glGetString(GLenum name) {
103     ALOGI("%s %lu", "glesLayer_glGetString called with parameters:", (unsigned long)name);
104 
105     if (funcMap.find("glGetString") == funcMap.end())
106         ALOGI("%s", "Unable to find funcMap entry for glGetString");
107 
108     EGLFuncPointer entry = funcMap["glGetString"];
109 
110     PFNGLGETSTRINGPROC next = reinterpret_cast<PFNGLGETSTRINGPROC>(entry);
111 
112     return next(name);
113 }
114 
glesLayer_eglGetDisplay(EGLNativeDisplayType display_type)115 EGLAPI EGLDisplay EGLAPIENTRY glesLayer_eglGetDisplay(EGLNativeDisplayType display_type) {
116     ALOGI("%s %lu", "glesLayer_eglGetDisplay called with parameters:", (unsigned long)display_type);
117 
118     if (funcMap.find("eglGetDisplay") == funcMap.end())
119         ALOGI("%s", "Unable to find funcMap entry for eglGetDisplay");
120 
121     EGLFuncPointer entry = funcMap["eglGetDisplay"];
122 
123     typedef EGLDisplay (*PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType);
124     PFNEGLGETDISPLAYPROC next = reinterpret_cast<PFNEGLGETDISPLAYPROC>(entry);
125 
126     return next(display_type);
127 }
128 
glesLayer_eglInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)129 EGLAPI EGLBoolean EGLAPIENTRY glesLayer_eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
130     ALOGI("%s %lu %li %li", "glesLayer_eglInitialize called with parameters:", (unsigned long)dpy, major ? (long)*major : 0, minor ? (long)*minor : 0);
131 
132     if (funcMap.find("eglInitialize") == funcMap.end())
133         ALOGI("%s", "Unable to find funcMap entry for eglInitialize");
134 
135     EGLFuncPointer entry = funcMap["eglInitialize"];
136 
137     typedef EGLBoolean (*PFNEGLINITIALIZEPROC)(EGLDisplay, EGLint*, EGLint*);
138     PFNEGLINITIALIZEPROC next = reinterpret_cast<PFNEGLINITIALIZEPROC>(entry);
139 
140     return next(dpy, major, minor);
141 }
142 
glesLayer_eglChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)143 EGLAPI EGLBoolean EGLAPIENTRY glesLayer_eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) {
144 
145     const char* msg = "glesLayer_eglChooseConfig called in glesLayer" xstr(LAYERNAME);
146     ALOGI("%s", msg);
147 
148     if (funcMap.find("eglChooseConfig") == funcMap.end())
149         ALOGI("%s", "Unable to find funcMap entry for eglChooseConfig");
150 
151     EGLFuncPointer entry = funcMap["eglChooseConfig"];
152 
153     typedef EGLBoolean (*PFNEGLCHOOSECONFIGPROC)(EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);
154     PFNEGLCHOOSECONFIGPROC next = reinterpret_cast<PFNEGLCHOOSECONFIGPROC>(entry);
155 
156     return next(dpy, attrib_list, configs, config_size, num_config);
157 }
158 
glesLayer_eglSwapBuffersWithDamageKHR(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)159 EGLAPI EGLBoolean EGLAPIENTRY glesLayer_eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects) {
160 
161     const char* msg = "glesLayer_eglSwapBuffersWithDamageKHR called in glesLayer" xstr(LAYERNAME);
162     ALOGI("%s", msg);
163 
164     if (funcMap.find("eglSwapBuffersWithDamageKHR") == funcMap.end())
165         ALOGI("%s", "Unable to find funcMap entry for eglSwapBuffersWithDamageKHR");
166 
167     EGLFuncPointer entry = funcMap["eglSwapBuffersWithDamageKHR"];
168 
169     typedef EGLBoolean (*PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC)(EGLDisplay, EGLSurface, EGLint*, EGLint);
170     PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC next = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>(entry);
171 
172     return next(dpy, surface, rects, n_rects);
173 }
174 
glesLayer_eglGetProcAddress(const char * procname)175 EGLAPI void* EGLAPIENTRY glesLayer_eglGetProcAddress (const char* procname) {
176 
177     const char* msg = "glesLayer_eglGetProcAddress called in glesLayer" xstr(LAYERNAME) " for:";
178     ALOGI("%s%s", msg, procname);
179 
180     if (funcMap.find("eglGetProcAddress") == funcMap.end())
181         ALOGI("%s", "Unable to find funcMap entry for eglGetProcAddress");
182 
183     EGLFuncPointer entry = funcMap["eglGetProcAddress"];
184 
185     typedef void* (*PFNEGLGETPROCADDRESSPROC)(const char*);
186     PFNEGLGETPROCADDRESSPROC next = reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(entry);
187 
188     return next(procname);
189 }
190 
eglGPA(const char * funcName)191 EGLAPI EGLFuncPointer EGLAPIENTRY eglGPA(const char* funcName) {
192 
193 #define GETPROCADDR(func) if(!strcmp(funcName, #func)) { \
194 ALOGI("%s%s%s", "Returning glesLayer_" #func " for ", funcName, " in eglGPA"); \
195 return (EGLFuncPointer)glesLayer_##func; \
196 }
197 
198     if (strcmp("A", xstr(LAYERNAME)) == 0) {
199 
200         const char* targetFunc = "glCompileShader";
201         if (strcmp(targetFunc, funcName) == 0) {
202             ALOGI("%s%s%s", "Returning glesLayer_glCompileShaderA for ", funcName, " in eglGPA");
203             return (EGLFuncPointer)glesLayer_glCompileShaderA;
204         }
205 
206         GETPROCADDR(glDrawArraysInstanced);
207 
208     } else if (strcmp("B", xstr(LAYERNAME)) == 0) {
209 
210         const char* targetFunc = "glCompileShader";
211         if (strcmp(targetFunc, funcName) == 0) {
212             ALOGI("%s%s%s", "Returning glesLayer_glCompileShaderB for ", funcName, " in eglGPA");
213             return (EGLFuncPointer)glesLayer_glCompileShaderB;
214         }
215 
216         GETPROCADDR(glBindBuffer);
217     }
218 
219     GETPROCADDR(glGetString);
220     GETPROCADDR(eglGetDisplay);
221     GETPROCADDR(eglInitialize);
222     GETPROCADDR(eglChooseConfig);
223     GETPROCADDR(eglSwapBuffersWithDamageKHR);
224     GETPROCADDR(eglGetProcAddress);
225 
226     // Don't return anything for unrecognized functions
227     return nullptr;
228 }
229 
glesLayer_InitializeLayer(void * layer_id,PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address)230 EGLAPI void EGLAPIENTRY glesLayer_InitializeLayer(void* layer_id, PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {
231     ALOGI("%s%llu%s%llu", "glesLayer_InitializeLayer called with layer_id (", (unsigned long long) layer_id,
232                               ") get_next_layer_proc_address (", (unsigned long long) get_next_layer_proc_address);
233 
234     // Pick a real function to look up and test the pointer we've been handed
235     const char* func = "eglGetProcAddress";
236 
237     ALOGI("%s%s%s%llu%s%llu%s", "Looking up address of ", func,
238                                 " using get_next_layer_proc_address (", (unsigned long long) get_next_layer_proc_address,
239                                 ") with layer_id (", (unsigned long long) layer_id,
240                                 ")");
241 
242     void* gpa = get_next_layer_proc_address(layer_id, func);
243 
244     // Pick a fake function to look up and test the pointer we've been handed
245     func = "eglFoo";
246 
247     ALOGI("%s%s%s%llu%s%llu%s", "Looking up address of ", func,
248                                 " using get_next_layer_proc_address (", (unsigned long long) get_next_layer_proc_address,
249                                 ") with layer_id (", (unsigned long long) layer_id,
250                                 ")");
251 
252     gpa = get_next_layer_proc_address(layer_id, func);
253 
254     ALOGI("%s%llu%s%s", "Got back (", (unsigned long long) gpa, ") for ", func);
255 }
256 
glesLayer_GetLayerProcAddress(const char * funcName,EGLFuncPointer next)257 EGLAPI EGLFuncPointer EGLAPIENTRY glesLayer_GetLayerProcAddress(const char* funcName, EGLFuncPointer next) {
258 
259     EGLFuncPointer entry = eglGPA(funcName);
260 
261     if (entry != nullptr) {
262         ALOGI("%s%s%s%llu%s", "Setting up glesLayer version of ", funcName, " calling down with: next (", (unsigned long long) next, ")");
263         funcMap[std::string(funcName)] = next;
264         return entry;
265     }
266 
267     // If the layer does not intercept the function, just return original func pointer
268     return next;
269 }
270 
271 }  // namespace
272 
273 extern "C" {
274 
AndroidGLESLayer_Initialize(void * layer_id,PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address)275     __attribute((visibility("default"))) EGLAPI void AndroidGLESLayer_Initialize(void* layer_id,
276             PFNEGLGETNEXTLAYERPROCADDRESSPROC get_next_layer_proc_address) {
277         return (void)glesLayer_InitializeLayer(layer_id, get_next_layer_proc_address);
278     }
279 
AndroidGLESLayer_GetProcAddress(const char * funcName,EGLFuncPointer next)280     __attribute((visibility("default"))) EGLAPI void* AndroidGLESLayer_GetProcAddress(const char *funcName, EGLFuncPointer next) {
281         return (void*)glesLayer_GetLayerProcAddress(funcName, next);
282     }
283 }
284