diff options
Diffstat (limited to 'tests/auto/gui')
18 files changed, 644 insertions, 102 deletions
diff --git a/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro b/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro index 17553158bc..49c615721b 100644 --- a/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro +++ b/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro @@ -1,5 +1,5 @@ CONFIG += testcase -TARGET = tst_qicon +TARGET = tst_qiconhighdpi QT += testlib SOURCES += tst_qiconhighdpi.cpp diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 60f89fcb4e..34de756ab5 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -1031,6 +1031,23 @@ public: Qt::MouseButtons buttonStateInGeneratedMove; }; +static void simulateMouseClick(QWindow *target, const QPointF &local, const QPointF &global) +{ + QWindowSystemInterface::handleMouseEvent(target, local, global, + {}, Qt::LeftButton, QEvent::MouseButtonPress); + QWindowSystemInterface::handleMouseEvent(target, local, global, + Qt::LeftButton, Qt::LeftButton, QEvent::MouseButtonRelease); +} + +static void simulateMouseClick(QWindow *target, ulong &timeStamp, + const QPointF &local, const QPointF &global) +{ + QWindowSystemInterface::handleMouseEvent(target, timeStamp++, local, global, + {}, Qt::LeftButton, QEvent::MouseButtonPress); + QWindowSystemInterface::handleMouseEvent(target, timeStamp++, local, global, + Qt::LeftButton, Qt::LeftButton, QEvent::MouseButtonRelease); +} + void tst_QWindow::testInputEvents() { InputTestWindow window; @@ -1072,15 +1089,13 @@ void tst_QWindow::testInputEvents() window.mousePressButton = window.mouseReleaseButton = 0; const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen()); - QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton); + simulateMouseClick(nullptr, deviceNonWindowGlobal, deviceNonWindowGlobal); QCoreApplication::processEvents(); QCOMPARE(window.mousePressButton, 0); QCOMPARE(window.mouseReleaseButton, 0); const QPointF windowGlobal = window.mapToGlobal(local.toPoint()); const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen()); - QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(nullptr, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton); + simulateMouseClick(nullptr, deviceWindowGlobal, deviceWindowGlobal); QCoreApplication::processEvents(); QCOMPARE(window.mousePressButton, int(Qt::LeftButton)); QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton)); @@ -1204,8 +1219,7 @@ void tst_QWindow::mouseToTouchTranslation() window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); + QTest::mouseClick(&window, Qt::LeftButton, {}, QPoint(10, 10)); QCoreApplication::processEvents(); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); @@ -1217,8 +1231,7 @@ void tst_QWindow::mouseToTouchTranslation() window.ignoreMouse = false; - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); + QTest::mouseClick(&window, Qt::LeftButton, {}, QPoint(10, 10)); QCoreApplication::processEvents(); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); @@ -1229,8 +1242,7 @@ void tst_QWindow::mouseToTouchTranslation() window.ignoreMouse = true; - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); + QTest::mouseClick(&window, Qt::LeftButton, {}, QPoint(10, 10)); QCoreApplication::processEvents(); // touch event synthesis disabled @@ -1255,8 +1267,7 @@ void tst_QWindow::mouseToTouchLoop() window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton); + QTest::mouseClick(&window, Qt::LeftButton, {}, QPoint(10, 10)); QCoreApplication::processEvents(); QCoreApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false); @@ -1551,8 +1562,8 @@ void tst_QWindow::mouseEventSequence() ulong timestamp = 0; QPointF local(12, 34); const QPointF deviceLocal = QHighDpi::toNativePixels(local, &window); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::NoButton); + + simulateMouseClick(&window, timestamp, deviceLocal, deviceLocal); QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 1); QCOMPARE(window.mouseReleasedCount, 1); @@ -1564,10 +1575,8 @@ void tst_QWindow::mouseEventSequence() // A double click must result in press, release, press, doubleclick, release. // Check that no unexpected event suppression occurs and that the order is correct. - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 2); QCOMPARE(window.mouseReleasedCount, 2); @@ -1578,12 +1587,9 @@ void tst_QWindow::mouseEventSequence() window.resetCounters(); // Triple click = double + single click - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 3); QCOMPARE(window.mouseReleasedCount, 3); @@ -1594,14 +1600,10 @@ void tst_QWindow::mouseEventSequence() window.resetCounters(); // Two double clicks. - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); + simulateMouseClick(&window, timestamp, local, local); QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 4); QCOMPARE(window.mouseReleasedCount, 4); @@ -1612,17 +1614,13 @@ void tst_QWindow::mouseEventSequence() window.resetCounters(); // Four clicks, none of which qualifies as a double click. - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); timestamp += doubleClickInterval; - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); timestamp += doubleClickInterval; - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); timestamp += doubleClickInterval; - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton); + simulateMouseClick(&window, timestamp, local, local); timestamp += doubleClickInterval; QCoreApplication::processEvents(); QCOMPARE(window.mousePressedCount, 4); @@ -1674,10 +1672,13 @@ void tst_QWindow::inputReentrancy() // Queue three events. QPointF local(12, 34); - QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton); + QWindowSystemInterface::handleMouseEvent(&window, local, local, {}, + Qt::LeftButton, QEvent::MouseButtonPress); local += QPointF(2, 2); - QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::NoButton); + QWindowSystemInterface::handleMouseEvent(&window, local, local, + Qt::LeftButton, Qt::LeftButton, QEvent::MouseMove); + QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton, + Qt::LeftButton, QEvent::MouseButtonRelease); // Process them. However, the event handler for the press will also call // processEvents() so the move and release will be delivered before returning // from mousePressEvent(). The point is that no events should get lost. @@ -1747,12 +1748,14 @@ void tst_QWindow::tabletEvents() const QPoint global = window.mapToGlobal(local); const QPoint deviceLocal = QHighDpi::toNativeLocalPosition(local, &window); const QPoint deviceGlobal = QHighDpi::toNativePixels(global, window.screen()); - QWindowSystemInterface::handleTabletEvent(&window, true, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); + QWindowSystemInterface::handleTabletEvent(&window, deviceLocal, deviceGlobal, + 1, 2, Qt::LeftButton, 0.5, 1, 2, 0.1, 0, 0, 0); QCoreApplication::processEvents(); QTRY_VERIFY(window.eventType == QEvent::TabletPress); QTRY_COMPARE(window.eventGlobal.toPoint(), global); QTRY_COMPARE(window.eventLocal.toPoint(), local); - QWindowSystemInterface::handleTabletEvent(&window, false, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0); + QWindowSystemInterface::handleTabletEvent(&window, deviceLocal, deviceGlobal, 1, 2, + {}, 0.5, 1, 2, 0.1, 0, 0, 0); QCoreApplication::processEvents(); QTRY_COMPARE(window.eventType, QEvent::TabletRelease); @@ -1788,11 +1791,9 @@ void tst_QWindow::windowModality_QTBUG27039() modalB.setModality(Qt::ApplicationModal); modalB.show(); - QPointF local(5, 5); - QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton); - QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::NoButton); + QPoint local(5, 5); + QTest::mouseClick(&modalA, Qt::LeftButton, {}, local); + QTest::mouseClick(&modalB, Qt::LeftButton, {}, local); QCoreApplication::processEvents(); // modal A should be blocked since it was shown first, but modal B should not be blocked @@ -1800,8 +1801,7 @@ void tst_QWindow::windowModality_QTBUG27039() QCOMPARE(modalA.mousePressedCount, 0); modalB.hide(); - QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton); - QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton); + QTest::mouseClick(&modalA, Qt::LeftButton, {}, local); QCoreApplication::processEvents(); // modal B has been hidden, modal A should be unblocked again diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 6e48439944..e05de64be5 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -715,7 +715,7 @@ void tst_QPainter::drawBorderPixmap() QPainter p(&pm); p.setTransform(QTransform(-1,0,0,-1,173.5,153.5)); qDrawBorderPixmap(&p, QRect(0,0,75,105), QMargins(39,39,39,39), src, QRect(0,0,79,79), QMargins(39,39,39,39), - QTileRules(Qt::StretchTile,Qt::StretchTile), 0); + QTileRules(Qt::StretchTile,Qt::StretchTile), { }); } #endif @@ -1739,7 +1739,7 @@ void tst_QPainter::renderHints() // Turn off all... p.setRenderHints(QPainter::RenderHints(0xffffffff), false); - QCOMPARE(p.renderHints(), QPainter::RenderHints(0)); + QCOMPARE(p.renderHints(), QPainter::RenderHints{}); // Single set/get p.setRenderHint(QPainter::Antialiasing); diff --git a/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp b/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp index 9e9b0db366..b2b2b685ae 100644 --- a/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp +++ b/tests/auto/gui/painting/qpdfwriter/tst_qpdfwriter.cpp @@ -73,12 +73,12 @@ void tst_QPdfWriter::basics() QCOMPARE(writer.pageSize(), QPdfWriter::A5); QCOMPARE(writer.pageSizeMM(), QSizeF(148, 210)); - writer.setPageSize(QPdfWriter::A3); + writer.setPageSize(QPageSize(QPageSize::A3)); QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A3); QCOMPARE(writer.pageSize(), QPdfWriter::A3); QCOMPARE(writer.pageSizeMM(), QSizeF(297, 420)); - writer.setPageSizeMM(QSize(210, 297)); + writer.setPageSize(QPageSize(QSize(210, 297), QPageSize::Millimeter)); QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::A4); QCOMPARE(writer.pageSize(), QPdfWriter::A4); QCOMPARE(writer.pageSizeMM(), QSizeF(210, 297)); @@ -101,9 +101,9 @@ void tst_QPdfWriter::basics() QCOMPARE(writer.margins().right, 20.0); QCOMPARE(writer.margins().top, 20.0); QCOMPARE(writer.margins().bottom, 20.0); - QPdfWriter::Margins margins = {50, 50, 50, 50}; - writer.setMargins(margins); - QCOMPARE(writer.pageLayout().margins(), QMarginsF(50, 50, 50, 50)); + const QMarginsF margins = {50, 50, 50, 50}; + writer.setPageMargins(margins, QPageLayout::Millimeter); + QCOMPARE(writer.pageLayout().margins(), margins); QCOMPARE(writer.pageLayout().units(), QPageLayout::Millimeter); QCOMPARE(writer.margins().left, 50.0); QCOMPARE(writer.margins().right, 50.0); @@ -117,7 +117,7 @@ void tst_QPdfWriter::basics() // Test the old page metrics methods, see also QPrinter tests for the same. void tst_QPdfWriter::testPageMetrics_data() { - QTest::addColumn<int>("pageSize"); + QTest::addColumn<QPageSize::PageSizeId>("pageSizeId"); QTest::addColumn<qreal>("widthMMf"); QTest::addColumn<qreal>("heightMMf"); QTest::addColumn<bool>("setMargins"); @@ -126,17 +126,24 @@ void tst_QPdfWriter::testPageMetrics_data() QTest::addColumn<qreal>("topMMf"); QTest::addColumn<qreal>("bottomMMf"); - QTest::newRow("A4") << int(QPdfWriter::A4) << 210.0 << 297.0 << false << 3.53 << 3.53 << 3.53 << 3.53; - QTest::newRow("A4 Margins") << int(QPdfWriter::A4) << 210.0 << 297.0 << true << 20.0 << 30.0 << 40.0 << 50.0; - QTest::newRow("Portrait") << -1 << 345.0 << 678.0 << false << 3.53 << 3.53 << 3.53 << 3.53; - QTest::newRow("Portrait Margins") << -1 << 345.0 << 678.0 << true << 20.0 << 30.0 << 40.0 << 50.0; - QTest::newRow("Landscape") << -1 << 678.0 << 345.0 << false << 3.53 << 3.53 << 3.53 << 3.53; - QTest::newRow("Landscape Margins") << -1 << 678.0 << 345.0 << true << 20.0 << 30.0 << 40.0 << 50.0; + QTest::newRow("A4") << QPageSize::A4 << 210.0 << 297.0 << false + << 3.53 << 3.53 << 3.53 << 3.53; + QTest::newRow("A4 Margins") << QPageSize::A4 << 210.0 << 297.0 << true + << 20.0 << 30.0 << 40.0 << 50.0; + + QTest::newRow("Portrait") << QPageSize::Custom << 345.0 << 678.0 << false + << 3.53 << 3.53 << 3.53 << 3.53; + QTest::newRow("Portrait Margins") << QPageSize::Custom << 345.0 << 678.0 << true + << 20.0 << 30.0 << 40.0 << 50.0; + QTest::newRow("Landscape") << QPageSize::Custom << 678.0 << 345.0 << false + << 3.53 << 3.53 << 3.53 << 3.53; + QTest::newRow("Landscape Margins") << QPageSize::Custom << 678.0 << 345.0 << true + << 20.0 << 30.0 << 40.0 << 50.0; } void tst_QPdfWriter::testPageMetrics() { - QFETCH(int, pageSize); + QFETCH(QPageSize::PageSizeId, pageSizeId); QFETCH(qreal, widthMMf); QFETCH(qreal, heightMMf); QFETCH(bool, setMargins); @@ -161,17 +168,13 @@ void tst_QPdfWriter::testPageMetrics() QCOMPARE(writer.margins().bottom, bottomMMf); } - // Set the given size, in Portrait mode - if (pageSize < 0) { - writer.setPageSize(QPageSize(sizeMMf, QPageSize::Millimeter)); - QCOMPARE(writer.pageSize(), QPdfWriter::Custom); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::Custom); - } else { - writer.setPageSize(QPdfWriter::PageSize(pageSize)); - QCOMPARE(writer.pageSize(), QPdfWriter::PageSize(pageSize)); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize)); - } + const QPageSize pageSize = pageSizeId == QPageSize::Custom + ? QPageSize(sizeMMf, QPageSize::Millimeter) : QPageSize(pageSizeId); + writer.setPageSize(pageSize); + QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId); + QCOMPARE(int(writer.pageSize()), int(pageSizeId)); + QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Portrait); QCOMPARE(writer.margins().left, leftMMf); QCOMPARE(writer.margins().right, rightMMf); @@ -187,13 +190,8 @@ void tst_QPdfWriter::testPageMetrics() // Now switch to Landscape mode, size should be unchanged, but rect and metrics should change writer.setPageOrientation(QPageLayout::Landscape); - if (pageSize < 0) { - QCOMPARE(writer.pageSize(), QPdfWriter::Custom); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::Custom); - } else { - QCOMPARE(writer.pageSize(), QPdfWriter::PageSize(pageSize)); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize)); - } + QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId); + QCOMPARE(int(writer.pageSize()), int(pageSizeId)); QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Landscape); QCOMPARE(writer.margins().left, leftMMf); QCOMPARE(writer.margins().right, rightMMf); @@ -215,15 +213,9 @@ void tst_QPdfWriter::testPageMetrics() // Now while in Landscape mode, set the size again, results should be the same - if (pageSize < 0) { - writer.setPageSize(QPageSize(sizeMMf, QPageSize::Millimeter)); - QCOMPARE(writer.pageSize(), QPdfWriter::Custom); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::Custom); - } else { - writer.setPageSize(QPdfWriter::PageSize(pageSize)); - QCOMPARE(writer.pageSize(), QPdfWriter::PageSize(pageSize)); - QCOMPARE(writer.pageLayout().pageSize().id(), QPageSize::PageSizeId(pageSize)); - } + writer.setPageSize(pageSize); + QCOMPARE(writer.pageLayout().pageSize().id(), pageSizeId); + QCOMPARE(int(writer.pageSize()), int(pageSizeId)); QCOMPARE(writer.pageLayout().orientation(), QPageLayout::Landscape); QCOMPARE(writer.margins().left, leftMMf); QCOMPARE(writer.margins().right, rightMMf); diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 533d6b17b1..302630ae15 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -52,7 +52,7 @@ # define TST_D3D11 #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) # include <QtGui/private/qrhimetal_p.h> # define TST_MTL #endif @@ -91,6 +91,10 @@ private slots: void renderToTextureTexturedQuadAndUniformBuffer(); void renderToWindowSimple_data(); void renderToWindowSimple(); + void srbLayoutCompatibility_data(); + void srbLayoutCompatibility(); + void renderPassDescriptorCompatibility_data(); + void renderPassDescriptorCompatibility(); private: struct { @@ -1728,5 +1732,318 @@ void tst_QRhi::renderToWindowSimple() QVERIFY(redCount < blueCount); } +void tst_QRhi::srbLayoutCompatibility_data() +{ + rhiTestData(); +} + +void tst_QRhi::srbLayoutCompatibility() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr)); + if (!rhi) + QSKIP("QRhi could not be created, skipping testing texture resource updates"); + + QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512))); + QVERIFY(texture->build()); + QScopedPointer<QRhiSampler> sampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); + QVERIFY(sampler->build()); + QScopedPointer<QRhiSampler> otherSampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); + QVERIFY(otherSampler->build()); + QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 1024)); + QVERIFY(buf->build()); + QScopedPointer<QRhiBuffer> otherBuf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256)); + QVERIFY(otherBuf->build()); + + // empty (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different count (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::sampledTexture(0, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // full match (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different visibility (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, buf.data()), + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // different binding points (not compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(1, QRhiShaderResourceBinding::VertexStage, buf.data()), + }); + QVERIFY(srb2->build()); + + QVERIFY(!srb1->isLayoutCompatible(srb2.data())); + QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + } + + // different buffer region offset and size (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data(), rhi->ubufAligned(1), 128), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } + + // different resources (compatible) + { + QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings()); + srb1->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, otherBuf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), otherSampler.data()) + }); + QVERIFY(srb1->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings()); + srb2->setBindings({ + QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data()) + }); + QVERIFY(srb2->build()); + + QVERIFY(srb1->isLayoutCompatible(srb2.data())); + QVERIFY(srb2->isLayoutCompatible(srb1.data())); + } +} + +void tst_QRhi::renderPassDescriptorCompatibility_data() +{ + rhiTestData(); +} + +void tst_QRhi::renderPassDescriptorCompatibility() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr)); + if (!rhi) + QSKIP("QRhi could not be created, skipping testing texture resource updates"); + + // Note that checking compatibility is only relevant with backends where + // there is a concept of renderpass descriptions (Vulkan, and partially + // Metal). It is perfectly fine for isCompatible() to always return true + // when that is not the case (D3D11, OpenGL). Hence the 'if (Vulkan or + // Metal)' for all the negative tests. Also note "partial" for Metal: + // resolve textures for examples have no effect on compatibility with Metal. + + // tex and tex2 have the same format + QScopedPointer<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex->build()); + QScopedPointer<QRhiTexture> tex2(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex2->build()); + + QScopedPointer<QRhiRenderBuffer> ds(rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, QSize(512, 512))); + QVERIFY(ds->build()); + + // two texture rendertargets with tex and tex2 as color0 (compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex2.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // two texture rendertargets with tex and tex2 as color0, and a depth-stencil attachment as well (compatible) + { + QRhiTextureRenderTargetDescription desc({ tex.data() }, ds.data()); + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget(desc)); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget(desc)); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // now one of them does not have the ds attachment (not compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ { tex.data() }, ds.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan || impl == QRhi::Metal) { + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + + if (rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer)) { + // resolve attachments (compatible) + { + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer->build()); + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer2->build()); + + QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample + colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample + colorAtt2.setResolveTexture(tex2.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + QVERIFY(rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(rpDesc2->isCompatible(rpDesc.data())); + } + + // missing resolve for one of them (not compatible) + { + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer->build()); + QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4)); + QVERIFY(msaaRenderBuffer2->build()); + + QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample + colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan) { // no Metal here + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + } else { + qDebug("Skipping multisample renderbuffer dependent tests"); + } + + if (rhi->isTextureFormatSupported(QRhiTexture::RGBA32F)) { + QScopedPointer<QRhiTexture> tex3(rhi->newTexture(QRhiTexture::RGBA32F, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(tex3->build()); + + // different texture formats (not compatible) + { + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex3.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor()); + rt2->setRenderPassDescriptor(rpDesc2.data()); + QVERIFY(rt2->build()); + + if (impl == QRhi::Vulkan || impl == QRhi::Metal) { + QVERIFY(!rpDesc->isCompatible(rpDesc2.data())); + QVERIFY(!rpDesc2->isCompatible(rpDesc.data())); + } + } + } else { + qDebug("Skipping texture format dependent tests"); + } +} + #include <tst_qrhi.moc> QTEST_MAIN(tst_QRhi) diff --git a/tests/auto/gui/rhi/qshader/data/README b/tests/auto/gui/rhi/qshader/data/README new file mode 100644 index 0000000000..3d89f2a0c5 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/README @@ -0,0 +1,15 @@ +Warning: Do NOT regenerate the .qsb files without proper planning and understanding +the following. + +Among other things, we are also testing backwards compatibility for QShader +deserialization. + +.qsb files with _v1 in the name were produced with an older qtshadertools +and have a QSB_VERSION of 1. + +Files with _v2 are generated with a newer qsb, those have QSB_VERSION 2. +The difference is the support for nativeResourceBindingMap() which is only +present in v2. + +Files with _v3 come from an even newer qsb, and have QSB_VERSION 3. The +difference to 2 is the use of CBOR instead of binary JSON for QShaderDescription. diff --git a/tests/auto/gui/rhi/qshader/data/color.vert.qsb b/tests/auto/gui/rhi/qshader/data/color_all_v1.vert.qsb Binary files differindex 7d02d823d2..7d02d823d2 100644 --- a/tests/auto/gui/rhi/qshader/data/color.vert.qsb +++ b/tests/auto/gui/rhi/qshader/data/color_all_v1.vert.qsb diff --git a/tests/auto/gui/rhi/qshader/data/color_simple.vert.qsb b/tests/auto/gui/rhi/qshader/data/color_spirv_v1.vert.qsb Binary files differindex c82ba7e8e7..c82ba7e8e7 100644 --- a/tests/auto/gui/rhi/qshader/data/color_simple.vert.qsb +++ b/tests/auto/gui/rhi/qshader/data/color_spirv_v1.vert.qsb diff --git a/tests/auto/gui/rhi/qshader/data/texture.frag b/tests/auto/gui/rhi/qshader/data/texture.frag new file mode 100644 index 0000000000..bd22f817e0 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture.frag @@ -0,0 +1,16 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float opacity; +} ubuf; + +layout(binding = 1) uniform sampler2D qt_Texture; + +void main() +{ + fragColor = texture(qt_Texture, qt_TexCoord) * ubuf.opacity; +} diff --git a/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb b/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb Binary files differnew file mode 100644 index 0000000000..79f5486945 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb diff --git a/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb b/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb Binary files differnew file mode 100644 index 0000000000..b6e49aa03d --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp index 21f0cc7895..a0082f1e3b 100644 --- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp +++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp @@ -40,6 +40,9 @@ private slots: void genVariants(); void shaderDescImplicitSharing(); void bakedShaderImplicitSharing(); + void mslResourceMapping(); + void loadV3(); + void serializeShaderDesc(); }; static QShader getShader(const QString &name) @@ -53,8 +56,9 @@ static QShader getShader(const QString &name) void tst_QShader::simpleCompileCheckResults() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); const QShaderCode shader = s.shader(QShaderKey(QShader::SpirvShader, @@ -125,10 +129,11 @@ void tst_QShader::simpleCompileCheckResults() void tst_QShader::genVariants() { - QShader s = getShader(QLatin1String(":/data/color.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); // spirv, glsl 100, glsl 330, glsl 120, hlsl 50, msl 12 // + batchable variants QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 2 * 6); int batchableVariantCount = 0; @@ -149,8 +154,9 @@ void tst_QShader::genVariants() void tst_QShader::shaderDescImplicitSharing() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); QVERIFY(s.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -168,6 +174,7 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); d1.detach(); QVERIFY(QShaderDescriptionPrivate::get(&d0) != QShaderDescriptionPrivate::get(&d1)); @@ -177,12 +184,17 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); + + d1 = QShaderDescription(); + QVERIFY(d0 != d1); } void tst_QShader::bakedShaderImplicitSharing() { - QShader s0 = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s0 = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s0.isValid()); + QCOMPARE(QShaderPrivate::get(&s0)->qsbVersion, 1); QCOMPARE(s0.availableShaders().count(), 1); QVERIFY(s0.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -229,5 +241,159 @@ void tst_QShader::bakedShaderImplicitSharing() } } +void tst_QShader::mslResourceMapping() +{ + QShader s = getShader(QLatin1String(":/data/texture_all_v2.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 2); + + const QVector<QShaderKey> availableShaders = s.availableShaders(); + QCOMPARE(availableShaders.count(), 7); + QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330)))); + + const QShader::NativeResourceBindingMap *resMap = + s.nativeResourceBindingMap(QShaderKey(QShader::GlslShader, QShaderVersion(330))); + QVERIFY(!resMap); + + // The Metal shader must come with a mapping table for binding points 0 + // (uniform buffer) and 1 (combined image sampler mapped to a texture and + // sampler in the shader). + resMap = s.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))); + QVERIFY(resMap); + + QCOMPARE(resMap->count(), 2); + QCOMPARE(resMap->value(0).first, 0); // mapped to native buffer index 0 + QCOMPARE(resMap->value(1), qMakePair(0, 0)); // mapped to native texture index 0 and sampler index 0 +} + +void tst_QShader::loadV3() +{ + // qsb version 3: QShaderDescription is serialized as CBOR. Ensure the deserialized data is as expected. + QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 3); + + const QVector<QShaderKey> availableShaders = s.availableShaders(); + QCOMPARE(availableShaders.count(), 7); + QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330)))); + + const QShaderDescription desc = s.description(); + QVERIFY(desc.isValid()); + QCOMPARE(desc.inputVariables().count(), 1); + for (const QShaderDescription::InOutVariable &v : desc.inputVariables()) { + switch (v.location) { + case 0: + QCOMPARE(v.name, QLatin1String("qt_TexCoord")); + QCOMPARE(v.type, QShaderDescription::Vec2); + break; + default: + QVERIFY(false); + break; + } + } + QCOMPARE(desc.outputVariables().count(), 1); + for (const QShaderDescription::InOutVariable &v : desc.outputVariables()) { + switch (v.location) { + case 0: + QCOMPARE(v.name, QLatin1String("fragColor")); + QCOMPARE(v.type, QShaderDescription::Vec4); + break; + default: + QVERIFY(false); + break; + } + } + QCOMPARE(desc.uniformBlocks().count(), 1); + const QShaderDescription::UniformBlock blk = desc.uniformBlocks().first(); + QCOMPARE(blk.blockName, QLatin1String("buf")); + QCOMPARE(blk.structName, QLatin1String("ubuf")); + QCOMPARE(blk.size, 68); + QCOMPARE(blk.binding, 0); + QCOMPARE(blk.descriptorSet, 0); + QCOMPARE(blk.members.count(), 2); + for (int i = 0; i < blk.members.count(); ++i) { + const QShaderDescription::BlockVariable v = blk.members[i]; + switch (i) { + case 0: + QCOMPARE(v.offset, 0); + QCOMPARE(v.size, 64); + QCOMPARE(v.name, QLatin1String("qt_Matrix")); + QCOMPARE(v.type, QShaderDescription::Mat4); + QCOMPARE(v.matrixStride, 16); + break; + case 1: + QCOMPARE(v.offset, 64); + QCOMPARE(v.size, 4); + QCOMPARE(v.name, QLatin1String("opacity")); + QCOMPARE(v.type, QShaderDescription::Float); + break; + default: + QVERIFY(false); + break; + } + } +} + +void tst_QShader::serializeShaderDesc() +{ + // default constructed QShaderDescription + { + QShaderDescription desc; + QVERIFY(!desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2 = QShaderDescription::fromCbor(data); + QVERIFY(!desc2.isValid()); + } + + // a QShaderDescription with inputs, outputs, uniform block and combined image sampler + { + QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s.isValid()); + const QShaderDescription desc = s.description(); + QVERIFY(desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2; + QVERIFY(!desc2.isValid()); + QVERIFY(!(desc == desc2)); + QVERIFY(desc != desc2); + + desc2 = QShaderDescription::fromCbor(data); + QVERIFY(desc2.isValid()); + QCOMPARE(desc, desc2); + } + + // exercise QShader and QShaderDescription comparisons + { + QShader s1 = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s1.isValid()); + QShader s2 = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); + QVERIFY(s2.isValid()); + + QVERIFY(s1.description().isValid()); + QVERIFY(s2.description().isValid()); + + QVERIFY(s1 != s2); + QVERIFY(s1.description() != s2.description()); + } +} + #include <tst_qshader.moc> QTEST_MAIN(tst_QShader) diff --git a/tests/auto/gui/text/qfontdatabase/testdata.qrc b/tests/auto/gui/text/qfontdatabase/testdata.qrc index 224e845601..a590099b20 100644 --- a/tests/auto/gui/text/qfontdatabase/testdata.qrc +++ b/tests/auto/gui/text/qfontdatabase/testdata.qrc @@ -4,5 +4,6 @@ <file alias="testfont.ttf">../../../shared/resources/testfont.ttf</file> <file alias="testfont_condensed.ttf">../../../shared/resources/testfont_condensed.ttf</file> <file alias="testfont_italic.ttf">../../../shared/resources/testfont_italic.ttf</file> + <file alias="testfont_open.otf">../../../shared/resources/testfont_open.otf</file> </qresource> </RCC> diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index 2b69801b59..12e8083622 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -76,6 +76,9 @@ private slots: void rasterFonts(); void smoothFonts(); + void registerOpenTypePreferredNamesSystem(); + void registerOpenTypePreferredNamesApplication(); + private: QString m_ledFont; QString m_testFont; @@ -440,5 +443,31 @@ void tst_QFontDatabase::smoothFonts() QVERIFY(!QFontDatabase().isBitmapScalable(font.family())); } +void tst_QFontDatabase::registerOpenTypePreferredNamesSystem() +{ + QFontDatabase db; + // This font family was picked because it was the only one I had installed which showcased the + // problem + if (!db.hasFamily(QString::fromLatin1("Source Code Pro ExtraLight"))) + QSKIP("Source Code Pro ExtraLight is not installed"); + + QStringList styles = db.styles(QString::fromLatin1("Source Code Pro")); + QVERIFY(styles.contains(QLatin1String("ExtraLight"))); +} + +void tst_QFontDatabase::registerOpenTypePreferredNamesApplication() +{ + QFontDatabase db; + + int id = QFontDatabase::addApplicationFont(QString::fromLatin1(":/testfont_open.otf")); + if (id == -1) + QSKIP("Skip the test since app fonts are not supported on this system"); + + QStringList styles = db.styles(QString::fromLatin1("QtBidiTestFont")); + QVERIFY(styles.contains(QLatin1String("Open"))); + + QFontDatabase::removeApplicationFont(id); +} + QTEST_MAIN(tst_QFontDatabase) #include "tst_qfontdatabase.moc" diff --git a/tests/auto/gui/text/qsyntaxhighlighter/qsyntaxhighlighter.pro b/tests/auto/gui/text/qsyntaxhighlighter/qsyntaxhighlighter.pro index a78c429433..c91eaad944 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/qsyntaxhighlighter.pro +++ b/tests/auto/gui/text/qsyntaxhighlighter/qsyntaxhighlighter.pro @@ -2,4 +2,4 @@ CONFIG += testcase TARGET = tst_qsyntaxhighlighter SOURCES += tst_qsyntaxhighlighter.cpp QT += testlib -qtHaveModule(widgets) QT += widgets +qtHaveModule(widgets): QT += widgets diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 52e56feb5a..0e9f94ab2b 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -1793,6 +1793,12 @@ void tst_QTextDocument::toHtml() QCOMPARE(output, expectedOutput); QDomDocument document; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QEXPECT_FAIL("charfmt-for-list-item", + "The attribute \"style\" is redefined in the generated HTML, which is not valid " + "according to XML standard. The new QDomDocument implementation follows the XML " + "standard.", Continue); +#endif QVERIFY2(document.setContent(output), "Output was not valid XML"); } diff --git a/tests/auto/gui/text/qtextdocumentlayout/qtextdocumentlayout.pro b/tests/auto/gui/text/qtextdocumentlayout/qtextdocumentlayout.pro index 5d31ee3930..322690e4cc 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/qtextdocumentlayout.pro +++ b/tests/auto/gui/text/qtextdocumentlayout/qtextdocumentlayout.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qtextdocumentlayout QT += testlib -qtHaveModule(widgets) QT += widgets +qtHaveModule(widgets): QT += widgets SOURCES += tst_qtextdocumentlayout.cpp diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index 7b2ff4cc10..474079037b 100644 --- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp +++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp @@ -1041,7 +1041,7 @@ public: QList<QRectF> rects; PaintEngine() - : QPaintEngine(0) + : QPaintEngine(QPaintEngine::PaintEngineFeatures{ }) {} virtual Type type() const { |