/**************************************************************************** ** ** 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 #include #include #include #include #if QT_CONFIG(opengl) #include #else #include #endif class tst_QQuickPaintedItem: public QObject { Q_OBJECT private slots: void initTestCase(); void update(); void opaquePainting(); void antialiasing(); void mipmap(); void performanceHints(); void contentsSize(); void contentScale(); void contentsBoundingRect(); void fillColor(); void renderTarget(); private: QQuickWindow window; }; class TestPaintedItem : public QQuickPaintedItem { Q_OBJECT public: TestPaintedItem(QQuickItem *parent = nullptr) : QQuickPaintedItem(parent) , paintNode(nullptr) , paintRequests(0) { } void paint(QPainter *painter) { ++paintRequests; clipRect = painter->clipBoundingRect(); } #if QT_CONFIG(opengl) QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { paintNode = static_cast(QQuickPaintedItem::updatePaintNode(oldNode, data)); return paintNode; } QSGDefaultPainterNode *paintNode; #else QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { paintNode = static_cast(QQuickPaintedItem::updatePaintNode(oldNode, data)); return paintNode; } QSGSoftwarePainterNode *paintNode; #endif int paintRequests; QRectF clipRect; }; static bool hasDirtyContentFlag(QQuickItem *item) { return QQuickItemPrivate::get(item)->dirtyAttributes & QQuickItemPrivate::Content; } static void clearDirtyContentFlag(QQuickItem *item) { QQuickItemPrivate::get(item)->dirtyAttributes &= ~QQuickItemPrivate::Content; } void tst_QQuickPaintedItem::initTestCase() { window.resize(320, 240); window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); } void tst_QQuickPaintedItem::update() { TestPaintedItem item; item.setParentItem(window.contentItem()); QCOMPARE(hasDirtyContentFlag(&item), false); item.update(); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(item.paintRequests, 0); // Size empty item.setSize(QSizeF(320, 240)); item.update(); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(item.paintRequests, 1); QCOMPARE(item.clipRect, QRectF(0, 0, 0, 0)); item.update(QRect(30, 25, 12, 11)); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(item.paintRequests, 2); QCOMPARE(item.clipRect, QRectF(30, 25, 12, 11)); item.update(QRect(30, 25, 12, 11)); item.update(QRect(112, 56, 20, 20)); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(item.paintRequests, 3); QCOMPARE(item.clipRect, QRectF(30, 25, 102, 51)); } void tst_QQuickPaintedItem::opaquePainting() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QCOMPARE(item.opaquePainting(), false); item.setOpaquePainting(false); QCOMPARE(item.opaquePainting(), false); QCOMPARE(hasDirtyContentFlag(&item), false); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->opaquePainting(), false); item.setOpaquePainting(true); QCOMPARE(item.opaquePainting(), true); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->opaquePainting(), true); item.setOpaquePainting(true); QCOMPARE(item.opaquePainting(), true); QCOMPARE(hasDirtyContentFlag(&item), false); item.setOpaquePainting(false); QCOMPARE(item.opaquePainting(), false); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->opaquePainting(), false); } void tst_QQuickPaintedItem::antialiasing() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QCOMPARE(item.antialiasing(), false); item.setAntialiasing(false); QCOMPARE(item.antialiasing(), false); QCOMPARE(hasDirtyContentFlag(&item), false); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->smoothPainting(), false); item.setAntialiasing(true); QCOMPARE(item.antialiasing(), true); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->smoothPainting(), true); item.setAntialiasing(true); QCOMPARE(item.antialiasing(), true); QCOMPARE(hasDirtyContentFlag(&item), false); item.setAntialiasing(false); QCOMPARE(item.antialiasing(), false); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->smoothPainting(), false); } void tst_QQuickPaintedItem::mipmap() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QCOMPARE(item.mipmap(), false); item.setMipmap(false); QCOMPARE(item.mipmap(), false); QCOMPARE(hasDirtyContentFlag(&item), false); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->mipmapping(), false); item.setMipmap(true); QCOMPARE(item.mipmap(), true); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->mipmapping(), true); item.setMipmap(true); QCOMPARE(item.mipmap(), true); QCOMPARE(hasDirtyContentFlag(&item), false); item.setMipmap(false); QCOMPARE(item.mipmap(), false); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->mipmapping(), false); } void tst_QQuickPaintedItem::performanceHints() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QCOMPARE(item.performanceHints(), QQuickPaintedItem::PerformanceHints()); item.setPerformanceHints(QQuickPaintedItem::PerformanceHints()); QCOMPARE(item.performanceHints(), QQuickPaintedItem::PerformanceHints()); QCOMPARE(hasDirtyContentFlag(&item), false); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fastFBOResizing(), false); item.setPerformanceHints(QQuickPaintedItem::PerformanceHints(QQuickPaintedItem::FastFBOResizing)); QCOMPARE(item.performanceHints(), QQuickPaintedItem::PerformanceHints(QQuickPaintedItem::FastFBOResizing)); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fastFBOResizing(), true); item.setPerformanceHint(QQuickPaintedItem::FastFBOResizing, true); QCOMPARE(item.performanceHints(), QQuickPaintedItem::PerformanceHints(QQuickPaintedItem::FastFBOResizing)); QCOMPARE(hasDirtyContentFlag(&item), false); item.setPerformanceHint(QQuickPaintedItem::FastFBOResizing, false); QCOMPARE(item.performanceHints(), QQuickPaintedItem::PerformanceHints()); QCOMPARE(hasDirtyContentFlag(&item), true); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fastFBOResizing(), false); } void tst_QQuickPaintedItem::contentsSize() { TestPaintedItem item; QSignalSpy spy(&item, SIGNAL(contentsSizeChanged())); QCOMPARE(item.contentsSize(), QSize()); item.setContentsSize(QSize()); QCOMPARE(item.contentsSize(), QSize()); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 0); item.setContentsSize(QSize(320, 240)); QCOMPARE(item.contentsSize(), QSize(320, 240)); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 1); clearDirtyContentFlag(&item); item.setContentsSize(QSize(320, 240)); QCOMPARE(item.contentsSize(), QSize(320, 240)); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 1); item.resetContentsSize(); QCOMPARE(item.contentsSize(), QSize()); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 2); } void tst_QQuickPaintedItem::contentScale() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QSignalSpy spy(&item, SIGNAL(contentsScaleChanged())); QCOMPARE(item.contentsScale(), 1.); item.setContentsScale(1.); QCOMPARE(item.contentsScale(), 1.); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 0); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->contentsScale(), 1.0); item.setContentsScale(0.4); QCOMPARE(item.contentsScale(), 0.4); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 1); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->contentsScale(), 0.4); item.setContentsScale(0.4); QCOMPARE(item.contentsScale(), 0.4); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 1); item.setContentsScale(2.5); QCOMPARE(item.contentsScale(), 2.5); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 2); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->contentsScale(), 2.5); } void tst_QQuickPaintedItem::contentsBoundingRect() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QCOMPARE(item.contentsBoundingRect(), QRectF(0, 0, 320, 240)); item.setContentsSize(QSize(500, 500)); QCOMPARE(item.contentsBoundingRect(), QRectF(0, 0, 500, 500)); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->size(), QSize(500, 500)); item.setContentsScale(0.5); QCOMPARE(item.contentsBoundingRect(), QRectF(0, 0, 320, 250)); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->size(), QSize(320, 250)); item.setContentsSize(QSize(150, 150)); QCOMPARE(item.contentsBoundingRect(), QRectF(0, 0, 320, 240)); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->size(), QSize(320, 240)); item.setContentsScale(2.0); QCOMPARE(item.contentsBoundingRect(), QRectF(0, 0, 320, 300)); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->size(), QSize(320, 300)); } void tst_QQuickPaintedItem::fillColor() { TestPaintedItem item; item.setSize(QSizeF(320, 240)); item.setParentItem(window.contentItem()); QSignalSpy spy(&item, SIGNAL(fillColorChanged())); QCOMPARE(item.fillColor(), QColor(Qt::transparent)); item.setFillColor(QColor(Qt::transparent)); QCOMPARE(item.fillColor(), QColor(Qt::transparent)); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 0); item.update(); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fillColor(), QColor(Qt::transparent)); item.setFillColor(QColor(Qt::green)); QCOMPARE(item.fillColor(), QColor(Qt::green)); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 1); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fillColor(), QColor(Qt::green)); item.setFillColor(QColor(Qt::green)); QCOMPARE(item.fillColor(), QColor(Qt::green)); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 1); item.setFillColor(QColor(Qt::blue)); QCOMPARE(item.fillColor(), QColor(Qt::blue)); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 2); QTRY_COMPARE(hasDirtyContentFlag(&item), false); QVERIFY(item.paintNode); QCOMPARE(item.paintNode->fillColor(), QColor(Qt::blue)); } void tst_QQuickPaintedItem::renderTarget() { TestPaintedItem item; QSignalSpy spy(&item, SIGNAL(renderTargetChanged())); QCOMPARE(item.renderTarget(), QQuickPaintedItem::Image); item.setRenderTarget(QQuickPaintedItem::Image); QCOMPARE(item.renderTarget(), QQuickPaintedItem::Image); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 0); item.setRenderTarget(QQuickPaintedItem::FramebufferObject); QCOMPARE(item.renderTarget(), QQuickPaintedItem::FramebufferObject); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 1); clearDirtyContentFlag(&item); item.setRenderTarget(QQuickPaintedItem::FramebufferObject); QCOMPARE(item.renderTarget(), QQuickPaintedItem::FramebufferObject); QCOMPARE(hasDirtyContentFlag(&item), false); QCOMPARE(spy.count(), 1); item.setRenderTarget(QQuickPaintedItem::InvertedYFramebufferObject); QCOMPARE(item.renderTarget(), QQuickPaintedItem::InvertedYFramebufferObject); QCOMPARE(hasDirtyContentFlag(&item), true); QCOMPARE(spy.count(), 2); } QTEST_MAIN(tst_QQuickPaintedItem) #include "tst_qquickpainteditem.moc"