aboutsummaryrefslogtreecommitdiff
path: root/vendor/gioui.org/app/internal/window/gl_macos.go
blob: e4e293deb48a963ab2e0bad2dfdf544ef704bf48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// SPDX-License-Identifier: Unlicense OR MIT

// +build darwin,!ios

package window

import (
	"gioui.org/app/internal/glimpl"
	"gioui.org/gpu/backend"
	"gioui.org/gpu/gl"
)

/*
#include <CoreFoundation/CoreFoundation.h>
#include <CoreGraphics/CoreGraphics.h>
#include <AppKit/AppKit.h>
#include <OpenGL/gl3.h>

__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createGLView(void);
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_contextForView(CFTypeRef viewRef);
__attribute__ ((visibility ("hidden"))) void gio_makeCurrentContext(CFTypeRef ctx);
__attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ctx);
__attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext(void);
__attribute__ ((visibility ("hidden"))) void gio_lockContext(CFTypeRef ctxRef);
__attribute__ ((visibility ("hidden"))) void gio_unlockContext(CFTypeRef ctxRef);
*/
import "C"

type context struct {
	c    *glimpl.Functions
	ctx  C.CFTypeRef
	view C.CFTypeRef
}

func init() {
	viewFactory = func() C.CFTypeRef {
		return C.gio_createGLView()
	}
}

func newContext(w *window) (*context, error) {
	view := w.contextView()
	ctx := C.gio_contextForView(view)
	c := &context{
		ctx:  ctx,
		c:    new(glimpl.Functions),
		view: view,
	}
	return c, nil
}

func (c *context) Backend() (backend.Device, error) {
	return gl.NewBackend(c.c)
}

func (c *context) Release() {
	c.Lock()
	defer c.Unlock()
	C.gio_clearCurrentContext()
	// We could release the context with [view clearGLContext]
	// and rely on [view openGLContext] auto-creating a new context.
	// However that second context is not properly set up by
	// OpenGLContextView, so we'll stay on the safe side and keep
	// the first context around.
}

func (c *context) Present() error {
	// Assume the caller already locked the context.
	C.glFlush()
	return nil
}

func (c *context) Lock() {
	C.gio_lockContext(c.ctx)
}

func (c *context) Unlock() {
	C.gio_unlockContext(c.ctx)
}

func (c *context) MakeCurrent() error {
	c.Lock()
	defer c.Unlock()
	C.gio_makeCurrentContext(c.ctx)
	return nil
}

func (w *window) NewContext() (Context, error) {
	return newContext(w)
}