132001f49Smrg/* 232001f49Smrg * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. 332001f49Smrg */ 432001f49Smrg 532001f49Smrg/* 632001f49Smrg * List OpenGL ES extensions. 732001f49Smrg * Print ES 1 or ES 2 extensions depending on which library we're 832001f49Smrg * linked with: libGLESv1_CM.so vs libGLESv2.so 932001f49Smrg */ 1032001f49Smrg 1132001f49Smrg#define GL_GLEXT_PROTOTYPES 1232001f49Smrg 1332001f49Smrg#include <assert.h> 1432001f49Smrg#include <math.h> 1532001f49Smrg#include <stdlib.h> 1632001f49Smrg#include <stdio.h> 1732001f49Smrg#include <string.h> 1832001f49Smrg#include <X11/Xlib.h> 1932001f49Smrg#include <X11/Xutil.h> 2032001f49Smrg#include <X11/keysym.h> 2132001f49Smrg#include <EGL/egl.h> 2232001f49Smrg 2332001f49Smrg 2432001f49Smrg/* 2532001f49Smrg * Print a list of extensions, with word-wrapping. 2632001f49Smrg */ 2732001f49Smrgstatic void 2832001f49Smrgprint_extension_list(const char *ext) 2932001f49Smrg{ 3032001f49Smrg const char indentString[] = " "; 3132001f49Smrg const int indent = 4; 3232001f49Smrg const int max = 79; 3332001f49Smrg int width, i, j; 3432001f49Smrg 3532001f49Smrg if (!ext || !ext[0]) 3632001f49Smrg return; 3732001f49Smrg 3832001f49Smrg width = indent; 3932001f49Smrg printf("%s", indentString); 4032001f49Smrg i = j = 0; 4132001f49Smrg while (1) { 4232001f49Smrg if (ext[j] == ' ' || ext[j] == 0) { 4332001f49Smrg /* found end of an extension name */ 4432001f49Smrg const int len = j - i; 4532001f49Smrg if (width + len > max) { 4632001f49Smrg /* start a new line */ 4732001f49Smrg printf("\n"); 4832001f49Smrg width = indent; 4932001f49Smrg printf("%s", indentString); 5032001f49Smrg } 5132001f49Smrg /* print the extension name between ext[i] and ext[j] */ 5232001f49Smrg while (i < j) { 5332001f49Smrg printf("%c", ext[i]); 5432001f49Smrg i++; 5532001f49Smrg } 5632001f49Smrg /* either we're all done, or we'll continue with next extension */ 5732001f49Smrg width += len + 1; 5832001f49Smrg if (ext[j] == 0) { 5932001f49Smrg break; 6032001f49Smrg } 6132001f49Smrg else { 6232001f49Smrg i++; 6332001f49Smrg j++; 6432001f49Smrg if (ext[j] == 0) 6532001f49Smrg break; 6632001f49Smrg printf(", "); 6732001f49Smrg width += 2; 6832001f49Smrg } 6932001f49Smrg } 7032001f49Smrg j++; 7132001f49Smrg } 7232001f49Smrg printf("\n"); 7332001f49Smrg} 7432001f49Smrg 7532001f49Smrg 7632001f49Smrgstatic void 7732001f49Smrginfo(EGLDisplay egl_dpy) 7832001f49Smrg{ 7932001f49Smrg const char *s; 8032001f49Smrg 8132001f49Smrg s = eglQueryString(egl_dpy, EGL_VERSION); 8232001f49Smrg printf("EGL_VERSION: %s\n", s); 8332001f49Smrg 8432001f49Smrg s = eglQueryString(egl_dpy, EGL_VENDOR); 8532001f49Smrg printf("EGL_VENDOR: %s\n", s); 8632001f49Smrg 8732001f49Smrg s = eglQueryString(egl_dpy, EGL_EXTENSIONS); 8832001f49Smrg printf("EGL_EXTENSIONS:\n", s); 8932001f49Smrg print_extension_list((char *) s); 9032001f49Smrg 9132001f49Smrg s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); 9232001f49Smrg printf("EGL_CLIENT_APIS: %s\n", s); 9332001f49Smrg 9432001f49Smrgconst char *glGetString (int name); 9532001f49Smrg 9632001f49Smrg#define GL_RENDERER 0x1F01 9732001f49Smrg#define GL_VERSION 0x1F02 9832001f49Smrg#define GL_EXTENSIONS 0x1F03 9932001f49Smrg 10032001f49Smrg printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION)); 10132001f49Smrg printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); 10232001f49Smrg printf("GL_EXTENSIONS:\n"); 10332001f49Smrg print_extension_list((char *) glGetString(GL_EXTENSIONS)); 10432001f49Smrg} 10532001f49Smrg 10632001f49Smrg 10732001f49Smrg/* 10832001f49Smrg * Create an RGB, double-buffered X window. 10932001f49Smrg * Return the window and context handles. 11032001f49Smrg */ 11132001f49Smrgstatic void 11232001f49Smrgmake_x_window(Display *x_dpy, EGLDisplay egl_dpy, 11332001f49Smrg const char *name, 11432001f49Smrg int x, int y, int width, int height, int es_ver, 11532001f49Smrg Window *winRet, 11632001f49Smrg EGLContext *ctxRet, 11732001f49Smrg EGLSurface *surfRet) 11832001f49Smrg{ 11932001f49Smrg EGLint attribs[] = { 12032001f49Smrg EGL_RENDERABLE_TYPE, 0x0, 12132001f49Smrg EGL_RED_SIZE, 1, 12232001f49Smrg EGL_GREEN_SIZE, 1, 12332001f49Smrg EGL_BLUE_SIZE, 1, 12432001f49Smrg EGL_NONE 12532001f49Smrg }; 12632001f49Smrg EGLint ctx_attribs[] = { 12732001f49Smrg EGL_CONTEXT_CLIENT_VERSION, 0, 12832001f49Smrg EGL_NONE 12932001f49Smrg }; 13032001f49Smrg 13132001f49Smrg int scrnum; 13232001f49Smrg XSetWindowAttributes attr; 13332001f49Smrg unsigned long mask; 13432001f49Smrg Window root; 13532001f49Smrg Window win; 13632001f49Smrg XVisualInfo *visInfo, visTemplate; 13732001f49Smrg int num_visuals; 13832001f49Smrg EGLContext ctx; 13932001f49Smrg EGLConfig config; 14032001f49Smrg EGLint num_configs; 14132001f49Smrg EGLint vid; 14232001f49Smrg 14332001f49Smrg scrnum = DefaultScreen( x_dpy ); 14432001f49Smrg root = RootWindow( x_dpy, scrnum ); 14532001f49Smrg 14632001f49Smrg if (es_ver == 1) 14732001f49Smrg attribs[1] = EGL_OPENGL_ES_BIT; 14832001f49Smrg else 14932001f49Smrg attribs[1] = EGL_OPENGL_ES2_BIT; 15032001f49Smrg ctx_attribs[1] = es_ver; 15132001f49Smrg 15232001f49Smrg if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { 15332001f49Smrg printf("Error: couldn't get an EGL visual config\n"); 15432001f49Smrg exit(1); 15532001f49Smrg } 15632001f49Smrg 15732001f49Smrg assert(config); 15832001f49Smrg assert(num_configs > 0); 15932001f49Smrg 16032001f49Smrg if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { 16132001f49Smrg printf("Error: eglGetConfigAttrib() failed\n"); 16232001f49Smrg exit(1); 16332001f49Smrg } 16432001f49Smrg 16532001f49Smrg /* The X window visual must match the EGL config */ 16632001f49Smrg visTemplate.visualid = vid; 16732001f49Smrg visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); 16832001f49Smrg if (!visInfo) { 16932001f49Smrg printf("Error: couldn't get X visual\n"); 17032001f49Smrg exit(1); 17132001f49Smrg } 17232001f49Smrg 17332001f49Smrg /* window attributes */ 17432001f49Smrg attr.background_pixel = 0; 17532001f49Smrg attr.border_pixel = 0; 17632001f49Smrg attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); 17732001f49Smrg attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; 17832001f49Smrg mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 17932001f49Smrg 18032001f49Smrg win = XCreateWindow( x_dpy, root, 0, 0, width, height, 18132001f49Smrg 0, visInfo->depth, InputOutput, 18232001f49Smrg visInfo->visual, mask, &attr ); 18332001f49Smrg 18432001f49Smrg /* set hints and properties */ 18532001f49Smrg { 18632001f49Smrg XSizeHints sizehints; 18732001f49Smrg sizehints.x = x; 18832001f49Smrg sizehints.y = y; 18932001f49Smrg sizehints.width = width; 19032001f49Smrg sizehints.height = height; 19132001f49Smrg sizehints.flags = USSize | USPosition; 19232001f49Smrg XSetNormalHints(x_dpy, win, &sizehints); 19332001f49Smrg XSetStandardProperties(x_dpy, win, name, name, 19432001f49Smrg None, (char **)NULL, 0, &sizehints); 19532001f49Smrg } 19632001f49Smrg 19732001f49Smrg eglBindAPI(EGL_OPENGL_ES_API); 19832001f49Smrg 19932001f49Smrg ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); 20032001f49Smrg if (!ctx) { 20132001f49Smrg printf("Error: eglCreateContext failed\n"); 20232001f49Smrg exit(1); 20332001f49Smrg } 20432001f49Smrg 20532001f49Smrg *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); 20632001f49Smrg 20732001f49Smrg if (!*surfRet) { 20832001f49Smrg printf("Error: eglCreateWindowSurface failed\n"); 20932001f49Smrg exit(1); 21032001f49Smrg } 21132001f49Smrg 21232001f49Smrg XFree(visInfo); 21332001f49Smrg 21432001f49Smrg *winRet = win; 21532001f49Smrg *ctxRet = ctx; 21632001f49Smrg} 21732001f49Smrg 21832001f49Smrg 21932001f49Smrgstatic void 22032001f49Smrgusage(void) 22132001f49Smrg{ 22232001f49Smrg printf("Usage:\n"); 22332001f49Smrg printf(" -display <displayname> set the display to run on\n"); 22432001f49Smrg} 22532001f49Smrg 22632001f49Smrg 22732001f49Smrgint 22832001f49Smrgmain(int argc, char *argv[]) 22932001f49Smrg{ 23032001f49Smrg const int winWidth = 400, winHeight = 300; 23132001f49Smrg Display *x_dpy; 23232001f49Smrg Window win; 23332001f49Smrg EGLSurface egl_surf; 23432001f49Smrg EGLContext egl_ctx; 23532001f49Smrg EGLDisplay egl_dpy; 23632001f49Smrg char *dpyName = NULL; 23732001f49Smrg EGLint egl_major, egl_minor, es_ver; 23832001f49Smrg int i; 23932001f49Smrg 24032001f49Smrg for (i = 1; i < argc; i++) { 24132001f49Smrg if (strcmp(argv[i], "-display") == 0) { 24232001f49Smrg dpyName = argv[i+1]; 24332001f49Smrg i++; 24432001f49Smrg } 24532001f49Smrg else { 24632001f49Smrg usage(); 24732001f49Smrg return -1; 24832001f49Smrg } 24932001f49Smrg } 25032001f49Smrg 25132001f49Smrg x_dpy = XOpenDisplay(dpyName); 25232001f49Smrg if (!x_dpy) { 25332001f49Smrg printf("Error: couldn't open display %s\n", 25432001f49Smrg dpyName ? dpyName : getenv("DISPLAY")); 25532001f49Smrg return -1; 25632001f49Smrg } 25732001f49Smrg 25832001f49Smrg egl_dpy = eglGetDisplay(x_dpy); 25932001f49Smrg if (!egl_dpy) { 26032001f49Smrg printf("Error: eglGetDisplay() failed\n"); 26132001f49Smrg return -1; 26232001f49Smrg } 26332001f49Smrg 26432001f49Smrg if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { 26532001f49Smrg printf("Error: eglInitialize() failed\n"); 26632001f49Smrg return -1; 26732001f49Smrg } 26832001f49Smrg 26932001f49Smrg es_ver = 1; 27032001f49Smrg /* decide the version from the executable's name */ 27132001f49Smrg if (argc > 0 && argv[0] && strstr(argv[0], "es2")) 27232001f49Smrg es_ver = 2; 27332001f49Smrg make_x_window(x_dpy, egl_dpy, 27432001f49Smrg "ES info", 0, 0, winWidth, winHeight, es_ver, 27532001f49Smrg &win, &egl_ctx, &egl_surf); 27632001f49Smrg 27732001f49Smrg /*XMapWindow(x_dpy, win);*/ 27832001f49Smrg if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { 27932001f49Smrg printf("Error: eglMakeCurrent() failed\n"); 28032001f49Smrg return -1; 28132001f49Smrg } 28232001f49Smrg 28332001f49Smrg info(egl_dpy); 28432001f49Smrg 28532001f49Smrg eglDestroyContext(egl_dpy, egl_ctx); 28632001f49Smrg eglDestroySurface(egl_dpy, egl_surf); 28732001f49Smrg eglTerminate(egl_dpy); 28832001f49Smrg 28932001f49Smrg 29032001f49Smrg XDestroyWindow(x_dpy, win); 29132001f49Smrg XCloseDisplay(x_dpy); 29232001f49Smrg 29332001f49Smrg return 0; 29432001f49Smrg} 295