summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-10-23 07:19:49 +0100
committerMike Krus <mike.krus@kdab.com>2019-10-28 17:47:13 +0000
commite5723fd820f5ae2c103c8985ea2d5d27d9bb7ee4 (patch)
tree03130379c8ea16e100d94f07c24b89e7853c59ac /src
parent1597b809a90138afc81fabbe96ffe2be98abc9de (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.cpp6
-rw-r--r--src/render/services/vsyncframeadvanceservice.cpp11
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;