1 /*
2  * Copyright (C) 2008 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 package android.opengl;
18 
19 import java.io.IOException;
20 import java.io.Writer;
21 
22 import javax.microedition.khronos.egl.EGL;
23 import javax.microedition.khronos.egl.EGL10;
24 import javax.microedition.khronos.egl.EGL11;
25 import javax.microedition.khronos.egl.EGLConfig;
26 import javax.microedition.khronos.egl.EGLContext;
27 import javax.microedition.khronos.egl.EGLDisplay;
28 import javax.microedition.khronos.egl.EGLSurface;
29 
30 class EGLLogWrapper implements EGL11 {
31     private EGL10 mEgl10;
32     Writer mLog;
33     boolean mLogArgumentNames;
34     boolean mCheckError;
35     private int mArgCount;
36 
37 
EGLLogWrapper(EGL egl, int configFlags, Writer log)38     public EGLLogWrapper(EGL egl, int configFlags, Writer log) {
39         mEgl10 = (EGL10) egl;
40         mLog = log;
41         mLogArgumentNames =
42             (GLDebugHelper.CONFIG_LOG_ARGUMENT_NAMES & configFlags) != 0;
43         mCheckError =
44             (GLDebugHelper.CONFIG_CHECK_GL_ERROR & configFlags) != 0;
45     }
46 
eglChooseConfig(EGLDisplay display, int[] attrib_list, EGLConfig[] configs, int config_size, int[] num_config)47     public boolean eglChooseConfig(EGLDisplay display, int[] attrib_list,
48             EGLConfig[] configs, int config_size, int[] num_config) {
49         begin("eglChooseConfig");
50         arg("display", display);
51         arg("attrib_list", attrib_list);
52         arg("config_size", config_size);
53         end();
54 
55         boolean result = mEgl10.eglChooseConfig(display, attrib_list, configs,
56                 config_size, num_config);
57         arg("configs", configs);
58         arg("num_config", num_config);
59         returns(result);
60         checkError();
61         return result;
62     }
63 
eglCopyBuffers(EGLDisplay display, EGLSurface surface, Object native_pixmap)64     public boolean eglCopyBuffers(EGLDisplay display, EGLSurface surface,
65             Object native_pixmap) {
66         begin("eglCopyBuffers");
67         arg("display", display);
68         arg("surface", surface);
69         arg("native_pixmap", native_pixmap);
70         end();
71 
72         boolean result = mEgl10.eglCopyBuffers(display, surface, native_pixmap);
73         returns(result);
74         checkError();
75         return result;
76     }
77 
eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list)78     public EGLContext eglCreateContext(EGLDisplay display, EGLConfig config,
79             EGLContext share_context, int[] attrib_list) {
80         begin("eglCreateContext");
81         arg("display", display);
82         arg("config", config);
83         arg("share_context", share_context);
84         arg("attrib_list", attrib_list);
85         end();
86 
87         EGLContext result = mEgl10.eglCreateContext(display, config,
88                 share_context, attrib_list);
89         returns(result);
90         checkError();
91         return result;
92     }
93 
eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list)94     public EGLSurface eglCreatePbufferSurface(EGLDisplay display,
95             EGLConfig config, int[] attrib_list) {
96         begin("eglCreatePbufferSurface");
97         arg("display", display);
98         arg("config", config);
99         arg("attrib_list", attrib_list);
100         end();
101 
102         EGLSurface result = mEgl10.eglCreatePbufferSurface(display, config,
103                 attrib_list);
104         returns(result);
105         checkError();
106         return result;
107     }
108 
eglCreatePixmapSurface(EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list)109     public EGLSurface eglCreatePixmapSurface(EGLDisplay display,
110             EGLConfig config, Object native_pixmap, int[] attrib_list) {
111         begin("eglCreatePixmapSurface");
112         arg("display", display);
113         arg("config", config);
114         arg("native_pixmap", native_pixmap);
115         arg("attrib_list", attrib_list);
116         end();
117 
118         EGLSurface result = mEgl10.eglCreatePixmapSurface(display, config,
119                 native_pixmap, attrib_list);
120         returns(result);
121         checkError();
122         return result;
123         }
124 
eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list)125     public EGLSurface eglCreateWindowSurface(EGLDisplay display,
126             EGLConfig config, Object native_window, int[] attrib_list) {
127         begin("eglCreateWindowSurface");
128         arg("display", display);
129         arg("config", config);
130         arg("native_window", native_window);
131         arg("attrib_list", attrib_list);
132         end();
133 
134         EGLSurface result = mEgl10.eglCreateWindowSurface(display, config,
135                 native_window, attrib_list);
136         returns(result);
137         checkError();
138         return result;
139     }
140 
eglDestroyContext(EGLDisplay display, EGLContext context)141     public boolean eglDestroyContext(EGLDisplay display, EGLContext context) {
142         begin("eglDestroyContext");
143         arg("display", display);
144         arg("context", context);
145         end();
146 
147         boolean result = mEgl10.eglDestroyContext(display, context);
148         returns(result);
149         checkError();
150         return result;
151     }
152 
eglDestroySurface(EGLDisplay display, EGLSurface surface)153     public boolean eglDestroySurface(EGLDisplay display, EGLSurface surface) {
154         begin("eglDestroySurface");
155         arg("display", display);
156         arg("surface", surface);
157         end();
158 
159         boolean result = mEgl10.eglDestroySurface(display, surface);
160         returns(result);
161         checkError();
162         return result;
163     }
164 
eglGetConfigAttrib(EGLDisplay display, EGLConfig config, int attribute, int[] value)165     public boolean eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
166             int attribute, int[] value) {
167         begin("eglGetConfigAttrib");
168         arg("display", display);
169         arg("config", config);
170         arg("attribute", attribute);
171         end();
172         boolean result = mEgl10.eglGetConfigAttrib(display, config, attribute,
173                 value);
174         arg("value", value);
175         returns(result);
176         checkError();
177         return false;
178     }
179 
eglGetConfigs(EGLDisplay display, EGLConfig[] configs, int config_size, int[] num_config)180     public boolean eglGetConfigs(EGLDisplay display, EGLConfig[] configs,
181             int config_size, int[] num_config) {
182         begin("eglGetConfigs");
183         arg("display", display);
184         arg("config_size", config_size);
185         end();
186 
187         boolean result = mEgl10.eglGetConfigs(display, configs, config_size,
188                 num_config);
189         arg("configs", configs);
190         arg("num_config", num_config);
191         returns(result);
192         checkError();
193         return result;
194     }
195 
eglGetCurrentContext()196     public EGLContext eglGetCurrentContext() {
197         begin("eglGetCurrentContext");
198         end();
199 
200         EGLContext result = mEgl10.eglGetCurrentContext();
201         returns(result);
202 
203         checkError();
204         return result;
205     }
206 
eglGetCurrentDisplay()207     public EGLDisplay eglGetCurrentDisplay() {
208         begin("eglGetCurrentDisplay");
209         end();
210 
211         EGLDisplay result = mEgl10.eglGetCurrentDisplay();
212         returns(result);
213 
214         checkError();
215         return result;
216     }
217 
eglGetCurrentSurface(int readdraw)218     public EGLSurface eglGetCurrentSurface(int readdraw) {
219         begin("eglGetCurrentSurface");
220         arg("readdraw", readdraw);
221         end();
222 
223         EGLSurface result = mEgl10.eglGetCurrentSurface(readdraw);
224         returns(result);
225 
226         checkError();
227         return result;
228     }
229 
eglGetDisplay(Object native_display)230     public EGLDisplay eglGetDisplay(Object native_display) {
231         begin("eglGetDisplay");
232         arg("native_display", native_display);
233         end();
234 
235         EGLDisplay result = mEgl10.eglGetDisplay(native_display);
236         returns(result);
237 
238         checkError();
239         return result;
240     }
241 
eglGetError()242     public int eglGetError() {
243         begin("eglGetError");
244         end();
245 
246         int result = mEgl10.eglGetError();
247         returns(getErrorString(result));
248 
249         return result;
250     }
251 
eglInitialize(EGLDisplay display, int[] major_minor)252     public boolean eglInitialize(EGLDisplay display, int[] major_minor) {
253         begin("eglInitialize");
254         arg("display", display);
255         end();
256         boolean result = mEgl10.eglInitialize(display, major_minor);
257         returns(result);
258         arg("major_minor", major_minor);
259         checkError();
260         return result;
261     }
262 
eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)263     public boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw,
264             EGLSurface read, EGLContext context) {
265         begin("eglMakeCurrent");
266         arg("display", display);
267         arg("draw", draw);
268         arg("read", read);
269         arg("context", context);
270         end();
271         boolean result = mEgl10.eglMakeCurrent(display, draw, read, context);
272         returns(result);
273         checkError();
274         return result;
275     }
276 
eglQueryContext(EGLDisplay display, EGLContext context, int attribute, int[] value)277     public boolean eglQueryContext(EGLDisplay display, EGLContext context,
278             int attribute, int[] value) {
279         begin("eglQueryContext");
280         arg("display", display);
281         arg("context", context);
282         arg("attribute", attribute);
283         end();
284         boolean result = mEgl10.eglQueryContext(display, context, attribute,
285                 value);
286         returns(value[0]);
287         returns(result);
288         checkError();
289         return result;
290     }
291 
eglQueryString(EGLDisplay display, int name)292     public String eglQueryString(EGLDisplay display, int name) {
293         begin("eglQueryString");
294         arg("display", display);
295         arg("name", name);
296         end();
297         String result = mEgl10.eglQueryString(display, name);
298         returns(result);
299         checkError();
300         return result;
301     }
302 
eglQuerySurface(EGLDisplay display, EGLSurface surface, int attribute, int[] value)303     public boolean eglQuerySurface(EGLDisplay display, EGLSurface surface,
304             int attribute, int[] value) {
305         begin("eglQuerySurface");
306         arg("display", display);
307         arg("surface", surface);
308         arg("attribute", attribute);
309         end();
310         boolean result = mEgl10.eglQuerySurface(display, surface, attribute,
311                 value);
312         returns(value[0]);
313         returns(result);
314         checkError();
315         return result;
316     }
317 
318     /** @hide **/
eglReleaseThread()319     public boolean eglReleaseThread() {
320         begin("eglReleaseThread");
321         end();
322         boolean result = mEgl10.eglReleaseThread();
323         returns(result);
324         checkError();
325         return result;
326     }
327 
eglSwapBuffers(EGLDisplay display, EGLSurface surface)328     public boolean eglSwapBuffers(EGLDisplay display, EGLSurface surface) {
329         begin("eglSwapBuffers");
330         arg("display", display);
331         arg("surface", surface);
332         end();
333         boolean result = mEgl10.eglSwapBuffers(display, surface);
334         returns(result);
335         checkError();
336         return result;
337     }
338 
eglTerminate(EGLDisplay display)339     public boolean eglTerminate(EGLDisplay display) {
340         begin("eglTerminate");
341         arg("display", display);
342         end();
343         boolean result = mEgl10.eglTerminate(display);
344         returns(result);
345         checkError();
346         return result;
347     }
348 
eglWaitGL()349     public boolean eglWaitGL() {
350         begin("eglWaitGL");
351         end();
352         boolean result = mEgl10.eglWaitGL();
353         returns(result);
354         checkError();
355         return result;
356     }
357 
eglWaitNative(int engine, Object bindTarget)358     public boolean eglWaitNative(int engine, Object bindTarget) {
359         begin("eglWaitNative");
360         arg("engine", engine);
361         arg("bindTarget", bindTarget);
362         end();
363         boolean result = mEgl10.eglWaitNative(engine, bindTarget);
364         returns(result);
365         checkError();
366         return result;
367     }
368 
checkError()369     private void checkError() {
370         int eglError;
371         if ((eglError = mEgl10.eglGetError()) != EGL_SUCCESS) {
372             String errorMessage = "eglError: " + getErrorString(eglError);
373             logLine(errorMessage);
374             if (mCheckError) {
375                 throw new GLException(eglError, errorMessage);
376             }
377         }
378     }
379 
logLine(String message)380     private void logLine(String message) {
381         log(message + '\n');
382     }
383 
log(String message)384     private void log(String message) {
385         try {
386             mLog.write(message);
387         } catch (IOException e) {
388             // Ignore exception, keep on trying
389         }
390     }
391 
begin(String name)392     private void begin(String name) {
393         log(name + '(');
394         mArgCount = 0;
395     }
396 
arg(String name, String value)397     private void arg(String name, String value) {
398         if (mArgCount++ > 0) {
399             log(", ");
400         }
401         if (mLogArgumentNames) {
402             log(name + "=");
403         }
404         log(value);
405     }
406 
end()407     private void end() {
408         log(");\n");
409         flush();
410     }
411 
flush()412     private void flush() {
413         try {
414             mLog.flush();
415         } catch (IOException e) {
416             mLog = null;
417         }
418     }
419 
arg(String name, int value)420     private void arg(String name, int value) {
421         arg(name, Integer.toString(value));
422     }
423 
arg(String name, Object object)424     private void arg(String name, Object object) {
425         arg(name, toString(object));
426     }
427 
arg(String name, EGLDisplay object)428     private void arg(String name, EGLDisplay object) {
429         if (object == EGL10.EGL_DEFAULT_DISPLAY) {
430             arg(name, "EGL10.EGL_DEFAULT_DISPLAY");
431         } else if (object == EGL_NO_DISPLAY) {
432             arg(name, "EGL10.EGL_NO_DISPLAY");
433         } else {
434             arg(name, toString(object));
435         }
436     }
437 
arg(String name, EGLContext object)438     private void arg(String name, EGLContext object) {
439         if (object == EGL10.EGL_NO_CONTEXT) {
440             arg(name, "EGL10.EGL_NO_CONTEXT");
441         } else {
442             arg(name, toString(object));
443         }
444     }
445 
arg(String name, EGLSurface object)446     private void arg(String name, EGLSurface object) {
447         if (object == EGL10.EGL_NO_SURFACE) {
448             arg(name, "EGL10.EGL_NO_SURFACE");
449         } else {
450             arg(name, toString(object));
451         }
452     }
453 
returns(String result)454     private void returns(String result) {
455         log(" returns " + result + ";\n");
456         flush();
457     }
458 
returns(int result)459     private void returns(int result) {
460         returns(Integer.toString(result));
461     }
462 
returns(boolean result)463     private void returns(boolean result) {
464         returns(Boolean.toString(result));
465     }
466 
returns(Object result)467     private void returns(Object result) {
468         returns(toString(result));
469     }
470 
toString(Object obj)471     private String toString(Object obj) {
472         if (obj == null) {
473             return "null";
474         } else {
475             return obj.toString();
476         }
477     }
478 
arg(String name, int[] arr)479     private void arg(String name, int[] arr) {
480         if (arr == null) {
481             arg(name, "null");
482         } else {
483             arg(name, toString(arr.length, arr, 0));
484         }
485     }
486 
arg(String name, Object[] arr)487     private void arg(String name, Object[] arr) {
488         if (arr == null) {
489             arg(name, "null");
490         } else {
491             arg(name, toString(arr.length, arr, 0));
492         }
493     }
494 
toString(int n, int[] arr, int offset)495     private String toString(int n, int[] arr, int offset) {
496         StringBuilder buf = new StringBuilder();
497         buf.append("{\n");
498         int arrLen = arr.length;
499         for (int i = 0; i < n; i++) {
500             int index = offset + i;
501             buf.append(" [" + index + "] = ");
502             if (index < 0 || index >= arrLen) {
503                 buf.append("out of bounds");
504             } else {
505                 buf.append(arr[index]);
506             }
507             buf.append('\n');
508         }
509         buf.append("}");
510         return buf.toString();
511     }
512 
toString(int n, Object[] arr, int offset)513     private String toString(int n, Object[] arr, int offset) {
514         StringBuilder buf = new StringBuilder();
515         buf.append("{\n");
516         int arrLen = arr.length;
517         for (int i = 0; i < n; i++) {
518             int index = offset + i;
519             buf.append(" [" + index + "] = ");
520             if (index < 0 || index >= arrLen) {
521                 buf.append("out of bounds");
522             } else {
523                 buf.append(arr[index]);
524             }
525             buf.append('\n');
526         }
527         buf.append("}");
528         return buf.toString();
529     }
530 
getHex(int value)531     private static String getHex(int value) {
532         return "0x" + Integer.toHexString(value);
533     }
534 
getErrorString(int error)535     public static String getErrorString(int error) {
536         switch (error) {
537         case EGL_SUCCESS:
538             return "EGL_SUCCESS";
539         case EGL_NOT_INITIALIZED:
540             return "EGL_NOT_INITIALIZED";
541         case EGL_BAD_ACCESS:
542             return "EGL_BAD_ACCESS";
543         case EGL_BAD_ALLOC:
544             return "EGL_BAD_ALLOC";
545         case EGL_BAD_ATTRIBUTE:
546             return "EGL_BAD_ATTRIBUTE";
547         case EGL_BAD_CONFIG:
548             return "EGL_BAD_CONFIG";
549         case EGL_BAD_CONTEXT:
550             return "EGL_BAD_CONTEXT";
551         case EGL_BAD_CURRENT_SURFACE:
552             return "EGL_BAD_CURRENT_SURFACE";
553         case EGL_BAD_DISPLAY:
554             return "EGL_BAD_DISPLAY";
555         case EGL_BAD_MATCH:
556             return "EGL_BAD_MATCH";
557         case EGL_BAD_NATIVE_PIXMAP:
558             return "EGL_BAD_NATIVE_PIXMAP";
559         case EGL_BAD_NATIVE_WINDOW:
560             return "EGL_BAD_NATIVE_WINDOW";
561         case EGL_BAD_PARAMETER:
562             return "EGL_BAD_PARAMETER";
563         case EGL_BAD_SURFACE:
564             return "EGL_BAD_SURFACE";
565         case EGL11.EGL_CONTEXT_LOST:
566             return "EGL_CONTEXT_LOST";
567         default:
568             return getHex(error);
569         }
570     }
571 }
572