Qt: Reuse timer when rescheduling missing frames

This commit is contained in:
Vicki Pfau 2021-07-09 02:45:49 -07:00
parent 386c4a6cc5
commit 1358000d74
2 changed files with 21 additions and 5 deletions

View File

@ -50,7 +50,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
m_painter = std::make_unique<PainterGL>(windowHandle(), format);
m_drawThread.setObjectName("Painter Thread");
m_painter->moveToThread(&m_drawThread);
m_painter->setThread(&m_drawThread);
connect(&m_drawThread, &QThread::started, m_painter.get(), &PainterGL::create);
connect(m_painter.get(), &PainterGL::started, this, [this] {
@ -263,6 +263,8 @@ PainterGL::PainterGL(QWindow* surface, const QSurfaceFormat& format)
for (auto& buf : m_buffers) {
m_free.append(&buf.front());
}
connect(&m_drawTimer, &QTimer::timeout, this, &PainterGL::draw);
m_drawTimer.setSingleShot(true);
}
PainterGL::~PainterGL() {
@ -271,6 +273,11 @@ PainterGL::~PainterGL() {
}
}
void PainterGL::setThread(QThread* thread) {
moveToThread(thread);
m_drawTimer.moveToThread(thread);
}
void PainterGL::makeCurrent() {
m_gl->makeCurrent(m_surface);
#if defined(_WIN32) && defined(USE_EPOXY)
@ -433,8 +440,14 @@ void PainterGL::draw() {
mCoreSync* sync = &m_context->thread()->impl->sync;
if (!mCoreSyncWaitFrameStart(sync)) {
mCoreSyncWaitFrameEnd(sync);
if ((sync->audioWait || sync->videoFrameWait) && m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) {
QTimer::singleShot(1, this, &PainterGL::draw);
if (!sync->audioWait && !sync->videoFrameWait) {
return;
}
if (m_delayTimer.elapsed() >= 1000 / m_surface->screen()->refreshRate()) {
return;
}
if (!m_drawTimer.isActive()) {
m_drawTimer.start(1);
}
return;
}
@ -478,6 +491,7 @@ void PainterGL::forceDraw() {
}
void PainterGL::stop() {
m_drawTimer.stop();
m_active = false;
m_started = false;
dequeueAll(false);
@ -501,6 +515,7 @@ void PainterGL::stop() {
}
void PainterGL::pause() {
m_drawTimer.stop();
m_active = false;
dequeueAll(true);
}

View File

@ -96,11 +96,13 @@ public:
PainterGL(QWindow* surface, const QSurfaceFormat& format);
~PainterGL();
void setThread(QThread*);
void setContext(std::shared_ptr<CoreController>);
void setMessagePainter(MessagePainter*);
void enqueue(const uint32_t* backing);
bool supportsShaders() const { return m_supportsShaders; }
int glTex();
void setVideoProxy(std::shared_ptr<VideoProxy>);
void interrupt();
@ -127,8 +129,6 @@ public slots:
void clearShaders();
VideoShader* shaders();
int glTex();
signals:
void started();
@ -150,6 +150,7 @@ private:
std::unique_ptr<QOpenGLContext> m_gl;
bool m_active = false;
bool m_started = false;
QTimer m_drawTimer;
std::shared_ptr<CoreController> m_context;
CoreController::Interrupter m_interrupter;
bool m_supportsShaders;