diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bcad7ef5..9be1c1cd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,8 @@ include_directories(${GLFW_SOURCE_DIR}/include set(GETOPT ${GLFW_SOURCE_DIR}/support/getopt.h ${GLFW_SOURCE_DIR}/support/getopt.c) +set(TINYCTHREAD ${GLFW_SOURCE_DIR}/support/tinycthread.h + ${GLFW_SOURCE_DIR}/support/tinycthread.c) add_executable(clipboard clipboard.c ${GETOPT}) add_executable(defaults defaults.c) @@ -27,6 +29,7 @@ add_executable(joysticks joysticks.c) add_executable(modes modes.c ${GETOPT}) add_executable(peter peter.c) add_executable(reopen reopen.c) +add_executable(threads threads.c ${TINYCTHREAD}) add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") @@ -45,7 +48,7 @@ set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") set(WINDOWS_BINARIES accuracy sharing tearing title windows) set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma glfwinfo - iconify joysticks modes peter reopen) + iconify joysticks modes peter reopen threads) if (MSVC) # Tell MSVC to use main instead of WinMain for Windows subsystem executables diff --git a/tests/threads.c b/tests/threads.c new file mode 100644 index 00000000..ba844dd7 --- /dev/null +++ b/tests/threads.c @@ -0,0 +1,96 @@ +//======================================================================== +// Multithreading test +// Copyright (c) Camilla Berglund +// +// 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 +// +//======================================================================== + +#include + +#include +#include +#include + +#include "tinycthread.h" + +static GLboolean running = GL_TRUE; + +static int thread_start(void* data) +{ + GLFWwindow window = (GLFWwindow) data; + + glfwMakeContextCurrent(window); + glfwSwapInterval(1); + + while (running) + { + const float red = (float) sin(glfwGetTime()) / 2.f + 0.5f; + + glClearColor(red, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +int main(void) +{ + int result; + GLFWwindow window; + thrd_t thread; + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); + exit(EXIT_FAILURE); + } + + window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Multithreading", NULL); + if (!window) + { + fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError())); + exit(EXIT_FAILURE); + } + + if (thrd_create(&thread, thread_start, window) == thrd_success) + { + while (!glfwGetWindowParam(window, GLFW_CLOSE_REQUESTED)) + glfwPollEvents(); + + running = GL_FALSE; + thrd_join(thread, &result); + } + else + { + fprintf(stderr, "Failed to create secondary thread\n"); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} +