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

Display Modes for New Renderers #1502

Open
colincornaby opened this issue Oct 12, 2023 · 7 comments
Open

Display Modes for New Renderers #1502

colincornaby opened this issue Oct 12, 2023 · 7 comments

Comments

@colincornaby
Copy link
Contributor

colincornaby commented Oct 12, 2023

I'm going to write this issue with a Mac slant - but I don't think this is a Mac specific issue. This is attempting to take #1244 and back it up into an issue so we can talk it through without going into the code.

Background

Direct3D 9 requires that full screen rendering be done in one of the display's supported modes. For Metal and OpenGL - there is no such requirement. Frames can be rendered in any resolution.

There are a few rough edges with the current approach:

  • Whenever Plasma is run on a new display that doesn't have the same display mode available - all graphics settings are reset. This means if you're using a laptop - but you plug into a desktop display with different display modes - Plasma will wipe all your graphics settings. That's annoying.
  • Plasma doesn't adjust properly when moving between a HiDPI and standard DPI display in windowed mode - because the required display mode has changed.
  • You can't resize a Plasma window on the fly. The window is locked to the current display mode.

For the Mac specifically:

  • Display modes on macOS are ambiguous on newer hardware. Since Apple started shipping displays that are not rectangular - Apple will advertise two sets of display modes. Some display modes represent the full area of the display, while other display modes represent the largest rectangle that will fit inside the display.
  • Full screen windows on macOS (using the modern full screen API) are restricted to rectangles - and cannot use any portion of the display that has a notch or curved corners. That means some of the advertised display modes will not actually be achievable by a full screen window.

Possible approach

#1244 proposes adding a render scale slider - like most modern games have. The render scale could be maintained between different displays. And because Metal and OpenGL don't actually have to follow the display modes on the current system - it's ok if the output resolution is completely made up by Plasma.

There are a few other features that could be added after a render scale:

  • 2D elements such as the cursor and the menus could always be rendered at the native resolution. This would eliminate the cursor changing it's physical size when the display mode is changed.
  • Plasma could dynamically adjust the display scale on the fly as the FPS increases or decreases. Most modern games implement this sort of feature on consoles. (Note: Because Plasma isn't really GPU constrained, this probably isn't necessary.)
    • An iPad or Vision Pro port might take this approach though.

What other games do

  • World of Warcraft on macOS only allows a render scale slider to be used on Macs with non square displays. It does not allow display mode changes.
  • No Man's Sky on Mac has both a render scale slider and a display mode selector. However - it offers (and defaults to) non rectangular display modes incorrectly even though it's render area is restricted to the rectangular area of a Mac display.
  • The Myst remaster and Firmament only offer a render scale slider and do not support display mode switching (at least on Mac.)
@Hoikas
Copy link
Member

Hoikas commented Oct 12, 2023

Direct3D 9 requires that full screen rendering be done in one of the display's supported modes

While this is strictly speaking true, H'uru no longer uses exclusive fullscreen in this way. Fullscreen gameplay is now accomplished by creating a borderless window and changing the resolution of the display. We are, at this point, using the list of D3D9 resolutions as a convenience.

@colincornaby
Copy link
Contributor Author

Direct3D 9 requires that full screen rendering be done in one of the display's supported modes

While this is strictly speaking true, H'uru no longer uses exclusive fullscreen in this way. Fullscreen gameplay is now accomplished by creating a borderless window and changing the resolution of the display. We are, at this point, using the list of D3D9 resolutions as a convenience.

Ahhh, thanks. I see that line in the DX renderer.

fSettings.fPresentParams.Windowed = TRUE;

I'll update the text of the issue.

@Hoikas
Copy link
Member

Hoikas commented Oct 15, 2023

Plasma doesn't adjust properly when moving between a HiDPI and standard DPI display in windowed mode - because the required display mode has changed.

I don't think this is true - #1269 was supposed to fix this with the DPI stuff.

@colincornaby
Copy link
Contributor Author

Plasma doesn't adjust properly when moving between a HiDPI and standard DPI display in windowed mode - because the required display mode has changed.

I don't think this is true - #1269 was supposed to fix this with the DPI stuff.

I'm not sure there has been standard behavior defined here. (I need to look at what Windows is doing.)

When a Window moves from a low DPI display to a HiDPI display, the framebuffer resolution is going to double. Games treat this as a new resolution. So either Plasma locks the resolution to exactly what is in the settings (in which case the window size gets halved as the window moves displays which is kind of weird.) Or the active resolution is doubled, which requires a write to options and may not match the available display modes on the display.

The other weird thing is that moving displays means the display modes should change. The new display has a different set of available modes. Plasma ignores this. But it means internally its rules about how to manage resolutions don't match up with what the window is doing. So technically the current display mode in windowed mode may not even be available on the other display.

This sort of weirdness is why it would be nice to decouple Plasma from the available display modes. The contract it's trying to make with the display modes is awkward to enforce.

@Hoikas
Copy link
Member

Hoikas commented Oct 15, 2023

While we don't write back to the options, when the DPI changes (eg moving to a display with a different DPI), we do reset the pipeline with the new display's information per 9c05355. If we're using a sufficiently recent version of Windows 10 (from either 2017 or 2018), then game window will remain the same size when swapping monitors.

@colincornaby
Copy link
Contributor Author

While we don't write back to the options, when the DPI changes (eg moving to a display with a different DPI), we do reset the pipeline with the new display's information per 9c05355. If we're using a sufficiently recent version of Windows 10 (from either 2017 or 2018), then game window will remain the same size when swapping monitors.

Lemme go connect my low DPI portable display to my Windows machine, but immediate thought on why this could be an issue:

Even in windowed mode - Plasma's output is supposed to match one of the display's available video modes. So maintaining the same window size isn't in alignment with that rule. If the new display doesn't have a display mode that matches the desired window size, things will get misaligned.

That said - I think there are several bugs that are also stacking here. I'm not sure Windows is querying anything but the main display for display modes (which is wrong, if my main display is a 4k display and my secondary display is a 1080p display, it's going to offer display modes my secondary display can't do.) I also don't think on Windows anything is being written back to options when the window moves displays, so Plasma may never realize things have become inconsistent. But that means the resolution won't be remembered the next run.

@colincornaby
Copy link
Contributor Author

colincornaby commented Oct 15, 2023

Ok - Checked out Windows. There are some issues - but there might be a reason the Mac is stumbling more than Windows is.

On macOS - I can move a full screen window to any display. So I can tell my Mac to move my Plasma window from a 4k display to a 1080p display - even if it's in full screen mode. I can also do it manually by un-fullscreening it, and then re-fullscreening it on the new display. But there are ways to move it even without leaving full screen.

This is not how Windows Plasma works. Windows Plasma will not let you go full screen on any display but the primary display. Windows also will only query display modes from the primary display. Even if I move the window to another display - I can't select the display modes from the new display. So if I move from a 4k display to a 1080p display in windowed mode - I still only see the 4k display modes.

So - macOS needs a way to move full screen from one display to another and have the display modes adjust correctly. I don't think Plasma is capable of that today.

I'll add that in general it seems like multiple displays in Windows is broken in Plasma. Weird things began to happen. I started the debug copy which defaults to windowed. But when I set a resolution of 800x600, hit apply, and then went full screen and hit apply - It resized my primary display's output resolution to 800x600. As in the display mode was changed and Windows was in 800x600. It also was drawing entirely on my main display, but I was also seeing half out the game output on my secondary display. My secondary display's output resolution was also resized to 800x600.

So - very much not convinced display modes are working properly under Windows right now. I don't think the current code will scale to macOS. I'm open to what approach we use exactly to scale to macOS - but the current code isn't working.

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

No branches or pull requests

2 participants