我在fork中使用各种GL操作时遇到错误(它们在主线程上工作正常)。例如,createProgram
我得到了:
用户错误(未知的OpenGL扩展条目glCreateProgram,检查OpenGL 3.1)
当我初始化我的背景(4.3核心)后,我正在调用它。
问题是我在使用forkOS
时遇到此错误,但它仍然失败(好像我在一个不知道GL上下文的TLS中)。
发生了什么事?
module Main where
import Graphics.UI.GLUT
import Control.Concurrent
import Control.Monad
main :: IO ()
main = do
getArgsAndInitialize
initialDisplayMode $= [RGBMode, DoubleBuffered]
initialContextVersion $= (4,3)
initialContextProfile $= [CoreProfile]
initialContextFlags $= [DebugContext, ForwardCompatibleContext]
createWindow "GL Window"
createProgram -- Works
forkOS $ void createProgram -- Fails (user error)
displayCallback $= do
clearColor $= Color4 0.2 0.2 1 1
clear [ColorBuffer]
flush >> swapBuffers
mainLoop
答案 0 :(得分:2)
OpenGL上下文绑定到一个线程。基本上它们是TLS结构。 forkOS
不会为您自动“结转”您的OpenGL上下文绑定。 forkOS
的想法是通过它绑定的Haskell操作保持在与操作系统看到的相同的线程中。 forkIO可以通过Haskell自己的调度程序在线程之间进行混乱操作,这只会使FFI调用的库和API的TLS关联成为一场噩梦。
当GLUT createWindow
执行时,它会创建一个窗口和一个OpenGL上下文并将其绑定到调用线程。
所以你必须选择:将OpenGL上下文重新绑定到另一个线程。或者您创建另一个上下文,向第一个上下文安装命名空间共享,并将其绑定到另一个线程。