From 7be5215c084d14dde9f5cd98e733c3df2d1e55d4 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Tue, 23 May 2017 11:11:32 +0300 Subject: [PATCH] When redrawing screen, read the last written frame This should fix the bug with loadstates, where wrong screenshot was displayed in certain race condition. --- include/library/triplebuffer.hpp | 15 +++++++++++++++ src/core/framebuffer.cpp | 5 ++--- src/library/triplebuffer.cpp | 7 +++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/library/triplebuffer.hpp b/include/library/triplebuffer.hpp index 2573f46b..e431d63d 100644 --- a/include/library/triplebuffer.hpp +++ b/include/library/triplebuffer.hpp @@ -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 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 fn) throw() + { + l.read_last_write_synchronous([this,fn](unsigned x){ fn(*objs[x]); }); + } private: T* objs[3]; logic l; diff --git a/src/core/framebuffer.cpp b/src/core/framebuffer.cpp index 922a2260..946fa3e8 100644 --- a/src/core/framebuffer.cpp +++ b/src/core/framebuffer.cpp @@ -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([©](render_info& ri) { copy = ri.fbuf; }); //Redraws are never spontaneous redraw_framebuffer(copy, last_redraw_no_lua, false); } diff --git a/src/library/triplebuffer.cpp b/src/library/triplebuffer.cpp index 8ecc4d1f..6444596d 100644 --- a/src/library/triplebuffer.cpp +++ b/src/library/triplebuffer.cpp @@ -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 fn) throw() +{ + threads::alock h(lock); + fn(last_complete); +} + } -- 2.11.4.GIT