summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/w32.c')
-rw-r--r--video/out/opengl/w32.c58
1 files changed, 50 insertions, 8 deletions
diff --git a/video/out/opengl/w32.c b/video/out/opengl/w32.c
index dca76b3406..97ad0d6e47 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);
}
@@ -250,6 +262,8 @@ static int w32_init(struct MPGLContext *ctx, int flags)
current_w32_context = w32_ctx;
wglMakeCurrent(w32_ctx->hdc, w32_ctx->context);
+ if (w32_ctx->pDwmEnableMMCSS)
+ w32_ctx->pDwmEnableMMCSS(TRUE);
return 0;
fail:
@@ -283,12 +297,37 @@ static void w32_uninit(MPGLContext *ctx)
wglMakeCurrent(w32_ctx->hdc, 0);
vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx);
+ if (w32_ctx->pDwmEnableMMCSS)
+ w32_ctx->pDwmEnableMMCSS(FALSE);
+
if (w32_ctx->dwmapi_dll)
FreeLibrary(w32_ctx->dwmapi_dll);
w32_ctx->dwmapi_dll = NULL;
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 +336,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 &&