summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossy@jrg.systems>2017-12-26 20:50:31 +1100
committerJan Ekström <jeebjp@gmail.com>2020-04-12 21:18:50 +0300
commit2a542b7f197c1936ac69b782c058885bbd9ee4a5 (patch)
treebd59908ac229b77ab3cb9ca4fe98f939dea3266b
parent530a0863b859e96d20318704284bf52962e691ec (diff)
downloadmpv-2a542b7f197c1936ac69b782c058885bbd9ee4a5.tar.bz2
mpv-2a542b7f197c1936ac69b782c058885bbd9ee4a5.tar.xz
vo_gpu: d3d11: add support for exclusive fullscreen
Lets the application fully control the rendering onto the screen instead of the compositor.
-rw-r--r--DOCS/man/options.rst6
-rw-r--r--video/out/d3d11/context.c87
2 files changed, 92 insertions, 1 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index f5b59d291a..871561cde3 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -5158,6 +5158,12 @@ The following video options are currently all specific to ``--vo=gpu`` and
use of compute shaders over fragment shaders wherever possible. Enabled by
default, although Nvidia users may want to disable it.
+``--d3d11-exclusive-fs=<yes|no>``
+ Switches the D3D11 swap chain fullscreen state to 'fullscreen' when
+ fullscreen video is requested. Also known as "exclusive fullscreen" or
+ "D3D fullscreen" in other applications. Gives mpv full control of
+ rendering on the swap chain's screen. Off by default.
+
``--d3d11-warp=<yes|no|auto>``
Use WARP (Windows Advanced Rasterization Platform) with the D3D11 GPU
backend (default: auto). This is a high performance software renderer. By
diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c
index 600058c1d2..afcfefa2e0 100644
--- a/video/out/d3d11/context.c
+++ b/video/out/d3d11/context.c
@@ -38,6 +38,7 @@ struct d3d11_opts {
char *adapter_name;
int output_format;
int color_space;
+ int exclusive_fs;
};
#define OPT_BASE_STRUCT struct d3d11_opts
@@ -73,6 +74,7 @@ const struct m_sub_options d3d11_conf = {
{"linear", DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709},
{"pq", DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020},
{"bt.2020", DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020})},
+ {"d3d11-exclusive-fs", OPT_FLAG(exclusive_fs)},
{0}
},
.defaults = &(const struct d3d11_opts) {
@@ -83,6 +85,7 @@ const struct m_sub_options d3d11_conf = {
.adapter_name = NULL,
.output_format = DXGI_FORMAT_UNKNOWN,
.color_space = -1,
+ .exclusive_fs = 0,
},
.size = sizeof(struct d3d11_opts)
};
@@ -90,6 +93,9 @@ const struct m_sub_options d3d11_conf = {
struct priv {
struct d3d11_opts *opts;
+ struct mp_vo_opts *vo_opts;
+ struct m_config_cache *vo_opts_cache;
+
struct ra_tex *backbuffer;
ID3D11Device *device;
IDXGISwapChain *swapchain;
@@ -319,9 +325,82 @@ static void d3d11_get_vsync(struct ra_swapchain *sw, struct vo_vsync_info *info)
}
}
+static bool d3d11_set_fullscreen(struct ra_ctx *ctx)
+{
+ struct priv *p = ctx->priv;
+ HRESULT hr;
+
+ if (!p->swapchain) {
+ MP_ERR(ctx, "Full screen configuration was requested before D3D11 "
+ "swap chain was ready!");
+ return false;
+ }
+
+ // we only want exclusive FS if we are entering FS and
+ // exclusive FS is enabled. Otherwise disable exclusive FS.
+ bool enable_exclusive_fs = p->vo_opts->fullscreen &&
+ p->opts->exclusive_fs;
+
+ MP_VERBOSE(ctx, "%s full-screen exclusive mode while %s fullscreen\n",
+ enable_exclusive_fs ? "Enabling" : "Disabling",
+ ctx->vo->opts->fullscreen ? "entering" : "leaving");
+
+ hr = IDXGISwapChain_SetFullscreenState(p->swapchain,
+ enable_exclusive_fs, NULL);
+ if (FAILED(hr))
+ return false;
+
+ if (!resize(ctx))
+ return false;
+
+ return true;
+}
+
static int d3d11_control(struct ra_ctx *ctx, int *events, int request, void *arg)
{
- int ret = vo_w32_control(ctx->vo, events, request, arg);
+ struct priv *p = ctx->priv;
+ int ret = -1;
+ bool fullscreen_switch_needed = false;
+
+ switch (request) {
+ case VOCTRL_VO_OPTS_CHANGED: {
+ void *changed_option;
+
+ while (m_config_cache_get_next_changed(p->vo_opts_cache,
+ &changed_option))
+ {
+ struct mp_vo_opts *vo_opts = p->vo_opts_cache->opts;
+
+ if (changed_option == &vo_opts->fullscreen) {
+ fullscreen_switch_needed = true;
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ // if leaving full screen, handle d3d11 stuff first, then general
+ // windowing
+ if (fullscreen_switch_needed && !p->vo_opts->fullscreen) {
+ if (!d3d11_set_fullscreen(ctx))
+ return VO_FALSE;
+
+ fullscreen_switch_needed = false;
+ }
+
+ ret = vo_w32_control(ctx->vo, events, request, arg);
+
+ // if entering full screen, handle d3d11 after general windowing stuff
+ if (fullscreen_switch_needed && p->vo_opts->fullscreen) {
+ if (!d3d11_set_fullscreen(ctx))
+ return VO_FALSE;
+
+ fullscreen_switch_needed = false;
+ }
+
if (*events & VO_EVENT_RESIZE) {
if (!resize(ctx))
return VO_ERROR;
@@ -333,6 +412,9 @@ static void d3d11_uninit(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
+ if (p->swapchain)
+ IDXGISwapChain_SetFullscreenState(p->swapchain, FALSE, NULL);
+
if (ctx->ra)
ra_tex_free(ctx->ra, &p->backbuffer);
SAFE_RELEASE(p->swapchain);
@@ -358,6 +440,9 @@ static bool d3d11_init(struct ra_ctx *ctx)
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
p->opts = mp_get_config_group(ctx, ctx->global, &d3d11_conf);
+ p->vo_opts_cache = m_config_cache_alloc(ctx, ctx->vo->global, &vo_sub_opts);
+ p->vo_opts = p->vo_opts_cache->opts;
+
LARGE_INTEGER perf_freq;
QueryPerformanceFrequency(&perf_freq);
p->perf_freq = perf_freq.QuadPart;