egl_wayland.go 1.9 KB

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