QQuickCanvas renames
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickitemlayer / tst_qquickitemlayer.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 test suite of the Qt Toolkit.
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 <qtest.h>
43
44 #include <QtQuick/qquickitem.h>
45 #include <QtQuick/qquickview.h>
46 #include <QtGui/qopenglcontext.h>
47
48 #include "../../shared/util.h"
49
50 class tst_QQuickItemLayer: public QQmlDataTest
51 {
52     Q_OBJECT
53 public:
54     tst_QQuickItemLayer();
55
56     QImage runTest(const QString &fileName)
57     {
58         QQuickView view;
59         view.setSource(testFileUrl(fileName));
60
61         view.show();
62         QTest::qWaitForWindowShown(&view);
63
64         return view.grabWindow();
65     }
66
67 private slots:
68     void layerEnabled();
69     void layerSmooth();
70     void layerMipmap();
71     void layerEffect();
72
73     void layerVisibility_data();
74     void layerVisibility();
75
76     void layerSourceRect();
77
78     void layerZOrder_data();
79     void layerZOrder();
80
81     void layerIsTextureProvider();
82
83     void changeZOrder_data();
84     void changeZOrder();
85
86     void toggleLayerAndEffect();
87     void disableLayer();
88     void changeSamplerName();
89     void itemEffect();
90     void rectangleEffect();
91
92 private:
93     bool m_isMesaSoftwareRasterizer;
94     int m_mesaVersion;
95 };
96
97 tst_QQuickItemLayer::tst_QQuickItemLayer()
98     : m_mesaVersion(0)
99 {
100     QWindow window;
101     QOpenGLContext context;
102     window.setSurfaceType(QWindow::OpenGLSurface);
103     window.create();
104     context.create();
105     context.makeCurrent(&window);
106     const char *vendor = (const char *)glGetString(GL_VENDOR);
107     const char *renderer = (const char *)glGetString(GL_RENDERER);
108     m_isMesaSoftwareRasterizer = strcmp(vendor, "Mesa Project") == 0
109             && strcmp(renderer, "Software Rasterizer") == 0;
110     if (m_isMesaSoftwareRasterizer) {
111         // Expects format: <OpenGL version> Mesa <Mesa version>[-devel] [...]
112         const char *version = (const char *)glGetString(GL_VERSION);
113         QList<QByteArray> list = QByteArray(version).split(' ');
114         if (list.size() >= 3) {
115             list = list.at(2).split('-').at(0).split('.');
116             int major = 0;
117             int minor = 0;
118             int patch = 0;
119             if (list.size() >= 1)
120                 major = list.at(0).toInt();
121             if (list.size() >= 2)
122                 minor = list.at(1).toInt();
123             if (list.size() >= 3)
124                 patch = list.at(2).toInt();
125             m_mesaVersion = QT_VERSION_CHECK(major, minor, patch);
126         }
127     }
128 }
129
130 // The test draws a red and a blue box next to each other and tests that the
131 // output is still red and blue on the left and right and a combination of
132 // the two in the middle.
133
134 void tst_QQuickItemLayer::layerSmooth()
135 {
136     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
137         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
138     QImage fb = runTest("Smooth.qml");
139     QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
140     QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0, 0xff));
141
142     uint pixel = fb.pixel(fb.width() / 2, 0);
143     QVERIFY(qRed(pixel) > 0);
144     QVERIFY(qBlue(pixel) > 0);
145 }
146
147
148
149 // The test draws a gradient at a small size into a layer and scales the
150 // layer. If the layer is enabled there should be very visible bands in
151 // the gradient.
152
153 void tst_QQuickItemLayer::layerEnabled()
154 {
155     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
156         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
157     QImage fb = runTest("Enabled.qml");
158     // Verify the banding
159     QCOMPARE(fb.pixel(0, 0), fb.pixel(0, 1));
160     // Verify the gradient
161     QVERIFY(fb.pixel(0, 0) != fb.pixel(0, fb.height() - 1));
162 }
163
164
165
166 // The test draws a one pixel wide line and scales it down by more than a a factor 2
167 // If mipmpping works, the pixels should be gray, not white or black
168
169 void tst_QQuickItemLayer::layerMipmap()
170 {
171     if (m_isMesaSoftwareRasterizer)
172         QSKIP("Mipmapping does not work with the Mesa Software Rasterizer.");
173     QImage fb = runTest("Mipmap.qml");
174     QVERIFY(fb.pixel(0, 0) != 0xff000000);
175     QVERIFY(fb.pixel(0, 0) != 0xffffffff);
176 }
177
178
179
180 // The test implements an rgb swapping effect sourced from a blue rectangle. The
181 // resulting pixel should be red
182
183 void tst_QQuickItemLayer::layerEffect()
184 {
185     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
186         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
187     QImage fb = runTest("Effect.qml");
188     QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
189     QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
190 }
191
192
193
194 // The test draws a rectangle and verifies that there is padding on each side
195 // as the source rect spans outside the item. The padding is verified using
196 // a shader that pads transparent to blue. Everything else is red.
197 void tst_QQuickItemLayer::layerSourceRect()
198 {
199     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
200         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
201
202     QImage fb = runTest("SourceRect.qml");
203
204     // Check that the edges are converted to blue
205     QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff));
206     QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0, 0xff));
207     QCOMPARE(fb.pixel(0, fb.height() - 1), qRgb(0, 0, 0xff));
208     QCOMPARE(fb.pixel(fb.width() - 1, fb.height() - 1), qRgb(0, 0, 0xff));
209
210     // The center pixel should be red
211     QCOMPARE(fb.pixel(fb.width() / 2, fb.height() / 2), qRgb(0xff, 0, 0));
212 }
213
214
215
216 // Same as the effect test up above, but this time use the item
217 // directly in a stand alone ShaderEffect
218 void tst_QQuickItemLayer::layerIsTextureProvider()
219 {
220     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
221         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
222     QImage fb = runTest("TextureProvider.qml");
223     QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
224     QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
225 }
226
227
228 void tst_QQuickItemLayer::layerVisibility_data()
229 {
230     QTest::addColumn<bool>("visible");
231     QTest::addColumn<bool>("effect");
232     QTest::addColumn<qreal>("opacity");
233
234     QTest::newRow("!effect, !visible, a=1") << false << false << 1.;
235     QTest::newRow("!effect, visible, a=1") << false << true << 1.;
236     QTest::newRow("effect, !visible, a=1") << true << false << 1.;
237     QTest::newRow("effect, visible, a=1") << true << true << 1.;
238
239     QTest::newRow("!effect, !visible, a=.5") << false << false << .5;
240     QTest::newRow("!effect, visible, a=.5") << false << true << .5;
241     QTest::newRow("effect, !visible, a=.5") << true << false << .5;
242     QTest::newRow("effect, visible, a=.5") << true << true << .5;
243
244     QTest::newRow("!effect, !visible, a=0") << false << false << 0.;
245     QTest::newRow("!effect, visible, a=0") << false << true << 0.;
246     QTest::newRow("effect, !visible, a=0") << true << false << 0.;
247     QTest::newRow("effect, visible, a=0") << true << true << 0.;
248 }
249
250 void tst_QQuickItemLayer::layerVisibility()
251 {
252     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
253         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
254
255     QFETCH(bool, visible);
256     QFETCH(bool, effect);
257     QFETCH(qreal, opacity);
258
259     QQuickView view;
260     view.setSource(testFileUrl("Visible.qml"));
261
262     QQuickItem *child = view.rootItem()->childItems().at(0);
263     child->setProperty("layerVisible", visible);
264     child->setProperty("layerEffect", effect);
265     child->setProperty("layerOpacity", opacity);
266
267     view.show();
268
269     QTest::qWaitForWindowActive(&view);
270
271     QImage fb = view.grabWindow();
272     uint pixel = fb.pixel(0, 0);
273
274     if (!visible || opacity == 0) {
275         QCOMPARE(pixel, qRgb(0xff, 0xff, 0xff));
276     } else if (effect) {
277         QCOMPARE(qRed(pixel), 0xff);
278         QVERIFY(qGreen(pixel) < 0xff);
279         QVERIFY(qBlue(pixel) < 0xff);
280     } else { // no effect
281         QCOMPARE(qBlue(pixel), 0xff);
282         QVERIFY(qGreen(pixel) < 0xff);
283         QVERIFY(qRed(pixel) < 0xff);
284     }
285 }
286
287
288
289
290 void tst_QQuickItemLayer::layerZOrder_data()
291 {
292     QTest::addColumn<bool>("effect");
293
294     QTest::newRow("!effect") << false;
295     QTest::newRow("effect") << true;
296 }
297
298 void tst_QQuickItemLayer::layerZOrder()
299 {
300     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
301         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
302
303     QFETCH(bool, effect);
304
305     QQuickView view;
306     view.setSource(testFileUrl("ZOrder.qml"));
307
308     QQuickItem *child = view.rootItem()->childItems().at(0);
309     child->setProperty("layerEffect", effect);
310
311     view.show();
312
313     QTest::qWaitForWindowShown(&view);
314
315     QImage fb = view.grabWindow();
316
317     QCOMPARE(fb.pixel(50, 50), qRgb(0, 0, 0xff));
318     QCOMPARE(fb.pixel(150, 150), qRgb(0, 0xff, 00));
319
320 }
321
322 void tst_QQuickItemLayer::changeZOrder_data()
323 {
324     QTest::addColumn<bool>("layered");
325     QTest::addColumn<bool>("effect");
326
327     QTest::newRow("layered, effect") << true << true;
328     QTest::newRow("layered, !effect") << true << false;
329     QTest::newRow("!layered") << false << false;
330 }
331
332 void tst_QQuickItemLayer::changeZOrder()
333 {
334     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
335         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
336
337     QFETCH(bool, layered);
338     QFETCH(bool, effect);
339
340     QQuickView view;
341     view.setSource(testFileUrl("ZOrderChange.qml"));
342
343     QQuickItem *child = view.rootItem()->childItems().at(0);
344     child->setProperty("layerEnabled", layered);
345     child->setProperty("layerEffect", effect);
346     child->setProperty("layerZ", 1);
347
348     view.show();
349
350     QTest::qWaitForWindowShown(&view);
351
352     QImage fb = view.grabWindow();
353
354     QRgb topLeft = fb.pixel(50, 50);
355     QRgb topRight = fb.pixel(150, 50);
356     QRgb bottomLeft = fb.pixel(50, 150);
357     QRgb bottomRight = fb.pixel(150, 150);
358
359     QCOMPARE(bottomLeft, qRgb(0, 0, 0xff));
360
361     if (layered) {
362         QCOMPARE(topLeft, qRgb(0, 0xff, 0xff));
363     } else {
364         QCOMPARE(qGreen(topLeft), 0xff);
365         QVERIFY(qAbs(qRed(topLeft) - 0x3f) < 4);
366         QVERIFY(qAbs(qBlue(topLeft) - 0xbf) < 4);
367     }
368
369     if (layered && effect) {
370         QCOMPARE(qRed(topRight), 0xff);
371         QCOMPARE(qGreen(topRight), 0x00);
372         QVERIFY(qAbs(qBlue(topRight) - 0x7f) < 4);
373
374         QVERIFY(qAbs(qRed(bottomRight) - 0x7f) < 4);
375         QCOMPARE(qBlue(bottomRight), 0xff);
376         QVERIFY(qAbs(qGreen(bottomRight) - 0x7f) < 4);
377     } else {
378         QCOMPARE(qRed(topRight), 0xff);
379         QCOMPARE(qBlue(topRight), 0x00);
380         QVERIFY(qAbs(qGreen(topRight) - 0x7f) < 4);
381
382         QVERIFY(qAbs(qRed(bottomRight) - 0x7f) < 4);
383         QCOMPARE(qGreen(bottomRight), 0xff);
384         QVERIFY(qAbs(qBlue(bottomRight) - 0x7f) < 4);
385     }
386 }
387
388 void tst_QQuickItemLayer::toggleLayerAndEffect()
389 {
390     // This test passes if it doesn't crash.
391     runTest("ToggleLayerAndEffect.qml");
392 }
393
394 void tst_QQuickItemLayer::disableLayer()
395 {
396     // This test passes if it doesn't crash.
397     runTest("DisableLayer.qml");
398 }
399
400 void tst_QQuickItemLayer::changeSamplerName()
401 {
402     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
403         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
404     QImage fb = runTest("SamplerNameChange.qml");
405     QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff));
406 }
407
408 void tst_QQuickItemLayer::itemEffect()
409 {
410     if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
411         QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
412     QImage fb = runTest("ItemEffect.qml");
413     QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
414     QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0));
415     QCOMPARE(fb.pixel(0, 199), qRgb(0, 0, 0xff));
416     QCOMPARE(fb.pixel(199, 199), qRgb(0, 0, 0xff));
417 }
418
419 void tst_QQuickItemLayer::rectangleEffect()
420 {
421     QImage fb = runTest("RectangleEffect.qml");
422     QCOMPARE(fb.pixel(0, 0), qRgb(0, 0xff, 0));
423     QCOMPARE(fb.pixel(199, 0), qRgb(0, 0xff, 0));
424     QCOMPARE(fb.pixel(0, 199), qRgb(0, 0xff, 0));
425     QCOMPARE(fb.pixel(199, 199), qRgb(0, 0xff, 0));
426
427     QCOMPARE(fb.pixel(100, 0), qRgb(0, 0, 0xff));
428     QCOMPARE(fb.pixel(199, 100), qRgb(0, 0, 0xff));
429     QCOMPARE(fb.pixel(100, 199), qRgb(0, 0, 0xff));
430     QCOMPARE(fb.pixel(0, 100), qRgb(0, 0, 0xff));
431 }
432
433
434 QTEST_MAIN(tst_QQuickItemLayer)
435
436 #include "tst_qquickitemlayer.moc"