1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <stdlib.h> 27 #include <assert.h> 28 #include <stdio.h> 29 #include <string.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <linux/fb.h> 33 #include <sys/ioctl.h> 34 35 #include "../PrismES2Defs.h" 36 37 #include "eglUtils.h" 38 39 #include "eglfb/wrapped_egl.h" 40 41 #ifdef EGL_X11_FB_CONTAINER 42 #include "X11/Xlib.h" 43 #endif 44 45 #define WARN_MISSING_SYMBOLS 0 46 47 void *get_dlsym(void *handle, const char *symbol, int warn) { 48 void *ret = dlsym(handle, symbol); 49 if (!ret && warn) { 50 fprintf(stderr, "ERROR: could not find symbol for %s\n", symbol); 51 } 52 return ret; 53 } 54 55 #define GET_DLSYM(handle,symbol) get_dlsym(handle,symbol, WARN_MISSING_SYMBOLS); 56 57 EGLSurface sharedWindowSurface = NULL; 58 #ifdef ANDROID_NDK 59 EGLNativeWindowType currentNativeWindow = NULL; 60 #endif 61 #ifdef EGL_X11_FB_CONTAINER 62 EGLSurface dummySurface = NULL; 63 #endif 64 65 EGLSurface getDummyWindowSurface(EGLDisplay dpy, EGLConfig cfg) { 66 #ifdef EGL_X11_FB_CONTAINER 67 if (dummySurface == NULL) { 68 Display *display; 69 Window window; 70 71 display = XOpenDisplay(0); 72 if (display == NULL) { 73 fprintf(stderr, "XOpenDisplay failed\n"); 74 return 0; 75 } 76 window = XCreateWindow(display, 77 RootWindow(display, DefaultScreen(display)), 78 0, 0, 1, 1, 0, 79 CopyFromParent, InputOutput, CopyFromParent, 0, 80 (XSetWindowAttributes *) 0); 81 XSync(display, False); 82 dummySurface = eglCreateWindowSurface(dpy, cfg, window, NULL); 83 XSync(display, False); 84 } 85 return dummySurface; 86 #else 87 return getSharedWindowSurface(dpy, cfg, NULL); 88 #endif 89 } 90 91 EGLSurface getSharedWindowSurface(EGLDisplay dpy, 92 EGLConfig cfg, 93 void *nativeWindow) { 94 if (sharedWindowSurface == NULL) { 95 EGLNativeWindowType window = 0; 96 #if EGL_X11_FB_CONTAINER 97 window = (EGLNativeWindowType)nativeWindow; 98 #else 99 if (nativeWindow == NULL) { 100 window = getNativeWindowType(); 101 } 102 #endif 103 sharedWindowSurface = eglCreateWindowSurface(dpy, cfg, window, NULL); 104 if (sharedWindowSurface == EGL_NO_SURFACE) { 105 fprintf(stderr, "eglCreateWindowSurface failed! eglGetError %d\n", eglGetError()); 106 return 0; 107 } 108 #ifdef ANDROID_NDK 109 currentNativeWindow = window; 110 #endif 111 return sharedWindowSurface; 112 } 113 #ifdef ANDROID_NDK 114 EGLNativeWindowType wnd = getNativeWindowType(); 115 if (currentNativeWindow != wnd) { 116 sharedWindowSurface = eglCreateWindowSurface(dpy, cfg, wnd, NULL); 117 if (sharedWindowSurface == EGL_NO_SURFACE) { 118 fprintf(stderr, "Recreating eglSurface: eglCreateWindowSurface failed! eglGetError %d\n", eglGetError()); 119 return 0; 120 } 121 currentNativeWindow = wnd; 122 } 123 #endif 124 return sharedWindowSurface; 125 } 126 127 void setEGLAttrs(jint *attrs, int *eglAttrs) { 128 int index = 0; 129 130 eglAttrs[index++] = EGL_SURFACE_TYPE; 131 if (attrs[ONSCREEN] != 0) { 132 eglAttrs[index++] = (EGL_WINDOW_BIT); 133 } else { 134 eglAttrs[index++] = EGL_PBUFFER_BIT; 135 } 136 137 // NOTE: EGL_TRANSPARENT_TYPE ? 138 139 if (attrs[RED_SIZE] == 5 && attrs[GREEN_SIZE] == 6 140 && attrs[BLUE_SIZE] == 5 && attrs[ALPHA_SIZE] == 0) { 141 // Optimization for Raspberry Pi model B. Even though the result 142 // of setting EGL_BUFFER_SIZE to 16 should be the same as setting 143 // component sizes separately, we get less per-frame overhead if we 144 // only set EGL_BUFFER_SIZE. 145 eglAttrs[index++] = EGL_BUFFER_SIZE; 146 eglAttrs[index++] = 16; 147 } else { 148 eglAttrs[index++] = EGL_RED_SIZE; 149 eglAttrs[index++] = attrs[RED_SIZE]; 150 eglAttrs[index++] = EGL_GREEN_SIZE; 151 eglAttrs[index++] = attrs[GREEN_SIZE]; 152 eglAttrs[index++] = EGL_BLUE_SIZE; 153 eglAttrs[index++] = attrs[BLUE_SIZE]; 154 eglAttrs[index++] = EGL_ALPHA_SIZE; 155 eglAttrs[index++] = attrs[ALPHA_SIZE]; 156 } 157 158 eglAttrs[index++] = EGL_DEPTH_SIZE; 159 eglAttrs[index++] = attrs[DEPTH_SIZE]; 160 eglAttrs[index++] = EGL_RENDERABLE_TYPE; 161 eglAttrs[index++] = EGL_OPENGL_ES2_BIT; 162 eglAttrs[index] = EGL_NONE; 163 } 164 165 ContextInfo *eglContextFromConfig(EGLDisplay *dpy, EGLConfig config) { 166 167 EGLSurface surface = getDummyWindowSurface(dpy, config); 168 169 EGLint contextAttrs[] = { 170 EGL_CONTEXT_CLIENT_VERSION, 2, 171 EGL_NONE 172 }; 173 174 EGLContext context = eglCreateContext(dpy, config, NULL, contextAttrs); 175 if (context == EGL_NO_CONTEXT) { 176 fprintf(stderr, "eglCreateContext() failed - %d\n", eglGetError()); 177 return 0; 178 } 179 180 if (!eglMakeCurrent(dpy, surface, surface, context)) { 181 fprintf(stderr, "eglMakeCurrent failed - %d\n", eglGetError()); 182 return 0; 183 } 184 ContextInfo *ctxInfo = NULL; 185 186 /* Note: We are only storing the string information of a driver. 187 Assuming a system with a single or homogeneous GPUs. For the case 188 of heterogeneous GPUs system the string information will need to move to 189 GLContext class. */ 190 /* allocate the structure */ 191 ctxInfo = (ContextInfo *) malloc(sizeof(ContextInfo)); 192 if (ctxInfo == NULL) { 193 fprintf(stderr, "nInitialize: Failed in malloc\n"); 194 return 0; 195 } 196 /* initialize the structure */ 197 initializeCtxInfo(ctxInfo); 198 199 const char *glVersion = (char *)glGetString(GL_VERSION); 200 const char *glVendor = (char *)glGetString(GL_VENDOR); 201 const char *glRenderer = (char *)glGetString(GL_RENDERER); 202 // Make a copy, at least one platform does not preserve the string beyond the call. 203 char *glExtensions = strdup((char *)glGetString(GL_EXTENSIONS)); 204 char *eglExtensions = strdup((char *)eglQueryString(dpy, EGL_EXTENSIONS)); 205 206 /* find out the version, major and minor version number */ 207 char *tmpVersionStr = strdup(glVersion); 208 int versionNumbers[2]; 209 extractVersionInfo(tmpVersionStr, versionNumbers); 210 free(tmpVersionStr); 211 212 ctxInfo->versionStr = strdup(glVersion); 213 ctxInfo->vendorStr = strdup(glVendor); 214 ctxInfo->rendererStr = strdup(glRenderer); 215 ctxInfo->glExtensionStr = strdup(glExtensions); 216 ctxInfo->glxExtensionStr = strdup(eglExtensions); 217 ctxInfo->versionNumbers[0] = versionNumbers[0]; 218 ctxInfo->versionNumbers[1] = versionNumbers[1]; 219 220 ctxInfo->display = getNativeDisplayType(); 221 ctxInfo->context = context; 222 ctxInfo->egldisplay = dpy; 223 224 // cleanup 225 free(glExtensions); 226 free(eglExtensions); 227 228 // from the wrapped_egl.c 229 void *handle = getLibGLEShandle(); 230 231 /* set function pointers */ 232 ctxInfo->glActiveTexture = (PFNGLACTIVETEXTUREPROC) 233 GET_DLSYM(handle, "glActiveTexture"); 234 ctxInfo->glAttachShader = (PFNGLATTACHSHADERPROC) 235 GET_DLSYM(handle, "glAttachShader"); 236 ctxInfo->glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) 237 GET_DLSYM(handle, "glBindAttribLocation"); 238 ctxInfo->glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) 239 GET_DLSYM(handle, "glBindFramebuffer"); 240 ctxInfo->glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) 241 GET_DLSYM(handle, "glBindRenderbuffer"); 242 ctxInfo->glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) 243 GET_DLSYM(handle, "glCheckFramebufferStatus"); 244 ctxInfo->glCreateProgram = (PFNGLCREATEPROGRAMPROC) 245 GET_DLSYM(handle, "glCreateProgram"); 246 ctxInfo->glCreateShader = (PFNGLCREATESHADERPROC) 247 GET_DLSYM(handle, "glCreateShader"); 248 ctxInfo->glCompileShader = (PFNGLCOMPILESHADERPROC) 249 GET_DLSYM(handle, "glCompileShader"); 250 ctxInfo->glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) 251 GET_DLSYM(handle, "glDeleteBuffers"); 252 ctxInfo->glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) 253 GET_DLSYM(handle, "glDeleteFramebuffers"); 254 ctxInfo->glDeleteProgram = (PFNGLDELETEPROGRAMPROC) 255 GET_DLSYM(handle, "glDeleteProgram"); 256 ctxInfo->glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) 257 GET_DLSYM(handle, "glDeleteRenderbuffers"); 258 ctxInfo->glDeleteShader = (PFNGLDELETESHADERPROC) 259 GET_DLSYM(handle, "glDeleteShader"); 260 ctxInfo->glDetachShader = (PFNGLDETACHSHADERPROC) 261 GET_DLSYM(handle, "glDetachShader"); 262 ctxInfo->glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) 263 GET_DLSYM(handle, "glDisableVertexAttribArray"); 264 ctxInfo->glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) 265 GET_DLSYM(handle, "glEnableVertexAttribArray"); 266 ctxInfo->glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) 267 GET_DLSYM(handle, "glFramebufferRenderbuffer"); 268 ctxInfo->glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) 269 GET_DLSYM(handle, "glFramebufferTexture2D"); 270 ctxInfo->glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) 271 GET_DLSYM(handle, "glGenFramebuffers"); 272 ctxInfo->glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) 273 GET_DLSYM(handle, "glGenRenderbuffers"); 274 ctxInfo->glGetProgramiv = (PFNGLGETPROGRAMIVPROC) 275 GET_DLSYM(handle, "glGetProgramiv"); 276 ctxInfo->glGetShaderiv = (PFNGLGETSHADERIVPROC) 277 GET_DLSYM(handle, "glGetShaderiv"); 278 ctxInfo->glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) 279 GET_DLSYM(handle, "glGetUniformLocation"); 280 ctxInfo->glLinkProgram = (PFNGLLINKPROGRAMPROC) 281 GET_DLSYM(handle, "glLinkProgram"); 282 ctxInfo->glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) 283 GET_DLSYM(handle, "glRenderbufferStorage"); 284 ctxInfo->glShaderSource = (PFNGLSHADERSOURCEPROC) 285 GET_DLSYM(handle, "glShaderSource"); 286 ctxInfo->glUniform1f = (PFNGLUNIFORM1FPROC) 287 GET_DLSYM(handle, "glUniform1f"); 288 ctxInfo->glUniform2f = (PFNGLUNIFORM2FPROC) 289 GET_DLSYM(handle, "glUniform2f"); 290 ctxInfo->glUniform3f = (PFNGLUNIFORM3FPROC) 291 GET_DLSYM(handle, "glUniform3f"); 292 ctxInfo->glUniform4f = (PFNGLUNIFORM4FPROC) 293 GET_DLSYM(handle, "glUniform4f"); 294 ctxInfo->glUniform4fv = (PFNGLUNIFORM4FVPROC) 295 GET_DLSYM(handle, "glUniform4fv"); 296 ctxInfo->glUniform1i = (PFNGLUNIFORM1IPROC) 297 GET_DLSYM(handle, "glUniform1i"); 298 ctxInfo->glUniform2i = (PFNGLUNIFORM2IPROC) 299 GET_DLSYM(handle, "glUniform2i"); 300 ctxInfo->glUniform3i = (PFNGLUNIFORM3IPROC) 301 GET_DLSYM(handle, "glUniform3i"); 302 ctxInfo->glUniform4i = (PFNGLUNIFORM4IPROC) 303 GET_DLSYM(handle, "glUniform4i"); 304 ctxInfo->glUniform4iv = (PFNGLUNIFORM4IVPROC) 305 GET_DLSYM(handle, "glUniform4iv"); 306 ctxInfo->glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) 307 GET_DLSYM(handle, "glUniformMatrix4fv"); 308 ctxInfo->glUseProgram = (PFNGLUSEPROGRAMPROC) 309 GET_DLSYM(handle, "glUseProgram"); 310 ctxInfo->glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) 311 GET_DLSYM(handle, "glValidateProgram"); 312 ctxInfo->glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) 313 GET_DLSYM(handle, "glVertexAttribPointer"); 314 ctxInfo->glGenBuffers = (PFNGLGENBUFFERSPROC) 315 GET_DLSYM(handle, "glGenBuffers"); 316 ctxInfo->glBindBuffer = (PFNGLBINDBUFFERPROC) 317 GET_DLSYM(handle, "glBindBuffer"); 318 ctxInfo->glBufferData = (PFNGLBUFFERDATAPROC) 319 GET_DLSYM(handle, "glBufferData"); 320 ctxInfo->glBufferSubData = (PFNGLBUFFERSUBDATAPROC) 321 GET_DLSYM(handle, "glBufferSubData"); 322 ctxInfo->glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) 323 GET_DLSYM(handle, "glGetShaderInfoLog"); 324 ctxInfo->glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) 325 GET_DLSYM(handle, "glGetProgramInfoLog"); 326 ctxInfo->glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) 327 GET_DLSYM(handle, "glTexImage2DMultisample"); 328 ctxInfo->glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) 329 GET_DLSYM(handle, "glRenderbufferStorageMultisample"); 330 ctxInfo->glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) 331 GET_DLSYM(handle, "glBlitFramebuffer"); 332 333 initState(ctxInfo); 334 /* Releasing native resources */ 335 eglMakeCurrent(ctxInfo->egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 336 //eglDestroySurface(ctxInfo->egldisplay, surface); 337 return ctxInfo; 338 } 339 340 341 342 //#ifdef DEBUG 343 344 const char *eglErrorMsg(int err) { 345 const char *ret; 346 if (err == EGL_SUCCESS) { 347 ret = "The last function succeeded without error."; 348 } else if (err == EGL_NOT_INITIALIZED) { 349 ret = "EGL is not initialized, or could not be initialized, for the specified EGL display connection."; 350 } else if (err == EGL_BAD_ACCESS) { 351 ret = "EGL cannot access a requested resource (for example a context is bound in another thread)."; 352 } else if (err == EGL_BAD_ALLOC) { 353 ret = "EGL failed to allocate resources for the requested operation."; 354 } else if (err == EGL_BAD_ATTRIBUTE) { 355 ret = "An unrecognized attribute or attribute value was passed in the attribute list."; 356 } else if (err == EGL_BAD_CONTEXT) { 357 ret = "An EGLContext argument does not name a valid EGL rendering context."; 358 } else if (err == EGL_BAD_CONFIG) { 359 ret = "An EGLConfig argument does not name a valid EGL frame buffer configuration."; 360 } else if (err == EGL_BAD_CURRENT_SURFACE) { 361 ret = "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid."; 362 } else if (err == EGL_BAD_DISPLAY) { 363 ret = "An EGLDisplay argument does not name a valid EGL display connection."; 364 } else if (err == EGL_BAD_SURFACE) { 365 ret = "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering."; 366 } else if (err == EGL_BAD_MATCH) { 367 ret = "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface)."; 368 } else if (err == EGL_BAD_PARAMETER) { 369 ret = "One or more argument values are invalid."; 370 } else if (err == EGL_BAD_NATIVE_PIXMAP) { 371 ret = "A NativePixmapType argument does not refer to a valid native pixmap."; 372 } else if (err == EGL_BAD_NATIVE_WINDOW) { 373 ret = "A NativeWindowType argument does not refer to a valid native window."; 374 } else { 375 ret = "Unknown EGL error"; 376 } 377 return ret; 378 } 379 380 char *printErrorExit(char *message) { 381 EGLint err = eglGetError(); 382 char buffer[80]; 383 char *ret; 384 if (err == EGL_SUCCESS) { 385 ret = "The last function succeeded without error."; 386 } else if (err == EGL_NOT_INITIALIZED) { 387 ret = "EGL is not initialized, or could not be initialized, for the specified EGL display connection."; 388 } else if (err == EGL_BAD_ACCESS) { 389 ret = "EGL cannot access a requested resource (for example a context is bound in another thread)."; 390 } else if (err == EGL_BAD_ALLOC) { 391 ret = "EGL failed to allocate resources for the requested operation."; 392 } else if (err == EGL_BAD_ATTRIBUTE) { 393 ret = "An unrecognized attribute or attribute value was passed in the attribute list."; 394 } else if (err == EGL_BAD_CONTEXT) { 395 ret = "An EGLContext argument does not name a valid EGL rendering context."; 396 } else if (err == EGL_BAD_CONFIG) { 397 ret = "An EGLConfig argument does not name a valid EGL frame buffer configuration."; 398 } else if (err == EGL_BAD_CURRENT_SURFACE) { 399 ret = "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid."; 400 } else if (err == EGL_BAD_DISPLAY) { 401 ret = "An EGLDisplay argument does not name a valid EGL display connection."; 402 } else if (err == EGL_BAD_SURFACE) { 403 ret = "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering."; 404 } else if (err == EGL_BAD_MATCH) { 405 ret = "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface)."; 406 } else if (err == EGL_BAD_PARAMETER) { 407 ret = "One or more argument values are invalid."; 408 } else if (err == EGL_BAD_NATIVE_PIXMAP) { 409 ret = "A NativePixmapType argument does not refer to a valid native pixmap."; 410 } else if (err == EGL_BAD_NATIVE_WINDOW) { 411 ret = "A NativeWindowType argument does not refer to a valid native window."; 412 } else { 413 sprintf(buffer, "unknown error code 0x%0x", err); 414 ret = buffer; 415 } 416 if (message) { 417 printf("%s\n", message); 418 } 419 printf("EGL ERROR: %s\n", ret); 420 exit(1); 421 } 422 423 int printConfigAttrs(EGLint *config) { 424 int cnt = 0; 425 while ((*config != EGL_NONE) && (cnt < 25)) { 426 EGLint arg = *config++; 427 EGLint val = *config++; 428 cnt++; 429 printf(" "); 430 switch (arg) { 431 case EGL_SURFACE_TYPE: 432 if (val == (EGL_PBUFFER_BIT | EGL_WINDOW_BIT)) { 433 printf("EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,\n"); 434 } else if (val == (EGL_WINDOW_BIT)) { 435 printf("EGL_SURFACE_TYPE: EGL_WINDOW_BIT,\n"); 436 } else if (val == (EGL_PBUFFER_BIT)) { 437 printf("EGL_SURFACE_TYPE: EGL_PBUFFER_BIT,\n"); 438 } else { 439 printf("EGL_SURFACE_TYPE, %d,\n", val); 440 } 441 break; 442 case EGL_BUFFER_SIZE: 443 printf("EGL_BUFFER_SIZE, %d,\n", val); 444 break; 445 case EGL_SAMPLE_BUFFERS: 446 printf("EGL_SAMPLE_BUFFERS, %d,\n", val); 447 break; 448 case EGL_SAMPLES: 449 printf("EGL_SAMPLES, %d,\n", val); 450 break; 451 case EGL_DEPTH_SIZE: 452 printf("EGL_DEPTH_SIZE, %d,\n", val); 453 break; 454 case EGL_RED_SIZE: 455 printf("EGL_RED_SIZE, %d,\n", val); 456 break; 457 case EGL_GREEN_SIZE: 458 printf("EGL_GREEN_SIZE, %d,\n", val); 459 break; 460 case EGL_BLUE_SIZE: 461 printf("EGL_BLUE_SIZE, %d,\n", val); 462 break; 463 case EGL_ALPHA_SIZE: 464 printf("EGL_ALPHA_SIZE, %d,\n", val); 465 break; 466 case EGL_LEVEL: 467 printf("EGL_LEVEL, %d,\n", val); 468 break; 469 case EGL_NATIVE_RENDERABLE: 470 printf("EGL_NATIVE_RENDERABLE, %d,\n", val); 471 break; 472 case EGL_STENCIL_SIZE: 473 printf("EGL_STENCIL_SIZE, %d,\n", val); 474 break; 475 case EGL_TRANSPARENT_TYPE: 476 if (val == EGL_TRANSPARENT_RGB) { 477 printf("EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RGB,\n"); 478 } else if (val == EGL_NONE) { 479 printf("EGL_TRANSPARENT_TYPE, EGL_NONE,\n"); 480 } else { 481 printf("EGL_TRANSPARENT_TYPE, bad val %d\n", val); 482 } 483 break; 484 case EGL_TRANSPARENT_RED_VALUE: 485 printf("EGL_TRANSPARENT_RED_VALUE, %d,\n", val); 486 break; 487 case EGL_TRANSPARENT_GREEN_VALUE: 488 printf("EGL_TRANSPARENT_GREEN_VALUE, %d,\n", val); 489 break; 490 case EGL_TRANSPARENT_BLUE_VALUE: 491 printf("EGL_TRANSPARENT_BLUE_VALUE, %d,\n", val); 492 break; 493 case EGL_NATIVE_VISUAL_TYPE: 494 printf("EGL_NATIVE_VISUAL_TYPE, %d,\n", val); 495 break; 496 case EGL_RENDERABLE_TYPE: 497 printf("EGL_RENDERABLE_TYPE, %s,\n", val == EGL_OPENGL_ES2_BIT ? "EGL_OPENGL_ES2_BIT," : "EGL_OPENGL_ES_BIT"); 498 break; 499 default: 500 printf("UNRECOGNIZED, %d, %d\n", arg, val); 501 } 502 } 503 if (*config == EGL_NONE) { 504 printf(" EGL_NONE\n"); 505 } else { 506 printf(" *** ERROR exceeded arg limit *** \n"); 507 } 508 return 1; 509 } 510 511 int printConfig(EGLDisplay display, EGLConfig config) { 512 513 int id; 514 eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &id); 515 516 int red, green, blue, alpha, depth; 517 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red); 518 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green); 519 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue); 520 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha); 521 eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &depth); 522 523 int pwidth, phgt, psize; 524 pwidth = phgt = psize = 0; 525 eglGetConfigAttrib(display, config, EGL_MAX_PBUFFER_WIDTH, &pwidth); 526 eglGetConfigAttrib(display, config, EGL_MAX_PBUFFER_HEIGHT, &phgt); 527 eglGetConfigAttrib(display, config, EGL_MAX_PBUFFER_PIXELS, &psize); 528 529 int sbuffers, samples; 530 eglGetConfigAttrib(display, config, EGL_SAMPLE_BUFFERS, &sbuffers); 531 eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples); 532 533 int stencil; 534 eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencil); 535 536 int surface; 537 eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surface); 538 539 int transparent; 540 eglGetConfigAttrib(display, config, EGL_TRANSPARENT_TYPE, &transparent); 541 542 int caveat; 543 eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &caveat); 544 char *strcaveat = "Normal"; 545 if (caveat == EGL_SLOW_CONFIG) { 546 strcaveat = "Slow"; 547 } else if (caveat == EGL_NON_CONFORMANT_CONFIG) { 548 strcaveat = "NonConf"; 549 } 550 551 // humm, not documented as a supported element, but there all the same ? 552 int rtype = -1; 553 if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &rtype)) { 554 printf("failed to get EGL_RENDERABLE_TYPE\n"); 555 } 556 char rstr[5]; 557 char *rstrptr = rstr; 558 if ((rtype & EGL_OPENGL_ES_BIT) == EGL_OPENGL_ES_BIT) { 559 *(rstrptr++) = '1'; 560 } 561 if ((rtype & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) { 562 *(rstrptr++) = '2'; 563 } 564 if ((rtype & EGL_OPENVG_BIT) == EGL_OPENVG_BIT) { 565 *(rstrptr++) = 'V'; 566 } 567 if ((rtype & EGL_OPENGL_BIT) == EGL_OPENGL_BIT) { 568 *(rstrptr++) = 'G'; 569 } 570 *rstrptr = 0; 571 572 printf(" %02d: %d%d%d%d %02d %04dx%04d %d %d,%d %d %s%s%s %s %s %s\n", id, 573 red, green, blue, alpha, depth, 574 pwidth, phgt, psize, 575 sbuffers, samples, 576 stencil, 577 ((surface & EGL_WINDOW_BIT) == EGL_WINDOW_BIT) ? "W" : "_", 578 ((surface & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT) ? "P" : "_", 579 ((surface & EGL_PIXMAP_BIT) == EGL_PIXMAP_BIT) ? "X" : "_", 580 (transparent == EGL_TRANSPARENT_RGB) ? "Trans" : "Opaqe", 581 strcaveat, 582 rstr 583 ); 584 585 return 1; 586 } 587 588 //#endif // DEBUG