summaryrefslogtreecommitdiffstats
path: root/video/out/gl_w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/gl_w32.c')
-rw-r--r--video/out/gl_w32.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/video/out/gl_w32.c b/video/out/gl_w32.c
index f2b7cf63d3..b1985e5e1f 100644
--- a/video/out/gl_w32.c
+++ b/video/out/gl_w32.c
@@ -24,10 +24,15 @@
#include "w32_common.h"
#include "gl_common.h"
+typedef HRESULT (WINAPI *DwmFlush_t)(void);
+
struct w32_context {
HGLRC context;
HDC hdc;
int flags;
+
+ HINSTANCE dwmapi_dll;
+ DwmFlush_t dwmflush;
};
static bool create_dc(struct MPGLContext *ctx, int flags)
@@ -202,6 +207,11 @@ static void create_ctx(void *ptr)
create_context_w32_gl3(ctx);
if (!w32_ctx->context)
create_context_w32_old(ctx);
+
+ w32_ctx->dwmapi_dll = LoadLibrary(L"Dwmapi.dll");
+ if (w32_ctx->dwmapi_dll)
+ w32_ctx->dwmflush = (DwmFlush_t)GetProcAddress(w32_ctx->dwmapi_dll, "DwmFlush");
+
wglMakeCurrent(w32_ctx->hdc, NULL);
}
@@ -240,6 +250,11 @@ static void releaseGlContext_w32(MPGLContext *ctx)
if (w32_ctx->context)
wglMakeCurrent(w32_ctx->hdc, 0);
vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx);
+
+ w32_ctx->dwmflush = NULL;
+ if (w32_ctx->dwmapi_dll)
+ FreeLibrary(w32_ctx->dwmapi_dll);
+ w32_ctx->dwmapi_dll = NULL;
}
static void swapGlBuffers_w32(MPGLContext *ctx)
@@ -248,6 +263,32 @@ static void swapGlBuffers_w32(MPGLContext *ctx)
SwapBuffers(w32_ctx->hdc);
}
+// opt_dwmflush: 0 - never DwmFlush, 1 - only in windowed mode, 2 - always
+// return: the current (applied if modified) SwapInterval value.
+// DwmFlush waits on DWM vsync similar to SwapBuffers but a bit more noisy.
+// SwapBuffers still needs to be called, but we SwapInterval(0) when DwmFLush is
+// used (will get applied for the following SwapBuffers calls)
+static int DwmFlush_w32(MPGLContext *ctx, int opt_dwmflush,
+ int opt_swapinterval, int current_swapinterval)
+{
+ struct w32_context *w32_ctx = ctx->priv;
+ int new_swapinterval = opt_swapinterval; // default if we don't DwmFLush
+
+ if (w32_ctx->dwmflush &&
+ (opt_dwmflush == 2 || (opt_dwmflush == 1 && !ctx->vo->opts->fullscreen)) &&
+ S_OK == w32_ctx->dwmflush())
+ {
+ new_swapinterval = 0;
+ }
+
+ if ((new_swapinterval != current_swapinterval) && ctx->gl->SwapInterval) {
+ ctx->gl->SwapInterval(new_swapinterval);
+ MP_VERBOSE(ctx->vo, "DwmFlush: set SwapInterval(%d)\n", new_swapinterval);
+ }
+
+ return new_swapinterval;
+}
+
void mpgl_set_backend_w32(MPGLContext *ctx)
{
ctx->priv = talloc_zero(ctx, struct w32_context);
@@ -257,4 +298,5 @@ void mpgl_set_backend_w32(MPGLContext *ctx)
ctx->vo_init = vo_w32_init;
ctx->vo_uninit = vo_w32_uninit;
ctx->vo_control = vo_w32_control;
+ ctx->DwmFlush = DwmFlush_w32;
}