fix the spelling in whole piglit
[piglit.git] / tests / egl / egl-util.c
blobfa2f6a37cfe9e3e5dfc0ffb88f86594c7be24dd2
1 /*
2 * Copyright © 2010 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
23 * Author: Kristian Høgsberg <krh@bitplanet.net>
26 /**
27 * \file egl-util.c
28 * Common framework for EGL tests.
30 * \author Kristian Høgsberg <krh@bitplanet.net>
33 #include <X11/XKBlib.h>
34 #include "piglit-util-gl.h"
35 #include "piglit-util-egl.h"
36 #include "egl-util.h"
38 int depth;
40 int
41 egl_probe_front_pixel_rgb(struct egl_state *state,
42 int x, int y, const float *expected)
44 XImage *ximage = XGetImage(state->dpy, state->win,
45 x, state->height - y - 1, 1, 1, AllPlanes, ZPixmap);
46 unsigned long pixel = XGetPixel(ximage, 0, 0);
47 uint8_t *probe = (uint8_t *)&pixel;
48 int pass = 1;
49 int i;
51 XDestroyImage(ximage);
53 /* NB: XGetPixel returns a normalized BGRA, byte per
54 * component, pixel format */
55 for(i = 0; i < 3; ++i) {
56 if (fabs(probe[2 - i]/255.0 - expected[i]) > piglit_tolerance[i]) {
57 pass = 0;
61 if (pass)
62 return 1;
64 printf("Front Buffer Probe at (%i,%i)\n", x, y);
65 printf(" Expected: %f %f %f %f\n", expected[0], expected[1], expected[2], expected[3]);
66 printf(" Observed: %f %f %f %f\n", probe[0]/255.0, probe[1]/255.0, probe[2]/255.0, probe[3]/255.0);
68 return 0;
71 void
72 egl_init_test(struct egl_test *test)
74 static const char *no_extensions[] = { NULL };
76 test->context_attribs = NULL;
77 test->config_attribs = egl_default_attribs;
78 test->surface_attribs = NULL;
79 test->draw = NULL;
80 test->extensions = no_extensions;
81 test->window_width = egl_default_window_width;
82 test->window_height = egl_default_window_height;
83 test->stop_on_failure = true;
86 EGLNativePixmapType
87 egl_util_create_native_pixmap(struct egl_state *state, int width, int height)
89 return XCreatePixmap(state->dpy, state->win,
90 width, height, state->depth);
93 EGLSurface
94 egl_util_create_pixmap(struct egl_state *state,
95 int width, int height, const EGLint *attribs)
97 EGLNativePixmapType pixmap;
98 EGLSurface surf;
100 pixmap = egl_util_create_native_pixmap(state, width, height);
102 surf = eglCreatePixmapSurface(state->egl_dpy, state->cfg,
103 pixmap, attribs);
105 return surf;
108 static enum piglit_result
109 create_window(struct egl_state *state)
111 XSetWindowAttributes window_attr;
112 XVisualInfo template, *vinfo;
113 EGLint id;
114 unsigned long mask;
115 int screen = DefaultScreen(state->dpy);
116 Window root_win = RootWindow(state->dpy, screen);
117 int count;
119 if (!eglGetConfigAttrib(state->egl_dpy,
120 state->cfg, EGL_NATIVE_VISUAL_ID, &id)) {
121 fprintf(stderr, "eglGetConfigAttrib() failed\n");
122 return PIGLIT_FAIL;
125 template.visualid = id;
126 vinfo = XGetVisualInfo(state->dpy, VisualIDMask, &template, &count);
127 if (count != 1) {
128 fprintf(stderr, "XGetVisualInfo() failed\n");
129 if (vinfo)
130 XFree(vinfo);
131 return PIGLIT_FAIL;
134 state->depth = vinfo->depth;
135 window_attr.background_pixel = 0;
136 window_attr.border_pixel = 0;
137 window_attr.colormap = XCreateColormap(state->dpy, root_win,
138 vinfo->visual, AllocNone);
139 window_attr.event_mask =
140 StructureNotifyMask | ExposureMask | KeyPressMask;
141 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
142 state->win = XCreateWindow(state->dpy, root_win, 0, 0,
143 state->width, state->height,
144 0, vinfo->depth, InputOutput,
145 vinfo->visual, mask, &window_attr);
147 /* Some tests expect the window size to be what they set. It is really
148 * up to the window manager to decide the size, but we can at least
149 * try to ask it to do what we want.
151 XSetWMNormalHints(state->dpy, state->win, &(XSizeHints){
152 .flags = PSize | PMinSize | PMaxSize | PBaseSize,
153 .width = state->width,
154 .height = state->height,
155 .min_width = state->width,
156 .min_height = state->height,
157 .max_width = state->width,
158 .max_height = state->height,
159 .base_width = state->width,
160 .base_height = state->height,
163 XMapWindow(state->dpy, state->win);
165 XFree(vinfo);
166 return PIGLIT_PASS;
169 static enum piglit_result
170 event_loop(struct egl_state *state, const struct egl_test *test)
172 XEvent event;
173 enum piglit_result result = PIGLIT_FAIL;
175 while (1) {
176 XNextEvent (state->dpy, &event);
178 if (event.type == Expose) {
179 result = test->draw(state);
180 if (piglit_automatic)
181 break;
184 if (event.type == KeyPress) {
185 KeySym sym = XkbKeycodeToKeysym (state->dpy,
186 event.xkey.keycode,
187 0, 0);
189 if (sym == XK_Escape || sym == XK_q || sym == XK_Q)
190 break;
194 return result;
197 static void
198 check_extensions(struct egl_state *state, const struct egl_test *test)
200 int i;
202 for (i = 0; test->extensions[i]; i++)
203 piglit_require_egl_extension(state->egl_dpy,
204 test->extensions[i]);
207 enum piglit_result
208 egl_util_run(const struct egl_test *test, int argc, char *argv[])
210 struct egl_state state = { 0 };
211 EGLint count;
212 enum piglit_result result = PIGLIT_PASS;
213 int i, dispatch_api, api_bit = EGL_OPENGL_BIT;
215 EGLint nCtxAttribs = 0;
216 EGLint ctxAttribs[40];
218 for (i = 1; i < argc; ++i) {
219 if (!strcmp(argv[i], "-auto"))
220 piglit_automatic = 1;
221 else
222 fprintf(stderr, "Unknown option: %s\n", argv[i]);
225 state.dpy = XOpenDisplay(NULL);
226 if (state.dpy == NULL) {
227 fprintf(stderr, "couldn't open display\n");
228 piglit_report_result(PIGLIT_SKIP);
231 /* read api_bit if EGL_RENDERABLE_TYPE set in the attribs */
232 for (count = 0; test->config_attribs[count] != EGL_NONE; count += 2) {
233 if (test->config_attribs[count] == EGL_RENDERABLE_TYPE) {
234 api_bit = test->config_attribs[count+1];
238 /* choose dispatch_api and set ctx version to ctxAttribs if using ES */
239 switch (api_bit) {
240 case EGL_OPENGL_ES_BIT:
241 dispatch_api = PIGLIT_DISPATCH_ES1;
242 ctxAttribs[nCtxAttribs++] = EGL_CONTEXT_CLIENT_VERSION;
243 ctxAttribs[nCtxAttribs++] = 1;
244 break;
245 case EGL_OPENGL_ES2_BIT:
246 dispatch_api = PIGLIT_DISPATCH_ES2;
247 ctxAttribs[nCtxAttribs++] = EGL_CONTEXT_CLIENT_VERSION;
248 ctxAttribs[nCtxAttribs++] = 2;
249 break;
250 default:
251 fprintf(stderr, "Note: No EGL_RENDERABLE_TYPE defined in test attributes, defaulted to gl\n");
252 dispatch_api = PIGLIT_DISPATCH_GL;
256 state.egl_dpy = piglit_egl_get_display(EGL_PLATFORM_X11_EXT, state.dpy);
257 if (state.egl_dpy == EGL_NO_DISPLAY) {
258 fprintf(stderr, "piglit_egl_get_display() failed\n");
259 result = PIGLIT_FAIL;
260 goto fail;
263 if (!eglInitialize(state.egl_dpy, &state.major, &state.minor)) {
264 fprintf(stderr, "eglInitialize() failed\n");
265 result = PIGLIT_FAIL;
266 goto fail;
269 /* bind chosen API and set ctxattribs if using ES */
270 if (api_bit == EGL_OPENGL_BIT)
271 eglBindAPI(EGL_OPENGL_API);
272 else
273 eglBindAPI(EGL_OPENGL_ES_API);
275 check_extensions(&state, test);
277 if (!eglChooseConfig(state.egl_dpy, test->config_attribs, &state.cfg, 1, &count) ||
278 count == 0) {
279 fprintf(stderr, "eglChooseConfig() failed\n");
280 result = PIGLIT_FAIL;
281 goto fail;
284 for (int i = 0; test->context_attribs && test->context_attribs[i] != EGL_NONE; i++)
285 ctxAttribs[nCtxAttribs++] = test->context_attribs[i];
287 ctxAttribs[nCtxAttribs++] = EGL_NONE;
288 assert(nCtxAttribs < ARRAY_SIZE(ctxAttribs));
290 state.ctx = eglCreateContext(state.egl_dpy, state.cfg,
291 EGL_NO_CONTEXT, ctxAttribs);
292 if (state.ctx == EGL_NO_CONTEXT) {
293 fprintf(stderr, "eglCreateContext() failed\n");
294 result = PIGLIT_FAIL;
295 goto fail;
298 state.width = test->window_width;
299 state.height = test->window_height;
300 result = create_window(&state);
301 if (result != PIGLIT_PASS)
302 goto fail;
304 state.surf = eglCreateWindowSurface(state.egl_dpy,
305 state.cfg, state.win,
306 test->surface_attribs);
307 if (state.surf == EGL_NO_SURFACE) {
308 fprintf(stderr, "eglCreateWindowSurface() failed\n");
309 result = PIGLIT_FAIL;
310 goto fail;
313 if (!eglMakeCurrent(state.egl_dpy,
314 state.surf, state.surf, state.ctx)) {
315 fprintf(stderr, "eglMakeCurrent() failed\n");
316 result = PIGLIT_FAIL;
317 goto fail;
320 piglit_dispatch_default_init(dispatch_api);
322 result = event_loop(&state, test);
324 fail:
325 if (state.egl_dpy) {
326 eglMakeCurrent(state.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
327 eglDestroyContext(state.egl_dpy, state.ctx);
329 if (state.win)
330 XDestroyWindow(state.dpy, state.win);
331 if (state.egl_dpy)
332 eglTerminate(state.egl_dpy);
333 if (test->stop_on_failure)
334 piglit_report_result(result);
335 return result;