raylib
raylib copied to clipboard
[rcore] `GetWindowScaleDPI()` inconsistency : `RGFW` and `GLFW` backends disagree
Testing the RGFW backend and comparing with GLFW : GetWindowSCaleDPI() don't return similar values.
On my Linux desktop :
- the GLFW implementation returns an ~~incorrect~~ unexpected
{ 1.145833 , 1.145833 }value despite the display scale is set to 100%. - the RGFW implementation returns the size of the window or render ... with no diff whatever my display is set to 100% or 200% ...
I don't know which one is correct. Maybe none ? (edit: i think GLFW backend is correct, but it needs a tiny fix somewhere else to solve #3972)
https://github.com/raysan5/raylib/blob/9764fef26260e6fcf671ddffb230360cc1efa1f8/src/platforms/rcore_desktop_glfw.c#L935-L941
https://github.com/raysan5/raylib/blob/9764fef26260e6fcf671ddffb230360cc1efa1f8/src/platforms/rcore_desktop_rgfw.c#L641-L649
Regarding GLFW's glfwGetWindowContentScale() : https://www.glfw.org/docs/latest/window_guide.html#window_scale
The content scale can be thought of as the ratio between the current DPI and the platform's default DPI. It is intended to be a scaling factor to apply to the pixel dimensions of text and other UI elements. If the dimensions scaled by this factor looks appropriate on your machine then it should appear at a reasonable size on other machines with different DPI and scaling settings.
This relies on the DPI and scaling settings on both machines being appropriate.
The content scale may depend on both the monitor resolution and pixel density and on user settings like DPI or a scaling percentage. It may be very different from the raw DPI calculated from the physical size and current resolution.
On systems where each monitors can have its own content scale, the window content scale will depend on which monitor or monitors the system considers the window to be "on".
I think GLFW backend is correct.
This looks like a problem with RGFW itself rather than rcore_desktop_rgfw.c. It would be better to move the issue to the RGFW repo
The GLFW backend returns DPI scales factors. But the RGFW backend returns scaled resolutions.
Shouldn't GetWindowScaleDPI() returns two scale factors instead of the scaled resolution of platform.window->r ?
If yes, then the issue is in the RGFW backend side. (and maybe also on the RGFW repo if DPI scale is not detected correctly) If no, then the issue is in the GLFW backend side.
edit : i've just noticed you're the author of RGFW :-D
GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowContentScale(window, xscale, yscale);
}
https://github.com/glfw/glfw/blob/b35641f4a3c62aa86a0b3c983d163bc0fe36026d/src/window.c#L752
I'm confused with the wording
"glfwGetWindowContentScale" seems like it should be the content scale for that window
Do you know if
Vector2 GetWindowScaleDPI(void)
{
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
return (Vector2){((u32)monitor.scaleX), ((u32) monitor.scaleX)};
}
returns the same output as GLFW?
I tested both backends.
With a 1280x720 window, here are the result of both on my Linux system :
| Backend | GetWindowScaleDPI() |
|---|---|
| GLFW | { 1.145833 , 1.145833 } |
| RGFW | { 1280 , 720 } |
Here the test code i used :
#include "raylib.h"
void update();
void draw();
int main( int argc , char **argv )
{
// SetWindowState( FLAG_MSAA_4X_HINT );
// SetConfigFlags(FLAG_WINDOW_HIGHDPI); // <======= ???
InitWindow( 1280 , 720 , "Test" );
ClearWindowState( FLAG_VSYNC_HINT );
SetTargetFPS( 60 );
//SetWindowState( FLAG_WINDOW_RESIZABLE );
while( ! WindowShouldClose() )
{
update();
BeginDrawing();
{
ClearBackground( RAYWHITE );
draw();
}
EndDrawing();
}
CloseWindow();
}
void update()
{
if ( IsKeyPressed( KEY_F ) )
{
// SetWindowSize( 1280 , 720 );
// ClearWindowState( FLAG_WINDOW_RESIZABLE );
ToggleFullscreen();
// SetWindowState( FLAG_WINDOW_RESIZABLE );
// SetWindowSize( 1280 , 720 );
}
else
if ( ! IsWindowFullscreen() && IsKeyPressed( KEY_B ) )
{
ToggleBorderlessWindowed();
}
}
void draw()
{
int sw = GetScreenWidth();
int sh = GetScreenHeight();
int rw = GetRenderWidth();
int rh = GetRenderHeight();
Vector2 dpi = GetWindowScaleDPI();
int monitor = GetCurrentMonitor();
int mw = GetMonitorWidth( monitor );
int mh = GetMonitorHeight( monitor );
Rectangle infoRect = { 0.0 , 0.0 , sw , sh };
// Draw the border of the screen :
DrawRectangleLinesEx( infoRect , 300.0f , RED );
// Draw the text NOT in the center :
DrawText( TextFormat( "Screen : %d x %d" , sw , sh ) , 10 , 10 , 30 , BROWN );
DrawText( TextFormat( "Render : %d x %d" , rw , rh ) , 10 , 40 , 30 , DARKGREEN );
DrawText( TextFormat( "Monitor[%d] : %d x %d" , monitor , mw , mh ) , 10 , 70 , 30 , DARKBLUE );
DrawText( TextFormat( "DPI : %f x %f" , dpi.x , dpi.y ) , 10 , 100 , 30 , BLACK );
DrawText( TextFormat( "infoRect : %f x %f" , infoRect.width , infoRect.height ) , 10 , 140 , 30 , RED ); // <===
}
@SuperUserNameMan
Could you try to change it to
Vector2 GetWindowScaleDPI(void)
{
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
return (Vector2){monitor.scaleX, monitor.scaleX};
}
instead?
actually I'll test this myself
just tested.
It return { 1.0 , 1.0 }.
I don't think it has to return the exact same value as GLFW, because the GLFW documentation remains quite vague regarding the way the DPI scales are computed. They say there is a mix of this and mix of that, and that, at the end, it is system dependent.
However, if your RGFW framework tries to match the DPI scale of the system, I think we should also open an issue on your repo, because the value does not change when I change the system display DPI setting to 200%.
edit : also, other backends (SDL, Android; DRM) just return { 1.0 , 1.0 } whatsoever, because there is no DPI scale function available.
@SuperUserNameMan I get {1.0, 1.0} on both glfw and rgfw no matter what settings I have. Could be something with manjaro.
No don't worry. I'm on Linux Mint with MATE desktop.
I must have a default DPI hardcoded somewhere on my distro that explains my strange { 1.145833 , 1.145833 } at 100% DPI scale.
The most important, is that it matches when you change the DPI scale of your display settings.
Note that this GetWindowScaleDPI() function is only useful if we want to manage DPI scale by code instead of in an automated way. (so the size of text and UI of our raylib application matches the rest of the desktop environment's text and UI sizes)
If FLAG_WINDOW_HIGHDPI is enabled, that's up to the backend to automatically rescale the size of the window's content to match the DPI scale of the display. (the GLFW backend has a bug that should be fixed by #4143)
Thanks for all the analysis.
I'm uncertain when some of these need to be happening though. InitWindow has a presumed (unscaled?) desired size and there are also matters of default fonts and font rendering in raylib that may not be sensitive to scaling, leading to some p;ixel-expansion ugliness or shrinkage.
I guess the trick will be to see how the raylib/examples can be kept simple.