Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / nodes / tst_nodestest.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the Qt scene graph research project.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtCore/QString>
43 #include <QtTest/QtTest>
44
45 #include <QtQuick/qsgnode.h>
46 #include <QtQuick/private/qsgrenderer_p.h>
47 #include <QtQuick/private/qsgnodeupdater_p.h>
48
49 #include <QtQuick/qsgsimplerectnode.h>
50 #include <QtOpenGL/QGLWidget>
51 class NodesTest : public QObject
52 {
53     Q_OBJECT
54
55 public:
56     NodesTest();
57
58 private Q_SLOTS:
59     void initTestCase();
60     void cleanupTestCase() {
61         delete widget;
62     }
63
64     // Root nodes
65     void propegate();
66     void propegateWithMultipleRoots();
67     void simulatedEffect_data();
68     void simulatedEffect();
69
70     // Opacity nodes
71     void basicOpacityNode();
72     void opacityPropegation();
73
74     // QSGNodeUpdater
75     void isBlockedCheck();
76
77 private:
78     QGLWidget *widget;
79
80     QSGNodeUpdater updater;
81 };
82
83 void NodesTest::initTestCase()
84 {
85     widget = new QGLWidget();
86     widget->resize(100, 30);
87     widget->show();
88 }
89
90 class DummyRenderer : public QSGRenderer
91 {
92 public:
93     DummyRenderer(QSGRootNode *root)
94         : QSGRenderer(QSGContext::createDefaultContext())
95         , changedNode(0)
96         , changedState(0)
97         , renderCount(0)
98     {
99         setRootNode(root);
100     }
101
102     void render() {
103         ++renderCount;
104         renderingOrder = ++globalRendereringOrder;
105     }
106
107     void nodeChanged(QSGNode *node, QSGNode::DirtyState state) {
108         changedNode = node;
109         changedState = state;
110         QSGRenderer::nodeChanged(node, state);
111     }
112
113     QSGNode *changedNode;
114     QSGNode::DirtyState changedState;
115
116     int renderCount;
117     int renderingOrder;
118     static int globalRendereringOrder;
119 };
120
121 int DummyRenderer::globalRendereringOrder;
122
123 NodesTest::NodesTest()
124 {
125 }
126
127
128 void NodesTest::propegate()
129 {
130     QSGRootNode root;
131     QSGNode child; child.setFlag(QSGNode::OwnedByParent, false);
132     root.appendChildNode(&child);
133
134     DummyRenderer renderer(&root);
135
136     child.markDirty(QSGNode::DirtyGeometry);
137
138     QCOMPARE(&child, renderer.changedNode);
139     QCOMPARE((int) renderer.changedState, (int) QSGNode::DirtyGeometry);
140 }
141
142
143 void NodesTest::propegateWithMultipleRoots()
144 {
145     QSGRootNode root1;
146     QSGNode child2; child2.setFlag(QSGNode::OwnedByParent, false);
147     QSGRootNode root3; root3.setFlag(QSGNode::OwnedByParent, false);
148     QSGNode child4; child4.setFlag(QSGNode::OwnedByParent, false);
149
150     root1.appendChildNode(&child2);
151     child2.appendChildNode(&root3);
152     root3.appendChildNode(&child4);
153
154     DummyRenderer ren1(&root1);
155     DummyRenderer ren2(&root3);
156
157     child4.markDirty(QSGNode::DirtyGeometry);
158
159     QCOMPARE(ren1.changedNode, &child4);
160     QCOMPARE(ren2.changedNode, &child4);
161
162     QCOMPARE((int) ren1.changedState, (int) QSGNode::DirtyGeometry);
163     QCOMPARE((int) ren2.changedState, (int) QSGNode::DirtyGeometry);
164 }
165
166
167
168 class SimulatedEffectRenderer : public DummyRenderer
169 {
170 public:
171     SimulatedEffectRenderer(QSGRootNode *root, QSGBasicGeometryNode *c)
172         : DummyRenderer(root)
173     {
174         child = c;
175     }
176
177     void render() {
178         matrix = child->matrix() ? *child->matrix() : QMatrix4x4();
179         DummyRenderer::render();
180     }
181
182     QSGBasicGeometryNode *child;
183     QMatrix4x4 matrix;
184 };
185
186
187 class PseudoEffectNode : public QSGNode {
188 public:
189     PseudoEffectNode(QSGRenderer *r)
190         : renderer(r)
191     {
192         setFlag(UsePreprocess);
193     }
194
195     void preprocess() {
196
197         if (renderer->rootNode()->parent()) {
198             // Mark the root dirty to build a clean state from the root and down
199             renderer->rootNode()->markDirty(QSGNode::DirtyForceUpdate);
200         }
201
202         renderer->renderScene();
203
204         if (renderer->rootNode()->parent()) {
205             // Mark the parent of the root dirty to force the root and down to be updated.
206             renderer->rootNode()->parent()->markDirty(QSGNode::DirtyForceUpdate);
207         }
208     }
209
210     QSGRenderer *renderer;
211 };
212
213 void NodesTest::simulatedEffect_data()
214 {
215     QTest::addColumn<bool>("connected");
216
217     QTest::newRow("connected") << true;
218     QTest::newRow("disconnected") << false;
219 }
220
221 void NodesTest::simulatedEffect()
222 {
223     QFETCH(bool, connected);
224
225     QSGRootNode root;
226     QSGRootNode source;
227     QSGTransformNode xform;
228     QSGSimpleRectNode geometry;
229     geometry.setRect(QRectF(0, 0, 1, 1));
230     geometry.setColor(Qt::red);
231
232     root.setFlag(QSGNode::OwnedByParent, false);
233     source.setFlag(QSGNode::OwnedByParent, false);
234     xform.setFlag(QSGNode::OwnedByParent, false);
235     geometry.setFlag(QSGNode::OwnedByParent, false);
236
237     SimulatedEffectRenderer rootRenderer(&root, &geometry);
238     SimulatedEffectRenderer sourceRenderer(&source, &geometry);
239
240     PseudoEffectNode effect(&sourceRenderer);
241
242     /*
243       root              Source is redirected into effect using  the SimulatedEffectRenderer
244      /    \
245   xform  effect
246     |
247   source
248     |
249  geometry
250     */
251
252     root.appendChildNode(&xform);
253     root.appendChildNode(&effect);
254     if (connected)
255         xform.appendChildNode(&source);
256     source.appendChildNode(&geometry);
257     QMatrix4x4 m; m.translate(1, 2, 3);
258     xform.setMatrix(m);
259
260     // Clear all dirty states...
261     updater.updateStates(&root);
262
263     rootRenderer.renderScene();
264
265     // compare that we got one render call to each
266     QCOMPARE(rootRenderer.renderCount, 1);
267     QCOMPARE(sourceRenderer.renderCount, 1);
268     QVERIFY(sourceRenderer.renderingOrder < rootRenderer.renderingOrder);
269     if (connected) // geometry is not rendered in this case, so skip it...
270         QCOMPARE(rootRenderer.matrix, xform.matrix());
271     QCOMPARE(sourceRenderer.matrix, QMatrix4x4());
272 }
273
274 void NodesTest::basicOpacityNode()
275 {
276     QSGOpacityNode n;
277     QCOMPARE(n.opacity(), 1.);
278
279     n.setOpacity(0.5);
280     QCOMPARE(n.opacity(), 0.5);
281
282     n.setOpacity(-1);
283     QCOMPARE(n.opacity(), 0.);
284
285     n.setOpacity(2);
286     QCOMPARE(n.opacity(), 1.);
287 }
288
289 void NodesTest::opacityPropegation()
290 {
291     QSGRootNode root;
292     QSGOpacityNode *a = new QSGOpacityNode;
293     QSGOpacityNode *b = new QSGOpacityNode;
294     QSGOpacityNode *c = new QSGOpacityNode;
295
296     QSGSimpleRectNode *geometry = new QSGSimpleRectNode;
297     geometry->setRect(0, 0, 100, 100);
298
299     root.appendChildNode(a);
300     a->appendChildNode(b);
301     b->appendChildNode(c);
302     c->appendChildNode(geometry);
303
304     a->setOpacity(0.9);
305     b->setOpacity(0.8);
306     c->setOpacity(0.7);
307
308     updater.updateStates(&root);
309
310     QCOMPARE(a->combinedOpacity(), 0.9);
311     QCOMPARE(b->combinedOpacity(), 0.9 * 0.8);
312     QCOMPARE(c->combinedOpacity(), 0.9 * 0.8 * 0.7);
313     QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.8 * 0.7);
314
315     b->setOpacity(0.1);
316     updater.updateStates(&root);
317
318     QCOMPARE(a->combinedOpacity(), 0.9);
319     QCOMPARE(b->combinedOpacity(), 0.9 * 0.1);
320     QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7);
321     QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7);
322
323     b->setOpacity(0);
324     updater.updateStates(&root);
325
326     QVERIFY(b->isSubtreeBlocked());
327
328     // Verify that geometry did not get updated as it is in a blocked
329     // subtree
330     QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7);
331     QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7);
332 }
333
334 void NodesTest::isBlockedCheck()
335 {
336     QSGRootNode root;
337     QSGOpacityNode *opacity = new QSGOpacityNode();
338     QSGNode *node = new QSGNode();
339
340     root.appendChildNode(opacity);
341     opacity->appendChildNode(node);
342
343     QSGNodeUpdater updater;
344
345     opacity->setOpacity(0);
346     QVERIFY(updater.isNodeBlocked(node, &root));
347
348     opacity->setOpacity(1);
349     QVERIFY(!updater.isNodeBlocked(node, &root));
350 }
351
352 QTEST_MAIN(NodesTest);
353
354 #include "tst_nodestest.moc"