aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-03-17 18:40:02 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-03-18 10:17:01 +0100
commitb1e89b57667c95f3ad81076b5fd3c57272435450 (patch)
tree7a62a919594bb5c8e8688a13f4d649b8b88bbed6 /src/quick
parent869efe4a49c5286493d7f039325992725bcac6c3 (diff)
rhi: Enable layer updateTexture(), and so grabs, in the sync phase
Calling updateTexture() from an updatePaintNode() implementation means we are still in the synchronization phase, with the render step (as in QQuickWindow::renderSceneGraph()) not started yet. Make sure the QRhiCommandBuffer is sent around early enough, so it is usable by QSGRhiLayer already during sync. There is no use case for this in Qt Quick itself since all standard items invoke updateTexture() from QSGNode::preprocess() (which is part of the render, not the sync, step), but Qt Quick 3D relies on this in Texture.sourceItem. This should fix the sourceitem manual test in Qt Quick 3D, so that it will not crash anymore when running with RHI enabled. Task-number: QTBUG-82927 Change-Id: I38adf512e49b1c6eef4730cd23663d351725d6cd Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickwindow.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp8
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp3
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp9
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h2
6 files changed, 18 insertions, 8 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 50777ef03d..0b12b13978 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -430,7 +430,7 @@ void QQuickWindowPrivate::syncSceneGraph()
if (renderTargetId && !QQuickRenderControl::renderWindowFor(q))
devicePixelRatio = 1;
- context->prepareSync(devicePixelRatio);
+ context->prepareSync(devicePixelRatio, rhi ? swapchain->currentFrameCommandBuffer() : nullptr);
animationController->beforeNodeSync();
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index 715633fdba..418aaca605 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -842,11 +842,15 @@ void QSGTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *res
/*!
\fn bool QSGDynamicTexture::updateTexture()
- Call this function to explicitly update the dynamic texture. Calling bind() will bind
- the content that was previously updated.
+ Call this function to explicitly update the dynamic texture.
The function returns true if the texture was changed as a resul of the update; otherwise
returns false.
+
+ \note This function is typically called from QQuickItem::updatePaintNode()
+ or QSGNode::preprocess(), meaning during the \c{synchronization} or the
+ \c{node preprocessing} phases of the scenegraph. Calling it at other times
+ is discouraged and can lead to unexpected behavior.
*/
/*!
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 17eb1e312c..e3c951e5ed 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -341,9 +341,10 @@ void QSGRenderContext::invalidate()
{
}
-void QSGRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
Q_UNUSED(devicePixelRatio);
+ Q_UNUSED(cb);
}
void QSGRenderContext::beginNextFrame(QSGRenderer *renderer,
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 244bcfabd1..d389420907 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -174,7 +174,7 @@ public:
using RenderPassCallback = void (*)(void *);
- virtual void prepareSync(qreal devicePixelRatio);
+ virtual void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb);
virtual void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index e8c3ac4abb..b5bf56649b 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -200,9 +200,14 @@ void QSGDefaultRenderContext::invalidate()
emit invalidated();
}
-void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
m_currentDevicePixelRatio = devicePixelRatio;
+
+ // we store the command buffer already here, in case there is something in
+ // an updatePaintNode() implementation that leads to needing it (for
+ // example, an updateTexture() call on a QSGRhiLayer)
+ m_currentFrameCommandBuffer = cb;
}
static QBasicMutex qsg_framerender_mutex;
@@ -244,7 +249,7 @@ void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRende
renderer->setCommandBuffer(cb);
renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
- m_currentFrameCommandBuffer = cb;
+ m_currentFrameCommandBuffer = cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called
m_currentFrameRenderPass = rp;
}
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 2fdb3a48dd..97ed681f9a 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -104,7 +104,7 @@ public:
void initialize(const QSGRenderContext::InitParams *params) override;
void invalidate() override;
- void prepareSync(qreal devicePixelRatio) override;
+ void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) override;
void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,