Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: Iaab37b633a8286c2c21425aaac34d30529a3ea82
This commit is contained in:
Qt Forward Merge Bot 2020-03-18 11:44:48 +01:00
commit 22daba4ff9
18 changed files with 172 additions and 70 deletions

View File

@ -6,7 +6,8 @@
xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"
xmlns:uap3=\"http://schemas.microsoft.com/appx/manifest/uap/windows10/3\"
xmlns:mobile=\"http://schemas.microsoft.com/appx/manifest/mobile/windows10\"
IgnorableNamespaces=\"uap uap3 mp mobile\">
xmlns:iot=\"http://schemas.microsoft.com/appx/manifest/iot/windows10\"
IgnorableNamespaces=\"uap uap3 mp mobile iot\">
<Identity
Name=\"$${WINRT_MANIFEST.identity}\"

View File

@ -123,6 +123,8 @@
UAP3_CAPABILITIES += backgroundMediaPlayback remoteSystem userNotificationListener
IOT_CAPABILITIES += systemManagement
# Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities)
WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device)
@ -133,6 +135,8 @@
MANIFEST_CAPABILITIES += " <uap:Capability Name=\"$$CAPABILITY\" />"
else:contains(UAP3_CAPABILITIES, $$CAPABILITY): \
MANIFEST_CAPABILITIES += " <uap3:Capability Name=\"$$CAPABILITY\" />"
else:contains(IOT_CAPABILITIES, $$CAPABILITY): \
MANIFEST_CAPABILITIES += " <iot:Capability Name=\"$$CAPABILITY\" />"
else: \
MANIFEST_CAPABILITIES += " <Capability Name=\"$$CAPABILITY\" />"
}

View File

@ -37,6 +37,7 @@ EMCC_COMMON_LFLAGS += \
-s NO_EXIT_RUNTIME=0 \
-s ERROR_ON_UNDEFINED_SYMBOLS=1 \
-s EXTRA_EXPORTED_RUNTIME_METHODS=[\"UTF16ToString\",\"stringToUTF16\"] \
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 \
--bind
# The -s arguments can also be used with release builds,

View File

@ -31,7 +31,6 @@ struct TranslatedAttribute;
// The order of this enum governs priority of 'getLatestBufferStorage'.
enum BufferUsage
{
BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_STAGING,
BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
BUFFER_USAGE_INDEX,
@ -40,6 +39,7 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
BUFFER_USAGE_COUNT,

View File

@ -0,0 +1,37 @@
From b215999d63d6e6b087e53e24a47b8b60520ec9e4 Mon Sep 17 00:00:00 2001
From: Oliver Wolff <oliver.wolff@qt.io>
Date: Wed, 11 Mar 2020 13:59:39 +0100
Subject: [PATCH] ANGLE: Fix severe performance regression
The changed buffer usage priority that was introduced in our ANGLE
update caused severe performance regressions for Qt applications.
Fixes: QTBUG-73835
Change-Id: I49839bb272cdeec0027264f2751b88bc149665ad
---
src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index ddbeeb90d2..f92a68454b 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -31,7 +31,6 @@ struct TranslatedAttribute;
// The order of this enum governs priority of 'getLatestBufferStorage'.
enum BufferUsage
{
- BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_STAGING,
BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
BUFFER_USAGE_INDEX,
@@ -40,6 +39,7 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM,
+ BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
BUFFER_USAGE_COUNT,
--
2.20.1.windows.1

View File

@ -123,6 +123,10 @@
a vector can be quite slow, because it can lead to large numbers
of items having to be moved by one position in memory.
\row \li \l{QVarLengthArray}<T, Prealloc>
\li This provides a low-level variable-length array. It can be used
instead of QVector in places where speed is particularly important.
\row \li \l{QStack}<T>
\li This is a convenience subclass of QVector that provides
"last in, first out" (LIFO) semantics. It adds the following
@ -622,15 +626,11 @@
\section1 Other Container-Like Classes
Qt includes three template classes that resemble containers in
Qt includes other template classes that resemble containers in
some respects. These classes don't provide iterators and cannot
be used with the \c foreach keyword.
\list
\li QVarLengthArray<T, Prealloc> provides a low-level
variable-length array. It can be used instead of QVector in
places where speed is particularly important.
\li QCache<Key, T> provides a cache to store objects of a certain
type T associated with keys of type Key.

View File

@ -102,7 +102,7 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
for (int style = 1; m_id.isEmpty() && style-- > 0;) {
for (int dst = 1; m_id.isEmpty() && dst-- > 0;) {
m_id = match(androidTimeZone.callObjectMethod(
"getDisplayName", "(ZI;)Ljava/lang/String;", bool(dst), style));
"getDisplayName", "(ZI)Ljava/lang/String;", bool(dst), style));
}
}
}

View File

@ -797,8 +797,12 @@ QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State
if (svgIcon.isNull())
svgIcon = QIcon(filename);
// Simply reuse svg icon engine
return svgIcon.pixmap(size, mode, state);
// Bypass QIcon API, as that will scale by device pixel ratio of the
// highest DPR screen since we're not passing on any QWindow.
if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine : nullptr)
return engine->pixmap(size, mode, state);
return QPixmap();
}
QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode,

View File

@ -1006,6 +1006,13 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
return result;
}
void QWindowsContext::forceNcCalcSize(HWND hwnd)
{
// Force WM_NCCALCSIZE to adjust margin
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out,
unsigned dpi)
{

View File

@ -249,6 +249,8 @@ public:
bool asyncExpose() const;
void setAsyncExpose(bool value);
static void forceNcCalcSize(HWND hwnd);
static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi = 0);
static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out,
const QPlatformScreen *screen = nullptr);

View File

@ -794,20 +794,13 @@ QWindowsMenuBar *QWindowsMenuBar::menuBarOf(const QWindow *notYetCreatedWindow)
? qobject_cast<QWindowsMenuBar *>(menuBarV.value<QObject *>()) : nullptr;
}
static inline void forceNcCalcSize(HWND hwnd)
{
// Force WM_NCCALCSIZE to adjust margin: Does not appear to work?
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
void QWindowsMenuBar::install(QWindowsWindow *window)
{
const HWND hwnd = window->handle();
const BOOL result = SetMenu(hwnd, m_hMenuBar);
if (result) {
window->setMenuBar(this);
forceNcCalcSize(hwnd);
QWindowsContext::forceNcCalcSize(hwnd);
}
}
@ -817,7 +810,7 @@ void QWindowsMenuBar::removeFromWindow()
const HWND hwnd = window->handle();
SetMenu(hwnd, nullptr);
window->setMenuBar(nullptr);
forceNcCalcSize(hwnd);
QWindowsContext::forceNcCalcSize(hwnd);
}
}

View File

@ -2442,7 +2442,17 @@ void QWindowsWindow::setFullFrameMargins(const QMargins &newMargins)
void QWindowsWindow::updateFullFrameMargins()
{
// Normally obtained from WM_NCCALCSIZE
// QTBUG-82580: If a native menu is present, force a WM_NCCALCSIZE.
if (GetMenu(m_data.hwnd))
QWindowsContext::forceNcCalcSize(m_data.hwnd);
else
calculateFullFrameMargins();
}
void QWindowsWindow::calculateFullFrameMargins()
{
// Normally obtained from WM_NCCALCSIZE. This calculation only works
// when no native menu is present.
const auto systemMargins = testFlag(DisableNonClientScaling)
? QWindowsGeometryHint::frameOnPrimaryScreen(m_data.hwnd)
: frameMargins_sys();

View File

@ -373,6 +373,7 @@ private:
void handleWindowStateChange(Qt::WindowStates state);
inline void destroyIcon();
void fireExpose(const QRegion &region, bool force=false);
void calculateFullFrameMargins();
mutable QWindowsWindowData m_data;
QPointer<QWindowsMenuBar> m_menuBar;

View File

@ -43,6 +43,7 @@
#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
#include <QtCore/qfunctions_winrt.h>
#include <private/qeventdispatcher_winrt_p.h>
#include <wrl.h>
#include <windows.foundation.h>
@ -94,13 +95,17 @@ bool QWinRTServices::openUrl(const QUrl &url)
HRESULT hr = d->uriFactory->CreateUri(uriString.Get(), &uri);
RETURN_FALSE_IF_FAILED("Failed to create URI from QUrl.");
ComPtr<IAsyncOperation<bool>> op;
hr = d->launcher->LaunchUriAsync(uri.Get(), &op);
RETURN_FALSE_IF_FAILED("Failed to start URI launch.");
boolean result;
hr = QWinRTFunctions::await(op, &result);
RETURN_FALSE_IF_FAILED("Failed to launch URI.");
hr = QEventDispatcherWinRT::runOnXamlThread([this, d, uri, &result]() {
ComPtr<IAsyncOperation<bool>> op;
HRESULT hr = d->launcher->LaunchUriAsync(uri.Get(), &op);
RETURN_HR_IF_FAILED("Failed to start URI launch.");
hr = QWinRTFunctions::await(op, &result);
RETURN_HR_IF_FAILED("Failed to launch URI.");
return hr;
});
RETURN_FALSE_IF_FAILED("Failed to launch URI from Xaml thread.");
return result;
}
@ -131,12 +136,16 @@ bool QWinRTServices::openDocument(const QUrl &url)
boolean result;
{
ComPtr<IAsyncOperation<bool>> op;
hr = d->launcher->LaunchFileAsync(file.Get(), &op);
RETURN_FALSE_IF_FAILED("Failed to start file launch.");
hr = QEventDispatcherWinRT::runOnXamlThread([this, d, file, &result]() {
ComPtr<IAsyncOperation<bool>> op;
HRESULT hr = d->launcher->LaunchFileAsync(file.Get(), &op);
RETURN_HR_IF_FAILED("Failed to start file launch.");
hr = QWinRTFunctions::await(op, &result);
RETURN_FALSE_IF_FAILED("Failed to launch file.");
hr = QWinRTFunctions::await(op, &result);
RETURN_HR_IF_FAILED("Failed to launch file.");
return hr;
});
RETURN_FALSE_IF_FAILED("Failed to launch file from Xaml thread.");
}
return result;

View File

@ -3755,7 +3755,8 @@ int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
bool spanned = false;
if (!spanningIndexes.isEmpty()) {
const QModelIndex index = q->indexAt(pos);
spanned = q->isFirstColumnSpanned(index.row(), index.parent());
if (index.isValid())
spanned = q->isFirstColumnSpanned(index.row(), index.parent());
}
const int column = spanned ? 0 : header->logicalIndexAt(pos.x());
if (!isTreePosition(column))

View File

@ -1090,12 +1090,21 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest()
QProcess serverProcess;
serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"),
QIODevice::ReadWrite | QIODevice::Text);
QVERIFY2(serverProcess.waitForStarted(3000),
qPrintable("Failed to start subprocess: " + serverProcess.errorString()));
const auto serverProcessCleaner = qScopeGuard([&serverProcess] {
serverProcess.kill();
serverProcess.waitForFinished();
});
if (!serverProcess.waitForStarted(3000))
QSKIP("Failed to start server as a subprocess");
// Wait until the server has started and reports success.
while (!serverProcess.canReadLine())
QVERIFY(serverProcess.waitForReadyRead(3000));
while (!serverProcess.canReadLine()) {
if (!serverProcess.waitForReadyRead(3000))
QSKIP("No output from the server process, bailing out");
}
QByteArray serverGreeting = serverProcess.readLine();
QVERIFY(serverGreeting != QByteArray("XXX\n"));
int serverPort = serverGreeting.trimmed().toInt();
@ -1105,12 +1114,21 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest()
clientProcess.start(QString::fromLatin1("clientserver/clientserver connectedclient %1 %2")
.arg(QLatin1String("127.0.0.1")).arg(serverPort),
QIODevice::ReadWrite | QIODevice::Text);
QVERIFY2(clientProcess.waitForStarted(3000),
qPrintable("Failed to start subprocess: " + clientProcess.errorString()));
// Wait until the server has started and reports success.
while (!clientProcess.canReadLine())
QVERIFY(clientProcess.waitForReadyRead(3000));
const auto clientProcessCleaner = qScopeGuard([&clientProcess] {
clientProcess.kill();
clientProcess.waitForFinished();
});
if (!clientProcess.waitForStarted(3000))
QSKIP("Client process did not start");
// Wait until the client has started and reports success.
while (!clientProcess.canReadLine()) {
if (!clientProcess.waitForReadyRead(3000))
QSKIP("No output from the client process, bailing out");
}
QByteArray clientGreeting = clientProcess.readLine();
QCOMPARE(clientGreeting, QByteArray("ok\n"));
@ -1135,11 +1153,6 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest()
QCOMPARE(serverData.at(i * 3 + 2).trimmed().mid(8).toInt(),
sdata.mid(4).trimmed().toInt() * 2);
}
clientProcess.kill();
QVERIFY(clientProcess.waitForFinished());
serverProcess.kill();
QVERIFY(serverProcess.waitForFinished());
#endif
}
@ -1151,12 +1164,21 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest()
QProcess serverProcess;
serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"),
QIODevice::ReadWrite | QIODevice::Text);
QVERIFY2(serverProcess.waitForStarted(3000),
qPrintable("Failed to start subprocess: " + serverProcess.errorString()));
const auto serverProcessCleaner = qScopeGuard([&serverProcess] {
serverProcess.kill();
serverProcess.waitForFinished();
});
if (!serverProcess.waitForStarted(3000))
QSKIP("Failed to start the server subprocess");
// Wait until the server has started and reports success.
while (!serverProcess.canReadLine())
QVERIFY(serverProcess.waitForReadyRead(3000));
while (!serverProcess.canReadLine()) {
if (!serverProcess.waitForReadyRead(3000))
QSKIP("No output from the server, probably, it is not running");
}
QByteArray serverGreeting = serverProcess.readLine();
QVERIFY(serverGreeting != QByteArray("XXX\n"));
int serverPort = serverGreeting.trimmed().toInt();
@ -1166,12 +1188,21 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest()
clientProcess.start(QString::fromLatin1("clientserver/clientserver unconnectedclient %1 %2")
.arg(QLatin1String("127.0.0.1")).arg(serverPort),
QIODevice::ReadWrite | QIODevice::Text);
QVERIFY2(clientProcess.waitForStarted(3000),
qPrintable("Failed to start subprocess: " + clientProcess.errorString()));
// Wait until the server has started and reports success.
while (!clientProcess.canReadLine())
QVERIFY(clientProcess.waitForReadyRead(3000));
const auto clientProcessCleaner = qScopeGuard([&clientProcess] {
clientProcess.kill();
clientProcess.waitForFinished();
});
if (!clientProcess.waitForStarted(3000))
QSKIP("Failed to start the client's subprocess");
// Wait until the client has started and reports success.
while (!clientProcess.canReadLine()) {
if (!clientProcess.waitForReadyRead(3000))
QSKIP("The client subprocess produced not output, exiting.");
}
QByteArray clientGreeting = clientProcess.readLine();
QCOMPARE(clientGreeting, QByteArray("ok\n"));
@ -1197,11 +1228,6 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest()
QCOMPARE(serverData.at(i * 3 + 2).trimmed().mid(8).toInt(),
sdata.mid(4).trimmed().toInt() * 2);
}
clientProcess.kill();
QVERIFY(clientProcess.waitForFinished());
serverProcess.kill();
QVERIFY(serverProcess.waitForFinished());
#endif
}

View File

@ -51,7 +51,7 @@ private slots:
void about();
void detailsText();
void detailsButtonText();
void expandDetails_QTBUG_32473();
void expandDetailsWithoutMoving();
#ifndef Q_OS_MAC
void shortcut();
@ -499,7 +499,7 @@ void tst_QMessageBox::detailsButtonText()
}
}
void tst_QMessageBox::expandDetails_QTBUG_32473()
void tst_QMessageBox::expandDetailsWithoutMoving() // QTBUG-32473
{
tst_ResizingMessageBox box;
box.setDetailedText("bla");
@ -516,18 +516,14 @@ void tst_QMessageBox::expandDetails_QTBUG_32473()
auto moreButton = *it;
QVERIFY(QTest::qWaitForWindowExposed(&box));
QTRY_VERIFY2(!box.geometry().topLeft().isNull(), "window manager is expected to decorate and position the dialog");
QRect geom = box.geometry();
box.resized = false;
// now click the "more" button, and verify that the dialog resizes but does not move
moreButton->click();
QTRY_VERIFY(box.resized);
// After we receive the expose event for a second widget, it's likely
// that the window manager is also done manipulating the first QMessageBox.
QWidget fleece;
fleece.show();
QVERIFY(QTest::qWaitForWindowExposed(&fleece));
if (geom.topLeft() == box.geometry().topLeft())
QTest::qWait(500);
QCOMPARE(geom.topLeft(), box.geometry().topLeft());
QVERIFY(box.geometry().height() > geom.height());
QCOMPARE(box.geometry().topLeft(), geom.topLeft());
}
void tst_QMessageBox::incorrectDefaultButton()

View File

@ -294,6 +294,12 @@ public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
{
if (onlyValidCalls) {
Q_ASSERT(row >= 0);
Q_ASSERT(column >= 0);
Q_ASSERT(row < rows);
Q_ASSERT(column < cols);
}
if (row < 0 || column < 0 || (level(parent) > levels) || column >= cols || row >= rows) {
return QModelIndex();
}
@ -402,6 +408,7 @@ public:
mutable bool fetched = false;
bool decorationsEnabled = false;
bool statusTipsEnabled = false;
bool onlyValidCalls = false;
};
// Testing get/set functions
@ -2450,6 +2457,7 @@ void tst_QTreeView::hiddenItems()
void tst_QTreeView::spanningItems()
{
QtTestModel model(10, 10);
model.onlyValidCalls = true;
QTreeView view;
view.setModel(&model);
view.show();
@ -2489,6 +2497,8 @@ void tst_QTreeView::spanningItems()
}
}
QCOMPARE(view.sizeHintForColumn(0), w);
view.repaint(); // to check that this doesn't hit any assert
}
void tst_QTreeView::selectionOrderTest()