diff --git a/CHANGES b/CHANGES index 2b034de37..fbf948053 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ Other fixes: - Qt: Fix OpenGL renderer lagging behind when fast-forwarding (fixes mgba.io/i/2094) - Qt: Fix smudged window icon on Windows - Qt: Fix saving settings enabling camera when camera name changes (fixes mgba.io/i/2125) + - Qt: Fix frames getting backlogged (fixes mgba.io/i/2122) Misc: - Core: Truncate preloading ROMs that slightly exceed max size (fixes mgba.io/i/2093) - GBA: Default-enable VBA bug compat for Ruby and Emerald ROM hacks diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index c613e7afb..de494cba3 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -371,7 +371,7 @@ void PainterGL::resizeContext() { if (m_dims == size) { return; } - dequeueAll(); + dequeueAll(false); m_backend->setDimensions(m_backend, size.width(), size.height()); } @@ -429,7 +429,7 @@ void PainterGL::start() { } void PainterGL::draw() { - if (!m_active || m_queue.isEmpty()) { + if (!m_started || m_queue.isEmpty()) { return; } mCoreSync* sync = &m_context->thread()->impl->sync; @@ -461,6 +461,11 @@ void PainterGL::draw() { performDraw(); m_backend->swap(m_backend); } + + QMutexLocker locker(&m_mutex); + if (!m_queue.isEmpty()) { + QTimer::singleShot(1, this, &PainterGL::draw); + } } void PainterGL::forceDraw() { @@ -477,7 +482,7 @@ void PainterGL::forceDraw() { void PainterGL::stop() { m_active = false; m_started = false; - dequeueAll(); + dequeueAll(false); if (m_context) { if (m_videoProxy) { m_videoProxy->detach(m_context.get()); @@ -499,6 +504,7 @@ void PainterGL::stop() { void PainterGL::pause() { m_active = false; + dequeueAll(true); } void PainterGL::unpause() { @@ -551,20 +557,24 @@ void PainterGL::dequeue() { m_buffer = buffer; } -void PainterGL::dequeueAll() { +void PainterGL::dequeueAll(bool keep) { + QMutexLocker locker(&m_mutex); uint32_t* buffer = 0; - m_mutex.lock(); while (!m_queue.isEmpty()) { buffer = m_queue.dequeue(); - if (buffer) { + if (keep) { + if (m_buffer && buffer) { + m_free.append(m_buffer); + m_buffer = buffer; + } + } else if (buffer) { m_free.append(buffer); } } - if (m_buffer) { + if (m_buffer && !keep) { m_free.append(m_buffer); m_buffer = nullptr; } - m_mutex.unlock(); } void PainterGL::setVideoProxy(std::shared_ptr proxy) { diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index d0cea76cb..e8951be93 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -136,7 +136,7 @@ private: void makeCurrent(); void performDraw(); void dequeue(); - void dequeueAll(); + void dequeueAll(bool keep = false); std::array, 3> m_buffers; QList m_free;