diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3e6b4477aa..41aa552c70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,7 @@ junit4 = "junit:junit:4.13.2" junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } lwjgl2 = "org.jmonkeyengine:lwjgl:2.9.5" -lwjgl3-awt = "org.jmonkeyengine:lwjgl3-awt:0.2.4" +lwjgl3-awt = "org.lwjglx:lwjgl3-awt:0.2.5" lwjgl3-base = { module = "org.lwjgl:lwjgl", version.ref = "lwjgl3" } lwjgl3-glfw = { module = "org.lwjgl:lwjgl-glfw", version.ref = "lwjgl3" } diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java index 18aa0183ca..eb9e71acce 100644 --- a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java +++ b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java @@ -35,6 +35,8 @@ import com.jme3.app.SimpleApplication; import com.jme3.system.AppSettings; import com.jme3.system.JmeCanvasContext; +import com.jme3.system.JmeSystem; +import com.jme3.system.Platform; import com.jme3.util.JmeFormatter; import java.awt.BorderLayout; import java.awt.Canvas; @@ -60,6 +62,7 @@ public class TestCanvas { private static Container canvasPanel1, canvasPanel2; private static Container currentPanel; private static JTabbedPane tabbedPane; + private static boolean platformX11 = false; private static final String appClass = "jme3test.post.TestRenderToTexture"; private static void createTabs(){ @@ -170,7 +173,7 @@ public void actionPerformed(ActionEvent e){ public void actionPerformed(ActionEvent e) { currentPanel.remove(canvas); app.stop(true); - + createCanvas(appClass); currentPanel.add(canvas, BorderLayout.CENTER); frame.pack(); @@ -187,6 +190,10 @@ public void actionPerformed(ActionEvent ae) { app.stop(); } }); + + if (JmeSystem.getPlatform().getOs() == Platform.Os.Linux) { + frame.setTitle("Test - Platform " + (platformX11 ? "X11" : "XWayland")); + } } private static void createFrame(){ @@ -207,9 +214,9 @@ public void windowClosed(WindowEvent e) { public static void createCanvas(String appClass){ AppSettings settings = new AppSettings(true); - // Note: Only for Linux and Wayland platforms, forces you to - // use XWayland (x11) with awt. - settings.setX11PlatformPreferred(true); + // Note: Only for Linux and Wayland platforms, select the + // XWayland or x11 platform (if possible). + settings.setX11PlatformPreferred(platformX11); settings.setRenderer(AppSettings.LWJGL_OPENGL32); settings.setWidth(640); settings.setHeight(480); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java index b6126a5b44..354679c928 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java @@ -72,7 +72,6 @@ import org.lwjgl.opengl.awt.GLData; import org.lwjgl.system.Configuration; -import org.lwjgl.system.Platform; import static org.lwjgl.system.MemoryUtil.*; import static com.jme3.system.lwjglx.LwjglxDefaultGLPlatform.*; @@ -185,10 +184,10 @@ private class LwjglAWTGLCanvas extends Canvas { /** * Information object used to create the OpenGL context. */ - private GLData data; + private final GLData data; /** Effective data to initialize the context. */ - private GLData effective; + private final GLData effective; /** * Constructor of the LwjglAWTGLCanva class where objects are @@ -200,14 +199,35 @@ public LwjglAWTGLCanvas(GLData data) { this.effective = new GLData(); this.context = NULL; this.data = data; + } + /** + * Create the platform according to the operating system and user + * preferences. + * + * @param settings Backend configurations + */ + public void createPlatform(AppSettings settings) { try { - platformCanvas = createLwjglxGLPlatform(); + platformCanvas = createLwjglxGLPlatform(settings); } catch (UnsupportedOperationException e) { listener.handleError(e.getLocalizedMessage(), e); } } + /** + * Returns information about the controllers (names) that are being + * used. + * + * @return String + */ + public String getVideoDriver() { + if (platformCanvas == null) { + return "Unknown NULL"; + } + return platformCanvas.getVideoDriver(); + } + /** * (non-Javadoc) * @see java.awt.Component#addComponentListener(java.awt.event.ComponentListener) @@ -464,33 +484,8 @@ protected String getCurrentVideoDriver() { buffer.append("AWT|Swing (LWJGLX) GLv") .append(canvas.data.majorVersion) .append('.') - .append(canvas.data.minorVersion); - - String driver = JmeSystem.isWaylandSession() ? "(XWayland|X11) GLX" : "X11 GLX"; - - Platform platform = Platform.get(); - if (null == platform) { - buffer.append(" Unknown NULL"); - } else { - switch (platform) { - case FREEBSD: - buffer.append(" FreeBSD ") - .append(driver); - break; - case LINUX: - buffer.append(" Linux ") - .append(driver); - break; - case MACOSX: - buffer.append(" MacOSX Cocoa NSGL"); - break; - case WINDOWS: - buffer.append(" Win32 WGL"); - break; - default: - break; - } - } + .append(canvas.data.minorVersion) + .append(' ').append(canvas.getVideoDriver()); return String.valueOf(buffer); } @@ -539,11 +534,13 @@ public void run() { renderer.cleanup(); } + canvas.lock(); canvas.releaseContext(); canvas.deleteContext(); canvas.doDisposeCanvas(); canvas.context = NULL; } finally { + canvas.unlock(); renderable.set(false); lock.notifyAll(); } @@ -705,19 +702,12 @@ protected void destroyContext() { */ @Override protected void createContext(AppSettings settings) { - boolean linux = Platform.get() == Platform.LINUX - || Platform.get() == Platform.FREEBSD; - if (!settings.isX11PlatformPreferred() && linux && JmeSystem.isWaylandSession()) { - LOGGER.log(Level.WARNING, "LWJGLX and AWT/Swing only work with X11, so XWayland will be used for GLX."); - } - - // HACK: For LWJGLX to work in Wyland, it is necessary to use GLX via - // XWayland, so LWJGL must be forced to load GLX as a native API. - // This is because LWJGLX does not provide an EGL context. - if (linux && JmeSystem.isWaylandSession()) { + if (settings.isX11PlatformPreferred() && JmeSystem.isWaylandSession()) { Configuration.OPENGL_CONTEXT_API.set("native"); + LOGGER.log(Level.INFO, "The use of GLX is forced through XWayland (X11)."); } + canvas.createPlatform(settings); RENDER_CONFIGS.computeIfAbsent(settings.getRenderer(), (t) -> { return (data) -> { data.majorVersion = 2; @@ -761,7 +751,12 @@ protected void createContext(AppSettings settings) { allowSwapBuffers = settings.isSwapBuffers(); canvas.createContext(); - canvas.makeCurrent(); + try { + canvas.lock(); + canvas.makeCurrent(); + } finally { + canvas.unlock(); + } SwingUtilities.invokeLater(() -> { canvas.validate(); @@ -1070,7 +1065,8 @@ public void setSettings(AppSettings settings) { StringBuilder buffer = new StringBuilder(); buffer.append("LWJGLX is not compatible with ANGLE/SDL or GLES, as it only supports the following:") .append('\n').append(" * WGL | Windows") - .append('\n').append(" * GLX | Linux (X11/XWayland)") + .append('\n').append(" * GLX | Linux (X11)") + .append('\n').append(" * EGL | Linux (XWayland)") .append('\n').append(" * CGL | MacOsX") .append('\n').append(" * Therefore, version ") .append(AppSettings.LWJGL_OPENGL32) @@ -1079,6 +1075,16 @@ public void setSettings(AppSettings settings) { LOGGER.log(Level.WARNING, String.valueOf(buffer)); settings.setRenderer(AppSettings.LWJGL_OPENGL32); } + + if (isGLInitAPI() && JmeSystem.isWaylandSession() + && (getSettings().isX11PlatformPreferred() != settings.isX11PlatformPreferred())) { + LOGGER.log(Level.WARNING, " Platform Preferred: \n" + + " * It is not possible to switch platforms at runtime (from GLX to EGL or vice versa)"); + + settings.setX11PlatformPreferred( + getSettings().isX11PlatformPreferred() + ); + } super.setSettings(settings); } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java index aacda06818..6fa776b8be 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2026 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,8 +31,12 @@ */ package com.jme3.system.lwjglx; -import org.lwjgl.system.Platform; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeSystem; + +import java.util.concurrent.atomic.AtomicBoolean; +import org.lwjgl.system.Platform; import static org.lwjgl.system.MemoryUtil.*; import static org.lwjgl.system.Platform.*; @@ -42,6 +46,11 @@ */ public final class LwjglxDefaultGLPlatform { + /** + * A flag indicating that the GL API has been initialized or loaded. + */ + private static final AtomicBoolean CHECK_GL_INITAPI = new AtomicBoolean(false); + /** * Detects if you are in a Wayland session. * @@ -61,6 +70,18 @@ public static boolean isWayland() { return false; } + /** + * Returns the value of the indicator signaling the load status of the GL + * API. + * + * @see #CHECK_GL_INITAPI + * + * @return boolean + */ + public static boolean isGLInitAPI() { + return CHECK_GL_INITAPI.get(); + } + /** * Returns the pointer to a {@code Display*} that uses X11. * @@ -80,17 +101,23 @@ public static long getX11Display(LwjglxGLPlatform platform) { /** * Returns a drawing platform based on the platform it is running on. * + * @param settings AppSettings + * * @return LwjglxGLPlatform + * * @throws UnsupportedOperationException throws exception if platform is not - * supported + * supported */ - public static LwjglxGLPlatform createLwjglxGLPlatform() throws UnsupportedOperationException { + public static LwjglxGLPlatform createLwjglxGLPlatform(AppSettings settings) throws UnsupportedOperationException { + CHECK_GL_INITAPI.set(true); switch (Platform.get()) { case WINDOWS: return new Win32GLPlatform(); case FREEBSD: case LINUX: - return new X11GLPlatform(); + return JmeSystem.isWaylandSession() && !settings.isX11PlatformPreferred() + ? new WaylandGLPlatform() + : new X11GLPlatform(); case MACOSX: return new MacOSXGLPlatform(); default: diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java index a04ad57923..98f5af81ad 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2026 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,13 @@ */ public interface LwjglxGLPlatform extends PlatformGLCanvas { + /** + * Returns information about the controllers (names) that are being used. + * + * @return String + */ + String getVideoDriver(); + /** * Free the drawing surface. */ diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java index bce9b4c6da..520ecbc164 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2026 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,17 @@ */ final class MacOSXGLPlatform extends PlatformMacOSXGLCanvas implements LwjglxGLPlatform { + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver() + * + * @return String + */ + @Override + public String getVideoDriver() { + return "MacOSX Cocoa NSGL"; + } + /** * (non-Javadoc) * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy() diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java new file mode 100644 index 0000000000..eaac88d711 --- /dev/null +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009-2026 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.system.lwjglx; + +import org.lwjgl.opengl.awt.PlatformLinuxEGLCanvas; +import org.lwjgl.system.Platform; + +/** + * WaylandGLPlatform class that implements the {@link com.jme3.system.lwjglx.LwjglxGLPlatform} + * interface for the Linux (Based) platform with Wayland. + * + * @author wil + */ +final class WaylandGLPlatform extends PlatformLinuxEGLCanvas implements LwjglxGLPlatform { + + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver() + * + * @return String + */ + @Override + public String getVideoDriver() { + Platform platform = Platform.get(); + return (platform == Platform.FREEBSD + ? "FreeBSD" : "Linux") + + " EGL XWayland"; + } + + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy() + */ + @Override + public void destroy() { } +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java index 9312606979..282e654af8 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2026 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,17 @@ */ final class Win32GLPlatform extends PlatformWin32GLCanvas implements LwjglxGLPlatform { + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver() + * + * @return String + */ + @Override + public String getVideoDriver() { + return "Win32 WGL"; + } + /* (non-Javadoc) * @see com.jme3.system.lwjglx.LwjglxGLPlatform#dispose() */ diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java index e5930eb7e3..d290469c21 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2026 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ package com.jme3.system.lwjglx; import org.lwjgl.opengl.awt.*; +import org.lwjgl.system.Platform; import static org.lwjgl.opengl.GLX.*; import static org.lwjgl.system.MemoryUtil.*; @@ -45,6 +46,20 @@ */ final class X11GLPlatform extends PlatformLinuxGLCanvas implements LwjglxGLPlatform { + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver() + * + * @return String + */ + @Override + public String getVideoDriver() { + Platform platform = Platform.get(); + return (platform == Platform.FREEBSD + ? "FreeBSD" : "Linux") + + " X11 GLX"; + } + /** * Returns a pointer to the {@code Display*} of the current X11 window using * AWT.