summaryrefslogtreecommitdiffstats
path: root/video/out/gl_w32.c
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2015-03-17 01:15:28 +0200
committerwm4 <wm4@nowhere>2015-04-09 20:36:35 +0200
commit843bc822a8a7974c7fbeea62525cb56bbab23fde (patch)
tree0ce52c36cbae7804ce12d922c3bddc6bcb0dda25 /video/out/gl_w32.c
parentc97f014576143c706e9d5189a89fa9959a651c71 (diff)
downloadmpv-843bc822a8a7974c7fbeea62525cb56bbab23fde.tar.bz2
mpv-843bc822a8a7974c7fbeea62525cb56bbab23fde.tar.xz
opengl: win32 - add option 'dwmflush' to sync in DWM
This could help in cases where the DWM (Windows desktop compositor) adds another layer of bufferring and therefore the SwapBuffers timing could get messed up. Signed-off-by: wm4 <wm4@nowhere>
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;
}