github.com/utopiagio/gio@v0.0.8/app/egl_wayland.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 //go:build ((linux && !android) || freebsd) && !nowayland && !noopengl 4 // +build linux,!android freebsd 5 // +build !nowayland 6 // +build !noopengl 7 8 package app 9 10 import ( 11 "errors" 12 "unsafe" 13 14 "github.com/utopiagio/gio/internal/egl" 15 ) 16 17 /* 18 #cgo linux pkg-config: egl wayland-egl 19 #cgo freebsd openbsd LDFLAGS: -lwayland-egl 20 #cgo CFLAGS: -DEGL_NO_X11 21 22 #include <EGL/egl.h> 23 #include <wayland-client.h> 24 #include <wayland-egl.h> 25 */ 26 import "C" 27 28 type wlContext struct { 29 win *window 30 *egl.Context 31 eglWin *C.struct_wl_egl_window 32 } 33 34 func init() { 35 newWaylandEGLContext = func(w *window) (context, error) { 36 disp := egl.NativeDisplayType(unsafe.Pointer(w.display())) 37 ctx, err := egl.NewContext(disp) 38 if err != nil { 39 return nil, err 40 } 41 return &wlContext{Context: ctx, win: w}, nil 42 } 43 } 44 45 func (c *wlContext) Release() { 46 if c.Context != nil { 47 c.Context.Release() 48 c.Context = nil 49 } 50 if c.eglWin != nil { 51 C.wl_egl_window_destroy(c.eglWin) 52 c.eglWin = nil 53 } 54 } 55 56 func (c *wlContext) Refresh() error { 57 c.Context.ReleaseSurface() 58 if c.eglWin != nil { 59 C.wl_egl_window_destroy(c.eglWin) 60 c.eglWin = nil 61 } 62 surf, width, height := c.win.surface() 63 if surf == nil { 64 return errors.New("wayland: no surface") 65 } 66 eglWin := C.wl_egl_window_create(surf, C.int(width), C.int(height)) 67 if eglWin == nil { 68 return errors.New("wayland: wl_egl_window_create failed") 69 } 70 c.eglWin = eglWin 71 eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin))) 72 if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { 73 return err 74 } 75 if err := c.Context.MakeCurrent(); err != nil { 76 return err 77 } 78 defer c.Context.ReleaseCurrent() 79 // We're in charge of the frame callbacks, don't let eglSwapBuffers 80 // wait for callbacks that may never arrive. 81 c.Context.EnableVSync(false) 82 return nil 83 } 84 85 func (c *wlContext) Lock() error { 86 return c.Context.MakeCurrent() 87 } 88 89 func (c *wlContext) Unlock() { 90 c.Context.ReleaseCurrent() 91 }