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

vo_gpu: d3d11: add support for exclusive fullscreen #6329

Merged
merged 2 commits into from Apr 12, 2020

Conversation

jeeb
Copy link
Member

@jeeb jeeb commented Nov 18, 2018

Picked up from @rossy's box o' nifty features.

Lets the application fully control the rendering onto the screen
instead of the compositor.

Test build here.

@jeeb jeeb force-pushed the exclusive_fs branch 4 times, most recently from dfd79b3 to f071e57 Compare November 18, 2018 20:18
@jeeb jeeb changed the title vo_gpu: d3d11: add support for exclusive fullscreen WIP: vo_gpu: d3d11: add support for exclusive fullscreen Nov 18, 2018
@jeeb
Copy link
Member Author

jeeb commented Nov 18, 2018

It seems to work, but the code still requires some stabs as f.ex. the fullscreen→!fullscreen transition happens without calling that function at all.

@jeeb jeeb force-pushed the exclusive_fs branch 3 times, most recently from 0d9a2ac to a9c8b73 Compare November 18, 2018 21:24
@jeeb
Copy link
Member Author

jeeb commented Nov 18, 2018

OK, now things mostly work if we leave out the capability of switching (within full-screen mode) between exclusive and non-exclusive. Also the logging could be lessened by querying the exclusive full-screen mode in the setting function, but I decided to not do that for now.

The main thing that I'd like to get done before pushing this upstream is to make --fullscreen work :) (as in, starting the player in full screen mode). Adding the mode init into the d3d11 init function kind of has it happen, but then right after that the window gets scaled/sized.

@jeeb
Copy link
Member Author

jeeb commented Nov 18, 2018

Alright, initial --fullscreen now works :) . Not sure if I have to listen to VOCTRL_FULLSCREEN any more.

@jeeb jeeb changed the title WIP: vo_gpu: d3d11: add support for exclusive fullscreen vo_gpu: d3d11: add support for exclusive fullscreen Nov 18, 2018
@jeeb
Copy link
Member Author

jeeb commented Nov 19, 2018

grep "VOCTR" $(git grep --files-with-matches  "ra_ctx_fns")
video/out/d3d11/context.c:    if (request == VOCTRL_FULLSCREEN ||
video/out/opengl/context_drm_egl.c:    case VOCTRL_GET_DISPLAY_FPS: {
video/out/opengl/context_rpi.c:    case VOCTRL_SCREENSHOT_WIN:
video/out/opengl/context_rpi.c:    case VOCTRL_FULLSCREEN:
video/out/opengl/context_rpi.c:    case VOCTRL_CHECK_EVENTS:
video/out/opengl/context_rpi.c:    case VOCTRL_GET_DISPLAY_FPS:

These are the similar files that poke VOCTRL_ in my branch... and only context_rpi seems to be using the fullscreen thing (but it also grabs check events and does the full reconfig then as well).

┐(´д`)┌ I think I will remove the VOCTRL now since the first commit should always send an event to us in case fullscreen state gets switched.

edit
Also I am not 100% sure if my location for the signal_events is correct, or if it should be after update_window_state.

@jeeb
Copy link
Member Author

jeeb commented Nov 19, 2018

Alright, only listening to the event given out by the w32 common code now, and it still works just as well. Noticed that going out of full screen has some weirdness in there compared to non-exclusive mode, probably there's some funkiness happening.

Not a major bugbear though...

@jeeb
Copy link
Member Author

jeeb commented Nov 19, 2018

--msg-level=vo=v gives me the following tidbit:

[vo/gpu/win32] save window bounds: 960:510:1920:1080
[vo/gpu/win32] reset window bounds: 0:0:3840:2160
[vo/gpu/win32] resize window: 3840:2160
[vo/gpu/d3d11] Enabling full-screen exclusive mode while entering fullscreen

...

[vo/gpu/win32] restore window bounds: 960:510:1920:1080
[vo/gpu/win32] reset window bounds: 960:510:1920:1080
[vo/gpu/win32] resize window: 1920:1080
[vo/gpu/d3d11] Disabling full-screen exclusive mode while leaving fullscreen
[vo/gpu/win32] DPI detected from the new API: 144
[vo/gpu/win32] resize window: 3818:2104

Sudden DPI resize?

@jeeb
Copy link
Member Author

jeeb commented Nov 20, 2018

Nah, that was just generic logging as far as I can tell. Just the previous width/height coming up due to an additional resize event.

Non-exclusive osc init to osc init

[   0.612][d][osc] osc_init 
[   1.854][d][cplayer] Run command: cycle, flags=9, args=[fullscreen, (NULL)]
[   1.860][v][vo/gpu] Resize: 3840x2160
[   1.862][v][vo/gpu] Window size: 3840x2160
[   1.863][v][vo/gpu] Video source: 1920x1080 (1:1)
[   1.865][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (0, 0) 3840x2160
[   1.866][v][vo/gpu] Video scale: 2.000000/2.000000
[   1.867][v][vo/gpu] OSD borders: l=0 t=0 r=0 b=0
[   1.876][v][vo/gpu] Video borders: l=0 t=0 r=0 b=0
[   1.877][v][vo/gpu] Reported display depth: 8
[   1.879][v][vo/gpu/win32] restore window bounds: 960:510:1920:1080
[   1.881][v][vo/gpu/win32] reset window bounds: 960:510:1920:1080
[   1.923][d][vo/gpu/win32] move window: 960:510
[   1.924][v][vo/gpu/win32] resize window: 1920:1080
[   1.939][i][vo/gpu/d3d11] D3D11 Control: fullscreen state: yup, resize: yup, width=1920, height=1080
[   1.940][v][vo/gpu/d3d11] Disabling full-screen exclusive mode while leaving fullscreen
[   1.946][v][vo/gpu] Resize: 1920x1080
[   1.946][v][vo/gpu] Window size: 1920x1080
[   1.947][v][vo/gpu] Video source: 1920x1080 (1:1)
[   1.947][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (0, 0) 1920x1080
[   1.950][v][vo/gpu] Video scale: 1.000000/1.000000
[   1.951][v][vo/gpu] OSD borders: l=0 t=0 r=0 b=0
[   1.951][v][vo/gpu] Video borders: l=0 t=0 r=0 b=0
[   1.952][v][vo/gpu] Reported display depth: 8
[   1.952][i][vo/gpu/d3d11] D3D11 Control: fullscreen state: nope, resize: nope, width=1920, height=1080
[   1.952][v][cplayer] Set property: fullscreen -> 1
[   1.952][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[   1.952][d][osc] osc_init

Exclusive osc init to osc init

[   1.027][d][osc] osc_init 
[   2.735][d][cplayer] Run command: cycle, flags=9, args=[fullscreen, (NULL)]
[   2.741][v][vo/gpu] Resize: 3840x2160
[   2.743][v][vo/gpu] Window size: 3840x2160
[   2.745][v][vo/gpu] Video source: 1920x1080 (1:1)
[   2.746][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (0, 0) 3840x2160
[   2.747][v][vo/gpu] Video scale: 2.000000/2.000000
[   2.756][v][vo/gpu] OSD borders: l=0 t=0 r=0 b=0
[   2.757][v][vo/gpu] Video borders: l=0 t=0 r=0 b=0
[   2.759][v][vo/gpu] Reported display depth: 8
[   2.760][v][vo/gpu/win32] restore window bounds: 960:510:1920:1080
[   2.762][v][vo/gpu/win32] reset window bounds: 960:510:1920:1080
[   2.829][d][vo/gpu/win32] move window: 960:510
[   2.831][v][vo/gpu/win32] resize window: 1920:1080
[   2.844][i][vo/gpu/d3d11] D3D11 Control: fullscreen state: yup, resize: yup, width=1920, height=1080
[   2.845][v][vo/gpu/d3d11] Disabling full-screen exclusive mode while leaving fullscreen
[   3.072][v][vo/gpu/win32] DPI detected from the new API: 144
[   3.092][d][vo/gpu/win32] move window: 11:45
[   3.092][v][vo/gpu/win32] resize window: 3818:2104
[   3.139][v][vo/gpu] Resize: 1920x1080
[   3.139][v][vo/gpu] Window size: 1920x1080
[   3.140][v][vo/gpu] Video source: 1920x1080 (1:1)
[   3.140][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (0, 0) 1920x1080
[   3.140][v][vo/gpu] Video scale: 1.000000/1.000000
[   3.141][v][vo/gpu] OSD borders: l=0 t=0 r=0 b=0
[   3.141][v][vo/gpu] Video borders: l=0 t=0 r=0 b=0
[   3.141][v][vo/gpu] Reported display depth: 8
[   3.141][v][cplayer] Set property: fullscreen -> 1
[   3.142][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[   3.142][d][osc] osc_init 
[   3.142][i][vo/gpu/d3d11] D3D11 Control: fullscreen state: nope, resize: yup, width=3818, height=2104
[   3.163][v][vo/gpu] Resize: 3818x2104
[   3.165][v][vo/gpu] Window size: 3818x2104
[   3.167][v][vo/gpu] Video source: 1920x1080 (1:1)
[   3.167][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (39, 0) 3740x2104
[   3.168][v][vo/gpu] Video scale: 1.947917/1.948148
[   3.168][v][vo/gpu] OSD borders: l=39 t=0 r=39 b=0
[   3.169][v][vo/gpu] Video borders: l=39 t=0 r=39 b=0
[   3.169][v][vo/gpu] Reported display depth: 8
[   3.226][v][vo/gpu] Resize: 3818x2104
[   3.226][v][vo/gpu] Window size: 3818x2104
[   3.226][v][vo/gpu] Video source: 1920x1080 (1:1)
[   3.227][v][vo/gpu] Video display: (0, 0) 1920x1080 -> (39, 0) 3740x2104
[   3.227][v][vo/gpu] Video scale: 1.947917/1.948148
[   3.227][v][vo/gpu] OSD borders: l=39 t=0 r=39 b=0
[   3.228][v][vo/gpu] Video borders: l=39 t=0 r=39 b=0
[   3.228][v][vo/gpu] Reported display depth: 8
[   3.229][d][vo/gpu] Resizing texture: 1920x2104
[   3.230][d][cplayer] Run command: enable-section, flags=0, args=[input, ]
[   3.230][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[   3.230][d][osc] osc_init

@jeeb
Copy link
Member Author

jeeb commented Nov 20, 2018

OK, so after leaving exclusive FS you get WM_MOVE and WM_SIZE with what the fullscreen size was - or what the fitting size for it would be on the screen.

@jeeb
Copy link
Member Author

jeeb commented Feb 3, 2019

Alright, so what I didn't mention here is that I think I figured what was happening. If you are going into exclusive FS then Windows will attempt to do the resize back to original size for you (instead of you doing it).

Thus what was happening was:

  1. We start windowed, with a smaller than full screen window size.
  2. We save original position and window size, and scale to full screen.
  3. We switch to exclusive full screen. Windows remembers the window size at this point.
  4. We switch back from d3d11 full screen.
  5. We instantly scale/move to the original size/position.
  6. Windows auto-sends a window resize to the scale it remembers (taking into account window decorations).
  7. You're stuck with a window size that is not the original one.

Thus what's left is:

  • Make the option available to the win32 back-end instead of just the d3d11 GPU vo back-end.
  • If we're going into/out of exclusive full screen, we do not attempt to resize the window ourselves.

@ghost
Copy link

ghost commented Sep 23, 2019

@jeeb same thing as the HDR PR I guess.

@rossy
Copy link
Member

rossy commented Oct 3, 2019

Well, you could also do what the original code did by entering fullscreen after vo_w32_control() and leaving fullscreen before vo_w32_control().

if (request == VOCTRL_FULLSCREEN && p->swapchain && p->opts->excl_fs &&
!ctx->vo->opts->fullscreen)
{
if (!set_fullscreen(ctx))
return VO_FALSE;
}
int ret = vo_w32_control(ctx->vo, events, request, arg);
if (request == VOCTRL_FULLSCREEN && p->swapchain && p->opts->excl_fs &&
ctx->vo->opts->fullscreen)
{
if (!set_fullscreen(ctx))
return VO_FALSE;
}

The code is kind of ugly, but it has the advantage of making w32_common.c responsible for positioning the window, which should allow the --fs-screen option to work correctly, moving mpv to the correct screen when entering fullscreen and moving it back to the screen it was on when leaving.

@Doofussy2
Copy link

Will there be an option to disable this?

@ghost
Copy link

ghost commented Nov 9, 2019

As implemented, it's off by default (as it should).

@Doofussy2
Copy link

Doofussy2 commented Nov 9, 2019

Good to know, thanks. I have that problem with opengl and vulkan. I can't disable exclusivity, and I have a use case in which that causes a problem, and stops me from using them.

@ghost
Copy link

ghost commented Nov 9, 2019

Ye,s it's known that OpenGL drivers on Windows typically enable exclusive fullscreen, but this has nothing to do with this PR, and the player has no control over them. I don't know about Vulkan, but since it's gamer idiocy and outside of the winapi graphics ecosystem, I wouldn't be surprised if the drivers behaved exactly like OpenGL in this aspect.

@Doofussy2
Copy link

Thanks for the explanation. I very much appreciate all the work that you guys do.

@aufkrawall
Copy link

aufkrawall commented Nov 11, 2019

Yes, there is no borderless mode with AMD and Vulkan on Windows. With Nvidia, it always uses DWM direct mode instead.

Edit: The Nvidia part is not true anymore.

@jeeb
Copy link
Member Author

jeeb commented Feb 16, 2020

Updated to work with the switch from events to config cache (finally). This brings us to the state that we were working with before.

Now back to the finishing this up:

  1. People don't seem to like that now both win32 common and d3d11 are both looking at when the fullscreen state option is changing.
  2. We still have the issue of not having win32 common code and d3d11 in synch.

Basically, if d3d11 fullscreen is utilized, update_fullscreen_state in common code does not have to do window size saving or restoration (Windows/D3D11 does that for you). But for that to happen we need to either call d3d11 fullscreen setting function from common win32 code, or otherwise inform win32 common of not having to do those specifics.

@ghost
Copy link

ghost commented Feb 16, 2020

Basically, if d3d11 fullscreen is utilized, update_fullscreen_state in common code does not have to do window size saving or restoration (Windows/D3D11 does that for you).

Does it really do that? Or does it just leave the window alone and use the screen for the d3d surface? Is there a conflict if we resize the window etc. ourselves?

But for that to happen we need to either call d3d11 fullscreen setting function from common win32 code, or otherwise inform win32 common of not having to do those specifics.

Not sure what that means.

@jeeb
Copy link
Member Author

jeeb commented Feb 17, 2020

The difference between the two behaviors. "resize window: XxY" is when the window receives a resize message from the OS (both ours and the OS's).

Exclusive FS:

VO: [gpu] 1280x720 yuv420p
[vo/gpu/win32] reset window bounds: 1280:690:1280:720
[vo/gpu/win32] resize window: 1280:720
[vo/gpu/win32] resize window: 1280:720
// fullscreen in
[vo/gpu/win32] fullscreen happened: 1
[vo/gpu/win32] save window bounds: 1280:690:1280:720
[vo/gpu/win32] reset window bounds: 0:0:3840:2160
[vo/gpu/win32] resize window: 3840:2160
[vo/gpu/d3d11] Enabling full-screen exclusive mode while entering fullscreen
[vo/gpu/d3d11] Das swap chain is now fullscreen: yes
// fullscreen out
[vo/gpu/win32] fullscreen happened: 0
[vo/gpu/win32] reset window bounds: 1280:690:1280:720
[vo/gpu/win32] resize window: 1280:720
[vo/gpu/d3d11] Disabling full-screen exclusive mode while leaving fullscreen
[vo/gpu/win32] resize window: 3832:2118
[vo/gpu/d3d11] Das swap chain is now fullscreen: no

Normal FS:

VO: [gpu] 1280x720 yuv420p
[vo/gpu/win32] reset window bounds: 1280:690:1280:720
[vo/gpu/win32] resize window: 1280:720
[vo/gpu/win32] resize window: 1280:720
// fullscreen in
[vo/gpu/win32] fullscreen happened: 1
[vo/gpu/win32] save window bounds: 1280:690:1280:720
[vo/gpu/win32] reset window bounds: 0:0:3840:2160
[vo/gpu/win32] resize window: 3840:2160
[vo/gpu/d3d11] Disabling full-screen exclusive mode while entering fullscreen
[vo/gpu/d3d11] Das swap chain is now fullscreen: no
// fullscreen out
[vo/gpu/win32] fullscreen happened: 0
[vo/gpu/win32] reset window bounds: 1280:690:1280:720
[vo/gpu/win32] resize window: 1280:720
[vo/gpu/d3d11] Disabling full-screen exclusive mode while leaving fullscreen
[vo/gpu/d3d11] Das swap chain is now fullscreen: no

@amayra
Copy link

amayra commented Apr 8, 2020

i was looking forward for this option

@jeeb jeeb force-pushed the exclusive_fs branch 3 times, most recently from b73255a to 869484a Compare April 12, 2020 14:04
rossy and others added 2 commits April 12, 2020 20:54
Lets the application fully control the rendering onto the screen
instead of the compositor.
Update the cache whenever we utilize p->opts, as recommended by
wm4.
@jeeb
Copy link
Member Author

jeeb commented Apr 12, 2020

Alright, after discussions with @wm4 this seems to be in a good enough state and with the hacky timing of things going back from full screen actually works now.

I think we all agree that while imperfect, we can now take this in.

@jeeb jeeb merged commit b885f80 into mpv-player:master Apr 12, 2020
@jeeb jeeb deleted the exclusive_fs branch April 12, 2020 18:18
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 this pull request may close these issues.

None yet

5 participants