diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2017-05-05 11:23:46 +0200 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2017-05-06 19:15:53 +0000 |
commit | bb0f4b48390b5ddc9758f04f6ecd692072fb279f (patch) | |
tree | 780e7f75bf1b708b5c5c2de85a61c4431302102d /src/quick3d/imports/scene3d/scene3drenderer.cpp | |
parent | 4baec347253b14a934cb9f6bcba420adbb09ee35 (diff) |
Scene3DRenderer: fix race conditionv5.9.0-beta4
When the window geometry changes, the Scene3DRenderer was updating
a Qt3D frontend node's property from the QSGRenderThread.
This resulted in the QPostman::notifyBackend being called from possibly two threads at the same time,
resulting in a race condition where the changes would never be submitted again to the backend.
Change-Id: I842aaa54637d85d4d45eb54620749efb36168e2a
Task-number: QTBUG-54900
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Reviewed-by: Oleg Evseev <ev.mipt@gmail.com>
Diffstat (limited to 'src/quick3d/imports/scene3d/scene3drenderer.cpp')
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 88f3be3c1..b32191391 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -57,6 +57,17 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +namespace { + +inline QMetaMethod setItemAreaMethod() +{ + const int idx = Scene3DItem::staticMetaObject.indexOfMethod("setItemArea(QSize)"); + Q_ASSERT(idx != -1); + return Scene3DItem::staticMetaObject.method(idx); +} + +} // anonymous + class ContextSaver { public: @@ -250,8 +261,11 @@ void Scene3DRenderer::render() const bool multisampleHasChanged = m_multisample != m_lastMultisample; const bool forceRecreate = sizeHasChanged || multisampleHasChanged; - if (sizeHasChanged) - m_item->setItemArea(boundingRectSize); + if (sizeHasChanged) { + // We are in the QSGRenderThread (doing a direct call would result in a race) + static const QMetaMethod setItemArea = setItemAreaMethod(); + setItemArea.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize)); + } // Rebuild FBO and textures if never created or a resize has occurred if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) { |