For Qt GUI, add video buffer mutex to ensure clean transfer between emulation and GUI threads. Use common FCEU::mutex wrapper for cleaner code.
This commit is contained in:
parent
cb0edc5a21
commit
d363d04dbb
|
@ -170,11 +170,6 @@ consoleWin_t::consoleWin_t(QWidget *parent)
|
|||
setAcceptDrops(true);
|
||||
|
||||
gameTimer = new QTimer( this );
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
mutex = new QRecursiveMutex();
|
||||
#else
|
||||
mutex = new QMutex( QMutex::Recursive );
|
||||
#endif
|
||||
emulatorThread = new emulatorThread_t(this);
|
||||
|
||||
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
|
||||
|
@ -336,8 +331,6 @@ consoleWin_t::~consoleWin_t(void)
|
|||
|
||||
unloadVideoDriver();
|
||||
|
||||
delete mutex;
|
||||
|
||||
// LoadGame() checks for an IP and if it finds one begins a network session
|
||||
// clear the NetworkIP field so this doesn't happen unintentionally
|
||||
//g_config->setOption ("SDL.NetworkIP", "");
|
||||
|
@ -4564,17 +4557,28 @@ int consoleWin_t::getPeriodicInterval(void)
|
|||
|
||||
void consoleWin_t::transferVideoBuffer(void)
|
||||
{
|
||||
bool redraw = false;
|
||||
FCEU_PROFILE_FUNC(prof, "VideoXfer");
|
||||
|
||||
{
|
||||
FCEU::autoScopedLock lock(videoBufferMutex);
|
||||
if ( nes_shm->blitUpdated )
|
||||
{
|
||||
nes_shm->blitUpdated = 0;
|
||||
|
||||
if (viewport_Interface)
|
||||
if (viewport_Interface != nullptr)
|
||||
{
|
||||
viewport_Interface->transfer2LocalBuffer();
|
||||
viewport_Interface->queueRedraw();
|
||||
redraw = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't queue redraw in mutex lock scope
|
||||
if (redraw && (viewport_Interface != nullptr))
|
||||
{
|
||||
viewport_Interface->queueRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void consoleWin_t::emuFrameFinish(void)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <QRecursiveMutex>
|
||||
#endif
|
||||
|
||||
#include "utils/mutex.h"
|
||||
#include "Qt/ColorMenu.h"
|
||||
#include "Qt/ConsoleViewerGL.h"
|
||||
#include "Qt/ConsoleViewerSDL.h"
|
||||
|
@ -134,11 +135,8 @@ class consoleWin_t : public QMainWindow
|
|||
|
||||
void setCyclePeriodms( int ms );
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
QRecursiveMutex *mutex;
|
||||
#else
|
||||
QMutex *mutex;
|
||||
#endif
|
||||
FCEU::mutex emulatorMutex;
|
||||
FCEU::mutex videoBufferMutex;
|
||||
|
||||
int videoInit(void);
|
||||
void videoReset(void);
|
||||
|
|
|
@ -1382,7 +1382,7 @@ void fceuWrapperLock(void)
|
|||
mutexPending++;
|
||||
if ( consoleWindow != NULL )
|
||||
{
|
||||
consoleWindow->mutex->lock();
|
||||
consoleWindow->emulatorMutex.lock();
|
||||
}
|
||||
mutexPending--;
|
||||
mutexLocks++;
|
||||
|
@ -1412,7 +1412,7 @@ bool fceuWrapperTryLock(int timeout)
|
|||
mutexPending++;
|
||||
if ( consoleWindow != NULL )
|
||||
{
|
||||
lockAcq = consoleWindow->mutex->tryLock( timeout );
|
||||
lockAcq = consoleWindow->emulatorMutex.tryLock( timeout );
|
||||
}
|
||||
mutexPending--;
|
||||
|
||||
|
@ -1430,7 +1430,7 @@ void fceuWrapperUnLock(void)
|
|||
mutexLocks--;
|
||||
if ( consoleWindow != NULL )
|
||||
{
|
||||
consoleWindow->mutex->unlock();
|
||||
consoleWindow->emulatorMutex.unlock();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -496,8 +496,6 @@ doBlitScreen(uint8_t *XBuf, uint8_t *dest)
|
|||
void
|
||||
BlitScreen(uint8 *XBuf)
|
||||
{
|
||||
int i = nes_shm->pixBufIdx;
|
||||
|
||||
if (usePaletteForVideoBg)
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
|
@ -511,11 +509,18 @@ BlitScreen(uint8 *XBuf)
|
|||
}
|
||||
}
|
||||
|
||||
if (consoleWindow != nullptr)
|
||||
{
|
||||
FCEU::autoScopedLock lock(consoleWindow->videoBufferMutex);
|
||||
|
||||
int i = nes_shm->pixBufIdx;
|
||||
|
||||
doBlitScreen(XBuf, (uint8_t*)nes_shm->pixbuf[i]);
|
||||
|
||||
nes_shm->pixBufIdx = (i+1) % NES_VIDEO_BUFLEN;
|
||||
nes_shm->blit_count++;
|
||||
nes_shm->blitUpdated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void FCEUI_AviVideoUpdate(const unsigned char* buffer)
|
||||
|
|
|
@ -48,6 +48,24 @@ void mutex::unlock(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool mutex::tryLock()
|
||||
{
|
||||
bool success = false;
|
||||
#ifdef __QT_DRIVER__
|
||||
success = mtx->tryLock();
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
bool mutex::tryLock(int timeout)
|
||||
{
|
||||
bool success = false;
|
||||
#ifdef __QT_DRIVER__
|
||||
success = mtx->tryLock(timeout);
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Scoped AutoLock
|
||||
//-----------------------------------------------------
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace FCEU
|
|||
|
||||
void lock(void);
|
||||
void unlock(void);
|
||||
bool tryLock(void);
|
||||
bool tryLock(int timeout);
|
||||
|
||||
private:
|
||||
#ifdef __QT_DRIVER__
|
||||
|
|
Loading…
Reference in New Issue