diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index fb59baf5c..4608a1b45 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -203,10 +203,10 @@ CoreController::~CoreController() { } const color_t* CoreController::drawContext() { - QMutexLocker locker(&m_mutex); if (m_hwaccel) { return nullptr; } + QMutexLocker locker(&m_bufferMutex); return reinterpret_cast(m_completeBuffer.constData()); } @@ -401,8 +401,7 @@ void CoreController::setPaused(bool paused) { return; } if (paused) { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); } else { @@ -411,13 +410,17 @@ void CoreController::setPaused(bool paused) { } void CoreController::frameAdvance() { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); setPaused(false); } +void CoreController::addFrameAction(std::function action) { + QMutexLocker locker(&m_actionMutex); + m_frameActions.append(action); +} + void CoreController::setSync(bool sync) { if (sync) { m_threadContext.impl->sync.audioWait = m_audioSync; @@ -880,9 +883,9 @@ int CoreController::updateAutofire() { } void CoreController::finishFrame() { - QMutexLocker locker(&m_mutex); if (!m_hwaccel) { - memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); + QMutexLocker locker(&m_bufferMutex); + memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); // TODO: Generalize this to triple buffering? m_activeBuffer = &m_buffers[0]; @@ -893,10 +896,13 @@ void CoreController::finishFrame() { memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), screenDimensions().width()); } - for (auto& action : m_frameActions) { + + QMutexLocker locker(&m_actionMutex); + QList> frameActions(m_frameActions); + m_frameActions.clear(); + for (auto& action : frameActions) { action(); } - m_frameActions.clear(); updateKeys(); QMetaObject::invokeMethod(this, "frameAvailable"); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index b6f9d7ecf..5463bf76b 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -102,6 +102,8 @@ public: bool audioSync() const { return m_audioSync; } bool videoSync() const { return m_videoSync; } + void addFrameAction(std::function callback); + public slots: void start(); void stop(); @@ -209,7 +211,8 @@ private: QList> m_resetActions; QList> m_frameActions; - QMutex m_mutex; + QMutex m_actionMutex{QMutex::Recursive}; + QMutex m_bufferMutex; int m_activeKeys = 0; bool m_autofire[32] = {};