Qt: Discard additional frame draws if waiting fails

This commit is contained in:
Vicki Pfau 2020-11-27 18:31:13 -08:00
parent fc3e47a4ba
commit 8e096916b1
3 changed files with 22 additions and 5 deletions

View File

@ -102,6 +102,7 @@ Misc:
- Qt: Add copy button to GB printer dialog - Qt: Add copy button to GB printer dialog
- Qt: Window title updates can be disabled (closes mgba.io/i/1912) - Qt: Window title updates can be disabled (closes mgba.io/i/1912)
- Qt: Redo OpenGL context thread handling (fixes mgba.io/i/1724) - Qt: Redo OpenGL context thread handling (fixes mgba.io/i/1724)
- Qt: Discard additional frame draws if waiting fails
- Util: Reset vector size on deinit - Util: Reset vector size on deinit
- VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730)

View File

@ -432,8 +432,18 @@ void PainterGL::draw() {
if (!m_active || m_queue.isEmpty()) { if (!m_active || m_queue.isEmpty()) {
return; return;
} }
if (m_lagging >= 1) {
return;
}
mCoreSync* sync = &m_context->thread()->impl->sync; mCoreSync* sync = &m_context->thread()->impl->sync;
mCoreSyncWaitFrameStart(sync); if (!mCoreSyncWaitFrameStart(sync)) {
mCoreSyncWaitFrameEnd(sync);
++m_lagging;
if (m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) {
QTimer::singleShot(1, this, &PainterGL::draw);
}
return;
}
dequeue(); dequeue();
if (m_videoProxy) { if (m_videoProxy) {
// Only block on the next frame if we're trying to run at roughly 60fps via audio // Only block on the next frame if we're trying to run at roughly 60fps via audio
@ -445,17 +455,16 @@ void PainterGL::draw() {
while (m_delayTimer.nsecsElapsed() + 2000000 < 1000000000 / sync->fpsTarget) { while (m_delayTimer.nsecsElapsed() + 2000000 < 1000000000 / sync->fpsTarget) {
QThread::usleep(500); QThread::usleep(500);
} }
m_delayTimer.restart();
} }
mCoreSyncWaitFrameEnd(sync); mCoreSyncWaitFrameEnd(sync);
forceDraw(); performDraw();
m_backend->swap(m_backend);
m_delayTimer.restart();
} }
void PainterGL::forceDraw() { void PainterGL::forceDraw() {
m_painter.begin(m_window.get());
performDraw(); performDraw();
m_painter.end();
if (!m_context->thread()->impl->sync.audioWait && !m_context->thread()->impl->sync.videoFrameWait) { if (!m_context->thread()->impl->sync.audioWait && !m_context->thread()->impl->sync.videoFrameWait) {
if (m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) { if (m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) {
return; return;
@ -486,10 +495,12 @@ void PainterGL::pause() {
} }
void PainterGL::unpause() { void PainterGL::unpause() {
m_lagging = 0;
m_active = true; m_active = true;
} }
void PainterGL::performDraw() { void PainterGL::performDraw() {
m_painter.begin(m_window.get());
m_painter.beginNativePainting(); m_painter.beginNativePainting();
float r = m_surface->devicePixelRatio(); float r = m_surface->devicePixelRatio();
m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r);
@ -501,6 +512,7 @@ void PainterGL::performDraw() {
if (m_showOSD && m_messagePainter) { if (m_showOSD && m_messagePainter) {
m_messagePainter->paint(&m_painter); m_messagePainter->paint(&m_painter);
} }
m_painter.end();
} }
void PainterGL::enqueue(const uint32_t* backing) { void PainterGL::enqueue(const uint32_t* backing) {
@ -517,6 +529,7 @@ void PainterGL::enqueue(const uint32_t* backing) {
memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL);
} }
} }
m_lagging = 0;
m_queue.enqueue(buffer); m_queue.enqueue(buffer);
} }
@ -531,6 +544,7 @@ void PainterGL::dequeue() {
m_buffer = nullptr; m_buffer = nullptr;
} }
m_buffer = buffer; m_buffer = buffer;
return;
} }
void PainterGL::dequeueAll() { void PainterGL::dequeueAll() {

View File

@ -16,6 +16,7 @@
#endif #endif
#endif #endif
#include <QAtomicInt>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QList> #include <QList>
@ -130,6 +131,7 @@ private:
std::array<std::array<uint32_t, 0x100000>, 3> m_buffers; std::array<std::array<uint32_t, 0x100000>, 3> m_buffers;
QList<uint32_t*> m_free; QList<uint32_t*> m_free;
QQueue<uint32_t*> m_queue; QQueue<uint32_t*> m_queue;
QAtomicInt m_lagging = 0;
uint32_t* m_buffer; uint32_t* m_buffer;
QPainter m_painter; QPainter m_painter;
QMutex m_mutex; QMutex m_mutex;