diff --git a/CHANGES b/CHANGES index 6b0fedc8f..0a9123002 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Other fixes: - GBA Video: Fix mode 5 frame 1 caching (fixes mgba.io/i/2075) - GBA Video: Don't attempt to copy invalid registers when switching renderer - Qt: Fix crash when switching from high-resolution OpenGL renderer to software + - Qt: Fix OpenGL renderer lagging behind when fast-forwarding (fixes mgba.io/i/2094) 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 c30cba9f5..c613e7afb 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -432,23 +432,16 @@ void PainterGL::draw() { if (!m_active || m_queue.isEmpty()) { return; } - if (m_lagging >= 1) { - return; - } mCoreSync* sync = &m_context->thread()->impl->sync; if (!mCoreSyncWaitFrameStart(sync)) { mCoreSyncWaitFrameEnd(sync); - ++m_lagging; if ((sync->audioWait || sync->videoFrameWait) && m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) { QTimer::singleShot(1, this, &PainterGL::draw); } return; } dequeue(); - if (m_videoProxy) { - // Only block on the next frame if we're trying to run at roughly 60fps via audio - m_videoProxy->setBlocking(sync->audioWait && std::abs(60.f - sync->fpsTarget) < 0.1f); - } + bool forceRedraw = !m_videoProxy; if (!m_delayTimer.isValid()) { m_delayTimer.start(); } else { @@ -456,13 +449,18 @@ void PainterGL::draw() { while (m_delayTimer.nsecsElapsed() + 2000000 < 1000000000 / sync->fpsTarget) { QThread::usleep(500); } + forceRedraw = true; + } else if (!forceRedraw) { + forceRedraw = m_delayTimer.nsecsElapsed() + 2000000 >= 1000000000 / m_surface->screen()->refreshRate(); } - m_delayTimer.restart(); } mCoreSyncWaitFrameEnd(sync); - performDraw(); - m_backend->swap(m_backend); + if (forceRedraw) { + m_delayTimer.restart(); + performDraw(); + m_backend->swap(m_backend); + } } void PainterGL::forceDraw() { @@ -504,7 +502,6 @@ void PainterGL::pause() { } void PainterGL::unpause() { - m_lagging = 0; m_active = true; } @@ -538,7 +535,6 @@ void PainterGL::enqueue(const uint32_t* backing) { memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); } } - m_lagging = 0; m_queue.enqueue(buffer); } diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 111f0cc88..d0cea76cb 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -141,7 +141,6 @@ private: std::array, 3> m_buffers; QList m_free; QQueue m_queue; - QAtomicInt m_lagging = 0; uint32_t* m_buffer = nullptr; QPainter m_painter; QMutex m_mutex; diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 60cb938b8..7c6366229 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -14,7 +14,7 @@ using namespace QGBA; VideoProxy::VideoProxy() { mVideoLoggerRendererCreate(&m_logger.d, false); m_logger.d.block = true; - m_logger.d.waitOnFlush = false; + m_logger.d.waitOnFlush = true; m_logger.d.init = &cbind<&VideoProxy::init>; m_logger.d.reset = &cbind<&VideoProxy::reset>;