github.com/coming-chat/gomobile@v0.0.0-20220601074111-56995f7d7aba/exp/gl/glutil/context_darwin_desktop.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build darwin && !ios
     6  // +build darwin,!ios
     7  
     8  package glutil
     9  
    10  // TODO(crawshaw): Only used in glutil tests for now (cgo is not support in _test.go files).
    11  // TODO(crawshaw): Export some kind of Context. Work out what we can offer, where. Maybe just for tests.
    12  // TODO(crawshaw): Support android and windows.
    13  
    14  /*
    15  #cgo CFLAGS: -DGL_SILENCE_DEPRECATION
    16  #cgo LDFLAGS: -framework OpenGL
    17  #import <OpenGL/OpenGL.h>
    18  #import <OpenGL/gl3.h>
    19  
    20  CGLError CGCreate(CGLContextObj* ctx) {
    21  	CGLError err;
    22  	CGLPixelFormatAttribute attributes[] = {
    23  		kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
    24  		kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
    25  		kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
    26  		kCGLPFADepthSize, (CGLPixelFormatAttribute)16,
    27  		kCGLPFAAccelerated,
    28  		kCGLPFADoubleBuffer,
    29  		(CGLPixelFormatAttribute) 0
    30  	};
    31  	CGLPixelFormatObj pix;
    32  	GLint num;
    33  
    34  	if ((err = CGLChoosePixelFormat(attributes, &pix, &num)) != kCGLNoError) {
    35  		return err;
    36  	}
    37  	if ((err = CGLCreateContext(pix, 0, ctx)) != kCGLNoError) {
    38  		return err;
    39  	}
    40  	if ((err = CGLDestroyPixelFormat(pix)) != kCGLNoError) {
    41  		return err;
    42  	}
    43  	if ((err = CGLSetCurrentContext(*ctx)) != kCGLNoError) {
    44  		return err;
    45  	}
    46  	if ((err = CGLLockContext(*ctx)) != kCGLNoError) {
    47  		return err;
    48  	}
    49  	return kCGLNoError;
    50  }
    51  */
    52  import "C"
    53  
    54  import (
    55  	"fmt"
    56  	"runtime"
    57  )
    58  
    59  // contextGL holds a copy of the OpenGL Context from thread-local storage.
    60  //
    61  // Do not move a contextGL between goroutines or OS threads.
    62  type contextGL struct {
    63  	ctx C.CGLContextObj
    64  }
    65  
    66  // createContext creates an OpenGL context, binds it as the current context
    67  // stored in thread-local storage, and locks the current goroutine to an os
    68  // thread.
    69  func createContext() (*contextGL, error) {
    70  	// The OpenGL active context is stored in TLS.
    71  	runtime.LockOSThread()
    72  
    73  	c := new(contextGL)
    74  	if cglErr := C.CGCreate(&c.ctx); cglErr != C.kCGLNoError {
    75  		return nil, fmt.Errorf("CGL: %v", C.GoString(C.CGLErrorString(cglErr)))
    76  	}
    77  
    78  	// Using attribute arrays in OpenGL 3.3 requires the use of a VBA.
    79  	// But VBAs don't exist in ES 2. So we bind a default one.
    80  	var id C.GLuint
    81  	C.glGenVertexArrays(1, &id)
    82  	C.glBindVertexArray(id)
    83  
    84  	return c, nil
    85  }
    86  
    87  // destroy destroys an OpenGL context and unlocks the current goroutine from
    88  // its os thread.
    89  func (c *contextGL) destroy() {
    90  	C.CGLUnlockContext(c.ctx)
    91  	C.CGLSetCurrentContext(nil)
    92  	C.CGLDestroyContext(c.ctx)
    93  	c.ctx = nil
    94  	runtime.UnlockOSThread()
    95  }