screen: remember last partial updates reset time because of scheduler time travel issue

This commit is contained in:
hap 2025-02-24 18:37:08 +01:00
parent 456e2e3154
commit 56a55eb6ce
2 changed files with 23 additions and 3 deletions

View File

@ -555,6 +555,7 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
, m_curbitmap(0)
, m_curtexture(0)
, m_changed(true)
, m_last_partial_reset(attotime::zero)
, m_last_partial_scan(0)
, m_partial_scan_hpos(0)
, m_color(rgb_t(0xff, 0xff, 0xff, 0xff))
@ -877,6 +878,7 @@ void screen_device::device_start()
save_item(NAME(m_visarea.min_y));
save_item(NAME(m_visarea.max_x));
save_item(NAME(m_visarea.max_y));
save_item(NAME(m_last_partial_reset));
save_item(NAME(m_last_partial_scan));
save_item(NAME(m_frame_period));
save_item(NAME(m_brightness));
@ -1169,6 +1171,14 @@ bool screen_device::update_partial(int scanline)
return false;
}
// skip if we already rendered this frame
// this can happen if the executing cpu timeslice is in the previous frame while scanline 0 already started
if (m_last_partial_scan == 0 && m_last_partial_reset > machine().time())
{
LOG_PARTIAL_UPDATES(("skipped because frame was already rendered\n"));
return false;
}
// set the range of scanlines to render
rectangle clip(m_visarea);
clip.sety((std::max)(clip.top(), m_last_partial_scan), (std::min)(clip.bottom(), scanline));
@ -1279,6 +1289,14 @@ void screen_device::update_now()
return;
}
// skip if we already rendered this frame
// this can happen if the executing cpu timeslice is in the previous frame while scanline 0 already started
if (m_last_partial_scan == 0 && m_partial_scan_hpos == 0 && m_last_partial_reset > machine().time())
{
LOG_PARTIAL_UPDATES(("skipped because frame was already rendered\n"));
return;
}
LOG_PARTIAL_UPDATES(("update_now(): Y=%d, X=%d, last partial %d, partial hpos %d (vis %d %d)\n", current_vpos, current_hpos, m_last_partial_scan, m_partial_scan_hpos, m_visarea.right(), m_visarea.bottom()));
// start off by doing a partial update up to the line before us, in case that was necessary
@ -1394,6 +1412,7 @@ void screen_device::update_now()
void screen_device::reset_partial_updates()
{
m_last_partial_reset = machine().time();
m_last_partial_scan = 0;
m_partial_scan_hpos = 0;
m_partial_updates_this_frame = 0;

View File

@ -461,7 +461,7 @@ private:
screen_update_rgb32_delegate m_screen_update_rgb32; // screen update callback (32-bit RGB)
devcb_write_line m_screen_vblank; // screen vblank line callback
devcb_write32 m_scanline_cb; // screen scanline callback
optional_device<device_palette_interface> m_palette; // our palette
optional_device<device_palette_interface> m_palette; // our palette
u32 m_video_attributes; // flags describing the video system
optional_memory_region m_svg_region; // the region in which the svg data is in
@ -485,6 +485,7 @@ private:
u8 m_curbitmap; // current bitmap index
u8 m_curtexture; // current texture index
bool m_changed; // has this bitmap changed?
attotime m_last_partial_reset; // last time partial updates were reset
s32 m_last_partial_scan; // scanline of last partial update
s32 m_partial_scan_hpos; // horizontal pixel last rendered on this partial scanline
bitmap_argb32 m_screen_overlay_bitmap; // screen overlay bitmap
@ -504,7 +505,7 @@ private:
emu_timer * m_scanline0_timer; // scanline 0 timer
emu_timer * m_scanline_timer; // scanline timer
u64 m_frame_number; // the current frame number
u32 m_partial_updates_this_frame;// partial update counter this frame
u32 m_partial_updates_this_frame; // partial update counter this frame
bool m_is_primary_screen;
@ -517,7 +518,7 @@ private:
vblank_state_delegate m_callback;
};
std::vector<std::unique_ptr<callback_item>> m_callback_list; // list of VBLANK callbacks
std::vector<std::unique_ptr<callback_item>> m_callback_list; // list of VBLANK callbacks
// auto-sizing bitmaps
class auto_bitmap_item