From 4be626f707d00a41ce96f20c1e6a63a83c6aebad Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 4 Nov 2024 14:34:08 +0900 Subject: [PATCH] internal/graphicsdriver/opengl: bug fix: use GLX when possible for ES Use GLX when possible. EGL with an X window might not work well on Wayland unfortunately. Closes #3152 --- .../graphicsdriver/opengl/graphics_linbsd.go | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/internal/graphicsdriver/opengl/graphics_linbsd.go b/internal/graphicsdriver/opengl/graphics_linbsd.go index cbfe1ee64..37a690cd2 100644 --- a/internal/graphicsdriver/opengl/graphics_linbsd.go +++ b/internal/graphicsdriver/opengl/graphics_linbsd.go @@ -17,11 +17,56 @@ package opengl import ( + "bufio" + "bytes" + "os/exec" + "strings" + "github.com/hajimehoshi/ebiten/v2/internal/glfw" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl" ) +func isGLXExtensionForGL2Available() bool { + var buf bytes.Buffer + cmd := exec.Command("glxinfo") + cmd.Stdout = &buf + if err := cmd.Run(); err != nil { + return false + } + + const ( + indent = " " + ext = "GLX_EXT_create_context_es2_profile" + ) + + var listingExtensions bool + s := bufio.NewScanner(&buf) + for s.Scan() { + if !listingExtensions { + if s.Text() == "GLX extensions:" { + listingExtensions = true + } + continue + } + + if !strings.HasPrefix(s.Text(), indent) { + listingExtensions = false + break + } + + line := s.Text() + for len(line) > 0 { + head, tail, _ := strings.Cut(line, ",") + if strings.TrimSpace(head) == ext { + return true + } + line = tail + } + } + return false +} + type graphicsPlatform struct { window *glfw.Window } @@ -52,8 +97,12 @@ func setGLFWClientAPI(isES bool) error { if err := glfw.WindowHint(glfw.ContextVersionMinor, 0); err != nil { return err } - if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil { - return err + // Use GLX if the extension allows, or use EGL otherwise. + // Prefer GLX since EGL might not work well on Wayland (#3152). + if !isGLXExtensionForGL2Available() { + if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil { + return err + } } return nil }