summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h2
-rw-r--r--src/angle/patches/0016-ANGLE-Fix-severe-performance-regression.patch37
-rw-r--r--src/corelib/doc/src/containers.qdoc10
-rw-r--r--src/corelib/time/qtimezoneprivate_android.cpp2
-rw-r--r--src/gui/image/qiconloader.cpp8
-rw-r--r--src/gui/text/qtextlayout.cpp29
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmenu.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp33
-rw-r--r--src/widgets/itemviews/qtreeview.cpp3
13 files changed, 112 insertions, 45 deletions
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,
diff --git a/src/angle/patches/0016-ANGLE-Fix-severe-performance-regression.patch b/src/angle/patches/0016-ANGLE-Fix-severe-performance-regression.patch
new file mode 100644
index 0000000000..e9cda1337f
--- /dev/null
+++ b/src/angle/patches/0016-ANGLE-Fix-severe-performance-regression.patch
@@ -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
+
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index d0bb251e81..4c7cb32aac 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -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.
diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp
index 5cb8155dcc..fc3653752a 100644
--- a/src/corelib/time/qtimezoneprivate_android.cpp
+++ b/src/corelib/time/qtimezoneprivate_android.cpp
@@ -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));
}
}
}
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 27c82bc09f..2f907a7709 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -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,
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index a3e194f835..aaca1061b7 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1667,7 +1667,8 @@ namespace {
QFontEngine *previousGlyphFontEngine;
QFixed minw;
- QFixed softHyphenWidth;
+ QFixed currentSoftHyphenWidth;
+ QFixed commitedSoftHyphenWidth;
QFixed rightBearing;
QFixed minimumRightBearing;
@@ -1681,7 +1682,7 @@ namespace {
QFixed calculateNewWidth(const QScriptLine &line) const {
return line.textWidth + tmpData.textWidth + spaceData.textWidth
- + softHyphenWidth + negativeRightBearing();
+ + (line.textWidth > 0 ? currentSoftHyphenWidth : QFixed()) + negativeRightBearing();
}
inline glyph_t currentGlyph() const
@@ -1755,6 +1756,7 @@ inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line)
if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs))
return true;
+ const QFixed oldTextWidth = line.textWidth;
minw = qMax(minw, tmpData.textWidth);
line += tmpData;
line.textWidth += spaceData.textWidth;
@@ -1765,6 +1767,11 @@ inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line)
spaceData.textWidth = 0;
spaceData.length = 0;
+ if (oldTextWidth != line.textWidth || currentSoftHyphenWidth > 0) {
+ commitedSoftHyphenWidth = currentSoftHyphenWidth;
+ currentSoftHyphenWidth = 0;
+ }
+
return false;
}
@@ -1837,7 +1844,6 @@ void QTextLine::layout_helper(int maxGlyphs)
while (newItem < eng->layoutData->items.size()) {
lbh.resetRightBearing();
- lbh.softHyphenWidth = 0;
if (newItem != item) {
item = newItem;
const QScriptItem &current = eng->layoutData->items.at(item);
@@ -1975,9 +1981,9 @@ void QTextLine::layout_helper(int maxGlyphs)
} while (lbh.currentPosition < end);
lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw);
- if (lbh.currentPosition > 0 && lbh.currentPosition < end
- && attributes[lbh.currentPosition].lineBreak
- && eng->layoutData->string.at(lbh.currentPosition - 1).unicode() == QChar::SoftHyphen) {
+ if (lbh.currentPosition > 0 && lbh.currentPosition <= end
+ && (lbh.currentPosition == end || attributes[lbh.currentPosition].lineBreak)
+ && eng->layoutData->string.at(lbh.currentPosition - 1) == QChar::SoftHyphen) {
// if we are splitting up a word because of
// a soft hyphen then we ...
//
@@ -1994,10 +2000,7 @@ void QTextLine::layout_helper(int maxGlyphs)
// want the soft-hyphen to slip into the next line
// and thus become invisible again.
//
- if (line.length)
- lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
- else if (breakany)
- lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
+ lbh.currentSoftHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
}
if (sb_or_ws|breakany) {
@@ -2023,6 +2026,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.calculateRightBearing();
if (lbh.checkFullOtherwiseExtend(line)) {
+
// We are too wide to accept the next glyph with its bearing, so we restore the
// right bearing to that of the previous glyph (the one that was already accepted),
// so that the bearing can be be applied to the final width of the text below.
@@ -2031,9 +2035,7 @@ void QTextLine::layout_helper(int maxGlyphs)
else
lbh.calculateRightBearingForPreviousGlyph();
- if (!breakany) {
- line.textWidth += lbh.softHyphenWidth;
- }
+ line.textWidth += lbh.commitedSoftHyphenWidth;
goto found;
}
@@ -2045,6 +2047,7 @@ void QTextLine::layout_helper(int maxGlyphs)
}
LB_DEBUG("reached end of line");
lbh.checkFullOtherwiseExtend(line);
+ line.textWidth += lbh.commitedSoftHyphenWidth;
found:
line.textAdvance = line.textWidth;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index d31352b854..293faf8a53 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -978,6 +978,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)
{
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 8027f09389..07398bd61c 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -246,6 +246,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);
diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp
index d20edd685e..221e4ff6ec 100644
--- a/src/plugins/platforms/windows/qwindowsmenu.cpp
+++ b/src/plugins/platforms/windows/qwindowsmenu.cpp
@@ -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);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index a11da598fc..04478d5f1f 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -2431,7 +2431,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();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 1f8800272b..aaf02d2a81 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -370,6 +370,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;
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index b27c408f40..04d7417801 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -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 = QWinRTFunctions::await(op, &result);
- RETURN_FALSE_IF_FAILED("Failed to launch file.");
+ 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_HR_IF_FAILED("Failed to launch file.");
+ return hr;
+ });
+ RETURN_FALSE_IF_FAILED("Failed to launch file from Xaml thread.");
}
return result;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 442369c2ec..a9e6e90623 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -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))