From b1e89b57667c95f3ad81076b5fd3c57272435450 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 17 Mar 2020 18:40:02 +0100 Subject: 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 --- src/quick/items/qquickwindow.cpp | 2 +- src/quick/scenegraph/coreapi/qsgtexture.cpp | 8 ++++++-- src/quick/scenegraph/qsgcontext.cpp | 3 ++- src/quick/scenegraph/qsgcontext_p.h | 2 +- src/quick/scenegraph/qsgdefaultrendercontext.cpp | 9 +++++++-- src/quick/scenegraph/qsgdefaultrendercontext_p.h | 2 +- 6 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src') 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, -- cgit v1.2.3 From 61406f76198e2cd503d54b095a22a4a6ffbdcb4c Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Wed, 18 Mar 2020 14:39:48 +0100 Subject: qmlRegisterSingletonInstance: show user-friendly signature in documentation Change-Id: I50ee4c014acf3f95d00a38c6d115776143688c8e Reviewed-by: Simon Hausmann --- src/qml/doc/src/qmlfunctions.qdoc | 2 +- src/qml/qml/qqml.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 04d907f168..0ff0de1ef9 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -906,7 +906,7 @@ */ /*! - \fn template auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, T *cppObject) + \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject) \relates QQmlEngine \since 5.14 diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index a3e3f1c584..4adf100a1f 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -754,9 +754,14 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } +#ifdef Q_QDOC +int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, + const char *typeName, QObject *cppObject) +#else template inline auto qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, T *cppObject) -> typename std::enable_if::value, int>::type +#endif { QQmlPrivate::RegisterSingletonFunctor registrationFunctor; registrationFunctor.m_object = cppObject; -- cgit v1.2.3 From 266dbbef1fdc34a9740458e86f0a0ee3fffa3f98 Mon Sep 17 00:00:00 2001 From: Norihito Tohge Date: Thu, 12 Mar 2020 12:07:30 +0900 Subject: Doc: Add missing documentations of Window Type signals Task-number: QTBUG-82705 Change-Id: I78a614c47a0f7d95b2a215d94e964c1202d89bcf Reviewed-by: Shawn Rutledge Reviewed-by: Paul Wicking Reviewed-by: Laszlo Agocs --- src/quick/items/qquickwindow.cpp | 85 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 0b12b13978..de7a28d66e 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -3869,6 +3869,13 @@ bool QQuickWindow::isSceneGraphInitialized() const This signal will be emitted from the scene graph rendering thread. */ +/*! + \qmlsignal QtQuick.Window::Window::frameSwapped() + + This signal is emitted when a frame has been queued for presenting. With + vertical synchronization enabled the signal is emitted at most once per + vsync interval in a continuously animating scene. + */ /*! \fn void QQuickWindow::sceneGraphInitialized() @@ -3876,9 +3883,12 @@ bool QQuickWindow::isSceneGraphInitialized() const This signal is emitted when the scene graph has been initialized. This signal will be emitted from the scene graph rendering thread. - */ +/*! + \qmlsignal QtQuick.Window::Window::sceneGraphInitialized() + \internal + */ /*! \fn void QQuickWindow::sceneGraphInvalidated() @@ -3897,6 +3907,11 @@ bool QQuickWindow::isSceneGraphInitialized() const This signal will be emitted from the scene graph rendering thread. */ +/*! + \qmlsignal QtQuick.Window::Window::sceneGraphInvalidated() + \internal + */ + /*! \fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message) @@ -3912,6 +3927,19 @@ bool QQuickWindow::isSceneGraphInitialized() const \since 5.3 */ +/*! + \qmlsignal QtQuick.Window::Window::sceneGraphError(SceneGraphError error, QString message) + + This signal is emitted when an \a error occurred during scene graph initialization. + + You can implement onSceneGraphError(error, message) to handle errors, + such as graphics context creation failures, in a custom way. + If no handler is connected to this signal, Quick will print the \a message, + or show a message box, and terminate the application. + + \since 5.3 + */ + /*! \class QQuickCloseEvent \internal @@ -4256,6 +4284,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const \sa resetOpenGLState() */ +/*! + \qmlsignal QtQuick.Window::Window::beforeSynchronizing() + \internal +*/ + /*! \fn void QQuickWindow::afterSynchronizing() @@ -4279,6 +4312,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const \sa resetOpenGLState() */ +/*! + \qmlsignal QtQuick.Window::Window::afterSynchronizing() + \internal + \since 5.3 + */ + /*! \fn void QQuickWindow::beforeRendering() @@ -4314,6 +4353,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const \sa resetOpenGLState() */ +/*! + \qmlsignal QtQuick.Window::Window::beforeRendering() + \internal +*/ + /*! \fn void QQuickWindow::afterRendering() @@ -4347,6 +4391,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const \sa resetOpenGLState() */ +/*! + \qmlsignal QtQuick.Window::Window::afterRendering() + \internal + */ + /*! \fn void QQuickWindow::beforeRenderPassRecording() @@ -4379,6 +4428,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const \since 5.14 */ +/*! + \qmlsignal QtQuick.Window::Window::beforeRenderPassRecording() + \internal + \since 5.14 +*/ + /*! \fn void QQuickWindow::afterRenderPassRecording() @@ -4410,6 +4465,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const \since 5.14 */ +/*! + \qmlsignal QtQuick.Window::Window::afterRenderPassRecording() + \internal + \since 5.14 +*/ + /*! \fn void QQuickWindow::afterAnimating() @@ -4424,6 +4485,17 @@ QQmlIncubationController *QQuickWindow::incubationController() const \since 5.3 */ +/*! + \qmlsignal QtQuick.Window::Window::afterAnimating() + + This signal is emitted on the gui thread before requesting the render thread to + perform the synchronization of the scene graph. + + You can implement onAfterAnimating to do additional processing after each animation step. + + \since 5.3 + */ + /*! \fn void QQuickWindow::openglContextCreated(QOpenGLContext *context) @@ -4446,6 +4518,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const \since 5.3 */ +/*! + \qmlsignal QtQuick.Window::Window::openglContextCreated() + \internal + \since 5.3 + */ + /*! \fn void QQuickWindow::sceneGraphAboutToStop() @@ -4469,6 +4547,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const \since 5.3 */ +/*! + \qmlsignal QtQuick.Window::Window::sceneGraphAboutToStop() + \internal + \since 5.3 + */ /*! Sets whether the scene graph rendering of QML should clear the color buffer -- cgit v1.2.3