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

[Windows] Remove visible WINDOW_MODE_FULLSCREEN border by setting window region. #88852

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bruvzg
Copy link
Member

@bruvzg bruvzg commented Feb 26, 2024

An attempt to solve #63500 and preserve multi-window functionality.

In non-exclusive full-screen mode (or borderless maximized, which is the same thing), the window client area is set to be 2 pixels wider than a screen, renderer context size is set to screen size, and extra pixels are cut by setting window region.

  • Test on NVIDIA GPU.
  • Test on AMD GPU.
  • Test on Intel GPU.
  • Test for potential performance changes in WINDOW_MODE_FULLSCREEN.

test_project.zip

Expected test project behavior:

  • Red border IS NOT visible in all modes (clean color).
  • Green border IS fully visible on all window sides and in all modes (draw in the usable window area from the code).
  • Option box is functional in all modes except WINDOW_MODE_EXCLUSIVE_FULLSCREEN.

@Kiisu-Master
Copy link
Contributor

Kiisu-Master commented Feb 26, 2024

It breaks the application when fullscreen is set in project settings.
It first shows black screen, then application window disappears and trying to open it from alt+tab or taskbar doesn't work anymore. It shows an empty preview.

Setting fullscreen at runtime works well!

GPU is AMD Radeon R7

Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great. It fixes current fullscreen problems, but I didn't test extensively for new ones (didn't notice any from brief testing though).

@alvinhochun
Copy link
Contributor

Hmm, I haven't tested it yet but honestly I am a bit wary of SetWindowRgn. I am not sure how it interacts with DWM and it just feels like a dated technology. Perhaps actual testing will prove me wrong?

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on Windows 11 23H2 + NVIDIA 560.94 (rebased on top of master 44fa552), it works as expected (single-monitor setup).

This fixes the issue where integer scaling did not work correctly in non-exclusive fullscreen, using a lower scale factor than could be possible instead:

image

Now, it looks like this regardless of whether fullscreen or exclusive fullscreen is used:

image

  • Option box is functional in all modes except WINDOW_MODE_EXCLUSIVE_FULLSCREEN.

However, this is not the case: I can still use the dropdown when in exclusive fullscreen (with either 4.3.stable or this PR). This may be a NVIDIA-specific thing.

Latency test and some quirks I found

Note

This also applies to master, and has only been tested in D3D12 so far since it's the only rendering driver where I can get Special K working with Godot. Feel free to give this a try with Vulkan or OpenGL on your end if you can 🙂

Regarding input lag, when using fullscreen mode, D3D12 is unable to use independent flip, which is how low latency can be achieved. Here's the best you can do with traditional flip, assuming a FPS cap that is just below VRR range:

image

Only exclusive fullscreen can achieve independent flip:

image

I'm not sure if it's technically feasible for fullscreen to achieve independent flip, or not without the driver automatically turning fullscreen into exclusive fullscreen (which would break dropdowns... at least in theory). I wonder if anything here is related to MPO support? I'm using a recent GPU on a single-monitor display and on Windows 11, which is a best-case scenario here. Hardware-accelerated GPU scheduling is also enabled.

Edit: This is 100% related to MPO support. My display has interesting behavior where MPO is only available if HDR is enabled in the system settings. It will affect the game that is being run even if the game isn't restarted in between toggling HDR.

This is what I see with HDR disabled on the TV (LG C2 42"):

image

Once I enable HDR, I get MPO support:

image

When MPO is used, a presentation mode called Hardware Composed is used:

image

This presentation mode breaks dropdowns under any window mode, on both master and this PR! This occurs even in windowed mode, since MPO makes it possible to achieve low latency even in windowed mode with other windows visible on the screen. However, other windows can't appear on top of it, which breaks the dropdowns. This does not happen with Vulkan, presumably because it can't make use of MPO support (which is one of the reasons it generally suffers from higher input lag compared to D3D12).

Special K's readout is pretty accurate: there's significantly less latency when moving the mouse over the dropdown quickly (visual feedback appears much sooner with independent flip) when V-Synced at 120 Hz on a VRR display (with a FPS cap of 115). This difference of 12 ms is roughly 1.5 frames at 120 Hz.

Therefore, regardless, we should keep recommending exclusive fullscreen for games. The difference will be even more noticeable on displays with a lower refresh rate, as the latency penalty of traditional flip is measured in frames rather than milliseconds.

That said, for the purpose of improving the non-exclusive fullscreen experience, this PR still helps. The latency penalty is still there though: non-exclusive fullscreen is still not ideal for games, so it should be documented clearly. I've seen a lot of Godot games shipping with non-exclusive fullscreen (with no option to choose exclusive fullscreen) recently, so we should probably make it print a warning that can be disabled in the project settings.

@Thought-Weaver
Copy link

Hey all! Just bumping this PR and wondering what testing still remains before it can be merged. Is there anything I can help with? Seems like this would be a great benefit to folks trying to create a non-exclusive fullscreen setup that doesn't impact scaling.

@KoBeWi
Copy link
Member

KoBeWi commented Dec 22, 2024

It seems to be missing some testing. See the checkboxes in the OP.

@Thought-Weaver
Copy link

Thought-Weaver commented Dec 22, 2024

Gotcha! Wasn't sure if the checklist had actually been updated, since it looks like @Calinou gathered some perf metrics. Is there a more exhaustive set of metrics to validate?

In the meantime, I did some testing on an Intel GPU (Intel Iris Xe Graphics) on Windows 11. Note: I did merge with latest main before testing; given the recent embedded game window changes also touched this file, there may be additional adjustments to make. Going down the expected test project behavior:

  • Red border was indeed never visible, though the red clear color in the background was visible when resizing (I believe that's expected)
  • Green border was visible most of the time, but I've attached a video where switching into borderless seems to cause the window to resize incorrectly and cut off the green border (see video)
  • I can switch values in the option box on exclusive fullscreen -- and in fact the window flashes whenever I do

Hopefully the video below is helpful. I'll continue to test, peruse the changes, and update folks if I find anything else!

2024-12-22.14-47-16.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants