blob: 27cb7b0680cb59645fa5ad9709fcd0b5d6113439 [file] [log] [blame]
Camilla Berglund5b957152012-08-12 15:05:18 +02001//========================================================================
2// Multithreading test
3// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
4//
5// This software is provided 'as-is', without any express or implied
6// warranty. In no event will the authors be held liable for any damages
7// arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it
11// freely, subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented; you must not
14// claim that you wrote the original software. If you use this software
15// in a product, an acknowledgment in the product documentation would
16// be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such, and must not
19// be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source
22// distribution.
23//
24//========================================================================
25//
26// This test is intended to verify whether the OpenGL context part of
27// the GLFW API is able to be used from multiple threads
28//
29//========================================================================
30
Camilla Berglund63383952012-09-13 00:05:54 +020031#include "tinycthread.h"
32
Camilla Berglund5b957152012-08-12 15:05:18 +020033#include <GL/glfw3.h>
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <math.h>
Camilla Berglund86bcfb32012-08-13 19:37:39 +020038#include <assert.h>
Camilla Berglund5b957152012-08-12 15:05:18 +020039
Camilla Berglund86bcfb32012-08-13 19:37:39 +020040typedef struct
41{
42 GLFWwindow window;
43 const char* title;
44 float r, g, b;
Camilla Berglund12e00872012-08-15 20:26:09 +020045 thrd_t id;
Camilla Berglund86bcfb32012-08-13 19:37:39 +020046} Thread;
47
Camilla Berglundc594bb42012-08-12 22:36:10 +020048static volatile GLboolean running = GL_TRUE;
Camilla Berglund5b957152012-08-12 15:05:18 +020049
Camilla Berglund12e00872012-08-15 20:26:09 +020050static int thread_main(void* data)
Camilla Berglund5b957152012-08-12 15:05:18 +020051{
Camilla Berglund86bcfb32012-08-13 19:37:39 +020052 const Thread* thread = (const Thread*) data;
Camilla Berglund5b957152012-08-12 15:05:18 +020053
Camilla Berglund86bcfb32012-08-13 19:37:39 +020054 glfwMakeContextCurrent(thread->window);
55 assert(glfwGetCurrentContext() == thread->window);
56
Camilla Berglund5b957152012-08-12 15:05:18 +020057 glfwSwapInterval(1);
58
59 while (running)
60 {
Camilla Berglund86bcfb32012-08-13 19:37:39 +020061 const float v = (float) fabs(sin(glfwGetTime() * 2.f));
62 glClearColor(thread->r * v, thread->g * v, thread->b * v, 0.f);
Camilla Berglund5b957152012-08-12 15:05:18 +020063
Camilla Berglund5b957152012-08-12 15:05:18 +020064 glClear(GL_COLOR_BUFFER_BIT);
Camilla Berglund86bcfb32012-08-13 19:37:39 +020065 glfwSwapBuffers(thread->window);
Camilla Berglund5b957152012-08-12 15:05:18 +020066 }
67
68 glfwMakeContextCurrent(NULL);
69 return 0;
70}
71
72int main(void)
73{
Camilla Berglund86bcfb32012-08-13 19:37:39 +020074 int i, result;
75 Thread threads[] =
76 {
77 { NULL, "Red", 1.f, 0.f, 0.f, 0 },
78 { NULL, "Green", 0.f, 1.f, 0.f, 0 },
79 { NULL, "Blue", 0.f, 0.f, 1.f, 0 }
80 };
81 const int count = sizeof(threads) / sizeof(Thread);
Camilla Berglund5b957152012-08-12 15:05:18 +020082
83 if (!glfwInit())
84 {
Camilla Berglund86bcfb32012-08-13 19:37:39 +020085 fprintf(stderr, "Failed to initialize GLFW: %s\n",
86 glfwErrorString(glfwGetError()));
Camilla Berglund5b957152012-08-12 15:05:18 +020087 exit(EXIT_FAILURE);
88 }
89
Camilla Berglund86bcfb32012-08-13 19:37:39 +020090 for (i = 0; i < count; i++)
Camilla Berglund5b957152012-08-12 15:05:18 +020091 {
m@bitsnbites.euc9f4ded2012-10-28 00:23:28 +020092 glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i);
93 glfwWindowHint(GLFW_POSITION_Y, 200);
Camilla Berglund86bcfb32012-08-13 19:37:39 +020094 threads[i].window = glfwCreateWindow(200, 200,
Camilla Berglund86bcfb32012-08-13 19:37:39 +020095 threads[i].title,
Camilla Berglund1be16362012-09-27 21:37:36 +020096 NULL, NULL);
Camilla Berglund86bcfb32012-08-13 19:37:39 +020097 if (!threads[i].window)
98 {
99 fprintf(stderr, "Failed to open GLFW window: %s\n",
100 glfwErrorString(glfwGetError()));
101 exit(EXIT_FAILURE);
102 }
103
Camilla Berglund12e00872012-08-15 20:26:09 +0200104 if (thrd_create(&threads[i].id, thread_main, threads + i) !=
Camilla Berglund86bcfb32012-08-13 19:37:39 +0200105 thrd_success)
106 {
107 fprintf(stderr, "Failed to create secondary thread\n");
108 exit(EXIT_FAILURE);
109 }
Camilla Berglund5b957152012-08-12 15:05:18 +0200110 }
111
Camilla Berglund86bcfb32012-08-13 19:37:39 +0200112 while (running)
Camilla Berglund5b957152012-08-12 15:05:18 +0200113 {
Camilla Berglund86bcfb32012-08-13 19:37:39 +0200114 assert(glfwGetCurrentContext() == NULL);
Camilla Berglund5b957152012-08-12 15:05:18 +0200115
Camilla Berglund40578852012-08-12 16:32:54 +0200116 glfwWaitEvents();
117
Camilla Berglund86bcfb32012-08-13 19:37:39 +0200118 for (i = 0; i < count; i++)
119 {
120 if (glfwGetWindowParam(threads[i].window, GLFW_CLOSE_REQUESTED))
121 running = GL_FALSE;
122 }
123 }
124
125 for (i = 0; i < count; i++)
Camilla Berglund12e00872012-08-15 20:26:09 +0200126 thrd_join(threads[i].id, &result);
Camilla Berglund40578852012-08-12 16:32:54 +0200127
Camilla Berglund5b957152012-08-12 15:05:18 +0200128 exit(EXIT_SUCCESS);
129}
130