Some hints on HiDPI and scaling on monitors

This post is mainly aimed at the implementation of HiDPI scaling by Microsoft Windows. Unfortunately I have not had a chance to test the current implementation on MacOS.

I have been reading several posts about HiDPI, but they were not very helpful. I also see that SDL still doesn’t implement this functionality well.

I’m going to explain a little bit about the problem:

I have two screens:

  • 1080p scaled to 100%
  • 4K scaled to 150%

When I move an SDL window (with and without SDL_WINDOW_ALLOW_HIGHDPI) the window is resized from one monitor to another, normal behavior on all windows.

But according to SDL, the window is the same size on both monitors, something easy to check with programs like GreenShot. With this operation, it is impossible to make programs with perfect pixels because if you move the window to other monkeys, it can scale the content and you cannot do anything from the code.

In contrast, in GLFW there are two ways to create a window.

With glfwWindowHint (GLFW_SCALE_TO_MONITOR, 0), if I change the window from one monitor to another, the window does not vary in size.

But with glfwWindowHint (GLFW_SCALE_TO_MONITOR, 1), the window is resized as Windows deems necessary. But GLFW detects the resizing and gives you the correct pixel size for both the window and framebuffer.

Also, it has a function and a callback (either one can be used) glfwGetWindowContentScale that allows you to choose the scaling factor configured on that monitor.
The scaling factor for example is:

100% -> 1.0
150% -> 1,5
etc.

With that information I can scale the content my way. Also the position of the cursor is in pixels, not in a relative position according to the scaling.

How could it be implemented:

If SDL_WINDOW_ALLOW_HIGHDPI is not applied in the SDL window, then if you move from one window to another, let SDL scale the content and make the logic believe that a 400x400 window at 150% scaling is actually 350x350.

Instead, if SDL_WINDOW_ALLOW_HIGHDPI is applied, let Windows resize the window in its own way, but let SDL get the actual pixel size of the window, and thus 400x400 is the actual size it would get in logic in my program.

Also, add to events an event that manifests when you change the monitor and allows obtaining the scale factor of that monitor.

All of this can be applied to MacOS.

Finally, I think it is necessary to add to SDL the possibility of drawing filled triangles and polygons for both SDL_Surface and SDL_Renderer (of course, in SDL_Renderer that is hardware accelerated).

Although there are libraries like SDL_gfx, this works on a line and dot basis, something that does not have as much performance as a polygon directly on the GPU.

I am leaving this post because I have had to stop using SDL because I could not have the expected behavior in SDL. And although GLFW supplies everything very well, I don’t really like its callback event system and that it is necessary to use OpenGL obligatorily.

Here is GLFW’s documentation on scaling. window_scale

Thanks for your great work, and I hope this post is helpful. Sorry for my English, I needed help from Google Translator.

SDL doesn’t currently have any implementation of high DPI scaling support on Windows - anything you observe is done entirely by the OS without SDL’s knowledge.

It does have high DPI scaling implementations on macOS, iOS, and Wayland. There’s a bugzilla post which has a history of the current state of development of high DPI scaling on Windows, here: https://bugzilla.libsdl.org/show_bug.cgi?id=3281

1 Like