From 75c0c06640da677477a0cfd08deee1d4e23a4361 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Sat, 16 Sep 2017 01:37:28 +1000 Subject: [PATCH] vo_gpu: convert windows/osx hwdecs/contexts to new API --- DOCS/man/options.rst | 19 -- video/out/gpu/context.c | 6 +- video/out/opengl/context_angle.c | 220 ++++++++-------- video/out/opengl/context_cocoa.c | 72 ++++-- video/out/opengl/context_dxinterop.c | 191 +++++++------- .../opengl/{context_w32.c => context_win.c} | 238 +++++++++--------- video/out/opengl/hwdec_d3d11egl.c | 2 +- video/out/opengl/hwdec_d3d11eglrgb.c | 2 +- video/out/opengl/hwdec_dxva2egl.c | 2 +- video/out/opengl/hwdec_dxva2gldx.c | 2 +- wscript_build.py | 18 +- 11 files changed, 410 insertions(+), 362 deletions(-) rename video/out/opengl/{context_w32.c => context_win.c} (67%) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 4a880fb72c..b4416ec34d 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4541,14 +4541,6 @@ The following video options are currently all specific to ``--vo=gpu`` and Windows with ANGLE only. -``--angle-max-frame-latency=<1-16>`` - Sets the maximum number of frames that the system is allowed to queue for - rendering with the ANGLE backend (default: 3). Lower values should make - VSync timing more accurate, but a value of ``1`` requires powerful - hardware, since the CPU will not be able to "render ahead" of the GPU. - - Windows with ANGLE only. - ``--angle-renderer=`` Forces a specific renderer when using the ANGLE backend (default: auto). In auto mode this will pick D3D11 for systems that support Direct3D 11 feature @@ -4561,17 +4553,6 @@ The following video options are currently all specific to ``--vo=gpu`` and Windows with ANGLE only. -``--angle-swapchain-length=<2-16>`` - Sets the number of buffers in the D3D11 presentation queue when using the - ANGLE backend (default: 6). At least 2 are required, since one is the back - buffer that mpv renders to and the other is the front buffer that is - presented by the DWM. Additional buffers can improve performance, because - for example, mpv will not have to wait on the DWM to release the front - buffer before rendering a new frame to it. For this reason, Microsoft - recommends at least 4. - - Windows with ANGLE only. - ``--cocoa-force-dedicated-gpu=`` Deactivates the automatic graphics switching and forces the dedicated GPU. (default: no) diff --git a/video/out/gpu/context.c b/video/out/gpu/context.c index dbabba8b3b..ba710ff59e 100644 --- a/video/out/gpu/context.c +++ b/video/out/gpu/context.c @@ -40,7 +40,7 @@ extern const struct ra_ctx_fns ra_ctx_cocoa; extern const struct ra_ctx_fns ra_ctx_wayland_egl; extern const struct ra_ctx_fns ra_ctx_wgl; extern const struct ra_ctx_fns ra_ctx_angle; -extern const struct ra_ctx_fns ra_ctx_dxinterop; +extern const struct ra_ctx_fns ra_ctx_dxgl; extern const struct ra_ctx_fns ra_ctx_rpi; extern const struct ra_ctx_fns ra_ctx_mali; extern const struct ra_ctx_fns ra_ctx_vdpauglx; @@ -50,7 +50,6 @@ static const struct ra_ctx_fns *contexts[] = { #if HAVE_RPI &ra_ctx_rpi, #endif -/* #if HAVE_GL_COCOA &ra_ctx_cocoa, #endif @@ -61,9 +60,8 @@ static const struct ra_ctx_fns *contexts[] = { &ra_ctx_wgl, #endif #if HAVE_GL_DXINTEROP - &ra_ctx_dxinterop, + &ra_ctx_dxgl, #endif -*/ #if HAVE_GL_X11 &ra_ctx_glx_probe, #endif diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c index f249b746cb..a8051155e1 100644 --- a/video/out/opengl/context_angle.c +++ b/video/out/opengl/context_angle.c @@ -31,6 +31,7 @@ #include "video/out/w32_common.h" #include "osdep/windows_utils.h" #include "context.h" +#include "utils.h" #ifndef EGL_D3D_TEXTURE_ANGLE #define EGL_D3D_TEXTURE_ANGLE 0x33A3 @@ -52,8 +53,6 @@ struct angle_opts { int d3d11_warp; int d3d11_feature_level; int egl_windowing; - int swapchain_length; // Currently only works with DXGI 1.2+ - int max_frame_latency; int flip; }; @@ -77,9 +76,9 @@ const struct m_sub_options angle_conf = { ({"auto", -1}, {"no", 0}, {"yes", 1})), - OPT_INTRANGE("angle-swapchain-length", swapchain_length, 0, 2, 16), - OPT_INTRANGE("angle-max-frame-latency", max_frame_latency, 0, 1, 16), OPT_FLAG("angle-flip", flip, 0), + OPT_REPLACED("angle-max-frame-latency", "swapchain-depth"), + OPT_REMOVED("angle-swapchain-length", "controlled by --swapchain-depth"), {0} }, .defaults = &(const struct angle_opts) { @@ -87,14 +86,14 @@ const struct m_sub_options angle_conf = { .d3d11_warp = -1, .d3d11_feature_level = D3D_FEATURE_LEVEL_11_0, .egl_windowing = -1, - .swapchain_length = 6, - .max_frame_latency = 3, .flip = 1, }, .size = sizeof(struct angle_opts), }; struct priv { + GL gl; + IDXGISwapChain *dxgi_swapchain; ID3D11Device *d3d11_device; @@ -110,20 +109,21 @@ struct priv { int sc_width, sc_height; // Swap chain width and height int swapinterval; + bool flipped; struct angle_opts *opts; }; -static __thread struct MPGLContext *current_ctx; +static __thread struct ra_ctx *current_ctx; -static void update_sizes(MPGLContext *ctx) +static void update_sizes(struct ra_ctx *ctx) { struct priv *p = ctx->priv; p->sc_width = ctx->vo->dwidth ? ctx->vo->dwidth : 1; p->sc_height = ctx->vo->dheight ? ctx->vo->dheight : 1; } -static void d3d11_backbuffer_release(MPGLContext *ctx) +static void d3d11_backbuffer_release(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -137,7 +137,7 @@ static void d3d11_backbuffer_release(MPGLContext *ctx) SAFE_RELEASE(p->d3d11_backbuffer); } -static bool d3d11_backbuffer_get(MPGLContext *ctx) +static bool d3d11_backbuffer_get(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -168,7 +168,7 @@ static bool d3d11_backbuffer_get(MPGLContext *ctx) return true; } -static void d3d11_backbuffer_resize(MPGLContext *ctx) +static void d3d11_backbuffer_resize(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -197,7 +197,7 @@ static void d3d11_backbuffer_resize(MPGLContext *ctx) MP_FATAL(vo, "Couldn't get back buffer after resize\n"); } -static void d3d11_device_destroy(MPGLContext *ctx) +static void d3d11_device_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -215,7 +215,7 @@ static void d3d11_device_destroy(MPGLContext *ctx) SAFE_RELEASE(p->d3d11_device); } -static bool d3d11_device_create(MPGLContext *ctx, int flags) +static bool d3d11_device_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -226,7 +226,7 @@ static bool d3d11_device_create(MPGLContext *ctx, int flags) .force_warp = o->d3d11_warp == 1, .max_feature_level = o->d3d11_feature_level, .min_feature_level = D3D_FEATURE_LEVEL_9_3, - .max_frame_latency = o->max_frame_latency, + .max_frame_latency = ctx->opts.swapchain_depth, }; if (!mp_d3d11_create_present_device(vo->log, &device_opts, &p->d3d11_device)) return false; @@ -262,7 +262,7 @@ static bool d3d11_device_create(MPGLContext *ctx, int flags) return true; } -static void d3d11_swapchain_surface_destroy(MPGLContext *ctx) +static void d3d11_swapchain_surface_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -277,7 +277,7 @@ static void d3d11_swapchain_surface_destroy(MPGLContext *ctx) ID3D11DeviceContext_Flush(p->d3d11_context); } -static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags) +static bool d3d11_swapchain_surface_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -292,7 +292,9 @@ static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags) .width = p->sc_width, .height = p->sc_height, .flip = o->flip, - .length = o->swapchain_length, + // Add one frame for the backbuffer and one frame of "slack" to reduce + // contention with the window manager when acquiring the backbuffer + .length = ctx->opts.swapchain_depth + 2, .usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT, }; if (!mp_d3d11_create_swapchain(p->d3d11_device, vo->log, &swapchain_opts, @@ -301,8 +303,7 @@ static bool d3d11_swapchain_surface_create(MPGLContext *ctx, int flags) if (!d3d11_backbuffer_get(ctx)) goto fail; - // EGL_D3D_TEXTURE_ANGLE pbuffers are always flipped vertically - ctx->flip_v = true; + p->flipped = true; return true; fail: @@ -310,7 +311,7 @@ fail: return false; } -static void d3d9_device_destroy(MPGLContext *ctx) +static void d3d9_device_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -319,7 +320,7 @@ static void d3d9_device_destroy(MPGLContext *ctx) p->egl_display = EGL_NO_DISPLAY; } -static bool d3d9_device_create(MPGLContext *ctx, int flags) +static bool d3d9_device_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -348,7 +349,7 @@ static bool d3d9_device_create(MPGLContext *ctx, int flags) return true; } -static void egl_window_surface_destroy(MPGLContext *ctx) +static void egl_window_surface_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; if (p->egl_window) { @@ -357,7 +358,7 @@ static void egl_window_surface_destroy(MPGLContext *ctx) } } -static bool egl_window_surface_create(MPGLContext *ctx, int flags) +static bool egl_window_surface_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -374,7 +375,7 @@ static bool egl_window_surface_create(MPGLContext *ctx, int flags) EGL_SURFACE_ORIENTATION_ANGLE); MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); - ctx->flip_v = true; + p->flipped = true; MP_VERBOSE(vo, "Rendering flipped.\n"); } } @@ -396,7 +397,7 @@ fail: return false; } -static void context_destroy(struct MPGLContext *ctx) +static void context_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; if (p->egl_context) { @@ -407,7 +408,7 @@ static void context_destroy(struct MPGLContext *ctx) p->egl_context = EGL_NO_CONTEXT; } -static bool context_init(struct MPGLContext *ctx, int flags) +static bool context_init(struct ra_ctx *ctx) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; @@ -421,8 +422,8 @@ static bool context_init(struct MPGLContext *ctx, int flags) if (exts) MP_DBG(vo, "EGL extensions: %s\n", exts); - if (!mpegl_create_context(p->egl_display, vo->log, flags | VOFLAG_GLES, - &p->egl_context, &p->egl_config)) + if (!mpegl_create_context(ctx, p->egl_display, &p->egl_context, + &p->egl_config)) { MP_FATAL(vo, "Could not create EGL context!\n"); goto fail; @@ -434,10 +435,12 @@ fail: return false; } -static void angle_uninit(struct MPGLContext *ctx) +static void angle_uninit(struct ra_ctx *ctx) { struct priv *p = ctx->priv; + ra_gl_ctx_uninit(ctx); + DwmEnableMMCSS(FALSE); // Uninit the EGL surface implementation that is being used. Note: This may @@ -474,17 +477,56 @@ static int GLAPIENTRY angle_swap_interval(int interval) } } -static int angle_init(struct MPGLContext *ctx, int flags) +static void d3d11_swap_buffers(struct ra_ctx *ctx) { struct priv *p = ctx->priv; + + // Calling Present() on a flip-sequential swap chain will silently change + // the underlying storage of the back buffer to point to the next buffer in + // the chain. This results in the RTVs for the back buffer becoming + // unbound. Since ANGLE doesn't know we called Present(), it will continue + // using the unbound RTVs, so we must save and restore them ourselves. + ID3D11RenderTargetView *rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11DepthStencilView *dsv = NULL; + ID3D11DeviceContext_OMGetRenderTargets(p->d3d11_context, + MP_ARRAY_SIZE(rtvs), rtvs, &dsv); + + HRESULT hr = IDXGISwapChain_Present(p->dxgi_swapchain, p->swapinterval, 0); + if (FAILED(hr)) + MP_FATAL(ctx->vo, "Couldn't present: %s\n", mp_HRESULT_to_str(hr)); + + // Restore the RTVs and release the objects + ID3D11DeviceContext_OMSetRenderTargets(p->d3d11_context, + MP_ARRAY_SIZE(rtvs), rtvs, dsv); + for (int i = 0; i < MP_ARRAY_SIZE(rtvs); i++) + SAFE_RELEASE(rtvs[i]); + SAFE_RELEASE(dsv); +} + +static void egl_swap_buffers(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + eglSwapBuffers(p->egl_display, p->egl_window); +} + +static void angle_swap_buffers(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + if (p->dxgi_swapchain) + d3d11_swap_buffers(ctx); + else + egl_swap_buffers(ctx); +} + +static bool angle_init(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv = talloc_zero(ctx, struct priv); struct vo *vo = ctx->vo; + GL *gl = &p->gl; p->opts = mp_get_config_group(ctx, ctx->global, &angle_conf); struct angle_opts *o = p->opts; - // DWM MMCSS cargo-cult. The dxinterop backend also does this. - DwmEnableMMCSS(TRUE); - if (!angle_load()) { MP_VERBOSE(vo, "Failed to load LIBEGL.DLL\n"); goto fail; @@ -493,19 +535,19 @@ static int angle_init(struct MPGLContext *ctx, int flags) // Create the underlying EGL device implementation bool context_ok = false; if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D11) { - context_ok = d3d11_device_create(ctx, flags); + context_ok = d3d11_device_create(ctx); if (context_ok) { - context_ok = context_init(ctx, flags); + context_ok = context_init(ctx); if (!context_ok) d3d11_device_destroy(ctx); } } if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D9) { - context_ok = d3d9_device_create(ctx, flags); + context_ok = d3d9_device_create(ctx); if (context_ok) { MP_VERBOSE(vo, "Using Direct3D 9\n"); - context_ok = context_init(ctx, flags); + context_ok = context_init(ctx); if (!context_ok) d3d9_device_destroy(ctx); } @@ -519,34 +561,58 @@ static int angle_init(struct MPGLContext *ctx, int flags) // Create the underlying EGL surface implementation bool surface_ok = false; if ((!surface_ok && o->egl_windowing == -1) || o->egl_windowing == 0) { - surface_ok = d3d11_swapchain_surface_create(ctx, flags); + surface_ok = d3d11_swapchain_surface_create(ctx); } if ((!surface_ok && o->egl_windowing == -1) || o->egl_windowing == 1) { - surface_ok = egl_window_surface_create(ctx, flags); + surface_ok = egl_window_surface_create(ctx); if (surface_ok) MP_VERBOSE(vo, "Using EGL windowing\n"); } if (!surface_ok) goto fail; - mpegl_load_functions(ctx->gl, vo->log); + mpegl_load_functions(gl, vo->log); current_ctx = ctx; - ctx->gl->SwapInterval = angle_swap_interval; + gl->SwapInterval = angle_swap_interval; - return 0; + // ANGLE doesn't actually need to override any of the functions (yet) + static const struct ra_swapchain_fns empty_swapchain_fns = {0}; + struct ra_gl_ctx_params params = { + .swap_buffers = angle_swap_buffers, + .flipped = p->flipped, + .external_swapchain = p->dxgi_swapchain ? &empty_swapchain_fns : NULL, + }; + + if (!ra_gl_ctx_init(ctx, gl, params)) + goto fail; + + DwmEnableMMCSS(TRUE); // DWM MMCSS cargo-cult. The dxgl backend also does this. + + return true; fail: angle_uninit(ctx); - return -1; + return false; } -static int angle_reconfig(struct MPGLContext *ctx) +static void resize(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + if (p->dxgi_swapchain) + d3d11_backbuffer_resize(ctx); + else + eglWaitClient(); // Should get ANGLE to resize its swapchain + ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0); +} + +static bool angle_reconfig(struct ra_ctx *ctx) { vo_w32_config(ctx->vo); - return 0; + resize(ctx); + return true; } -static struct mp_image *d3d11_screenshot(MPGLContext *ctx) +static struct mp_image *d3d11_screenshot(struct ra_ctx *ctx) { struct priv *p = ctx->priv; ID3D11Texture2D *frontbuffer = NULL; @@ -624,10 +690,8 @@ done: return img; } -static int angle_control(MPGLContext *ctx, int *events, int request, void *arg) +static int angle_control(struct ra_ctx *ctx, int *events, int request, void *arg) { - struct priv *p = ctx->priv; - // Try a D3D11-specific method of taking a window screenshot if (request == VOCTRL_SCREENSHOT_WIN) { struct mp_image *img = d3d11_screenshot(ctx); @@ -637,63 +701,17 @@ static int angle_control(MPGLContext *ctx, int *events, int request, void *arg) } } - int r = vo_w32_control(ctx->vo, events, request, arg); - if (*events & VO_EVENT_RESIZE) { - if (p->dxgi_swapchain) - d3d11_backbuffer_resize(ctx); - else - eglWaitClient(); // Should get ANGLE to resize its swapchain - } - return r; + int ret = vo_w32_control(ctx->vo, events, request, arg); + if (*events & VO_EVENT_RESIZE) + resize(ctx); + return ret; } -static void d3d11_swap_buffers(MPGLContext *ctx) -{ - struct priv *p = ctx->priv; - - // Calling Present() on a flip-sequential swap chain will silently change - // the underlying storage of the back buffer to point to the next buffer in - // the chain. This results in the RTVs for the back buffer becoming - // unbound. Since ANGLE doesn't know we called Present(), it will continue - // using the unbound RTVs, so we must save and restore them ourselves. - ID3D11RenderTargetView *rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11DepthStencilView *dsv = NULL; - ID3D11DeviceContext_OMGetRenderTargets(p->d3d11_context, - MP_ARRAY_SIZE(rtvs), rtvs, &dsv); - - HRESULT hr = IDXGISwapChain_Present(p->dxgi_swapchain, p->swapinterval, 0); - if (FAILED(hr)) - MP_FATAL(ctx->vo, "Couldn't present: %s\n", mp_HRESULT_to_str(hr)); - - // Restore the RTVs and release the objects - ID3D11DeviceContext_OMSetRenderTargets(p->d3d11_context, - MP_ARRAY_SIZE(rtvs), rtvs, dsv); - for (int i = 0; i < MP_ARRAY_SIZE(rtvs); i++) - SAFE_RELEASE(rtvs[i]); - SAFE_RELEASE(dsv); -} - -static void egl_swap_buffers(MPGLContext *ctx) -{ - struct priv *p = ctx->priv; - eglSwapBuffers(p->egl_display, p->egl_window); -} - -static void angle_swap_buffers(MPGLContext *ctx) -{ - struct priv *p = ctx->priv; - if (p->dxgi_swapchain) - d3d11_swap_buffers(ctx); - else - egl_swap_buffers(ctx); -} - -const struct mpgl_driver mpgl_driver_angle = { +const struct ra_ctx_fns ra_ctx_angle = { + .type = "opengl", .name = "angle", - .priv_size = sizeof(struct priv), .init = angle_init, .reconfig = angle_reconfig, - .swap_buffers = angle_swap_buffers, .control = angle_control, .uninit = angle_uninit, }; diff --git a/video/out/opengl/context_cocoa.c b/video/out/opengl/context_cocoa.c index cdf6faffcd..585c49f9a9 100644 --- a/video/out/opengl/context_cocoa.c +++ b/video/out/opengl/context_cocoa.c @@ -36,6 +36,7 @@ const struct m_sub_options cocoa_conf = { }; struct priv { + GL gl; CGLPixelFormatObj pix; CGLContextObj ctx; @@ -62,7 +63,7 @@ static void *cocoa_glgetaddr(const char *s) return ret; } -static CGLError test_gl_version(struct MPGLContext *ctx, CGLOpenGLProfile ver) +static CGLError test_gl_version(struct ra_ctx *ctx, CGLOpenGLProfile ver) { struct priv *p = ctx->priv; @@ -107,9 +108,10 @@ error_out: return err; } -static bool create_gl_context(struct MPGLContext *ctx, int vo_flags) +static bool create_gl_context(struct ra_ctx *ctx) { struct priv *p = ctx->priv; + GL *gl = &p->gl; CGLError err; CGLOpenGLProfile gl_versions[] = { @@ -132,60 +134,82 @@ static bool create_gl_context(struct MPGLContext *ctx, int vo_flags) vo_cocoa_set_opengl_ctx(ctx->vo, p->ctx); CGLSetCurrentContext(p->ctx); - if (vo_flags & VOFLAG_ALPHA) + if (ctx->opts.want_alpha) CGLSetParameter(p->ctx, kCGLCPSurfaceOpacity, &(GLint){0}); - mpgl_load_functions(ctx->gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log); + mpgl_load_functions(gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log); + gl->SwapInterval = set_swap_interval; CGLReleasePixelFormat(p->pix); return true; } -static void cocoa_uninit(MPGLContext *ctx) +static void cocoa_uninit(struct ra_ctx *ctx) { struct priv *p = ctx->priv; + ra_gl_ctx_uninit(ctx); CGLReleaseContext(p->ctx); vo_cocoa_uninit(ctx->vo); } -static int cocoa_init(MPGLContext *ctx, int vo_flags) +static void cocoa_swap_buffers(struct ra_ctx *ctx) { - struct priv *p = ctx->priv; + GL *gl = &p->gl; + vo_cocoa_swap_buffers(ctx->vo); + gl->Flush(); +} + +static bool cocoa_init(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv = talloc_zero(ctx, struct priv); + GL *gl = &p->gl; p->opts = mp_get_config_group(ctx, ctx->global, &cocoa_conf); vo_cocoa_init(ctx->vo); - if (!create_gl_context(ctx, vo_flags)) - return -1; + if (!create_gl_context(ctx)) + goto fail; - ctx->gl->SwapInterval = set_swap_interval; - return 0; + struct ra_gl_ctx_params params = { + .swap_buffers = cocoa_swap_buffers, + }; + + if (!ra_gl_ctx_init(ctx, gl, params)) + goto fail; + + return true; + +fail: + cocoa_uninit(ctx); + return false; } -static int cocoa_reconfig(struct MPGLContext *ctx) +static void resize(struct ra_ctx *ctx) +{ + ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0); +} + +static bool cocoa_reconfig(struct ra_ctx *ctx) { vo_cocoa_config_window(ctx->vo); - return 0; + resize(ctx); + return true; } -static int cocoa_control(struct MPGLContext *ctx, int *events, int request, +static int cocoa_control(struct ra_ctx *ctx, int *events, int request, void *arg) { - return vo_cocoa_control(ctx->vo, events, request, arg); + int ret = vo_cocoa_control(ctx->vo, events, request, arg); + if (*events & VO_EVENT_RESIZE) + resize(ctx); + return ret; } -static void cocoa_swap_buffers(struct MPGLContext *ctx) -{ - vo_cocoa_swap_buffers(ctx->vo); - ctx->gl->Flush(); -} - -const struct mpgl_driver mpgl_driver_cocoa = { +const struct ra_ctx_fns ra_ctx_cocoa = { + .type = "opengl", .name = "cocoa", - .priv_size = sizeof(struct priv), .init = cocoa_init, .reconfig = cocoa_reconfig, - .swap_buffers = cocoa_swap_buffers, .control = cocoa_control, .uninit = cocoa_uninit, }; diff --git a/video/out/opengl/context_dxinterop.c b/video/out/opengl/context_dxinterop.c index 507c150d15..85d84bf677 100644 --- a/video/out/opengl/context_dxinterop.c +++ b/video/out/opengl/context_dxinterop.c @@ -22,6 +22,7 @@ #include "osdep/windows_utils.h" #include "video/out/w32_common.h" #include "context.h" +#include "utils.h" // For WGL_ACCESS_WRITE_DISCARD_NV, etc. #include @@ -35,6 +36,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; #endif struct priv { + GL gl; + HMODULE d3d9_dll; HRESULT (WINAPI *Direct3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D); @@ -54,6 +57,7 @@ struct priv { // OpenGL resources GLuint texture; + GLuint main_fb; // Did we lose the device? bool lost_device; @@ -63,7 +67,7 @@ struct priv { int width, height, swapinterval; }; -static __thread struct MPGLContext *current_ctx; +static __thread struct ra_ctx *current_ctx; static void pump_message_loop(void) { @@ -84,10 +88,11 @@ static void *w32gpa(const GLubyte *procName) return GetProcAddress(oglmod, procName); } -static int os_ctx_create(struct MPGLContext *ctx) +static int os_ctx_create(struct ra_ctx *ctx) { static const wchar_t os_wnd_class[] = L"mpv offscreen gl"; struct priv *p = ctx->priv; + GL *gl = &p->gl; HGLRC legacy_context = NULL; RegisterClassExW(&(WNDCLASSEXW) { @@ -190,8 +195,8 @@ static int os_ctx_create(struct MPGLContext *ctx) goto fail; } - mpgl_load_functions(ctx->gl, w32gpa, wgl_exts, ctx->vo->log); - if (!(ctx->gl->mpgl_caps & MPGL_CAP_DXINTEROP)) { + mpgl_load_functions(gl, w32gpa, wgl_exts, ctx->vo->log); + if (!(gl->mpgl_caps & MPGL_CAP_DXINTEROP)) { MP_FATAL(ctx->vo, "WGL_NV_DX_interop is not supported\n"); goto fail; } @@ -205,7 +210,7 @@ fail: return -1; } -static void os_ctx_destroy(MPGLContext *ctx) +static void os_ctx_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -219,10 +224,10 @@ static void os_ctx_destroy(MPGLContext *ctx) DestroyWindow(p->os_wnd); } -static int d3d_size_dependent_create(MPGLContext *ctx) +static int d3d_size_dependent_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; + GL *gl = &p->gl; HRESULT hr; IDirect3DSwapChain9 *sw9; @@ -294,7 +299,7 @@ static int d3d_size_dependent_create(MPGLContext *ctx) return -1; } - gl->BindFramebuffer(GL_FRAMEBUFFER, ctx->main_fb); + gl->BindFramebuffer(GL_FRAMEBUFFER, p->main_fb); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p->texture, 0); gl->BindFramebuffer(GL_FRAMEBUFFER, 0); @@ -302,10 +307,10 @@ static int d3d_size_dependent_create(MPGLContext *ctx) return 0; } -static void d3d_size_dependent_destroy(MPGLContext *ctx) +static void d3d_size_dependent_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; + GL *gl = &p->gl; if (p->rtarget_h) { gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h); @@ -321,7 +326,8 @@ static void d3d_size_dependent_destroy(MPGLContext *ctx) SAFE_RELEASE(p->swapchain); } -static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams) +static void fill_presentparams(struct ra_ctx *ctx, + D3DPRESENT_PARAMETERS *pparams) { struct priv *p = ctx->priv; @@ -338,13 +344,9 @@ static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams) .Windowed = TRUE, .BackBufferWidth = ctx->vo->dwidth ? ctx->vo->dwidth : 1, .BackBufferHeight = ctx->vo->dheight ? ctx->vo->dheight : 1, - // The length of the backbuffer queue shouldn't affect latency because - // swap_buffers() always uses the backbuffer at the head of the queue - // and presents it immediately. MSDN says there is a performance - // penalty for having a short backbuffer queue and this seems to be - // true, at least on Nvidia, where less than four backbuffers causes - // very high CPU usage. Use six to be safe. - .BackBufferCount = 6, + // Add one frame for the backbuffer and one frame of "slack" to reduce + // contention with the window manager when acquiring the backbuffer + .BackBufferCount = ctx->opts.swapchain_depth + 2, .SwapEffect = IsWindows7OrGreater() ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_FLIP, // Automatically get the backbuffer format from the display format .BackBufferFormat = D3DFMT_UNKNOWN, @@ -353,10 +355,10 @@ static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams) }; } -static int d3d_create(MPGLContext *ctx) +static int d3d_create(struct ra_ctx *ctx) { struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; + GL *gl = &p->gl; HRESULT hr; p->d3d9_dll = LoadLibraryW(L"d3d9.dll"); @@ -396,8 +398,7 @@ static int d3d_create(MPGLContext *ctx) return -1; } - // mpv expects frames to be presented right after swap_buffers() returns - IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, 1); + IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, ctx->opts.swapchain_depth); // Register the Direct3D device with WGL_NV_dx_interop p->device_h = gl->DXOpenDeviceNV(p->device); @@ -410,10 +411,10 @@ static int d3d_create(MPGLContext *ctx) return 0; } -static void d3d_destroy(MPGLContext *ctx) +static void d3d_destroy(struct ra_ctx *ctx) { struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; + GL *gl = &p->gl; if (p->device_h) gl->DXCloseDeviceNV(p->device_h); @@ -423,8 +424,9 @@ static void d3d_destroy(MPGLContext *ctx) FreeLibrary(p->d3d9_dll); } -static void dxinterop_uninit(MPGLContext *ctx) +static void dxgl_uninit(struct ra_ctx *ctx) { + ra_gl_ctx_uninit(ctx); d3d_size_dependent_destroy(ctx); d3d_destroy(ctx); os_ctx_destroy(ctx); @@ -433,7 +435,7 @@ static void dxinterop_uninit(MPGLContext *ctx) pump_message_loop(); } -static void dxinterop_reset(struct MPGLContext *ctx) +static void dxgl_reset(struct ra_ctx *ctx) { struct priv *p = ctx->priv; HRESULT hr; @@ -468,18 +470,18 @@ static void dxinterop_reset(struct MPGLContext *ctx) p->lost_device = false; } -static int GLAPIENTRY dxinterop_swap_interval(int interval) +static int GLAPIENTRY dxgl_swap_interval(int interval) { if (!current_ctx) return 0; struct priv *p = current_ctx->priv; p->requested_swapinterval = interval; - dxinterop_reset(current_ctx); + dxgl_reset(current_ctx); return 1; } -static void * GLAPIENTRY dxinterop_get_native_display(const char *name) +static void * GLAPIENTRY dxgl_get_native_display(const char *name) { if (!current_ctx || !name) return NULL; @@ -493,60 +495,17 @@ static void * GLAPIENTRY dxinterop_get_native_display(const char *name) return NULL; } -static int dxinterop_init(struct MPGLContext *ctx, int flags) +static void dxgl_swap_buffers(struct ra_ctx *ctx) { struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; - - p->requested_swapinterval = 1; - - if (!vo_w32_init(ctx->vo)) - goto fail; - if (os_ctx_create(ctx) < 0) - goto fail; - - // Create the shared framebuffer - gl->GenFramebuffers(1, &ctx->main_fb); - - current_ctx = ctx; - gl->SwapInterval = dxinterop_swap_interval; - gl->MPGetNativeDisplay = dxinterop_get_native_display; - - if (d3d_create(ctx) < 0) - goto fail; - if (d3d_size_dependent_create(ctx) < 0) - goto fail; - - // The OpenGL and Direct3D coordinate systems are flipped vertically - // relative to each other. Flip the video during rendering so it can be - // copied to the Direct3D backbuffer with a simple (and fast) StretchRect. - ctx->flip_v = true; - - DwmEnableMMCSS(TRUE); - - return 0; -fail: - dxinterop_uninit(ctx); - return -1; -} - -static int dxinterop_reconfig(struct MPGLContext *ctx) -{ - vo_w32_config(ctx->vo); - return 0; -} - -static void dxinterop_swap_buffers(MPGLContext *ctx) -{ - struct priv *p = ctx->priv; - struct GL *gl = ctx->gl; + GL *gl = &p->gl; HRESULT hr; pump_message_loop(); // If the device is still lost, try to reset it again if (p->lost_device) - dxinterop_reset(ctx); + dxgl_reset(ctx); if (p->lost_device) return; @@ -571,7 +530,7 @@ static void dxinterop_swap_buffers(MPGLContext *ctx) case D3DERR_DEVICEHUNG: MP_VERBOSE(ctx->vo, "Direct3D device lost! Resetting.\n"); p->lost_device = true; - dxinterop_reset(ctx); + dxgl_reset(ctx); return; default: if (FAILED(hr)) @@ -584,21 +543,75 @@ static void dxinterop_swap_buffers(MPGLContext *ctx) } } -static int dxinterop_control(MPGLContext *ctx, int *events, int request, - void *arg) +static bool dxgl_init(struct ra_ctx *ctx) { - int r = vo_w32_control(ctx->vo, events, request, arg); - if (*events & VO_EVENT_RESIZE) - dxinterop_reset(ctx); - return r; + struct priv *p = ctx->priv = talloc_zero(ctx, struct priv); + GL *gl = &p->gl; + + p->requested_swapinterval = 1; + + if (!vo_w32_init(ctx->vo)) + goto fail; + if (os_ctx_create(ctx) < 0) + goto fail; + + // Create the shared framebuffer + gl->GenFramebuffers(1, &p->main_fb); + + current_ctx = ctx; + gl->SwapInterval = dxgl_swap_interval; + gl->MPGetNativeDisplay = dxgl_get_native_display; + + if (d3d_create(ctx) < 0) + goto fail; + if (d3d_size_dependent_create(ctx) < 0) + goto fail; + + static const struct ra_swapchain_fns empty_swapchain_fns = {0}; + struct ra_gl_ctx_params params = { + .swap_buffers = dxgl_swap_buffers, + .flipped = true, + .external_swapchain = &empty_swapchain_fns, + }; + + if (!ra_gl_ctx_init(ctx, gl, params)) + goto fail; + + DwmEnableMMCSS(TRUE); + return true; +fail: + dxgl_uninit(ctx); + return false; } -const struct mpgl_driver mpgl_driver_dxinterop = { +static void resize(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + dxgl_reset(ctx); + ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, p->main_fb); +} + +static bool dxgl_reconfig(struct ra_ctx *ctx) +{ + vo_w32_config(ctx->vo); + resize(ctx); + return true; +} + +static int dxgl_control(struct ra_ctx *ctx, int *events, int request, + void *arg) +{ + int ret = vo_w32_control(ctx->vo, events, request, arg); + if (*events & VO_EVENT_RESIZE) + resize(ctx); + return ret; +} + +const struct ra_ctx_fns ra_ctx_dxgl = { + .type = "opengl", .name = "dxinterop", - .priv_size = sizeof(struct priv), - .init = dxinterop_init, - .reconfig = dxinterop_reconfig, - .swap_buffers = dxinterop_swap_buffers, - .control = dxinterop_control, - .uninit = dxinterop_uninit, + .init = dxgl_init, + .reconfig = dxgl_reconfig, + .control = dxgl_control, + .uninit = dxgl_uninit, }; diff --git a/video/out/opengl/context_w32.c b/video/out/opengl/context_win.c similarity index 67% rename from video/out/opengl/context_w32.c rename to video/out/opengl/context_win.c index eb6123967b..e650867feb 100644 --- a/video/out/opengl/context_w32.c +++ b/video/out/opengl/context_win.c @@ -23,6 +23,7 @@ #include "video/out/w32_common.h" #include "video/out/win32/exclusive_hack.h" #include "context.h" +#include "utils.h" #if !defined(WGL_CONTEXT_MAJOR_VERSION_ARB) /* these are supposed to be defined in wingdi.h but mingw's is too old */ @@ -37,7 +38,9 @@ #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #endif -struct w32_context { +struct priv { + GL gl; + int opt_swapinterval; int current_swapinterval; @@ -45,26 +48,25 @@ struct w32_context { HGLRC context; HDC hdc; - int flags; }; -static void w32_uninit(MPGLContext *ctx); +static void wgl_uninit(struct ra_ctx *ctx); -static __thread struct w32_context *current_w32_context; +static __thread struct priv *current_wgl_context; -static int GLAPIENTRY w32_swap_interval(int interval) +static int GLAPIENTRY wgl_swap_interval(int interval) { - if (current_w32_context) - current_w32_context->opt_swapinterval = interval; + if (current_wgl_context) + current_wgl_context->opt_swapinterval = interval; return 0; } -static bool create_dc(struct MPGLContext *ctx, int flags) +static bool create_dc(struct ra_ctx *ctx) { - struct w32_context *w32_ctx = ctx->priv; + struct priv *p = ctx->priv; HWND win = vo_w32_hwnd(ctx->vo); - if (w32_ctx->hdc) + if (p->hdc) return true; HDC hdc = GetDC(win); @@ -90,11 +92,11 @@ static bool create_dc(struct MPGLContext *ctx, int flags) SetPixelFormat(hdc, pf, &pfd); - w32_ctx->hdc = hdc; + p->hdc = hdc; return true; } -static void *w32gpa(const GLubyte *procName) +static void *wglgpa(const GLubyte *procName) { HMODULE oglmod; void *res = wglGetProcAddress(procName); @@ -104,11 +106,11 @@ static void *w32gpa(const GLubyte *procName) return GetProcAddress(oglmod, procName); } -static bool create_context_w32_old(struct MPGLContext *ctx) +static bool create_context_wgl_old(struct ra_ctx *ctx) { - struct w32_context *w32_ctx = ctx->priv; + struct priv *p = ctx->priv; - HDC windc = w32_ctx->hdc; + HDC windc = p->hdc; bool res = false; HGLRC context = wglCreateContext(windc); @@ -123,17 +125,15 @@ static bool create_context_w32_old(struct MPGLContext *ctx) return res; } - w32_ctx->context = context; - - mpgl_load_functions(ctx->gl, w32gpa, NULL, ctx->vo->log); + p->context = context; return true; } -static bool create_context_w32_gl3(struct MPGLContext *ctx) +static bool create_context_wgl_gl3(struct ra_ctx *ctx) { - struct w32_context *w32_ctx = ctx->priv; + struct priv *p = ctx->priv; - HDC windc = w32_ctx->hdc; + HDC windc = p->hdc; HGLRC context = 0; // A legacy context is needed to get access to the new functions. @@ -150,7 +150,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx) } const char *(GLAPIENTRY *wglGetExtensionsStringARB)(HDC hdc) - = w32gpa((const GLubyte*)"wglGetExtensionsStringARB"); + = wglgpa((const GLubyte*)"wglGetExtensionsStringARB"); if (!wglGetExtensionsStringARB) goto unsupported; @@ -161,7 +161,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx) HGLRC (GLAPIENTRY *wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList) - = w32gpa((const GLubyte*)"wglCreateContextAttribsARB"); + = wglgpa((const GLubyte*)"wglCreateContextAttribsARB"); if (!wglCreateContextAttribsARB) goto unsupported; @@ -197,11 +197,7 @@ static bool create_context_w32_gl3(struct MPGLContext *ctx) return false; } - w32_ctx->context = context; - - /* update function pointers */ - mpgl_load_functions(ctx->gl, w32gpa, NULL, ctx->vo->log); - + p->context = context; return true; unsupported: @@ -214,79 +210,20 @@ out: static void create_ctx(void *ptr) { - struct MPGLContext *ctx = ptr; - struct w32_context *w32_ctx = ctx->priv; + struct ra_ctx *ctx = ptr; + struct priv *p = ctx->priv; - if (!create_dc(ctx, w32_ctx->flags)) + if (!create_dc(ctx)) return; - create_context_w32_gl3(ctx); - if (!w32_ctx->context) - create_context_w32_old(ctx); + create_context_wgl_gl3(ctx); + if (!p->context) + create_context_wgl_old(ctx); - wglMakeCurrent(w32_ctx->hdc, NULL); + wglMakeCurrent(p->hdc, NULL); } -static int w32_init(struct MPGLContext *ctx, int flags) -{ - if (!vo_w32_init(ctx->vo)) - goto fail; - - struct w32_context *w32_ctx = ctx->priv; - - w32_ctx->flags = flags; - vo_w32_run_on_thread(ctx->vo, create_ctx, ctx); - - if (!w32_ctx->context) - goto fail; - - if (!ctx->gl->SwapInterval) - MP_VERBOSE(ctx->vo, "WGL_EXT_swap_control missing.\n"); - w32_ctx->real_wglSwapInterval = ctx->gl->SwapInterval; - ctx->gl->SwapInterval = w32_swap_interval; - w32_ctx->current_swapinterval = -1; - - current_w32_context = w32_ctx; - wglMakeCurrent(w32_ctx->hdc, w32_ctx->context); - DwmEnableMMCSS(TRUE); - return 0; - -fail: - w32_uninit(ctx); - return -1; -} - -static int w32_reconfig(struct MPGLContext *ctx) -{ - vo_w32_config(ctx->vo); - return 0; -} - -static void destroy_gl(void *ptr) -{ - struct MPGLContext *ctx = ptr; - struct w32_context *w32_ctx = ctx->priv; - if (w32_ctx->context) - wglDeleteContext(w32_ctx->context); - w32_ctx->context = 0; - if (w32_ctx->hdc) - ReleaseDC(vo_w32_hwnd(ctx->vo), w32_ctx->hdc); - w32_ctx->hdc = NULL; - current_w32_context = NULL; -} - -static void w32_uninit(MPGLContext *ctx) -{ - struct w32_context *w32_ctx = ctx->priv; - if (w32_ctx->context) - wglMakeCurrent(w32_ctx->hdc, 0); - vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx); - - DwmEnableMMCSS(FALSE); - vo_w32_uninit(ctx->vo); -} - -static bool compositor_active(MPGLContext *ctx) +static bool compositor_active(struct ra_ctx *ctx) { // For Windows 7. BOOL enabled = 0; @@ -308,13 +245,13 @@ static bool compositor_active(MPGLContext *ctx) return true; } -static void w32_swap_buffers(MPGLContext *ctx) +static void wgl_swap_buffers(struct ra_ctx *ctx) { - struct w32_context *w32_ctx = ctx->priv; - SwapBuffers(w32_ctx->hdc); + struct priv *p = ctx->priv; + SwapBuffers(p->hdc); // default if we don't DwmFLush - int new_swapinterval = w32_ctx->opt_swapinterval; + int new_swapinterval = p->opt_swapinterval; int dwm_flush_opt; mp_read_option_raw(ctx->global, "opengl-dwmflush", &m_option_type_choice, @@ -330,26 +267,103 @@ static void w32_swap_buffers(MPGLContext *ctx) } } - if (new_swapinterval != w32_ctx->current_swapinterval && - w32_ctx->real_wglSwapInterval) + if (new_swapinterval != p->current_swapinterval && + p->real_wglSwapInterval) { - w32_ctx->real_wglSwapInterval(new_swapinterval); + p->real_wglSwapInterval(new_swapinterval); MP_VERBOSE(ctx->vo, "set SwapInterval(%d)\n", new_swapinterval); } - w32_ctx->current_swapinterval = new_swapinterval; + p->current_swapinterval = new_swapinterval; } -static int w32_control(MPGLContext *ctx, int *events, int request, void *arg) +static bool wgl_init(struct ra_ctx *ctx) { - return vo_w32_control(ctx->vo, events, request, arg); + struct priv *p = ctx->priv = talloc_zero(ctx, struct priv); + GL *gl = &p->gl; + + if (!vo_w32_init(ctx->vo)) + goto fail; + + vo_w32_run_on_thread(ctx->vo, create_ctx, ctx); + if (!p->context) + goto fail; + + current_wgl_context = p; + wglMakeCurrent(p->hdc, p->context); + + mpgl_load_functions(gl, wglgpa, NULL, ctx->vo->log); + + if (!gl->SwapInterval) + MP_VERBOSE(ctx->vo, "WGL_EXT_swap_control missing.\n"); + p->real_wglSwapInterval = gl->SwapInterval; + gl->SwapInterval = wgl_swap_interval; + p->current_swapinterval = -1; + + struct ra_gl_ctx_params params = { + .swap_buffers = wgl_swap_buffers, + }; + + if (!ra_gl_ctx_init(ctx, gl, params)) + goto fail; + + DwmEnableMMCSS(TRUE); + return true; + +fail: + wgl_uninit(ctx); + return false; } -const struct mpgl_driver mpgl_driver_w32 = { +static void resize(struct ra_ctx *ctx) +{ + ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0); +} + +static bool wgl_reconfig(struct ra_ctx *ctx) +{ + vo_w32_config(ctx->vo); + resize(ctx); + return true; +} + +static void destroy_gl(void *ptr) +{ + struct ra_ctx *ctx = ptr; + struct priv *p = ctx->priv; + if (p->context) + wglDeleteContext(p->context); + p->context = 0; + if (p->hdc) + ReleaseDC(vo_w32_hwnd(ctx->vo), p->hdc); + p->hdc = NULL; + current_wgl_context = NULL; +} + +static void wgl_uninit(struct ra_ctx *ctx) +{ + struct priv *p = ctx->priv; + ra_gl_ctx_uninit(ctx); + if (p->context) + wglMakeCurrent(p->hdc, 0); + vo_w32_run_on_thread(ctx->vo, destroy_gl, ctx); + + DwmEnableMMCSS(FALSE); + vo_w32_uninit(ctx->vo); +} + +static int wgl_control(struct ra_ctx *ctx, int *events, int request, void *arg) +{ + int ret = vo_w32_control(ctx->vo, events, request, arg); + if (*events & VO_EVENT_RESIZE) + resize(ctx); + return ret; +} + +const struct ra_ctx_fns ra_ctx_wgl = { + .type = "opengl", .name = "win", - .priv_size = sizeof(struct w32_context), - .init = w32_init, - .reconfig = w32_reconfig, - .swap_buffers = w32_swap_buffers, - .control = w32_control, - .uninit = w32_uninit, + .init = wgl_init, + .reconfig = wgl_reconfig, + .control = wgl_control, + .uninit = wgl_uninit, }; diff --git a/video/out/opengl/hwdec_d3d11egl.c b/video/out/opengl/hwdec_d3d11egl.c index 3988f8310e..0597fbbb12 100644 --- a/video/out/opengl/hwdec_d3d11egl.c +++ b/video/out/opengl/hwdec_d3d11egl.c @@ -27,7 +27,7 @@ #include "common/common.h" #include "osdep/timer.h" #include "osdep/windows_utils.h" -#include "hwdec.h" +#include "video/out/gpu/hwdec.h" #include "ra_gl.h" #include "video/hwdec.h" #include "video/decode/d3d.h" diff --git a/video/out/opengl/hwdec_d3d11eglrgb.c b/video/out/opengl/hwdec_d3d11eglrgb.c index fa3976fec6..46264ac1bf 100644 --- a/video/out/opengl/hwdec_d3d11eglrgb.c +++ b/video/out/opengl/hwdec_d3d11eglrgb.c @@ -27,7 +27,7 @@ #include "common/common.h" #include "osdep/timer.h" #include "osdep/windows_utils.h" -#include "hwdec.h" +#include "video/out/gpu/hwdec.h" #include "ra_gl.h" #include "video/hwdec.h" #include "video/decode/d3d.h" diff --git a/video/out/opengl/hwdec_dxva2egl.c b/video/out/opengl/hwdec_dxva2egl.c index 01fb482325..6a92eb8934 100644 --- a/video/out/opengl/hwdec_dxva2egl.c +++ b/video/out/opengl/hwdec_dxva2egl.c @@ -27,7 +27,7 @@ #include "common/common.h" #include "osdep/timer.h" #include "osdep/windows_utils.h" -#include "hwdec.h" +#include "video/out/gpu/hwdec.h" #include "ra_gl.h" #include "video/hwdec.h" #include "video/decode/d3d.h" diff --git a/video/out/opengl/hwdec_dxva2gldx.c b/video/out/opengl/hwdec_dxva2gldx.c index fd9c80b7a2..0b3e30fbb1 100644 --- a/video/out/opengl/hwdec_dxva2gldx.c +++ b/video/out/opengl/hwdec_dxva2gldx.c @@ -20,7 +20,7 @@ #include "common/common.h" #include "osdep/windows_utils.h" -#include "hwdec.h" +#include "video/out/gpu/hwdec.h" #include "ra_gl.h" #include "video/hwdec.h" #include "video/decode/d3d.h" diff --git a/wscript_build.py b/wscript_build.py index 8dab6012c0..1e7a6ee357 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -400,25 +400,25 @@ def build(ctx): ( "video/out/opengl/utils.c", "gl" ), ( "video/out/opengl/ra_gl.c", "gl" ), ( "video/out/opengl/context.c", "gl" ), -# ( "video/out/opengl/context_angle.c", "egl-angle-win32" ), -# ( "video/out/opengl/context_cocoa.c", "gl-cocoa" ), + ( "video/out/opengl/context_angle.c", "egl-angle-win32" ), + ( "video/out/opengl/context_cocoa.c", "gl-cocoa" ), ( "video/out/opengl/context_drm_egl.c", "egl-drm" ), -# ( "video/out/opengl/context_dxinterop.c","gl-dxinterop" ), + ( "video/out/opengl/context_dxinterop.c","gl-dxinterop" ), ( "video/out/opengl/context_mali_fbdev.c","mali-fbdev" ), ( "video/out/opengl/context_rpi.c", "rpi" ), ( "video/out/opengl/context_vdpau.c", "vdpau-gl-x11" ), ( "video/out/opengl/context_wayland.c", "gl-wayland" ), -# ( "video/out/opengl/context_w32.c", "gl-win32" ), + ( "video/out/opengl/context_win.c", "gl-win32" ), ( "video/out/opengl/context_glx.c", "gl-x11" ), ( "video/out/opengl/context_x11egl.c", "egl-x11" ), ( "video/out/opengl/cuda_dynamic.c", "cuda-hwaccel" ), -# ( "video/out/opengl/d3d11_helpers.c", "egl-angle-win32" ), + ( "video/out/opengl/d3d11_helpers.c", "egl-angle-win32" ), ( "video/out/opengl/egl_helpers.c", "egl-helpers" ), ( "video/out/opengl/hwdec_cuda.c", "cuda-hwaccel" ), -# ( "video/out/opengl/hwdec_d3d11egl.c", "d3d-hwaccel" ), -# ( "video/out/opengl/hwdec_d3d11eglrgb.c","d3d-hwaccel" ), -# ( "video/out/opengl/hwdec_dxva2gldx.c", "gl-dxinterop-d3d9" ), -# ( "video/out/opengl/hwdec_dxva2egl.c", "d3d9-hwaccel" ), + ( "video/out/opengl/hwdec_d3d11egl.c", "d3d-hwaccel" ), + ( "video/out/opengl/hwdec_d3d11eglrgb.c","d3d-hwaccel" ), + ( "video/out/opengl/hwdec_dxva2gldx.c", "gl-dxinterop-d3d9" ), + ( "video/out/opengl/hwdec_dxva2egl.c", "d3d9-hwaccel" ), ( "video/out/opengl/hwdec_osx.c", "videotoolbox-gl" ), ( "video/out/opengl/hwdec_ios.m", "ios-gl" ), ( "video/out/opengl/hwdec_rpi.c", "rpi" ),