glfw/tests/threads.c

135 lines
3.6 KiB
C
Raw Normal View History

2012-08-12 15:05:18 +02:00
//========================================================================
// Multithreading test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test is intended to verify whether the OpenGL context part of
// the GLFW API is able to be used from multiple threads
//
//========================================================================
2012-09-13 00:05:54 +02:00
#include "tinycthread.h"
2012-08-12 15:05:18 +02:00
#include <GL/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
2012-08-12 15:05:18 +02:00
typedef struct
{
GLFWwindow window;
const char* title;
float r, g, b;
2012-08-15 20:26:09 +02:00
thrd_t id;
} Thread;
2012-08-12 22:36:10 +02:00
static volatile GLboolean running = GL_TRUE;
2012-08-12 15:05:18 +02:00
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
2012-08-15 20:26:09 +02:00
static int thread_main(void* data)
2012-08-12 15:05:18 +02:00
{
const Thread* thread = (const Thread*) data;
glfwMakeContextCurrent(thread->window);
assert(glfwGetCurrentContext() == thread->window);
2012-08-12 15:05:18 +02:00
glfwSwapInterval(1);
while (running)
{
const float v = (float) fabs(sin(glfwGetTime() * 2.f));
glClearColor(thread->r * v, thread->g * v, thread->b * v, 0.f);
2012-08-12 15:05:18 +02:00
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(thread->window);
2012-08-12 15:05:18 +02:00
}
glfwMakeContextCurrent(NULL);
return 0;
}
int main(void)
{
int i, result;
Thread threads[] =
{
{ NULL, "Red", 1.f, 0.f, 0.f, 0 },
{ NULL, "Green", 0.f, 1.f, 0.f, 0 },
{ NULL, "Blue", 0.f, 0.f, 1.f, 0 }
};
const int count = sizeof(threads) / sizeof(Thread);
2012-08-12 15:05:18 +02:00
glfwSetErrorCallback(error_callback);
2012-08-12 15:05:18 +02:00
if (!glfwInit())
exit(EXIT_FAILURE);
for (i = 0; i < count; i++)
2012-08-12 15:05:18 +02:00
{
glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i);
glfwWindowHint(GLFW_POSITION_Y, 200);
threads[i].window = glfwCreateWindow(200, 200,
threads[i].title,
2012-09-27 21:37:36 +02:00
NULL, NULL);
if (!threads[i].window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
2012-08-15 20:26:09 +02:00
if (thrd_create(&threads[i].id, thread_main, threads + i) !=
thrd_success)
{
fprintf(stderr, "Failed to create secondary thread\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
2012-08-12 15:05:18 +02:00
}
while (running)
2012-08-12 15:05:18 +02:00
{
assert(glfwGetCurrentContext() == NULL);
2012-08-12 15:05:18 +02:00
2012-08-12 16:32:54 +02:00
glfwWaitEvents();
for (i = 0; i < count; i++)
{
if (glfwGetWindowParam(threads[i].window, GLFW_SHOULD_CLOSE))
running = GL_FALSE;
}
}
for (i = 0; i < count; i++)
2012-08-15 20:26:09 +02:00
thrd_join(threads[i].id, &result);
2012-08-12 16:32:54 +02:00
2012-08-12 15:05:18 +02:00
exit(EXIT_SUCCESS);
}