When redrawing screen, read the last written frame

This should fix the bug with loadstates, where wrong screenshot was
displayed in certain race condition.
This commit is contained in:
Ilari Liusvaara 2017-05-23 11:11:32 +03:00
parent 8ac8304824
commit 7be5215c08
3 changed files with 24 additions and 3 deletions

View file

@ -45,6 +45,12 @@ public:
* Throws std::logic_error: If write count is 0.
*/
void put_write() throw(std::logic_error);
/**
* Call specified function synchronously for last written buffer.
*
* The buffer number is passed to specified function.
*/
void read_last_write_synchronous(std::function<void(unsigned)> fn) throw();
private:
threads::lock lock;
unsigned last_complete; //Number of last completed buffer
@ -103,6 +109,15 @@ public:
* Throws std::logic_error: If write count is 0.
*/
void put_write() throw(std::logic_error) { l.put_write(); }
/**
* Call specified function synchronously for last written buffer.
*
* The buffer itself is passed to the function.
*/
void read_last_write_synchronous(std::function<void(T&)> fn) throw()
{
l.read_last_write_synchronous([this,fn](unsigned x){ fn(*objs[x]); });
}
private:
T* objs[3];
logic l;

View file

@ -170,9 +170,8 @@ void emu_framebuffer::redraw_framebuffer(framebuffer::raw& todraw, bool no_lua,
void emu_framebuffer::redraw_framebuffer()
{
render_info& ri = buffering.get_read();
framebuffer::raw copy = ri.fbuf;
buffering.put_read();
framebuffer::raw copy;
buffering.read_last_write_synchronous([&copy](render_info& ri) { copy = ri.fbuf; });
//Redraws are never spontaneous
redraw_framebuffer(copy, last_redraw_no_lua, false);
}

View file

@ -60,4 +60,11 @@ void logic::put_write() throw(std::logic_error)
if(!count_write)
last_complete = current_write;
}
void logic::read_last_write_synchronous(std::function<void(unsigned)> fn) throw()
{
threads::alock h(lock);
fn(last_complete);
}
}