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

Creating fullscreen window with higher resolution than desktop broken #3313

Closed
SDLBugzilla opened this issue Feb 11, 2021 · 2 comments · Fixed by #4392
Closed

Creating fullscreen window with higher resolution than desktop broken #3313

SDLBugzilla opened this issue Feb 11, 2021 · 2 comments · Fixed by #4392

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: 2.0.10
Reported for operating system, platform: Windows (All), x86_64

Comments on the original bug report:

On 2019-06-30 02:35:45 +0000, Daniel Gibson wrote:

Created attachment 3849
simple testcase

Following scenario:
I'm running Windows (only tested Win10, but I assume it happens with other versions as well?).
I have a display with 1920x1200 native resolution.
I switch my desktop resolution to a lower resolution, like 1680x1050.
I do SDL_CreateWindow("Test Fullscreen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1920, 1200, SDL_WINDOW_FULLSCREEN);

Result: I get a fullscreen windows at 1680x1050
Expected Result: Getting a fullscreen window at the requested resolution (1920x1200) - or alternatively, SDL_CreateWindow() failing and returning NULL if it really thinks it can't use the requested resolution.

It does work the other way around (if display on desktop is running at native resolution and I request a lower one in SDL).
It also seems to work on Linux/X11 - I didn't test any other operating systems.

I attached a simple testcase that tests this and logs some messages about the requested and received resolution and the supported resolutions to testlog.txt
(yes, even in fullscreen mode the requested resolution that it didn't use is listed by SDL_GetDisplayMode())

This seems to happen at least with 2.0.9 and 2.0.10

I'm not very familiar with WinAPI or the SDL Win32 video code, so I didn't really try to debug it myself.
Also, I found it confusing that SDL_CreateWindow() sets window->w and window->h to the current display mode bounds, so the requested information is only stored in window->windowed.w/h which sound like they should only be for windowed mode - but apparently they aren't, otherwise setting any fullscreen resolution that is not the current desktop resolution should fail, on all platforms, and that is not the case.

On 2019-06-30 02:36:44 +0000, Daniel Gibson wrote:

Created attachment 3850
test log on my system

On 2019-06-30 03:10:24 +0000, Daniel Gibson wrote:

"This seems to happen at least with 2.0.9 and 2.0.10"
oh, just a clarification: I mean the 2.0.10 "Prerelease" as downloaded from https://www.libsdl.org/tmp/download-2.0.php on 2019-06-29

On 2019-07-02 23:23:48 +0000, Daniel Gibson wrote:

If you wonder why anyone would even run a game at a higher resolution than the desktop, apparently nvidia has a feature called "DSR" which is like super sampling and from the games point of view is just a higher resolution supported by the GPU driver/display. So even with a FullHD display one might render the game in 4k then - probably especially attractive for older games that otherwise don't stress the GPU very much.

Another weird thing I noticed when testing a bit more: If I, after creating the fullscreen window that gets the wrong resolution, call SDL_SetWindowDisplayMode() to set the higher resolution I wanted to have, the display flickers (appears to change mode) and according to SDL_GetWindowDisplayMode() the display then indeed has the desired mode, but SDL_GetWindowSize() still returns the old lower mode?!

On 2019-07-03 06:52:13 +0000, Cameron Gutman wrote:

I think this is working as intended.

From https://wiki.libsdl.org/SDL_CreateWindow

If the window is set fullscreen, the width and height parameters w and h will not be used.

You have to use SDL_SetWindowDisplayMode() to set the display mode. The window size that you're setting with SDL_GetWindowSize()/SDL_SetWindowSize() are the values that will be used if you ever exit full-screen using SDL_SetWindowFullscreen().

On 2019-07-03 21:06:34 +0000, Daniel Gibson wrote:

I think that sentence in the wiki is wrong, or maybe based on observation of the broken behavior. (It has been added on August 2015 by "ChrisBush", who AFAIK is no core SDL developer and thus probably not authoritative)

And it does set the fullscreen resolution - on Linux it works completely as I expect and on Windows it at least sets fullscreen resolutions that are <= the current desktop resolution.

To be honest, it not setting the fullscreen resolution for fullscreen windows would be horrible API design: If I can set SDL_WINDOW_FULLSCREEN there to immediately switch to fullscreen mode, then it should use the resolution I provide in the same call.

On 2019-07-30 17:49:38 +0000, Ryan C. Gordon wrote:

(Sorry if you get several emails like this, we're marking a bunch of bugs.)

We're hoping to ship SDL 2.0.11 on a much shorter timeframe than we have historically done releases, so I'm starting to tag bugs we hope to have closed in this release cycle.

Note that this tag means we just intend to scrutinize this bug for the 2.0.11 release: we may fix it, reject it, or even push it back to a later release for now, but this helps give us both a goal and a wishlist for the next release.

If this bug has been quiet for a few months and you have new information (such as, "this is definitely still broken" or "this got fixed at some point"), please feel free to retest and/or add more notes to the bug.

--ryan.

On 2019-09-20 20:47:39 +0000, Ryan C. Gordon wrote:

We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.

On 2019-09-20 20:48:41 +0000, Ryan C. Gordon wrote:

We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.

@DanielGibson
Copy link
Contributor

DanielGibson commented May 20, 2021

I have investigated this a bit (I'll eventually create a PR for at least those issues I can fix) and discovered even more issues:

  • The original problem: SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN doesn't work on Windows if resolution is higher than desktop resolution. I think the main problem here is that
    1. SDL_CreateWindow() doesn't set window->fullscreen.w/h but only window->w/h and window->windowed.w/h.
    2. Windows are always first created in windowed mode (and hidden!) and then switched to fullscreen (CREATE_FLAGS doesn't contain SDL_WINDOW_FULLSCREEN)
    • So if the windowed window is created with a lower resolution by Win32 or whatever, that lower resolution is used when SDL_CreateWindow() finally switches to fullscreen mode
      • I wonder if SDL_CreateWindow() should always fail and return NULL if it can't create the window at the requested resolution (except maybe when using SDL_WINDOW_FULLSCREEN_DESKTOP), instead of silently returning a window at a different resolution
  • SDL_SetWindowDisplayMode() on a fullscreen window switches the display resolution, but doesn't set window->w and window->h.
    • (probably as a result of that) SDL_SetWindowDisplayMode() doesn't change the size of the window surface (from SDL_GetWindowSurface()) either I think the OpenGL drawable area isn't adjusted either
    • so one has to call SDL_SetWindowSize() afterwards to get a working state (or possibly switch to windowed mode and back to fullscreen?)

Does anyone know if this behavior of SDL_SetWindowDisplayMode() on a window that's already in fullscreen is expected?

DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
.. and maybe other platforms as well (though X11 was not affected)?

The issue was that passing a higher resolution than the current desktop
resolution to SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN didn't switch
to that resolution (even though it did switch to lower resolutions).

When creating a fullscreen window, window->fullscreen wasn't even set
at all (only zeroed out), setting it only happened if the user explicitly
called SDL_SetWindowDisplayMode(). So without that, SDL_CreateWindow()
-> SDL_UpdateFullscreenMode() -> SDL_GetWindowDisplayMode() used the
resolution from window->windowed.w/h which were limited to the desktop size
due to some weird combination of WIN_AdjustWindowRectWithStyle() and
WIN_WindowProc() being called after a call to SetWindowPos().

fixes libsdl-org#3313
DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
Otherwise only the display resolution is changed, but the SDL window size
(and for example the window-surface size) aren't adjusted accordingly
and thus don't fill the whole screen.
See libsdl-org#3313
@DanielGibson
Copy link
Contributor

#4392 has fixes for the aforementioned issues.

DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
.. and maybe other platforms as well (though X11 was not affected)?

The issue was that passing a higher resolution than the current desktop
resolution to SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN didn't switch
to that resolution (even though it did switch to lower resolutions).

When creating a fullscreen window, window->fullscreen wasn't even set
at all (only zeroed out), setting it only happened if the user explicitly
called SDL_SetWindowDisplayMode(). So without that, SDL_CreateWindow()
-> SDL_UpdateFullscreenMode() -> SDL_GetWindowDisplayMode() used the
resolution from window->windowed.w/h which were limited to the desktop size
due to some weird combination of WIN_AdjustWindowRectWithStyle() and
WIN_WindowProc() being called after a call to SetWindowPos().

fixes libsdl-org#3313
DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
Otherwise only the display resolution is changed, but the SDL window size
(and for example the window-surface size) aren't adjusted accordingly
and thus don't fill the whole screen.
See libsdl-org#3313
DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
.. and maybe other platforms as well (though X11 was not affected)?

The issue was that passing a higher resolution than the current desktop
resolution to SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN didn't switch
to that resolution (even though it did switch to lower resolutions).

When creating a fullscreen window, window->fullscreen wasn't even set
at all (only zeroed out), setting it only happened if the user explicitly
called SDL_SetWindowDisplayMode(). So without that, SDL_CreateWindow()
-> SDL_UpdateFullscreenMode() -> SDL_GetWindowDisplayMode() used the
resolution from window->windowed.w/h which were limited to the desktop size
due to some weird combination of WIN_AdjustWindowRectWithStyle() and
WIN_WindowProc() being called after a call to SetWindowPos().

fixes libsdl-org#3313
DanielGibson added a commit to DanielGibson/SDL that referenced this issue May 21, 2021
Otherwise only the display resolution is changed, but the SDL window size
(and for example the window-surface size) aren't adjusted accordingly
and thus don't fill the whole screen.
See libsdl-org#3313
slouken pushed a commit that referenced this issue Aug 4, 2021
.. and maybe other platforms as well (though X11 was not affected)?

The issue was that passing a higher resolution than the current desktop
resolution to SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN didn't switch
to that resolution (even though it did switch to lower resolutions).

When creating a fullscreen window, window->fullscreen wasn't even set
at all (only zeroed out), setting it only happened if the user explicitly
called SDL_SetWindowDisplayMode(). So without that, SDL_CreateWindow()
-> SDL_UpdateFullscreenMode() -> SDL_GetWindowDisplayMode() used the
resolution from window->windowed.w/h which were limited to the desktop size
due to some weird combination of WIN_AdjustWindowRectWithStyle() and
WIN_WindowProc() being called after a call to SetWindowPos().

fixes #3313
slouken pushed a commit that referenced this issue Aug 4, 2021
Otherwise only the display resolution is changed, but the SDL window size
(and for example the window-surface size) aren't adjusted accordingly
and thus don't fill the whole screen.
See #3313
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants