From 5296b54fd5f5ea8f31fd3e6e19b57165e31d702e Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 15 May 2018 20:17:55 +0300 Subject: [PATCH] Lagless vsync updates. --- custom.cpp | 21 +++++++++++--------- events.cpp | 45 ++++++++++++++++++++++++++++--------------- include/events.h | 1 + od-win32/win32gfx.cpp | 3 ++- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/custom.cpp b/custom.cpp index 2e140888..315d8d4d 100644 --- a/custom.cpp +++ b/custom.cpp @@ -488,7 +488,7 @@ void reset_frame_rate_hack (void) return; rpt_did_reset = 1; - is_syncline = 0; + events_reset_syncline(); vsyncmintime = read_processor_time () + vsynctimebase; write_log (_T("Resetting frame rate hack\n")); } @@ -7431,7 +7431,7 @@ static bool framewait (void) int vs = isvsync_chipset (); int status = 0; - is_syncline = 0; + events_reset_syncline(); static struct mavg_data ma_frameskipt; int frameskipt_avg = mavg (&ma_frameskipt, frameskiptime, MAVG_VSYNC_SIZE); @@ -8290,7 +8290,6 @@ static bool linesync_beam_single(void) { frame_time_t maxtime = read_processor_time() + 2 * vsynctimebase; - is_syncline = 0; if (is_last_line()) { do_render_slice(-1, 0, vpos - 1); while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) { @@ -8328,7 +8327,7 @@ static bool linesync_beam_multi_dual(void) bool input_read_done = false; bool was_syncline = is_syncline != 0; - is_syncline = 0; + events_reset_syncline(); if (vpos == 0) { int firstline, lastline; linesync_first_last_line(&firstline, &lastline); @@ -8430,7 +8429,7 @@ static bool linesync_beam_vrr(void) bool input_read_done = false; bool was_syncline = is_syncline != 0; - is_syncline = 0; + events_reset_syncline(); if (vpos == 0 && !was_syncline) { int firstline, lastline; linesync_first_last_line(&firstline, &lastline); @@ -8500,6 +8499,7 @@ static bool linesync_beam_vrr(void) maybe_process_pull_audio(); if (currprefs.m68k_speed < 0 && !was_syncline) { is_syncline = -1; + is_syncline_end = target_get_display_scanline(-1); return 0; } target_spin(0); @@ -8517,10 +8517,12 @@ static bool linesync_beam_vrr(void) maybe_process_pull_audio(); if (currprefs.m68k_speed < 0 && !was_syncline) { is_syncline = -1; + is_syncline_end = target_get_display_scanline(-1); return 0; } target_spin(0); } + if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) { vsyncmintime += vsynctimebase; } else { @@ -8585,7 +8587,7 @@ static bool linesync_beam_multi_single(void) bool input_read_done = false; bool was_syncline = is_syncline != 0; - is_syncline = 0; + events_reset_syncline(); if (vpos == 0 && !was_syncline) { int firstline, lastline; linesync_first_last_line(&firstline, &lastline); @@ -8691,6 +8693,7 @@ static bool linesync_beam_multi_single(void) break; if (currprefs.m68k_speed < 0 && !was_syncline) { is_syncline = -1; + is_syncline_end = vp; return 0; } maybe_process_pull_audio(); @@ -8752,7 +8755,7 @@ static bool linesync_beam_multi_single(void) void vsync_event_done(void) { if (!isvsync_chipset()) { - is_syncline = 0; + events_reset_syncline(); return; } if (currprefs.gfx_display_sections <= 1) { @@ -8947,7 +8950,7 @@ static void hsync_handler_post (bool onvsync) } } else if (currprefs.m68k_speed_throttle) { vsyncmintime = read_processor_time (); /* end of CPU emulation time */ - is_syncline = 0; + events_reset_syncline(); maybe_process_pull_audio(); } else { vsyncmintime = vsyncmaxtime; /* emulate if still time left */ @@ -8960,7 +8963,7 @@ static void hsync_handler_post (bool onvsync) /* end of scanline, run cpu emulation as long as we still have time */ vsyncmintime += vsynctimeperline; linecounter++; - is_syncline = 0; + events_reset_syncline(); if (vsync_isdone(NULL) <= 0 && !currprefs.turbo_emulation) { if ((int)vsyncmaxtime - (int)vsyncmintime > 0) { if ((int)vsyncwaittime - (int)vsyncmintime > 0) { diff --git a/events.cpp b/events.cpp index c496fcde..5d06c84e 100644 --- a/events.cpp +++ b/events.cpp @@ -34,6 +34,17 @@ frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime; int vsynctimebase; int event2_count; +static void events_fast(void) +{ + cycles_do_special(); +} + +void events_reset_syncline(void) +{ + is_syncline = 0; + events_fast(); +} + void events_schedule (void) { int i; @@ -58,20 +69,24 @@ static bool event_check_vsync(void) if (is_syncline == -1) { if (!isvsync_chipset()) { - is_syncline = 0; + events_reset_syncline(); return false; } // wait for vblank audio_finish_pull(); int done = vsync_isdone(NULL); + if (done == -2) { + // if no vsync thread + int vp = target_get_display_scanline(-1); + if (vp < is_syncline_end) + done = 1; + else if (vp > is_syncline_end) + is_syncline_end = vp; + } if (!done) { #ifdef WITH_PPC if (ppc_state) { - if (is_syncline == 1) { - uae_ppc_execute_check(); - } else { - uae_ppc_execute_quick(); - } + uae_ppc_execute_quick(); } #endif if (currprefs.cachesize) @@ -86,23 +101,21 @@ static bool event_check_vsync(void) } else if (is_syncline == -2) { if (!isvsync_chipset()) { - is_syncline = 0; + events_reset_syncline(); return false; } // wait for vblank or early vblank audio_finish_pull(); int done = vsync_isdone(NULL); + if (done == -2) + done = 0; int vp = target_get_display_scanline(-1); if (vp < 0 || vp >= is_syncline_end) - done = true; + done = 1; if (!done) { #ifdef WITH_PPC if (ppc_state) { - if (is_syncline == 1) { - uae_ppc_execute_check(); - } else { - uae_ppc_execute_quick(); - } + uae_ppc_execute_quick(); } #endif if (currprefs.cachesize) @@ -117,7 +130,7 @@ static bool event_check_vsync(void) } else if (is_syncline > 0) { if (!isvsync_chipset()) { - is_syncline = 0; + events_reset_syncline(); return false; } audio_finish_pull(); @@ -156,7 +169,7 @@ static bool event_check_vsync(void) return true; } } - is_syncline = 0; + events_reset_syncline(); } else if (is_syncline < -10) { @@ -185,7 +198,7 @@ static bool event_check_vsync(void) return true; } } - is_syncline = 0; + events_reset_syncline(); } return false; } diff --git a/include/events.h b/include/events.h index 42ed4563..e933413f 100644 --- a/include/events.h +++ b/include/events.h @@ -32,6 +32,7 @@ extern void do_cycles_ce (unsigned long cycles); extern void do_cycles_ce020 (unsigned long cycles); extern void events_schedule (void); extern void do_cycles_slow (unsigned long cycles_to_add); +extern void events_reset_syncline(void); extern int is_cycle_ce (void); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 9891880c..84f4feaf 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -474,7 +474,6 @@ static void display_vblank_thread_kill(void) CloseHandle(waitvblankevent); waitvblankevent = NULL; } - wait_vblank_display = NULL; } static void display_vblank_thread(struct AmigaMonitor *mon) @@ -2947,6 +2946,8 @@ int vsync_isdone(frame_time_t *dt) { if (isvsync() == 0) return -1; + if (waitvblankthread_mode <= 0) + return -2; if (dt) *dt = wait_vblank_timestamp; return vsync_active ? 1 : 0; -- 2.47.3