From 44650c741fc7e00002197001ae252a278b9c3ff5 Mon Sep 17 00:00:00 2001
From: faiface <faiface@ksp.sk>
Date: Tue, 22 Nov 2016 16:59:24 +0100
Subject: [PATCH] add function for managing dedicated OpenGL thread

---
 pixelgl/thread.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 pixelgl/thread.go

diff --git a/pixelgl/thread.go b/pixelgl/thread.go
new file mode 100644
index 0000000..e81257a
--- /dev/null
+++ b/pixelgl/thread.go
@@ -0,0 +1,61 @@
+package pixelgl
+
+import (
+	"runtime"
+)
+
+// 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.
+
+var (
+	callQueue = make(chan func())
+
+	//TODO: some OpenGL state variables will be here
+)
+
+func init() {
+	go func() {
+		runtime.LockOSThread()
+		for f := range callQueue {
+			f()
+		}
+	}()
+}
+
+// Do executes a function inside a dedicated OpenGL thread.
+// Do blocks until the function finishes.
+//
+// All OpenGL calls must be done in the dedicated thread.
+func Do(f func()) {
+	done := make(chan bool)
+	callQueue <- func() {
+		f()
+		done <- true
+	}
+	<-done
+}
+
+// DoErr executes a function inside a dedicated 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.
+func DoErr(f func() error) error {
+	err := make(chan error)
+	callQueue <- func() {
+		err <- f()
+	}
+	return <-err
+}
+
+// DoVal executes a function inside a dedicated 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.
+func DoVal(f func() interface{}) interface{} {
+	val := make(chan interface{})
+	callQueue <- func() {
+		val <- f()
+	}
+	return <-val
+}
-- 
GitLab