diff options
24 files changed, 278 insertions, 79 deletions
diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0 new file mode 100644 index 000000000..442296db8 --- /dev/null +++ b/dist/changes-5.14.0 @@ -0,0 +1,49 @@ +Qt 5.14 introduces many new features and improvements as well as bugfixes +over the 5.13.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt3DExtras * +**************************************************************************** + + - QDistanceFieldGlyphCache: + * make sure the change arbiter of atlas for QText2DEntity can be set + when traversing node tree, and add new auto test for this. + +**************************************************************************** +* Qt3DRender * +**************************************************************************** + + - QNoPicking: control picking execution in the FrameGraph + - Textures: internal data sharing removed + - QSortPolicy can now sort by Texture + - QPickEvent adds property for picked entity + + - QImageTextureDataFunctor: + * return a invalid image data when url is invalid to ensure the property + of GLTexture will not be set to NoFormat + +**************************************************************************** +* UNSPECIFIED * +**************************************************************************** + + - Add basic support for KTX container format. + - Add worldMatrix property on QTransform + - Added SubtreeEnabler to allow easing enabling + and disabling of frame graph subtrees. + - [QTBUG-74977] Scene3D add compositingMode property. Allows underlay + rendering. + - Introduce Scene3DView to render multiple distinct 3D scenes diff --git a/src/extras/shaders/es2/distancefieldtext.frag b/src/extras/shaders/es2/distancefieldtext.frag index d2db2e306..b7563e397 100644 --- a/src/extras/shaders/es2/distancefieldtext.frag +++ b/src/extras/shaders/es2/distancefieldtext.frag @@ -33,5 +33,5 @@ void main() FP float maxAlpha = threshold + range; FP float distVal = texture2D(distanceFieldTexture, texCoord).r; - gl_FragColor = color * smoothstep(minAlpha, maxAlpha, distVal); + gl_FragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal)); } diff --git a/src/extras/shaders/gl3/distancefieldtext.frag b/src/extras/shaders/gl3/distancefieldtext.frag index 23dff8e0f..8e0684adc 100644 --- a/src/extras/shaders/gl3/distancefieldtext.frag +++ b/src/extras/shaders/gl3/distancefieldtext.frag @@ -34,6 +34,6 @@ void main() float maxAlpha = threshold + range; float distVal = texture(distanceFieldTexture, texCoord).r; - fragColor = color * smoothstep(minAlpha, maxAlpha, distVal); + fragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal)); gl_FragDepth = gl_FragCoord.z - zValue * 0.00001; } diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp index aa4785fe7..897672782 100644 --- a/src/extras/text/qtext2dentity.cpp +++ b/src/extras/text/qtext2dentity.cpp @@ -217,9 +217,6 @@ struct RenderData { void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs) { - if (runs.isEmpty()) - return; - // For each distinct texture, we need a separate DistanceFieldTextRenderer, // for which we need vertex and index data QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData; @@ -294,6 +291,11 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs) } } + // de-ref all glyphs for previous QGlyphRuns + for (int i = 0; i < m_currentGlyphRuns.size(); i++) + m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]); + m_currentGlyphRuns = runs; + // make sure we have the correct number of DistanceFieldTextRenderers // TODO: we might keep one renderer at all times, so we won't delete and // re-allocate one every time the text changes from an empty to a non-empty string @@ -314,11 +316,6 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs) for (auto it = renderData.begin(); it != renderData.end(); ++it) { m_renderers[rendererIdx++]->setGlyphData(it.key(), it.value().vertex, it.value().index); } - - // de-ref all glyphs for previous QGlyphRuns - for (int i = 0; i < m_currentGlyphRuns.size(); i++) - m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]); - m_currentGlyphRuns = runs; } void QText2DEntityPrivate::clearCurrentGlyphRuns() diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index c93d10b64..f824d2c4e 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -433,12 +433,26 @@ void Scene3DItem::applyRootEntityChange() bool Scene3DItem::needsRender() { + // We need the dirty flag which is connected to the change arbiter + // receiving updates to know whether something in the scene has changed + + // Ideally we would use shouldRender() alone but given that it becomes true + // only after the arbiter has sync the changes and might be reset before + // process jobs is completed, we cannot fully rely on it. It would require + // splitting processFrame in 2 parts. + + // We only use it for cases where Qt3D render may require several loops of + // the simulation to fully process a frame (e.g shaders are loaded in frame + // n and we can only build render commands for the new shader at frame n + + // This is where renderer->shouldRender() comes into play as it knows + // whether some states remain dirty or not (even after processFrame is + // called) + auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect)); const bool dirty = m_dirty || (renderAspectPriv && renderAspectPriv->m_renderer - && renderAspectPriv->m_renderer->settings() - && renderAspectPriv->m_renderer->settings()->renderPolicy() == QRenderSettings::Always); + && renderAspectPriv->m_renderer->shouldRender()); m_dirty = false; return dirty; } @@ -468,10 +482,6 @@ void Scene3DItem::onBeforeSync() if (!isVisible() && dontRenderWhenHidden) return; - // Has anything in the 3D scene actually changed that requires us to render? - if (!needsRender()) - return; - Q_ASSERT(QThread::currentThread() == thread()); // Since we are in manual mode, trigger jobs for the next frame @@ -512,6 +522,7 @@ void Scene3DItem::onBeforeSync() // start rendering before this function has been called // We add in a safety to skip such frames as this could otherwise // make Qt3D enter a locked state + m_renderer->setSkipFrame(!needsRender()); m_renderer->allowRender(); // Note: it's too early to request an update at this point as diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 1e322a615..fafeeedf4 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -161,6 +161,7 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp , m_forceRecreate(false) , m_shouldRender(false) , m_dirtyViews(false) + , m_skipFrame(false) , m_allowRendering(0) , m_compositingMode(Scene3DItem::FBO) { @@ -278,6 +279,19 @@ void Scene3DRenderer::beforeSynchronize() // We could otherwise enter a deadlock state if (!m_allowRendering.tryAcquire(std::max(m_allowRendering.available(), 1))) return; + + // In the case of OnDemand rendering, we still need to get to this + // point to ensure we have processed jobs for all aspects. + // We also still need to call render() to allow proceeding with the + // next frame. However it won't be performing any 3d rendering at all + // so we do it here and return early. This prevents a costly QtQuick + // SceneGraph update for nothing + if (m_skipFrame) { + m_skipFrame = false; + static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(false); + return; + } + m_shouldRender = true; // Check size / multisampling @@ -360,6 +374,11 @@ void Scene3DRenderer::setCompositingMode(Scene3DItem::CompositingMode mode) m_compositingMode = mode; } +void Scene3DRenderer::setSkipFrame(bool skip) +{ + m_skipFrame = skip; +} + // Main Thread, Render Thread locked void Scene3DRenderer::setScene3DViews(const QVector<Scene3DView *> views) { diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h index 4f3651cd3..08a2c60a3 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer_p.h +++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h @@ -87,7 +87,7 @@ public: void setCleanerHelper(Scene3DCleaner *cleaner); void allowRender(); void setCompositingMode(Scene3DItem::CompositingMode mode); - + void setSkipFrame(bool skip); void setScene3DViews(const QVector<Scene3DView *> views); public Q_SLOTS: @@ -119,6 +119,7 @@ private: bool m_forceRecreate; bool m_shouldRender; bool m_dirtyViews; + bool m_skipFrame; QSemaphore m_allowRendering; Scene3DItem::CompositingMode m_compositingMode; QVector<Scene3DView *> m_views; diff --git a/src/quick3d/quick3d/qquaternionanimation.cpp b/src/quick3d/quick3d/qquaternionanimation.cpp index 22cc905f7..933a08ee4 100644 --- a/src/quick3d/quick3d/qquaternionanimation.cpp +++ b/src/quick3d/quick3d/qquaternionanimation.cpp @@ -144,7 +144,7 @@ void QQuaternionAnimation::setType(Type type) switch (type) { case Nlerp: QT_WARNING_PUSH -QT_WARNING_DISABLE_GCC(-Wcast-function-type) +QT_WARNING_DISABLE_GCC("-Wcast-function-type") d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&q_quaternionNlerpInterpolator); QT_WARNING_POP break; diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index 518c0809c..8bbfcd548 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -152,7 +152,7 @@ public: #if defined(QT_BUILD_INTERNAL) virtual void clearDirtyBits(BackendNodeDirtySet changes) = 0; #endif - virtual bool shouldRender() = 0; + virtual bool shouldRender() const = 0; virtual void skipNextFrame() = 0; virtual void jobsDone(Qt3DCore::QAspectManager *manager) = 0; diff --git a/src/render/backend/bufferutils_p.h b/src/render/backend/bufferutils_p.h index 2bb35fac6..ea783df0d 100644 --- a/src/render/backend/bufferutils_p.h +++ b/src/render/backend/bufferutils_p.h @@ -74,6 +74,8 @@ struct BufferInfo , count(0) , byteStride(0) , byteOffset(0) + , restartEnabled(false) + , restartIndexValue(-1) {} QByteArray data; @@ -82,6 +84,8 @@ struct BufferInfo uint count; uint byteStride; uint byteOffset; + bool restartEnabled; + int restartIndexValue; }; diff --git a/src/render/backend/segmentsvisitor.cpp b/src/render/backend/segmentsvisitor.cpp index a3a5d059c..d9f2d79ec 100644 --- a/src/render/backend/segmentsvisitor.cpp +++ b/src/render/backend/segmentsvisitor.cpp @@ -135,34 +135,44 @@ void traverseSegmentStripIndexed(Index *indices, bool loop) { uint i = 0; + uint stripStartIndex = 0; + const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex); const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U); uint ndx[2]; Vector3D abc[2]; - ndx[0] = indices[0]; - uint idx = ndx[0] * verticesStride; - for (uint j = 0; j < maxVerticesDataSize; ++j) - abc[0][j] = vertices[idx + j]; - while (i < indexInfo.count - 1) { - ndx[1] = indices[i + 1]; - if (ndx[0] != ndx[1]) { - idx = ndx[1] * verticesStride; - for (uint j = 0; j < maxVerticesDataSize; ++j) - abc[1][j] = vertices[idx + j]; - visitor->visit(ndx[0], abc[0], ndx[1], abc[1]); + while (i < indexInfo.count) { + if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i])) { + ++i; + continue; } + stripStartIndex = i; + ndx[0] = indices[stripStartIndex]; + uint idx = ndx[0] * verticesStride; + for (uint j = 0; j < maxVerticesDataSize; ++j) + abc[0][j] = vertices[idx + j]; ++i; - ndx[0] = ndx[1]; - abc[0] = abc[1]; - } - if (loop) { - ndx[1] = indices[0]; - if (ndx[0] != ndx[1]) { - idx = ndx[1] * verticesStride; - for (uint j = 0; j < maxVerticesDataSize; ++j) - abc[1][j] = vertices[idx + j]; - visitor->visit(ndx[0], abc[0], ndx[1], abc[1]); + while (i < indexInfo.count && (!indexInfo.restartEnabled || indexInfo.restartIndexValue != static_cast<int>(indices[i]))) { + ndx[1] = indices[i]; + if (ndx[0] != ndx[1]) { + idx = ndx[1] * verticesStride; + for (uint j = 0; j < maxVerticesDataSize; ++j) + abc[1][j] = vertices[idx + j]; + visitor->visit(ndx[0], abc[0], ndx[1], abc[1]); + } + ++i; + ndx[0] = ndx[1]; + abc[0] = abc[1]; + } + if (loop) { + ndx[1] = indices[stripStartIndex]; + if (ndx[0] != ndx[1]) { + idx = ndx[1] * verticesStride; + for (uint j = 0; j < maxVerticesDataSize; ++j) + abc[1][j] = vertices[idx + j]; + visitor->visit(ndx[0], abc[0], ndx[1], abc[1]); + } } } } diff --git a/src/render/backend/trianglesvisitor.cpp b/src/render/backend/trianglesvisitor.cpp index 87ba7bde9..a58f2d20b 100644 --- a/src/render/backend/trianglesvisitor.cpp +++ b/src/render/backend/trianglesvisitor.cpp @@ -153,6 +153,10 @@ void traverseTriangleStripIndexed(index *indices, uint ndx[3]; Vector3D abc[3]; while (i < indexInfo.count - 2) { + if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 2])) { + i += 3; + continue; + } bool degenerate = false; for (uint u = 0; u < 3; ++u) { ndx[u] = indices[i + u]; @@ -216,6 +220,11 @@ void traverseTriangleFanIndexed(index *indices, ndx[0] = indices[0]; uint i = 1; while (i < indexInfo.count - 1) { + if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 1])) { + ndx[0] = indices[i + 2]; + i += 3; + continue; + } for (uint u = 0; u < 2; ++u) { ndx[u + 1] = indices[i + u]; uint idx = ndx[u + 1] * verticesStride; @@ -224,7 +233,7 @@ void traverseTriangleFanIndexed(index *indices, } } visitor->visit(ndx[2], abc[2], ndx[1], abc[1], ndx[0], abc[0]); - i += 1; + ++i; } } diff --git a/src/render/backend/visitorutils_p.h b/src/render/backend/visitorutils_p.h index 6a5c7b4ff..14183e11b 100644 --- a/src/render/backend/visitorutils_p.h +++ b/src/render/backend/visitorutils_p.h @@ -149,6 +149,8 @@ void visitPrimitives(NodeManagers *manager, const GeometryRenderer *renderer, Vi indexBufferInfo.byteOffset = indexAttribute->byteOffset(); indexBufferInfo.byteStride = indexAttribute->byteStride(); indexBufferInfo.count = indexAttribute->count(); + indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled(); + indexBufferInfo.restartIndexValue = renderer->restartIndexValue(); IndexExecutor executor; executor.m_vertexBufferInfo = vertexBufferInfo; diff --git a/src/render/lights/qdirectionallight.cpp b/src/render/lights/qdirectionallight.cpp index 13fb78843..51827b644 100644 --- a/src/render/lights/qdirectionallight.cpp +++ b/src/render/lights/qdirectionallight.cpp @@ -115,12 +115,18 @@ QDirectionalLight::QDirectionalLight(QDirectionalLightPrivate &dd, QNode *parent /*! \qmlproperty vector3d Qt3D.Render::DirectionalLight::worldDirection - Specifies the world direction of the directional light + Specifies the world direction of the directional light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QDirectionalLight::worldDirection - Specifies the world direction of the directional light + Specifies the world direction of the directional light. + + \note The exact meaning and use of this property is up to the + material implementation. */ void QDirectionalLight::setWorldDirection(const QVector3D &direction) { diff --git a/src/render/lights/qenvironmentlight.cpp b/src/render/lights/qenvironmentlight.cpp index 86ef04f95..977e117db 100644 --- a/src/render/lights/qenvironmentlight.cpp +++ b/src/render/lights/qenvironmentlight.cpp @@ -158,6 +158,9 @@ QEnvironmentLight::~QEnvironmentLight() Holds the current environment irradiance map texture. By default, the environment irradiance texture is null. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! @@ -166,6 +169,9 @@ QEnvironmentLight::~QEnvironmentLight() Holds the current environment irradiance map texture. By default, the environment irradiance texture is null. + + \note The exact meaning and use of this property is up to the + material implementation. */ QAbstractTexture *QEnvironmentLight::irradiance() const { @@ -179,6 +185,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const Holds the current environment specular map texture. By default, the environment specular texture is null. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! @@ -187,6 +196,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const Holds the current environment specular map texture. By default, the environment specular texture is null. + + \note The exact meaning and use of this property is up to the + material implementation. */ QAbstractTexture *QEnvironmentLight::specular() const { diff --git a/src/render/lights/qpointlight.cpp b/src/render/lights/qpointlight.cpp index 2b042c91d..c16291709 100644 --- a/src/render/lights/qpointlight.cpp +++ b/src/render/lights/qpointlight.cpp @@ -135,12 +135,18 @@ QPointLight::QPointLight(QPointLightPrivate &dd, QNode *parent) /*! \qmlproperty float Qt3D.Render::PointLight::constantAttenuation - Specifies the constant attenuation of the point light + Specifies the constant attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QPointLight::constantAttenuation - Specifies the constant attenuation of the point light + Specifies the constant attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QPointLight::constantAttenuation() const { @@ -159,12 +165,18 @@ void QPointLight::setConstantAttenuation(float value) /*! \qmlproperty float Qt3D.Render::PointLight::linearAttenuation - Specifies the linear attenuation of the point light + Specifies the linear attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QPointLight::linearAttenuation - Specifies the linear attenuation of the point light + Specifies the linear attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QPointLight::linearAttenuation() const { @@ -183,12 +195,18 @@ void QPointLight::setLinearAttenuation(float value) /*! \qmlproperty float Qt3D.Render::PointLight::quadraticAttenuation - Specifies the quadratic attenuation of the point light + Specifies the quadratic attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QPointLight::quadraticAttenuation - Specifies the quadratic attenuation of the point light + Specifies the quadratic attenuation of the point light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QPointLight::quadraticAttenuation() const { diff --git a/src/render/lights/qspotlight.cpp b/src/render/lights/qspotlight.cpp index eddafbe61..c725a6baf 100644 --- a/src/render/lights/qspotlight.cpp +++ b/src/render/lights/qspotlight.cpp @@ -140,12 +140,18 @@ QSpotLight::QSpotLight(QSpotLightPrivate &dd, QNode *parent) /*! \qmlproperty float Qt3D.Render::SpotLight::constantAttenuation - Specifies the constant attenuation of the spot light + Specifies the constant attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QSpotLight::constantAttenuation - Specifies the constant attenuation of the spot light + Specifies the constant attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QSpotLight::constantAttenuation() const { @@ -164,12 +170,18 @@ void QSpotLight::setConstantAttenuation(float value) /*! \qmlproperty float Qt3D.Render::SpotLight::linearAttenuation - Specifies the linear attenuation of the spot light + Specifies the linear attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QSpotLight::linearAttenuation - Specifies the linear attenuation of the spot light + Specifies the linear attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QSpotLight::linearAttenuation() const { @@ -188,12 +200,18 @@ void QSpotLight::setLinearAttenuation(float value) /*! \qmlproperty float Qt3D.Render::SpotLight::quadraticAttenuation - Specifies the quadratic attenuation of the spot light + Specifies the quadratic attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QSpotLight::quadraticAttenuation - Specifies the quadratic attenuation of the spot light + Specifies the quadratic attenuation of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QSpotLight::quadraticAttenuation() const { @@ -212,12 +230,18 @@ void QSpotLight::setQuadraticAttenuation(float value) /*! \qmlproperty vector3d Qt3D.Render::SpotLight::localDirection - Specifies the local direction of the spot light + Specifies the local direction of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QSpotLight::localDirection - Specifies the local direction of the spot light + Specifies the local direction of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ QVector3D QSpotLight::localDirection() const { @@ -227,12 +251,18 @@ QVector3D QSpotLight::localDirection() const /*! \qmlproperty float Qt3D.Render::SpotLight::cutOffAngle - Specifies the cut off angle of the spot light + Specifies the cut off angle of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ /*! \property Qt3DRender::QSpotLight::cutOffAngle - Specifies the cut off angle of the spot light + Specifies the cut off angle of the spot light. + + \note The exact meaning and use of this property is up to the + material implementation. */ float QSpotLight::cutOffAngle() const { diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 352067492..1e0f6ba96 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -1730,12 +1730,11 @@ void Renderer::clearDirtyBits(BackendNodeDirtySet changes) } #endif -bool Renderer::shouldRender() +bool Renderer::shouldRender() const { // Only render if something changed during the last frame, or the last frame // was not rendered successfully (or render-on-demand is disabled) return (m_settings->renderPolicy() == QRenderSettings::Always - || m_renderThread == nullptr // <==> we use Scene3D || m_dirtyBits.marked != 0 || m_dirtyBits.remaining != 0 || !m_lastFrameCorrect.loadRelaxed()); diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 49847196b..d5d2deb31 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -206,7 +206,7 @@ public: #if defined(QT_BUILD_INTERNAL) void clearDirtyBits(BackendNodeDirtySet changes) override; #endif - bool shouldRender() override; + bool shouldRender() const override; void skipNextFrame() override; void jobsDone(Qt3DCore::QAspectManager *manager) override; diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index 3612d8767..c00a92629 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -282,6 +282,7 @@ RenderView::RenderView() RenderView::~RenderView() { + delete m_stateSet; } namespace { @@ -686,11 +687,9 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector<Entity case QAttribute::DrawIndirectAttribute: indirectAttribute = attribute; break; - case QAttribute::VertexAttribute: { - if (command.m_activeAttributes.contains(attribute->nameId())) - estimatedCount = std::max(int(attribute->count()), estimatedCount); + case QAttribute::VertexAttribute: + estimatedCount = std::max(int(attribute->count()), estimatedCount); break; - } default: Q_UNREACHABLE(); break; diff --git a/tests/auto/core/qaspectengine/tst_qaspectengine.cpp b/tests/auto/core/qaspectengine/tst_qaspectengine.cpp index 466e103ec..48443a66f 100644 --- a/tests/auto/core/qaspectengine/tst_qaspectengine.cpp +++ b/tests/auto/core/qaspectengine/tst_qaspectengine.cpp @@ -146,6 +146,10 @@ private Q_SLOTS: void shouldNotCrashInNormalStartupShutdownSequence() { +#ifdef Q_OS_MACOS + QSKIP("Test frequently times out. See QTBUG-80660."); +#endif + // GIVEN // An initialized aspect engine... QAspectEngine engine; diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h index 8cab7edfc..05ef4c130 100644 --- a/tests/auto/render/commons/testrenderer.h +++ b/tests/auto/render/commons/testrenderer.h @@ -55,7 +55,7 @@ public: void doRender(bool swapBuffers) override { Q_UNUSED(swapBuffers) } void cleanGraphicsResources() override {} bool isRunning() const override { return true; } - bool shouldRender() override { return true; } + bool shouldRender() const override { return true; } void skipNextFrame() override {} void jobsDone(Qt3DCore::QAspectManager *manager) override { Q_UNUSED(manager) } QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); } diff --git a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp index 4db12136a..fc65d0854 100644 --- a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp +++ b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp @@ -426,12 +426,15 @@ private Q_SLOTS: simulateInitializationSync(dataBuffer.data(), backendBuffer); QByteArray indexData; - indexData.resize(sizeof(uint) * 2 * 4); + indexData.resize(sizeof(uint) * 7); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); iDataPtr[0] = 0; iDataPtr[1] = 1; iDataPtr[2] = 2; iDataPtr[3] = 3; + iDataPtr[4] = static_cast<uint>(-1); + iDataPtr[5] = 0; + iDataPtr[6] = 1; indexDataBuffer->setData(indexData); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); @@ -450,7 +453,7 @@ private Q_SLOTS: indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); - indexAttribute->setCount(4); + indexAttribute->setCount(7); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); geometry->addAttribute(positionAttribute.data()); @@ -458,6 +461,8 @@ private Q_SLOTS: geometryRenderer->setGeometry(geometry); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip); + geometryRenderer->setPrimitiveRestartEnabled(true); + geometryRenderer->setRestartIndexValue(-1); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); backendAttribute->setRenderer(&renderer); @@ -480,10 +485,11 @@ private Q_SLOTS: visitor.apply(backendRenderer, Qt3DCore::QNodeId()); // THEN - QCOMPARE(visitor.segmentCount(), uint(3)); + QCOMPARE(visitor.segmentCount(), uint(4)); QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0))); QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0))); QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0))); + QVERIFY(visitor.verifySegment(3, 0,1, Vector3D(0,0,0), Vector3D(1,0,0))); } void testVisitLineLoop() @@ -588,12 +594,16 @@ private Q_SLOTS: simulateInitializationSync(dataBuffer.data(), backendBuffer); QByteArray indexData; - indexData.resize(sizeof(uint) * 2 * 4); + indexData.resize(sizeof(uint) * 8); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); iDataPtr[0] = 0; iDataPtr[1] = 1; iDataPtr[2] = 2; iDataPtr[3] = 3; + iDataPtr[4] = static_cast<uint>(-1); + iDataPtr[5] = 0; + iDataPtr[6] = 1; + iDataPtr[7] = 2; indexDataBuffer->setData(indexData); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); @@ -612,7 +622,7 @@ private Q_SLOTS: indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); - indexAttribute->setCount(4); + indexAttribute->setCount(8); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); geometry->addAttribute(positionAttribute.data()); @@ -620,6 +630,8 @@ private Q_SLOTS: geometryRenderer->setGeometry(geometry); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop); + geometryRenderer->setPrimitiveRestartEnabled(true); + geometryRenderer->setRestartIndexValue(-1); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); backendAttribute->setRenderer(&renderer); @@ -642,11 +654,14 @@ private Q_SLOTS: visitor.apply(backendRenderer, Qt3DCore::QNodeId()); // THEN - QCOMPARE(visitor.segmentCount(), uint(4)); + QCOMPARE(visitor.segmentCount(), uint(7)); QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0))); QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0))); QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0))); QVERIFY(visitor.verifySegment(3, 3,0, Vector3D(0,1,0), Vector3D(0,0,0))); + QVERIFY(visitor.verifySegment(4, 0,1, Vector3D(0,0,0), Vector3D(1,0,0))); + QVERIFY(visitor.verifySegment(5, 1,2, Vector3D(1,0,0), Vector3D(1,1,0))); + QVERIFY(visitor.verifySegment(6, 2,0, Vector3D(1,1,0), Vector3D(0,0,0))); } void testVisitLineAdjacency() diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp index 8dfda0eea..66f67e08a 100644 --- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp +++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp @@ -454,7 +454,7 @@ private Q_SLOTS: simulateInitializationSync(dataBuffer.data(), backendBuffer); QByteArray indexData; - indexData.resize(sizeof(uint) * 3 * 4); + indexData.resize(sizeof(uint) * 4 * 4); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); iDataPtr[0] = 0; iDataPtr[1] = 1; @@ -468,6 +468,10 @@ private Q_SLOTS: iDataPtr[9] = 4; iDataPtr[10] = 3; iDataPtr[11] = 2; + iDataPtr[12] = static_cast<uint>(-1); + iDataPtr[13] = 0; + iDataPtr[14] = 1; + iDataPtr[15] = 2; indexDataBuffer->setData(indexData); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); @@ -486,7 +490,7 @@ private Q_SLOTS: indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); - indexAttribute->setCount(3*4); + indexAttribute->setCount(4*4); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); geometry->addAttribute(positionAttribute.data()); @@ -494,6 +498,8 @@ private Q_SLOTS: geometryRenderer->setGeometry(geometry); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleStrip); + geometryRenderer->setPrimitiveRestartEnabled(true); + geometryRenderer->setRestartIndexValue(-1); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); backendAttribute->setRenderer(&renderer); @@ -516,7 +522,7 @@ private Q_SLOTS: visitor.apply(backendRenderer, Qt3DCore::QNodeId()); // THEN - QVERIFY(visitor.triangleCount() == 8); + QCOMPARE(visitor.triangleCount(), 9U); QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1))); QVERIFY(visitor.verifyTriangle(1, 3,2,1, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(1,0,0))); QVERIFY(visitor.verifyTriangle(2, 4,3,2, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,1,0))); @@ -525,6 +531,7 @@ private Q_SLOTS: QVERIFY(visitor.verifyTriangle(5, 4,0,1, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(1,0,0))); QVERIFY(visitor.verifyTriangle(6, 3,4,0, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,0,1))); QVERIFY(visitor.verifyTriangle(7, 2,3,4, Vector3D(0,1,0), Vector3D(0,0,1), Vector3D(1,0,0))); + QVERIFY(visitor.verifyTriangle(8, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1))); } void testVisitTriangleFan() @@ -643,7 +650,7 @@ private Q_SLOTS: simulateInitializationSync(dataBuffer.data(), backendBuffer); QByteArray indexData; - indexData.resize(sizeof(uint) * 3 * 2); + indexData.resize(sizeof(uint) * 10); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); iDataPtr[0] = 0; iDataPtr[1] = 1; @@ -651,6 +658,10 @@ private Q_SLOTS: iDataPtr[3] = 3; iDataPtr[4] = 4; iDataPtr[5] = 5; + iDataPtr[6] = static_cast<uint>(-1); + iDataPtr[7] = 0; + iDataPtr[8] = 1; + iDataPtr[9] = 2; indexDataBuffer->setData(indexData); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); @@ -669,7 +680,7 @@ private Q_SLOTS: indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); - indexAttribute->setCount(3*2); + indexAttribute->setCount(10); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); geometry->addAttribute(positionAttribute.data()); @@ -677,6 +688,8 @@ private Q_SLOTS: geometryRenderer->setGeometry(geometry); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleFan); + geometryRenderer->setPrimitiveRestartEnabled(true); + geometryRenderer->setRestartIndexValue(-1); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); backendAttribute->setRenderer(&renderer); @@ -699,11 +712,12 @@ private Q_SLOTS: visitor.apply(backendRenderer, Qt3DCore::QNodeId()); // THEN - QVERIFY(visitor.triangleCount() == 4); + QCOMPARE(visitor.triangleCount(), 5U); QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1))); QVERIFY(visitor.verifyTriangle(1, 3,2,0, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(0,0,1))); QVERIFY(visitor.verifyTriangle(2, 4,3,0, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,0,1))); QVERIFY(visitor.verifyTriangle(3, 5,4,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1))); + QVERIFY(visitor.verifyTriangle(4, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1))); } void testVisitTrianglesAdjacency() |