diff options
author | James Ross-Gowan <rossymiles@gmail.com> | 2017-05-16 21:10:09 +1000 |
---|---|---|
committer | James Ross-Gowan <rossymiles@gmail.com> | 2017-05-16 22:59:15 +1000 |
commit | 6a000598504b60a198236eae93f08801dd6ebeb7 (patch) | |
tree | 98c1af3dbf12bdbcc389b236f091567057383f63 | |
parent | 858bcea5b468641bfa1636805d0ef1323ea8bafd (diff) |
context_angle: fix fallback to D3D9 device
This was broken in e0250b9604b2. In some cases, device creation will
succeed, but creating an EGL context on the device will fail. With
--angle-renderer=auto, it should try to create the context again on a
D3D9 device.
This fixes mpv in Windows Vista on VirtualBox for me.
-rw-r--r-- | video/out/opengl/context_angle.c | 86 |
1 files changed, 56 insertions, 30 deletions
diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c index 3e227f93f8..13e29c410e 100644 --- a/video/out/opengl/context_angle.c +++ b/video/out/opengl/context_angle.c @@ -578,6 +578,44 @@ fail: return false; } +static void context_destroy(struct MPGLContext *ctx) +{ + struct priv *p = ctx->priv; + if (p->egl_context) { + eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + eglDestroyContext(p->egl_display, p->egl_context); + } + p->egl_context = EGL_NO_CONTEXT; +} + +static bool context_init(struct MPGLContext *ctx, int flags) +{ + struct priv *p = ctx->priv; + struct vo *vo = ctx->vo; + + if (!eglInitialize(p->egl_display, NULL, NULL)) { + MP_FATAL(vo, "Couldn't initialize EGL\n"); + goto fail; + } + + const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); + 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)) + { + MP_FATAL(vo, "Could not create EGL context!\n"); + goto fail; + } + + return true; +fail: + context_destroy(ctx); + return false; +} + static void angle_uninit(struct MPGLContext *ctx) { struct priv *p = ctx->priv; @@ -593,12 +631,7 @@ static void angle_uninit(struct MPGLContext *ctx) else egl_window_surface_destroy(ctx); - if (p->egl_context) { - eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglDestroyContext(p->egl_display, p->egl_context); - } - p->egl_context = EGL_NO_CONTEXT; + context_destroy(ctx); // Uninit the EGL device implementation that is being used if (p->d3d11_device) @@ -640,41 +673,34 @@ static int angle_init(struct MPGLContext *ctx, int flags) } // Create the underlying EGL device implementation - bool device_ok = false; - if ((!device_ok && !o->renderer) || o->renderer == RENDERER_D3D11) { - device_ok = d3d11_device_create(ctx, flags); - if (device_ok) { + bool context_ok = false; + if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D11) { + context_ok = d3d11_device_create(ctx, flags); + if (context_ok) { MP_VERBOSE(vo, "Using Direct3D 11 feature level %u_%u\n", ((unsigned)p->d3d11_level) >> 12, (((unsigned)p->d3d11_level) >> 8) & 0xf); + + context_ok = context_init(ctx, flags); + if (!context_ok) + d3d11_device_destroy(ctx); } } - if ((!device_ok && !o->renderer) || o->renderer == RENDERER_D3D9) { - device_ok = d3d9_device_create(ctx, flags); - if (device_ok) + if ((!context_ok && !o->renderer) || o->renderer == RENDERER_D3D9) { + context_ok = d3d9_device_create(ctx, flags); + if (context_ok) { MP_VERBOSE(vo, "Using Direct3D 9\n"); - } - if (!device_ok) - goto fail; - if (!eglInitialize(p->egl_display, NULL, NULL)) { - MP_FATAL(vo, "Couldn't initialize EGL\n"); - return false; + context_ok = context_init(ctx, flags); + if (!context_ok) + d3d9_device_destroy(ctx); + } } - - if (!vo_w32_init(vo)) + if (!context_ok) goto fail; - const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); - if (exts) - MP_DBG(ctx->vo, "EGL extensions: %s\n", exts); - - if (!mpegl_create_context(p->egl_display, vo->log, flags | VOFLAG_GLES, - &p->egl_context, &p->egl_config)) - { - MP_FATAL(vo, "Could not create EGL context!\n"); + if (!vo_w32_init(vo)) goto fail; - } // Create the underlying EGL surface implementation bool surface_ok = false; |