summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/core/qentity/tst_qentity.cpp33
-rw-r--r--tests/auto/core/threadpooler/tst_threadpooler.cpp6
-rw-r--r--tests/auto/quick3d/3drender/3drender.qml4
-rw-r--r--tests/auto/render/attribute/tst_attribute.cpp4
-rw-r--r--tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp14
-rw-r--r--tests/auto/render/buffer/tst_buffer.cpp6
-rw-r--r--tests/auto/render/commons/testrenderer.h1
-rw-r--r--tests/auto/render/computecommand/tst_computecommand.cpp75
-rw-r--r--tests/auto/render/geometry/tst_geometry.cpp28
-rw-r--r--tests/auto/render/gltfplugins/tst_gltfplugins.cpp24
-rw-r--r--tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp39
-rw-r--r--tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp104
-rw-r--r--tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp104
-rw-r--r--tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp106
-rw-r--r--tests/auto/render/memorybarrier/tst_memorybarrier.cpp4
-rw-r--r--tests/auto/render/objectpicker/tst_objectpicker.cpp36
-rw-r--r--tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc1
-rw-r--r--tests/auto/render/pickboundingvolumejob/testscene_priorityoverlapping.qml135
-rw-r--r--tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp139
-rw-r--r--tests/auto/render/proximityfilter/tst_proximityfilter.cpp6
-rw-r--r--tests/auto/render/qabstracttexture/tst_qabstracttexture.cpp249
-rw-r--r--tests/auto/render/qbuffer/tst_qbuffer.cpp20
-rw-r--r--tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp163
-rw-r--r--tests/auto/render/qgeometry/tst_qgeometry.cpp55
-rw-r--r--tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp160
-rw-r--r--tests/auto/render/qsetfence/qsetfence.pro12
-rw-r--r--tests/auto/render/qsetfence/tst_qsetfence.cpp190
-rw-r--r--tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp92
-rw-r--r--tests/auto/render/qsharedgltexture/qsharedgltexture.pro12
-rw-r--r--tests/auto/render/qsharedgltexture/tst_qsharedgltexture.cpp171
-rw-r--r--tests/auto/render/qwaitfence/qwaitfence.pro12
-rw-r--r--tests/auto/render/qwaitfence/tst_qwaitfence.cpp349
-rw-r--r--tests/auto/render/render.pro9
-rw-r--r--tests/auto/render/renderer/tst_renderer.cpp109
-rw-r--r--tests/auto/render/setfence/setfence.pro12
-rw-r--r--tests/auto/render/setfence/tst_setfence.cpp163
-rw-r--r--tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp79
-rw-r--r--tests/auto/render/texture/tst_texture.cpp13
-rw-r--r--tests/auto/render/textures/tst_textures.cpp94
-rw-r--r--tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp6
-rw-r--r--tests/auto/render/waitfence/tst_waitfence.cpp186
-rw-r--r--tests/auto/render/waitfence/waitfence.pro12
-rw-r--r--tests/manual/manual.pro6
-rw-r--r--tests/manual/sharedtexture/main.cpp159
-rw-r--r--tests/manual/sharedtexture/sharedtexture.pro12
-rw-r--r--tests/manual/sharedtexture/videoplayer.cpp233
-rw-r--r--tests/manual/sharedtexture/videoplayer.h122
-rw-r--r--tests/manual/sharedtextureqml/main.cpp131
-rw-r--r--tests/manual/sharedtextureqml/main.qml144
-rw-r--r--tests/manual/sharedtextureqml/qml.qrc5
-rw-r--r--tests/manual/sharedtextureqml/sharedtextureqml.pro17
-rw-r--r--tests/manual/texture_property_updates/main.cpp2
-rw-r--r--tests/manual/texture_property_updates/main.qml4
53 files changed, 3744 insertions, 128 deletions
diff --git a/tests/auto/core/qentity/tst_qentity.cpp b/tests/auto/core/qentity/tst_qentity.cpp
index e27cd1fc9..d7847342b 100644
--- a/tests/auto/core/qentity/tst_qentity.cpp
+++ b/tests/auto/core/qentity/tst_qentity.cpp
@@ -53,6 +53,8 @@ private slots:
void addComponentsSeveralParentsSingleAggregations();
void addComponentsSeveralParentsSeveralAggregations();
+ void retrieveSingleComponent();
+
void removeComponentSingleParentSingleAggregation();
void removeComponentSingleParentSeveralAggregations();
void removeComponentsSeveralParentsSingleAggreation();
@@ -76,6 +78,14 @@ public:
{}
};
+class MyQ2Component : public Qt3DCore::QComponent
+{
+ Q_OBJECT
+public:
+ explicit MyQ2Component(Qt3DCore::QNode *parent = 0)
+ : QComponent(parent)
+ {}
+};
class MyEntity : public Qt3DCore::QEntity
{
@@ -504,6 +514,29 @@ void tst_Entity::removeComponentsSeveralParentsSeveralAggregations()
QCOMPARE(comp3->entities().size(), 0);
}
+void tst_Entity::retrieveSingleComponent()
+{
+ // GIVEN
+ QScopedPointer<Qt3DCore::QEntity> entity1(new QEntity());
+
+ MyQComponent *comp1 = new MyQComponent(entity1.data());
+ MyQComponent *comp2 = new MyQComponent(entity1.data());
+ QCoreApplication::processEvents();
+ entity1->addComponent(comp1);
+ entity1->addComponent(comp2);
+
+ // WHEN
+ QVector<MyQComponent*> myQComponentsInEntity = entity1->componentsOfType<MyQComponent>();
+ QVector<MyQ2Component*> myQ2ComponentsInEntity = entity1->componentsOfType<MyQ2Component>();
+
+ // THEN
+ QVERIFY(myQComponentsInEntity.size() == 2);
+ QVERIFY(myQComponentsInEntity[0] == comp1);
+ QVERIFY(myQComponentsInEntity[1] == comp2);
+
+ QVERIFY(myQ2ComponentsInEntity.size() == 0);
+}
+
void tst_Entity::addSeveralTimesSameComponent()
{
// GIVEN
diff --git a/tests/auto/core/threadpooler/tst_threadpooler.cpp b/tests/auto/core/threadpooler/tst_threadpooler.cpp
index bc4552c66..98cbbc92d 100644
--- a/tests/auto/core/threadpooler/tst_threadpooler.cpp
+++ b/tests/auto/core/threadpooler/tst_threadpooler.cpp
@@ -332,13 +332,13 @@ public:
m_globalAtomic.fetchAndAddOrdered(qPow(3, index));
}
- int globalAtomicValue() const
+ quint64 globalAtomicValue() const
{
return m_globalAtomic.load();
}
private:
- QAtomicInt m_globalAtomic;
+ QAtomicInteger<quint64> m_globalAtomic;
QAtomicInt m_currentIndex;
};
@@ -353,7 +353,7 @@ void tst_ThreadPooler::perThreadUniqueCall()
// GIVEN
PerThreadUniqueTester tester;
const int maxThreads = QThread::idealThreadCount();
- int maxValue = 0;
+ quint64 maxValue = 0;
for (int i = 0; i < maxThreads; ++i) {
maxValue += qPow(3, i);
}
diff --git a/tests/auto/quick3d/3drender/3drender.qml b/tests/auto/quick3d/3drender/3drender.qml
index 112031282..c20ce6c45 100644
--- a/tests/auto/quick3d/3drender/3drender.qml
+++ b/tests/auto/quick3d/3drender/3drender.qml
@@ -30,6 +30,7 @@
import Qt3D.Render 2.0 as QQ3Render20
import Qt3D.Render 2.1 as QQ3Render21
import Qt3D.Render 2.10 as QQ3Render210
+import Qt3D.Render 2.13 as QQ3Render213
import QtQuick 2.0
Item {
@@ -79,6 +80,9 @@ Item {
QQ3Render20.TextureLoader {} //Qt3DRender::QTextureLoader, Qt3DRender::Render::Quick::Quick3DTextureExtension
//QQ3Render20.QAbstractTextureImage // (uncreatable) Qt3DRender::QAbstractTextureImage
QQ3Render20.TextureImage {} //Qt3DRender::QTextureImage
+ QQ3Render213.SharedGLTexture {} //Qt3DRender::QSharedGLTexture
+ QQ3Render213.WaitFence {} //Qt3DRender::QWaitFence
+ QQ3Render213.SetFence {} //Qt3DRender::QSetFence
// Geometry
QQ3Render20.Attribute {} //Qt3DRender::QAttribute
diff --git a/tests/auto/render/attribute/tst_attribute.cpp b/tests/auto/render/attribute/tst_attribute.cpp
index a673a327b..e0f6f6b5c 100644
--- a/tests/auto/render/attribute/tst_attribute.cpp
+++ b/tests/auto/render/attribute/tst_attribute.cpp
@@ -53,7 +53,7 @@ private Q_SLOTS:
attribute.setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort);
attribute.setVertexSize(3);
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy);
buffer.setData(QByteArrayLiteral("Corvette"));
attribute.setBuffer(&buffer);
@@ -105,7 +105,7 @@ private Q_SLOTS:
attribute.setName(QStringLiteral("C3"));
attribute.setVertexBaseType(Qt3DRender::QAttribute::Double);
attribute.setVertexSize(4);
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy);
buffer.setData(QByteArrayLiteral("C7"));
attribute.setBuffer(&buffer);
diff --git a/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp
index 26c43b5c2..9232aa70f 100644
--- a/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp
+++ b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp
@@ -118,6 +118,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -130,6 +132,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.sourceRenderTargetId(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -142,6 +146,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.destinationRenderTargetId(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -153,6 +159,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.sourceRect(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -164,6 +172,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.destinationRect(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -175,6 +185,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -186,6 +198,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
}
diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp
index a3098f0bd..da853d4e9 100644
--- a/tests/auto/render/buffer/tst_buffer.cpp
+++ b/tests/auto/render/buffer/tst_buffer.cpp
@@ -71,7 +71,7 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::Buffer renderBuffer;
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
Qt3DRender::Render::BufferManager bufferManager;
TestRenderer renderer;
@@ -268,7 +268,7 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::Buffer renderBuffer;
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
Qt3DRender::Render::BufferManager bufferManager;
TestRenderer renderer;
@@ -294,7 +294,7 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::Buffer renderBuffer;
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
Qt3DRender::Render::BufferManager bufferManager;
TestRenderer renderer;
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index 466cebe14..f19b3211b 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -57,6 +57,7 @@ public:
bool isRunning() const override { return true; }
bool shouldRender() override { return true; }
void skipNextFrame() override {}
+ QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
Qt3DCore::QAspectJobPtr rayCastingJob() override { return Qt3DCore::QAspectJobPtr(); }
diff --git a/tests/auto/render/computecommand/tst_computecommand.cpp b/tests/auto/render/computecommand/tst_computecommand.cpp
index 13688d299..1c8380f73 100644
--- a/tests/auto/render/computecommand/tst_computecommand.cpp
+++ b/tests/auto/render/computecommand/tst_computecommand.cpp
@@ -31,9 +31,11 @@
#include <Qt3DRender/qcomputecommand.h>
#include <Qt3DRender/private/qcomputecommand_p.h>
#include <Qt3DRender/private/computecommand_p.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include "qbackendnodetester.h"
#include "testrenderer.h"
+#include "testpostmanarbiter.h"
class tst_ComputeCommand : public Qt3DCore::QBackendNodeTester
{
@@ -52,6 +54,8 @@ private Q_SLOTS:
QCOMPARE(backendComputeCommand.x(), 1);
QCOMPARE(backendComputeCommand.y(), 1);
QCOMPARE(backendComputeCommand.z(), 1);
+ QCOMPARE(backendComputeCommand.runType(), Qt3DRender::QComputeCommand::Continuous);
+ QCOMPARE(backendComputeCommand.frameCount(), 0);
}
void checkCleanupState()
@@ -75,6 +79,8 @@ private Q_SLOTS:
computeCommand.setWorkGroupX(256);
computeCommand.setWorkGroupY(512);
computeCommand.setWorkGroupZ(128);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.trigger(6);
{
// WHEN
@@ -87,6 +93,8 @@ private Q_SLOTS:
QCOMPARE(backendComputeCommand.x(), computeCommand.workGroupX());
QCOMPARE(backendComputeCommand.y(), computeCommand.workGroupY());
QCOMPARE(backendComputeCommand.z(), computeCommand.workGroupZ());
+ QCOMPARE(backendComputeCommand.runType(), computeCommand.runType());
+ QCOMPARE(backendComputeCommand.frameCount(), 6);
}
{
// WHEN
@@ -151,8 +159,75 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.z(), newValue);
}
+ {
+ // WHEN
+ const Qt3DRender::QComputeCommand::RunType newValue = Qt3DRender::QComputeCommand::Manual;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("runType");
+ change->setValue(newValue);
+ backendComputeCommand.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendComputeCommand.runType(), newValue);
+ }
+ {
+ // WHEN
+ const int newValue = 32;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("frameCount");
+ change->setValue(newValue);
+ backendComputeCommand.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), newValue);
+ }
}
+ void checkUpdateFrameCount()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ TestArbiter arbiter;
+
+ Qt3DRender::QComputeCommand computeCommand;
+ Qt3DRender::Render::ComputeCommand backendComputeCommand;
+
+ computeCommand.setWorkGroupX(256);
+ computeCommand.setWorkGroupY(512);
+ computeCommand.setWorkGroupZ(128);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.trigger(6);
+
+
+ Qt3DCore::QBackendNodePrivate::get(&backendComputeCommand)->setArbiter(&arbiter);
+
+ backendComputeCommand.setRenderer(&renderer);
+ simulateInitialization(&computeCommand, &backendComputeCommand);
+
+ for (int i = 0; i < 5; ++i) {
+ // WHEN
+ backendComputeCommand.updateFrameCount();
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), 6 - (i + 1));
+ QCOMPARE(backendComputeCommand.isEnabled(), true);
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ // WHEN
+ backendComputeCommand.updateFrameCount();
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), false);
+ QCOMPARE(backendComputeCommand.isEnabled(), false);
+ QCOMPARE(arbiter.events.size(), 1);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<int>(), false);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ }
};
QTEST_MAIN(tst_ComputeCommand)
diff --git a/tests/auto/render/geometry/tst_geometry.cpp b/tests/auto/render/geometry/tst_geometry.cpp
index 958edfd09..7e65d27aa 100644
--- a/tests/auto/render/geometry/tst_geometry.cpp
+++ b/tests/auto/render/geometry/tst_geometry.cpp
@@ -34,7 +34,9 @@
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
#include "testrenderer.h"
+#include "testpostmanarbiter.h"
class DummyAttribute : public Qt3DRender::QAttribute
{
@@ -187,6 +189,32 @@ private Q_SLOTS:
QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
+
+ void checkExtentTransmission()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ TestArbiter arbiter;
+ Qt3DRender::Render::Geometry renderGeometry;
+
+ Qt3DCore::QBackendNodePrivate::get(&renderGeometry)->setArbiter(&arbiter);
+ renderGeometry.setRenderer(&renderer);
+
+ // WHEN
+ renderGeometry.updateExtent(QVector3D(-1.0f, -1.0f, -1.0f), QVector3D(1.0f, 1.0f, 1.0f));
+ renderGeometry.notifyExtentChanged();
+
+ // THEN
+ QCOMPARE(arbiter.events.count(), 1);
+
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "extent");
+ const QPair<QVector3D, QVector3D> v = change->value().value<QPair<QVector3D, QVector3D>>();
+ QCOMPARE(v.first, QVector3D(-1.0f, -1.0f, -1.0f));
+ QCOMPARE(v.second, QVector3D(1.0f, 1.0f, 1.0f));
+
+ arbiter.events.clear();
+ }
};
diff --git a/tests/auto/render/gltfplugins/tst_gltfplugins.cpp b/tests/auto/render/gltfplugins/tst_gltfplugins.cpp
index e5a0eef21..0de94a931 100644
--- a/tests/auto/render/gltfplugins/tst_gltfplugins.cpp
+++ b/tests/auto/render/gltfplugins/tst_gltfplugins.cpp
@@ -516,7 +516,7 @@ void tst_gltfPlugins::createTestScene()
Qt3DRender::QGeometryRenderer *boxMesh = createCustomCube();
Qt3DRender::QBuffer *colorDataBuffer =
- new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, boxMesh->geometry());
+ new Qt3DRender::QBuffer(boxMesh->geometry());
QByteArray colorBufferData;
colorBufferData.resize(8 * 4 * sizeof(float));
@@ -571,7 +571,7 @@ void tst_gltfPlugins::createTestScene()
transform->setRotation(Qt3DCore::QTransform::fromAxisAndAngle(1.0f, 2.0f, 3.0f, 90.0f));
Qt3DRender::QGeometryRenderer *boxMesh = createCustomCube();
Qt3DRender::QBuffer *offsetBuffer =
- new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, boxMesh->geometry());
+ new Qt3DRender::QBuffer(boxMesh->geometry());
QByteArray offsetBufferData;
offsetBufferData.resize(8 * 3 * sizeof(float));
@@ -587,8 +587,8 @@ void tst_gltfPlugins::createTestScene()
Qt3DRender::QAttribute *customAttribute = new Qt3DRender::QAttribute();
customAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
customAttribute->setBuffer(offsetBuffer);
- customAttribute->setDataType(Qt3DRender::QAttribute::Float);
- customAttribute->setDataSize(3);
+ customAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ customAttribute->setVertexSize(3);
customAttribute->setByteOffset(0);
customAttribute->setByteStride(0);
customAttribute->setCount(8);
@@ -620,8 +620,8 @@ void tst_gltfPlugins::addPositionAttributeToGeometry(Qt3DRender::QGeometry *geom
Qt3DRender::QAttribute *posAttribute = new Qt3DRender::QAttribute();
posAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
posAttribute->setBuffer(buffer);
- posAttribute->setDataType(Qt3DRender::QAttribute::Float);
- posAttribute->setDataSize(3);
+ posAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ posAttribute->setVertexSize(3);
posAttribute->setByteOffset(0);
posAttribute->setByteStride(0);
posAttribute->setCount(count);
@@ -636,8 +636,8 @@ void tst_gltfPlugins::addIndexAttributeToGeometry(Qt3DRender::QGeometry *geometr
Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute();
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
indexAttribute->setBuffer(buffer);
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedShort);
- indexAttribute->setDataSize(1);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort);
+ indexAttribute->setVertexSize(1);
indexAttribute->setByteOffset(0);
indexAttribute->setByteStride(0);
indexAttribute->setCount(count);
@@ -651,8 +651,8 @@ void tst_gltfPlugins::addColorAttributeToGeometry(Qt3DRender::QGeometry *geometr
Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute();
colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
colorAttribute->setBuffer(buffer);
- colorAttribute->setDataType(Qt3DRender::QAttribute::Float);
- colorAttribute->setDataSize(4);
+ colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ colorAttribute->setVertexSize(4);
colorAttribute->setByteOffset(0);
colorAttribute->setByteStride(0);
colorAttribute->setCount(count);
@@ -964,9 +964,9 @@ Qt3DRender::QGeometryRenderer *tst_gltfPlugins::createCustomCube()
Qt3DRender::QGeometryRenderer *boxMesh = new Qt3DRender::QGeometryRenderer;
Qt3DRender::QGeometry *boxGeometry = new Qt3DRender::QGeometry(boxMesh);
Qt3DRender::QBuffer *boxDataBuffer =
- new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, boxGeometry);
+ new Qt3DRender::QBuffer(boxGeometry);
Qt3DRender::QBuffer *indexDataBuffer =
- new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, boxGeometry);
+ new Qt3DRender::QBuffer(boxGeometry);
QByteArray vertexBufferData;
QByteArray indexBufferData;
diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
index 584b675ee..6c756957f 100644
--- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
+++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
@@ -926,6 +926,9 @@ private Q_SLOTS:
SUPPORTS_FEATURE(GraphicsHelperInterface::DrawBuffersBlend, false);
SUPPORTS_FEATURE(GraphicsHelperInterface::Tessellation, false);
SUPPORTS_FEATURE(GraphicsHelperInterface::BlitFramebuffer, false);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::IndirectDrawing, false);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::MapBuffer, true);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::Fences, false);
}
@@ -1524,6 +1527,36 @@ private Q_SLOTS:
// Not supported by GL2
}
+ void fenceSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void clientWaitSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void waitSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void wasSyncSignaled()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void deleteSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
@@ -1537,17 +1570,11 @@ QT_END_NAMESPACE
#endif
-
-QT_BEGIN_NAMESPACE
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
-QT_END_NAMESPACE
-
int main(int argc, char *argv[])
{
#ifdef TEST_SHOULD_BE_PERFORMED
QGuiApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
- QTEST_ADD_GPU_BLACKLIST_SUPPORT
tst_GraphicsHelperGL2 tc;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
index 648eaaddb..5eb171827 100644
--- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
+++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
@@ -2151,6 +2151,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
@@ -2161,16 +2260,11 @@ private:
#endif
-QT_BEGIN_NAMESPACE
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
-QT_END_NAMESPACE
-
int main(int argc, char *argv[])
{
#ifdef TEST_SHOULD_BE_PERFORMED
QGuiApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
- QTEST_ADD_GPU_BLACKLIST_SUPPORT
tst_GraphicsHelperGL3_2 tc;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
index 06a3c41cd..a88e36d5e 100644
--- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
+++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
@@ -2251,6 +2251,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
@@ -2261,16 +2360,11 @@ private:
#endif
-QT_BEGIN_NAMESPACE
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
-QT_END_NAMESPACE
-
int main(int argc, char *argv[])
{
#ifdef TEST_SHOULD_BE_PERFORMED
QGuiApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
- QTEST_ADD_GPU_BLACKLIST_SUPPORT
tst_GraphicsHelperGL3_3 tc;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
index 39bd15021..87eee19ac 100644
--- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
+++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
@@ -1430,7 +1430,7 @@ private Q_SLOTS:
void supportsFeature()
{
- for (int i = 0; i <= GraphicsHelperInterface::BlitFramebuffer; ++i)
+ for (int i = 0; i <= GraphicsHelperInterface::Fences; ++i)
QVERIFY(m_glHelper.supportsFeature(static_cast<GraphicsHelperInterface::Feature>(i)));
}
@@ -2349,6 +2349,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
@@ -2359,16 +2458,11 @@ private:
#endif
-QT_BEGIN_NAMESPACE
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
-QT_END_NAMESPACE
-
int main(int argc, char *argv[])
{
#ifdef TEST_SHOULD_BE_PERFORMED
QGuiApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
- QTEST_ADD_GPU_BLACKLIST_SUPPORT
tst_GraphicsHelperGL4 tc;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
diff --git a/tests/auto/render/memorybarrier/tst_memorybarrier.cpp b/tests/auto/render/memorybarrier/tst_memorybarrier.cpp
index f0d4931d9..33a1247fa 100644
--- a/tests/auto/render/memorybarrier/tst_memorybarrier.cpp
+++ b/tests/auto/render/memorybarrier/tst_memorybarrier.cpp
@@ -98,6 +98,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendMemoryBarrier.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -109,6 +111,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendMemoryBarrier.waitOperations(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
}
diff --git a/tests/auto/render/objectpicker/tst_objectpicker.cpp b/tests/auto/render/objectpicker/tst_objectpicker.cpp
index c1b06ccd8..644849102 100644
--- a/tests/auto/render/objectpicker/tst_objectpicker.cpp
+++ b/tests/auto/render/objectpicker/tst_objectpicker.cpp
@@ -47,6 +47,7 @@ private Q_SLOTS:
Qt3DRender::Render::ObjectPicker objectPicker;
Qt3DRender::QObjectPicker picker;
picker.setHoverEnabled(true);
+ picker.setPriority(883);
// WHEN
simulateInitialization(&picker, &objectPicker);
@@ -54,6 +55,7 @@ private Q_SLOTS:
// THEN
QVERIFY(!objectPicker.peerId().isNull());
QCOMPARE(objectPicker.isHoverEnabled(), true);
+ QCOMPARE(objectPicker.priority(), 883);
}
void checkInitialAndCleanedUpState()
@@ -64,10 +66,14 @@ private Q_SLOTS:
// THEN
QVERIFY(objectPicker.peerId().isNull());
QCOMPARE(objectPicker.isHoverEnabled(), false);
+ QCOMPARE(objectPicker.isDragEnabled(), false);
+ QCOMPARE(objectPicker.priority(), 0);
// GIVEN
Qt3DRender::QObjectPicker picker;
picker.setHoverEnabled(true);
+ picker.setDragEnabled(true);
+ picker.setPriority(1584);
// WHEN
simulateInitialization(&picker, &objectPicker);
@@ -75,6 +81,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(objectPicker.isHoverEnabled(), false);
+ QCOMPARE(objectPicker.isDragEnabled(), false);
+ QCOMPARE(objectPicker.priority(), 0);
}
void checkPropertyChanges()
@@ -95,6 +103,34 @@ private Q_SLOTS:
QCOMPARE(objectPicker.isHoverEnabled(), true);
QVERIFY(renderer.dirtyBits() != 0);
}
+ {
+ Qt3DRender::Render::ObjectPicker objectPicker;
+ objectPicker.setRenderer(&renderer);
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(true);
+ updateChange->setPropertyName("dragEnabled");
+ objectPicker.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(objectPicker.isDragEnabled(), true);
+ QVERIFY(renderer.dirtyBits() != 0);
+ }
+ {
+ Qt3DRender::Render::ObjectPicker objectPicker;
+ objectPicker.setRenderer(&renderer);
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setValue(15);
+ updateChange->setPropertyName("priority");
+ objectPicker.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(objectPicker.priority(), 15);
+ QVERIFY(renderer.dirtyBits() != 0);
+ }
}
void checkBackendPropertyNotifications()
diff --git a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
index feef480e2..e1506de86 100644
--- a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
+++ b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
@@ -10,5 +10,6 @@
<file>testscene_parententity.qml</file>
<file>testscene_viewports.qml</file>
<file>testscene_cameraposition.qml</file>
+ <file>testscene_priorityoverlapping.qml</file>
</qresource>
</RCC>
diff --git a/tests/auto/render/pickboundingvolumejob/testscene_priorityoverlapping.qml b/tests/auto/render/pickboundingvolumejob/testscene_priorityoverlapping.qml
new file mode 100644
index 000000000..7cacb3d2d
--- /dev/null
+++ b/tests/auto/render/pickboundingvolumejob/testscene_priorityoverlapping.qml
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.13
+import Qt3D.Extras 2.0
+import QtQuick.Window 2.0
+
+Entity {
+ id: sceneRoot
+
+ Window {
+ id: win
+ width: 600
+ height: 600
+ visible: true
+ }
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 0.0, -40.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
+ }
+
+ components: [
+ RenderSettings {
+ activeFrameGraph: Viewport {
+ normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
+
+ RenderSurfaceSelector {
+ surface: win
+
+ ClearBuffers {
+ buffers : ClearBuffers.ColorDepthBuffer
+ NoDraw {}
+ }
+
+ CameraSelector {
+ camera: camera
+ }
+ }
+ }
+ pickingSettings {
+ pickResultMode: PickingSettings.NearestPriorityPick
+ pickMethod: PickingSettings.TrianglePicking
+ faceOrientationPickingMode: PickingSettings.FrontAndBackFace
+ }
+ }
+ ]
+
+ CuboidMesh { id: cubeMesh }
+ PhongMaterial { id: material }
+
+ // Entity 1
+ Entity {
+ property ObjectPicker picker: ObjectPicker {
+ id: picker1
+ objectName: "Picker1"
+ }
+
+ property Transform transform: Transform {
+ translation: Qt.vector3d(0, 0, 0)
+ scale: 2.0
+ }
+
+ components: [cubeMesh, material, picker1, transform]
+ }
+
+ // Entity 2
+ Entity {
+ property ObjectPicker picker: ObjectPicker {
+ id: picker2
+ objectName: "Picker2"
+ }
+
+ property Transform transform: Transform {
+ translation: Qt.vector3d(0, 0, 10)
+ scale: 2.5
+ }
+
+ components: [cubeMesh, material, picker2, transform]
+ }
+}
diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
index 21f75b7a4..497e620a7 100644
--- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
+++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
@@ -249,40 +249,6 @@ private Q_SLOTS:
QCOMPARE(vca.viewport, QRectF(0.0f, 0.0f, 1.0f, 1.0f));
}
- void entityGatherer()
- {
- // GIVEN
- QmlSceneReader sceneReader(QUrl("qrc:/testscene_dragenabled.qml"));
- QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root()));
- QVERIFY(root);
- QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data()));
-
- Qt3DRender::Render::UpdateEntityHierarchyJob updateEntitiesJob;
- updateEntitiesJob.setManager(test->nodeManagers());
- updateEntitiesJob.run();
-
- // THEN
- QList<Qt3DCore::QEntity *> frontendEntities;
- frontendEntities << qobject_cast<Qt3DCore::QEntity *>(root.data()) << root->findChildren<Qt3DCore::QEntity *>();
- QCOMPARE(frontendEntities.size(), 4);
-
- // WHEN
- Qt3DRender::Render::PickingUtils::EntityGatherer gatherer(test->nodeManagers()->lookupResource<Qt3DRender::Render::Entity, Qt3DRender::Render::EntityManager>(root->id()));
- QVector<Qt3DRender::Render::Entity *> entities = gatherer.entities();
-
- // THEN
- QCOMPARE(frontendEntities.size(), entities.size());
-
- std::sort(frontendEntities.begin(), frontendEntities.end(),
- [] (Qt3DCore::QEntity *a, Qt3DCore::QEntity *b) { return a->id() > b->id(); });
-
- std::sort(entities.begin(), entities.end(),
- [] (Qt3DRender::Render::Entity *a, Qt3DRender::Render::Entity *b) { return a->peerId() > b->peerId(); });
-
- for (int i = 0, e = frontendEntities.size(); i < e; ++i)
- QCOMPARE(frontendEntities.at(i)->id(), entities.at(i)->peerId());
- }
-
void checkCurrentPickerChange_data()
{
generateAllPickingSettingsCombinations();
@@ -1482,6 +1448,111 @@ private Q_SLOTS:
arbiter.events.clear();
}
+ void checkPriorityPicking()
+ {
+ // GIVEN
+ QmlSceneReader sceneReader(QUrl("qrc:/testscene_priorityoverlapping.qml"));
+ QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root()));
+ QVERIFY(root);
+
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data()));
+ TestArbiter arbiter1;
+ TestArbiter arbiter2;
+
+ // Runs Required jobs
+ runRequiredJobs(test.data());
+
+ // THEN
+ QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>();
+ QCOMPARE(pickers.size(), 2);
+
+ Qt3DRender::QObjectPicker *picker1 = nullptr;
+ Qt3DRender::QObjectPicker *picker2 = nullptr;
+ if (pickers.first()->objectName() == QLatin1String("Picker1")) {
+ picker1 = pickers.first();
+ picker2 = pickers.last();
+ } else {
+ picker1 = pickers.last();
+ picker2 = pickers.first();
+ }
+
+ Qt3DRender::Render::ObjectPicker *backendPicker1 = test->nodeManagers()->objectPickerManager()->lookupResource(picker1->id());
+ QVERIFY(backendPicker1);
+ Qt3DCore::QBackendNodePrivate::get(backendPicker1)->setArbiter(&arbiter1);
+
+ Qt3DRender::Render::ObjectPicker *backendPicker2 = test->nodeManagers()->objectPickerManager()->lookupResource(picker2->id());
+ QVERIFY(backendPicker2);
+ Qt3DCore::QBackendNodePrivate::get(backendPicker2)->setArbiter(&arbiter2);
+
+
+ // WHEN both have priority == 0, select closest
+ {
+ Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
+ initializePickBoundingVolumeJob(&pickBVJob, test.data());
+
+ // WHEN -> Pressed on object
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(300.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ bool earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Select picker with highest priority
+ QVERIFY(!earlyReturn);
+ QVERIFY(backendPicker1->isPressed());
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter1.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pressed");
+
+ QVERIFY(!backendPicker2->isPressed());
+ QVERIFY(arbiter2.events.isEmpty());
+
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(300.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ pickBVJob.runHelper();
+ arbiter1.events.clear();
+ arbiter2.events.clear();
+
+ QVERIFY(!backendPicker1->isPressed());
+ QVERIFY(!backendPicker2->isPressed());
+ }
+
+ // WHEN furthest one has higher priority, select furthest one
+ {
+ backendPicker2->setPriority(1000);
+ QCOMPARE(backendPicker2->priority(), 1000);
+
+ Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
+ initializePickBoundingVolumeJob(&pickBVJob, test.data());
+
+ // WHEN -> Pressed on object
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(300.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ bool earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Select picker with highest priority
+ QVERIFY(!earlyReturn);
+ QVERIFY(backendPicker2->isPressed());
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter2.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pressed");
+
+ QVERIFY(!backendPicker1->isPressed());
+ QVERIFY(arbiter1.events.isEmpty());
+
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(300.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ pickBVJob.runHelper();
+ arbiter1.events.clear();
+ arbiter2.events.clear();
+
+ QVERIFY(!backendPicker1->isPressed());
+ QVERIFY(!backendPicker2->isPressed());
+ }
+ }
+
};
QTEST_MAIN(tst_PickBoundingVolumeJob)
diff --git a/tests/auto/render/proximityfilter/tst_proximityfilter.cpp b/tests/auto/render/proximityfilter/tst_proximityfilter.cpp
index 774e2dd1f..ac9cc610c 100644
--- a/tests/auto/render/proximityfilter/tst_proximityfilter.cpp
+++ b/tests/auto/render/proximityfilter/tst_proximityfilter.cpp
@@ -101,6 +101,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendProximityFilter.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -112,6 +114,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendProximityFilter.distanceThreshold(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -123,6 +127,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendProximityFilter.entityId(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
}
diff --git a/tests/auto/render/qabstracttexture/tst_qabstracttexture.cpp b/tests/auto/render/qabstracttexture/tst_qabstracttexture.cpp
index c7158f4de..73c882619 100644
--- a/tests/auto/render/qabstracttexture/tst_qabstracttexture.cpp
+++ b/tests/auto/render/qabstracttexture/tst_qabstracttexture.cpp
@@ -42,6 +42,17 @@
class FakeTexture : public Qt3DRender::QAbstractTexture
{
+public:
+ int sharedTextureId() const
+ {
+ return static_cast<Qt3DRender::QAbstractTexturePrivate *>(d_ptr.get())->m_sharedTextureId;
+ }
+
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override
+ {
+ Qt3DRender::QAbstractTexture::sceneChangeEvent(change);
+ }
+
};
class FakeTextureImage : public Qt3DRender::QAbstractTextureImage
@@ -91,6 +102,10 @@ private Q_SLOTS:
QCOMPARE(abstractTexture.layers(), 1);
QCOMPARE(abstractTexture.samples(), 1);
QCOMPARE(abstractTexture.textureImages().size(), 0);
+ QCOMPARE(abstractTexture.samples(), 1);
+ QCOMPARE(abstractTexture.sharedTextureId(), -1);
+ QCOMPARE(abstractTexture.handleType(), Qt3DRender::QAbstractTexture::NoHandle);
+ QCOMPARE(abstractTexture.handle(), QVariant());
}
void checkPropertyChanges()
@@ -383,6 +398,7 @@ private Q_SLOTS:
QCOMPARE(abstractTexture.comparisonMode(), cloneData.comparisonMode);
QCOMPARE(abstractTexture.layers(), cloneData.layers);
QCOMPARE(abstractTexture.samples(), cloneData.samples);
+ QCOMPARE(abstractTexture.sharedTextureId(), cloneData.sharedTextureId);
QCOMPARE(abstractTexture.textureImages().size(), cloneData.textureImageIds.size());
for (int i = 0, m = abstractTexture.textureImages().size(); i < m; ++i)
@@ -425,6 +441,7 @@ private Q_SLOTS:
QCOMPARE(abstractTexture.comparisonMode(), cloneData.comparisonMode);
QCOMPARE(abstractTexture.layers(), cloneData.layers);
QCOMPARE(abstractTexture.samples(), cloneData.samples);
+ QCOMPARE(abstractTexture.sharedTextureId(), cloneData.sharedTextureId);
QCOMPARE(abstractTexture.textureImages().size(), cloneData.textureImageIds.size());
for (int i = 0, m = abstractTexture.textureImages().size(); i < m; ++i)
@@ -882,6 +899,238 @@ private Q_SLOTS:
}
}
+ void checkSceneChangedEvent()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ FakeTexture abstractTexture;
+ arbiter.setArbiterOnNode(&abstractTexture);
+
+ qRegisterMetaType<Qt3DRender::QAbstractTexture::Status>("Status");
+ qRegisterMetaType<Qt3DRender::QAbstractTexture::TextureFormat>("TextureFormat");
+ qRegisterMetaType<Qt3DRender::QAbstractTexture::HandleType>("HandleType");
+
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(widthChanged(int)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("width");
+ valueChange->setValue(883);
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.width(), 883);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.width(), 883);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(heightChanged(int)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("height");
+ valueChange->setValue(1584);
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.height(), 1584);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.height(), 1584);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(depthChanged(int)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("depth");
+ valueChange->setValue(8);
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.depth(), 8);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.depth(), 8);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(layersChanged(int)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("layers");
+ valueChange->setValue(256);
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.layers(), 256);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.layers(), 256);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(formatChanged(TextureFormat)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("format");
+ const auto newFormat = Qt3DRender::QAbstractTexture::R8I;
+ valueChange->setValue(QVariant::fromValue(newFormat));
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.format(), newFormat);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.format(), newFormat);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(statusChanged(Status)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("status");
+ const auto newStatus = Qt3DRender::QAbstractTexture::Error;
+ valueChange->setValue(QVariant::fromValue(newStatus));
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.status(), newStatus);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.status(), newStatus);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(handleTypeChanged(HandleType)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("handleType");
+ const auto newType = Qt3DRender::QAbstractTexture::OpenGLTextureId;
+ valueChange->setValue(QVariant::fromValue(newType));
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.handleType(), newType);
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.handleType(), newType);
+ }
+
+ {
+ QSignalSpy spy(&abstractTexture, SIGNAL(handleChanged(QVariant)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("handle");
+ valueChange->setValue(QVariant(1));
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.handle(), QVariant(1));
+
+ // WHEN
+ spy.clear();
+ abstractTexture.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(arbiter.events.size(), 0);
+ QCOMPARE(abstractTexture.handle(), QVariant(1));
+ }
+ }
+
};
QTEST_MAIN(tst_QAbstractTexture)
diff --git a/tests/auto/render/qbuffer/tst_qbuffer.cpp b/tests/auto/render/qbuffer/tst_qbuffer.cpp
index c0d96d10b..21bedf744 100644
--- a/tests/auto/render/qbuffer/tst_qbuffer.cpp
+++ b/tests/auto/render/qbuffer/tst_qbuffer.cpp
@@ -76,13 +76,13 @@ private Q_SLOTS:
Qt3DRender::QBuffer *defaultConstructed = new Qt3DRender::QBuffer();
QTest::newRow("defaultConstructed") << defaultConstructed;
- Qt3DRender::QBuffer *buffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer);
+ auto buffer = new Qt3DRender::QBuffer;
buffer->setUsage(Qt3DRender::QBuffer::DynamicRead);
buffer->setData(QByteArrayLiteral("There's no replacement"));
buffer->setDataGenerator(Qt3DRender::QBufferDataGeneratorPtr(new TestFunctor(883)));
QTest::newRow("vertex") << buffer;
- Qt3DRender::QBuffer *indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer);
+ auto indexBuffer = new Qt3DRender::QBuffer;
indexBuffer->setUsage(Qt3DRender::QBuffer::StaticCopy);
indexBuffer->setData(QByteArrayLiteral("For displacement"));
indexBuffer->setDataGenerator(Qt3DRender::QBufferDataGeneratorPtr(new TestFunctor(1340)));
@@ -125,28 +125,16 @@ private Q_SLOTS:
{
// GIVEN
TestArbiter arbiter;
- QScopedPointer<Qt3DRender::QBuffer> buffer(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer));
+ QScopedPointer<Qt3DRender::QBuffer> buffer(new Qt3DRender::QBuffer);
arbiter.setArbiterOnNode(buffer.data());
// WHEN
- buffer->setType(Qt3DRender::QBuffer::IndexBuffer);
- QCoreApplication::processEvents();
-
- // THEN
- QCOMPARE(arbiter.events.size(), 1);
- Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
- QCOMPARE(change->propertyName(), "type");
- QCOMPARE(change->value().value<int>(), static_cast<int>(Qt3DRender::QBuffer::IndexBuffer));
-
- arbiter.events.clear();
-
- // WHEN
buffer->setUsage(Qt3DRender::QBuffer::DynamicCopy);
QCoreApplication::processEvents();
// THEN
QCOMPARE(arbiter.events.size(), 1);
- change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->propertyName(), "usage");
QCOMPARE(change->value().value<int>(), static_cast<int>(Qt3DRender::QBuffer::DynamicCopy));
diff --git a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
index 94609c129..cc07120a2 100644
--- a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
+++ b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
@@ -52,6 +52,7 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupX(), 1);
QCOMPARE(computeCommand.workGroupY(), 1);
QCOMPARE(computeCommand.workGroupZ(), 1);
+ QCOMPARE(computeCommand.runType(), Qt3DRender::QComputeCommand::Continuous);
}
void checkPropertyChanges()
@@ -116,6 +117,25 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupZ(), newValue);
QCOMPARE(spy.count(), 0);
}
+ {
+ // WHEN
+ QSignalSpy spy(&computeCommand, SIGNAL(runTypeChanged()));
+ const Qt3DRender::QComputeCommand::RunType newValue = Qt3DRender::QComputeCommand::Manual;
+ computeCommand.setRunType(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(computeCommand.runType(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ computeCommand.setRunType(newValue);
+
+ // THEN
+ QCOMPARE(computeCommand.runType(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
}
void checkCreationData()
@@ -126,6 +146,7 @@ private Q_SLOTS:
computeCommand.setWorkGroupX(128);
computeCommand.setWorkGroupY(512);
computeCommand.setWorkGroupZ(1024);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
// WHEN
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
@@ -145,6 +166,8 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupX(), cloneData.workGroupX);
QCOMPARE(computeCommand.workGroupY(), cloneData.workGroupY);
QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
+ QCOMPARE(computeCommand.runType(), cloneData.runType);
+ QCOMPARE(0, cloneData.frameCount);
QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
QCOMPARE(computeCommand.isEnabled(), true);
QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
@@ -171,6 +194,8 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
QCOMPARE(computeCommand.isEnabled(), false);
+ QCOMPARE(computeCommand.runType(), cloneData.runType);
+ QCOMPARE(0, cloneData.frameCount);
QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
QCOMPARE(computeCommand.metaObject(), creationChangeData->metaObject());
}
@@ -275,6 +300,144 @@ private Q_SLOTS:
}
+ void checkRunTypeUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+
+ {
+ // WHEN
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "runType");
+ QCOMPARE(change->value().value<int>(), int(computeCommand.runType()));
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkTrigger()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+
+ {
+ // WHEN
+ computeCommand.trigger(1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 2);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.trigger(2);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 2);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 2);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.trigger(10, 11, 12, 1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 5);
+ {
+ auto change = arbiter.events.at(0).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupX");
+ QCOMPARE(change->value().value<int>(), 10);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(1).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupY");
+ QCOMPARE(change->value().value<int>(), 11);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(2).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupZ");
+ QCOMPARE(change->value().value<int>(), 12);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(3).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+ }
+
};
QTEST_MAIN(tst_QComputeCommand)
diff --git a/tests/auto/render/qgeometry/tst_qgeometry.cpp b/tests/auto/render/qgeometry/tst_qgeometry.cpp
index b9271a8c0..55b7e752c 100644
--- a/tests/auto/render/qgeometry/tst_qgeometry.cpp
+++ b/tests/auto/render/qgeometry/tst_qgeometry.cpp
@@ -39,9 +39,21 @@
#include <Qt3DCore/QPropertyUpdatedChange>
#include <Qt3DCore/QPropertyNodeAddedChange>
#include <Qt3DCore/QPropertyNodeRemovedChange>
+#include <QSignalSpy>
#include "testpostmanarbiter.h"
+class FakeGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+
+public:
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override
+ {
+ Qt3DRender::QGeometry::sceneChangeEvent(change);
+ }
+};
+
class tst_QGeometry: public QObject
{
Q_OBJECT
@@ -180,6 +192,49 @@ private Q_SLOTS:
// THEN Should not crash when the attribute is destroyed (tests for failed removal of destruction helper)
}
}
+
+ void checkExtentUpdates()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ QScopedPointer<FakeGeometry> geometry(new FakeGeometry());
+ arbiter.setArbiterOnNode(geometry.data());
+ QSignalSpy spyMinExtent(geometry.data(), SIGNAL(minExtentChanged(QVector3D)));
+ QSignalSpy spyMaxExtent(geometry.data(), SIGNAL(maxExtentChanged(QVector3D)));
+
+ // THEN
+ QVERIFY(spyMinExtent.isValid());
+ QVERIFY(spyMaxExtent.isValid());
+ QCOMPARE(geometry->minExtent(), QVector3D());
+ QCOMPARE(geometry->maxExtent(), QVector3D());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("extent");
+ valueChange->setValue(QVariant::fromValue(QPair<QVector3D, QVector3D>(QVector3D(10.0f, 10.f, 10.0f),
+ QVector3D())));
+ geometry->sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spyMinExtent.count(), 1);
+ QCOMPARE(spyMaxExtent.count(), 0);
+ QCOMPARE(geometry->minExtent(), QVector3D(10.0f, 10.0f, 10.0f));
+
+ spyMinExtent.clear();
+
+ // WHEN
+ valueChange->setPropertyName("extent");
+ valueChange->setValue(QVariant::fromValue(QPair<QVector3D, QVector3D>(QVector3D(10.0f, 10.f, 10.0f),
+ QVector3D(11.0f, 11.f, 11.0f))));
+ geometry->sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spyMinExtent.count(), 0);
+ QCOMPARE(spyMaxExtent.count(), 1);
+ QCOMPARE(geometry->maxExtent(), QVector3D(11.0f, 11.0f, 11.0f));
+
+ spyMaxExtent.clear();
+ }
};
QTEST_MAIN(tst_QGeometry)
diff --git a/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp b/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
index 6714d8a06..bd486774c 100644
--- a/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
+++ b/tests/auto/render/qobjectpicker/tst_qobjectpicker.cpp
@@ -31,8 +31,10 @@
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DRender/QObjectPicker>
+#include <Qt3DRender/private/qobjectpicker_p.h>
#include <Qt3DRender/QPickEvent>
-
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
#include "testpostmanarbiter.h"
class MyObjectPicker : public Qt3DRender::QObjectPicker
@@ -71,6 +73,162 @@ public:
private Q_SLOTS:
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::QObjectPicker picker;
+
+ // THEN
+ QCOMPARE(picker.priority(), 0);
+ QCOMPARE(picker.isDragEnabled(), false);
+ QCOMPARE(picker.isHoverEnabled(), false);
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QObjectPicker picker;
+
+ picker.setPriority(1584);
+ picker.setDragEnabled(true);
+ picker.setHoverEnabled(true);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&picker);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QObjectPickerData>>(creationChanges.first());
+ const Qt3DRender::QObjectPickerData cloneData = creationChangeData->data;
+
+ QCOMPARE(cloneData.priority, 1584);
+ QCOMPARE(cloneData.hoverEnabled, true);
+ QCOMPARE(cloneData.dragEnabled, true);
+ QCOMPARE(picker.id(), creationChangeData->subjectId());
+ QCOMPARE(picker.isEnabled(), true);
+ QCOMPARE(picker.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(picker.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ picker.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&picker);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QObjectPickerData>>(creationChanges.first());
+ const Qt3DRender::QObjectPickerData cloneData = creationChangeData->data;
+
+ QCOMPARE(cloneData.priority, 1584);
+ QCOMPARE(cloneData.hoverEnabled, true);
+ QCOMPARE(cloneData.dragEnabled, true);
+ QCOMPARE(picker.id(), creationChangeData->subjectId());
+ QCOMPARE(picker.isEnabled(), false);
+ QCOMPARE(picker.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(picker.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkPropertyUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QObjectPicker picker;
+ arbiter.setArbiterOnNode(&picker);
+
+ {
+ {
+ // WHEN
+ picker.setPriority(883);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ QCOMPARE(picker.priority(), 883);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "priority");
+ QCOMPARE(change->value().value<int>(), picker.priority());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ picker.setPriority(883);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+ {
+ {
+ // WHEN
+ picker.setDragEnabled(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ QCOMPARE(picker.isDragEnabled(), true);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "dragEnabled");
+ QCOMPARE(change->value().value<bool>(), picker.isDragEnabled());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ picker.setDragEnabled(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+ {
+ {
+ // WHEN
+ picker.setHoverEnabled(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ QCOMPARE(picker.isHoverEnabled(), true);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "hoverEnabled");
+ QCOMPARE(change->value().value<bool>(), picker.isHoverEnabled());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ picker.setHoverEnabled(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+ }
+
void checkCloning_data()
{
QTest::addColumn<Qt3DRender::QObjectPicker *>("objectPicker");
diff --git a/tests/auto/render/qsetfence/qsetfence.pro b/tests/auto/render/qsetfence/qsetfence.pro
new file mode 100644
index 000000000..4e70559c9
--- /dev/null
+++ b/tests/auto/render/qsetfence/qsetfence.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qsetfence
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qsetfence.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qsetfence/tst_qsetfence.cpp b/tests/auto/render/qsetfence/tst_qsetfence.cpp
new file mode 100644
index 000000000..c602e6f5c
--- /dev/null
+++ b/tests/auto/render/qsetfence/tst_qsetfence.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qsetfence.h>
+#include <Qt3DRender/private/qsetfence_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include "testpostmanarbiter.h"
+
+class MySetFence : public Qt3DRender::QSetFence
+{
+public:
+ using Qt3DRender::QSetFence::sceneChangeEvent;
+};
+
+class tst_QSetFence : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DRender::QSetFence::HandleType>("HandleType");
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QSetFence setFence;
+
+ // THEN
+ QCOMPARE(setFence.handleType(), Qt3DRender::QSetFence::NoHandle);
+ QCOMPARE(setFence.handle(), QVariant());
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DCore::QScene scene;
+ MySetFence setFence;
+
+ Qt3DCore::QNodePrivate::get(&setFence)->setScene(&scene);
+
+ {
+ // WHEN
+ QSignalSpy spy(&setFence, SIGNAL(handleTypeChanged(HandleType)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // THEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("handleType");
+ valueChange->setValue(QVariant::fromValue(Qt3DRender::QSetFence::OpenGLFenceId));
+ setFence.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(setFence.handleType(), Qt3DRender::QSetFence::OpenGLFenceId);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ setFence.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
+ QSignalSpy spy(&setFence, SIGNAL(handleChanged(QVariant)));
+
+ // THEN
+ QVERIFY(spy.isValid());
+
+ // WHEN
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("handle");
+ valueChange->setValue(QVariant(984));
+ setFence.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(setFence.handle(),QVariant(984));
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ setFence.sceneChangeEvent(valueChange);
+
+ // THEN
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QSetFence setFence;
+
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&setFence);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QSetFenceData>>(creationChanges.first());
+ const Qt3DRender::QSetFenceData cloneData = creationChangeData->data;
+
+ QCOMPARE(setFence.id(), creationChangeData->subjectId());
+ QCOMPARE(setFence.isEnabled(), true);
+ QCOMPARE(setFence.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(setFence.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ setFence.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&setFence);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QSetFenceData>>(creationChanges.first());
+ const Qt3DRender::QSetFenceData cloneData = creationChangeData->data;
+
+ QCOMPARE(setFence.id(), creationChangeData->subjectId());
+ QCOMPARE(setFence.isEnabled(), false);
+ QCOMPARE(setFence.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(setFence.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+};
+
+QTEST_MAIN(tst_QSetFence)
+
+#include "tst_qsetfence.moc"
diff --git a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
index 93bee22cc..021a3d6c1 100644
--- a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
+++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
@@ -38,12 +38,12 @@
#include <Qt3DCore/qnodecreatedchange.h>
#include "testpostmanarbiter.h"
-class tst_QShaderProgramBuilder : public QObject
+class tst_QShaderProgramBuilder : public Qt3DRender::QShaderProgramBuilder
{
Q_OBJECT
public:
tst_QShaderProgramBuilder()
- : QObject()
+ : Qt3DRender::QShaderProgramBuilder()
{
qRegisterMetaType<Qt3DRender::QShaderProgram*>("Qt3DRender::QShaderProgram*");
}
@@ -63,6 +63,12 @@ private Q_SLOTS:
QCOMPARE(builder.geometryShaderGraph(), QUrl());
QCOMPARE(builder.fragmentShaderGraph(), QUrl());
QCOMPARE(builder.computeShaderGraph(), QUrl());
+ QCOMPARE(builder.vertexShaderCode(), QByteArray());
+ QCOMPARE(builder.fragmentShaderCode(), QByteArray());
+ QCOMPARE(builder.computeShaderCode(), QByteArray());
+ QCOMPARE(builder.geometryShaderCode(), QByteArray());
+ QCOMPARE(builder.tessellationEvaluationShaderCode(), QByteArray());
+ QCOMPARE(builder.tessellationControlShaderCode(), QByteArray());
}
void checkPropertyChanges()
@@ -592,8 +598,90 @@ private Q_SLOTS:
// THEN
QCOMPARE(arbiter.events.size(), 0);
}
+ }
+
+ void checkGeneratedCodePropertyUpdates()
+ {
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(vertexShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Vertex), QByteArrayLiteral("vertex"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(vertexShaderCode(), QByteArrayLiteral("vertex"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(fragmentShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Fragment), QByteArrayLiteral("fragment"))));
+ sceneChangeEvent(valueChange);
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(fragmentShaderCode(), QByteArrayLiteral("fragment"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(geometryShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Geometry), QByteArrayLiteral("geometry"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(geometryShaderCode(), QByteArrayLiteral("geometry"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(computeShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::Compute), QByteArrayLiteral("compute"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(computeShaderCode(), QByteArrayLiteral("compute"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(tessellationControlShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationControl), QByteArrayLiteral("control"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(tessellationControlShaderCode(), QByteArrayLiteral("control"));
+ }
+ {
+ // WHEN
+ QSignalSpy spy(this, SIGNAL(tessellationEvaluationShaderCodeChanged(QByteArray)));
+ Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange->setPropertyName("generatedShaderCode");
+ valueChange->setValue(QVariant::fromValue(QPair<int, QByteArray>(int(Qt3DRender::QShaderProgram::TessellationEvaluation), QByteArrayLiteral("eval"))));
+ sceneChangeEvent(valueChange);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(tessellationEvaluationShaderCode(), QByteArrayLiteral("eval"));
+ }
}
+
};
QTEST_MAIN(tst_QShaderProgramBuilder)
diff --git a/tests/auto/render/qsharedgltexture/qsharedgltexture.pro b/tests/auto/render/qsharedgltexture/qsharedgltexture.pro
new file mode 100644
index 000000000..a5c76aa7d
--- /dev/null
+++ b/tests/auto/render/qsharedgltexture/qsharedgltexture.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qsharedgltexture
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qsharedgltexture.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qsharedgltexture/tst_qsharedgltexture.cpp b/tests/auto/render/qsharedgltexture/tst_qsharedgltexture.cpp
new file mode 100644
index 000000000..1a1db60e4
--- /dev/null
+++ b/tests/auto/render/qsharedgltexture/tst_qsharedgltexture.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <QtTest/QTest>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/private/qtexture_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QSharedGLTexture : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QSharedGLTexture glTexture;
+
+ // THEN
+ QCOMPARE(glTexture.textureId(), -1);
+ QCOMPARE(glTexture.target(), Qt3DRender::QAbstractTexture::TargetAutomatic);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QSharedGLTexture glTexture;
+
+ {
+ // WHEN
+ QSignalSpy spy(&glTexture, SIGNAL(textureIdChanged(int)));
+ const int newValue = 883;
+ glTexture.setTextureId(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(glTexture.textureId(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ glTexture.setTextureId(newValue);
+
+ // THEN
+ QCOMPARE(glTexture.textureId(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QSharedGLTexture glTexture;
+
+ glTexture.setTextureId(1200);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&glTexture);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QAbstractTextureData>>(creationChanges.first());
+ const Qt3DRender::QAbstractTextureData cloneData = creationChangeData->data;
+
+ QCOMPARE(glTexture.id(), creationChangeData->subjectId());
+ QCOMPARE(glTexture.isEnabled(), true);
+ QCOMPARE(glTexture.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(glTexture.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(cloneData.sharedTextureId, 1200);
+ }
+
+ // WHEN
+ glTexture.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&glTexture);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QAbstractTextureData>>(creationChanges.first());
+ const Qt3DRender::QAbstractTextureData cloneData = creationChangeData->data;
+
+ QCOMPARE(glTexture.id(), creationChangeData->subjectId());
+ QCOMPARE(glTexture.isEnabled(), false);
+ QCOMPARE(glTexture.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(glTexture.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(cloneData.sharedTextureId, 1200);
+ }
+ }
+
+ void checkTextureIdUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QSharedGLTexture glTexture;
+ arbiter.setArbiterOnNode(&glTexture);
+
+ {
+ // WHEN
+ glTexture.setTextureId(1584);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ const auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "textureId");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().toInt(), 1584);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ glTexture.setTextureId(1584);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+};
+
+QTEST_MAIN(tst_QSharedGLTexture)
+
+#include "tst_qsharedgltexture.moc"
diff --git a/tests/auto/render/qwaitfence/qwaitfence.pro b/tests/auto/render/qwaitfence/qwaitfence.pro
new file mode 100644
index 000000000..18ac21088
--- /dev/null
+++ b/tests/auto/render/qwaitfence/qwaitfence.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qwaitfence
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qwaitfence.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qwaitfence/tst_qwaitfence.cpp b/tests/auto/render/qwaitfence/tst_qwaitfence.cpp
new file mode 100644
index 000000000..ab3ae9b4d
--- /dev/null
+++ b/tests/auto/render/qwaitfence/tst_qwaitfence.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qwaitfence.h>
+#include <Qt3DRender/private/qwaitfence_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QWaitFence : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DRender::QWaitFence::HandleType>("HandleType");
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QWaitFence waitFence;
+
+ // THEN
+ QCOMPARE(waitFence.handleType(), Qt3DRender::QWaitFence::NoHandle);
+ QCOMPARE(waitFence.handle(), QVariant());
+ QCOMPARE(waitFence.waitOnCPU(), false);
+ QCOMPARE(waitFence.timeout(), quint64(-1));
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QWaitFence waitFence;
+
+ {
+ // WHEN
+ QSignalSpy spy(&waitFence, SIGNAL(handleTypeChanged(HandleType)));
+ const Qt3DRender::QWaitFence::HandleType newValue = Qt3DRender::QWaitFence::OpenGLFenceId;
+ waitFence.setHandleType(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(waitFence.handleType(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ waitFence.setHandleType(newValue);
+
+ // THEN
+ QCOMPARE(waitFence.handleType(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&waitFence, SIGNAL(handleChanged(QVariant)));
+ const QVariant newValue(883);
+ waitFence.setHandle(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(waitFence.handle(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ waitFence.setHandle(newValue);
+
+ // THEN
+ QCOMPARE(waitFence.handle(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&waitFence, SIGNAL(waitOnCPUChanged(bool)));
+ const bool newValue = true;
+ waitFence.setWaitOnCPU(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(waitFence.waitOnCPU(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ waitFence.setWaitOnCPU(newValue);
+
+ // THEN
+ QCOMPARE(waitFence.waitOnCPU(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&waitFence, SIGNAL(timeoutChanged(quint64)));
+ const quint64 newValue = 984;
+ waitFence.setTimeout(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(waitFence.timeout(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ waitFence.setTimeout(newValue);
+
+ // THEN
+ QCOMPARE(waitFence.timeout(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QWaitFence waitFence;
+
+ waitFence.setHandleType(Qt3DRender::QWaitFence::OpenGLFenceId);
+ waitFence.setHandle(QVariant(1200));
+ waitFence.setWaitOnCPU(true);
+ waitFence.setTimeout(1584);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&waitFence);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QWaitFenceData>>(creationChanges.first());
+ const Qt3DRender::QWaitFenceData cloneData = creationChangeData->data;
+
+ QCOMPARE(waitFence.handleType(), cloneData.handleType);
+ QCOMPARE(waitFence.handle(), cloneData.handle);
+ QCOMPARE(waitFence.waitOnCPU(), cloneData.waitOnCPU);
+ QCOMPARE(waitFence.timeout(), cloneData.timeout);
+ QCOMPARE(waitFence.id(), creationChangeData->subjectId());
+ QCOMPARE(waitFence.isEnabled(), true);
+ QCOMPARE(waitFence.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(waitFence.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ waitFence.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&waitFence);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QWaitFenceData>>(creationChanges.first());
+ const Qt3DRender::QWaitFenceData cloneData = creationChangeData->data;
+
+ QCOMPARE(waitFence.handleType(), cloneData.handleType);
+ QCOMPARE(waitFence.handle(), cloneData.handle);
+ QCOMPARE(waitFence.waitOnCPU(), cloneData.waitOnCPU);
+ QCOMPARE(waitFence.timeout(), cloneData.timeout);
+ QCOMPARE(waitFence.id(), creationChangeData->subjectId());
+ QCOMPARE(waitFence.isEnabled(), false);
+ QCOMPARE(waitFence.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(waitFence.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkHandleTypeUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QWaitFence waitFence;
+ arbiter.setArbiterOnNode(&waitFence);
+
+ {
+ // WHEN
+ waitFence.setHandleType(Qt3DRender::QWaitFence::OpenGLFenceId);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "handleType");
+ QCOMPARE(change->value().value<Qt3DRender::QWaitFence::HandleType>(), waitFence.handleType());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ waitFence.setHandleType(Qt3DRender::QWaitFence::OpenGLFenceId);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkHandleUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QWaitFence waitFence;
+ arbiter.setArbiterOnNode(&waitFence);
+
+ {
+ // WHEN
+ waitFence.setHandle(QVariant(883));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "handle");
+ QCOMPARE(change->value().value<QVariant>(), waitFence.handle());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ waitFence.setHandle(QVariant(883));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkWaitOnCPUUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QWaitFence waitFence;
+ arbiter.setArbiterOnNode(&waitFence);
+
+ {
+ // WHEN
+ waitFence.setWaitOnCPU(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "waitOnCPU");
+ QCOMPARE(change->value().value<bool>(), waitFence.waitOnCPU());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ waitFence.setWaitOnCPU(true);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkTimeoutUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QWaitFence waitFence;
+ arbiter.setArbiterOnNode(&waitFence);
+
+ {
+ // WHEN
+ waitFence.setTimeout(quint64(600));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "timeout");
+ QCOMPARE(change->value().value<quint64>(), waitFence.timeout());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ waitFence.setTimeout(quint64(600));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+};
+
+QTEST_MAIN(tst_QWaitFence)
+
+#include "tst_qwaitfence.moc"
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 2fa8538f9..edf6fa101 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -59,6 +59,7 @@ qtConfig(private_tests) {
qparameter \
parameter \
qtextureloader \
+ qsharedgltexture \
qtextureimage \
qabstracttexture \
qabstracttextureimage \
@@ -98,7 +99,11 @@ qtConfig(private_tests) {
raycaster \
qscreenraycaster \
raycastingjob \
- qcamera
+ qcamera \
+ qsetfence \
+ qwaitfence \
+ setfence \
+ waitfence
QT_FOR_CONFIG = 3dcore-private
# TO DO: These could be restored to be executed in all cases
@@ -153,5 +158,5 @@ qtConfig(qt3d-opengl-renderer):qtConfig(private_tests) {
!macos: SUBDIRS += graphicshelpergl4
qtConfig(qt3d-simd-avx2): SUBDIRS += alignedresourcesmanagers-avx
- qtConfig(qt3d-simd-sse2): SUBDIRS += alignedresourcesmanagers-sse
+ qtConfig(qt3d-simd-sse2):!qtConfig(qt3d-simd-avx2): SUBDIRS += alignedresourcesmanagers-sse
}
diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp
index 892e13b25..2fc76c792 100644
--- a/tests/auto/render/renderer/tst_renderer.cpp
+++ b/tests/auto/render/renderer/tst_renderer.cpp
@@ -45,6 +45,88 @@ public :
~tst_Renderer() {}
private Q_SLOTS:
+
+ void checkPreRenderBinJobs()
+ {
+ // GIVEN
+ Qt3DRender::Render::NodeManagers nodeManagers;
+ Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+ Qt3DRender::Render::OffscreenSurfaceHelper offscreenHelper(&renderer);
+ Qt3DRender::Render::RenderSettings settings;
+ // owned by FG manager
+ Qt3DRender::Render::ViewportNode *fgRoot = new Qt3DRender::Render::ViewportNode();
+ const Qt3DCore::QNodeId fgRootId = Qt3DCore::QNodeId::createId();
+
+ nodeManagers.frameGraphManager()->appendNode(fgRootId, fgRoot);
+ settings.setActiveFrameGraphId(fgRootId);
+
+ renderer.setNodeManagers(&nodeManagers);
+ renderer.setSettings(&settings);
+ renderer.setOffscreenSurfaceHelper(&offscreenHelper);
+ renderer.initialize();
+
+ // Ensure invoke calls are performed
+ QCoreApplication::processEvents();
+
+ // WHEN (nothing dirty, no buffers, no layers to be rebuilt, no materials to be rebuilt)
+ QVector<Qt3DCore::QAspectJobPtr> jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1); // RayCastingJob
+
+ // WHEN
+ renderer.addRenderCaptureSendRequest(Qt3DCore::QNodeId::createId());
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1); // SendRenderCaptureJob
+
+ // WHEN
+ renderer.m_sendBufferCaptureJob->addRequest({nullptr, {}});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1); // SendBufferCaptureJob
+ // Note: pending render buffer captures are only cleared when the job is run
+
+ // WHEN
+ renderer.m_updatedSetFences.push_back({Qt3DCore::QNodeId(), nullptr});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1 + // SendBufferCaptureJob
+ 1); // SendSetFenceHandlesJob
+ // Note: pending set fence handles are only cleared when the job is run
+
+ // WHEN
+ renderer.m_updatedTextureProperties.push_back({{}, {}});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1 + // SendBufferCaptureJob
+ 1 + // SendSetFenceHandlesJob
+ 1); // SendTextureChangesToFrontend
+
+ // Note: pending texture changes are only cleared when the job is run
+
+ // Properly shutdown command thread
+ renderer.shutdown();
+ }
+
void checkRenderBinJobs()
{
// GIVEN
@@ -95,7 +177,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset
@@ -104,23 +185,6 @@ private Q_SLOTS:
renderQueue->reset();
// WHEN
- renderer.addRenderCaptureSendRequest(Qt3DCore::QNodeId::createId());
- jobs = renderer.renderBinJobs();
-
- // THEN
- QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendBufferCaptureJob
- 1 + // sendRenderCaptureJob
- 1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- singleRenderViewJobCount);
-
- renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
- renderQueue->reset();
-
- // WHEN
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, nullptr);
jobs = renderer.renderBinJobs();
@@ -128,7 +192,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
1 + // EntityEnabledDirty
@@ -146,7 +209,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // WorldTransformJob
1 + // UpdateWorldBoundingVolume
@@ -168,7 +230,6 @@ private Q_SLOTS:
1 + // cleanupJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
- 1 + // sendBufferCaptureJob
singleRenderViewJobCount +
renderViewBuilderMaterialCacheJobCount);
@@ -183,7 +244,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // CalculateBoundingVolumeJob
1 + // UpdateMeshTriangleListJob
@@ -204,7 +264,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
1 + // CalculateBoundingVolumeJob
@@ -223,7 +282,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // TexturesGathererJob
1 + // updateSkinningPaletteJob
@@ -241,7 +299,6 @@ private Q_SLOTS:
1 + // updateLevelOfDetailJob
1 + // cleanupJob
1 + // VAOGatherer
- 1 + // sendBufferCaptureJob
1 + // updateSkinningPaletteJob
singleRenderViewJobCount +
layerCacheJobCount +
@@ -262,7 +319,6 @@ private Q_SLOTS:
1 + // UpdateWorldBoundingVolume
1 + // UpdateShaderDataTransform
1 + // ExpandBoundingVolumeJob
- 1 + // CalculateBoundingVolumeJob
1 + // UpdateEntityLayersJob
1 + // updateLevelOfDetailJob
1 + // updateSkinningPaletteJob
@@ -292,7 +348,6 @@ private Q_SLOTS:
1 + // updateSkinningPaletteJob
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // BufferGathererJob
1 + // TexturesGathererJob
diff --git a/tests/auto/render/setfence/setfence.pro b/tests/auto/render/setfence/setfence.pro
new file mode 100644
index 000000000..5e9793c36
--- /dev/null
+++ b/tests/auto/render/setfence/setfence.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_setfence
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_setfence.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/setfence/tst_setfence.cpp b/tests/auto/render/setfence/tst_setfence.cpp
new file mode 100644
index 000000000..82cee4b17
--- /dev/null
+++ b/tests/auto/render/setfence/tst_setfence.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qsetfence.h>
+#include <Qt3DRender/private/qsetfence_p.h>
+#include <Qt3DRender/private/setfence_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include "qbackendnodetester.h"
+#include "testrenderer.h"
+#include "testpostmanarbiter.h"
+
+class tst_SetFence : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::SetFence backendSetFence;
+
+ // THEN
+ QCOMPARE(backendSetFence.isEnabled(), false);
+ QVERIFY(backendSetFence.peerId().isNull());
+ QCOMPARE(backendSetFence.nodeType(), Qt3DRender::Render::FrameGraphNode::SetFence);
+ }
+
+ void checkInitializeFromPeer()
+ {
+ // GIVEN
+ Qt3DRender::QSetFence setFence;
+
+ {
+ // WHEN
+ Qt3DRender::Render::SetFence backendSetFence;
+ simulateInitialization(&setFence, &backendSetFence);
+
+ // THEN
+ QCOMPARE(backendSetFence.isEnabled(), true);
+ QCOMPARE(backendSetFence.peerId(), setFence.id());
+ }
+ {
+ // WHEN
+ Qt3DRender::Render::SetFence backendSetFence;
+ setFence.setEnabled(false);
+ simulateInitialization(&setFence, &backendSetFence);
+
+ // THEN
+ QCOMPARE(backendSetFence.peerId(), setFence.id());
+ QCOMPARE(backendSetFence.isEnabled(), false);
+ }
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ Qt3DRender::Render::SetFence backendSetFence;
+ TestRenderer renderer;
+ backendSetFence.setRenderer(&renderer);
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendSetFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendSetFence.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ }
+
+ void checkSetHandleType()
+ {
+ // GIVEN
+ Qt3DRender::Render::SetFence backendSetFence;
+ TestRenderer renderer;
+ TestArbiter arbiter;
+
+ Qt3DCore::QBackendNodePrivate::get(&backendSetFence)->setArbiter(&arbiter);
+ backendSetFence.setRenderer(&renderer);
+
+ // WHEN
+ backendSetFence.setHandleType(Qt3DRender::QSetFence::OpenGLFenceId);
+
+ // THEN
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(arbiter.events.count(), 1);
+ QCOMPARE(change->propertyName(), "handleType");
+ QCOMPARE(change->value().value<Qt3DRender::QSetFence::HandleType>(), Qt3DRender::QSetFence::OpenGLFenceId);
+
+ arbiter.events.clear();
+ }
+
+ void checkSetHandle()
+ {
+ // GIVEN
+ Qt3DRender::Render::SetFence backendSetFence;
+ TestRenderer renderer;
+ TestArbiter arbiter;
+
+ Qt3DCore::QBackendNodePrivate::get(&backendSetFence)->setArbiter(&arbiter);
+ backendSetFence.setRenderer(&renderer);
+
+ // WHEN
+ backendSetFence.setHandle(QVariant(984));
+
+ // THEN
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(arbiter.events.count(), 1);
+ QCOMPARE(change->propertyName(), "handle");
+ QCOMPARE(change->value(), QVariant(984));
+
+ arbiter.events.clear();
+ }
+};
+
+QTEST_MAIN(tst_SetFence)
+
+#include "tst_setfence.moc"
diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
index 71b42cc09..e365256cc 100644
--- a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
+++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
@@ -28,12 +28,15 @@
#include <QtTest/QTest>
#include <qbackendnodetester.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DRender/private/shaderbuilder_p.h>
#include <Qt3DRender/qshaderprogram.h>
#include <Qt3DRender/qshaderprogrambuilder.h>
#include "testrenderer.h"
+#include "testpostmanarbiter.h"
Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderBuilder::ShaderType)
+Q_DECLARE_METATYPE(Qt3DRender::QShaderProgram::ShaderType)
class tst_ShaderBuilder : public Qt3DCore::QBackendNodeTester
{
@@ -541,6 +544,82 @@ private slots:
QVERIFY(!backend.isShaderCodeDirty(type));
QCOMPARE(backend.shaderCode(type), es2Code);
}
+
+ void checkCodeUpdatedNotification_data()
+ {
+ QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type");
+ QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("notificationType");
+
+ QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex << Qt3DRender::QShaderProgram::Vertex;
+ QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl << Qt3DRender::QShaderProgram::TessellationControl;
+ QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation << Qt3DRender::QShaderProgram::TessellationEvaluation;
+ QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry << Qt3DRender::QShaderProgram::Geometry;
+ QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment << Qt3DRender::QShaderProgram::Fragment;
+ QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute << Qt3DRender::QShaderProgram::Compute;
+ }
+
+
+ void checkCodeUpdatedNotification()
+ {
+ // GIVEN
+ QSKIP("Disabled for Qt Base QShaderGenerator Integration");
+
+ Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json");
+ QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty());
+ QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type);
+ QFETCH(Qt3DRender::QShaderProgram::ShaderType, notificationType);
+
+ const auto gl3Api = []{
+ auto api = Qt3DRender::GraphicsApiFilterData();
+ api.m_api = Qt3DRender::QGraphicsApiFilter::OpenGL;
+ api.m_profile = Qt3DRender::QGraphicsApiFilter::CoreProfile;
+ api.m_major = 3;
+ api.m_minor = 2;
+ return api;
+ }();
+
+ const auto readCode = [](const QString &suffix) -> QString {
+ const auto filePath = QStringLiteral(":/output.") + suffix;
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly | QFile::Text))
+ qFatal("File open failed: %s", qPrintable(filePath));
+ return file.readAll();
+ };
+
+ const auto gl3Code = readCode("gl3");
+
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestArbiter arbiter;
+ Qt3DCore::QBackendNodePrivate::get(&backend)->setArbiter(&arbiter);
+
+
+ // WHEN
+ const auto graphUrl = QUrl::fromEncoded("qrc:/input.json");
+ backend.setShaderGraph(type, graphUrl);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+
+ // WHEN
+ backend.setGraphicsApi(gl3Api);
+ backend.generateCode(type);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ QCOMPARE(backend.shaderCode(type), gl3Code);
+
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(arbiter.events.count(), 1);
+ QCOMPARE(change->propertyName(), "generatedShaderCode");
+ const QPair<int, QByteArray> value = change->value().value<QPair<int, QByteArray>>();
+ QCOMPARE(value.first, int(notificationType));
+ QCOMPARE(value.second, gl3Code);
+
+ arbiter.events.clear();
+ }
};
QTEST_MAIN(tst_ShaderBuilder)
diff --git a/tests/auto/render/texture/tst_texture.cpp b/tests/auto/render/texture/tst_texture.cpp
index d64533732..b0ce782a0 100644
--- a/tests/auto/render/texture/tst_texture.cpp
+++ b/tests/auto/render/texture/tst_texture.cpp
@@ -506,6 +506,19 @@ void tst_RenderTexture::checkPropertyChanges()
backend.unsetDirty();
// WHEN
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
+ updateChange->setValue(883);
+ updateChange->setPropertyName("textureId");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.sharedTextureId(), 883);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ QVERIFY(backend.dirtyFlags() == Qt3DRender::Render::Texture::DirtySharedTextureId);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ backend.unsetDirty();
+
+ // WHEN
Qt3DRender::QTextureImage img;
const auto imageAddChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &img);
imageAddChange->setPropertyName("textureImage");
diff --git a/tests/auto/render/textures/tst_textures.cpp b/tests/auto/render/textures/tst_textures.cpp
index 8bd4b355c..390853e77 100644
--- a/tests/auto/render/textures/tst_textures.cpp
+++ b/tests/auto/render/textures/tst_textures.cpp
@@ -112,6 +112,24 @@ private:
Q_DECLARE_PRIVATE(TestTexture)
};
+class TestSharedGLTexturePrivate : public Qt3DRender::QAbstractTexturePrivate
+{
+};
+
+class TestSharedGLTexture : public Qt3DRender::QAbstractTexture
+{
+public:
+ TestSharedGLTexture(int textureId, Qt3DCore::QNode *p = nullptr)
+ : QAbstractTexture(*new TestSharedGLTexturePrivate(), p)
+ {
+ d_func()->m_sharedTextureId = textureId;
+ }
+
+private:
+ Q_DECLARE_PRIVATE(TestSharedGLTexture)
+};
+
+
/**
* @brief Test QTextureImage
*/
@@ -163,6 +181,11 @@ class tst_RenderTextures : public Qt3DCore::QBackendNodeTester
return tex;
}
+ Qt3DRender::QAbstractTexture *createQTextureWithTextureId(int textureId)
+ {
+ return new TestSharedGLTexture(textureId);
+ }
+
Qt3DRender::Render::Texture *createBackendTexture(Qt3DRender::QAbstractTexture *frontend,
Qt3DRender::Render::TextureManager *texMgr,
Qt3DRender::Render::TextureImageManager *texImgMgr,
@@ -270,6 +293,77 @@ private Q_SLOTS:
renderer.shutdown();
}
+ void shouldCreateDifferentGLTexturesWhenUsingSharedTextureIds()
+ {
+ QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers());
+ Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+ renderer.setNodeManagers(mgrs.data());
+
+ // both texture having the same sharedTextureId
+ {
+ // GIVEN
+ Qt3DRender::QAbstractTexture *tex1a = createQTextureWithTextureId(1);
+ Qt3DRender::QAbstractTexture *tex1b = createQTextureWithTextureId(1);
+
+ // WHEN
+ Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a,
+ mgrs->textureManager(),
+ mgrs->textureImageManager(),
+ mgrs->textureImageDataManager());
+ Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b,
+ mgrs->textureManager(),
+ mgrs->textureImageManager(),
+ mgrs->textureImageDataManager());
+ // THEN
+ QCOMPARE(bt1->sharedTextureId(), 1);
+ QCOMPARE(bt2->sharedTextureId(), 1);
+
+ // WHEN
+ renderer.updateTexture(bt1);
+ renderer.updateTexture(bt2);
+
+ // THEN
+ Qt3DRender::Render::GLTexture *glt1 = mgrs->glTextureManager()->lookupResource(bt1->peerId());
+ Qt3DRender::Render::GLTexture *glt2 = mgrs->glTextureManager()->lookupResource(bt2->peerId());
+ QVERIFY(glt1 != glt2);
+ QCOMPARE(glt1->sharedTextureId(), bt1->sharedTextureId());
+ QCOMPARE(glt2->sharedTextureId(), bt2->sharedTextureId());
+ }
+
+ // textures having a different sharedTextureId
+ {
+ // GIVEN
+ Qt3DRender::QAbstractTexture *tex1a = createQTextureWithTextureId(1);
+ Qt3DRender::QAbstractTexture *tex1b = createQTextureWithTextureId(2);
+
+ // WHEN
+ Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a,
+ mgrs->textureManager(),
+ mgrs->textureImageManager(),
+ mgrs->textureImageDataManager());
+ Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b,
+ mgrs->textureManager(),
+ mgrs->textureImageManager(),
+ mgrs->textureImageDataManager());
+ // THEN
+ QCOMPARE(bt1->sharedTextureId(), 1);
+ QCOMPARE(bt2->sharedTextureId(), 2);
+
+ // WHEN
+ renderer.updateTexture(bt1);
+ renderer.updateTexture(bt2);
+
+ // THEN
+ Qt3DRender::Render::GLTexture *glt1 = mgrs->glTextureManager()->lookupResource(bt1->peerId());
+ Qt3DRender::Render::GLTexture *glt2 = mgrs->glTextureManager()->lookupResource(bt2->peerId());
+ QVERIFY(glt1 != glt2);
+ QCOMPARE(glt1->sharedTextureId(), bt1->sharedTextureId());
+ QCOMPARE(glt2->sharedTextureId(), bt2->sharedTextureId());
+ }
+
+ renderer.shutdown();
+ }
+
void generatorsShouldCreateSameData()
{
QScopedPointer<Qt3DRender::Render::NodeManagers> mgrs(new Qt3DRender::Render::NodeManagers());
diff --git a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
index 2f6d283be..fa1cdd0de 100644
--- a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
+++ b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
@@ -53,8 +53,8 @@ Qt3DRender::QGeometryRenderer *customIndexedGeometryRenderer()
Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer;
Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer);
- Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);
- Qt3DRender::QBuffer *indexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, customGeometry);
+ auto vertexDataBuffer = new Qt3DRender::QBuffer(customGeometry);
+ auto indexDataBuffer = new Qt3DRender::QBuffer(customGeometry);
// vec3 for position
// vec3 for colors
@@ -196,7 +196,7 @@ Qt3DRender::QGeometryRenderer *customNonIndexedGeometryRenderer()
Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer;
Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer);
- Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);
+ auto vertexDataBuffer = new Qt3DRender::QBuffer(customGeometry);
// vec3 for position
// vec3 for colors
diff --git a/tests/auto/render/waitfence/tst_waitfence.cpp b/tests/auto/render/waitfence/tst_waitfence.cpp
new file mode 100644
index 000000000..8141fbb1c
--- /dev/null
+++ b/tests/auto/render/waitfence/tst_waitfence.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:LGPL$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#include <QtTest/QTest>
+#include <Qt3DRender/qwaitfence.h>
+#include <Qt3DRender/private/qwaitfence_p.h>
+#include <Qt3DRender/private/waitfence_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include "qbackendnodetester.h"
+#include "testrenderer.h"
+
+class tst_WaitFence : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::WaitFence backendWaitFence;
+
+ // THEN
+ QCOMPARE(backendWaitFence.isEnabled(), false);
+ QVERIFY(backendWaitFence.peerId().isNull());
+ QCOMPARE(backendWaitFence.nodeType(), Qt3DRender::Render::FrameGraphNode::WaitFence);
+ QCOMPARE(backendWaitFence.data().handleType, Qt3DRender::QWaitFence::NoHandle);
+ QCOMPARE(backendWaitFence.data().handle, QVariant());
+ QCOMPARE(backendWaitFence.data().waitOnCPU, false);
+ QCOMPARE(backendWaitFence.data().timeout, quint64(-1));
+ }
+
+ void checkInitializeFromPeer()
+ {
+ // GIVEN
+ Qt3DRender::QWaitFence waitFence;
+ waitFence.setHandle(QVariant(883));
+ waitFence.setWaitOnCPU(true);
+ waitFence.setTimeout(8);
+ waitFence.setHandleType(Qt3DRender::QWaitFence::OpenGLFenceId);
+
+ {
+ // WHEN
+ Qt3DRender::Render::WaitFence backendWaitFence;
+ simulateInitialization(&waitFence, &backendWaitFence);
+
+ // THEN
+ QCOMPARE(backendWaitFence.isEnabled(), true);
+ QCOMPARE(backendWaitFence.peerId(), waitFence.id());
+ QCOMPARE(backendWaitFence.data().handleType, Qt3DRender::QWaitFence::OpenGLFenceId);
+ QCOMPARE(backendWaitFence.data().handle, QVariant(883));
+ QCOMPARE(backendWaitFence.data().waitOnCPU, true);
+ QCOMPARE(backendWaitFence.data().timeout, quint64(8));
+ }
+ {
+ // WHEN
+ Qt3DRender::Render::WaitFence backendWaitFence;
+ waitFence.setEnabled(false);
+ simulateInitialization(&waitFence, &backendWaitFence);
+
+ // THEN
+ QCOMPARE(backendWaitFence.peerId(), waitFence.id());
+ QCOMPARE(backendWaitFence.isEnabled(), false);
+ QCOMPARE(backendWaitFence.data().handleType, Qt3DRender::QWaitFence::OpenGLFenceId);
+ QCOMPARE(backendWaitFence.data().handle, QVariant(883));
+ QCOMPARE(backendWaitFence.data().waitOnCPU, true);
+ QCOMPARE(backendWaitFence.data().timeout, quint64(8));
+ }
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ Qt3DRender::Render::WaitFence backendWaitFence;
+ TestRenderer renderer;
+ backendWaitFence.setRenderer(&renderer);
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendWaitFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendWaitFence.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ {
+ // WHEN
+ const QVariant newValue(984);
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("handle");
+ change->setValue(QVariant::fromValue(newValue));
+ backendWaitFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendWaitFence.data().handle, QVariant(984));
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ {
+ // WHEN
+ const Qt3DRender::QWaitFence::HandleType newValue = Qt3DRender::QWaitFence::OpenGLFenceId;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("handleType");
+ change->setValue(QVariant::fromValue(newValue));
+ backendWaitFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendWaitFence.data().handleType, Qt3DRender::QWaitFence::OpenGLFenceId);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ {
+ // WHEN
+ const bool newValue = true;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("waitOnCPU");
+ change->setValue(QVariant::fromValue(newValue));
+ backendWaitFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendWaitFence.data().waitOnCPU, true);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ {
+ // WHEN
+ const quint64 newValue = 984;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("timeout");
+ change->setValue(QVariant::fromValue(newValue));
+ backendWaitFence.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendWaitFence.data().timeout, quint64(984));
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::FrameGraphDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+ }
+};
+
+QTEST_MAIN(tst_WaitFence)
+
+#include "tst_waitfence.moc"
diff --git a/tests/auto/render/waitfence/waitfence.pro b/tests/auto/render/waitfence/waitfence.pro
new file mode 100644
index 000000000..cb8f71272
--- /dev/null
+++ b/tests/auto/render/waitfence/waitfence.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_waitfence
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_waitfence.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 4900add69..6a1839561 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -63,6 +63,12 @@ SUBDIRS += \
texture_property_updates \
qtbug-72236
+qtHaveModule(multimedia): {
+ SUBDIRS += \
+ sharedtexture \
+ sharedtextureqml
+}
+
qtHaveModule(widgets): {
SUBDIRS += \
assimp-cpp \
diff --git a/tests/manual/sharedtexture/main.cpp b/tests/manual/sharedtexture/main.cpp
new file mode 100644
index 000000000..a85f90ee6
--- /dev/null
+++ b/tests/manual/sharedtexture/main.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QPropertyAnimation>
+
+#include <Qt3DCore/QEntity>
+#include <Qt3DCore/QTransform>
+#include <Qt3DCore/QAspectEngine>
+
+#include <Qt3DRender/QCamera>
+#include <Qt3DRender/QCameraLens>
+#include <Qt3DRender/QRenderAspect>
+#include <Qt3DRender/QTexture>
+#include <Qt3DRender/QDirectionalLight>
+
+#include <Qt3DInput/QInputAspect>
+
+#include <Qt3DExtras/QForwardRenderer>
+#include <Qt3DExtras/QDiffuseMapMaterial>
+#include <Qt3DExtras/QCuboidMesh>
+#include <Qt3DExtras/QOrbitCameraController>
+#include <Qt3DExtras/Qt3DWindow>
+
+#include "videoplayer.h"
+
+Qt3DCore::QEntity *createScene(Qt3DExtras::Qt3DWindow *view, Qt3DRender::QAbstractTexture *diffuseTexture)
+{
+ // Root entity
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
+
+ // Material
+ Qt3DExtras::QDiffuseMapMaterial *material = new Qt3DExtras::QDiffuseMapMaterial(rootEntity);
+ material->setDiffuse(diffuseTexture);
+ material->setAmbient(QColor(30, 30, 30));
+
+ // Sphere
+ Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(rootEntity);
+ Qt3DExtras::QCuboidMesh *cuboidMesh = new Qt3DExtras::QCuboidMesh;
+ Qt3DCore::QTransform *transform = new Qt3DCore::QTransform;
+
+ transform->setRotationX(180);
+
+ QPropertyAnimation *cubeRotateTransformAnimation = new QPropertyAnimation(transform);
+ cubeRotateTransformAnimation->setTargetObject(transform);
+ cubeRotateTransformAnimation->setPropertyName("rotationY");
+ cubeRotateTransformAnimation->setStartValue(QVariant::fromValue(0));
+ cubeRotateTransformAnimation->setEndValue(QVariant::fromValue(360));
+ cubeRotateTransformAnimation->setDuration(10000);
+ cubeRotateTransformAnimation->setLoopCount(-1);
+ cubeRotateTransformAnimation->start();
+
+ sphereEntity->addComponent(cuboidMesh);
+ sphereEntity->addComponent(transform);
+ sphereEntity->addComponent(material);
+
+ // Camera
+ Qt3DRender::QCamera *camera = view->camera();
+ camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
+ camera->setPosition(QVector3D(0, 0, -5.0f));
+ camera->setViewCenter(QVector3D(0, 0, 0));
+
+ // For camera controls
+ Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
+ camController->setLinearSpeed( 50.0f );
+ camController->setLookSpeed( 180.0f );
+ camController->setCamera(camera);
+
+ Qt3DRender::QDirectionalLight *light = new Qt3DRender::QDirectionalLight();
+ light->setIntensity(0.8f);
+ light->setWorldDirection(camera->viewVector());
+ rootEntity->addComponent(light);
+
+ return rootEntity;
+}
+
+int main(int argc, char* argv[])
+{
+ QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+ format.setMajorVersion(4);
+ format.setMinorVersion(5);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ format.setRenderableType(QSurfaceFormat::OpenGL);
+ QSurfaceFormat::setDefaultFormat(format);
+
+ // Will make Qt3D and QOpenGLWidget share a common context
+ QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+
+ QApplication app(argc, argv);
+
+ // Multimedia player
+ TextureWidget textureWidget;
+ VideoPlayerThread *videoPlayer = new VideoPlayerThread(&textureWidget);
+ videoPlayer->start();
+
+ textureWidget.resize(800, 600);
+ textureWidget.show();
+
+ // Texture object that Qt3D uses to access the texture from the video player
+ Qt3DRender::QSharedGLTexture *sharedTexture = new Qt3DRender::QSharedGLTexture();
+
+ QObject::connect(&textureWidget, &TextureWidget::textureIdChanged,
+ sharedTexture, &Qt3DRender::QSharedGLTexture::setTextureId);
+
+ // Qt3D Scene
+ Qt3DExtras::Qt3DWindow view;
+ Qt3DCore::QEntity *scene = createScene(&view, sharedTexture);
+ view.setRootEntity(scene);
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/sharedtexture/sharedtexture.pro b/tests/manual/sharedtexture/sharedtexture.pro
new file mode 100644
index 000000000..b41f43d71
--- /dev/null
+++ b/tests/manual/sharedtexture/sharedtexture.pro
@@ -0,0 +1,12 @@
+!include( ../manual.pri ) {
+ error( "Couldn't find the manual.pri file!" )
+}
+
+QT += widgets 3dcore 3drender 3dinput 3dextras multimedia
+
+SOURCES += \
+ videoplayer.cpp \
+ main.cpp
+
+HEADERS += \
+ videoplayer.h
diff --git a/tests/manual/sharedtexture/videoplayer.cpp b/tests/manual/sharedtexture/videoplayer.cpp
new file mode 100644
index 000000000..f970116b5
--- /dev/null
+++ b/tests/manual/sharedtexture/videoplayer.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QMutexLocker>
+#include <QtMultimedia/QVideoFrame>
+
+#include "videoplayer.h"
+
+TextureWidget::TextureWidget(QWidget *parent)
+ : QOpenGLWidget(parent)
+ , m_texture(QOpenGLTexture::Target2D)
+{
+ // Lock mutex so that we never process a frame until we have been initialized
+ m_mutex.lock();
+}
+
+// Main thread
+void TextureWidget::initializeGL()
+{
+ initializeOpenGLFunctions();
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ if (!m_shader.addShaderFromSourceCode(QOpenGLShader::Vertex,
+ "#version 330\n"
+ "out vec2 coords;\n"
+ "const vec2 positions[6] = vec2[] ("
+ " vec2(-1.0, 1.0),"
+ " vec2(-1.0, -1.0),"
+ " vec2(1.0, 1.0),"
+ " vec2(1.0, 1.0),"
+ " vec2(-1.0, -1.0),"
+ " vec2(1.0, -1.0));\n"
+ "const vec2 texCoords[6] = vec2[] ("
+ " vec2(0.0, 0.0),"
+ " vec2(0.0, 1.0),"
+ " vec2(1.0, 0.0),"
+ " vec2(1.0, 0.0),"
+ " vec2(0.0, 1.0),"
+ " vec2(1.0, 1.0));\n"
+ "void main() {\n"
+ " coords = texCoords[gl_VertexID];\n"
+ " gl_Position = vec4(positions[gl_VertexID], 0.0, 1.0);\n"
+ "}"))
+ qDebug() << "Failed to load vertex shader" << m_shader.log();
+ if (!m_shader.addShaderFromSourceCode(QOpenGLShader::Fragment,
+ "#version 330\n"
+ "in vec2 coords;\n"
+ "uniform sampler2D video_texture;\n"
+ "out vec4 fragColor;\n"
+ "void main() {\n"
+ " fragColor = texture(video_texture, coords);\n"
+ "}"))
+ qDebug() << "Failed to load fragment shader" << m_shader.log();
+ if (!m_shader.link())
+ qDebug() << "Failed to link shaders" << m_shader.log();
+
+ qDebug() << Q_FUNC_INFO << context()->shareContext();
+
+ m_vao.create();
+ // Allow rendering/frame acquisition to go on
+ m_mutex.unlock();
+}
+
+// Main thread
+void TextureWidget::paintGL()
+{
+ QMutexLocker lock(&m_mutex);
+ glViewport(0, 0, width(), height());
+
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+ if (!m_texture.isCreated())
+ return;
+
+ m_shader.bind();
+
+ m_texture.bind(0);
+ m_shader.setUniformValue("video_texture", 0);
+
+ m_vao.bind();
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ m_vao.release();
+ m_shader.release();
+}
+
+// Video Player thread
+void TextureWidget::setVideoFrame(const QVideoFrame &frame)
+{
+ // Ensure we won't be rendering while we are processing the frame
+ QMutexLocker lock(&m_mutex);
+
+ QVideoFrame f = frame;
+
+ // Map frame
+ if (!f.map(QAbstractVideoBuffer::ReadOnly))
+ return;
+
+ makeCurrent();
+
+ // Create or recreate texture
+ if (m_texture.width() != f.width() || m_texture.height() != f.height()) {
+ if (m_texture.isCreated())
+ m_texture.destroy();
+
+ m_texture.setSize(f.width(), f.height());
+ m_texture.setFormat(QOpenGLTexture::RGBA32F);
+ m_texture.setWrapMode(QOpenGLTexture::ClampToBorder);
+ m_texture.setMinificationFilter(QOpenGLTexture::Nearest);
+ m_texture.setMagnificationFilter(QOpenGLTexture::Nearest);
+ m_texture.allocateStorage();
+
+ m_texture.create();
+ emit textureIdChanged(m_texture.textureId());
+ }
+
+ const QVideoFrame::PixelFormat pFormat = f.pixelFormat();
+ if (pFormat == QVideoFrame::Format_RGB32) {
+ m_texture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, f.bits());
+ }
+
+ doneCurrent();
+
+ // Request display udpate
+ QOpenGLWidget::update();
+
+ // Unmap
+ f.unmap();
+}
+
+QList<QVideoFrame::PixelFormat> GLVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
+{
+ if (type == QAbstractVideoBuffer::NoHandle)
+ return {
+ QVideoFrame::Format_RGB32,
+ QVideoFrame::Format_ARGB32,
+ QVideoFrame::Format_BGR32,
+ QVideoFrame::Format_BGRA32
+ };
+ return {};
+}
+
+// Video player thread
+bool GLVideoSurface::present(const QVideoFrame &frame)
+{
+ emit onNewFrame(frame);
+ return true;
+}
+
+VideoPlayerThread::VideoPlayerThread(TextureWidget *textureWidget)
+ : QThread(textureWidget)
+ , m_player(new QMediaPlayer(nullptr, QMediaPlayer::VideoSurface))
+ , m_surface(new GLVideoSurface())
+{
+ m_player->moveToThread(this);
+ m_player->setMedia(QUrl("https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"));
+
+ // Tell player to render on GLVideoSurface
+ m_surface->moveToThread(this);
+ m_player->setVideoOutput(m_surface.get());
+
+ // Display errors
+ QObject::connect(m_player.get(), QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error),
+ m_player.get(), [this] (QMediaPlayer::Error e) {
+ qDebug() << Q_FUNC_INFO << e << m_player->errorString();
+ });
+
+ // Repeat video indefinitely
+ QObject::connect(m_player.get(), &QMediaPlayer::stateChanged, m_player.get(), [this] (QMediaPlayer::State state) {
+ if (state == QMediaPlayer::StoppedState)
+ m_player->play();
+ });
+
+ // Start playing when thread starts
+ QObject::connect(this, &QThread::started, this, [this] { m_player->play(); });
+
+ // Direct connection between 2 objects living in different threads
+ QObject::connect(m_surface.get(), &GLVideoSurface::onNewFrame,
+ textureWidget, &TextureWidget::setVideoFrame, Qt::DirectConnection);
+}
+
+VideoPlayerThread::~VideoPlayerThread()
+{
+ exit(0);
+ wait();
+}
diff --git a/tests/manual/sharedtexture/videoplayer.h b/tests/manual/sharedtexture/videoplayer.h
new file mode 100644
index 000000000..377ea57fe
--- /dev/null
+++ b/tests/manual/sharedtexture/videoplayer.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QThread>
+#include <QMutex>
+
+#include <QOpenGLWidget>
+#include <QOpenGLFunctions>
+#include <QOpenGLVertexArrayObject>
+#include <QOpenGLBuffer>
+#include <QOpenGLTexture>
+#include <QOpenGLShaderProgram>
+
+#include <QtMultimedia/QAbstractVideoSurface>
+#include <QtMultimedia/QMediaPlayer>
+
+#include <memory>
+
+class TextureWidget : public QOpenGLWidget, private QOpenGLFunctions
+{
+ Q_OBJECT
+ Q_PROPERTY(int textureId READ textureId NOTIFY textureIdChanged)
+public:
+ TextureWidget(QWidget *parent = nullptr);
+
+ int textureId() { return m_texture.textureId(); }
+
+private:
+ // MainThread
+ void initializeGL() override;
+
+ // Main thread
+ void paintGL() override;
+
+public Q_SLOTS:
+ // Called from Video player thread
+ void setVideoFrame(const QVideoFrame &frame);
+
+Q_SIGNALS:
+ void textureIdChanged(int textureId);
+
+private:
+ QOpenGLVertexArrayObject m_vao;
+ QOpenGLShaderProgram m_shader;
+ QOpenGLTexture m_texture;
+ QMutex m_mutex;
+};
+
+
+class GLVideoSurface : public QAbstractVideoSurface
+{
+ Q_OBJECT
+public:
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override;
+
+ // Call in VideaPlayerThread context
+ bool present(const QVideoFrame &frame) override;
+
+Q_SIGNALS:
+ void onNewFrame(const QVideoFrame &frame);
+};
+
+
+class VideoPlayerThread : public QThread
+{
+ Q_OBJECT
+public:
+ VideoPlayerThread(TextureWidget *textureWidget);
+ ~VideoPlayerThread();
+
+private:
+ TextureWidget *m_textureWidget;
+ std::unique_ptr<QMediaPlayer> m_player;
+ std::unique_ptr<GLVideoSurface> m_surface;
+};
diff --git a/tests/manual/sharedtextureqml/main.cpp b/tests/manual/sharedtextureqml/main.cpp
new file mode 100644
index 000000000..5c7ae9cff
--- /dev/null
+++ b/tests/manual/sharedtextureqml/main.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QtQml/QQmlContext>
+#include <QtQuick/QQuickView>
+#include <Qt3DRender/QAbstractTexture>
+#include <QWindow>
+#include <QTimer>
+
+#include <QQuickView>
+#include "videoplayer.h"
+
+
+template<typename Obj>
+QHash<int, QString> enumToNameMap(const char *enumName)
+{
+ const QMetaObject metaObj = Obj::staticMetaObject;
+ const int indexOfEnum = metaObj.indexOfEnumerator(enumName);
+ const QMetaEnum metaEnum = metaObj.enumerator(indexOfEnum);
+ const int keysCount = metaEnum.keyCount();
+
+ QHash<int, QString> v;
+ v.reserve(keysCount);
+ for (int i = 0; i < keysCount; ++i)
+ v[metaEnum.value(i)] = metaEnum.key(i);
+ return v;
+}
+
+
+class EnumNameMapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE QString statusName(int v) const { return m_statusMap.value(v); }
+ Q_INVOKABLE QString formatName(int v) const { return m_formatMap.value(v); }
+ Q_INVOKABLE QString targetName(int v) const { return m_targetMap.value(v); }
+
+private:
+ const QHash<int, QString> m_statusMap = enumToNameMap<Qt3DRender::QAbstractTexture>("Status");
+ const QHash<int, QString> m_formatMap = enumToNameMap<Qt3DRender::QAbstractTexture>("TextureFormat");
+ const QHash<int, QString> m_targetMap = enumToNameMap<Qt3DRender::QAbstractTexture>("Target");
+};
+
+int main(int argc, char* argv[])
+{
+ QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+ format.setMajorVersion(4);
+ format.setMinorVersion(5);
+ format.setDepthBufferSize(16);
+ format.setStencilBufferSize(8);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ format.setRenderableType(QSurfaceFormat::OpenGL);
+ QSurfaceFormat::setDefaultFormat(format);
+
+
+ // Make the OpenGLWidget's shared context be qt_gl_global_share_context
+ QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ QApplication app(argc, argv);
+
+ // Multimedia player
+ TextureWidget textureWidget;
+ VideoPlayerThread *videoPlayer = new VideoPlayerThread(&textureWidget);
+ videoPlayer->start();
+
+ textureWidget.resize(800, 600);
+ textureWidget.show();
+
+ // Qt3D QtQuick Scene (uses qt_global_share_context by default)
+ QQuickView view;
+ QQmlContext *ctx = view.rootContext();
+ EnumNameMapper mapper;
+ ctx->setContextProperty(QStringLiteral("_nameMapper"), &mapper);
+ ctx->setContextProperty(QStringLiteral("_textureWidget"), &textureWidget);
+
+ view.resize(800, 600);
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/sharedtextureqml/main.qml b/tests/manual/sharedtextureqml/main.qml
new file mode 100644
index 000000000..fd529e51c
--- /dev/null
+++ b/tests/manual/sharedtextureqml/main.qml
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.10
+import QtQuick.Scene3D 2.0
+import Qt3D.Core 2.10
+import Qt3D.Render 2.13
+import Qt3D.Input 2.0
+import Qt3D.Extras 2.0
+
+Item {
+ width: 800
+ height: 600
+
+ Scene3D {
+ anchors.fill: parent
+
+ Entity {
+ id: sceneRoot
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 16/9
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 0.0, -4.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
+ }
+
+ OrbitCameraController {
+ camera: camera
+ }
+
+ components: [
+ RenderSettings {
+ activeFrameGraph: ForwardRenderer {
+ clearColor: Qt.rgba(0, 0.5, 1, 1)
+ camera: camera
+ }
+ },
+ // Event Source will be set by the Qt3DQuickWindow
+ InputSettings { },
+ DirectionalLight {
+ intensity: 0.8
+ worldDirection: camera.viewVector
+ }
+ ]
+
+
+ NumberAnimation {
+ target: cubeTransform
+ property: "rotationY"
+ duration: 10000
+ from: 0
+ to: 360
+
+ loops: Animation.Infinite
+ running: true
+ }
+
+ SharedGLTexture {
+ id: shaderGLTexture
+ textureId: _textureWidget.textureId
+ }
+
+ Entity {
+ id: cubeEntity
+ readonly property CuboidMesh cuboid: CuboidMesh {}
+ readonly property DiffuseMapMaterial material: DiffuseMapMaterial {
+ diffuse: shaderGLTexture
+ }
+ Transform {
+ id: cubeTransform
+ rotationX: 180
+ }
+
+ components: [ cuboid, material, cubeTransform ]
+ }
+ }
+ }
+
+ Grid {
+ spacing: 10
+ columns: 2
+ Text { text: "Target: " + _nameMapper.targetName(shaderGLTexture.target) }
+ Text { text: "Format: " + _nameMapper.formatName(shaderGLTexture.format) }
+ Text { text: "Width: " + shaderGLTexture.width }
+ Text { text: "Height: " + shaderGLTexture.height }
+ Text { text: "Depth: " + shaderGLTexture.depth }
+ Text { text: "Layers: " + shaderGLTexture.layers }
+ Text { text: "GL Texture Id: " + shaderGLTexture.textureId }
+ }
+
+}
diff --git a/tests/manual/sharedtextureqml/qml.qrc b/tests/manual/sharedtextureqml/qml.qrc
new file mode 100644
index 000000000..5f6483ac3
--- /dev/null
+++ b/tests/manual/sharedtextureqml/qml.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/sharedtextureqml/sharedtextureqml.pro b/tests/manual/sharedtextureqml/sharedtextureqml.pro
new file mode 100644
index 000000000..066bb8446
--- /dev/null
+++ b/tests/manual/sharedtextureqml/sharedtextureqml.pro
@@ -0,0 +1,17 @@
+!include( ../manual.pri ) {
+ error( "Couldn't find the manual.pri file!" )
+}
+
+QT += widgets gui-private 3dcore 3drender 3dinput 3dextras multimedia quick 3dquickextras
+
+SOURCES += \
+ main.cpp \
+ ../sharedtexture/videoplayer.cpp
+
+HEADERS += \
+ ../sharedtexture/videoplayer.h
+
+INCLUDEPATH += ../sharedtexture
+
+RESOURCES += \
+ qml.qrc
diff --git a/tests/manual/texture_property_updates/main.cpp b/tests/manual/texture_property_updates/main.cpp
index e145b0a26..725c6ccc1 100644
--- a/tests/manual/texture_property_updates/main.cpp
+++ b/tests/manual/texture_property_updates/main.cpp
@@ -77,11 +77,13 @@ public:
Q_INVOKABLE QString statusName(int v) const { return m_statusMap.value(v); }
Q_INVOKABLE QString formatName(int v) const { return m_formatMap.value(v); }
Q_INVOKABLE QString targetName(int v) const { return m_targetMap.value(v); }
+ Q_INVOKABLE QString handleTypeName(int v) const { return m_handleTypeMap.value(v); }
private:
const QHash<int, QString> m_statusMap = enumToNameMap<Qt3DRender::QAbstractTexture>("Status");
const QHash<int, QString> m_formatMap = enumToNameMap<Qt3DRender::QAbstractTexture>("TextureFormat");
const QHash<int, QString> m_targetMap = enumToNameMap<Qt3DRender::QAbstractTexture>("Target");
+ const QHash<int, QString> m_handleTypeMap = enumToNameMap<Qt3DRender::QAbstractTexture>("HandleType");
};
int main(int argc, char* argv[])
diff --git a/tests/manual/texture_property_updates/main.qml b/tests/manual/texture_property_updates/main.qml
index f1256c75b..7794dab55 100644
--- a/tests/manual/texture_property_updates/main.qml
+++ b/tests/manual/texture_property_updates/main.qml
@@ -51,7 +51,7 @@
import QtQuick 2.2 as QQ2
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
-import Qt3D.Render 2.0
+import Qt3D.Render 2.12
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
@@ -184,6 +184,8 @@ QQ2.Item {
QQ2.Text { text: "Depth: " + model.modelData.depth}
QQ2.Text { text: "Layers: " + model.modelData.layers}
QQ2.Text { text: "Status: " + nameMapper.statusName(model.modelData.status.toString()) }
+ QQ2.Text { text: "HandleType: " + nameMapper.handleTypeName(model.modelData.handleType) }
+ QQ2.Text { text: "Handle: " + model.modelData.handle }
}
}
}