glfw/tests/threads.c

152 lines
4.0 KiB
C
Raw Permalink Normal View History

2012-08-12 13:05:18 +00:00
//========================================================================
2015-01-05 20:55:15 +00:00
// Multi-threading test
2016-11-21 15:23:59 +00:00
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
2012-08-12 13:05:18 +00:00
//
// 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-12 22:05:54 +00:00
#include "tinycthread.h"
2015-10-14 01:11:20 +00:00
#include <glad/glad.h>
#include <GLFW/glfw3.h>
2012-08-12 13:05:18 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
GLFWwindow* window;
const char* title;
float r, g, b;
2012-08-15 18:26:09 +00:00
thrd_t id;
} Thread;
2015-08-23 17:30:04 +00:00
static volatile int running = GLFW_TRUE;
2012-08-12 13:05:18 +00:00
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
2016-10-09 23:24:16 +00:00
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
2012-08-15 18:26:09 +00:00
static int thread_main(void* data)
2012-08-12 13:05:18 +00:00
{
2014-03-24 12:31:01 +00:00
const Thread* thread = data;
glfwMakeContextCurrent(thread->window);
2012-08-12 13:05:18 +00: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 13:05:18 +00:00
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(thread->window);
2012-08-12 13:05:18 +00: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 13:05:18 +00:00
glfwSetErrorCallback(error_callback);
2012-08-12 13:05:18 +00:00
if (!glfwInit())
exit(EXIT_FAILURE);
2015-08-23 17:30:04 +00:00
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
for (i = 0; i < count; i++)
2012-08-12 13:05:18 +00:00
{
threads[i].window = glfwCreateWindow(200, 200,
threads[i].title,
2012-09-27 19:37:36 +00:00
NULL, NULL);
if (!threads[i].window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
2016-10-09 23:24:16 +00:00
glfwSetKeyCallback(threads[i].window, key_callback);
glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200);
glfwShowWindow(threads[i].window);
2015-10-14 01:11:20 +00:00
}
glfwMakeContextCurrent(threads[0].window);
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
glfwMakeContextCurrent(NULL);
2015-10-14 01:11:20 +00:00
for (i = 0; i < count; i++)
{
2012-08-15 18:26:09 +00: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 13:05:18 +00:00
}
while (running)
2012-08-12 13:05:18 +00:00
{
2012-08-12 14:32:54 +00:00
glfwWaitEvents();
for (i = 0; i < count; i++)
{
if (glfwWindowShouldClose(threads[i].window))
2015-08-23 17:30:04 +00:00
running = GLFW_FALSE;
}
}
2014-04-06 12:41:04 +00:00
for (i = 0; i < count; i++)
glfwHideWindow(threads[i].window);
for (i = 0; i < count; i++)
2012-08-15 18:26:09 +00:00
thrd_join(threads[i].id, &result);
2012-08-12 14:32:54 +00:00
2012-08-12 13:05:18 +00:00
exit(EXIT_SUCCESS);
}