raylib icon indicating copy to clipboard operation
raylib copied to clipboard

[rcore] Wayland: GLFW framebuffer scale is handled incorrectly

Open gfaster opened this issue 9 months ago • 14 comments

Please, before submitting a new issue verify and check:

  • [X] I tested it on latest raylib version from master branch
  • [X] I checked there is no similar issue already reported
  • [X] I checked the documentation on the wiki
  • [X] My code has no errors or misuse of raylib

Issue description

This is effectively a followup to #4815.

GLFW 4.3 now handles fractional scaling correctly by default, namely changing GLFW_COCOA_RETINA_FRAMEBUFFER to GLFW_SCALE_FRAMEBUFFER and enabling it by default. much of the handling the Raylib to handle when screen size doesn't equal render size is redundant and breaks rendering.

I'm including a workaround that goes back to pre-4.3 behavior. I also wrote a more complete fix, but I don't have the means to test it, so I figured going back to old behavior would be preferable for now.

Environment

OS: NixOS 25.05pre785698.b024ced1aac2 (Warbler)
Kernel: Linux 6.13.11
Display (LG HDR 4K): 3840x2160 @ 60 Hz (as 2259x1271) in 27"
Display (XB271HU): 2560x1440 @ 144 Hz (as 2229x1253) in 27"
WM: KWin (Wayland)
CPU: Intel(R) Core(TM) i7-7700 (8) @ 4.20 GHz
GPU: NVIDIA GeForce RTX 2080 Rev. A
INFO: GL: Supported extensions count: 395
INFO: GL: OpenGL device information:
INFO:     > Vendor:   NVIDIA Corporation
INFO:     > Renderer: NVIDIA GeForce RTX 2080/PCIe/SSE2
INFO:     > Version:  3.3.0 NVIDIA 570.133.07
INFO:     > GLSL:     3.30 NVIDIA via Cg compile

Cmake command:

cmake .. -DUSE_EXTERNAL_GLFW=ON -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DBUILD_SHARED_LIBS=ON

Issue Screenshot

Current behavior is identical to the screenshot in #4815

Image

Code Example

#include "raylib.h"
#include <GLFW/glfw3.h>
#include <stdio.h>

#define RECT_SIZE 100.0f

void
print_info(GLFWwindow *handle)
{
	int glfw_winx, glfw_winy;
	glfwGetWindowSize(handle, &glfw_winx, &glfw_winy);
	printf("GLFW window size:      %d, %d\n", glfw_winx, glfw_winy);

	int glfw_fbx, glfw_fby;
	glfwGetFramebufferSize(handle, &glfw_fbx, &glfw_fby);
	printf("GLFW framebuffer size: %d, %d\n", glfw_fbx, glfw_fby);

	int rl_winx, rl_winy;
	rl_winx = GetScreenWidth();
	rl_winy = GetScreenHeight();
	printf("RL window size:        %d, %d\n", rl_winx, rl_winy);

	int rl_fbx, rl_fby;
	rl_fbx = GetRenderWidth();
	rl_fby = GetRenderHeight();
	printf("RL render size:        %d, %d\n", rl_fbx, rl_fby);

	puts("");
}

void
draw(GLFWwindow *handle)
{
	// Draw a square at each corner of the screen, turning blue if the
	// mouse is over the top left square
	ClearBackground(BLACK);
	Vector2 pos = GetMousePosition();
	Color rcolor = (pos.x < RECT_SIZE && pos.y < RECT_SIZE) ? BLUE : RED;
	Vector2 bot = (Vector2) { (float)GetScreenWidth() - RECT_SIZE, (float)GetScreenHeight() - RECT_SIZE };
	DrawRectangleRec((Rectangle){0.0f, 0.0f, RECT_SIZE, RECT_SIZE}, rcolor);
	DrawRectangleRec((Rectangle){bot.x, 0.0f, RECT_SIZE, RECT_SIZE}, rcolor);
	DrawRectangleRec((Rectangle){bot.x, bot.y, RECT_SIZE, RECT_SIZE}, rcolor);
	DrawRectangleRec((Rectangle){0.0f, bot.y, RECT_SIZE, RECT_SIZE}, rcolor);

	(void)handle;
	// print_info(handle);
}

int
main(void)
{
	glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);

	// SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_MSAA_4X_HINT);
	SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);
	InitWindow(640, 480, "Issue on Wayland");
	GLFWwindow *handle = glfwGetCurrentContext();
	print_info(handle);
	SetTargetFPS(60);
	while(!WindowShouldClose()) {
		BeginDrawing();
		draw(handle);
		EndDrawing();
	}
}

gfaster avatar Apr 25 '25 18:04 gfaster

much of the handling the Raylib to handle when screen size doesn't equal render size is redundant and breaks rendering.

Definitely, that should be reviewed.

raysan5 avatar Apr 26 '25 13:04 raysan5

Via a friend's Mac, it seems like FLAG_WINDOW_HIGHDPI is broken in a similar way on MacOS (seems like not fixed by #4909 ). git-bisect tells us it was broken by 4bed3741c1b7167f53bff6c806ba301d93db1b05 -- this should be fixed when GLFW 4.3 behavior is matched

gfaster avatar Apr 26 '25 17:04 gfaster

👋🏼 I recently updated Raylib and my game doesn't work anymore. I'm not sure if this Issue is the right place to report it or if I should open a new Issue.

Steps to reproduce:

  1. git clone --recurse-submodules [email protected]:vegerot/snek.git
  2. zig build play

This should work!

Image

Now

  1. cd raylib && git switch -d 5c954c1f (this is the next commit!)
  2. zig build play

Expected: Should also work

Actual: it looks wrong. It's super zoomed in

Image

I found two workarounds:

  1. Resize the window. If you resize the window, the game will fix itself and look correct
  2. In snek.zig:682, set raylib.FLAG_WINDOW_HIGHDPI. This will also make it work correctly

Is this bug related to the current issue, or should I open a new one? My issue was introduced in 5c954c1f52cb04631c118f67b36b0b768a1f40b2 which seems related...

vegerot avatar May 31 '25 00:05 vegerot

@vegerot I was testing this on a Mac earlier, and it seems that the old behavior was horribly broken. Fundamentally, you should be drawing things according to the window size and not the render size, which is the default behavior for GLFW (and I assume SDL too but I haven't checked). I need to get on fixing this for all platforms and re-aligning with modern GLFW/SDL.

Also, on Mac, you should likely always have HIGHDPI set since the screens are so high resolution. I believe (based on vibes I think?) that not setting the flag is really for outdated windowing systems such as X11 or Windows.

gfaster avatar May 31 '25 08:05 gfaster

@gfaster I tried setting HIGHDPI but now I have the opposite problem! The game size is correct at first, but when resizing the window the game gets shrunk to exactly quarter the size of the window.

Steps to reproduce:

  1. Buy a Mac and set up developer tools
$ git clone --recurse-submodules ssh://[email protected]/vegerot/snek.git
$ git switch --detach 1697cf603654745ecc6ea21bf25f6aa20d732254
$ git submodule update
$ zig build play
  1. Note that the game looks great. 2.5. Take a break and play the game for a bit. It's a lot of fun!

  2. Just slightly change the size of the window

  3. Note that the game is now a quarter of the size.

I'm assuming my bug must either be in https://github.com/vegerot/snek/blob/0d8d298bc79a2ab5de6a7a76be4482c6d0abd362/snek.zig#L684 or https://github.com/vegerot/snek/blob/0d8d298bc79a2ab5de6a7a76be4482c6d0abd362/snek.zig#L533 but I don't know what the bug is.

Also @gfaster you said

Fundamentally, you should be drawing things according to the window size and not the render size

Sorry, I don't know what that means. Are you saying I'm doing something more fundamentally wrong with how I calculate the options.gameSize?

vegerot avatar Jun 17 '25 18:06 vegerot

@gfaster I think this is a bug in Raylib. Can you confirm? The regression in my game is either from 4bed3741c1b7167f53bff6c806ba301d93db1b05 or 5c954c1f52cb04631c118f67b36b0b768a1f40b2

vegerot avatar Jul 08 '25 23:07 vegerot

@vegerot sorry I missed the email on this earlier. I had a look at your code and it seems correct at first glance, and testing it on my wayland machine seems to work correctly (at least window resizing). I'll borrow a Mac tonight and see if I can figure out what's happening differently.

https://github.com/user-attachments/assets/852487ab-5476-4779-861c-d37e0abcc93c

gfaster avatar Jul 10 '25 17:07 gfaster

@gfaster thanks! Btw I should have mentioned that the issue is only on macOS; our Windows and GNU+Wayland+Linux players haven't reported any issues.

Also, I reverted the raylib upgrade after getting the bug reports, so make sure to checkout https://github.com/vegerot/snek/commit/1697cf603654745ecc6ea21bf25f6aa20d732254 (and run git submodule update --init) before reproducing 🙂

vegerot avatar Jul 10 '25 18:07 vegerot

@gfaster I'm hoping someone can take a look at this. It turns out that downgrading Raylib actually causes another resizing bug on Windows. 😭

vegerot avatar Jul 25 '25 18:07 vegerot

@vegerot I've been trying to work on it using a family member's macbook in my free time -- It's coming along slowly since I'm totally unfamiliar with MacOS development but I hope to figure things out.

gfaster avatar Jul 25 '25 21:07 gfaster

@gfaster thank you 🙂

vegerot avatar Jul 25 '25 22:07 vegerot

As a temporary workaround you could try to run the program under Valve's gamescope. It exposes flags to force a certain resolution and scaling so you don't need to change your DE configuration.

P.S.: not sure why there is people debating Mac OS in this issue, gamescope is obviouslly linux only.

lucaslugao avatar Aug 08 '25 21:08 lucaslugao

Mac-specific bug discussion continued in #5185

vegerot avatar Sep 15 '25 23:09 vegerot

Unfortunately this issue was make-or-break for me - I couldn't figure out a fix on Hyprland/Wayland with >1x scaling.

If anyone knows of any workarounds or solutions ("use X11 backend" doesn't work for me because then transparency breaks on XWayland), please do let me know!

ThatOtherAndrew avatar Oct 12 '25 03:10 ThatOtherAndrew