diff options
author | Mike Krus <mike.krus@kdab.com> | 2020-02-17 22:06:33 +0000 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2020-02-17 22:06:44 +0000 |
commit | 67c9d9e9e665bb5754ffcdd5963189d73672f5a7 (patch) | |
tree | 2168cae3806c937ce1f1ce8faacdf83fe6c35df1 /src/render | |
parent | 8f9a0e499243915aca0e719fef0a5bb075542ea4 (diff) | |
parent | aa7c8a5cb1111d46289e6b370dcd5b1d3f66c80d (diff) |
Merge remote-tracking branch 5.15 into dev
Change-Id: I2777f6a40b9029ef5569a84e04f9e18a914504e7
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/backend/attachmentpack.cpp | 26 | ||||
-rw-r--r-- | src/render/backend/attachmentpack_p.h | 6 | ||||
-rw-r--r-- | src/render/backend/managers_p.h | 44 | ||||
-rw-r--r-- | src/render/backend/rendertarget.cpp | 28 | ||||
-rw-r--r-- | src/render/backend/rendertarget_p.h | 15 | ||||
-rw-r--r-- | src/render/framegraph/qframegraphnode.cpp | 82 | ||||
-rw-r--r-- | src/render/frontend/qrenderaspect.cpp | 2 | ||||
-rw-r--r-- | src/render/jobs/genericlambdajob_p.h | 8 | ||||
-rw-r--r-- | src/render/jobs/pickboundingvolumejob.cpp | 13 | ||||
-rw-r--r-- | src/render/jobs/raycastingjob.cpp | 14 | ||||
-rw-r--r-- | src/render/jobs/updatelevelofdetailjob.cpp | 14 | ||||
-rw-r--r-- | src/render/materialsystem/shader.cpp | 8 | ||||
-rw-r--r-- | src/render/materialsystem/shader_p.h | 2 | ||||
-rw-r--r-- | src/render/texture/qtextureimagedata.h | 8 |
14 files changed, 240 insertions, 30 deletions
diff --git a/src/render/backend/attachmentpack.cpp b/src/render/backend/attachmentpack.cpp index a2ac8c30c..0cd5d8673 100644 --- a/src/render/backend/attachmentpack.cpp +++ b/src/render/backend/attachmentpack.cpp @@ -88,6 +88,32 @@ int AttachmentPack::getDrawBufferIndex(QRenderTargetOutput::AttachmentPoint atta return -1; } +bool operator ==(const Attachment &a, const Attachment &b) +{ + return (a.m_name == b.m_name && + a.m_mipLevel == b.m_mipLevel && + a.m_layer == b.m_layer && + a.m_textureUuid == b.m_textureUuid && + a.m_point == b.m_point && + a.m_face == b.m_face); +} + +bool operator !=(const Attachment &a, const Attachment &b) +{ + return !(a == b); +} + +bool operator ==(const AttachmentPack &packA, const AttachmentPack &packB) +{ + return (packA.attachments() == packB.attachments() && + packA.getGlDrawBuffers() == packB.getGlDrawBuffers()); +} + +bool operator !=(const AttachmentPack &packA, const AttachmentPack &packB) +{ + return !(packA == packB); +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/backend/attachmentpack_p.h b/src/render/backend/attachmentpack_p.h index 32ea774b6..7f3733a65 100644 --- a/src/render/backend/attachmentpack_p.h +++ b/src/render/backend/attachmentpack_p.h @@ -100,6 +100,12 @@ private: QVector<int> m_drawBuffers; }; +Q_3DRENDERSHARED_PRIVATE_EXPORT bool operator ==(const Attachment &a, const Attachment &b); +Q_3DRENDERSHARED_PRIVATE_EXPORT bool operator !=(const Attachment &a, const Attachment &b); + +Q_3DRENDERSHARED_PRIVATE_EXPORT bool operator ==(const AttachmentPack &packA, const AttachmentPack &packB); +Q_3DRENDERSHARED_PRIVATE_EXPORT bool operator !=(const AttachmentPack &packA, const AttachmentPack &packB); + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h index db12a8a7b..a3d42d24a 100644 --- a/src/render/backend/managers_p.h +++ b/src/render/backend/managers_p.h @@ -211,6 +211,21 @@ public: m_shaderIdsToCleanup.push_back(id); } + void removeShaderIdFromIdsToCleanup(Qt3DCore::QNodeId id) + { + m_shaderIdsToCleanup.removeAll(id); + } + + bool hasShaderIdToCleanup(Qt3DCore::QNodeId id) const + { + return m_shaderIdsToCleanup.contains(id); + } + + QVector<Qt3DCore::QNodeId> shaderIdsToCleanup() const + { + return m_shaderIdsToCleanup; + } + // Called by RenderThread in updateGLResources (locked) QVector<Qt3DCore::QNodeId> takeShaderIdsToCleanup() { @@ -285,6 +300,35 @@ class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderTargetManager : public Qt3DCore::QRe { public: RenderTargetManager() {} + + // Called in AspectThread by RenderTarget node functor destroy + void addRenderTargetIdToCleanup(Qt3DCore::QNodeId id) + { + m_renderTargetIdsToCleanup.push_back(id); + } + + // Called in AspectThread by RenderTarget node functor create + void removeRenderTargetToCleanup(Qt3DCore::QNodeId id) + { + m_renderTargetIdsToCleanup.removeAll(id); + } + + // Called by RenderThread in updateGLResources (locked) + QVector<Qt3DCore::QNodeId> takeRenderTargetIdsToCleanup() + { + return std::move(m_renderTargetIdsToCleanup); + } + +#ifdef QT_BUILD_INTERNAL + // For unit testing purposes only + QVector<Qt3DCore::QNodeId> renderTargetIdsToCleanup() const + { + return m_renderTargetIdsToCleanup; + } +#endif + +private: + QVector<Qt3DCore::QNodeId> m_renderTargetIdsToCleanup; }; class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderPassManager : public Qt3DCore::QResourceManager< diff --git a/src/render/backend/rendertarget.cpp b/src/render/backend/rendertarget.cpp index 088818c94..afe4bc23b 100644 --- a/src/render/backend/rendertarget.cpp +++ b/src/render/backend/rendertarget.cpp @@ -41,6 +41,7 @@ #include <Qt3DRender/qrendertarget.h> #include <Qt3DRender/private/qrendertarget_p.h> #include <Qt3DRender/qrendertargetoutput.h> +#include <Qt3DRender/private/managers_p.h> #include <QVariant> QT_BEGIN_NAMESPACE @@ -94,6 +95,33 @@ QVector<Qt3DCore::QNodeId> RenderTarget::renderOutputs() const return m_renderOutputs; } +RenderTargetFunctor::RenderTargetFunctor(AbstractRenderer *renderer, RenderTargetManager *manager) + : m_renderer(renderer) + , m_renderTargetManager(manager) +{ +} + +QBackendNode *RenderTargetFunctor::create(QNodeId id) const +{ + RenderTarget *backend = m_renderTargetManager->getOrCreateResource(id); + // Remove from the list of ids to destroy in case we were added to it + m_renderTargetManager->removeRenderTargetToCleanup(id); + backend->setRenderer(m_renderer); + return backend; +} + +QBackendNode *RenderTargetFunctor::get(QNodeId id) const +{ + return m_renderTargetManager->lookupResource(id); +} + +void RenderTargetFunctor::destroy(QNodeId id) const +{ + // We add ourselves to the dirty list to tell the renderer that this rendertarget has been destroyed + m_renderTargetManager->addRenderTargetIdToCleanup(id); + m_renderTargetManager->releaseResource(id); +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/backend/rendertarget_p.h b/src/render/backend/rendertarget_p.h index eeaf94940..67465cc1e 100644 --- a/src/render/backend/rendertarget_p.h +++ b/src/render/backend/rendertarget_p.h @@ -82,6 +82,21 @@ private: QVector<Qt3DCore::QNodeId> m_renderOutputs; }; +class Q_AUTOTEST_EXPORT RenderTargetFunctor : public Qt3DCore::QBackendNodeMapper +{ +public: + explicit RenderTargetFunctor(AbstractRenderer *renderer, + RenderTargetManager *manager); + Qt3DCore::QBackendNode *create(Qt3DCore::QNodeId id) const final; + Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const final; + void destroy(Qt3DCore::QNodeId id) const final; + +private: + AbstractRenderer *m_renderer; + RenderTargetManager *m_renderTargetManager; +}; + + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/framegraph/qframegraphnode.cpp b/src/render/framegraph/qframegraphnode.cpp index 797e24324..489fa03b4 100644 --- a/src/render/framegraph/qframegraphnode.cpp +++ b/src/render/framegraph/qframegraphnode.cpp @@ -41,7 +41,7 @@ #include "qframegraphnode_p.h" #include <Qt3DCore/QNode> - +#include <QVector> #include <QQueue> using namespace Qt3DCore; @@ -59,35 +59,87 @@ QString dumpNode(const Qt3DRender::QFrameGraphNode *n) { return res; } -QStringList dumpFG(const Qt3DRender::QFrameGraphNode *n, int level = 0) +QStringList dumpFG(const Qt3DCore::QNode *n, int level = 0) { QStringList reply; - QString res = dumpNode(n); - reply += res.rightJustified(res.length() + level * 2, ' '); + + const Qt3DRender::QFrameGraphNode *fgNode = qobject_cast<const Qt3DRender::QFrameGraphNode *>(n); + if (fgNode) { + QString res = dumpNode(fgNode); + reply += res.rightJustified(res.length() + level * 2, ' '); + } const auto children = n->childNodes(); + const int inc = fgNode ? 1 : 0; for (auto *child: children) { - auto *childFGNode = qobject_cast<Qt3DRender::QFrameGraphNode *>(child); + auto *childFGNode = qobject_cast<Qt3DCore::QNode *>(child); if (childFGNode != nullptr) - reply += dumpFG(childFGNode, level + 1); + reply += dumpFG(childFGNode, level + inc); } return reply; } -void dumpFGPaths(const Qt3DRender::QFrameGraphNode *n, QStringList &result, QStringList parents = {}) +struct HierarchyFGNode +{ + const Qt3DRender::QFrameGraphNode *root; + QVector<QSharedPointer<HierarchyFGNode>> children; +}; +using HierarchyFGNodePtr = QSharedPointer<HierarchyFGNode>; + +HierarchyFGNodePtr buildFGHierarchy(const Qt3DCore::QNode *n, HierarchyFGNodePtr lastFGParent = HierarchyFGNodePtr()) { - parents += dumpNode(n); + const Qt3DRender::QFrameGraphNode *fgNode = qobject_cast<const Qt3DRender::QFrameGraphNode *>(n); + + // Only happens for the root case + if (!lastFGParent) { + lastFGParent = HierarchyFGNodePtr::create(); + lastFGParent->root = fgNode; + } else { + if (fgNode != nullptr) { + HierarchyFGNodePtr hN = HierarchyFGNodePtr::create(); + hN->root = fgNode; + if (lastFGParent) + lastFGParent->children.push_back(hN); + lastFGParent = hN; + } + } const auto children = n->childNodes(); - if (children.length()) { - for (auto *child: children) { - auto *childFGNode = qobject_cast<Qt3DRender::QFrameGraphNode *>(child); - if (childFGNode != nullptr) - dumpFGPaths(childFGNode, result, parents); + for (auto *child: children) + buildFGHierarchy(child, lastFGParent); + + return lastFGParent; +} + +void findFGLeaves(const HierarchyFGNodePtr root, QVector<const Qt3DRender::QFrameGraphNode *> &fgLeaves) +{ + const auto children = root->children; + for (const auto &child : children) + findFGLeaves(child, fgLeaves); + + if (children.empty()) + fgLeaves.push_back(root->root); +} + +void dumpFGPaths(const Qt3DRender::QFrameGraphNode *n, QStringList &result) +{ + // Build FG node hierarchy + const HierarchyFGNodePtr rootHFg = buildFGHierarchy(n); + + // Gather FG leaves + QVector<const Qt3DRender::QFrameGraphNode *> fgLeaves; + findFGLeaves(rootHFg, fgLeaves); + + // Traverse back to root + for (const Qt3DRender::QFrameGraphNode *fgNode : fgLeaves) { + QStringList parents; + while (fgNode != nullptr) { + parents.prepend(dumpNode(fgNode)); + fgNode = fgNode->parentFrameGraphNode(); } - } else { - result << QLatin1String("[ ") + parents.join(QLatin1String(", ")) + QLatin1String(" ]"); + if (parents.size()) + result << QLatin1String("[ ") + parents.join(QLatin1String(", ")) + QLatin1String(" ]"); } } diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index fa6416199..e929f532f 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -283,7 +283,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QLevelOfDetail>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); q->registerBackendType<QLevelOfDetailSwitch>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); q->registerBackendType<QSceneLoader>(QSharedPointer<Render::RenderSceneFunctor>::create(m_renderer, m_nodeManagers->sceneManager())); - q->registerBackendType<QRenderTarget>(QSharedPointer<Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager> >::create(m_renderer)); + q->registerBackendType<QRenderTarget>(QSharedPointer<Render::RenderTargetFunctor>::create(m_renderer, m_nodeManagers->renderTargetManager())); q->registerBackendType<QRenderTargetOutput>(QSharedPointer<Render::NodeFunctor<Render::RenderTargetOutput, Render::AttachmentManager> >::create(m_renderer)); q->registerBackendType<QRenderSettings>(QSharedPointer<Render::RenderSettingsFunctor>::create(m_renderer)); q->registerBackendType<QRenderState>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer)); diff --git a/src/render/jobs/genericlambdajob_p.h b/src/render/jobs/genericlambdajob_p.h index 8cf4276f6..994cd3a14 100644 --- a/src/render/jobs/genericlambdajob_p.h +++ b/src/render/jobs/genericlambdajob_p.h @@ -64,11 +64,11 @@ template<typename T> class GenericLambdaJob : public Qt3DCore::QAspectJob { public: - explicit GenericLambdaJob(T callable, JobTypes::JobType type = JobTypes::GenericLambda) + explicit GenericLambdaJob(T callable, JobTypes::JobType type = JobTypes::GenericLambda, const char *name = "GenericLambda") : Qt3DCore::QAspectJob() , m_callable(callable) { - SET_JOB_RUN_STAT_TYPE(this, type, 0) + SET_JOB_RUN_STAT_TYPE_AND_NAME(this, type, name, 0) } // QAspectJob interface @@ -107,11 +107,11 @@ template<typename T, typename U> class GenericLambdaJobAndPostFrame : public Qt3DCore::QAspectJob { public: - explicit GenericLambdaJobAndPostFrame(T runCallable, U postFrameCallable, JobTypes::JobType type = JobTypes::GenericLambda) + explicit GenericLambdaJobAndPostFrame(T runCallable, U postFrameCallable, JobTypes::JobType type = JobTypes::GenericLambda, const char *name = "GenericLambda") : Qt3DCore::QAspectJob(*new GenericLambdaJobAndPostFramePrivate<T, U>(postFrameCallable)) , m_runCallable(runCallable) { - SET_JOB_RUN_STAT_TYPE(this, type, 0) + SET_JOB_RUN_STAT_TYPE_AND_NAME(this, type, name, 0) } // QAspectJob interface diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index dce184f46..96610f9f7 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -71,9 +71,10 @@ namespace Render { class PickBoundingVolumeJobPrivate : public Qt3DCore::QAspectJobPrivate { public: - PickBoundingVolumeJobPrivate() = default; + PickBoundingVolumeJobPrivate(PickBoundingVolumeJob *q) : q_ptr(q) { } ~PickBoundingVolumeJobPrivate() override = default; + bool isRequired() override; void postFrame(Qt3DCore::QAspectManager *manager) override; enum CustomEventType { @@ -88,9 +89,17 @@ public: }; QVector<EventDetails> dispatches; + PickBoundingVolumeJob *q_ptr; + Q_DECLARE_PUBLIC(PickBoundingVolumeJob) }; +bool PickBoundingVolumeJobPrivate::isRequired() +{ + Q_Q(PickBoundingVolumeJob); + return !q->m_pendingMouseEvents.isEmpty() || q->m_pickersDirty || q->m_oneEnabledAtLeast; +} + void PickBoundingVolumeJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) { using namespace Qt3DCore; @@ -188,7 +197,7 @@ void setEventButtonAndModifiers(const QMouseEvent &event, QPickEvent::Buttons &e } // anonymous PickBoundingVolumeJob::PickBoundingVolumeJob() - : AbstractPickingJob(*new PickBoundingVolumeJobPrivate) + : AbstractPickingJob(*new PickBoundingVolumeJobPrivate(this)) , m_pickersDirty(true) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::PickBoundingVolume, 0) diff --git a/src/render/jobs/raycastingjob.cpp b/src/render/jobs/raycastingjob.cpp index 50dcaecde..df01213f0 100644 --- a/src/render/jobs/raycastingjob.cpp +++ b/src/render/jobs/raycastingjob.cpp @@ -86,15 +86,25 @@ public: class Qt3DRender::Render::RayCastingJobPrivate : public Qt3DCore::QAspectJobPrivate { public: - RayCastingJobPrivate() { } + RayCastingJobPrivate(RayCastingJob *q) : q_ptr(q) { } ~RayCastingJobPrivate() override { Q_ASSERT(dispatches.isEmpty()); } + bool isRequired() override; void postFrame(Qt3DCore::QAspectManager *manager) override; QVector<QPair<RayCaster *, QAbstractRayCaster::Hits>> dispatches; + + RayCastingJob *q_ptr; + Q_DECLARE_PUBLIC(RayCastingJob) }; +bool RayCastingJobPrivate::isRequired() +{ + Q_Q(RayCastingJob); + return q->m_castersDirty || q->m_oneEnabledAtLeast; +} + void RayCastingJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) { for (auto res: qAsConst(dispatches)) { @@ -116,7 +126,7 @@ void RayCastingJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) RayCastingJob::RayCastingJob() - : AbstractPickingJob(*new RayCastingJobPrivate()) + : AbstractPickingJob(*new RayCastingJobPrivate(this)) , m_castersDirty(true) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::RayCasting, 0) diff --git a/src/render/jobs/updatelevelofdetailjob.cpp b/src/render/jobs/updatelevelofdetailjob.cpp index 0a28b7628..946d3bca8 100644 --- a/src/render/jobs/updatelevelofdetailjob.cpp +++ b/src/render/jobs/updatelevelofdetailjob.cpp @@ -210,15 +210,19 @@ namespace Render { class UpdateLevelOfDetailJobPrivate : public Qt3DCore::QAspectJobPrivate { public: - UpdateLevelOfDetailJobPrivate() { } + UpdateLevelOfDetailJobPrivate(UpdateLevelOfDetailJob *q) : q_ptr(q) { } + bool isRequired() override; void postFrame(Qt3DCore::QAspectManager *manager) override; QVector<QPair<Qt3DCore::QNodeId, int>> m_updatedIndices; + + UpdateLevelOfDetailJob *q_ptr; + Q_DECLARE_PUBLIC(UpdateLevelOfDetailJob) }; UpdateLevelOfDetailJob::UpdateLevelOfDetailJob() - : Qt3DCore::QAspectJob(*new UpdateLevelOfDetailJobPrivate) + : Qt3DCore::QAspectJob(*new UpdateLevelOfDetailJobPrivate(this)) , m_manager(nullptr) , m_frameGraphRoot(nullptr) , m_root(nullptr) @@ -262,6 +266,12 @@ void UpdateLevelOfDetailJob::run() d->m_updatedIndices = visitor.updatedIndices(); } +bool UpdateLevelOfDetailJobPrivate::isRequired() +{ + Q_Q(UpdateLevelOfDetailJob); + return q->m_manager->levelOfDetailManager()->count() > 0; +} + void UpdateLevelOfDetailJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) { for (const auto &updatedNode: qAsConst(m_updatedIndices)) { diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index ff56a74e9..d0e2e9a76 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -189,15 +189,21 @@ ShaderFunctor::ShaderFunctor(AbstractRenderer *renderer, ShaderManager *manager) { } -QBackendNode *ShaderFunctor::create(const QNodeId id) const +QBackendNode *ShaderFunctor::create(QNodeId id) const { Shader *backend = m_shaderManager->getOrCreateResource(id); + // Remove from the list of ids to destroy in case we were added to it + m_shaderManager->removeShaderIdFromIdsToCleanup(id); backend->setRenderer(m_renderer); return backend; } QBackendNode *ShaderFunctor::get(QNodeId id) const { + // If we are marked for destruction, return nullptr so that + // if we were to be recreated, create would be called again + if (m_shaderManager->hasShaderIdToCleanup(id)) + return nullptr; return m_shaderManager->lookupResource(id); } diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index 8f78163be..31603bcf7 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -140,7 +140,7 @@ inline QDebug operator<<(QDebug dbg, const Shader &shader) } #endif -class ShaderFunctor : public Qt3DCore::QBackendNodeMapper +class Q_AUTOTEST_EXPORT ShaderFunctor : public Qt3DCore::QBackendNodeMapper { public: explicit ShaderFunctor(AbstractRenderer *renderer, diff --git a/src/render/texture/qtextureimagedata.h b/src/render/texture/qtextureimagedata.h index 5bc71480e..8daf1becb 100644 --- a/src/render/texture/qtextureimagedata.h +++ b/src/render/texture/qtextureimagedata.h @@ -40,10 +40,14 @@ #ifndef QT3DRENDER_TEXTUREIMAGEDATA_H #define QT3DRENDER_TEXTUREIMAGEDATA_H -#include <QOpenGLTexture> +#include <Qt3DRender/qt3drender_global.h> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +# include <QOpenGLTexture> +#else +# include <QtGui/qopengltexture.h> +#endif #include <QtGui/QImage> #include <QtCore/QSharedPointer> -#include <Qt3DRender/qt3drender_global.h> QT_BEGIN_NAMESPACE |