diff options
68 files changed, 392 insertions, 14 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index 4a432f641..dbc157a2c 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -50,6 +50,7 @@ // We mean it. // +#include <QtCore/qflags.h> #include <Qt3DRender/private/qt3drender_global_p.h> #include <Qt3DCore/qaspectjob.h> #include <Qt3DCore/qnodeid.h> @@ -77,6 +78,17 @@ class NodeManagers; class Entity; class FrameGraphNode; class RendererSettings; +class BackendNode; + +// Changes made to backend nodes are reported to the Renderer +enum class BackendNodeDirtyFlag { + Transform = 1 << 0, + Material = 1 << 1, + Geometry = 1 << 2, + Any = 1 << 15 +}; +Q_DECLARE_FLAGS(BackendNodeDirtySet, BackendNodeDirtyFlag) +Q_DECLARE_OPERATORS_FOR_FLAGS(BackendNodeDirtySet) class QT3DRENDERSHARED_PRIVATE_EXPORT AbstractRenderer { @@ -111,6 +123,11 @@ public: virtual bool isRunning() const = 0; + virtual void markDirty(BackendNodeDirtySet changes, BackendNode *node) = 0; + virtual BackendNodeDirtySet dirtyBits() = 0; + virtual bool shouldRender() = 0; + virtual void skipNextFrame() = 0; + virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0; virtual Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() = 0; diff --git a/src/render/backend/backendnode.cpp b/src/render/backend/backendnode.cpp index 3051e6c90..247f6340b 100644 --- a/src/render/backend/backendnode.cpp +++ b/src/render/backend/backendnode.cpp @@ -61,6 +61,12 @@ void BackendNode::setRenderer(AbstractRenderer *renderer) m_renderer = renderer; } +void BackendNode::markDirty(BackendNodeDirtySet changes) +{ + Q_ASSERT(m_renderer); + m_renderer->markDirty(changes, this); +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/backend/backendnode_p.h b/src/render/backend/backendnode_p.h index b4996051c..e5e6c7b33 100644 --- a/src/render/backend/backendnode_p.h +++ b/src/render/backend/backendnode_p.h @@ -61,7 +61,7 @@ namespace Qt3DRender { namespace Render { -class BackendNode : public Qt3DCore::QBackendNode +class Q_AUTOTEST_EXPORT BackendNode : public Qt3DCore::QBackendNode { public: BackendNode(Qt3DCore::QBackendNode::Mode mode = ReadOnly); @@ -69,6 +69,9 @@ public: void setRenderer(AbstractRenderer *renderer); +protected: + void markDirty(BackendNodeDirtySet changes); + private: AbstractRenderer *m_renderer; }; diff --git a/src/render/backend/boundingvolumedebug.cpp b/src/render/backend/boundingvolumedebug.cpp index f9f6b84ff..21073e989 100644 --- a/src/render/backend/boundingvolumedebug.cpp +++ b/src/render/backend/boundingvolumedebug.cpp @@ -82,6 +82,7 @@ void BoundingVolumeDebug::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (propertyName == QByteArrayLiteral("recursive")) { m_recursive = propertyChange->value().toBool(); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp index 067fb28e9..d1a273a99 100644 --- a/src/render/backend/cameralens.cpp +++ b/src/render/backend/cameralens.cpp @@ -92,6 +92,8 @@ void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) { m_enabled = propertyChange->value().toBool(); } + + markDirty(BackendNodeDirtyFlag::Any); } break; diff --git a/src/render/backend/computejob.cpp b/src/render/backend/computejob.cpp index ed7d6ad35..6444e271e 100644 --- a/src/render/backend/computejob.cpp +++ b/src/render/backend/computejob.cpp @@ -73,6 +73,7 @@ void ComputeJob::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (e->type() == Qt3DCore::NodeUpdated) { if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) m_enabled = propertyChange->value().toBool(); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp index 728ef17ff..b7edb7c25 100644 --- a/src/render/backend/entity.cpp +++ b/src/render/backend/entity.cpp @@ -205,6 +205,7 @@ void Entity::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } void Entity::dump() const diff --git a/src/render/backend/layer.cpp b/src/render/backend/layer.cpp index c384479b6..c1a0a7d0b 100644 --- a/src/render/backend/layer.cpp +++ b/src/render/backend/layer.cpp @@ -91,6 +91,7 @@ void Layer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) { m_enabled = propertyChange->value().toBool(); } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/backend/nodefunctor_p.h b/src/render/backend/nodefunctor_p.h index 1fb1a8d82..2b5e8c9f7 100644 --- a/src/render/backend/nodefunctor_p.h +++ b/src/render/backend/nodefunctor_p.h @@ -51,7 +51,6 @@ // We mean it. // -#include <Qt3DCore/qbackendnode.h> #include <Qt3DCore/qnode.h> #include <Qt3DRender/private/backendnode_p.h> diff --git a/src/render/backend/renderattachment.cpp b/src/render/backend/renderattachment.cpp index 472eaad37..44ee3bb60 100644 --- a/src/render/backend/renderattachment.cpp +++ b/src/render/backend/renderattachment.cpp @@ -119,6 +119,7 @@ void RenderAttachment::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) else if (propertyChange->propertyName() == QByteArrayLiteral("name")) { m_attachmentData.m_name = propertyChange->value().toString(); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index b2df0bb32..0d67d7500 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -140,6 +140,8 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_waitForInitializationToBeCompleted(0) , m_pickEventFilter(new PickEventFilter()) , m_exposed(0) + , m_lastFrameCorrect(0) + , m_changeSet(0) , m_glContext(Q_NULLPTR) , m_pickBoundingVolumeJob(Q_NULLPTR) , m_time(0) @@ -597,6 +599,8 @@ bool Renderer::submitRenderViews() const int renderViewsCount = renderViews.size(); quint64 frameElapsed = queueElapsed; + m_lastFrameCorrect.store(1); // everything fine until now..... + m_changeSet = 0; // mark "not dirty" // Early return if there's actually nothing to render if (renderViewsCount <= 0) @@ -674,7 +678,8 @@ bool Renderer::submitRenderViews() m_graphicsContext->setViewport(renderView->viewport(), renderView->surfaceSize() * renderView->devicePixelRatio()); // Execute the render commands - executeCommands(renderView); + if (!executeCommands(renderView)) + m_lastFrameCorrect.store(0); // something went wrong; make sure to render the next frame! // executeCommands takes care of restoring the stateset to the value // of gc->currentContext() at the moment it was called (either @@ -705,16 +710,42 @@ bool Renderer::submitRenderViews() return true; } +void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node) +{ + Q_UNUSED(node); + m_changeSet |= changes; +} + +BackendNodeDirtySet Renderer::dirtyBits() +{ + return m_changeSet; +} + +bool Renderer::shouldRender() +{ + // Only render if something changed during the last frame, or the last frame + // was not rendered successfully + return (m_changeSet != 0 || !m_lastFrameCorrect.load()); +} + +void Renderer::skipNextFrame() +{ + // make submitRenderViews() actually run + m_renderQueue->setNoRender(); + m_submitRenderViewsSemaphore.release(1); +} + // Waits to be told to create jobs for the next frame // Called by QRenderAspect jobsToExecute context of QAspectThread QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() { + QVector<QAspectJobPtr> renderBinJobs; + // Traverse the current framegraph. For each leaf node create a // RenderView and set its configuration then create a job to // populate the RenderView with a set of RenderCommands that get // their details from the RenderNodes that are visible to the // Camera selected by the framegraph configuration - QVector<QAspectJobPtr> renderBinJobs; FrameGraphVisitor visitor; visitor.traverse(frameGraphRoot(), this, &renderBinJobs); @@ -842,8 +873,11 @@ bool Renderer::createOrUpdateVAO(RenderCommand *command, } // Called by RenderView->submit() in RenderThread context -void Renderer::executeCommands(const RenderView *rv) +// Returns true, if all RenderCommands were sent to the GPU +bool Renderer::executeCommands(const RenderView *rv) { + bool allCommandsIssued = true; + // Render drawing commands const QVector<RenderCommand *> commands = rv->commands(); @@ -867,6 +901,7 @@ void Renderer::executeCommands(const RenderView *rv) const bool hasGeometryRenderer = rGeometry != Q_NULLPTR && rGeometryRenderer != Q_NULLPTR && !rGeometry->attributes().isEmpty(); if (!hasGeometryRenderer) { + allCommandsIssued = false; qCWarning(Rendering) << "RenderCommand should have a mesh to render"; continue; } @@ -935,6 +970,8 @@ void Renderer::executeCommands(const RenderView *rv) //// Draw Calls if (primitiveCount && (specified || (vao && vao->isSpecified()))) { performDraw(rGeometry, rGeometryRenderer, primitiveCount, indexAttribute); + } else { + allCommandsIssued = false; } } } // end of RenderCommands loop @@ -955,6 +992,8 @@ void Renderer::executeCommands(const RenderView *rv) Q_FOREACH (Geometry *geometry, m_dirtyGeometry) geometry->unsetDirty(); m_dirtyGeometry.clear(); + + return allCommandsIssued; } Attribute *Renderer::updateBuffersAndAttributes(Geometry *geometry, RenderCommand *command, GLsizei &count, bool forceUpdate) diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 8cb1f8725..f68d8f9db 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -152,6 +152,11 @@ public: void setFrameGraphRoot(const Qt3DCore::QNodeId fgRootId) Q_DECL_OVERRIDE; FrameGraphNode *frameGraphRoot() const Q_DECL_OVERRIDE; + void markDirty(BackendNodeDirtySet changes, BackendNode *node) Q_DECL_OVERRIDE; + BackendNodeDirtySet dirtyBits() Q_DECL_OVERRIDE; + bool shouldRender() Q_DECL_OVERRIDE; + void skipNextFrame() Q_DECL_OVERRIDE; + QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() Q_DECL_OVERRIDE; Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() Q_DECL_OVERRIDE; @@ -164,7 +169,7 @@ public: virtual void setSettings(RendererSettings *settings) Q_DECL_OVERRIDE; virtual RendererSettings *settings() const Q_DECL_OVERRIDE; - void executeCommands(const RenderView *rv); + bool executeCommands(const RenderView *rv); Attribute *updateBuffersAndAttributes(Geometry *geometry, RenderCommand *command, GLsizei &count, bool forceUpdate); void setOpenGLContext(QOpenGLContext *context); @@ -250,6 +255,8 @@ private: QVector<Attribute *> m_dirtyAttributes; QVector<Geometry *> m_dirtyGeometry; QAtomicInt m_exposed; + BackendNodeDirtySet m_changeSet; + QAtomicInt m_lastFrameCorrect; QOpenGLContext *m_glContext; PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; diff --git a/src/render/backend/renderersettings.cpp b/src/render/backend/renderersettings.cpp index 148ce16fb..56e705bd7 100644 --- a/src/render/backend/renderersettings.cpp +++ b/src/render/backend/renderersettings.cpp @@ -75,6 +75,7 @@ void RendererSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_pickMethod = propertyChange->value().value<QRendererSettings::PickMethod>(); else if (propertyChange->propertyName() == QByteArrayLiteral("pickResult")) m_pickResultMode = propertyChange->value().value<QRendererSettings::PickResultMode>(); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp index 691288fc4..78bebfb42 100644 --- a/src/render/backend/renderqueue.cpp +++ b/src/render/backend/renderqueue.cpp @@ -51,6 +51,7 @@ RenderQueue::RenderQueue() : m_targetRenderViewCount(0) , m_currentRenderViewCount(0) , m_currentWorkQueue(1) + , m_noRender(false) { } @@ -66,7 +67,15 @@ int RenderQueue::currentRenderViewCount() const void RenderQueue::reset() { m_currentRenderViewCount = 0; - Q_ASSERT(currentRenderViewCount() == 0); + m_targetRenderViewCount = 0; + m_currentWorkQueue.clear(); + m_noRender = false; +} + +void RenderQueue::setNoRender() +{ + Q_ASSERT(m_targetRenderViewCount == 0); + m_noRender = true; } /*! @@ -76,6 +85,7 @@ void RenderQueue::reset() */ bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIndex) { + Q_ASSERT(!m_noRender); m_currentWorkQueue[submissionOrderIndex] = renderView; ++m_currentRenderViewCount; return isFrameQueueComplete(); @@ -96,6 +106,7 @@ QVector<RenderView *> RenderQueue::nextFrameQueue() */ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) { + Q_ASSERT(!m_noRender); m_targetRenderViewCount = targetRenderViewCount; m_currentWorkQueue.resize(targetRenderViewCount); } @@ -107,7 +118,8 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) */ bool RenderQueue::isFrameQueueComplete() const { - return m_targetRenderViewCount && m_targetRenderViewCount == currentRenderViewCount(); + return (m_noRender + || (m_targetRenderViewCount && m_targetRenderViewCount == currentRenderViewCount())); } } // namespace Render diff --git a/src/render/backend/renderqueue_p.h b/src/render/backend/renderqueue_p.h index 063b948f2..49316049b 100644 --- a/src/render/backend/renderqueue_p.h +++ b/src/render/backend/renderqueue_p.h @@ -76,7 +76,10 @@ public: QVector<RenderView *> nextFrameQueue(); void reset(); + void setNoRender(); + private: + bool m_noRender; int m_targetRenderViewCount; int m_currentRenderViewCount; QVector<RenderView *> m_currentWorkQueue; diff --git a/src/render/backend/rendertarget.cpp b/src/render/backend/rendertarget.cpp index 19bac8a3c..2d7130c23 100644 --- a/src/render/backend/rendertarget.cpp +++ b/src/render/backend/rendertarget.cpp @@ -90,6 +90,7 @@ void RenderTarget::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) appendRenderAttachment(propertyChange->value().value<QNodeId>()); else if (e->type() == NodeRemoved && propertyChange->propertyName() == QByteArrayLiteral("attachment")) removeRenderAttachment(propertyChange->value().value<QNodeId>()); + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp index 603529736..96fe7e991 100644 --- a/src/render/backend/transform.cpp +++ b/src/render/backend/transform.cpp @@ -92,6 +92,8 @@ void Transform::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_enabled = propertyChange->value().toBool(); } } + + markDirty(BackendNodeDirtyFlag::Transform); } void Transform::updateMatrix() diff --git a/src/render/framegraph/cameraselectornode.cpp b/src/render/framegraph/cameraselectornode.cpp index 1cacdf568..c2327cdc6 100644 --- a/src/render/framegraph/cameraselectornode.cpp +++ b/src/render/framegraph/cameraselectornode.cpp @@ -75,6 +75,7 @@ void CameraSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_cameraUuid = propertyChange->value().value<QNodeId>(); else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/clearbuffer.cpp b/src/render/framegraph/clearbuffer.cpp index 1161ab3c4..2f9e4b30b 100644 --- a/src/render/framegraph/clearbuffer.cpp +++ b/src/render/framegraph/clearbuffer.cpp @@ -68,6 +68,7 @@ void ClearBuffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_type = static_cast<QClearBuffer::BufferType>(propertyChange->value().toInt()); else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/dispatchcompute.cpp b/src/render/framegraph/dispatchcompute.cpp index e89e6e525..f5ec2bcbc 100644 --- a/src/render/framegraph/dispatchcompute.cpp +++ b/src/render/framegraph/dispatchcompute.cpp @@ -85,6 +85,7 @@ void DispatchCompute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_workGroups[2] = propertyChange->value().toInt(); else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/frustumculling.cpp b/src/render/framegraph/frustumculling.cpp index 10fc7d765..9037f81d2 100644 --- a/src/render/framegraph/frustumculling.cpp +++ b/src/render/framegraph/frustumculling.cpp @@ -75,6 +75,7 @@ void FrustumCulling::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) break; } } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/layerfilternode.cpp b/src/render/framegraph/layerfilternode.cpp index a0132b9b4..8f7fe3d75 100644 --- a/src/render/framegraph/layerfilternode.cpp +++ b/src/render/framegraph/layerfilternode.cpp @@ -69,6 +69,7 @@ void LayerFilterNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) setLayers(propertyChange->value().value<QStringList>()); else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/lighting.cpp b/src/render/framegraph/lighting.cpp index 906d22bd6..d4823212d 100644 --- a/src/render/framegraph/lighting.cpp +++ b/src/render/framegraph/lighting.cpp @@ -71,6 +71,7 @@ void Lighting::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/nodraw.cpp b/src/render/framegraph/nodraw.cpp index 343788c31..d7bd33637 100644 --- a/src/render/framegraph/nodraw.cpp +++ b/src/render/framegraph/nodraw.cpp @@ -71,6 +71,7 @@ void NoDraw::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) case NodeUpdated: { if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); break; default: diff --git a/src/render/framegraph/renderpassfilternode.cpp b/src/render/framegraph/renderpassfilternode.cpp index 21e05ac53..d1a3fab80 100644 --- a/src/render/framegraph/renderpassfilternode.cpp +++ b/src/render/framegraph/renderpassfilternode.cpp @@ -116,6 +116,7 @@ void RenderPassFilter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/rendersurfaceselector.cpp b/src/render/framegraph/rendersurfaceselector.cpp index 5003adfcb..ceee513d8 100644 --- a/src/render/framegraph/rendersurfaceselector.cpp +++ b/src/render/framegraph/rendersurfaceselector.cpp @@ -74,6 +74,7 @@ void RenderSurfaceSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_surface = propertyChange->value().value<QSurface *>(); else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) setEnabled(propertyChange->value().toBool()); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/rendertargetselectornode.cpp b/src/render/framegraph/rendertargetselectornode.cpp index ab9cc9dfc..d5df14df5 100644 --- a/src/render/framegraph/rendertargetselectornode.cpp +++ b/src/render/framegraph/rendertargetselectornode.cpp @@ -79,6 +79,7 @@ void RenderTargetSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) setEnabled(propertyChange->value().toBool()); else if (propertyChange->propertyName() == QByteArrayLiteral("drawBuffers")) m_drawBuffers = propertyChange->value().value<QList<Qt3DRender::QRenderAttachment::RenderAttachmentType> >(); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/framegraph/sortcriterion.cpp b/src/render/framegraph/sortcriterion.cpp index d558de77d..9b31e71cc 100644 --- a/src/render/framegraph/sortcriterion.cpp +++ b/src/render/framegraph/sortcriterion.cpp @@ -75,6 +75,7 @@ void SortCriterion::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (e->type() == NodeUpdated && propertyChange->propertyName() == QByteArrayLiteral("sort")) { m_type = static_cast<QSortCriterion::SortType>(propertyChange->value().toInt()); } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/sortmethod.cpp b/src/render/framegraph/sortmethod.cpp index 9746a8392..7ee462e6f 100644 --- a/src/render/framegraph/sortmethod.cpp +++ b/src/render/framegraph/sortmethod.cpp @@ -76,6 +76,7 @@ void SortMethod::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled") && e->type() == NodeUpdated) { setEnabled(propertyChange->value().toBool()); } + markDirty(BackendNodeDirtyFlag::Any); } QList<QNodeId> SortMethod::criteria() const diff --git a/src/render/framegraph/statesetnode.cpp b/src/render/framegraph/statesetnode.cpp index 4739c4a9a..b1c713b51 100644 --- a/src/render/framegraph/statesetnode.cpp +++ b/src/render/framegraph/statesetnode.cpp @@ -90,6 +90,7 @@ void StateSetNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/techniquefilternode.cpp b/src/render/framegraph/techniquefilternode.cpp index 87eff80a6..bd567d4ac 100644 --- a/src/render/framegraph/techniquefilternode.cpp +++ b/src/render/framegraph/techniquefilternode.cpp @@ -117,6 +117,7 @@ void TechniqueFilter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } } // namespace Render diff --git a/src/render/framegraph/viewportnode.cpp b/src/render/framegraph/viewportnode.cpp index 66f59a05d..1871eb2ba 100644 --- a/src/render/framegraph/viewportnode.cpp +++ b/src/render/framegraph/viewportnode.cpp @@ -126,6 +126,7 @@ void ViewportNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) { setEnabled(propertyChange->value().toBool()); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 80e7b8488..464ac56ed 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -126,6 +126,7 @@ #include <Qt3DRender/private/computejob_p.h> #include <Qt3DRender/private/rendersurfaceselector_p.h> #include <Qt3DRender/private/renderersettings_p.h> +#include <Qt3DRender/private/backendnode_p.h> #include <Qt3DCore/qentity.h> #include <Qt3DCore/qtransform.h> @@ -334,6 +335,11 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time) // Create jobs to load in any meshes that are pending if (d->m_renderer != Q_NULLPTR && d->m_renderer->isRunning()) { + // don't spawn any jobs, if the renderer decides to skip this frame + if (!d->m_renderer->shouldRender()) { + d->m_renderer->skipNextFrame(); + return jobs; + } Render::NodeManagers *manager = d->m_renderer->nodeManagers(); //QAspectJobPtr pickBoundingVolumeJob = d->m_renderer->pickBoundingVolumeJob(); diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp index e52815ede..1e4b16292 100644 --- a/src/render/geometry/attribute.cpp +++ b/src/render/geometry/attribute.cpp @@ -133,6 +133,7 @@ void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_bufferId = propertyChange->value().value<QNodeId>(); m_attributeDirty = true; } + markDirty(BackendNodeDirtyFlag::Any); break; } diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index 3389172e0..92217ff1e 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -135,6 +135,7 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyName == QByteArrayLiteral("sync")) { m_sync = propertyChange->value().toBool(); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/geometry/geometry.cpp b/src/render/geometry/geometry.cpp index 8b4a51a0b..8ef33ac54 100644 --- a/src/render/geometry/geometry.cpp +++ b/src/render/geometry/geometry.cpp @@ -120,6 +120,7 @@ void Geometry::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } void Geometry::unsetDirty() diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp index a20bb87cf..ff2fa149c 100644 --- a/src/render/geometry/geometryrenderer.cpp +++ b/src/render/geometry/geometryrenderer.cpp @@ -174,6 +174,8 @@ void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) break; } + markDirty(BackendNodeDirtyFlag::Any); + // Add to dirty list in manager } diff --git a/src/render/io/scene.cpp b/src/render/io/scene.cpp index 772a49837..d4f9bb010 100644 --- a/src/render/io/scene.cpp +++ b/src/render/io/scene.cpp @@ -74,6 +74,7 @@ void Scene::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_source = propertyChange->value().toUrl(); m_sceneManager->addSceneData(m_source, peerUuid()); } + markDirty(BackendNodeDirtyFlag::Any); } QUrl Scene::source() const diff --git a/src/render/materialsystem/annotation.cpp b/src/render/materialsystem/annotation.cpp index c3cf71b2d..b0ceeaf5c 100644 --- a/src/render/materialsystem/annotation.cpp +++ b/src/render/materialsystem/annotation.cpp @@ -86,6 +86,8 @@ void Annotation::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_value = propertyChange->value(); else if (propertyChange->propertyName() == QByteArrayLiteral("name")) m_name = propertyChange->value().toString(); + + markDirty(BackendNodeDirtyFlag::Any); } bool Annotation::operator ==(const Annotation &other) diff --git a/src/render/materialsystem/effect.cpp b/src/render/materialsystem/effect.cpp index 3cbfe9f9e..b31cd9485 100644 --- a/src/render/materialsystem/effect.cpp +++ b/src/render/materialsystem/effect.cpp @@ -104,6 +104,8 @@ void Effect::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default : break; } + + markDirty(BackendNodeDirtyFlag::Any); } void Effect::appendRenderTechnique(Qt3DCore::QNodeId technique) diff --git a/src/render/materialsystem/material.cpp b/src/render/materialsystem/material.cpp index 5c4f6f537..b93422015 100644 --- a/src/render/materialsystem/material.cpp +++ b/src/render/materialsystem/material.cpp @@ -113,6 +113,7 @@ void Material::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } QList<Qt3DCore::QNodeId> Material::parameters() const diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp index b5007ae95..58e5bb6bd 100644 --- a/src/render/materialsystem/parameter.cpp +++ b/src/render/materialsystem/parameter.cpp @@ -81,6 +81,7 @@ void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("value")) { m_value = propertyChange->value(); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/materialsystem/renderpass.cpp b/src/render/materialsystem/renderpass.cpp index 6f4a6e117..ece7972db 100644 --- a/src/render/materialsystem/renderpass.cpp +++ b/src/render/materialsystem/renderpass.cpp @@ -129,6 +129,7 @@ void RenderPass::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } Qt3DCore::QNodeId RenderPass::shaderProgram() const diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index 6c07c1caf..e4ffe59e4 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -156,6 +156,7 @@ void Shader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } if (!m_isLoaded) updateDNA(); + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/materialsystem/shaderdata.cpp b/src/render/materialsystem/shaderdata.cpp index 9694ea159..52ee7220b 100644 --- a/src/render/materialsystem/shaderdata.cpp +++ b/src/render/materialsystem/shaderdata.cpp @@ -322,6 +322,7 @@ void ShaderData::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + BackendNode::markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/materialsystem/technique.cpp b/src/render/materialsystem/technique.cpp index 2b1ba65b1..3526e134f 100644 --- a/src/render/materialsystem/technique.cpp +++ b/src/render/materialsystem/technique.cpp @@ -149,6 +149,7 @@ void Technique::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) default: break; } + markDirty(BackendNodeDirtyFlag::Any); } QList<Qt3DCore::QNodeId> Technique::parameters() const diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp index b3571d107..172f1733e 100644 --- a/src/render/picking/objectpicker.cpp +++ b/src/render/picking/objectpicker.cpp @@ -95,6 +95,7 @@ void ObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_mouseTrackingEnabled = propertyChange->value().toBool(); m_isDirty = true; } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp index a8e2716aa..3cce233b8 100644 --- a/src/render/renderstates/renderstates.cpp +++ b/src/render/renderstates/renderstates.cpp @@ -99,6 +99,7 @@ void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else { m_impl->updateProperty(propertyChange->propertyName(), propertyChange->value()); } + markDirty(BackendNodeDirtyFlag::Any); } } diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp index 7a4b238e4..a999d4fdb 100644 --- a/src/render/texture/texture.cpp +++ b/src/render/texture/texture.cpp @@ -597,6 +597,7 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) break; } + markDirty(BackendNodeDirtyFlag::Any); } TextureDNA Texture::dna() const diff --git a/src/render/texture/textureimage.cpp b/src/render/texture/textureimage.cpp index 7ce782e6d..aef4908bb 100644 --- a/src/render/texture/textureimage.cpp +++ b/src/render/texture/textureimage.cpp @@ -121,6 +121,7 @@ void TextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (txt != Q_NULLPTR) txt->addToPendingTextureJobs(); } + markDirty(BackendNodeDirtyFlag::Any); } void TextureImage::setTextureManager(TextureManager *manager) diff --git a/tests/auto/render/attribute/tst_attribute.cpp b/tests/auto/render/attribute/tst_attribute.cpp index 17cdcbc8d..ee5048691 100644 --- a/tests/auto/render/attribute/tst_attribute.cpp +++ b/tests/auto/render/attribute/tst_attribute.cpp @@ -30,6 +30,7 @@ #include <Qt3DRender/private/attribute_p.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DCore/qscenepropertychange.h> +#include "testrenderer.h" class tst_Attribute : public QObject { @@ -76,7 +77,9 @@ private Q_SLOTS: void checkInitialAndCleanedUpState() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Attribute renderAttribute; + renderAttribute.setRenderer(&renderer); // THEN QVERIFY(renderAttribute.peerUuid().isNull()); @@ -127,7 +130,9 @@ private Q_SLOTS: void checkPropertyChanges() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Attribute renderAttribute; + renderAttribute.setRenderer(&renderer); QVERIFY(!renderAttribute.isDirty()); @@ -140,9 +145,12 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.dataType(), Qt3DRender::QAbstractAttribute::Int); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); + QVERIFY(!renderer.dirtyBits()); // WHEN updateChange.reset(new Qt3DCore::QScenePropertyChange(Qt3DCore::NodeUpdated, Qt3DCore::QSceneChange::Node, Qt3DCore::QNodeId())); @@ -153,8 +161,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.dataSize(), 3U); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -166,8 +176,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.attributeType(), Qt3DRender::QAttribute::IndexAttribute); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -179,8 +191,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.count(), 1340U); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -192,8 +206,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.name(), QStringLiteral("L88")); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -205,8 +221,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.byteOffset(), 555U); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -218,8 +236,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.byteStride(), 454U); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -231,8 +251,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.divisor(), 1450U); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); // WHEN @@ -245,8 +267,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderAttribute.bufferId(), bufferId); QVERIFY(renderAttribute.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderAttribute.unsetDirty(); + renderer.resetDirty(); QVERIFY(!renderAttribute.isDirty()); } }; diff --git a/tests/auto/render/boundingvolumedebug/tst_boundingvolumedebug.cpp b/tests/auto/render/boundingvolumedebug/tst_boundingvolumedebug.cpp index 90cddc85e..b3fba50f8 100644 --- a/tests/auto/render/boundingvolumedebug/tst_boundingvolumedebug.cpp +++ b/tests/auto/render/boundingvolumedebug/tst_boundingvolumedebug.cpp @@ -32,6 +32,7 @@ #include <Qt3DCore/private/qbackendnode_p.h> #include <Qt3DCore/qscenepropertychange.h> #include "testpostmanarbiter.h" +#include "testrenderer.h" class tst_BoundingVolumeDebug : public QObject { @@ -84,7 +85,9 @@ private Q_SLOTS: void checkPropertyChanges() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::BoundingVolumeDebug boundingVolumeDebug; + boundingVolumeDebug.setRenderer(&renderer); QVERIFY(!boundingVolumeDebug.isRecursive()); // WHEN @@ -95,6 +98,7 @@ private Q_SLOTS: // THEN QCOMPARE(boundingVolumeDebug.isRecursive(), true); + QVERIFY(renderer.dirtyBits() != 0); } void checkBackendPropertyNotifications() diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp index b05871122..aeab3ade4 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -31,6 +31,7 @@ #include <Qt3DCore/qscenepropertychange.h> #include <Qt3DCore/private/qbackendnode_p.h> #include "testpostmanarbiter.h" +#include "testrenderer.h" class TestFunctor : public Qt3DRender::QBufferFunctor { @@ -119,7 +120,9 @@ private Q_SLOTS: void checkPropertyChanges() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Buffer renderBuffer; + renderBuffer.setRenderer(&renderer); // THEN QVERIFY(renderBuffer.type() != Qt3DRender::QBuffer::IndexBuffer); @@ -135,6 +138,7 @@ private Q_SLOTS: // THEN QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer); + QVERIFY(renderer.dirtyBits() != 0); QVERIFY(renderBuffer.isDirty()); renderBuffer.unsetDirty(); diff --git a/tests/auto/render/commons/commons.pri b/tests/auto/render/commons/commons.pri index 20274ca25..54bc0b949 100644 --- a/tests/auto/render/commons/commons.pri +++ b/tests/auto/render/commons/commons.pri @@ -1,9 +1,11 @@ SOURCES += \ - $$PWD/testpostmanarbiter.cpp + $$PWD/testpostmanarbiter.cpp \ + $$PWD/testrenderer.cpp HEADERS += \ - $$PWD/testpostmanarbiter.h + $$PWD/testpostmanarbiter.h \ + $$PWD/testrenderer.h INCLUDEPATH += $$PWD -QT += core-private 3dcore 3dcore-private +QT += core-private 3dcore 3dcore-private 3drender 3drender-private diff --git a/tests/auto/render/commons/testrenderer.cpp b/tests/auto/render/commons/testrenderer.cpp new file mode 100644 index 000000000..39cf936ac --- /dev/null +++ b/tests/auto/render/commons/testrenderer.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testrenderer.h" + +QT_BEGIN_NAMESPACE + +TestRenderer::TestRenderer() + : m_changes(0) +{ +} + +TestRenderer::~TestRenderer() +{ +} + +void TestRenderer::markDirty(Qt3DRender::Render::BackendNodeDirtySet changes, Qt3DRender::Render::BackendNode *node) +{ + Q_UNUSED(node); + m_changes |= changes; +} + +Qt3DRender::Render::BackendNodeDirtySet TestRenderer::dirtyBits() +{ + return m_changes; +} + +void TestRenderer::resetDirty() +{ + m_changes = 0; +} + +QT_END_NAMESPACE diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h new file mode 100644 index 000000000..d237b6051 --- /dev/null +++ b/tests/auto/render/commons/testrenderer.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTRENDERER_H +#define TESTRENDERER_H + +#include <Qt3DRender/private/abstractrenderer_p.h> + +QT_BEGIN_NAMESPACE + +class TestRenderer : public Qt3DRender::Render::AbstractRenderer +{ +public: + TestRenderer(); + ~TestRenderer(); + + API api() const Q_DECL_OVERRIDE { return AbstractRenderer::OpenGL; } + qint64 time() const Q_DECL_OVERRIDE { return 0; } + void setTime(qint64 time) Q_DECL_OVERRIDE { Q_UNUSED(time); } + void setNodeManagers(Qt3DRender::Render::NodeManagers *managers) Q_DECL_OVERRIDE { Q_UNUSED(managers); } + void setServices(Qt3DCore::QServiceLocator *services) Q_DECL_OVERRIDE { Q_UNUSED(services); } + void setSurfaceExposed(bool exposed) Q_DECL_OVERRIDE { Q_UNUSED(exposed); } + Qt3DRender::Render::NodeManagers *nodeManagers() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + Qt3DCore::QServiceLocator *services() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + void initialize() Q_DECL_OVERRIDE {} + void shutdown() Q_DECL_OVERRIDE {} + void createAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager) Q_DECL_OVERRIDE { Q_UNUSED(jobManager); } + void destroyAllocators(Qt3DCore::QAbstractAspectJobManager *jobManager) Q_DECL_OVERRIDE { Q_UNUSED(jobManager); } + void render() Q_DECL_OVERRIDE {} + void doRender() Q_DECL_OVERRIDE {} + bool isRunning() const Q_DECL_OVERRIDE { return true; } + bool shouldRender() Q_DECL_OVERRIDE { return true; } + void skipNextFrame() Q_DECL_OVERRIDE {} + QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() Q_DECL_OVERRIDE { return QVector<Qt3DCore::QAspectJobPtr>(); } + Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() Q_DECL_OVERRIDE { return Qt3DCore::QAspectJobPtr(); } + void setFrameGraphRoot(const Qt3DCore::QNodeId fgRootId) Q_DECL_OVERRIDE { Q_UNUSED(fgRootId); } + void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Qt3DRender::Render::Entity *root) Q_DECL_OVERRIDE { Q_UNUSED(factory); Q_UNUSED(root); } + Qt3DRender::Render::Entity *sceneRoot() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + Qt3DRender::Render::FrameGraphNode *frameGraphRoot() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + void registerEventFilter(Qt3DCore::QEventFilterService *service) Q_DECL_OVERRIDE { Q_UNUSED(service); } + void setSettings(Qt3DRender::Render::RendererSettings *settings) Q_DECL_OVERRIDE { Q_UNUSED(settings); } + Qt3DRender::Render::RendererSettings *settings() const Q_DECL_OVERRIDE { return Q_NULLPTR; } + + void markDirty(Qt3DRender::Render::BackendNodeDirtySet changes, Qt3DRender::Render::BackendNode *node) Q_DECL_OVERRIDE; + Qt3DRender::Render::BackendNodeDirtySet dirtyBits() Q_DECL_OVERRIDE; + + void resetDirty(); + +protected: + Qt3DRender::Render::BackendNodeDirtySet m_changes; +}; + +QT_END_NAMESPACE + +#endif // TESTRENDERER_H diff --git a/tests/auto/render/entity/entity.pro b/tests/auto/render/entity/entity.pro index be8998802..193bd745c 100644 --- a/tests/auto/render/entity/entity.pro +++ b/tests/auto/render/entity/entity.pro @@ -7,3 +7,5 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib CONFIG += testcase SOURCES += tst_entity.cpp + +include(../commons/commons.pri) diff --git a/tests/auto/render/entity/tst_entity.cpp b/tests/auto/render/entity/tst_entity.cpp index 237c7b6db..2ec160eed 100644 --- a/tests/auto/render/entity/tst_entity.cpp +++ b/tests/auto/render/entity/tst_entity.cpp @@ -42,6 +42,8 @@ #include <Qt3DRender/QBoundingVolumeDebug> #include <Qt3DRender/QComputeJob> +#include "testrenderer.h" + typedef Qt3DCore::QNodeId (*UuidMethod)(Qt3DRender::Render::Entity *); typedef QList<Qt3DCore::QNodeId> (*UuidListMethod)(Qt3DRender::Render::Entity *); @@ -94,7 +96,10 @@ private slots: { // GIVEN QFETCH(QList<QComponent*>, components); + + TestRenderer renderer; Qt3DRender::Render::Entity entity; + entity.setRenderer(&renderer); // THEN QVERIFY(entity.componentUuid<Transform>().isNull()); @@ -127,6 +132,7 @@ private slots: QVERIFY(!entity.componentsUuid<Layer>().isEmpty()); QVERIFY(!entity.componentsUuid<ShaderData>().isEmpty()); QVERIFY(entity.isBoundingVolumeDirty()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN entity.cleanup(); @@ -178,7 +184,9 @@ private slots: QFETCH(void*, functionPtr); UuidMethod method = reinterpret_cast<UuidMethod>(functionPtr); - Entity entity; + TestRenderer renderer; + Qt3DRender::Render::Entity entity; + entity.setRenderer(&renderer); // THEN QVERIFY(method(&entity).isNull()); @@ -191,8 +199,10 @@ private slots: // THEN QCOMPARE(method(&entity), component->id()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN + renderer.resetDirty(); QScenePropertyChangePtr removeChange(new QScenePropertyChange(ComponentRemoved, QSceneChange::Node, component->id())); removeChange->setPropertyName("componentId"); removeChange->setValue(QVariant::fromValue(component->id())); @@ -200,6 +210,7 @@ private slots: // THEN QVERIFY(method(&entity).isNull()); + QVERIFY(renderer.dirtyBits() != 0); delete component; } @@ -227,7 +238,9 @@ private slots: QFETCH(void*, functionPtr); UuidListMethod method = reinterpret_cast<UuidListMethod>(functionPtr); - Entity entity; + TestRenderer renderer; + Qt3DRender::Render::Entity entity; + entity.setRenderer(&renderer); // THEN QVERIFY(method(&entity).isEmpty()); @@ -245,8 +258,10 @@ private slots: Q_FOREACH (QComponent *component, components) { QVERIFY(method(&entity).contains(component->id())); } + QVERIFY(renderer.dirtyBits() != 0); // WHEN + renderer.resetDirty(); QScenePropertyChangePtr removeChange(new QScenePropertyChange(ComponentRemoved, QSceneChange::Node, components.first()->id())); removeChange->setPropertyName("componentId"); removeChange->setValue(QVariant::fromValue(components.first()->id())); @@ -255,6 +270,7 @@ private slots: // THEN QCOMPARE(method(&entity).size(), components.size() - 1); QVERIFY(!method(&entity).contains(components.first()->id())); + QVERIFY(renderer.dirtyBits() != 0); qDeleteAll(components); } diff --git a/tests/auto/render/geometry/geometry.pro b/tests/auto/render/geometry/geometry.pro index fc916fc7a..be2c16cb8 100644 --- a/tests/auto/render/geometry/geometry.pro +++ b/tests/auto/render/geometry/geometry.pro @@ -7,3 +7,5 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib CONFIG += testcase SOURCES += tst_geometry.cpp + +include(../commons/commons.pri) diff --git a/tests/auto/render/geometry/tst_geometry.cpp b/tests/auto/render/geometry/tst_geometry.cpp index 01d317677..79ed7a940 100644 --- a/tests/auto/render/geometry/tst_geometry.cpp +++ b/tests/auto/render/geometry/tst_geometry.cpp @@ -32,6 +32,7 @@ #include <Qt3DRender/qattribute.h> #include <Qt3DCore/qscenepropertychange.h> #include <Qt3DRender/qboundingvolumespecifier.h> +#include "testrenderer.h" class tst_RenderGeometry : public QObject { @@ -110,7 +111,9 @@ private Q_SLOTS: void checkPropertyChanges() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Geometry renderGeometry; + renderGeometry.setRenderer(&renderer); Qt3DCore::QNodeId geometryId = Qt3DCore::QNodeId::createId(); // WHEN diff --git a/tests/auto/render/geometryrenderer/geometryrenderer.pro b/tests/auto/render/geometryrenderer/geometryrenderer.pro index 7499730f9..424cb303a 100644 --- a/tests/auto/render/geometryrenderer/geometryrenderer.pro +++ b/tests/auto/render/geometryrenderer/geometryrenderer.pro @@ -7,3 +7,6 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib CONFIG += testcase SOURCES += tst_geometryrenderer.cpp + +include(../commons/commons.pri) + diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp index 4289b1ef3..07f94c08f 100644 --- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp +++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp @@ -31,6 +31,7 @@ #include <Qt3DRender/qgeometry.h> #include <Qt3DRender/qgeometryfunctor.h> #include <Qt3DCore/qscenepropertychange.h> +#include "testrenderer.h" class TestFunctor : public Qt3DRender::QGeometryFunctor { @@ -160,6 +161,8 @@ private Q_SLOTS: { // GIVEN Qt3DRender::Render::GeometryRenderer renderGeometryRenderer; + TestRenderer renderer; + renderGeometryRenderer.setRenderer(&renderer); QVERIFY(!renderGeometryRenderer.isDirty()); @@ -172,6 +175,7 @@ private Q_SLOTS: // THEN QCOMPARE(renderGeometryRenderer.instanceCount(), 2); QVERIFY(renderGeometryRenderer.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); renderGeometryRenderer.unsetDirty(); QVERIFY(!renderGeometryRenderer.isDirty()); diff --git a/tests/auto/render/material/material.pro b/tests/auto/render/material/material.pro index b848ec0ec..5cd5ab339 100644 --- a/tests/auto/render/material/material.pro +++ b/tests/auto/render/material/material.pro @@ -7,3 +7,6 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib CONFIG += testcase SOURCES += tst_material.cpp + +include(../commons/commons.pri) + diff --git a/tests/auto/render/material/tst_material.cpp b/tests/auto/render/material/tst_material.cpp index ad58b3c96..c25938fec 100644 --- a/tests/auto/render/material/tst_material.cpp +++ b/tests/auto/render/material/tst_material.cpp @@ -33,7 +33,7 @@ #include <Qt3DRender/QParameter> #include <Qt3DRender/QEffect> #include <Qt3DCore/QScenePropertyChange> - +#include "testrenderer.h" using namespace Qt3DCore; using namespace Qt3DRender; @@ -131,6 +131,8 @@ void tst_RenderMaterial::shouldHandleParametersPropertyChange() // GIVEN QScopedPointer<QParameter> parameter(new QParameter()); Material backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr addChange(new QScenePropertyChange(NodeAdded, QSceneChange::Node, parameter->id())); @@ -141,6 +143,7 @@ void tst_RenderMaterial::shouldHandleParametersPropertyChange() // THEN QCOMPARE(backend.parameters().count(), 1); QCOMPARE(backend.parameters().first(), parameter->id()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, parameter->id())); @@ -156,6 +159,8 @@ void tst_RenderMaterial::shouldHandleEnablePropertyChange() { // GIVEN Material backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr updateChange(new QScenePropertyChange(NodeUpdated, QSceneChange::Node, QNodeId())); @@ -165,6 +170,7 @@ void tst_RenderMaterial::shouldHandleEnablePropertyChange() // THEN QVERIFY(!backend.isEnabled()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr secondUpdateChange(new QScenePropertyChange(NodeUpdated, QSceneChange::Node, QNodeId())); @@ -181,6 +187,8 @@ void tst_RenderMaterial::shouldHandleEffectPropertyChange() { // GIVEN Material backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr updateChange(new Qt3DCore::QScenePropertyChange(Qt3DCore::NodeUpdated, Qt3DCore::QSceneChange::Node, Qt3DCore::QNodeId())); @@ -191,6 +199,7 @@ void tst_RenderMaterial::shouldHandleEffectPropertyChange() // THEN QCOMPARE(backend.effect(), effectId); + QVERIFY(renderer.dirtyBits() != 0); } QTEST_APPLESS_MAIN(tst_RenderMaterial) diff --git a/tests/auto/render/objectpicker/tst_objectpicker.cpp b/tests/auto/render/objectpicker/tst_objectpicker.cpp index 9e10274c2..fddde3248 100644 --- a/tests/auto/render/objectpicker/tst_objectpicker.cpp +++ b/tests/auto/render/objectpicker/tst_objectpicker.cpp @@ -33,6 +33,7 @@ #include <Qt3DCore/private/qbackendnode_p.h> #include <Qt3DCore/qscenepropertychange.h> #include "testpostmanarbiter.h" +#include "testrenderer.h" class tst_ObjectPicker : public QObject { @@ -83,6 +84,8 @@ private Q_SLOTS: { // GIVEN Qt3DRender::Render::ObjectPicker objectPicker; + TestRenderer renderer; + objectPicker.setRenderer(&renderer); QVERIFY(!objectPicker.isDirty()); @@ -95,6 +98,7 @@ private Q_SLOTS: // THEN QCOMPARE(objectPicker.hoverEnabled(), true); QVERIFY(objectPicker.isDirty()); + QVERIFY(renderer.dirtyBits() != 0); objectPicker.unsetDirty(); QVERIFY(!objectPicker.isDirty()); diff --git a/tests/auto/render/renderpass/renderpass.pro b/tests/auto/render/renderpass/renderpass.pro index 2b7806af1..63bb920e9 100644 --- a/tests/auto/render/renderpass/renderpass.pro +++ b/tests/auto/render/renderpass/renderpass.pro @@ -7,3 +7,5 @@ QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib CONFIG += testcase SOURCES += tst_renderpass.cpp + +include(../commons/commons.pri) diff --git a/tests/auto/render/renderpass/tst_renderpass.cpp b/tests/auto/render/renderpass/tst_renderpass.cpp index eea26fcd7..603cfb2a2 100644 --- a/tests/auto/render/renderpass/tst_renderpass.cpp +++ b/tests/auto/render/renderpass/tst_renderpass.cpp @@ -59,6 +59,8 @@ #include <Qt3DRender/private/renderstates_p.h> #include <Qt3DRender/private/managers_p.h> +#include "testrenderer.h" + using namespace Qt3DCore; using namespace Qt3DRender; using namespace Qt3DRender::Render; @@ -136,6 +138,8 @@ private slots: QScopedPointer<QShaderProgram> shader(new QShaderProgram); RenderPass backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr addChange(new QScenePropertyChange(NodeAdded, QSceneChange::Node, shader->id())); @@ -145,6 +149,7 @@ private slots: // THEN QCOMPARE(backend.shaderProgram(), shader->id()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, shader->id())); @@ -162,6 +167,8 @@ private slots: QScopedPointer<QAnnotation> annotation(new QAnnotation); RenderPass backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr addChange(new QScenePropertyChange(NodeAdded, QSceneChange::Node, annotation->id())); @@ -172,6 +179,7 @@ private slots: // THEN QCOMPARE(backend.annotations().size(), 1); QCOMPARE(backend.annotations().first(), annotation->id()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, annotation->id())); @@ -189,6 +197,8 @@ private slots: QScopedPointer<QParameterMapping> binding(new QParameterMapping); RenderPass backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr addChange(new QScenePropertyChange(NodeAdded, QSceneChange::Node, binding->id())); @@ -202,6 +212,7 @@ private slots: QCOMPARE(backend.bindings().first().bindingType(), binding->bindingType()); QCOMPARE(backend.bindings().first().parameterName(), binding->parameterName()); QCOMPARE(backend.bindings().first().shaderVariableName(), binding->shaderVariableName()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, binding->id())); @@ -219,6 +230,8 @@ private slots: QScopedPointer<QParameter> parameter(new QParameter); RenderPass backend; + TestRenderer renderer; + backend.setRenderer(&renderer); // WHEN QScenePropertyChangePtr addChange(new QScenePropertyChange(NodeAdded, QSceneChange::Node, parameter->id())); @@ -229,6 +242,7 @@ private slots: // THEN QCOMPARE(backend.parameters().size(), 1); QCOMPARE(backend.parameters().first(), parameter->id()); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, parameter->id())); @@ -246,6 +260,8 @@ private slots: QNodePtr frontendStatePtr(frontendState); RenderPass backend; + TestRenderer renderer; + backend.setRenderer(&renderer); RenderStateNode *backendState = m_renderStateManager->getOrCreateResource(frontendState->id()); backendState->setPeer(frontendState); @@ -259,6 +275,7 @@ private slots: // THEN QCOMPARE(backend.renderStates(m_renderStateManager).size(), 1); QCOMPARE(backend.renderStates(m_renderStateManager).first(), backendState); + QVERIFY(renderer.dirtyBits() != 0); // WHEN QScenePropertyChangePtr removeChange(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, frontendState->id())); diff --git a/tests/auto/render/renderqueue/tst_renderqueue.cpp b/tests/auto/render/renderqueue/tst_renderqueue.cpp index d8cb46329..46df32b5f 100644 --- a/tests/auto/render/renderqueue/tst_renderqueue.cpp +++ b/tests/auto/render/renderqueue/tst_renderqueue.cpp @@ -74,6 +74,7 @@ void tst_RenderQueue::circleQueues() // WHEN renderQueue.reset(); + renderQueue.setTargetRenderViewCount(7); // THEN QVERIFY(!renderQueue.isFrameQueueComplete()); @@ -206,6 +207,7 @@ void tst_RenderQueue::concurrentQueueAccess() // reset queue for next frame renderQueue->reset(); + renderQueue->setTargetRenderViewCount(7); jobsThread->m_waitToFillQueue.wakeAll(); } jobsThread->wait(); |