From eab5bcac0029e4e298e1f194133c21580098508d Mon Sep 17 00:00:00 2001 From: antonioginer Date: Sat, 16 Nov 2019 22:06:13 +0100 Subject: Remove up to one frame of input latency. (#5901) * Remove up to one frame of input latency. Makes MAME virtually lagless on VRR monitors. * Use empty parentheses and clean interface member calls * Add new option -instant_blit to make this feature optional * Rename new option to -lowlatency, -ll --- src/emu/emuopts.cpp | 1 + src/emu/emuopts.h | 2 ++ src/emu/video.cpp | 10 +++++++++- src/emu/video.h | 1 + src/osd/mac/osdmac.h | 1 + src/osd/mac/video.cpp | 16 ++++++++++++---- src/osd/mac/window.cpp | 3 --- src/osd/osdepend.h | 1 + src/osd/sdl/osdsdl.h | 1 + src/osd/sdl/video.cpp | 16 ++++++++++++---- src/osd/sdl/window.cpp | 3 --- src/osd/uwp/video.cpp | 15 +++++++++++---- src/osd/windows/video.cpp | 16 ++++++++++++---- src/osd/windows/winmain.h | 1 + 14 files changed, 64 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index eb7c9bdbf27..8af8541d32c 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -88,6 +88,7 @@ const options_entry emu_options::s_option_entries[] = { OPTION_SLEEP, "1", OPTION_BOOLEAN, "enable sleeping, which gives time back to other applications when idle" }, { OPTION_SPEED "(0.01-100)", "1.0", OPTION_FLOAT, "controls the speed of gameplay, relative to realtime; smaller numbers are slower" }, { OPTION_REFRESHSPEED ";rs", "0", OPTION_BOOLEAN, "automatically adjust emulation speed to keep the emulated refresh rate slower than the host screen" }, + { OPTION_LOWLATENCY ";ll", "0", OPTION_BOOLEAN, "draws new frame before throttling to reduce input latency" }, // render options { nullptr, nullptr, OPTION_HEADER, "CORE RENDER OPTIONS" }, diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h index 970a90c67da..a1a23e77a2b 100644 --- a/src/emu/emuopts.h +++ b/src/emu/emuopts.h @@ -75,6 +75,7 @@ #define OPTION_SLEEP "sleep" #define OPTION_SPEED "speed" #define OPTION_REFRESHSPEED "refreshspeed" +#define OPTION_LOWLATENCY "lowlatency" // core render options #define OPTION_KEEPASPECT "keepaspect" @@ -352,6 +353,7 @@ public: bool sleep() const { return m_sleep; } float speed() const { return float_value(OPTION_SPEED); } bool refresh_speed() const { return m_refresh_speed; } + bool low_latency() const { return bool_value(OPTION_LOWLATENCY); } // core render options bool keep_aspect() const { return bool_value(OPTION_KEEPASPECT); } diff --git a/src/emu/video.cpp b/src/emu/video.cpp index d8bea693005..fa0efb88a89 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -91,6 +91,7 @@ video_manager::video_manager(running_machine &machine) , m_seconds_to_run(machine.options().seconds_to_run()) , m_auto_frameskip(machine.options().auto_frameskip()) , m_speed(original_speed_setting()) + , m_low_latency(machine.options().low_latency()) , m_empty_skip_count(0) , m_frameskip_level(machine.options().frameskip()) , m_frameskip_counter(0) @@ -229,7 +230,7 @@ void video_manager::frame_update(bool from_debugger) // if we're throttling, synchronize before rendering attotime current_time = machine().time(); - if (!from_debugger && !skipped_it && effective_throttle()) + if (!from_debugger && !skipped_it && !m_low_latency && effective_throttle()) update_throttle(current_time); // ask the OSD to update @@ -237,6 +238,13 @@ void video_manager::frame_update(bool from_debugger) machine().osd().update(!from_debugger && skipped_it); g_profiler.stop(); + // we synchronize after rendering instead of before, if low latency mode is enabled + if (!from_debugger && !skipped_it && m_low_latency && effective_throttle()) + update_throttle(current_time); + + // get most recent input now + machine().osd().input_update(); + emulator_info::periodic_check(); // perform tasks for this frame diff --git a/src/emu/video.h b/src/emu/video.h index b8b1c408773..5ccfe2b99b0 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -163,6 +163,7 @@ private: u32 m_seconds_to_run; // number of seconds to run before quitting bool m_auto_frameskip; // flag: true if we're automatically frameskipping u32 m_speed; // overall speed (*1000) + bool m_low_latency; // flag: true if we are throttling after blitting // frameskipping u8 m_empty_skip_count; // number of empty frames we have skipped diff --git a/src/osd/mac/osdmac.h b/src/osd/mac/osdmac.h index 1ed9e6b8a5b..13b680cf271 100644 --- a/src/osd/mac/osdmac.h +++ b/src/osd/mac/osdmac.h @@ -44,6 +44,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; + virtual void input_update() override; // input overridables virtual void customize_input_type_list(simple_list &typelist) override; diff --git a/src/osd/mac/video.cpp b/src/osd/mac/video.cpp index 638e7a949b3..3f585458f8d 100644 --- a/src/osd/mac/video.cpp +++ b/src/osd/mac/video.cpp @@ -108,15 +108,23 @@ void mac_osd_interface::update(bool skip_redraw) // profiler_mark(PROFILER_END); } - // poll the joystick values here - downcast(machine().osd()).poll_inputs(machine()); - - check_osd_inputs(machine()); // if we're running, disable some parts of the debugger if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) debugger_update(); } +//============================================================ +// input_update +//============================================================ + +void mac_osd_interface::input_update() +{ + // poll the joystick values here + process_events_buf(); + poll_inputs(machine()); + check_osd_inputs(machine()); +} + //============================================================ // check_osd_inputs //============================================================ diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp index 3993b3502d2..d22268f86f4 100644 --- a/src/osd/mac/window.cpp +++ b/src/osd/mac/window.cpp @@ -499,9 +499,6 @@ void mac_window_info::update() // and redraw now - // Some configurations require events to be polled in the worker thread - downcast< mac_osd_interface& >(machine().osd()).process_events_buf(); - // Check whether window has vector screens { diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h index 2587b93e560..7b3160cb04e 100644 --- a/src/osd/osdepend.h +++ b/src/osd/osdepend.h @@ -64,6 +64,7 @@ public: // general overridables virtual void init(running_machine &machine) = 0; virtual void update(bool skip_redraw) = 0; + virtual void input_update() = 0; virtual void set_verbose(bool print_verbose) = 0; // debugger overridables diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h index 2fe9a239c8c..8bc4b5556c9 100644 --- a/src/osd/sdl/osdsdl.h +++ b/src/osd/sdl/osdsdl.h @@ -124,6 +124,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; + virtual void input_update() override; // input overridables virtual void customize_input_type_list(simple_list &typelist) override; diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp index 88bc1b51ce4..b8ea713d202 100644 --- a/src/osd/sdl/video.cpp +++ b/src/osd/sdl/video.cpp @@ -109,15 +109,23 @@ void sdl_osd_interface::update(bool skip_redraw) // profiler_mark(PROFILER_END); } - // poll the joystick values here - downcast(machine().osd()).poll_inputs(machine()); - - check_osd_inputs(machine()); // if we're running, disable some parts of the debugger if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) debugger_update(); } +//============================================================ +// input_update +//============================================================ + +void sdl_osd_interface::input_update() +{ + // poll the joystick values here + process_events_buf(); + poll_inputs(machine()); + check_osd_inputs(machine()); +} + //============================================================ // check_osd_inputs //============================================================ diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index 3916ad25b79..2eeeebf1d49 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -604,9 +604,6 @@ void sdl_window_info::update() // and redraw now - // Some configurations require events to be polled in the worker thread - downcast< sdl_osd_interface& >(machine().osd()).process_events_buf(); - // Check whether window has vector screens { diff --git a/src/osd/uwp/video.cpp b/src/osd/uwp/video.cpp index f59b59c171b..9ed9a6c98d3 100644 --- a/src/osd/uwp/video.cpp +++ b/src/osd/uwp/video.cpp @@ -103,15 +103,22 @@ void windows_osd_interface::update(bool skip_redraw) // profiler_mark(PROFILER_END); } - // poll the joystick values here - winwindow_process_events(machine(), true, false); - poll_input(machine()); - check_osd_inputs(); // if we're running, disable some parts of the debugger if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) debugger_update(); } +//============================================================ +// input_update +//============================================================ + +void windows_osd_interface::input_update() +{ + // poll the joystick values here + winwindow_process_events(machine(), true, false); + poll_input(machine()); + check_osd_inputs(); +} //============================================================ // check_osd_inputs diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp index 889e76caa6b..3f3fe78f1f7 100644 --- a/src/osd/windows/video.cpp +++ b/src/osd/windows/video.cpp @@ -95,16 +95,24 @@ void windows_osd_interface::update(bool skip_redraw) // profiler_mark(PROFILER_END); } - // poll the joystick values here - winwindow_process_events(machine(), true, false); - poll_input(machine()); - check_osd_inputs(); // if we're running, disable some parts of the debugger if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) debugger_update(); } +//============================================================ +// input_update +//============================================================ + +void windows_osd_interface::input_update() +{ + // poll the joystick values here + winwindow_process_events(machine(), true, false); + poll_input(machine()); + check_osd_inputs(); +} + //============================================================ // check_osd_inputs //============================================================ diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 21e1b9d2044..04e6da31d1d 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -280,6 +280,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; + virtual void input_update() override; // input overrideables virtual void customize_input_type_list(simple_list &typelist) override; -- cgit v1.2.3