--- tests/all.tests | 4 + tests/glx/CMakeLists.txt | 8 ++ tests/glx/glx-multithread-makecurrent-1.c | 183 +++++++++++++++++++++++++++++ tests/glx/glx-multithread-makecurrent-2.c | 183 +++++++++++++++++++++++++++++ tests/glx/glx-multithread-makecurrent-3.c | 175 +++++++++++++++++++++++++++ tests/glx/glx-multithread-makecurrent-4.c | 174 +++++++++++++++++++++++++++ 6 files changed, 727 insertions(+), 0 deletions(-) create mode 100644 tests/glx/glx-multithread-makecurrent-1.c create mode 100644 tests/glx/glx-multithread-makecurrent-2.c create mode 100644 tests/glx/glx-multithread-makecurrent-3.c create mode 100644 tests/glx/glx-multithread-makecurrent-4.c
diff --git a/tests/all.tests b/tests/all.tests index 10a384e..7c3df8a 100644 --- a/tests/all.tests +++ b/tests/all.tests @@ -828,6 +828,10 @@ glx = Group() add_plain_test(glx, 'glx-destroycontext-1') add_plain_test(glx, 'glx-destroycontext-2') add_plain_test(glx, 'glx-multithread') +add_plain_test(glx, 'glx-multithread-makecurrent-1') +add_plain_test(glx, 'glx-multithread-makecurrent-2') +add_plain_test(glx, 'glx-multithread-makecurrent-3') +add_plain_test(glx, 'glx-multithread-makecurrent-4') add_plain_test(glx, 'glx-shader-sharing') add_plain_test(glx, 'glx-swap-exchange') glx['glx-swap-event_event'] = PlainExecTest(['glx-swap-event', '-auto', '--event']) diff --git a/tests/glx/CMakeLists.txt b/tests/glx/CMakeLists.txt index 8516dc5..3f86450 100644 --- a/tests/glx/CMakeLists.txt +++ b/tests/glx/CMakeLists.txt @@ -27,6 +27,14 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") add_executable (glx-swap-event glx-swap-event.c) add_executable (glx-make-glxdrawable-current glx-make-glxdrawable-current.c) target_link_libraries(glx-multithread pthread X11) + add_executable (glx-multithread-makecurrent-1 glx-multithread-makecurrent-1.c) + target_link_libraries(glx-multithread-makecurrent-1 pthread) + add_executable (glx-multithread-makecurrent-2 glx-multithread-makecurrent-2.c) + target_link_libraries(glx-multithread-makecurrent-2 pthread) + add_executable (glx-multithread-makecurrent-3 glx-multithread-makecurrent-3.c) + target_link_libraries(glx-multithread-makecurrent-3 pthread) + add_executable (glx-multithread-makecurrent-4 glx-multithread-makecurrent-4.c) + target_link_libraries(glx-multithread-makecurrent-4 pthread) add_executable (glx-swap-exchange glx-swap-exchange.c) target_link_libraries(glx-swap-exchange X11) add_executable (glx-tfp glx-tfp.c) diff --git a/tests/glx/glx-multithread-makecurrent-1.c b/tests/glx/glx-multithread-makecurrent-1.c new file mode 100644 index 0000000..aa5b5a1 --- /dev/null +++ b/tests/glx/glx-multithread-makecurrent-1.c @@ -0,0 +1,183 @@ +/* + * Copyright © 2009-2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file glx-multithread-makecurrent-1.c + * + * First test of GLX_MESA_multithread_makecurrent: Bind one context into + * multiple threads and make sure that synchronized rendering from both + * threads works correctly. + */ + +#include <unistd.h> +#include "piglit-util.h" +#include "piglit-glx-util.h" +#include "pthread.h" + +int piglit_width = 70, piglit_height = 30; +static Display *dpy; +static Window win; +static GLXContext ctx; +static pthread_mutex_t mutex; +static XVisualInfo *visinfo; +static int current_step = 1; + +static void +get_lock_for_step(int step) +{ + while (true) { + pthread_mutex_lock(&mutex); + if (step == current_step) { + current_step++; + return; + } + pthread_mutex_unlock(&mutex); + usleep(1); + } +} + +static void * +thread1_func(void *arg) +{ + get_lock_for_step(1); + glXMakeCurrent(dpy, win, ctx); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(3); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(10, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(5); + glXMakeCurrent(dpy, None, None); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +static void * +thread2_func(void *arg) +{ + get_lock_for_step(2); + glXMakeCurrent(dpy, win, ctx); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(4); + glColor4f(0.0, 0.0, 1.0, 0.0); + piglit_draw_rect(30, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(6); + glXMakeCurrent(dpy, None, None); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +enum piglit_result +draw(Display *dpy) +{ + GLboolean pass = GL_TRUE; + float green[] = {0.0, 1.0, 0.0, 1.0}; + float blue[] = {0.0, 0.0, 1.0, 1.0}; + float gray[] = {0.5, 0.5, 0.5, 1.0}; + pthread_t thread1, thread2; + void *retval; + int ret; + int x1 = 10, x2 = 30; + + ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, ctx); + + piglit_require_glx_extension(dpy, "MESA_multithread_makecurrent"); + + /* Clear background to gray */ + glClearColor(0.5, 0.5, 0.5, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + pthread_mutex_init(&mutex, NULL); + + /* Now, spawn some threads that do some drawing, both with this + * context + */ + pthread_create(&thread1, NULL, thread1_func, &x1); + pthread_create(&thread2, NULL, thread2_func, &x2); + + ret = pthread_join(thread1, &retval); + assert(ret == 0); + ret = pthread_join(thread2, &retval); + assert(ret == 0); + + pthread_mutex_destroy(&mutex); + + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(50, 10, 10, 10); + + pass &= piglit_probe_rect_rgba( 0, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(10, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(20, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(30, 10, 10, 10, blue); + pass &= piglit_probe_rect_rgba(40, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(50, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(60, 10, 10, 10, gray); + + pass &= piglit_probe_rect_rgba(0, 0, piglit_width, 10, gray); + pass &= piglit_probe_rect_rgba(0, 20, piglit_width, 10, gray); + + glXSwapBuffers(dpy, win); + + glXMakeCurrent(dpy, None, None); + glXDestroyContext(dpy, ctx); + + return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE; +} + +int +main(int argc, char **argv) +{ + int i; + + for(i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-auto")) + piglit_automatic = 1; + else + fprintf(stderr, "Unknown option: %s\n", argv[i]); + } + + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + fprintf(stderr, "couldn't open display\n"); + piglit_report_result(PIGLIT_FAILURE); + } + visinfo = piglit_get_glx_visual(dpy); + win = piglit_get_glx_window(dpy, visinfo); + + XFree(visinfo); + + XMapWindow(dpy, win); + + piglit_glx_event_loop(dpy, draw); + + return 0; +} diff --git a/tests/glx/glx-multithread-makecurrent-2.c b/tests/glx/glx-multithread-makecurrent-2.c new file mode 100644 index 0000000..ae3276c --- /dev/null +++ b/tests/glx/glx-multithread-makecurrent-2.c @@ -0,0 +1,183 @@ +/* + * Copyright © 2009-2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file glx-multithread-makecurrent-2.c + * + * Test of issue #1 of GLX_MESA_multithread_makecurrent: Bind one + * context into multiple threads, do rendering from both, then make + * sure that once we bind a new context to one thread that rendering + * from the second can continue. + */ + +#include <unistd.h> +#include "piglit-util.h" +#include "piglit-glx-util.h" +#include "pthread.h" + +int piglit_width = 70, piglit_height = 30; +static Display *dpy; +static Window win; +static GLXContext ctx; +static pthread_mutex_t mutex; +static XVisualInfo *visinfo; +static int current_step = 1; + +static void +get_lock_for_step(int step) +{ + while (true) { + pthread_mutex_lock(&mutex); + if (step == current_step) { + current_step++; + return; + } + pthread_mutex_unlock(&mutex); + usleep(1); + } +} + +static void * +thread1_func(void *arg) +{ + GLXContext new_ctx; + + get_lock_for_step(1); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(10, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(3); + new_ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, new_ctx); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(5); + glXMakeCurrent(dpy, None, None); + glXDestroyContext(dpy, new_ctx); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +static void * +thread2_func(void *arg) +{ + get_lock_for_step(2); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(30, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(4); + piglit_draw_rect(50, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +enum piglit_result +draw(Display *dpy) +{ + GLboolean pass = GL_TRUE; + float green[] = {0.0, 1.0, 0.0, 1.0}; + float gray[] = {0.5, 0.5, 0.5, 1.0}; + pthread_t thread1, thread2; + void *retval; + int ret; + + ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, ctx); + + piglit_require_glx_extension(dpy, "MESA_multithread_makecurrent"); + + /* Clear background to gray */ + glClearColor(0.5, 0.5, 0.5, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + pthread_mutex_init(&mutex, NULL); + + glFlush(); + /* Now, spawn some threads that do some drawing, both with this + * context + */ + pthread_create(&thread1, NULL, thread1_func, NULL); + pthread_create(&thread2, NULL, thread2_func, NULL); + + ret = pthread_join(thread1, &retval); + assert(ret == 0); + ret = pthread_join(thread2, &retval); + assert(ret == 0); + + pthread_mutex_destroy(&mutex); + glFlush(); + + pass &= piglit_probe_rect_rgba( 0, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(10, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(20, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(30, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(40, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(50, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(60, 10, 10, 10, gray); + + pass &= piglit_probe_rect_rgba(0, 0, piglit_width, 10, gray); + pass &= piglit_probe_rect_rgba(0, 20, piglit_width, 10, gray); + + glXSwapBuffers(dpy, win); + + glXMakeCurrent(dpy, None, None); + glXDestroyContext(dpy, ctx); + + return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE; +} + +int +main(int argc, char **argv) +{ + int i; + + for(i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-auto")) + piglit_automatic = 1; + else + fprintf(stderr, "Unknown option: %s\n", argv[i]); + } + + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + fprintf(stderr, "couldn't open display\n"); + piglit_report_result(PIGLIT_FAILURE); + } + visinfo = piglit_get_glx_visual(dpy); + win = piglit_get_glx_window(dpy, visinfo); + + XMapWindow(dpy, win); + + piglit_glx_event_loop(dpy, draw); + + XFree(visinfo); + + return 0; +} diff --git a/tests/glx/glx-multithread-makecurrent-3.c b/tests/glx/glx-multithread-makecurrent-3.c new file mode 100644 index 0000000..c1f5540 --- /dev/null +++ b/tests/glx/glx-multithread-makecurrent-3.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2009-2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file glx-multithread-makecurrent-3.c + * + * Test of issue #2 of GLX_MESA_multithread_makecurrent: Bind one + * context into multiple threads, do rendering from both, then make + * sure that once we unbind from one that rendering from the second + * can continue. + */ + +#include <unistd.h> +#include "piglit-util.h" +#include "piglit-glx-util.h" +#include "pthread.h" + +int piglit_width = 70, piglit_height = 30; +static Display *dpy; +static Window win; +static GLXContext ctx; +static pthread_mutex_t mutex; +static XVisualInfo *visinfo; +static int current_step = 1; + +static void +get_lock_for_step(int step) +{ + while (true) { + pthread_mutex_lock(&mutex); + if (step == current_step) { + current_step++; + return; + } + pthread_mutex_unlock(&mutex); + usleep(1); + } +} + +static void * +thread1_func(void *arg) +{ + get_lock_for_step(1); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(10, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(3); + glXMakeCurrent(dpy, None, None); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +static void * +thread2_func(void *arg) +{ + get_lock_for_step(2); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(30, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(4); + piglit_draw_rect(50, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +enum piglit_result +draw(Display *dpy) +{ + GLboolean pass = GL_TRUE; + float green[] = {0.0, 1.0, 0.0, 1.0}; + float gray[] = {0.5, 0.5, 0.5, 1.0}; + pthread_t thread1, thread2; + void *retval; + int ret; + + ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, ctx); + + piglit_require_glx_extension(dpy, "MESA_multithread_makecurrent"); + + /* Clear background to gray */ + glClearColor(0.5, 0.5, 0.5, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + pthread_mutex_init(&mutex, NULL); + + glFlush(); + /* Now, spawn some threads that do some drawing, both with this + * context + */ + pthread_create(&thread1, NULL, thread1_func, NULL); + pthread_create(&thread2, NULL, thread2_func, NULL); + + ret = pthread_join(thread1, &retval); + assert(ret == 0); + ret = pthread_join(thread2, &retval); + assert(ret == 0); + + pthread_mutex_destroy(&mutex); + glFlush(); + + pass &= piglit_probe_rect_rgba( 0, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(10, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(20, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(30, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(40, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(50, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(60, 10, 10, 10, gray); + + pass &= piglit_probe_rect_rgba(0, 0, piglit_width, 10, gray); + pass &= piglit_probe_rect_rgba(0, 20, piglit_width, 10, gray); + + glXSwapBuffers(dpy, win); + + glXMakeCurrent(dpy, None, None); + glXDestroyContext(dpy, ctx); + + return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE; +} + +int +main(int argc, char **argv) +{ + int i; + + for(i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-auto")) + piglit_automatic = 1; + else + fprintf(stderr, "Unknown option: %s\n", argv[i]); + } + + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + fprintf(stderr, "couldn't open display\n"); + piglit_report_result(PIGLIT_FAILURE); + } + visinfo = piglit_get_glx_visual(dpy); + win = piglit_get_glx_window(dpy, visinfo); + + XFree(visinfo); + + XMapWindow(dpy, win); + + piglit_glx_event_loop(dpy, draw); + + return 0; +} diff --git a/tests/glx/glx-multithread-makecurrent-4.c b/tests/glx/glx-multithread-makecurrent-4.c new file mode 100644 index 0000000..2118271 --- /dev/null +++ b/tests/glx/glx-multithread-makecurrent-4.c @@ -0,0 +1,174 @@ +/* + * Copyright © 2009-2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** @file glx-multithread-makecurrent-4.c + * + * Test of issue #3 of GLX_MESA_multithread_makecurrent: Bind one + * context into multiple threads, do rendering from both, then destroy + * the context in one and keep using it to render from the other. + */ + +#include <unistd.h> +#include "piglit-util.h" +#include "piglit-glx-util.h" +#include "pthread.h" + +int piglit_width = 70, piglit_height = 30; +static Display *dpy; +static Window win; +static GLXContext ctx; +static pthread_mutex_t mutex; +static XVisualInfo *visinfo; +static int current_step = 1; + +static void +get_lock_for_step(int step) +{ + while (true) { + pthread_mutex_lock(&mutex); + if (step == current_step) { + current_step++; + return; + } + pthread_mutex_unlock(&mutex); + usleep(1); + } +} + +static void * +thread1_func(void *arg) +{ + get_lock_for_step(1); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(10, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(3); + glXMakeCurrent(dpy, None, None); + glXDestroyContext(dpy, ctx); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +static void * +thread2_func(void *arg) +{ + get_lock_for_step(2); + glXMakeCurrent(dpy, win, ctx); + glColor4f(0.0, 1.0, 0.0, 0.0); + piglit_draw_rect(30, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + get_lock_for_step(4); + piglit_draw_rect(50, 10, 10, 10); + pthread_mutex_unlock(&mutex); + + return NULL; +} + +enum piglit_result +draw(Display *dpy) +{ + GLboolean pass = GL_TRUE; + float green[] = {0.0, 1.0, 0.0, 1.0}; + float gray[] = {0.5, 0.5, 0.5, 1.0}; + pthread_t thread1, thread2; + void *retval; + int ret; + + ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, ctx); + + piglit_require_glx_extension(dpy, "MESA_multithread_makecurrent"); + + /* Clear background to gray */ + glClearColor(0.5, 0.5, 0.5, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + pthread_mutex_init(&mutex, NULL); + + glFlush(); + /* Now, spawn some threads that do some drawing, both with this + * context + */ + pthread_create(&thread1, NULL, thread1_func, NULL); + pthread_create(&thread2, NULL, thread2_func, NULL); + + ret = pthread_join(thread1, &retval); + assert(ret == 0); + ret = pthread_join(thread2, &retval); + assert(ret == 0); + + pthread_mutex_destroy(&mutex); + glFlush(); + + pass &= piglit_probe_rect_rgba( 0, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(10, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(20, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(30, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(40, 10, 10, 10, gray); + pass &= piglit_probe_rect_rgba(50, 10, 10, 10, green); + pass &= piglit_probe_rect_rgba(60, 10, 10, 10, gray); + + pass &= piglit_probe_rect_rgba(0, 0, piglit_width, 10, gray); + pass &= piglit_probe_rect_rgba(0, 20, piglit_width, 10, gray); + + glXSwapBuffers(dpy, win); + + glXMakeCurrent(dpy, None, None); + + return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE; +} + +int +main(int argc, char **argv) +{ + int i; + + for(i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-auto")) + piglit_automatic = 1; + else + fprintf(stderr, "Unknown option: %s\n", argv[i]); + } + + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + fprintf(stderr, "couldn't open display\n"); + piglit_report_result(PIGLIT_FAILURE); + } + visinfo = piglit_get_glx_visual(dpy); + win = piglit_get_glx_window(dpy, visinfo); + + XFree(visinfo); + + XMapWindow(dpy, win); + + piglit_glx_event_loop(dpy, draw); + + return 0; +} -- 1.7.4.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev