github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/app/internal/wm/gl_macos.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  // +build darwin,!ios
     4  
     5  package wm
     6  
     7  import (
     8  	"errors"
     9  
    10  	"github.com/cybriq/giocore/gpu"
    11  	"github.com/cybriq/giocore/internal/gl"
    12  )
    13  
    14  /*
    15  #include <CoreFoundation/CoreFoundation.h>
    16  #include <CoreGraphics/CoreGraphics.h>
    17  #include <AppKit/AppKit.h>
    18  
    19  __attribute__ ((visibility ("hidden"))) CFTypeRef gio_createGLContext(void);
    20  __attribute__ ((visibility ("hidden"))) void gio_setContextView(CFTypeRef ctx, CFTypeRef view);
    21  __attribute__ ((visibility ("hidden"))) void gio_makeCurrentContext(CFTypeRef ctx);
    22  __attribute__ ((visibility ("hidden"))) void gio_updateContext(CFTypeRef ctx);
    23  __attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ctx);
    24  __attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext(void);
    25  __attribute__ ((visibility ("hidden"))) void gio_lockContext(CFTypeRef ctxRef);
    26  __attribute__ ((visibility ("hidden"))) void gio_unlockContext(CFTypeRef ctxRef);
    27  */
    28  import "C"
    29  
    30  type context struct {
    31  	c    *gl.Functions
    32  	ctx  C.CFTypeRef
    33  	view C.CFTypeRef
    34  }
    35  
    36  func newContext(w *window) (*context, error) {
    37  	view := w.contextView()
    38  	ctx := C.gio_createGLContext()
    39  	if ctx == 0 {
    40  		return nil, errors.New("gl: failed to create NSOpenGLContext")
    41  	}
    42  	// [NSOpenGLContext setView] must run on the main thread. Fortunately,
    43  	// newContext is only called during a [NSView draw] on the main thread.
    44  	w.w.Run(func() {
    45  		C.gio_setContextView(ctx, view)
    46  	})
    47  	c := &context{
    48  		ctx:  ctx,
    49  		view: view,
    50  	}
    51  	return c, nil
    52  }
    53  
    54  func (c *context) API() gpu.API {
    55  	return gpu.OpenGL{}
    56  }
    57  
    58  func (c *context) Release() {
    59  	if c.ctx != 0 {
    60  		C.gio_clearCurrentContext()
    61  		C.CFRelease(c.ctx)
    62  		c.ctx = 0
    63  	}
    64  }
    65  
    66  func (c *context) Present() error {
    67  	return nil
    68  }
    69  
    70  func (c *context) Lock() {
    71  	C.gio_lockContext(c.ctx)
    72  }
    73  
    74  func (c *context) Unlock() {
    75  	C.gio_unlockContext(c.ctx)
    76  }
    77  
    78  func (c *context) Refresh() error {
    79  	c.Lock()
    80  	defer c.Unlock()
    81  	C.gio_updateContext(c.ctx)
    82  	return nil
    83  }
    84  
    85  func (c *context) MakeCurrent() error {
    86  	c.Lock()
    87  	defer c.Unlock()
    88  	C.gio_makeCurrentContext(c.ctx)
    89  	return nil
    90  }
    91  
    92  func (w *window) NewContext() (Context, error) {
    93  	return newContext(w)
    94  }