From 5043d0629500a77155f9608b7a7dbf0d77069c28 Mon Sep 17 00:00:00 2001 From: faiface <faiface@ksp.sk> Date: Fri, 25 Nov 2016 17:12:13 +0100 Subject: [PATCH] change pixelgl, so that it runs on the main thread --- pixelgl/thread.go | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/pixelgl/thread.go b/pixelgl/thread.go index 6153c20..9fc2537 100644 --- a/pixelgl/thread.go +++ b/pixelgl/thread.go @@ -7,23 +7,42 @@ import ( "github.com/go-gl/gl/v3.3-core/gl" ) -// Due to the existance and usage of thread-local variables by OpenGL, it's recommended to -// execute all OpenGL calls from a single dedicated thread. This file defines functions to make -// it possible. +// Due to the limitations of OpenGL and operating systems, all OpenGL related calls must be done from the main thread. var callQueue = make(chan func(), 32) func init() { + runtime.LockOSThread() +} + +// Run is essentialy the "main" function of the pixelgl package. +// Run this function from the main function (because that's guaranteed to run in the main thread). +// +// This function reserves the main thread for the OpenGL stuff and runs a supplied run function in a +// separate goroutine. +// +// Run returns when the provided run function finishes. +func Run(run func()) { + done := make(chan struct{}) + go func() { - runtime.LockOSThread() - for f := range callQueue { + run() + close(done) + }() + +loop: + for { + select { + case f := <-callQueue: f() + case <-done: + break loop } - }() + } } // Init initializes OpenGL by loading the function pointers from the active OpenGL context. -// This function must be manually run inside the dedicated thread (Do, DoErr, DoVal, etc.). +// This function must be manually run inside the main thread (Do, DoErr, DoVal, etc.). // // It must be called under the presence of an active OpenGL context, e.g., always after calling window.MakeContextCurrent(). // Also, always call this function when switching contexts. @@ -34,13 +53,13 @@ func Init() { } } -// DoNoBlock executes a function inside a dedicated OpenGL thread. +// DoNoBlock executes a function inside the main OpenGL thread. // DoNoBlock does not wait until the function finishes. func DoNoBlock(f func()) { callQueue <- f } -// Do executes a function inside a dedicated OpenGL thread. +// Do executes a function inside the main OpenGL thread. // Do blocks until the function finishes. // // All OpenGL calls must be done in the dedicated thread. @@ -53,7 +72,7 @@ func Do(f func()) { <-done } -// DoErr executes a function inside a dedicated OpenGL thread and returns an error to the called. +// DoErr executes a function inside the main OpenGL thread and returns an error to the called. // DoErr blocks until the function finishes. // // All OpenGL calls must be done in the dedicated thread. @@ -65,10 +84,10 @@ func DoErr(f func() error) error { return <-err } -// DoVal executes a function inside a dedicated OpenGL thread and returns a value to the caller. +// DoVal executes a function inside the main OpenGL thread and returns a value to the caller. // DoVal blocks until the function finishes. // -// All OpenGL calls must be done in the dedicated thread. +// All OpenGL calls must be done in the main thread. func DoVal(f func() interface{}) interface{} { val := make(chan interface{}) callQueue <- func() { -- GitLab