diff --git a/exp/gl/glutil/context_darwin_amd64.go b/exp/gl/glutil/context_darwin_amd64.go index 63cbc10..d92f24e 100644 --- a/exp/gl/glutil/context_darwin_amd64.go +++ b/exp/gl/glutil/context_darwin_amd64.go @@ -15,7 +15,8 @@ package glutil #import #import -void CGCreate(CGLContextObj* ctx) { +CGLError CGCreate(CGLContextObj* ctx) { + CGLError err; CGLPixelFormatAttribute attributes[] = { kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core, kCGLPFAColorSize, (CGLPixelFormatAttribute)24, @@ -27,16 +28,31 @@ void CGCreate(CGLContextObj* ctx) { }; CGLPixelFormatObj pix; GLint num; - CGLChoosePixelFormat(attributes, &pix, &num); - CGLCreateContext(pix, 0, ctx); - CGLDestroyPixelFormat(pix); - CGLSetCurrentContext(*ctx); - CGLLockContext(*ctx); + + if ((err = CGLChoosePixelFormat(attributes, &pix, &num)) != kCGLNoError) { + return err; + } + if ((err = CGLCreateContext(pix, 0, ctx)) != kCGLNoError) { + return err; + } + if ((err = CGLDestroyPixelFormat(pix)) != kCGLNoError) { + return err; + } + if ((err = CGLSetCurrentContext(*ctx)) != kCGLNoError) { + return err; + } + if ((err = CGLLockContext(*ctx)) != kCGLNoError) { + return err; + } + return kCGLNoError; } */ import "C" -import "runtime" +import ( + "fmt" + "runtime" +) // contextGL holds a copy of the OpenGL Context from thread-local storage. // @@ -48,12 +64,14 @@ type contextGL struct { // createContext creates an OpenGL context, binds it as the current context // stored in thread-local storage, and locks the current goroutine to an os // thread. -func createContext() *contextGL { +func createContext() (*contextGL, error) { // The OpenGL active context is stored in TLS. runtime.LockOSThread() c := new(contextGL) - C.CGCreate(&c.ctx) + if cglErr := C.CGCreate(&c.ctx); cglErr != C.kCGLNoError { + return nil, fmt.Errorf("CGL: %v", C.GoString(C.CGLErrorString(cglErr))) + } // Using attribute arrays in OpenGL 3.3 requires the use of a VBA. // But VBAs don't exist in ES 2. So we bind a default one. @@ -61,7 +79,7 @@ func createContext() *contextGL { C.glGenVertexArrays(1, &id) C.glBindVertexArray(id) - return c + return c, nil } // destroy destroys an OpenGL context and unlocks the current goroutine from diff --git a/exp/gl/glutil/context_x11.go b/exp/gl/glutil/context_x11.go index 01c44f5..49bda4b 100644 --- a/exp/gl/glutil/context_x11.go +++ b/exp/gl/glutil/context_x11.go @@ -92,11 +92,11 @@ type contextGL struct { surf C.EGLSurface } -func createContext() *contextGL { +func createContext() (*contextGL, error) { runtime.LockOSThread() c := &contextGL{} C.createContext(&c.dpy, &c.ctx, &c.surf) - return c + return c, nil } func (c *contextGL) destroy() { diff --git a/exp/gl/glutil/glimage_test.go b/exp/gl/glutil/glimage_test.go index bc87fbb..8b3439b 100644 --- a/exp/gl/glutil/glimage_test.go +++ b/exp/gl/glutil/glimage_test.go @@ -24,11 +24,12 @@ import ( ) func TestImage(t *testing.T) { - done := make(chan struct{}) + done := make(chan error) defer close(done) go func() { runtime.LockOSThread() - ctx := createContext() + ctx, err := createContext() + done <- err for { select { case <-gl.WorkAvailable: @@ -39,6 +40,10 @@ func TestImage(t *testing.T) { } } }() + if err := <-done; err != nil { + t.Fatalf("cannot create GL context: %v", err) + } + start() defer stop()