summaryrefslogtreecommitdiffstats
path: root/src/render/services
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-08-11 10:12:57 +0200
committerPaul Lemire <paul.lemire@kdab.com>2017-08-11 13:07:16 +0000
commitaa16ae56f6a3f559e4d195717fbdb9c57c7579cd (patch)
tree1ba119dc4b0c09f02d0c66d27b05bcc0e19372ed /src/render/services
parent7fcece168ebe2ab2ea8a8d28eadcf3206803e351 (diff)
VSyncFrameAdvanceService: fix Scene3D rendering
When rendering with Scene3D it could be that doRender() is called a lot more times than the speed at which the Qt3D simulation loop is running (this happens when resizing the window) This results in vsyncFrameAdvance->proceedToNextFrame() being called while the simulation isn't in a waiting state (simulation loop not yet blocking on vsyncFrameAdvance->waitForNextFrame()). This means that when the simulation loop finally unlocks, it would be able to make several loops for a given frame. Obviously this is really dangerous as the simulation loop drives the synching of changes and this could result in the data being prepared by the render jobs and the actual data in the managers to be corrupt. To fix that, vsyncFrameAdvance->waitForNextFrame() now acquires all available resources + 1 to cope with proceedToNextFrame being called more than once. Obviously this doesn't happen when Qt3D drives the rendering and the VSyncFrameAdvanceService was adjusted to have different behaviors depending on whether we are rendering with Scene3D or not. Change-Id: I495779571256d132fa7e1b3b31114f737de35a71 Task-number: QTBUG-60613 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/services')
-rw-r--r--src/render/services/vsyncframeadvanceservice.cpp20
-rw-r--r--src/render/services/vsyncframeadvanceservice_p.h2
2 files changed, 17 insertions, 5 deletions
diff --git a/src/render/services/vsyncframeadvanceservice.cpp b/src/render/services/vsyncframeadvanceservice.cpp
index 533b0fba1..880985aea 100644
--- a/src/render/services/vsyncframeadvanceservice.cpp
+++ b/src/render/services/vsyncframeadvanceservice.cpp
@@ -52,20 +52,22 @@ namespace Render {
class VSyncFrameAdvanceServicePrivate Q_DECL_FINAL : public Qt3DCore::QAbstractFrameAdvanceServicePrivate
{
public:
- VSyncFrameAdvanceServicePrivate()
+ explicit VSyncFrameAdvanceServicePrivate(bool drivenByRenderThread)
: QAbstractFrameAdvanceServicePrivate(QStringLiteral("Renderer Aspect Frame Advance Service - aligned with vsync"))
, m_semaphore(0)
, m_elapsedTimeSincePreviousFrame(0)
+ , m_drivenByRenderThread(drivenByRenderThread)
{
}
QSemaphore m_semaphore;
QElapsedTimer m_elapsed;
quint64 m_elapsedTimeSincePreviousFrame;
+ bool m_drivenByRenderThread;
};
-VSyncFrameAdvanceService::VSyncFrameAdvanceService()
- : QAbstractFrameAdvanceService(*new VSyncFrameAdvanceServicePrivate())
+VSyncFrameAdvanceService::VSyncFrameAdvanceService(bool drivenByRenderThread)
+ : QAbstractFrameAdvanceService(*new VSyncFrameAdvanceServicePrivate(drivenByRenderThread))
{
}
@@ -77,7 +79,17 @@ VSyncFrameAdvanceService::~VSyncFrameAdvanceService()
qint64 VSyncFrameAdvanceService::waitForNextFrame()
{
Q_D(VSyncFrameAdvanceService);
- d->m_semaphore.acquire(1);
+
+ // When rendering with Scene3D, we always want to acquire the available
+ // amount + 1 to handle the cases where for some reason proceedToNextFrame
+ // is being called more than once between calls to waitForNextFrame This
+ // could be the case when resizing the window
+
+ // When Qt3D is driving rendering however, this shouldn't happen
+ if (d->m_drivenByRenderThread)
+ d->m_semaphore.acquire(1);
+ else
+ d->m_semaphore.acquire(d->m_semaphore.available() + 1);
const quint64 currentTime = d->m_elapsed.nsecsElapsed();
qCDebug(VSyncAdvanceService) << "Elapsed nsecs since last call " << currentTime - d->m_elapsedTimeSincePreviousFrame;
diff --git a/src/render/services/vsyncframeadvanceservice_p.h b/src/render/services/vsyncframeadvanceservice_p.h
index 98daebf81..f33d41b98 100644
--- a/src/render/services/vsyncframeadvanceservice_p.h
+++ b/src/render/services/vsyncframeadvanceservice_p.h
@@ -64,7 +64,7 @@ class VSyncFrameAdvanceServicePrivate;
class Q_AUTOTEST_EXPORT VSyncFrameAdvanceService Q_DECL_FINAL : public Qt3DCore::QAbstractFrameAdvanceService
{
public:
- VSyncFrameAdvanceService();
+ explicit VSyncFrameAdvanceService(bool drivenByRenderThread);
~VSyncFrameAdvanceService();
qint64 waitForNextFrame() Q_DECL_FINAL;