libsdl-org/sdl2-compat

Should SDL_RenderSetLogicalSize use Nearest scaling?

icculus opened this issue · 4 comments

So I have a text editor that I've been using for, oh, almost 30 years, which I ported to SDL2 at some point, so it would work wherever I might work. :)

At the moment, on X11, it deals with HighDPI by creating a window at double the usual size and using SDL_RenderSetLogicalSize to let the app pretend it's running at the smaller dimensions, but SDL2 is scaling it up so the text is readable on a 4K display.

With sdl2-compat, this is what it looks like:

image

It's kind of blurry!

This is happening because SDL3 uses a render target for logical scaling, whereas SDL2 just rendered directly to the framebuffer, managing scaling itself.

Fortunately we can tell SDL3 to render the logical render target to the window framebuffer using Nearest scaling instead of Linear, and then this looks sharp again:

image

...which is this line in sdl2-compat:

return SDL3_SetRenderLogicalPresentation(renderer, w, h, SDL_LOGICAL_PRESENTATION_LETTERBOX, SDL_SCALEMODE_LINEAR);

This is not life and death for me: I'll eventually move the text editor to SDL3, and SDL2 works just fine for now in any case, but I guess the question here is: should sdl2-compat be forcing this to SDL_SCALEMODE_NEAREST instead of Linear? I haven't really thought through the ramifications of this; it's possible this fixes text but is ruinous for actual graphics.

(It's also possible we need a hint/quirk to force one or the other on a per-app basis.)

This is tough, because SDL2 uses a combination of nearest for lines and points, and linear for textures, which we can't replicate in the new model.

Fwiw, SDL2 defaults to nearest for textures, too, but can be overridden with a hint:

https://github.com/libsdl-org/SDL/blob/82cd3bfe1ccf83ade85847460d76b370b94ada53/src/render/SDL_render.c#L1229-L1232

So maybe we should default to nearest for the logical framebuffer, too? Both defaults feel like they could be wrong. :/

I think we probably need a hint for this in sdl2-compat, because some apps (and some users!) are going to have different opinions about blurry vs blocky scaling in different situations.

I guess we need to look at a couple of games in both forms and see which looks better as a default. I'm not sure I could predict.

We should probably add some SDL2 tests to verify renderer behavior and then check them in SDL3. At least we'll have a known starting point.

I'm also struggling what to do with the OpenGL ES renderer. It doesn't support target textures, but they're a required feature in SDL 3.0. I've played with a bunch of ideas, including just copying the SDL2 renderer wholesale into sdl2-compat, but I haven't landed on anything great yet.