1 /*
2 * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
3 */
4
5 /*
6 * List OpenGL ES extensions.
7 * Print ES 1 or ES 2 extensions depending on which library we're
8 * linked with: libGLESv1_CM.so vs libGLESv2.so
9 */
10
11 #define GL_GLEXT_PROTOTYPES
12
13 #include <assert.h>
14 #include <math.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <X11/Xlib.h>
19 #include <X11/Xutil.h>
20 #include <X11/keysym.h>
21 #include <EGL/egl.h>
22
23
24 /*
25 * Print a list of extensions, with word-wrapping.
26 */
27 static void
print_extension_list(const char * ext)28 print_extension_list(const char *ext)
29 {
30 const char indentString[] = " ";
31 const int indent = 4;
32 const int max = 79;
33 int width, i, j;
34
35 if (!ext || !ext[0])
36 return;
37
38 width = indent;
39 printf("%s", indentString);
40 i = j = 0;
41 while (1) {
42 if (ext[j] == ' ' || ext[j] == 0) {
43 /* found end of an extension name */
44 const int len = j - i;
45 if (width + len > max) {
46 /* start a new line */
47 printf("\n");
48 width = indent;
49 printf("%s", indentString);
50 }
51 /* print the extension name between ext[i] and ext[j] */
52 while (i < j) {
53 printf("%c", ext[i]);
54 i++;
55 }
56 /* either we're all done, or we'll continue with next extension */
57 width += len + 1;
58 if (ext[j] == 0) {
59 break;
60 }
61 else {
62 i++;
63 j++;
64 if (ext[j] == 0)
65 break;
66 printf(", ");
67 width += 2;
68 }
69 }
70 j++;
71 }
72 printf("\n");
73 }
74
75
76 static void
info(EGLDisplay egl_dpy)77 info(EGLDisplay egl_dpy)
78 {
79 const char *s;
80
81 s = eglQueryString(egl_dpy, EGL_VERSION);
82 printf("EGL_VERSION: %s\n", s);
83
84 s = eglQueryString(egl_dpy, EGL_VENDOR);
85 printf("EGL_VENDOR: %s\n", s);
86
87 s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
88 printf("EGL_EXTENSIONS:\n", s);
89 print_extension_list((char *) s);
90
91 s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
92 printf("EGL_CLIENT_APIS: %s\n", s);
93
94 const char *glGetString (int name);
95
96 #define GL_RENDERER 0x1F01
97 #define GL_VERSION 0x1F02
98 #define GL_EXTENSIONS 0x1F03
99
100 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
101 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
102 printf("GL_EXTENSIONS:\n");
103 print_extension_list((char *) glGetString(GL_EXTENSIONS));
104 }
105
106
107 /*
108 * Create an RGB, double-buffered X window.
109 * Return the window and context handles.
110 */
111 static void
make_x_window(Display * x_dpy,EGLDisplay egl_dpy,const char * name,int x,int y,int width,int height,int es_ver,Window * winRet,EGLContext * ctxRet,EGLSurface * surfRet)112 make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
113 const char *name,
114 int x, int y, int width, int height, int es_ver,
115 Window *winRet,
116 EGLContext *ctxRet,
117 EGLSurface *surfRet)
118 {
119 EGLint attribs[] = {
120 EGL_RENDERABLE_TYPE, 0x0,
121 EGL_RED_SIZE, 1,
122 EGL_GREEN_SIZE, 1,
123 EGL_BLUE_SIZE, 1,
124 EGL_NONE
125 };
126 EGLint ctx_attribs[] = {
127 EGL_CONTEXT_CLIENT_VERSION, 0,
128 EGL_NONE
129 };
130
131 int scrnum;
132 XSetWindowAttributes attr;
133 unsigned long mask;
134 Window root;
135 Window win;
136 XVisualInfo *visInfo, visTemplate;
137 int num_visuals;
138 EGLContext ctx;
139 EGLConfig config;
140 EGLint num_configs;
141 EGLint vid;
142
143 scrnum = DefaultScreen( x_dpy );
144 root = RootWindow( x_dpy, scrnum );
145
146 if (es_ver == 1)
147 attribs[1] = EGL_OPENGL_ES_BIT;
148 else
149 attribs[1] = EGL_OPENGL_ES2_BIT;
150 ctx_attribs[1] = es_ver;
151
152 if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
153 printf("Error: couldn't get an EGL visual config\n");
154 exit(1);
155 }
156
157 assert(config);
158 assert(num_configs > 0);
159
160 if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
161 printf("Error: eglGetConfigAttrib() failed\n");
162 exit(1);
163 }
164
165 /* The X window visual must match the EGL config */
166 visTemplate.visualid = vid;
167 visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
168 if (!visInfo) {
169 printf("Error: couldn't get X visual\n");
170 exit(1);
171 }
172
173 /* window attributes */
174 attr.background_pixel = 0;
175 attr.border_pixel = 0;
176 attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
177 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
178 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
179
180 win = XCreateWindow( x_dpy, root, 0, 0, width, height,
181 0, visInfo->depth, InputOutput,
182 visInfo->visual, mask, &attr );
183
184 /* set hints and properties */
185 {
186 XSizeHints sizehints;
187 sizehints.x = x;
188 sizehints.y = y;
189 sizehints.width = width;
190 sizehints.height = height;
191 sizehints.flags = USSize | USPosition;
192 XSetNormalHints(x_dpy, win, &sizehints);
193 XSetStandardProperties(x_dpy, win, name, name,
194 None, (char **)NULL, 0, &sizehints);
195 }
196
197 eglBindAPI(EGL_OPENGL_ES_API);
198
199 ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
200 if (!ctx) {
201 printf("Error: eglCreateContext failed\n");
202 exit(1);
203 }
204
205 *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
206
207 if (!*surfRet) {
208 printf("Error: eglCreateWindowSurface failed\n");
209 exit(1);
210 }
211
212 XFree(visInfo);
213
214 *winRet = win;
215 *ctxRet = ctx;
216 }
217
218
219 static void
usage(void)220 usage(void)
221 {
222 printf("Usage:\n");
223 printf(" -display <displayname> set the display to run on\n");
224 }
225
226
227 int
main(int argc,char * argv[])228 main(int argc, char *argv[])
229 {
230 const int winWidth = 400, winHeight = 300;
231 Display *x_dpy;
232 Window win;
233 EGLSurface egl_surf;
234 EGLContext egl_ctx;
235 EGLDisplay egl_dpy;
236 char *dpyName = NULL;
237 EGLint egl_major, egl_minor, es_ver;
238 int i;
239
240 for (i = 1; i < argc; i++) {
241 if (strcmp(argv[i], "-display") == 0) {
242 dpyName = argv[i+1];
243 i++;
244 }
245 else {
246 usage();
247 return -1;
248 }
249 }
250
251 x_dpy = XOpenDisplay(dpyName);
252 if (!x_dpy) {
253 printf("Error: couldn't open display %s\n",
254 dpyName ? dpyName : getenv("DISPLAY"));
255 return -1;
256 }
257
258 egl_dpy = eglGetDisplay(x_dpy);
259 if (!egl_dpy) {
260 printf("Error: eglGetDisplay() failed\n");
261 return -1;
262 }
263
264 if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
265 printf("Error: eglInitialize() failed\n");
266 return -1;
267 }
268
269 es_ver = 1;
270 /* decide the version from the executable's name */
271 if (argc > 0 && argv[0] && strstr(argv[0], "es2"))
272 es_ver = 2;
273 make_x_window(x_dpy, egl_dpy,
274 "ES info", 0, 0, winWidth, winHeight, es_ver,
275 &win, &egl_ctx, &egl_surf);
276
277 /*XMapWindow(x_dpy, win);*/
278 if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
279 printf("Error: eglMakeCurrent() failed\n");
280 return -1;
281 }
282
283 info(egl_dpy);
284
285 eglDestroyContext(egl_dpy, egl_ctx);
286 eglDestroySurface(egl_dpy, egl_surf);
287 eglTerminate(egl_dpy);
288
289
290 XDestroyWindow(x_dpy, win);
291 XCloseDisplay(x_dpy);
292
293 return 0;
294 }
295