From 35290293fe1e354a2a8c974bd979db75325475f2 Mon Sep 17 00:00:00 2001 From: Ali-RS Date: Mon, 9 Jan 2023 21:49:14 +0330 Subject: [PATCH 1/5] jme3-lwjgl:fallback to standard 60Hz fullscreen display mode if the specified frequency in the AppSettings is not available and log a warning. --- .../com/jme3/system/lwjgl/LwjglDisplay.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index cd00e1c3d5..d326217657 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -37,6 +37,9 @@ import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -70,16 +73,23 @@ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, i @Override protected void createContext(AppSettings settings) throws LWJGLException{ DisplayMode displayMode; - if (settings.getWidth() <= 0 || settings.getHeight() <= 0){ + if (settings.getWidth() <= 0 || settings.getHeight() <= 0) { displayMode = Display.getDesktopDisplayMode(); settings.setResolution(displayMode.getWidth(), displayMode.getHeight()); - }else if (settings.isFullscreen()){ + } else if (settings.isFullscreen()) { displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), - settings.getBitsPerPixel(), settings.getFrequency()); + settings.getBitsPerPixel(), settings.getFrequency()); if (displayMode == null) { - throw new RuntimeException("Unable to find fullscreen display mode matching settings"); + // Fallback to standard 60Hz mode if available + displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), + settings.getBitsPerPixel(), 60); + if (displayMode == null) { + throw new RuntimeException("Unable to find fullscreen display mode matching settings"); + } else { + logger.warning("Unable to find fullscreen display mode matching specified frequency, using 60Hz mode instead"); + } } - }else{ + } else { displayMode = new DisplayMode(settings.getWidth(), settings.getHeight()); } From 70c25edba8fbaeceb9e1ef054784f5918b66a2f6 Mon Sep 17 00:00:00 2001 From: Ali-RS Date: Tue, 10 Jan 2023 00:39:38 +0330 Subject: [PATCH 2/5] Fallback to whatever bps or frequency is available. Added a wild-card value to let selecting any bps or frequency available by passing -1. --- .../java/com/jme3/system/lwjgl/LwjglDisplay.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index d326217657..34126e36d1 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2021 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,8 +59,8 @@ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, i for (DisplayMode mode : modes) { if (mode.getWidth() == width && mode.getHeight() == height - && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32)) - && (mode.getFrequency() == freq || (freq == 60 && mode.getFrequency() == 59))) { + && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32) || bpp == -1) + && (mode.getFrequency() == freq || (freq == 60 && mode.getFrequency() == 59) || freq == -1)) { return mode; } } @@ -80,13 +80,12 @@ protected void createContext(AppSettings settings) throws LWJGLException{ displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), settings.getBitsPerPixel(), settings.getFrequency()); if (displayMode == null) { - // Fallback to standard 60Hz mode if available - displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), - settings.getBitsPerPixel(), 60); + // Fall back to whatever is available to the specified width & height + displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), -1, -1); if (displayMode == null) { throw new RuntimeException("Unable to find fullscreen display mode matching settings"); } else { - logger.warning("Unable to find fullscreen display mode matching specified frequency, using 60Hz mode instead"); + logger.warning("Unable to find fullscreen display mode matching settings, falling back to " + displayMode); } } } else { From b6a870038edd2a4ac97f7ee36253b159f73d9b16 Mon Sep 17 00:00:00 2001 From: Ali-RS Date: Tue, 10 Jan 2023 01:41:54 +0330 Subject: [PATCH 3/5] Support AWT display frequency model. Looks like AWT uses mathematics round to convert float frequency values to int while lwjgl 2 uses mathematics floor. For example if frequency is 59.83, AWT will return 60 but lwjgl 2 will return 59. --- .../src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index 34126e36d1..cf14b700c3 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -60,7 +60,7 @@ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, i if (mode.getWidth() == width && mode.getHeight() == height && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32) || bpp == -1) - && (mode.getFrequency() == freq || (freq == 60 && mode.getFrequency() == 59) || freq == -1)) { + && (Math.abs(mode.getFrequency() - freq) <= 1 || (freq == 60 && mode.getFrequency() == 59) || freq == -1)) { return mode; } } @@ -80,12 +80,12 @@ protected void createContext(AppSettings settings) throws LWJGLException{ displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), settings.getBitsPerPixel(), settings.getFrequency()); if (displayMode == null) { - // Fall back to whatever is available to the specified width & height + // Fall back to whatever mode is available at the specified width & height displayMode = getFullscreenDisplayMode(settings.getWidth(), settings.getHeight(), -1, -1); if (displayMode == null) { throw new RuntimeException("Unable to find fullscreen display mode matching settings"); } else { - logger.warning("Unable to find fullscreen display mode matching settings, falling back to " + displayMode); + logger.log(Level.WARNING, "Unable to find fullscreen display mode matching settings, falling back to: {0}", displayMode); } } } else { From a1e0d5ee3ed59a02a344ba69342c98a850efa01e Mon Sep 17 00:00:00 2001 From: Ali-RS Date: Tue, 10 Jan 2023 01:47:50 +0330 Subject: [PATCH 4/5] Remove redundant check. --- .../src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index cf14b700c3..b9418fca99 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -60,7 +60,7 @@ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, i if (mode.getWidth() == width && mode.getHeight() == height && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32) || bpp == -1) - && (Math.abs(mode.getFrequency() - freq) <= 1 || (freq == 60 && mode.getFrequency() == 59) || freq == -1)) { + && (Math.abs(mode.getFrequency() - freq) <= 1 || freq == -1)) { return mode; } } From bc0f6023b76104d234c16c26c00491e74322b239 Mon Sep 17 00:00:00 2001 From: Ali-RS Date: Tue, 10 Jan 2023 11:53:42 +0330 Subject: [PATCH 5/5] Added documentation for getFullscreenDisplayMode method. --- .../java/com/jme3/system/lwjgl/LwjglDisplay.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java index b9418fca99..d5d46ad6ca 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java +++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java @@ -53,6 +53,16 @@ public class LwjglDisplay extends LwjglAbstractDisplay { private final AtomicBoolean needRestart = new AtomicBoolean(false); private PixelFormat pixelFormat; + /** + * @param width The required display width + * @param height The required display height + * @param bpp The required bits per pixel. If -1 is passed it will return + * whatever bpp is found + * @param freq The required frequency, if -1 is passed it will return + * whatever frequency is found + * @return The {@link DisplayMode} matches with specified settings or + * return null if no matching display mode is found + */ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, int freq){ try { DisplayMode[] modes = Display.getAvailableDisplayModes(); @@ -60,6 +70,10 @@ protected DisplayMode getFullscreenDisplayMode(int width, int height, int bpp, i if (mode.getWidth() == width && mode.getHeight() == height && (mode.getBitsPerPixel() == bpp || (bpp == 24 && mode.getBitsPerPixel() == 32) || bpp == -1) + // Looks like AWT uses mathematical round to convert floating point + // frequency values to int while lwjgl 2 uses mathematical floor. + // For example if frequency is 59.83, AWT will return 60 but lwjgl2 + // will return 59. This is what I observed on Linux. - Ali-RS 2023-1-10 && (Math.abs(mode.getFrequency() - freq) <= 1 || freq == -1)) { return mode; }