Skip to content

Fix #1890 (crashes attempting to run example apps in fullscreen with LWJGL v2) #1898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglDisplay.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -50,14 +53,28 @@ 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();
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)
// 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;
}
}
Expand All @@ -70,16 +87,22 @@ 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");
// 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.log(Level.WARNING, "Unable to find fullscreen display mode matching settings, falling back to: {0}", displayMode);
}
}
}else{
} else {
displayMode = new DisplayMode(settings.getWidth(), settings.getHeight());
}

Expand Down