diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-03-18 15:07:11 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-03-25 14:23:18 +0000 |
commit | 982ea29558d6374067eb6cc0505b709eb9ecdae3 (patch) | |
tree | d42c780087e1dc5675ff4e45abb3a6bdc0c71697 /tests | |
parent | 8a5f83749373f5f3dc3490563ee437253ba59414 (diff) |
Add methods to set and retrieve format indices for a blend value node
In order to have a consistent data layout for all interior nodes of a
blend tree, we need a place to convert from whatever data layout a
clip produces when evaluated to the format used by the blend tree. We
will do this by creating for each value leaf node a vector of indices
that can be used to map from the ClipResults layout output by the clip
to the ClipResults format used by the blend tree.
With this approach, we can do the following:
* Evaluate each leaf node in the blend tree
* Perform a gather operation using these format indices to reorder the
data into a consistent layout for the whole blend tree
* Evaluate the blend tree using this consistent layout
This completely avoids having to perform complex mappings when
evaluating each blend node, which is a significant saving in
overhead and allows for more parallellism in the future.
Change-Id: Ie534534f9555842d0d0f1a89fc996e25f5c6ce9e
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp b/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp index 12eaf1a3c..9266161fc 100644 --- a/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp +++ b/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp @@ -35,8 +35,13 @@ #include <Qt3DCore/qpropertyupdatedchange.h> #include "qbackendnodetester.h" +#include <random> +#include <algorithm> + using namespace Qt3DAnimation::Animation; +Q_DECLARE_METATYPE(ClipBlendValue *) + class tst_ClipBlendValue : public Qt3DCore::QBackendNodeTester { Q_OBJECT @@ -162,6 +167,131 @@ private Q_SLOTS: // THEN QCOMPARE(actualDuration, expectedDuration); } + + void checkFormatIndices_data() + { + QTest::addColumn<ClipBlendValue *>("blendNode"); + QTest::addColumn<QVector<int>>("indexes"); + QTest::addColumn<QVector<Qt3DCore::QNodeId>>("animatorIds"); + QTest::addColumn<QVector<ComponentIndices>>("expectedFormatIndices"); + + // Single entry + { + auto blendNode = new ClipBlendValue; + QVector<Qt3DCore::QNodeId> animatorIds; + QVector<ComponentIndices> expectedFormatIndices; + + const auto animatorId = Qt3DCore::QNodeId::createId(); + animatorIds.push_back(animatorId); + + ComponentIndices formatIndices = { 0, 1, 2 }; + expectedFormatIndices.push_back(formatIndices); + + // Set data and indexes + blendNode->setFormatIndices(animatorId, formatIndices); + QVector<int> indexes = QVector<int>() << 0; + + QTest::newRow("single entry") + << blendNode << indexes << animatorIds << expectedFormatIndices; + } + + // No data + { + auto blendNode = new ClipBlendValue; + QVector<Qt3DCore::QNodeId> animatorIds; + QVector<ComponentIndices> expectedFormatIndices; + + auto animatorId = Qt3DCore::QNodeId::createId(); + animatorIds.push_back(animatorId); + + ComponentIndices formatIndices; + expectedFormatIndices.push_back(formatIndices); + + // Don't set any data + QVector<int> indexes = QVector<int>() << 0; + + QTest::newRow("no entries") + << blendNode << indexes << animatorIds << expectedFormatIndices; + } + + // Multiple entries, ordered + { + auto blendNode = new ClipBlendValue; + QVector<Qt3DCore::QNodeId> animatorIds; + QVector<ComponentIndices> expectedFormatIndices; + + const int animatorCount = 10; + for (int j = 0; j < animatorCount; ++j) { + auto animatorId = Qt3DCore::QNodeId::createId(); + animatorIds.push_back(animatorId); + + ComponentIndices formatIndices; + for (int i = 0; i < j + 5; ++i) + formatIndices.push_back(i + j); + expectedFormatIndices.push_back(formatIndices); + + blendNode->setFormatIndices(animatorId, formatIndices); + } + + QVector<int> indexes(animatorCount); + std::iota(indexes.begin(), indexes.end(), 0); + + QTest::newRow("multiple entries, ordered") + << blendNode << indexes << animatorIds << expectedFormatIndices; + } + + // Multiple entries, unordered + { + auto blendNode = new ClipBlendValue; + QVector<Qt3DCore::QNodeId> animatorIds; + QVector<ComponentIndices> expectedFormatIndices; + + const int animatorCount = 10; + for (int j = 0; j < animatorCount; ++j) { + auto animatorId = Qt3DCore::QNodeId::createId(); + animatorIds.push_back(animatorId); + + ComponentIndices formatIndices; + for (int i = 0; i < j + 5; ++i) + formatIndices.push_back(i + j); + expectedFormatIndices.push_back(formatIndices); + + blendNode->setFormatIndices(animatorId, formatIndices); + } + + // Shuffle the animatorIds to randomise the lookups + QVector<int> indexes(animatorCount); + std::iota(indexes.begin(), indexes.end(), 0); + std::random_device rd; + std::mt19937 generator(rd()); + std::shuffle(indexes.begin(), indexes.end(), generator); + + QTest::newRow("multiple entries, unordered") + << blendNode << indexes << animatorIds << expectedFormatIndices; + } + } + + void checkFormatIndices() + { + // GIVEN + QFETCH(ClipBlendValue *, blendNode); + QFETCH(QVector<int>, indexes); + QFETCH(QVector<Qt3DCore::QNodeId>, animatorIds); + QFETCH(QVector<ComponentIndices>, expectedFormatIndices); + + for (int i = 0; i < indexes.size(); ++i) { + // WHEN + const int index = indexes[i]; + const ComponentIndices actualFormatIndices = blendNode->formatIndices(animatorIds[index]); + + // THEN + QCOMPARE(actualFormatIndices.size(), expectedFormatIndices[index].size()); + for (int j = 0; j < actualFormatIndices.size(); ++j) + QCOMPARE(actualFormatIndices[j], expectedFormatIndices[index][j]); + } + + delete blendNode; + } }; QTEST_MAIN(tst_ClipBlendValue) |