diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2014-12-02 14:01:32 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-10-12 08:30:17 +0000 |
commit | a7c0393b35f213c11e9a20ff773c368e929a63ab (patch) | |
tree | 0df3abb370d659b346750621bfe0b5811f746ce0 /tests/auto/quick/drawingmodes | |
parent | d6dfbe8fd5d09388fc624d85c4aefa0269c20db9 (diff) |
Tests for various OpenGL drawing modes in conjunction with batching
Scene graph batching should not have an effect on how geometry is drawn.
This change introduces some tests to verify that drawing and batching
works correctly.
Change-Id: I1ac50546215adc6a9d17450990757acc4b3ede6f
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'tests/auto/quick/drawingmodes')
-rw-r--r-- | tests/auto/quick/drawingmodes/data/DrawingModes.qml | 14 | ||||
-rw-r--r-- | tests/auto/quick/drawingmodes/drawingmodes.pro | 17 | ||||
-rw-r--r-- | tests/auto/quick/drawingmodes/tst_drawingmodes.cpp | 340 |
3 files changed, 371 insertions, 0 deletions
diff --git a/tests/auto/quick/drawingmodes/data/DrawingModes.qml b/tests/auto/quick/drawingmodes/data/DrawingModes.qml new file mode 100644 index 0000000000..4211f247f8 --- /dev/null +++ b/tests/auto/quick/drawingmodes/data/DrawingModes.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Test 1.0 + +Rectangle { + id: root + + width: 200 + height: 200 + color: "black" + + DrawingModeItem { + anchors.fill: parent + } +} diff --git a/tests/auto/quick/drawingmodes/drawingmodes.pro b/tests/auto/quick/drawingmodes/drawingmodes.pro new file mode 100644 index 0000000000..ff5383b501 --- /dev/null +++ b/tests/auto/quick/drawingmodes/drawingmodes.pro @@ -0,0 +1,17 @@ +CONFIG += testcase +TARGET = tst_drawingmodes +SOURCES += tst_drawingmodes.cpp + +macos:CONFIG -= app_bundle + +TESTDATA = data/* + +include(../../shared/util.pri) + +CONFIG += parallel_test +QT += gui qml quick testlib + +OTHER_FILES += \ + data/DrawingModes.qml + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp new file mode 100644 index 0000000000..d4065e3d38 --- /dev/null +++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <qtest.h> + +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/qsgnode.h> +#include <QtQuick/qsggeometry.h> +#include <QtQuick/qsgflatcolormaterial.h> +#include <QtGui/qscreen.h> +#include <QtGui/qopenglcontext.h> + +#include "../../shared/util.h" + +class tst_drawingmodes : public QQmlDataTest +{ + Q_OBJECT +public: + tst_drawingmodes(); + + bool hasPixelAround(const QImage &fb, int centerX, int centerY); + QImage runTest(const QString &fileName) + { + QQuickView view(&outerWindow); + view.setResizeMode(QQuickView::SizeViewToRootObject); + view.setSource(testFileUrl(fileName)); + view.setVisible(true); + QTest::qWaitForWindowExposed(&view); + return view.grabWindow(); + } + + //It is important for platforms that only are able to show fullscreen windows + //to have a container for the window that is painted on. + QQuickWindow outerWindow; + const QRgb black; + const QRgb red; + +private slots: + void points(); + void lines(); + void lineStrip(); + void lineLoop(); + void triangles(); + void triangleStrip(); + void triangleFan(); +}; + +class DrawingModeItem : public QQuickItem +{ + Q_OBJECT +public: + static GLenum drawingMode; + + DrawingModeItem() : first(QSGGeometry::defaultAttributes_Point2D(), 5), + second(QSGGeometry::defaultAttributes_Point2D(), 5) + { + setFlag(ItemHasContents, true); + material.setColor(Qt::red); + } + +protected: + QSGGeometry first; + QSGGeometry second; + QSGFlatColorMaterial material; + + virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) + { + if (!node) { + QRect bounds(0, 0, 200, 200); + first.setDrawingMode(drawingMode); + second.setDrawingMode(drawingMode); + + QSGGeometry::Point2D *v = first.vertexDataAsPoint2D(); + v[0].set(bounds.width() * 2 / 8, bounds.height() / 2); + v[1].set(bounds.width() / 8, bounds.height() / 4); + v[2].set(bounds.width() * 3 / 8, bounds.height() / 4); + v[3].set(bounds.width() * 3 / 8, bounds.height() * 3 / 4); + v[4].set(bounds.width() / 8, bounds.height() * 3 / 4); + + v = second.vertexDataAsPoint2D(); + v[0].set(bounds.width() * 6 / 8, bounds.height() / 2); + v[1].set(bounds.width() * 5 / 8, bounds.height() / 4); + v[2].set(bounds.width() * 7 / 8, bounds.height() / 4); + v[3].set(bounds.width() * 7 / 8, bounds.height() * 3 / 4); + v[4].set(bounds.width() * 5 / 8, bounds.height() * 3 / 4); + + node = new QSGNode; + QSGGeometryNode *child = new QSGGeometryNode; + child->setGeometry(&first); + child->setMaterial(&material); + node->appendChildNode(child); + child = new QSGGeometryNode; + child->setGeometry(&second); + child->setMaterial(&material); + node->appendChildNode(child); + } + return node; + } +}; + +GLenum DrawingModeItem::drawingMode; + +bool tst_drawingmodes::hasPixelAround(const QImage &fb, int centerX, int centerY) { + for (int x = centerX - 2; x <= centerX + 2; ++x) { + for (int y = centerY - 2; y <= centerY + 2; ++y) { + if (fb.pixel(x, y) == red) + return true; + } + } + return false; +} + +tst_drawingmodes::tst_drawingmodes() : black(qRgb(0, 0, 0)), red(qRgb(0xff, 0, 0)) +{ + qmlRegisterType<DrawingModeItem>("Test", 1, 0, "DrawingModeItem"); + outerWindow.showNormal(); + outerWindow.setGeometry(0,0,400,400); +} + +void tst_drawingmodes::points() +{ + DrawingModeItem::drawingMode = GL_POINTS; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + +#ifdef Q_OS_WIN + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) + QSKIP("ANGLE cannot draw GL_POINTS."); +#endif + + QImage fb = runTest("DrawingModes.qml"); + + QVERIFY(hasPixelAround(fb, 50, 100)); + QVERIFY(hasPixelAround(fb, 25, 50)); + QVERIFY(hasPixelAround(fb, 75, 50)); + QVERIFY(hasPixelAround(fb, 75, 150)); + QVERIFY(hasPixelAround(fb, 25, 150)); + + QVERIFY(hasPixelAround(fb, 150, 100)); + QVERIFY(hasPixelAround(fb, 125, 50)); + QVERIFY(hasPixelAround(fb, 175, 50)); + QVERIFY(hasPixelAround(fb, 175, 150)); + QVERIFY(hasPixelAround(fb, 125, 150)); + + QVERIFY(!hasPixelAround(fb, 135, 70)); + QVERIFY(!hasPixelAround(fb, 175, 100)); + QVERIFY(!hasPixelAround(fb, 110, 140)); + QVERIFY(!hasPixelAround(fb, 50, 50)); + QVERIFY(!hasPixelAround(fb, 50, 150)); + QVERIFY(!hasPixelAround(fb, 25, 100)); + QVERIFY(!hasPixelAround(fb, 75, 100)); + QVERIFY(!hasPixelAround(fb, 125, 100)); + QVERIFY(!hasPixelAround(fb, 150, 50)); + QVERIFY(!hasPixelAround(fb, 150, 150)); + QVERIFY(!hasPixelAround(fb, 135, 130)); + QVERIFY(!hasPixelAround(fb, 35, 130)); +} + +void tst_drawingmodes::lines() +{ + DrawingModeItem::drawingMode = GL_LINES; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 135, 70)); + QVERIFY(hasPixelAround(fb, 175, 100)); + QVERIFY(!hasPixelAround(fb, 110, 140)); + QVERIFY(!hasPixelAround(fb, 50, 50)); + QVERIFY(!hasPixelAround(fb, 50, 150)); + + QVERIFY(hasPixelAround(fb, 35, 70)); + QVERIFY(hasPixelAround(fb, 75, 100)); + QVERIFY(!hasPixelAround(fb, 25, 100)); + QVERIFY(!hasPixelAround(fb, 125, 100)); + QVERIFY(!hasPixelAround(fb, 150, 50)); + QVERIFY(!hasPixelAround(fb, 150, 150)); + QVERIFY(!hasPixelAround(fb, 135, 130)); + QVERIFY(!hasPixelAround(fb, 35, 130)); +} + +void tst_drawingmodes::lineStrip() +{ + DrawingModeItem::drawingMode = GL_LINE_STRIP; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 135, 70)); + QVERIFY(hasPixelAround(fb, 150, 50)); + QVERIFY(hasPixelAround(fb, 175, 100)); + QVERIFY(hasPixelAround(fb, 150, 150)); + + QVERIFY(hasPixelAround(fb, 35, 70)); + QVERIFY(hasPixelAround(fb, 50, 50)); + QVERIFY(hasPixelAround(fb, 75, 100)); + QVERIFY(hasPixelAround(fb, 50, 150)); + + QVERIFY(!hasPixelAround(fb, 110, 140)); // bad line not there => line strip unbatched + + QVERIFY(!hasPixelAround(fb, 25, 100)); + QVERIFY(!hasPixelAround(fb, 125, 100)); + QVERIFY(!hasPixelAround(fb, 135, 130)); + QVERIFY(!hasPixelAround(fb, 35, 130)); +} + +void tst_drawingmodes::lineLoop() +{ + DrawingModeItem::drawingMode = GL_LINE_LOOP; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 135, 70)); + QVERIFY(hasPixelAround(fb, 135, 130)); + QVERIFY(hasPixelAround(fb, 150, 50)); + QVERIFY(hasPixelAround(fb, 175, 100)); + QVERIFY(hasPixelAround(fb, 150, 150)); + + QVERIFY(hasPixelAround(fb, 35, 70)); + QVERIFY(hasPixelAround(fb, 35, 130)); + QVERIFY(hasPixelAround(fb, 50, 50)); + QVERIFY(hasPixelAround(fb, 75, 100)); + QVERIFY(hasPixelAround(fb, 50, 150)); + + QVERIFY(!hasPixelAround(fb, 110, 140)); // bad line not there => line loop unbatched + + QVERIFY(!hasPixelAround(fb, 25, 100)); + QVERIFY(!hasPixelAround(fb, 125, 100)); +} + +void tst_drawingmodes::triangles() +{ + DrawingModeItem::drawingMode = GL_TRIANGLES; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 150, 75)); + QVERIFY(!hasPixelAround(fb, 162, 100)); + QVERIFY(!hasPixelAround(fb, 150, 125)); + QVERIFY(!hasPixelAround(fb, 137, 100)); + + QVERIFY(!hasPixelAround(fb, 100, 125)); + + QVERIFY(hasPixelAround(fb, 50, 75)); + QVERIFY(!hasPixelAround(fb, 62, 100)); + QVERIFY(!hasPixelAround(fb, 50, 125)); + QVERIFY(!hasPixelAround(fb, 37, 100)); +} + + +void tst_drawingmodes::triangleStrip() +{ + DrawingModeItem::drawingMode = GL_TRIANGLE_STRIP; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 150, 75)); + QVERIFY(hasPixelAround(fb, 162, 100)); + QVERIFY(hasPixelAround(fb, 150, 125)); + QVERIFY(!hasPixelAround(fb, 137, 100)); + + QVERIFY(!hasPixelAround(fb, 100, 125)); // batching avoids extra triangle by duplicating vertices. + + QVERIFY(hasPixelAround(fb, 50, 75)); + QVERIFY(hasPixelAround(fb, 62, 100)); + QVERIFY(hasPixelAround(fb, 50, 125)); + QVERIFY(!hasPixelAround(fb, 37, 100)); +} + +void tst_drawingmodes::triangleFan() +{ + DrawingModeItem::drawingMode = GL_TRIANGLE_FAN; + if (QGuiApplication::primaryScreen()->depth() < 24) + QSKIP("This test does not work at display depths < 24"); + QImage fb = runTest("DrawingModes.qml"); + + QCOMPARE(fb.width(), 200); + QCOMPARE(fb.height(), 200); + + QVERIFY(hasPixelAround(fb, 150, 75)); + QVERIFY(hasPixelAround(fb, 162, 100)); + QVERIFY(hasPixelAround(fb, 150, 125)); + QVERIFY(!hasPixelAround(fb, 137, 100)); + + QVERIFY(!hasPixelAround(fb, 100, 125)); // no extra triangle; triangle fan is not batched + + QVERIFY(hasPixelAround(fb, 50, 75)); + QVERIFY(hasPixelAround(fb, 62, 100)); + QVERIFY(hasPixelAround(fb, 50, 125)); + QVERIFY(!hasPixelAround(fb, 37, 100)); +} + + +QTEST_MAIN(tst_drawingmodes) + +#include "tst_drawingmodes.moc" |