diff --git a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java index a80f59850b..0a6e56d1d6 100644 --- a/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java +++ b/jme3-core/src/main/java/com/jme3/system/DisplayInfo.java @@ -34,8 +34,7 @@ import java.util.Objects; /** - * This class holds information about the display that was returned by glfwGetMonitors() calls in - * the context class + * Information about a display and its current display mode. * * @author Kevin Bales * @author wil @@ -54,6 +53,9 @@ public final class DisplayInfo { /** rate - refresh rate that was return from Lwjgl3. */ private int rate; + /** Pixel format depth of the current display mode, in bits per pixel. */ + private int bitDepth; + /** primary - indicates if the display is the primary monitor. */ private boolean primary; @@ -63,7 +65,7 @@ public final class DisplayInfo { private String name; /** - * Create a new display mode object with the default values + * Create a new display info object with the default values */ DisplayInfo() { this(0L /*NULL*/, 1080, 1920, 60, false, "Generic Monitor"); @@ -127,6 +129,15 @@ void setRate(int rate) { this.rate = rate; } + /** + * Sets the pixel format depth of the current display mode, in bits per pixel. + * + * @param bitDepth the number of bits per pixel, or 0 if unavailable + */ + void setBitDepth(int bitDepth) { + this.bitDepth = bitDepth; + } + /** * Set this display as primary or not. * @param primary {@code true} if the display is primary, {@code false} otherwise. @@ -179,6 +190,17 @@ public int getRate() { return rate; } + /** + * Returns the current display mode's pixel format size in bits per pixel. + * This does not describe depth or stencil buffers. A value of 0 means that the + * backend could not report a single bit depth. + * + * @return the number of bits per pixel, or 0 if unavailable + */ + public int getBitDepth() { + return bitDepth; + } + /** * Determines if this display belongs to the main monitor. * @return {@code true} if the display is primary, {@code false} otherwise. @@ -205,6 +227,7 @@ public int hashCode() { hash = 97 * hash + this.width; hash = 97 * hash + this.height; hash = 97 * hash + this.rate; + hash = 97 * hash + this.bitDepth; hash = 97 * hash + (this.primary ? 1 : 0); hash = 97 * hash + Objects.hashCode(this.name); return hash; @@ -237,6 +260,9 @@ public boolean equals(Object obj) { if (this.rate != other.rate) { return false; } + if (this.bitDepth != other.bitDepth) { + return false; + } if (this.primary != other.primary) { return false; } diff --git a/jme3-core/src/main/java/com/jme3/system/Displays.java b/jme3-core/src/main/java/com/jme3/system/Displays.java index c0e24f549f..11817b1c43 100644 --- a/jme3-core/src/main/java/com/jme3/system/Displays.java +++ b/jme3-core/src/main/java/com/jme3/system/Displays.java @@ -28,8 +28,7 @@ import java.util.ArrayList; /** - * This class holds all information about all displays that where return from the glfwGetMonitors() - * call. It stores them into an ArrayList + * Holds information about the displays detected by the active desktop context. * * @author Kevin Bales */ @@ -74,6 +73,7 @@ public DisplayInfo get(int pos) { /** * Set information about this display stored in displayPos display in the array list. + * The bit depth is set to 0 (unavailable) when using this overload. * * @param displayPos ArrayList position of display to update * @param name name of the display @@ -82,12 +82,28 @@ public DisplayInfo get(int pos) { * @param rate the current refresh rate the display is set to */ public void setInfo(int displayPos, String name, int width, int height, int rate) { + setInfo(displayPos, name, width, height, rate, 0); + } + + /** + * Set information about this display stored in displayPos display in the array list. + * + * @param displayPos ArrayList position of display to update + * @param name name of the display + * @param width the current width the display is displaying + * @param height the current height the display is displaying + * @param rate the current refresh rate the display is set to + * @param bitDepth the current display mode's pixel format size in bits per pixel, + * or 0 if unavailable + */ + public void setInfo(int displayPos, String name, int width, int height, int rate, int bitDepth) { if (displayPos < displays.size()) { DisplayInfo info = displays.get(displayPos); if (info != null) { info.setWidth(width); info.setHeight(height); info.setRate(rate); + info.setBitDepth(bitDepth); info.setName(name); } } diff --git a/jme3-core/src/test/java/com/jme3/system/DisplayInfoTest.java b/jme3-core/src/test/java/com/jme3/system/DisplayInfoTest.java new file mode 100644 index 0000000000..3bf9327dc2 --- /dev/null +++ b/jme3-core/src/test/java/com/jme3/system/DisplayInfoTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 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; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +class DisplayInfoTest { + + @Test + void reportsCurrentDisplayModeBitDepth() { + Displays displays = new Displays(); + int displayIndex = displays.addNewMonitor(1L); + + displays.setInfo(displayIndex, "Test display", 1920, 1080, 60, 32); + + assertEquals(32, displays.get(displayIndex).getBitDepth()); + } + + @Test + void legacySetInfoLeavesBitDepthUnavailable() { + Displays displays = new Displays(); + int displayIndex = displays.addNewMonitor(1L); + + displays.setInfo(displayIndex, "Test display", 1920, 1080, 60); + + assertEquals(0, displays.get(displayIndex).getBitDepth()); + } + + @Test + void bitDepthIsPartOfDisplayInfoEquality() { + Displays first = new Displays(); + int firstIndex = first.addNewMonitor(1L); + first.setInfo(firstIndex, "Test display", 1920, 1080, 60, 24); + + Displays second = new Displays(); + int secondIndex = second.addNewMonitor(1L); + second.setInfo(secondIndex, "Test display", 1920, 1080, 60, 32); + + assertNotEquals(first.get(firstIndex), second.get(secondIndex)); + } +} 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 5086bac0ff..14c820a256 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 @@ -1027,9 +1027,10 @@ public Displays getDisplays() { int width = mode.getWidth(); int height = mode.getHeight(); int rate = mode.getRefreshRate(); + int bitDepth = Math.max(0, mode.getBitDepth()); displays.addNewMonitor(i + 1); - displays.setInfo(i, gd.getIDstring(), width, height, rate); + displays.setInfo(i, gd.getIDstring(), width, height, rate, bitDepth); if (defaultgd.equals(gd)) { displays.setPrimaryDisplay(i); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java index 97d9560910..f65005d447 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java @@ -1436,7 +1436,8 @@ public Displays getDisplays() { int width = mode != null ? mode.w() : 0; int height = mode != null ? mode.h() : 0; int rate = mode != null ? Math.round(mode.refresh_rate()) : 0; - displayList.setInfo(monPos, name, width, height, rate); + int bitDepth = mode != null ? SDL_BITSPERPIXEL(mode.format()) : 0; + displayList.setInfo(monPos, name, width, height, rate, bitDepth); LOGGER.log(Level.INFO, "Display id: {0} Resolution: {1} x {2} @ {3}", new Object[]{displayId, width, height, rate});