From 328f2fb4414b772a110f5703ec64f097b77a073a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 20 May 2018 19:35:18 +0300 Subject: [PATCH] Fix screen update issue, for example hardware emulated boards didn't refresh properly. --- drawing.cpp | 16 +++++++++++++- gfxboard.cpp | 14 +++--------- include/drawing.h | 3 ++- include/gfxboard.h | 2 +- mame/a2410.cpp | 20 ++++++++--------- od-win32/direct3d.cpp | 46 +++++++++++++++++++++++---------------- od-win32/direct3d.h | 2 +- od-win32/direct3d11.cpp | 37 ++++++++++++++++--------------- od-win32/win32.cpp | 15 ++++++++----- od-win32/win32_scaler.cpp | 2 +- od-win32/win32gui.cpp | 2 +- 11 files changed, 90 insertions(+), 69 deletions(-) diff --git a/drawing.cpp b/drawing.cpp index 2150fc54..a5d34380 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -51,6 +51,7 @@ happening, all ports should restrict window widths to be multiples of 16 pixels. #include "cd32_fmv.h" #include "specialmonitors.h" #include "devices.h" +#include "gfxboard.h" #define BG_COLOR_DEBUG 0 //#define XLINECHECK @@ -3987,7 +3988,7 @@ void check_prefs_picasso(void) #endif } -void redraw_frame (void) +void redraw_frame(void) { last_drawn_line = 0; first_drawn_line = 32767; @@ -3995,6 +3996,19 @@ void redraw_frame (void) //flush_screen (vidinfo->inbuffer, 0, 0); } +void full_redraw_all(void) +{ + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; + notice_screen_contents_lost(monid); + gfxboard_refresh(monid); + if (!ad->picasso_on) { + redraw_frame(); + } + render_screen(0, 1, true); + show_screen(0, 0); +} + bool vsync_handle_check (void) { int monid = 0; diff --git a/gfxboard.cpp b/gfxboard.cpp index 4fa2e074..a0c0ee6c 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -898,10 +898,8 @@ void gfxboard_hsync_handler(void) } } -bool gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) +void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) { - bool flushed = false; - for (int i = 0; i < MAX_RTG_BOARDS; i++) { struct rtggfxboard *gb = &rtggfxboards[i]; struct amigadisplay *ad = &adisplays[gb->monitor_id]; @@ -912,7 +910,7 @@ bool gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) if (gb->userdata) { struct gfxboard_mode mode = { 0 }; mode.redraw_required = full_redraw_required; - flushed = gb->func->vsync(gb->userdata, &mode); + gb->func->vsync(gb->userdata, &mode); if (mode.mode && mode.width && mode.height) { if (state->Width != mode.width || state->Height != mode.height || @@ -1036,15 +1034,9 @@ bool gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) if (gb->fullrefresh > 0) gb->fullrefresh--; } - - if (gb->gfxboard_surface) { - flushed = true; - gfx_unlock_picasso(gb->monitor_id, true); - } + gfx_unlock_picasso(gb->monitor_id, true); gb->gfxboard_surface = NULL; } - - return flushed; } double gfxboard_get_vsync (void) diff --git a/include/drawing.h b/include/drawing.h index 41eebffc..5e35a8e6 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -316,7 +316,8 @@ extern void drawing_init (void); extern bool notice_interlace_seen (bool); extern void notice_resolution_seen (int, bool); extern bool frame_drawn (int monid); -extern void redraw_frame (void); +extern void redraw_frame(void); +extern void full_redraw_all(void); extern bool draw_frame (struct vidbuffer*); extern int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh); extern void store_custom_limits (int w, int h, int dx, int dy); diff --git a/include/gfxboard.h b/include/gfxboard.h index e470a433..269e4be0 100644 --- a/include/gfxboard.h +++ b/include/gfxboard.h @@ -8,7 +8,7 @@ extern bool gfxboard_init_memory_p4_z2(struct autoconfig_info*); extern bool gfxboard_init_registers(struct autoconfig_info*); extern void gfxboard_free (void); extern void gfxboard_reset (void); -extern bool gfxboard_vsync_handler (bool, bool); +extern void gfxboard_vsync_handler (bool, bool); extern void gfxboard_hsync_handler(void); extern int gfxboard_get_configtype (struct rtgboardconfig*); extern bool gfxboard_is_registers (struct rtgboardconfig*); diff --git a/mame/a2410.cpp b/mame/a2410.cpp index af0daec5..4de7dcc6 100644 --- a/mame/a2410.cpp +++ b/mame/a2410.cpp @@ -570,9 +570,10 @@ static addrbank tms_bank = { static void tms_reset(void *userdata) { struct a2410_struct *data = (struct a2410_struct*)userdata; + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; if (data->a2410_surface) - gfx_unlock_picasso(0, true); + gfx_unlock_picasso(monid, true); data->a2410_surface = NULL; data->a2410_modechanged = false; @@ -597,9 +598,10 @@ static void tms_configured(void *userdata, uae_u32 address) static void tms_free(void *userdata) { struct a2410_struct *data = (struct a2410_struct*)userdata; + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; if (data->a2410_surface) - gfx_unlock_picasso(0, true); + gfx_unlock_picasso(monid, true); data->a2410_surface = NULL; if (data->a2410_gfxboard >= 0) { gfxboard_free_vram(data->a2410_gfxboard); @@ -753,10 +755,10 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) } } } - - if (data->a2410_surface) - gfx_unlock_picasso(monid, true); - data->a2410_surface = NULL; + if (data->a2410_surface) { + data->a2410_surface = NULL; + gfx_unlock_picasso(monid, false); + } } data->a2410_interlace = -data->a2410_interlace; @@ -782,16 +784,14 @@ static void a2410_rethink(struct a2410_struct *data) static bool tms_vsync(void *userdata, struct gfxboard_mode *mode) { struct a2410_struct *data = (struct a2410_struct*)userdata; + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; bool flushed = false; if (!data->a2410_enabled) tms_vsync_handler2(data, false); - if (data->a2410_surface) { - gfx_unlock_picasso(0, false); - flushed = true; - } data->a2410_surface = NULL; + gfx_unlock_picasso(monid, true); if (data->a2410_visible) { mode->width = data->a2410_width; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index fb83e451..b77aba52 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -3719,23 +3719,6 @@ static bool xD3D_setcursor(int monid, int x, int y, int width, int height, bool return true; } -static void xD3D_unlocktexture(int monid, int y_start, int y_end) -{ - struct d3dstruct *d3d = &d3ddata[monid]; - HRESULT hr; - - if (!isd3d (d3d) || !d3d->texture) - return; - - if (d3d->locked) { - if (currprefs.leds_on_screen & (STATUSLINE_CHIPSET | STATUSLINE_RTG)) - updateleds (d3d); - hr = d3d->texture->UnlockRect (0); - } - d3d->locked = 0; - d3d->fulllocked = 0; -} - static void xD3D_flushtexture(int monid, int miny, int maxy) { struct d3dstruct *d3d = &d3ddata[monid]; @@ -3758,6 +3741,25 @@ static void xD3D_flushtexture(int monid, int miny, int maxy) } } +static void xD3D_unlocktexture(int monid, int y_start, int y_end) +{ + struct d3dstruct *d3d = &d3ddata[monid]; + HRESULT hr; + + if (!isd3d(d3d) || !d3d->texture) + return; + + if (d3d->locked) { + if (currprefs.leds_on_screen & (STATUSLINE_CHIPSET | STATUSLINE_RTG)) + updateleds(d3d); + hr = d3d->texture->UnlockRect(0); + if (y_start >= 0) + xD3D_flushtexture(monid, y_start, y_end); + } + d3d->locked = 0; + d3d->fulllocked = 0; +} + static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullupdate) { struct d3dstruct *d3d = &d3ddata[monid]; @@ -4063,7 +4065,7 @@ static uae_u8 *xD3D_setcursorsurface(int monid, int *pitch) } } -bool xD3D_getscanline(int *scanline, bool *invblank) +static bool xD3D_getscanline(int *scanline, bool *invblank) { struct d3dstruct *d3d = &d3ddata[0]; HRESULT hr; @@ -4082,6 +4084,12 @@ bool xD3D_getscanline(int *scanline, bool *invblank) return true; } +static bool xD3D_run(int monid) +{ + struct d3dstruct *d3d = &d3ddata[monid]; + return false; +} + void d3d9_select(void) { D3D_free = xD3D_free; @@ -4107,7 +4115,7 @@ void d3d9_select(void) D3D_resize = NULL; D3D_change = NULL; D3D_getscalerect = xD3D_getscalerect; - D3D_run = NULL; + D3D_run = xD3D_run; D3D_debug = xD3D_debug; D3D_led = xD3D_led; D3D_getscanline = xD3D_getscanline; diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index eb6796d1..850f23e7 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -22,7 +22,7 @@ extern void(*D3D_restore)(int, bool); extern void(*D3D_resize)(int, int); extern void(*D3D_change)(int, int); extern bool(*D3D_getscalerect)(int, float *mx, float *my, float *sx, float *sy); -extern void(*D3D_run)(int); +extern bool(*D3D_run)(int); extern int(*D3D_debug)(int, int); extern void(*D3D_led)(int, int, int); extern bool(*D3D_getscanline)(int*, bool*); diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index f7b4f918..64fde023 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -62,7 +62,7 @@ void(*D3D_restore)(int, bool); void(*D3D_resize)(int, int); void (*D3D_change)(int, int); bool(*D3D_getscalerect)(int, float *mx, float *my, float *sx, float *sy); -void(*D3D_run)(int); +bool(*D3D_run)(int); int(*D3D_debug)(int, int); void(*D3D_led)(int, int, int); bool(*D3D_getscanline)(int*, bool*); @@ -3554,7 +3554,8 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t d3d->swapChainDesc.Scaling = (d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL || d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH; d3d->blackscreen = false; - if (!monid) { + if (!monid && isvsync()) { + int vsync = isvsync(); int hzmult = 0; getvsyncrate(monid, *freq, &hzmult); if (hzmult < 0) { @@ -3565,7 +3566,6 @@ static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t d3d->blackscreen = true; } } - int vsync = isvsync(); if (vsync > 0 && !apm->gfx_vsyncmode) { if (apm->gfx_strobo) d3d->blackscreen = true; @@ -4476,14 +4476,14 @@ static void xD3D11_refresh(int monid) } -static void D3D11_resize_do(struct d3d11struct *d3d) +static bool D3D11_resize_do(struct d3d11struct *d3d) { HRESULT hr; if (!d3d->fsresizedo) - return; + return false; if (!d3d->m_swapChain) - return; + return false; d3d->fsresizedo = false; @@ -4515,30 +4515,31 @@ static void D3D11_resize_do(struct d3d11struct *d3d) } resizemode(d3d); - notice_screen_contents_lost(d3d - d3d11data); - gfxboard_refresh(d3d - d3d11data); write_log(_T("D3D11 resize exit\n")); + return true; } -static void recheck(struct d3d11struct *d3d) +static bool recheck(struct d3d11struct *d3d) { + bool r = false; if (xD3D11_quit(d3d)) - return; - D3D11_resize_do(d3d); + return r; + r = D3D11_resize_do(d3d); if (d3d->resizeretry) { resizemode(d3d); - return; + return r; } if (!d3d->delayedfs) - return; + return r; xD3D11_free(d3d - d3d11data, true); d3d->delayedfs = 0; ShowWindow(d3d->ahwnd, SW_SHOWNORMAL); int freq = 0; if (!xxD3D11_init2(d3d->ahwnd, d3d - d3d11data, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth2, d3d->m_bitmapHeight2, 32, &freq, d3d->dmultx)) d3d->invalidmode = true; + return false; } static bool xD3D11_alloctexture(int monid, int w, int h) @@ -4733,8 +4734,6 @@ static void xD3D11_guimode(int monid, int guion) ShowWindow(d3d->ahwnd, SW_HIDE); } else if (guion == 0) { d3d->delayedfs = 1; - notice_screen_contents_lost(monid); - gfxboard_refresh(monid); } write_log(_T("fs guimode end\n")); } @@ -4903,13 +4902,15 @@ static bool xD3D11_getscalerect(int monid, float *mx, float *my, float *sx, floa return true; } -static void xD3D11_run(int monid) +static bool xD3D11_run(int monid) { struct d3d11struct *d3d = &d3d11data[monid]; if (xD3D11_quit(d3d)) - return; - D3D11_resize_do(d3d); + return false; + if (recheck(d3d)) + return true; + return D3D11_resize_do(d3d); } void d3d11_select(void) diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index d2e6c6b5..30a84238 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -670,7 +670,7 @@ bool resumepaused(int priority) resumesoundpaused (); if (pausemouseactive) { pausemouseactive = 0; - setmouseactive(mon->monitor_id, -1); + setmouseactive(mon->monitor_id, isfullscreen() > 0 ? 1 : -1); } pause_emulation = 0; setsystime (); @@ -2914,8 +2914,11 @@ bool handle_events (void) TranslateMessage (&msg); DispatchMessage (&msg); } - if (D3D_run) - D3D_run(0); + if (D3D_run) { + if (D3D_run(0)) { + full_redraw_all(); + } + } inputdevicefunc_keyboard.read (); inputdevicefunc_mouse.read (); inputdevicefunc_joystick.read (); @@ -2955,8 +2958,10 @@ bool handle_events (void) cnt2 = 5; } } - if (D3D_run) - D3D_run(0); + if (D3D_run) { + if (D3D_run(0)) + full_redraw_all(); + } return pause_emulation != 0; } diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 8862f319..85cbb72e 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -999,7 +999,7 @@ void S2X_render(int monid, int y_start, int y_end) if (d3d) { if (D3D_restore) D3D_restore(monid, true); - surfstart = D3D_locktexture(monid, &pitch, &surf_height, true); + surfstart = D3D_locktexture(monid, &pitch, &surf_height, y_start < 0); if (surfstart == NULL) return; } else { diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index aff97a96..69d836e2 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -2243,7 +2243,7 @@ static void flipgui(int opengui) if (opengui) { DirectDraw_FlipToGDISurface(); } else { - ;// vblank_reset(-1); + full_redraw_all(); } } -- 2.47.3