all repos — mgba @ 4420054c1a3b13e406e28aaa7ab8f44ab3509438

mGBA Game Boy Advance Emulator

Qt: Expose frame actions
Vicki Pfau vi@endrift.com
Sat, 01 Jun 2019 11:08:49 -0700
commit

4420054c1a3b13e406e28aaa7ab8f44ab3509438

parent

5436d2576ffd0dac6254963e4a8d656e445ef078

2 files changed, 19 insertions(+), 10 deletions(-)

jump to
M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -203,10 +203,10 @@ m_threadContext.core->deinit(m_threadContext.core);

} const color_t* CoreController::drawContext() { - QMutexLocker locker(&m_mutex); if (m_hwaccel) { return nullptr; } + QMutexLocker locker(&m_bufferMutex); return reinterpret_cast<const color_t*>(m_completeBuffer.constData()); }

@@ -401,8 +401,7 @@ if (paused == isPaused()) {

return; } if (paused) { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); } else {

@@ -411,11 +410,15 @@ }

} void CoreController::frameAdvance() { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); setPaused(false); +} + +void CoreController::addFrameAction(std::function<void ()> action) { + QMutexLocker locker(&m_actionMutex); + m_frameActions.append(action); } void CoreController::setSync(bool sync) {

@@ -880,9 +883,9 @@ return active;

} 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 @@ // Copy contents to avoid issues when doing frameskip

memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer->data()), screenDimensions().width()); } - for (auto& action : m_frameActions) { + + QMutexLocker locker(&m_actionMutex); + QList<std::function<void ()>> frameActions(m_frameActions); + m_frameActions.clear(); + for (auto& action : frameActions) { action(); } - m_frameActions.clear(); updateKeys(); QMetaObject::invokeMethod(this, "frameAvailable");
M src/platform/qt/CoreController.hsrc/platform/qt/CoreController.h

@@ -102,6 +102,8 @@

bool audioSync() const { return m_audioSync; } bool videoSync() const { return m_videoSync; } + void addFrameAction(std::function<void ()> callback); + public slots: void start(); void stop();

@@ -209,7 +211,8 @@ std::unique_ptr<Override> m_override;

QList<std::function<void()>> m_resetActions; QList<std::function<void()>> m_frameActions; - QMutex m_mutex; + QMutex m_actionMutex{QMutex::Recursive}; + QMutex m_bufferMutex; int m_activeKeys = 0; bool m_autofire[32] = {};