From e1e9b6ef1c460da98bde3c0de179bd6a7790d3dd Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Tue, 24 Oct 2017 21:40:45 +0900 Subject: win32: recover from D3DERR_DEVICELOST --- pacc/pacc-d3d9.c | 47 ++++++++++++++++++++++++++++++++--------------- pacc/pacc-win.h | 2 +- 2 files changed, 33 insertions(+), 16 deletions(-) (limited to 'pacc') diff --git a/pacc/pacc-d3d9.c b/pacc/pacc-d3d9.c index e645366..df78f6a 100644 --- a/pacc/pacc-d3d9.c +++ b/pacc/pacc-d3d9.c @@ -412,23 +412,39 @@ static void pacc_delete(struct pacc_ctx *pc) { static DWORD WINAPI pacc_renderproc(void *ptr) { struct pacc_ctx *pc = ptr; + bool waitdevice = false; while (!atomic_load_explicit(&pc->killthread, memory_order_relaxed)) { if (WaitForSingleObject(pc->rendermtx, INFINITE) == WAIT_OBJECT_0) { - if (SUCCEEDED(pc->d3d9d->lpVtbl->BeginScene(pc->d3d9d))) { - if (pc->render_enabled) { - pc->rendercb(pc->renderptr); + if (!waitdevice) { + HRESULT r = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d); + if (r != D3D_OK) { + waitdevice = true; } else { - pc->d3d9d->lpVtbl->Clear( - pc->d3d9d, - 0, 0, D3DCLEAR_TARGET, - D3DCOLOR_RGBA(0x00, 0x00, 0x00, 0xff), - 1.0, 0); + if (SUCCEEDED(pc->d3d9d->lpVtbl->BeginScene(pc->d3d9d))) { + if (pc->render_enabled) { + pc->rendercb(pc->renderptr); + } else { + pc->d3d9d->lpVtbl->Clear( + pc->d3d9d, + 0, 0, D3DCLEAR_TARGET, + D3DCOLOR_RGBA(0x00, 0x00, 0x00, 0xff), + 1.0, 0); + } + pc->d3d9d->lpVtbl->EndScene(pc->d3d9d); + HRESULT res = pc->d3d9d->lpVtbl->Present(pc->d3d9d, 0, 0, 0, 0); + if (res == D3DERR_DEVICELOST) { + waitdevice = true; + } + } } - pc->d3d9d->lpVtbl->EndScene(pc->d3d9d); - HRESULT res = pc->d3d9d->lpVtbl->Present(pc->d3d9d, 0, 0, 0, 0); - if (res == D3DERR_DEVICELOST) { + } else { + HRESULT r = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d); + if (r == D3DERR_DEVICENOTRESET) { PostMessage(pc->msg_wnd, pc->msg_reset, 0, 0); + ReleaseMutex(pc->rendermtx); + return 0; } + Sleep(100); } ReleaseMutex(pc->rendermtx); } @@ -467,16 +483,15 @@ struct pacc_win_vtable pacc_win_vtable = { struct pacc_ctx *pacc_init_d3d9( HWND hwnd, + int w, int h, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt, UINT msg_reset, HWND msg_wnd) { struct pacc_ctx *pc = malloc(sizeof(*pc)); if (!pc) goto err; - RECT wr; - if (!GetClientRect(hwnd, &wr)) goto err; *pc = (struct pacc_ctx) { - .w = wr.right - wr.left, - .h = wr.bottom - wr.top, + .w = w, + .h = h, .hwnd = hwnd, .rendercb = rendercb, .renderptr = renderptr, @@ -540,6 +555,8 @@ struct pacc_ctx *pacc_init_d3d9( &pc->tex_pal, 0); if (res != D3D_OK) goto err; + res = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d); + if (res != D3D_OK) goto err; D3DVERTEXELEMENT9 vertexdecls[] = { { diff --git a/pacc/pacc-win.h b/pacc/pacc-win.h index e8bacc1..e96010a 100644 --- a/pacc/pacc-win.h +++ b/pacc/pacc-win.h @@ -15,7 +15,7 @@ struct pacc_win_vtable { void (*renderctrl)(struct pacc_ctx *ctx, bool enable); }; -struct pacc_ctx *pacc_init_d3d9(HWND hwnd, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt, UINT msg_reset, HWND msg_wnd); +struct pacc_ctx *pacc_init_d3d9(HWND hwnd, int w, int h, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt, UINT msg_reset, HWND msg_wnd); #endif // MYON_PACC_WIN_H_INCLUDED -- cgit v1.2.3