diff options
Diffstat (limited to 'video/out/gl_w32.c')
-rw-r--r-- | video/out/gl_w32.c | 42 |
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; } |