From b855240b782395f94315f43ea3e7e182299fac48 Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Thu, 16 Feb 2012 14:43:03 +1000 Subject: Rename QDeclarative symbols to QQuick and QQml Symbols beginning with QDeclarative are already exported by the quick1 module. Users can apply the bin/rename-qtdeclarative-symbols.sh script to modify client code using the previous names of the renamed symbols. Task-number: QTBUG-23737 Change-Id: Ifaa482663767634931e8711a8e9bf6e404859e66 Reviewed-by: Martin Jones --- tests/auto/quick/nodes/nodes.pro | 9 + tests/auto/quick/nodes/tst_nodestest.cpp | 354 +++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 tests/auto/quick/nodes/nodes.pro create mode 100644 tests/auto/quick/nodes/tst_nodestest.cpp (limited to 'tests/auto/quick/nodes') diff --git a/tests/auto/quick/nodes/nodes.pro b/tests/auto/quick/nodes/nodes.pro new file mode 100644 index 0000000000..51e3e2a156 --- /dev/null +++ b/tests/auto/quick/nodes/nodes.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_nodestest +macx:CONFIG -= app_bundle + +SOURCES += tst_nodestest.cpp + +CONFIG+=parallel_test + +QT += core-private gui-private qml-private quick-private opengl widgets testlib diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp new file mode 100644 index 0000000000..6a6de625d5 --- /dev/null +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt scene graph research project. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +class NodesTest : public QObject +{ + Q_OBJECT + +public: + NodesTest(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase() { + delete widget; + } + + // Root nodes + void propegate(); + void propegateWithMultipleRoots(); + void simulatedEffect_data(); + void simulatedEffect(); + + // Opacity nodes + void basicOpacityNode(); + void opacityPropegation(); + + // QSGNodeUpdater + void isBlockedCheck(); + +private: + QGLWidget *widget; + + QSGNodeUpdater updater; +}; + +void NodesTest::initTestCase() +{ + widget = new QGLWidget(); + widget->resize(100, 30); + widget->show(); +} + +class DummyRenderer : public QSGRenderer +{ +public: + DummyRenderer(QSGRootNode *root) + : QSGRenderer(QSGContext::createDefaultContext()) + , changedNode(0) + , changedState(0) + , renderCount(0) + { + setRootNode(root); + } + + void render() { + ++renderCount; + renderingOrder = ++globalRendereringOrder; + } + + void nodeChanged(QSGNode *node, QSGNode::DirtyState state) { + changedNode = node; + changedState = state; + QSGRenderer::nodeChanged(node, state); + } + + QSGNode *changedNode; + QSGNode::DirtyState changedState; + + int renderCount; + int renderingOrder; + static int globalRendereringOrder; +}; + +int DummyRenderer::globalRendereringOrder; + +NodesTest::NodesTest() +{ +} + + +void NodesTest::propegate() +{ + QSGRootNode root; + QSGNode child; child.setFlag(QSGNode::OwnedByParent, false); + root.appendChildNode(&child); + + DummyRenderer renderer(&root); + + child.markDirty(QSGNode::DirtyGeometry); + + QCOMPARE(&child, renderer.changedNode); + QCOMPARE((int) renderer.changedState, (int) QSGNode::DirtyGeometry); +} + + +void NodesTest::propegateWithMultipleRoots() +{ + QSGRootNode root1; + QSGNode child2; child2.setFlag(QSGNode::OwnedByParent, false); + QSGRootNode root3; root3.setFlag(QSGNode::OwnedByParent, false); + QSGNode child4; child4.setFlag(QSGNode::OwnedByParent, false); + + root1.appendChildNode(&child2); + child2.appendChildNode(&root3); + root3.appendChildNode(&child4); + + DummyRenderer ren1(&root1); + DummyRenderer ren2(&root3); + + child4.markDirty(QSGNode::DirtyGeometry); + + QCOMPARE(ren1.changedNode, &child4); + QCOMPARE(ren2.changedNode, &child4); + + QCOMPARE((int) ren1.changedState, (int) QSGNode::DirtyGeometry); + QCOMPARE((int) ren2.changedState, (int) QSGNode::DirtyGeometry); +} + + + +class SimulatedEffectRenderer : public DummyRenderer +{ +public: + SimulatedEffectRenderer(QSGRootNode *root, QSGBasicGeometryNode *c) + : DummyRenderer(root) + { + child = c; + } + + void render() { + matrix = child->matrix() ? *child->matrix() : QMatrix4x4(); + DummyRenderer::render(); + } + + QSGBasicGeometryNode *child; + QMatrix4x4 matrix; +}; + + +class PseudoEffectNode : public QSGNode { +public: + PseudoEffectNode(QSGRenderer *r) + : renderer(r) + { + setFlag(UsePreprocess); + } + + void preprocess() { + + if (renderer->rootNode()->parent()) { + // Mark the root dirty to build a clean state from the root and down + renderer->rootNode()->markDirty(QSGNode::DirtyForceUpdate); + } + + renderer->renderScene(); + + if (renderer->rootNode()->parent()) { + // Mark the parent of the root dirty to force the root and down to be updated. + renderer->rootNode()->parent()->markDirty(QSGNode::DirtyForceUpdate); + } + } + + QSGRenderer *renderer; +}; + +void NodesTest::simulatedEffect_data() +{ + QTest::addColumn("connected"); + + QTest::newRow("connected") << true; + QTest::newRow("disconnected") << false; +} + +void NodesTest::simulatedEffect() +{ + QFETCH(bool, connected); + + QSGRootNode root; + QSGRootNode source; + QSGTransformNode xform; + QSGSimpleRectNode geometry; + geometry.setRect(QRectF(0, 0, 1, 1)); + geometry.setColor(Qt::red); + + root.setFlag(QSGNode::OwnedByParent, false); + source.setFlag(QSGNode::OwnedByParent, false); + xform.setFlag(QSGNode::OwnedByParent, false); + geometry.setFlag(QSGNode::OwnedByParent, false); + + SimulatedEffectRenderer rootRenderer(&root, &geometry); + SimulatedEffectRenderer sourceRenderer(&source, &geometry); + + PseudoEffectNode effect(&sourceRenderer); + + /* + root Source is redirected into effect using the SimulatedEffectRenderer + / \ + xform effect + | + source + | + geometry + */ + + root.appendChildNode(&xform); + root.appendChildNode(&effect); + if (connected) + xform.appendChildNode(&source); + source.appendChildNode(&geometry); + QMatrix4x4 m; m.translate(1, 2, 3); + xform.setMatrix(m); + + // Clear all dirty states... + updater.updateStates(&root); + + rootRenderer.renderScene(); + + // compare that we got one render call to each + QCOMPARE(rootRenderer.renderCount, 1); + QCOMPARE(sourceRenderer.renderCount, 1); + QVERIFY(sourceRenderer.renderingOrder < rootRenderer.renderingOrder); + if (connected) // geometry is not rendered in this case, so skip it... + QCOMPARE(rootRenderer.matrix, xform.matrix()); + QCOMPARE(sourceRenderer.matrix, QMatrix4x4()); +} + +void NodesTest::basicOpacityNode() +{ + QSGOpacityNode n; + QCOMPARE(n.opacity(), 1.); + + n.setOpacity(0.5); + QCOMPARE(n.opacity(), 0.5); + + n.setOpacity(-1); + QCOMPARE(n.opacity(), 0.); + + n.setOpacity(2); + QCOMPARE(n.opacity(), 1.); +} + +void NodesTest::opacityPropegation() +{ + QSGRootNode root; + QSGOpacityNode *a = new QSGOpacityNode; + QSGOpacityNode *b = new QSGOpacityNode; + QSGOpacityNode *c = new QSGOpacityNode; + + QSGSimpleRectNode *geometry = new QSGSimpleRectNode; + geometry->setRect(0, 0, 100, 100); + + root.appendChildNode(a); + a->appendChildNode(b); + b->appendChildNode(c); + c->appendChildNode(geometry); + + a->setOpacity(0.9); + b->setOpacity(0.8); + c->setOpacity(0.7); + + updater.updateStates(&root); + + QCOMPARE(a->combinedOpacity(), 0.9); + QCOMPARE(b->combinedOpacity(), 0.9 * 0.8); + QCOMPARE(c->combinedOpacity(), 0.9 * 0.8 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.8 * 0.7); + + b->setOpacity(0.1); + updater.updateStates(&root); + + QCOMPARE(a->combinedOpacity(), 0.9); + QCOMPARE(b->combinedOpacity(), 0.9 * 0.1); + QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); + + b->setOpacity(0); + updater.updateStates(&root); + + QVERIFY(b->isSubtreeBlocked()); + + // Verify that geometry did not get updated as it is in a blocked + // subtree + QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); +} + +void NodesTest::isBlockedCheck() +{ + QSGRootNode root; + QSGOpacityNode *opacity = new QSGOpacityNode(); + QSGNode *node = new QSGNode(); + + root.appendChildNode(opacity); + opacity->appendChildNode(node); + + QSGNodeUpdater updater; + + opacity->setOpacity(0); + QVERIFY(updater.isNodeBlocked(node, &root)); + + opacity->setOpacity(1); + QVERIFY(!updater.isNodeBlocked(node, &root)); +} + +QTEST_MAIN(NodesTest); + +#include "tst_nodestest.moc" -- cgit v1.2.3