vo_gpu: d3d11: add support for exclusive fullscreen
Lets the application fully control the rendering onto the screen instead of the compositor.
This commit is contained in:
1 parent
530a0863b8
commit
2a542b7f19
2 files changed
+92
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user