diff options
author | Mike Krus <mike.krus@kdab.com> | 2019-10-23 07:19:49 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2019-10-28 17:47:13 +0000 |
commit | e5723fd820f5ae2c103c8985ea2d5d27d9bb7ee4 (patch) | |
tree | 03130379c8ea16e100d94f07c24b89e7853c59ac /src | |
parent | 1597b809a90138afc81fabbe96ffe2be98abc9de (diff) |
Fix frame advance service
on macOS, blocking the main thread waiting for current frame to finish
can lead to events flooding the event queue. In particular, moving the
mouse over the window causes the QBasicTimer used by the uniform
timer that drives (qtquick) animations to no longer fire.
Use tryAcquire to get the resources, waiting a short while to avoid
busy main thread.
Task-number: QTBUG-79379
Change-Id: I930aa8ad7d5a15600d7ac7af93e6e72321457089
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/aspects/qaspectmanager.cpp | 6 | ||||
-rw-r--r-- | src/render/services/vsyncframeadvanceservice.cpp | 11 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp index dffdd1c1a..f24248399 100644 --- a/src/core/aspects/qaspectmanager.cpp +++ b/src/core/aspects/qaspectmanager.cpp @@ -414,6 +414,8 @@ bool QAspectManager::event(QEvent *e) // the loop if (m_simulationLoopRunning && m_driveMode == QAspectEngine::Automatic) requestNextFrame(); + + return true; } return QObject::event(e); @@ -424,7 +426,7 @@ void QAspectManager::requestNextFrame() qCDebug(Aspects) << "Requesting new Frame"; // Post event in the event loop to force // next frame to be processed - qApp->postEvent(this, new RequestFrameEvent()); + QCoreApplication::postEvent(this, new RequestFrameEvent()); } void QAspectManager::processFrame() @@ -436,6 +438,8 @@ void QAspectManager::processFrame() m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService); const qint64 t = frameAdvanceService->waitForNextFrame(); + if (t < 0) + return; // Distribute accumulated changes. This includes changes sent from the frontend // to the backend nodes. We call this before the call to m_scheduler->update() to ensure diff --git a/src/render/services/vsyncframeadvanceservice.cpp b/src/render/services/vsyncframeadvanceservice.cpp index b49870e68..d7398e2ce 100644 --- a/src/render/services/vsyncframeadvanceservice.cpp +++ b/src/render/services/vsyncframeadvanceservice.cpp @@ -62,7 +62,7 @@ public: QSemaphore m_semaphore; QElapsedTimer m_elapsed; - quint64 m_elapsedTimeSincePreviousFrame; + qint64 m_elapsedTimeSincePreviousFrame; bool m_drivenByRenderThread; }; @@ -75,14 +75,19 @@ VSyncFrameAdvanceService::~VSyncFrameAdvanceService() { } -// Aspect Thread +// Main Thread qint64 VSyncFrameAdvanceService::waitForNextFrame() { Q_D(VSyncFrameAdvanceService); +#ifdef Q_OS_MACOS + if (!d->m_semaphore.tryAcquire(std::max(d->m_semaphore.available(), 1), 4)) + return -1; +#else d->m_semaphore.acquire(std::max(d->m_semaphore.available(), 1)); +#endif - const quint64 currentTime = d->m_elapsed.nsecsElapsed(); + const qint64 currentTime = d->m_elapsed.nsecsElapsed(); qCDebug(VSyncAdvanceService) << "Elapsed nsecs since last call " << currentTime - d->m_elapsedTimeSincePreviousFrame; d->m_elapsedTimeSincePreviousFrame = currentTime; return currentTime; |