[PATCH] sdl2: fix HighDPI display scaling

Oliver Clarke posted 1 patch 1 month, 4 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260730230449.963-1-oliverhenryc@gmail.com
Maintainers: "Marc-André Lureau" <marcandre.lureau@redhat.com>
ui/sdl2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] sdl2: fix HighDPI display scaling
Posted by Oliver Clarke 1 month, 4 weeks ago
This makes sdl2 windows work well with dpi scaling. It fixes the issue of the display surface being stretched to fit the dpi corrected window (which created a blurry result).

Note, this does not do any scaling, it just tells the os to not scale the window. Before, when the console requested size 640x480, the logical size of the window was 640x480, and the physical size was scaled by the dpi scaling. Now, both the logical and physical size will be 640x480. This is unlike most dpi aware programs which usually do have the scaled physical size, then also make the render target that scaled size as well. This doesn't make as much sense for QEMU, since the guest is responsible for modesetting, and they should get the exact physical pixels they request (if i modeset to 3840x2160, I wouldn't want this to be scaled in any way).

Signed-off-by: Oliver Clarke <oliverhenryc@gmail.com>
---
 ui/sdl2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 1c97d23a47..1910477db4 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -102,7 +102,7 @@ void sdl2_window_create(struct sdl2_console *scon)
         flags |= SDL_WINDOW_OPENGL;
     }
 #endif
-
+    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
     scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
                                          SDL_WINDOWPOS_UNDEFINED,
                                          surface_width(scon->surface),
@@ -907,6 +907,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
     char *dir;
 
     assert(o->type == DISPLAY_TYPE_SDL);
+    SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
 
     if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
         SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
-- 
2.51.0.windows.1
Re: [PATCH] sdl2: fix HighDPI display scaling
Posted by BALATON Zoltan 1 month, 4 weeks ago
On Thu, 30 Jul 2026, Oliver Clarke wrote:
> This makes sdl2 windows work well with dpi scaling. It fixes the issue 
> of the display surface being stretched to fit the dpi corrected window 
> (which created a blurry result).
>
> Note, this does not do any scaling, it just tells the os to not scale 
> the window. Before, when the console requested size 640x480, the logical 
> size of the window was 640x480, and the physical size was scaled by the 
> dpi scaling. Now, both the logical and physical size will be 640x480. 
> This is unlike most dpi aware programs which usually do have the scaled 
> physical size, then also make the render target that scaled size as 
> well. This doesn't make as much sense for QEMU, since the guest is 
> responsible for modesetting, and they should get the exact physical 
> pixels they request (if i modeset to 3840x2160, I wouldn't want this to 
> be scaled in any way).

Despite the patch is just two lines maybe it's not a trivial change. Does 
this mean that on hiDPI displays now a 640x480 guest screen (like BIOS or 
legacy guest) shows a tiny unusable window? In that case maybe this needs 
to be switchable with a property or turn off scaling of 4k and higher 
resolutions but then we get to the issue that other ui backends should do 
the same so just changing one backend may lead to inconsistency. Did you 
check how is this handled in other ui backends?

Regards,
BALATON Zoltan

> Signed-off-by: Oliver Clarke <oliverhenryc@gmail.com>
> ---
> ui/sdl2.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/ui/sdl2.c b/ui/sdl2.c
> index 1c97d23a47..1910477db4 100644
> --- a/ui/sdl2.c
> +++ b/ui/sdl2.c
> @@ -102,7 +102,7 @@ void sdl2_window_create(struct sdl2_console *scon)
>         flags |= SDL_WINDOW_OPENGL;
>     }
> #endif
> -
> +    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
>     scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
>                                          SDL_WINDOWPOS_UNDEFINED,
>                                          surface_width(scon->surface),
> @@ -907,6 +907,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
>     char *dir;
>
>     assert(o->type == DISPLAY_TYPE_SDL);
> +    SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
>
>     if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
>         SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
>
Re: [PATCH] sdl2: fix HighDPI display scaling
Posted by Oliver C 1 month, 4 weeks ago
> Does this mean that on hiDPI displays now a 640x480 guest screen
> (like BIOS or legacy guest) shows a tiny unusable window?

This is correct, but:

> ...the issue that other ui backends should do the same so just changing
> one backend may lead to inconsistency.

the gtk backend exhibits the same behavior as the sdl backend with my changes,
i.e. it creates a 640x480 guest screen in physical pixels (my machine has a
4k monitor with 150% scaling), just like the new changes. So these changes
in fact make it more consistent. Although, I just noticed that gtk has
a 'scale' option,
which scales the window size, and stretches the surface to it. I
suppose this can
be added to sdl. I think it would also be a good idea to enable linear filtering
when stretching the surface, so it doesn't look as blurry.

> Despite the patch is just two lines maybe it's not a trivial change.

Gotcha, sorry this is my first time sending a patch through mailing
list, so thanks for bearing with me.

Oliver

On Fri, Jul 31, 2026 at 7:05 AM BALATON Zoltan <balaton@eik.bme.hu> wrote:
>
> On Thu, 30 Jul 2026, Oliver Clarke wrote:
> > This makes sdl2 windows work well with dpi scaling. It fixes the issue
> > of the display surface being stretched to fit the dpi corrected window
> > (which created a blurry result).
> >
> > Note, this does not do any scaling, it just tells the os to not scale
> > the window. Before, when the console requested size 640x480, the logical
> > size of the window was 640x480, and the physical size was scaled by the
> > dpi scaling. Now, both the logical and physical size will be 640x480.
> > This is unlike most dpi aware programs which usually do have the scaled
> > physical size, then also make the render target that scaled size as
> > well. This doesn't make as much sense for QEMU, since the guest is
> > responsible for modesetting, and they should get the exact physical
> > pixels they request (if i modeset to 3840x2160, I wouldn't want this to
> > be scaled in any way).
>
> Despite the patch is just two lines maybe it's not a trivial change. Does
> this mean that on hiDPI displays now a 640x480 guest screen (like BIOS or
> legacy guest) shows a tiny unusable window? In that case maybe this needs
> to be switchable with a property or turn off scaling of 4k and higher
> resolutions but then we get to the issue that other ui backends should do
> the same so just changing one backend may lead to inconsistency. Did you
> check how is this handled in other ui backends?
>
> Regards,
> BALATON Zoltan
>
> > Signed-off-by: Oliver Clarke <oliverhenryc@gmail.com>
> > ---
> > ui/sdl2.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/ui/sdl2.c b/ui/sdl2.c
> > index 1c97d23a47..1910477db4 100644
> > --- a/ui/sdl2.c
> > +++ b/ui/sdl2.c
> > @@ -102,7 +102,7 @@ void sdl2_window_create(struct sdl2_console *scon)
> >         flags |= SDL_WINDOW_OPENGL;
> >     }
> > #endif
> > -
> > +    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
> >     scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
> >                                          SDL_WINDOWPOS_UNDEFINED,
> >                                          surface_width(scon->surface),
> > @@ -907,6 +907,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
> >     char *dir;
> >
> >     assert(o->type == DISPLAY_TYPE_SDL);
> > +    SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
> >
> >     if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
> >         SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
> >
Re: [PATCH] sdl2: fix HighDPI display scaling
Posted by Oliver C 1 month, 4 weeks ago
I added a scale option for sdl that works the same as gtk.
I said linear filtering in my last response, but I meant point
filtering. I played around with point filtering,
but it looks pretty bad with non-integer scaling (e.g. 150% scaling to
match my setup). It does however
look quite nice with an integer scale, so maybe this could be
configurable as well?

What's the process for amending a patch? Do I reply with the
additional patches, reply with the whole patch, or create a new
thread?

Thanks,
Oliver

On Fri, Jul 31, 2026 at 1:32 PM Oliver C <oliverhenryc@gmail.com> wrote:
>
> > Does this mean that on hiDPI displays now a 640x480 guest screen
> > (like BIOS or legacy guest) shows a tiny unusable window?
>
> This is correct, but:
>
> > ...the issue that other ui backends should do the same so just changing
> > one backend may lead to inconsistency.
>
> the gtk backend exhibits the same behavior as the sdl backend with my changes,
> i.e. it creates a 640x480 guest screen in physical pixels (my machine has a
> 4k monitor with 150% scaling), just like the new changes. So these changes
> in fact make it more consistent. Although, I just noticed that gtk has
> a 'scale' option,
> which scales the window size, and stretches the surface to it. I
> suppose this can
> be added to sdl. I think it would also be a good idea to enable linear filtering
> when stretching the surface, so it doesn't look as blurry.
>
> > Despite the patch is just two lines maybe it's not a trivial change.
>
> Gotcha, sorry this is my first time sending a patch through mailing
> list, so thanks for bearing with me.
>
> Oliver
>
> On Fri, Jul 31, 2026 at 7:05 AM BALATON Zoltan <balaton@eik.bme.hu> wrote:
> >
> > On Thu, 30 Jul 2026, Oliver Clarke wrote:
> > > This makes sdl2 windows work well with dpi scaling. It fixes the issue
> > > of the display surface being stretched to fit the dpi corrected window
> > > (which created a blurry result).
> > >
> > > Note, this does not do any scaling, it just tells the os to not scale
> > > the window. Before, when the console requested size 640x480, the logical
> > > size of the window was 640x480, and the physical size was scaled by the
> > > dpi scaling. Now, both the logical and physical size will be 640x480.
> > > This is unlike most dpi aware programs which usually do have the scaled
> > > physical size, then also make the render target that scaled size as
> > > well. This doesn't make as much sense for QEMU, since the guest is
> > > responsible for modesetting, and they should get the exact physical
> > > pixels they request (if i modeset to 3840x2160, I wouldn't want this to
> > > be scaled in any way).
> >
> > Despite the patch is just two lines maybe it's not a trivial change. Does
> > this mean that on hiDPI displays now a 640x480 guest screen (like BIOS or
> > legacy guest) shows a tiny unusable window? In that case maybe this needs
> > to be switchable with a property or turn off scaling of 4k and higher
> > resolutions but then we get to the issue that other ui backends should do
> > the same so just changing one backend may lead to inconsistency. Did you
> > check how is this handled in other ui backends?
> >
> > Regards,
> > BALATON Zoltan
> >
> > > Signed-off-by: Oliver Clarke <oliverhenryc@gmail.com>
> > > ---
> > > ui/sdl2.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/ui/sdl2.c b/ui/sdl2.c
> > > index 1c97d23a47..1910477db4 100644
> > > --- a/ui/sdl2.c
> > > +++ b/ui/sdl2.c
> > > @@ -102,7 +102,7 @@ void sdl2_window_create(struct sdl2_console *scon)
> > >         flags |= SDL_WINDOW_OPENGL;
> > >     }
> > > #endif
> > > -
> > > +    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
> > >     scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
> > >                                          SDL_WINDOWPOS_UNDEFINED,
> > >                                          surface_width(scon->surface),
> > > @@ -907,6 +907,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
> > >     char *dir;
> > >
> > >     assert(o->type == DISPLAY_TYPE_SDL);
> > > +    SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
> > >
> > >     if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
> > >         SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
> > >
Re: [PATCH] sdl2: fix HighDPI display scaling
Posted by BALATON Zoltan 1 month, 4 weeks ago
On Fri, 31 Jul 2026, Oliver C wrote:
> I added a scale option for sdl that works the same as gtk.
> I said linear filtering in my last response, but I meant point
> filtering. I played around with point filtering,
> but it looks pretty bad with non-integer scaling (e.g. 150% scaling to
> match my setup). It does however
> look quite nice with an integer scale, so maybe this could be
> configurable as well?

I don't know what other ui backends do but if this makes it more 
consistent with at least gtk it sounds good and a scale options is useful 
in itself even without hiDPI. The ui maintainers should do a final review 
though.

> What's the process for amending a patch? Do I reply with the
> additional patches, reply with the whole patch, or create a new
> thread?

You should post a new thread if you revise a patch with v2 for the first 
revision after initial submission without version and increasing for later 
revisions but adding a scale option should be in a different patch so this 
makes it a series with two patches. Series should be submitted as replies 
to a cover letter with new thread for v2 and so on for revised series as 
well. This should be explained in 
https://www.qemu.org/docs/master/devel/submitting-a-patch.html

Thanks for improving QEMU.

Regards,
BALATON Zoltan

> Thanks,
> Oliver
>
> On Fri, Jul 31, 2026 at 1:32 PM Oliver C <oliverhenryc@gmail.com> wrote:
>>
>>> Does this mean that on hiDPI displays now a 640x480 guest screen
>>> (like BIOS or legacy guest) shows a tiny unusable window?
>>
>> This is correct, but:
>>
>>> ...the issue that other ui backends should do the same so just changing
>>> one backend may lead to inconsistency.
>>
>> the gtk backend exhibits the same behavior as the sdl backend with my changes,
>> i.e. it creates a 640x480 guest screen in physical pixels (my machine has a
>> 4k monitor with 150% scaling), just like the new changes. So these changes
>> in fact make it more consistent. Although, I just noticed that gtk has
>> a 'scale' option,
>> which scales the window size, and stretches the surface to it. I
>> suppose this can
>> be added to sdl. I think it would also be a good idea to enable linear filtering
>> when stretching the surface, so it doesn't look as blurry.
>>
>>> Despite the patch is just two lines maybe it's not a trivial change.
>>
>> Gotcha, sorry this is my first time sending a patch through mailing
>> list, so thanks for bearing with me.
>>
>> Oliver
>>
>> On Fri, Jul 31, 2026 at 7:05 AM BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>>
>>> On Thu, 30 Jul 2026, Oliver Clarke wrote:
>>>> This makes sdl2 windows work well with dpi scaling. It fixes the issue
>>>> of the display surface being stretched to fit the dpi corrected window
>>>> (which created a blurry result).
>>>>
>>>> Note, this does not do any scaling, it just tells the os to not scale
>>>> the window. Before, when the console requested size 640x480, the logical
>>>> size of the window was 640x480, and the physical size was scaled by the
>>>> dpi scaling. Now, both the logical and physical size will be 640x480.
>>>> This is unlike most dpi aware programs which usually do have the scaled
>>>> physical size, then also make the render target that scaled size as
>>>> well. This doesn't make as much sense for QEMU, since the guest is
>>>> responsible for modesetting, and they should get the exact physical
>>>> pixels they request (if i modeset to 3840x2160, I wouldn't want this to
>>>> be scaled in any way).
>>>
>>> Despite the patch is just two lines maybe it's not a trivial change. Does
>>> this mean that on hiDPI displays now a 640x480 guest screen (like BIOS or
>>> legacy guest) shows a tiny unusable window? In that case maybe this needs
>>> to be switchable with a property or turn off scaling of 4k and higher
>>> resolutions but then we get to the issue that other ui backends should do
>>> the same so just changing one backend may lead to inconsistency. Did you
>>> check how is this handled in other ui backends?
>>>
>>> Regards,
>>> BALATON Zoltan
>>>
>>>> Signed-off-by: Oliver Clarke <oliverhenryc@gmail.com>
>>>> ---
>>>> ui/sdl2.c | 3 ++-
>>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/ui/sdl2.c b/ui/sdl2.c
>>>> index 1c97d23a47..1910477db4 100644
>>>> --- a/ui/sdl2.c
>>>> +++ b/ui/sdl2.c
>>>> @@ -102,7 +102,7 @@ void sdl2_window_create(struct sdl2_console *scon)
>>>>         flags |= SDL_WINDOW_OPENGL;
>>>>     }
>>>> #endif
>>>> -
>>>> +    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
>>>>     scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
>>>>                                          SDL_WINDOWPOS_UNDEFINED,
>>>>                                          surface_width(scon->surface),
>>>> @@ -907,6 +907,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
>>>>     char *dir;
>>>>
>>>>     assert(o->type == DISPLAY_TYPE_SDL);
>>>> +    SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");
>>>>
>>>>     if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
>>>>         SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
>>>>
>
>