From 306df144b40f81a81ac0119e02cc465792e961d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 27 Mar 2018 16:06:18 +0200 Subject: [PATCH 01/13] Cocoa: Make QMacNativeWidget paint correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWindows with transparent pixels (of which QMacNativeWidget is an example) must be composited, even if they are content views. This will display the NSWindow background instead of solid black for the areas where the Qt backingstore has transparent pixels. Change-Id: Ibee1327e11bc64975900b4c5d632dd5f103da4c8 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 57a03905ab..091453785e 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -163,9 +163,11 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo const qreal devicePixelRatio = m_image.devicePixelRatio(); // If the flushed window is a content view, and not in unified toolbar mode, - // we can get away with copying the backingstore instead of blending. - const NSCompositingOperation compositingOperation = static_cast( - window->handle())->isContentView() && !windowHasUnifiedToolbar() ? + // and is fully opaque, we can get away with copying the backingstore instead + // of blending. + QCocoaWindow *cocoaWindow = static_cast(window->handle()); + const NSCompositingOperation compositingOperation = cocoaWindow->isContentView() + && cocoaWindow->isOpaque() && !windowHasUnifiedToolbar() ? NSCompositingOperationCopy : NSCompositingOperationSourceOver; #ifdef QT_DEBUG From 8b9a9651d6efbd84cda476c47f962ff0a600b234 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Thu, 29 Mar 2018 09:34:21 +0300 Subject: [PATCH 02/13] Fix typoed integrity condition Amends 594fe5c4636cb783bb7840efff4171e772ae906a. Change-Id: I0fb5ab79d895cfd9698db9b4a4394481299a7e1a Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/network/socket/socket.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index a8a37492b7..44ff5b7b39 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -73,7 +73,7 @@ qtConfig(localserver) { SOURCES += socket/qlocalsocket.cpp \ socket/qlocalserver.cpp - intergrity|winrt { + integrity|winrt { SOURCES += socket/qlocalsocket_tcp.cpp \ socket/qlocalserver_tcp.cpp DEFINES += QT_LOCALSOCKET_TCP From 231ac1b878cf3246b0b4cf00bc63e956abd1c4fd Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Tue, 27 Mar 2018 10:20:59 +0300 Subject: [PATCH 03/13] tst_QFutureWatcher: Avoid unconditional qWait()s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use QSignalSpy::wait or QTRY_VERIFY instead. This shaved off ~200 ms of the running time of the test and is more reliable. Some unconditional qWait()s still remain in this test. They are giving an opportunity for the wrong thing to happen and thus are not waiting for any specific condition to be fulfilled. Task-number: QTBUG-63992 Change-Id: I25a4470fe8d6a5b8b5039b3ed77321d24faa1707 Reviewed-by: Morten Johan Sørvig Reviewed-by: Sami Nurmenniemi Reviewed-by: Edward Welbourne --- .../qfuturewatcher/tst_qfuturewatcher.cpp | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index a16e9e377c..b2ef516b4e 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -82,11 +82,11 @@ void tst_QFutureWatcher::startFinish() QVERIFY(finishedSpy.isValid()); futureWatcher.setFuture(QtConcurrent::run(sleeper)); - QTest::qWait(10); // spin the event loop to deliver queued signals. + QVERIFY(startedSpy.wait()); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); futureWatcher.future().waitForFinished(); - QTest::qWait(10); + QVERIFY(finishedSpy.wait()); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 1); } @@ -232,13 +232,12 @@ void tst_QFutureWatcher::resultAt() void tst_QFutureWatcher::resultReadyAt() { QFutureWatcher futureWatcher; - QObject::connect(&futureWatcher, SIGNAL(resultReadyAt(int)), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QSignalSpy resultSpy(&futureWatcher, &QFutureWatcher::resultReadyAt); QFuture future = (new IntTask())->start(); futureWatcher.setFuture(future); - QTestEventLoop::instance().enterLoop(1); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(resultSpy.wait()); // Setting the future again should give us another signal. // (this is to prevent the race where the task associated @@ -246,8 +245,7 @@ void tst_QFutureWatcher::resultReadyAt() futureWatcher.setFuture(QFuture()); futureWatcher.setFuture(future); - QTestEventLoop::instance().enterLoop(1); - QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(resultSpy.wait()); } class SignalSlotObject : public QObject @@ -320,19 +318,17 @@ void tst_QFutureWatcher::futureSignals() const int progress = 1; a.setProgressValue(progress); - QTest::qWait(10); - QCOMPARE(progressSpy.count(), 2); + QTRY_COMPARE(progressSpy.count(), 2); QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 0); QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 1); const int result = 10; a.reportResult(&result); - QTest::qWait(10); + QVERIFY(resultReadySpy.wait()); QCOMPARE(resultReadySpy.count(), 1); a.reportFinished(&result); - QTest::qWait(10); - QCOMPARE(resultReadySpy.count(), 2); + QTRY_COMPARE(resultReadySpy.count(), 2); QCOMPARE(resultReadySpy.takeFirst().at(0).toInt(), 0); // check the index QCOMPARE(resultReadySpy.takeFirst().at(0).toInt(), 1); @@ -373,7 +369,7 @@ void tst_QFutureWatcher::watchFinishedFuture() QVERIFY(canceledSpy.isValid()); watcher.setFuture(f); - QTest::qWait(10); + QVERIFY(finishedSpy.wait()); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 1); @@ -407,7 +403,7 @@ void tst_QFutureWatcher::watchCanceledFuture() QVERIFY(canceledSpy.isValid()); watcher.setFuture(f); - QTest::qWait(10); + QVERIFY(finishedSpy.wait()); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 1); @@ -434,7 +430,7 @@ void tst_QFutureWatcher::disconnectRunningFuture() const int result = 10; a.reportResult(&result); - QTest::qWait(10); + QVERIFY(resultReadySpy.wait()); QCOMPARE(resultReadySpy.count(), 1); delete watcher; @@ -624,7 +620,7 @@ void tst_QFutureWatcher::changeFuture() QSignalSpy resultReadySpy(&watcher, &QFutureWatcher::resultReadyAt); QVERIFY(resultReadySpy.isValid()); - watcher.setFuture(a); // Watch 'a' which will genere a resultReady event. + watcher.setFuture(a); // Watch 'a' which will generate a resultReady event. watcher.setFuture(b); // But oh no! we're switching to another future QTest::qWait(10); // before the event gets delivered. @@ -633,7 +629,7 @@ void tst_QFutureWatcher::changeFuture() watcher.setFuture(a); watcher.setFuture(b); watcher.setFuture(a); // setting it back gets us one event, not two. - QTest::qWait(10); + QVERIFY(resultReadySpy.wait()); QCOMPARE(resultReadySpy.count(), 1); } @@ -653,13 +649,15 @@ void tst_QFutureWatcher::cancelEvents() SignalSlotObject object; connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); + QSignalSpy finishedSpy(&watcher, &QFutureWatcher::finished); QSignalSpy resultReadySpy(&watcher, &QFutureWatcher::resultReadyAt); + QVERIFY(finishedSpy.isValid()); QVERIFY(resultReadySpy.isValid()); watcher.setFuture(a); watcher.cancel(); - QTest::qWait(10); + QVERIFY(finishedSpy.wait()); QCOMPARE(resultReadySpy.count(), 0); } @@ -730,15 +728,17 @@ void tst_QFutureWatcher::finishedState() iface.reportStarted(); QFuture future = iface.future(); QFutureWatcher watcher; + QSignalSpy startedSpy(&watcher, &QFutureWatcher::started); + QSignalSpy finishedSpy(&watcher, &QFutureWatcher::finished); watcher.setFuture(future); - QTest::qWait(10); + QVERIFY(startedSpy.wait()); iface.reportFinished(); QVERIFY(future.isFinished()); QVERIFY(!watcher.isFinished()); - QTest::qWait(10); + QVERIFY(finishedSpy.wait()); QVERIFY(watcher.isFinished()); } @@ -752,18 +752,20 @@ void tst_QFutureWatcher::throttling() iface.reportStarted(); QFuture future = iface.future(); QFutureWatcher watcher; + QSignalSpy resultSpy(&watcher, &QFutureWatcher::resultReadyAt); watcher.setFuture(future); QVERIFY(!iface.isThrottled()); - for (int i = 0; i < 1000; ++i) { + const int resultCount = 1000; + for (int i = 0; i < resultCount; ++i) { int result = 0; iface.reportResult(result); } QVERIFY(iface.isThrottled()); - QTest::qWait(100); // process events. + QTRY_COMPARE(resultSpy.count(), resultCount); // Process the results QVERIFY(!iface.isThrottled()); From c7dac6469c3bc804a70e1afcc0dc7865afc28e5a Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 26 Mar 2018 17:28:46 +0300 Subject: [PATCH 04/13] tst_QThread: Use QTRY_VERIFY instead of qWaits These two places were sort of manually implementing QTRY_VERIFY except that they never time out. Change-Id: I136e6c7400194327c0475c6acfc019825ccec1b5 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Sami Nurmenniemi --- tests/auto/corelib/thread/qthread/tst_qthread.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 0405896ca7..aee243d880 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -988,9 +988,7 @@ void tst_QThread::exitAndStart() connect(&sync2, SIGNAL(propChanged(int)), &sync1, SLOT(setProp(int)), Qt::QueuedConnection); connect(&sync1, SIGNAL(propChanged(int)), &thread, SLOT(quit()), Qt::QueuedConnection); QMetaObject::invokeMethod(&sync2, "setProp", Qt::QueuedConnection , Q_ARG(int, 89)); - QTest::qWait(50); - while(!thread.wait(10)) - QTest::qWait(10); + QTRY_VERIFY(thread.wait(10)); QCOMPARE(sync2.m_prop, 89); QCOMPARE(sync1.m_prop, 89); } @@ -1026,9 +1024,7 @@ void tst_QThread::exitAndExec() connect(&sync2, SIGNAL(propChanged(int)), &sync1, SLOT(setProp(int)), Qt::QueuedConnection); connect(&sync1, SIGNAL(propChanged(int)), &thread, SLOT(quit()), Qt::QueuedConnection); QMetaObject::invokeMethod(&sync2, "setProp", Qt::QueuedConnection , Q_ARG(int, 89)); - QTest::qWait(50); - while(!thread.wait(10)) - QTest::qWait(10); + QTRY_VERIFY(thread.wait(10)); QCOMPARE(sync2.m_prop, 89); QCOMPARE(sync1.m_prop, 89); } From 6d644c7a7737837fad71990b9ea028f7cfdcc2e5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 27 Mar 2018 11:23:03 -0700 Subject: [PATCH 05/13] QWidget: Fix typo in Mac size propagation This amends commit f8b6d104b981ef420756c0c20f62b8013d93ae15. Change-Id: I77a48e68ec7db791b843fe4dfeddc4c6fedf6380 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 0a46d2a8eb..c347ca0b59 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -11148,7 +11148,7 @@ void QWidgetPrivate::macUpdateSizeAttribute() for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast(children.at(i)); if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation)) - && !q->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent + && !w->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent && !w->testAttribute(Qt::WA_MacSmallSize) && !w->testAttribute(Qt::WA_MacNormalSize)) w->d_func()->macUpdateSizeAttribute(); From d31a68146d0c13a76b3da0cd2e3a7dcc524b7a8f Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Thu, 29 Mar 2018 16:31:42 +0300 Subject: [PATCH 06/13] Narrow tst_QDnsLookup::lookup blacklist to only CI It is suspected that the fault actually lies in CI infra. Amends e3cf2a1ae959b69957c98f4b9213c4cbc632e888. Task-number: QTBUG-66311 Change-Id: I967da283f0b94be1d0b99481d0cbd15ca7f98d45 Reviewed-by: Sami Nurmenniemi Reviewed-by: Thiago Macieira --- tests/auto/network/kernel/qdnslookup/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/network/kernel/qdnslookup/BLACKLIST b/tests/auto/network/kernel/qdnslookup/BLACKLIST index f07a8ce9a3..edf6436384 100644 --- a/tests/auto/network/kernel/qdnslookup/BLACKLIST +++ b/tests/auto/network/kernel/qdnslookup/BLACKLIST @@ -1,2 +1,2 @@ [lookup] -* +ci From 051228c9ba048188a5c596d3ced3210f130a28dd Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 27 Mar 2018 16:40:30 +0200 Subject: [PATCH 07/13] Doc: Increment copyright year in global doc templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I687ea95c0985c361ffb75ea3c162615b0abbb7f7 Reviewed-by: Eike Ziller Reviewed-by: Paul Wicking Reviewed-by: Topi Reiniö --- doc/global/config.qdocconf | 2 +- doc/global/html-footer-online.qdocconf | 2 +- doc/global/html-footer.qdocconf | 2 +- doc/global/qt-module-defaults-online.qdocconf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf index a18396876d..dbbccd0445 100644 --- a/doc/global/config.qdocconf +++ b/doc/global/config.qdocconf @@ -3,7 +3,7 @@ dita.metadata.default.author = Qt Project dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project -dita.metadata.default.copyryear = 2017 +dita.metadata.default.copyryear = 2018 dita.metadata.default.copyrholder = The Qt Company Ltd dita.metadata.default.audience = programmer diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf index d6cf5d2122..f2631555c1 100644 --- a/doc/global/html-footer-online.qdocconf +++ b/doc/global/html-footer-online.qdocconf @@ -78,7 +78,7 @@ HTML.footer += \ " \n" \ "\n" \ "\n" \ diff --git a/doc/global/html-footer.qdocconf b/doc/global/html-footer.qdocconf index 5a0fbd85e1..9957e71f20 100644 --- a/doc/global/html-footer.qdocconf +++ b/doc/global/html-footer.qdocconf @@ -8,7 +8,7 @@ HTML.footer = \ "\n" \ "
\n" \ "

\n" \ - " © 2017 The Qt Company Ltd.\n" \ + " © 2018 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners.
" \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/global/qt-module-defaults-online.qdocconf b/doc/global/qt-module-defaults-online.qdocconf index 15c193d698..1bed0c7934 100644 --- a/doc/global/qt-module-defaults-online.qdocconf +++ b/doc/global/qt-module-defaults-online.qdocconf @@ -5,7 +5,7 @@ HTML.footer = \ "

\n" \ "

\n" \ - " © 2017 The Qt Company Ltd.\n" \ + " © 2018 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners. " \ " The documentation provided herein is licensed under the terms of the" \ From 3e1ecdd74cfb85d1c73f96289fc2114708881c6b Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 26 Mar 2018 16:30:25 +0300 Subject: [PATCH 08/13] tst_QStateMachine: Don't use unconditional waits Instead use QSignalSpy to wait directly for the expected events. Change-Id: I319302ea7177fe690b5d885347c505454904518e Reviewed-by: Sami Nurmenniemi Reviewed-by: Erik Verbruggen --- .../statemachine/qstatemachine/tst_qstatemachine.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 17763f31f9..810698fb4e 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -4667,11 +4667,14 @@ void tst_QStateMachine::clonedSignals() s1->addTransition(t1); machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, &QStateMachine::started); machine.start(); - QTest::qWait(1); + QVERIFY(startedSpy.wait()); + QSignalSpy transitionSpy(t1, &CloneSignalTransition::triggered); emitter.emitSignalWithDefaultArg(); - QTest::qWait(1); + QTRY_COMPARE(transitionSpy.count(), 1); + QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()")); TEST_ACTIVE_CHANGED(s1, 2); TEST_ACTIVE_CHANGED(s2, 1); From 559964849af0d2dfcb409169dcc9e40d01c6fae2 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 23 Mar 2018 11:09:18 +0100 Subject: [PATCH 09/13] Add lancelot based benchmark Uses the scripts and tests we already have for lancelot as a painting benchmark. Change-Id: Idf8a55e2261162e619f6dbb567dc19f8dc96da4e Reviewed-by: Eirik Aavitsland --- tests/auto/other/lancelot/paintcommands.cpp | 7 +- .../gui/painting/lancebench/lancebench.pro | 13 + .../painting/lancebench/tst_lancebench.cpp | 328 ++++++++++++++++++ tests/benchmarks/gui/painting/painting.pro | 3 +- 4 files changed, 348 insertions(+), 3 deletions(-) create mode 100644 tests/benchmarks/gui/painting/lancebench/lancebench.pro create mode 100644 tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index 4e0cb3b835..074644393d 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -192,7 +192,7 @@ QList > PaintCommands::s_enumsTable = QList PaintCommands::s_commandHash; #define DECL_PAINTCOMMAND(identifier, method, regexp, syntax, sample) \ - s_commandInfoTable << PaintCommandInfos(QLatin1String(identifier), &PaintCommands::method, QRegularExpression(regexp, QRegularExpression::OptimizeOnFirstUsageOption), \ + s_commandInfoTable << PaintCommandInfos(QLatin1String(identifier), &PaintCommands::method, QRegularExpression(regexp), \ QLatin1String(syntax), QLatin1String(sample) ); #define DECL_PAINTCOMMANDSECTION(title) \ @@ -615,6 +615,8 @@ void PaintCommands::staticInit() // populate the command lookup hash for (int i=0; i indices = s_commandHash.values(firstWord); foreach(int idx, indices) { PaintCommandInfos command = s_commandInfoTable.at(idx); diff --git a/tests/benchmarks/gui/painting/lancebench/lancebench.pro b/tests/benchmarks/gui/painting/lancebench/lancebench.pro new file mode 100644 index 0000000000..6458c50861 --- /dev/null +++ b/tests/benchmarks/gui/painting/lancebench/lancebench.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = tst_bench_lancebench + +QT += testlib gui-private + + +SOURCES += tst_lancebench.cpp + +SOURCES += ../../../../auto/other/lancelot/paintcommands.cpp +HEADERS += ../../../../auto/other/lancelot/paintcommands.h +RESOURCES += ../../../../auto/other/lancelot/images.qrc + +TESTDATA += ../../../../auto/other/lancelot/scripts/* diff --git a/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp b/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp new file mode 100644 index 0000000000..bd0889bf4a --- /dev/null +++ b/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "../../../../auto/other/lancelot/paintcommands.h" + +#include +#include +#include + +#ifndef QT_NO_OPENGL +#include +#include +#include +#endif + +#include + +class tst_LanceBench : public QObject +{ + Q_OBJECT +public: + tst_LanceBench(); + +private: + enum GraphicsEngine { + Raster = 0, + OpenGL = 1 + }; + + void setupTestSuite(const QStringList& blacklist = QStringList()); + void runTestSuite(GraphicsEngine engine, QImage::Format format, const QSurfaceFormat &contextFormat = QSurfaceFormat()); + void paint(QPaintDevice *device, GraphicsEngine engine, QImage::Format format, const QStringList &script, const QString &filePath); + + QStringList qpsFiles; + QHash scripts; + QString scriptsDir; + +private slots: + void initTestCase(); + void cleanupTestCase() {} + + void testRasterARGB32PM_data(); + void testRasterARGB32PM(); + void testRasterRGB32_data(); + void testRasterRGB32(); + void testRasterARGB32_data(); + void testRasterARGB32(); + void testRasterRGB16_data(); + void testRasterRGB16(); + void testRasterBGR30_data(); + void testRasterBGR30(); + void testRasterARGB8565PM_data(); + void testRasterARGB8565PM(); + void testRasterGrayscale8_data(); + void testRasterGrayscale8(); + +#ifndef QT_NO_OPENGL + void testOpenGL_data(); + void testOpenGL(); + void testCoreOpenGL_data(); + void testCoreOpenGL(); +private: + bool checkSystemGLSupport(); + bool checkSystemCoreGLSupport(); +#endif +}; + +tst_LanceBench::tst_LanceBench() +{ +} + +void tst_LanceBench::initTestCase() +{ + QString baseDir = QFINDTESTDATA("../../../../auto/other/lancelot/scripts/text.qps"); + scriptsDir = baseDir.left(baseDir.lastIndexOf('/')) + '/'; + QDir qpsDir(scriptsDir); + qpsFiles = qpsDir.entryList(QStringList() << QLatin1String("*.qps"), QDir::Files | QDir::Readable); + if (qpsFiles.isEmpty()) { + QWARN("No qps script files found in " + qpsDir.path().toLatin1()); + QSKIP("Aborted due to errors."); + } + + std::sort(qpsFiles.begin(), qpsFiles.end()); + for (const QString& fileName : qAsConst(qpsFiles)) { + QFile file(scriptsDir + fileName); + file.open(QFile::ReadOnly); + QByteArray cont = file.readAll(); + scripts.insert(fileName, QString::fromUtf8(cont).split(QLatin1Char('\n'), QString::SkipEmptyParts)); + } +} + +void tst_LanceBench::testRasterARGB32PM_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterARGB32PM() +{ + runTestSuite(Raster, QImage::Format_ARGB32_Premultiplied); +} + +void tst_LanceBench::testRasterRGB32_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterRGB32() +{ + runTestSuite(Raster, QImage::Format_RGB32); +} + +void tst_LanceBench::testRasterARGB32_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterARGB32() +{ + runTestSuite(Raster, QImage::Format_ARGB32); +} + +void tst_LanceBench::testRasterRGB16_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterRGB16() +{ + runTestSuite(Raster, QImage::Format_RGB16); +} + +void tst_LanceBench::testRasterBGR30_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterBGR30() +{ + runTestSuite(Raster, QImage::Format_BGR30); +} + +void tst_LanceBench::testRasterARGB8565PM_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterARGB8565PM() +{ + runTestSuite(Raster, QImage::Format_ARGB8565_Premultiplied); +} + +void tst_LanceBench::testRasterGrayscale8_data() +{ + setupTestSuite(); +} + +void tst_LanceBench::testRasterGrayscale8() +{ + runTestSuite(Raster, QImage::Format_Grayscale8); +} + +#ifndef QT_NO_OPENGL +bool tst_LanceBench::checkSystemGLSupport() +{ + QWindow win; + win.setSurfaceType(QSurface::OpenGLSurface); + win.create(); + QOpenGLFramebufferObjectFormat fmt; + fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + fmt.setSamples(4); + QOpenGLContext ctx; + if (!ctx.create() || !ctx.makeCurrent(&win)) + return false; + QOpenGLFramebufferObject fbo(800, 800, fmt); + if (!fbo.isValid() || !fbo.bind()) + return false; + + return true; +} + +bool tst_LanceBench::checkSystemCoreGLSupport() +{ + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) + return false; + + QSurfaceFormat coreFormat; + coreFormat.setVersion(3, 2); + coreFormat.setProfile(QSurfaceFormat::CoreProfile); + QWindow win; + win.setSurfaceType(QSurface::OpenGLSurface); + win.setFormat(coreFormat); + win.create(); + QOpenGLFramebufferObjectFormat fmt; + fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + fmt.setSamples(4); + QOpenGLContext ctx; + ctx.setFormat(coreFormat); + if (!ctx.create() || !ctx.makeCurrent(&win)) + return false; + QOpenGLFramebufferObject fbo(800, 800, fmt); + if (!fbo.isValid() || !fbo.bind()) + return false; + + return true; +} + +void tst_LanceBench::testOpenGL_data() +{ + if (!checkSystemGLSupport()) + QSKIP("System under test does not meet preconditions for GL testing. Skipping."); + QStringList localBlacklist = QStringList() << QLatin1String("rasterops.qps"); + setupTestSuite(localBlacklist); +} + +void tst_LanceBench::testOpenGL() +{ + runTestSuite(OpenGL, QImage::Format_RGB32); +} + +void tst_LanceBench::testCoreOpenGL_data() +{ + if (!checkSystemCoreGLSupport()) + QSKIP("System under test does not meet preconditions for Core Profile GL testing. Skipping."); + QStringList localBlacklist = QStringList() << QLatin1String("rasterops.qps"); + setupTestSuite(localBlacklist); +} + +void tst_LanceBench::testCoreOpenGL() +{ + QSurfaceFormat coreFormat; + coreFormat.setVersion(3, 2); + coreFormat.setProfile(QSurfaceFormat::CoreProfile); + runTestSuite(OpenGL, QImage::Format_RGB32, coreFormat); +} +#endif + +void tst_LanceBench::setupTestSuite(const QStringList& blacklist) +{ + QTest::addColumn("qpsFile"); + for (const QString &fileName : qAsConst(qpsFiles)) { + if (blacklist.contains(fileName)) + continue; + QTest::newRow(fileName.toLatin1()) << fileName; + } +} + +void tst_LanceBench::runTestSuite(GraphicsEngine engine, QImage::Format format, const QSurfaceFormat &contextFormat) +{ + QFETCH(QString, qpsFile); + + QString filePath = scriptsDir + qpsFile; + QStringList script = scripts.value(qpsFile); + QImage rendered; + + if (engine == Raster) { + QImage img(800, 800, format); + paint(&img, engine, format, script, QFileInfo(filePath).absoluteFilePath()); + rendered = img; +#ifndef QT_NO_OPENGL + } else if (engine == OpenGL) { + QWindow win; + win.setSurfaceType(QSurface::OpenGLSurface); + win.setFormat(contextFormat); + win.create(); + QOpenGLFramebufferObjectFormat fmt; + fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + fmt.setSamples(4); + QOpenGLContext ctx; + ctx.setFormat(contextFormat); + QVERIFY(ctx.create()); + QVERIFY(ctx.makeCurrent(&win)); + QOpenGLFramebufferObject fbo(800, 800, fmt); + fbo.bind(); + QOpenGLPaintDevice pdv(800, 800); + paint(&pdv, engine, format, script, QFileInfo(filePath).absoluteFilePath()); + rendered = fbo.toImage().convertToFormat(format); +#endif + } +} + +void tst_LanceBench::paint(QPaintDevice *device, GraphicsEngine engine, QImage::Format format, const QStringList &script, const QString &filePath) +{ + PaintCommands pcmd(script, 800, 800, format); + switch (engine) { + case OpenGL: + pcmd.setType(OpenGLBufferType); // version/profile is communicated through the context's format() + break; + case Raster: + pcmd.setType(ImageType); + break; + } + pcmd.setFilePath(filePath); + QBENCHMARK { + QPainter p(device); + pcmd.setPainter(&p); + pcmd.runCommands(); + p.end(); + } +} + +QTEST_MAIN(tst_LanceBench) + +#include "tst_lancebench.moc" diff --git a/tests/benchmarks/gui/painting/painting.pro b/tests/benchmarks/gui/painting/painting.pro index bbca36259e..d08dfa707b 100644 --- a/tests/benchmarks/gui/painting/painting.pro +++ b/tests/benchmarks/gui/painting/painting.pro @@ -5,7 +5,8 @@ SUBDIRS = \ qpainter \ qregion \ qtransform \ - qtbench + qtbench \ + lancebench !qtHaveModule(widgets): SUBDIRS -= \ qpainter \ From 33e5b55b7e48b3a1f68ef66ddf49be05e6dda47f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 3 Apr 2018 14:28:37 +0200 Subject: [PATCH 10/13] Check if the movie's current pixmap is null before drawing it Change-Id: I87ed9998108961775f8f424bfbb4b957c0b03d8a Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qlabel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 046acfeea9..947da273dd 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -1008,7 +1008,7 @@ void QLabel::paintEvent(QPaintEvent *) : layoutDirection(), QFlag(d->align)); #if QT_CONFIG(movie) - if (d->movie) { + if (d->movie && !d->movie->currentPixmap().isNull()) { if (d->scaledcontents) style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size())); else From c53b86444ff871801e00e09232dde2d7de4a435b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 3 Apr 2018 12:41:53 +0200 Subject: [PATCH 11/13] macOS: Document availability of freetype font engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we have this documentation for the Windows platform plugin, it makes sense to also have it for Cocoa. Task-number: QTBUG-67372 Change-Id: I170ae251572c8e209643a582cdd7350aaf5c7ccd Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qguiapplication.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 12390928f0..836bbeccee 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -591,6 +591,12 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME applications. \endlist + The following parameter is available for \c {-platform cocoa} (on macOS): + + \list + \li \c {fontengine=freetype}, uses the FreeType font engine. + \endlist + For more information about the platform-specific arguments available for embedded Linux platforms, see \l{Qt for Embedded Linux}. From ab7d48625aed1c1bb56148f57f958371e810cf4c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 15 Feb 2018 15:45:51 +0100 Subject: [PATCH 12/13] Fix read-only text browser sometimes jump to the top of the document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Respect the inputMethodAccepted() attribute of QPlatformInputContext in the ibus input context plugin. This is what for example the windows input context plugin does, too. A text browser that is read-only should not receive input method events that include a cursor placement. So when it receives the focus, we must only convey the received-focus information to the input method if the widget is editable (or accepts input method events generally speaking), because as soon as the ibus process learns about it, it will send an input method event that looks like a "let us reset the state a clean start and place the cursor at the beginning" message. We are not interested in reaching that state with the ibus process. Task-number: QTBUG-63066 Change-Id: I1b0e5f8a396bc31169d6081f9325092b447cf60a Reviewed-by: Tor Arne Vestbø --- .../ibus/qibusplatforminputcontext.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 02f92bbb18..f339938f86 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -254,6 +254,12 @@ void QIBusPlatformInputContext::setFocusObject(QObject *object) if (!d->busConnected) return; + // It would seem natural here to call FocusOut() on the input method if we + // transition from an IME accepted focus object to one that does not accept it. + // Mysteriously however that is not sufficient to fix bug QTBUG-63066. + if (!inputMethodAccepted()) + return; + if (debug) qDebug() << "setFocusObject" << object; if (object) From 4b4870a12cd920cd45c534deae7ca90716398a19 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 22 Mar 2018 16:54:41 +0100 Subject: [PATCH 13/13] Parse XDG_SESSION_TYPE and use that to determine default platform Makes Qt application try to launch using wayland in a wayland session, even if it was a default desktop build. Change-Id: Ib7d4a79fbe777527d1862bd775627afae10b1e9e Reviewed-by: Thiago Macieira --- src/gui/kernel/qguiapplication.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 836bbeccee..caa8aaca4b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1291,6 +1291,21 @@ void QGuiApplicationPrivate::createPlatformIntegration() #ifdef QT_QPA_DEFAULT_PLATFORM_NAME platformName = QT_QPA_DEFAULT_PLATFORM_NAME; #endif +#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) + QByteArray sessionType = qgetenv("XDG_SESSION_TYPE"); + if (!sessionType.isEmpty()) { + if (sessionType == QByteArrayLiteral("x11") && !platformName.contains(QByteArrayLiteral("xcb"))) + platformName = QByteArrayLiteral("xcb"); + else if (sessionType == QByteArrayLiteral("wayland") && !platformName.contains(QByteArrayLiteral("wayland"))) + platformName = QByteArrayLiteral("wayland"); + } +#ifdef QT_QPA_DEFAULT_PLATFORM_NAME + // Add it as fallback in case XDG_SESSION_TYPE is something wrong + if (!platformName.contains(QT_QPA_DEFAULT_PLATFORM_NAME)) + platformName += QByteArrayLiteral(";" QT_QPA_DEFAULT_PLATFORM_NAME); +#endif +#endif + QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM"); if (!platformNameEnv.isEmpty()) { platformName = platformNameEnv;