diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/out/opengl/w32.c | 53 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 2 |
2 files changed, 46 insertions, 9 deletions
diff --git a/video/out/opengl/w32.c b/video/out/opengl/w32.c index dca76b3406..8365a3933c 100644 --- a/video/out/opengl/w32.c +++ b/video/out/opengl/w32.c @@ -22,6 +22,7 @@ #include <assert.h> #include <windows.h> +#include <Dwmapi.h> #include "video/out/w32_common.h" #include "common.h" @@ -36,7 +37,11 @@ struct w32_context { int flags; HINSTANCE dwmapi_dll; - HRESULT (WINAPI *dwmflush)(void); + HRESULT (WINAPI *pDwmFlush)(void); + HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *pfEnabled); + HRESULT (WINAPI *pDwmEnableMMCSS)(BOOL fEnableMMCSS); + HRESULT (WINAPI *pDwmGetCompositionTimingInfo) + (HWND hwnd, DWM_TIMING_INFO *pTimingInfo); }; static void w32_uninit(MPGLContext *ctx); @@ -223,8 +228,15 @@ static void create_ctx(void *ptr) create_context_w32_old(ctx); w32_ctx->dwmapi_dll = LoadLibrary(L"Dwmapi.dll"); - if (w32_ctx->dwmapi_dll) - w32_ctx->dwmflush = (void *)GetProcAddress(w32_ctx->dwmapi_dll, "DwmFlush"); + if (w32_ctx->dwmapi_dll) { + w32_ctx->pDwmFlush = (void *)GetProcAddress(w32_ctx->dwmapi_dll, "DwmFlush"); + w32_ctx->pDwmIsCompositionEnabled = + (void *)GetProcAddress(w32_ctx->dwmapi_dll, "DwmIsCompositionEnabled"); + w32_ctx->pDwmGetCompositionTimingInfo = + (void *)GetProcAddress(w32_ctx->dwmapi_dll, "DwmGetCompositionTimingInfo"); + w32_ctx->pDwmEnableMMCSS = + (void *)GetProcAddress(w32_ctx->dwmapi_dll, "DwmEnableMMCSS"); + } wglMakeCurrent(w32_ctx->hdc, NULL); } @@ -289,6 +301,28 @@ static void w32_uninit(MPGLContext *ctx) vo_w32_uninit(ctx->vo); } +static bool compositor_active(MPGLContext *ctx) +{ + struct w32_context *w32_ctx = ctx->priv; + + if (!w32_ctx->pDwmIsCompositionEnabled || !w32_ctx->pDwmGetCompositionTimingInfo) + return false; + + // For Windows 7. + BOOL enabled = 0; + if (FAILED(w32_ctx->pDwmIsCompositionEnabled(&enabled)) || !enabled) + return false; + + // This works at least on Windows 8.1: it returns an error in fullscreen, + // which is also when we get consistent timings without DwmFlush. Might + // be cargo-cult. + DWM_TIMING_INFO info = { .cbSize = sizeof(DWM_TIMING_INFO) }; + if (FAILED(w32_ctx->pDwmGetCompositionTimingInfo(0, &info))) + return false; + + return true; +} + static void w32_swap_buffers(MPGLContext *ctx) { struct w32_context *w32_ctx = ctx->priv; @@ -297,11 +331,14 @@ static void w32_swap_buffers(MPGLContext *ctx) // default if we don't DwmFLush int new_swapinterval = w32_ctx->opt_swapinterval; - if (w32_ctx->dwmflush && w32_ctx->dwmflush() == S_OK && - ((ctx->dwm_flush_opt == 1 && !ctx->vo->opts->fullscreen) || - ctx->dwm_flush_opt == 2)) - { - new_swapinterval = 0; + if (ctx->dwm_flush_opt >= 0) { + if ((ctx->dwm_flush_opt == 1 && !ctx->vo->opts->fullscreen) || + (ctx->dwm_flush_opt == 2) || + (ctx->dwm_flush_opt == 0 && compositor_active(ctx))) + { + if (w32_ctx->pDwmFlush && w32_ctx->pDwmFlush() == S_OK) + new_swapinterval = 0; + } } if (new_swapinterval != w32_ctx->current_swapinterval && diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index f5a3cdcf73..66ab7f11a7 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -460,7 +460,7 @@ static const struct m_option options[] = { OPT_FLAG("waitvsync", waitvsync, 0), OPT_INT("swapinterval", swap_interval, 0, OPTDEF_INT(1)), OPT_CHOICE("dwmflush", dwm_flush, 0, - ({"no", 0}, {"windowed", 1}, {"yes", 2})), + ({"no", -1}, {"auto", 0}, {"windowed", 1}, {"yes", 2})), OPT_FLAG("debug", use_gl_debug, 0), OPT_STRING_VALIDATE("backend", backend, 0, mpgl_validate_backend_opt), OPT_FLAG("sw", allow_sw, 0), |