summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/global/config.qdocconf2
-rw-r--r--doc/global/html-footer-online.qdocconf2
-rw-r--r--doc/global/html-footer.qdocconf2
-rw-r--r--doc/global/qt-module-defaults-online.qdocconf2
-rw-r--r--src/gui/kernel/qguiapplication.cpp21
-rw-r--r--src/network/socket/socket.pri2
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp6
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm8
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/widgets/qlabel.cpp2
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp7
-rw-r--r--tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp46
-rw-r--r--tests/auto/corelib/thread/qthread/tst_qthread.cpp8
-rw-r--r--tests/auto/network/kernel/qdnslookup/BLACKLIST2
-rw-r--r--tests/auto/other/lancelot/paintcommands.cpp7
-rw-r--r--tests/benchmarks/gui/painting/lancebench/lancebench.pro13
-rw-r--r--tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp328
-rw-r--r--tests/benchmarks/gui/painting/painting.pro3
18 files changed, 419 insertions, 44 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 += \
" <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \
" <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
- " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2017 The Qt Company</a></li>\n" \
+ " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2018 The Qt Company</a></li>\n" \
" </ul>\n" \
"</div>\n" \
"</div>\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 = \
"</div>\n" \
"<div class=\"footer\">\n" \
" <p>\n" \
- " <acronym title=\"Copyright\">&copy;</acronym> 2017 The Qt Company Ltd.\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2018 The Qt Company Ltd.\n" \
" Documentation contributions included herein are the copyrights of\n" \
" their respective owners.<br>" \
" 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 = \
" </div>\n" \
" <p class=\"copy-notice\">\n" \
- " <acronym title=\"Copyright\">&copy;</acronym> 2017 The Qt Company Ltd.\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 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/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 12390928f0..caa8aaca4b 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}.
@@ -1285,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;
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
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)
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 3621e5102f..5eb45be04a 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 &region, 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<QCocoaWindow *>(
- window->handle())->isContentView() && !windowHasUnifiedToolbar() ?
+ // and is fully opaque, we can get away with copying the backingstore instead
+ // of blending.
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ const NSCompositingOperation compositingOperation = cocoaWindow->isContentView()
+ && cocoaWindow->isOpaque() && !windowHasUnifiedToolbar() ?
NSCompositingOperationCopy : NSCompositingOperationSourceOver;
#ifdef QT_DEBUG
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index c947acd765..8e3263ad92 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -11124,7 +11124,7 @@ void QWidgetPrivate::macUpdateSizeAttribute()
for (int i = 0; i < children.size(); ++i) {
QWidget *w = qobject_cast<QWidget *>(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();
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index a6ae61545b..c624187190 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
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);
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<int> futureWatcher;
- QObject::connect(&futureWatcher, SIGNAL(resultReadyAt(int)), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QSignalSpy resultSpy(&futureWatcher, &QFutureWatcher<int>::resultReadyAt);
QFuture<int> 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<int>());
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<int>::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<int>::finished);
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::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<int> future = iface.future();
QFutureWatcher<int> watcher;
+ QSignalSpy startedSpy(&watcher, &QFutureWatcher<int>::started);
+ QSignalSpy finishedSpy(&watcher, &QFutureWatcher<int>::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<int> future = iface.future();
QFutureWatcher<int> watcher;
+ QSignalSpy resultSpy(&watcher, &QFutureWatcher<int>::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());
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);
}
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
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<QPair<QString,QStringList> > PaintCommands::s_enumsTable = QList<QPair<QSt
QMultiHash<QString, int> 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<s_commandInfoTable.size(); i++) {
+ // and pre-optimize the regexps.
+ s_commandInfoTable.at(i).regExp.optimize();
if (s_commandInfoTable.at(i).isSectionHeader() ||
s_commandInfoTable.at(i).identifier == QLatin1String("comment") ||
s_commandInfoTable.at(i).identifier == QLatin1String("noop"))
@@ -682,6 +684,7 @@ void PaintCommands::insertAt(int commandIndex, const QStringList &newCommands)
**********************************************************************************/
void PaintCommands::runCommand(const QString &scriptLine)
{
+ static QRegularExpression separators("\\s");
if (scriptLine.isEmpty()) {
command_noop(QRegularExpressionMatch());
return;
@@ -690,7 +693,7 @@ void PaintCommands::runCommand(const QString &scriptLine)
command_comment(QRegularExpressionMatch());
return;
}
- QString firstWord = scriptLine.section(QRegularExpression("\\s"), 0, 0);
+ QString firstWord = scriptLine.section(separators, 0, 0);
QList<int> 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 <qtest.h>
+#include <QDir>
+#include <QPainter>
+
+#ifndef QT_NO_OPENGL
+#include <QOpenGLFramebufferObjectFormat>
+#include <QOpenGLContext>
+#include <QOpenGLPaintDevice>
+#endif
+
+#include <algorithm>
+
+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<QString, QStringList> 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<QString>("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 534d882578..400c2994a6 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 \