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 +- win32/about.c | 9 ++++----- win32/fmplayer.mak | 3 +-- win32/main.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ 5 files changed, 78 insertions(+), 35 deletions(-) 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 diff --git a/win32/about.c b/win32/about.c index b2013a1..c6c1e7c 100644 --- a/win32/about.c +++ b/win32/about.c @@ -41,13 +41,11 @@ static void update_status(void) { L"Audio API: %ls\r\n" "ym2608_adpcm_rom.bin: %lsavailable\r\n" "font.rom: %ls\r\n" - "SSE2 (for SIMD SSG resampling): %lsavailable\r\n" - "SSSE3 (for SIMD FMDSP palette lookup): %lsavailable", + "SSE2 (for SIMD SSG resampling): %lsavailable", g.soundapiname ? g.soundapiname : L"", g.adpcm_rom ? L"" : L"un", g.font_rom ? L"available" : L"unavailable, using MS Gothic", - __builtin_cpu_supports("sse2") ? L"" : L"un", - __builtin_cpu_supports("ssse3") ? L"" : L"un"); + __builtin_cpu_supports("sse2") ? L"" : L"un"); SetWindowText(g.static_info, buf); } @@ -95,6 +93,7 @@ static bool on_create(HWND hwnd, const CREATESTRUCT *cs) { update_status(); g.static_help = CreateWindowEx(0, L"static", L"F11: toggle track display page\r\n" + "Shift+F11: toggle right display page\r\n" "F12: display FMDSP at 2x\r\n" "Ctrl+F1-F10: FMDSP color palette\r\n\r\n" "1-9,0,-: toggle track mask (Ctrl: PPZ8)\r\n" @@ -102,7 +101,7 @@ static bool on_create(HWND hwnd, const CREATESTRUCT *cs) { "=: invert all mask\r\n" "\\: all tracks on", WS_CHILD | WS_VISIBLE, - 75, 165, 400, 200, + 75, 150, 400, 215, hwnd, 0, g.hinst, 0); SetWindowFont(g.static_help, g.font, TRUE); g.static_main = CreateWindowEx(0, L"static", diff --git a/win32/fmplayer.mak b/win32/fmplayer.mak index 87c9c41..1fc8d7c 100644 --- a/win32/fmplayer.mak +++ b/win32/fmplayer.mak @@ -23,8 +23,7 @@ FMDSP_OBJS=fmdsp-pacc \ fmdsp_platform_win \ font_fmdsp_small TONEDATA_OBJS=tonedata -SSEOBJBASE=opnassg-sinc-sse2 \ - fmdsp-vramlookup-ssse3 +SSEOBJBASE=opnassg-sinc-sse2 OBJBASE=main \ fft \ toneview \ diff --git a/win32/main.c b/win32/main.c index e3fb702..8bee805 100644 --- a/win32/main.c +++ b/win32/main.c @@ -40,7 +40,7 @@ enum { }; enum { - WM_PACC_RESET = WM_USER, + WM_PACC_RESET = WM_APP, }; #define FMPLAYER_CLASSNAME L"myon_fmplayer_ym2608_win32" @@ -70,6 +70,7 @@ static struct { bool paused; HWND mainwnd; HWND fmdspwnd; + ATOM fmdspwndclass; WNDPROC btn_defproc; HWND button_2x, button_toneview, button_oscilloview, button_about, button_config; bool toneview_on, oscilloview_on, about_on, config_on; @@ -428,7 +429,7 @@ static LRESULT CALLBACK btn_wndproc( static bool on_create(HWND hwnd, CREATESTRUCT *cs) { (void)cs; g.fmdspwnd = CreateWindowEx( - 0, L"static", 0, + 0, MAKEINTATOM(g.fmdspwndclass), 0, WS_VISIBLE | WS_CHILD, 0, 80, PC98_W, PC98_H, @@ -685,6 +686,16 @@ static void on_activate(HWND hwnd, bool activate, HWND targetwnd, WINBOOL state) else g_currentdlg = 0; } +static void render_cb(void *ptr) { + (void)ptr; + if (!atomic_flag_test_and_set_explicit( + &g.at_fftdata_flag, memory_order_acquire)) { + memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata.fdata)); + atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release); + } + fmdsp_pacc_render(g.fp); +} + static LRESULT CALLBACK wndproc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { @@ -708,7 +719,22 @@ static LRESULT CALLBACK wndproc( } break; case WM_PACC_RESET: - // TODO + if (g.pc) { + g.pacc_win.renderctrl(g.pc, false); + fmdsp_pacc_deinit(g.fp); + g.pacc.pacc_delete(g.pc); + g.pc = 0; + } + g.pc = pacc_init_d3d9(g.fmdspwnd, PC98_W, PC98_H, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd); + if (!g.pc) { + break; + } + if (!fmdsp_pacc_init(g.fp, g.pc, &g.pacc)) { + break; + } + fmdsp_pacc_set_font16(g.fp, &g.font); + fmdsp_pacc_set(g.fp, &g.work, &g.opna, &g.fftdata); + g.pacc_win.renderctrl(g.pc, true); break; } return DefWindowProc(hwnd, msg, wParam, lParam); @@ -726,14 +752,15 @@ static ATOM register_class(HINSTANCE hinst) { return RegisterClass(&wc); } -static void render_cb(void *ptr) { - (void)ptr; - if (!atomic_flag_test_and_set_explicit( - &g.at_fftdata_flag, memory_order_acquire)) { - memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata.fdata)); - atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release); - } - fmdsp_pacc_render(g.fp); +static ATOM register_fmdsp_class(HINSTANCE hinst) { + WNDCLASS wc = {0}; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = DefWindowProc; + wc.hInstance = hinst; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hbrBackground = 0; + wc.lpszClassName = FMPLAYER_CLASSNAME "fmdsp"; + return RegisterClass(&wc); } int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst, @@ -775,6 +802,7 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst, g.hinst = hinst; g.heap = GetProcessHeap(); ATOM wcatom = register_class(g.hinst); + g.fmdspwndclass = register_fmdsp_class(g.hinst); DWORD style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN; DWORD exStyle = 0; RECT wr; @@ -796,7 +824,7 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst, wr.right-wr.left, wr.bottom-wr.top, 0, 0, g.hinst, 0 ); - g.pc = pacc_init_d3d9(g.fmdspwnd, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd); + g.pc = pacc_init_d3d9(g.fmdspwnd, PC98_W, PC98_H, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd); if (!g.pc) { MessageBox(g.mainwnd, L"Error", L"Cannot initialize Direct3D", MB_ICONSTOP); return 0; -- cgit v1.2.3