Aurimas Liutikas | 93554f2 | 2022-04-19 16:51:35 -0700 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 **/ |
| 319 | public boolean eglReleaseThread() { |
| 320 | begin("eglReleaseThread"); |
| 321 | end(); |
| 322 | boolean result = mEgl10.eglReleaseThread(); |
| 323 | returns(result); |
| 324 | checkError(); |
| 325 | return result; |
| 326 | } |
| 327 | |
| 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 | |
| 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 | |
| 349 | public boolean eglWaitGL() { |
| 350 | begin("eglWaitGL"); |
| 351 | end(); |
| 352 | boolean result = mEgl10.eglWaitGL(); |
| 353 | returns(result); |
| 354 | checkError(); |
| 355 | return result; |
| 356 | } |
| 357 | |
| 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 | |
| 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 | |
| 380 | private void logLine(String message) { |
| 381 | log(message + '\n'); |
| 382 | } |
| 383 | |
| 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 | |
| 392 | private void begin(String name) { |
| 393 | log(name + '('); |
| 394 | mArgCount = 0; |
| 395 | } |
| 396 | |
| 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 | |
| 407 | private void end() { |
| 408 | log(");\n"); |
| 409 | flush(); |
| 410 | } |
| 411 | |
| 412 | private void flush() { |
| 413 | try { |
| 414 | mLog.flush(); |
| 415 | } catch (IOException e) { |
| 416 | mLog = null; |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | private void arg(String name, int value) { |
| 421 | arg(name, Integer.toString(value)); |
| 422 | } |
| 423 | |
| 424 | private void arg(String name, Object object) { |
| 425 | arg(name, toString(object)); |
| 426 | } |
| 427 | |
| 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 | |
| 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 | |
| 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 | |
| 454 | private void returns(String result) { |
| 455 | log(" returns " + result + ";\n"); |
| 456 | flush(); |
| 457 | } |
| 458 | |
| 459 | private void returns(int result) { |
| 460 | returns(Integer.toString(result)); |
| 461 | } |
| 462 | |
| 463 | private void returns(boolean result) { |
| 464 | returns(Boolean.toString(result)); |
| 465 | } |
| 466 | |
| 467 | private void returns(Object result) { |
| 468 | returns(toString(result)); |
| 469 | } |
| 470 | |
| 471 | private String toString(Object obj) { |
| 472 | if (obj == null) { |
| 473 | return "null"; |
| 474 | } else { |
| 475 | return obj.toString(); |
| 476 | } |
| 477 | } |
| 478 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 531 | private static String getHex(int value) { |
| 532 | return "0x" + Integer.toHexString(value); |
| 533 | } |
| 534 | |
| 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 | } |