summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossymiles@gmail.com>2015-12-14 00:54:57 +1100
committerJames Ross-Gowan <rossymiles@gmail.com>2015-12-14 23:09:54 +1100
commitd0fd68f6dfeac03d07a005f230cdec0756636075 (patch)
treeb844f6a2c50eee4b9586484a0730f4b13ca57240
parent8d0a6cd03560ed8d20efb57c5e38a980380a1a1e (diff)
downloadmpv-d0fd68f6dfeac03d07a005f230cdec0756636075.tar.bz2
mpv-d0fd68f6dfeac03d07a005f230cdec0756636075.tar.xz
vo_opengl: dxinterop: prevent crash after lost device
When a Direct3D 9Ex device fails to reset, it gets put into the lost state, so set the lost_device flag and don't attempt to present until the device moves out of that state. Failure to recreate the size- dependent objects should set lost_device as well, since we shouldn't try to present in that state. Also, it looks like I was too eager to remove code that sets priv members to NULL and I accidentally removed some that was needed.
-rw-r--r--video/out/opengl/dxinterop.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/video/out/opengl/dxinterop.c b/video/out/opengl/dxinterop.c
index bfbde88182..bc302629aa 100644
--- a/video/out/opengl/dxinterop.c
+++ b/video/out/opengl/dxinterop.c
@@ -341,14 +341,19 @@ static void d3d_size_dependent_destroy(MPGLContext *ctx)
gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h);
gl->DXUnregisterObjectNV(p->device_h, p->rtarget_h);
}
+ p->rtarget_h = 0;
if (p->texture)
gl->DeleteTextures(1, &p->texture);
+ p->texture = 0;
if (p->rtarget)
IDirect3DSurface9_Release(p->rtarget);
+ p->rtarget = NULL;
if (p->backbuffer)
IDirect3DSurface9_Release(p->backbuffer);
+ p->backbuffer = NULL;
if (p->swapchain)
IDirect3DSwapChain9Ex_Release(p->swapchain);
+ p->swapchain = NULL;
}
static void fill_presentparams(MPGLContext *ctx, D3DPRESENT_PARAMETERS *pparams)
@@ -500,11 +505,13 @@ static void dxinterop_reset(struct MPGLContext *ctx)
hr = IDirect3DDevice9Ex_ResetEx(p->device, &pparams, NULL);
if (FAILED(hr)) {
+ p->lost_device = true;
MP_FATAL(ctx->vo, "Couldn't reset device\n");
return;
}
if (d3d_size_dependent_create(ctx) < 0) {
+ p->lost_device = true;
MP_FATAL(ctx->vo, "Couldn't recreate Direct3D objects after reset\n");
return;
}
@@ -585,6 +592,12 @@ static void dxinterop_swap_buffers(MPGLContext *ctx)
pump_message_loop();
+ // If the device is still lost, try to reset it again
+ if (p->lost_device)
+ dxinterop_reset(ctx);
+ if (p->lost_device)
+ return;
+
if (!gl->DXUnlockObjectsNV(p->device_h, 1, &p->rtarget_h)) {
MP_FATAL(ctx->vo, "Couldn't unlock rendertarget for present\n");
return;