Skip to content
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

[rcore] GetWindowScaleDPI() inconsistency : RGFW and GLFW backends disagree #4142

Closed
SuperUserNameMan opened this issue Jul 8, 2024 · 14 comments
Labels
windowing Issues about the window system

Comments

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 8, 2024

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)

// Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void)
{
Vector2 scale = {0};
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
return scale;
}

// Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void)
{
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
return (Vector2){((u32)monitor.scaleX)*platform.window->r.w, ((u32) monitor.scaleX)*platform.window->r.h};
}

@SuperUserNameMan
Copy link
Contributor Author

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".

@SuperUserNameMan
Copy link
Contributor Author

I think GLFW backend is correct.

@ColleagueRiley
Copy link
Contributor

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

@SuperUserNameMan
Copy link
Contributor Author

SuperUserNameMan commented Jul 8, 2024

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

@ColleagueRiley
Copy link
Contributor

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

@ColleagueRiley
Copy link
Contributor

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?

@SuperUserNameMan
Copy link
Contributor Author

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 ); // <===
}

@ColleagueRiley
Copy link
Contributor

@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?

@ColleagueRiley
Copy link
Contributor

actually I'll test this myself

@SuperUserNameMan
Copy link
Contributor Author

SuperUserNameMan commented Jul 8, 2024

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.

@ColleagueRiley
Copy link
Contributor

@SuperUserNameMan I get {1.0, 1.0} on both glfw and rgfw no matter what settings I have. Could be something with manjaro.

@SuperUserNameMan
Copy link
Contributor Author

SuperUserNameMan commented Jul 8, 2024

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.

@SuperUserNameMan
Copy link
Contributor Author

SuperUserNameMan commented Jul 8, 2024

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)

@orcmid
Copy link
Contributor

orcmid commented Jul 8, 2024

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.

@raysan5 raysan5 added the windowing Issues about the window system label Aug 24, 2024
@raysan5 raysan5 closed this as completed Sep 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
windowing Issues about the window system
Projects
None yet
Development

No branches or pull requests

4 participants