README: recommend Ninja by default and switch to cmake --build
[piglit.git] / tests / glx / glx-multithread-makecurrent-1.c
blobda4f7c80816ab90d16bf22c7fb3a7817ab0de98d
1 /*
2 * Copyright © 2009-2011 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.
24 /** @file glx-multithread-makecurrent-1.c
26 * First test of GLX_MESA_multithread_makecurrent: Bind one context into
27 * multiple threads and make sure that synchronized rendering from both
28 * threads works correctly.
31 #include <unistd.h>
32 #include "piglit-util-gl.h"
33 #include "piglit-glx-util.h"
34 #include "pthread.h"
36 int piglit_width = 70, piglit_height = 30;
37 static Display *dpy;
38 static Window win;
39 static GLXContext ctx;
40 static pthread_mutex_t mutex;
41 static XVisualInfo *visinfo;
42 static int current_step = 1;
44 static void
45 get_lock_for_step(int step)
47 while (true) {
48 pthread_mutex_lock(&mutex);
49 if (step == current_step) {
50 current_step++;
51 return;
53 pthread_mutex_unlock(&mutex);
54 usleep(1);
58 static void *
59 thread1_func(void *arg)
61 get_lock_for_step(1);
62 glXMakeCurrent(dpy, win, ctx);
63 pthread_mutex_unlock(&mutex);
65 get_lock_for_step(3);
66 glColor4f(0.0, 1.0, 0.0, 1.0);
67 piglit_draw_rect(10, 10, 10, 10);
68 pthread_mutex_unlock(&mutex);
70 get_lock_for_step(5);
71 glXMakeCurrent(dpy, None, None);
72 pthread_mutex_unlock(&mutex);
74 return NULL;
77 static void *
78 thread2_func(void *arg)
80 get_lock_for_step(2);
81 glXMakeCurrent(dpy, win, ctx);
82 pthread_mutex_unlock(&mutex);
84 get_lock_for_step(4);
85 glColor4f(0.0, 0.0, 1.0, 1.0);
86 piglit_draw_rect(30, 10, 10, 10);
87 pthread_mutex_unlock(&mutex);
89 get_lock_for_step(6);
90 glXMakeCurrent(dpy, None, None);
91 pthread_mutex_unlock(&mutex);
93 return NULL;
96 enum piglit_result
97 draw(Display *dpy)
99 GLboolean pass = GL_TRUE;
100 float green[] = {0.0, 1.0, 0.0, 1.0};
101 float blue[] = {0.0, 0.0, 1.0, 1.0};
102 float gray[] = {0.5, 0.5, 0.5, 1.0};
103 pthread_t thread1, thread2;
104 void *retval;
105 int ret;
106 int x1 = 10, x2 = 30;
108 ctx = piglit_get_glx_context(dpy, visinfo);
109 glXMakeCurrent(dpy, win, ctx);
110 piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
112 piglit_require_glx_extension(dpy, "GLX_MESA_multithread_makecurrent");
114 /* Clear background to gray */
115 glClearColor(0.5, 0.5, 0.5, 1.0);
116 glClear(GL_COLOR_BUFFER_BIT);
118 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
120 pthread_mutex_init(&mutex, NULL);
122 /* Now, spawn some threads that do some drawing, both with this
123 * context
125 pthread_create(&thread1, NULL, thread1_func, &x1);
126 pthread_create(&thread2, NULL, thread2_func, &x2);
128 ret = pthread_join(thread1, &retval);
129 assert(ret == 0);
130 ret = pthread_join(thread2, &retval);
131 assert(ret == 0);
133 pthread_mutex_destroy(&mutex);
135 glColor4f(0.0, 1.0, 0.0, 1.0);
136 piglit_draw_rect(50, 10, 10, 10);
138 pass &= piglit_probe_rect_rgba( 0, 10, 10, 10, gray);
139 pass &= piglit_probe_rect_rgba(10, 10, 10, 10, green);
140 pass &= piglit_probe_rect_rgba(20, 10, 10, 10, gray);
141 pass &= piglit_probe_rect_rgba(30, 10, 10, 10, blue);
142 pass &= piglit_probe_rect_rgba(40, 10, 10, 10, gray);
143 pass &= piglit_probe_rect_rgba(50, 10, 10, 10, green);
144 pass &= piglit_probe_rect_rgba(60, 10, 10, 10, gray);
146 pass &= piglit_probe_rect_rgba(0, 0, piglit_width, 10, gray);
147 pass &= piglit_probe_rect_rgba(0, 20, piglit_width, 10, gray);
149 glXSwapBuffers(dpy, win);
151 glXMakeCurrent(dpy, None, None);
152 glXDestroyContext(dpy, ctx);
154 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
158 main(int argc, char **argv)
160 int i;
162 for(i = 1; i < argc; ++i) {
163 if (!strcmp(argv[i], "-auto"))
164 piglit_automatic = 1;
165 else
166 fprintf(stderr, "Unknown option: %s\n", argv[i]);
169 dpy = XOpenDisplay(NULL);
170 if (dpy == NULL) {
171 fprintf(stderr, "couldn't open display\n");
172 piglit_report_result(PIGLIT_FAIL);
174 visinfo = piglit_get_glx_visual(dpy);
175 win = piglit_get_glx_window(dpy, visinfo);
177 piglit_glx_event_loop(dpy, draw);
179 XFree(visinfo);
181 return 0;