From d0fd68f6dfeac03d07a005f230cdec0756636075 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Mon, 14 Dec 2015 00:54:57 +1100 Subject: 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. --- video/out/opengl/dxinterop.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'video') 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; -- cgit v1.2.3