summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-13 01:00:38 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-13 01:00:39 +0200
commitf5bf8ca9c31d98fbfd2d7691724f5339deacbe1c (patch)
treea606b82ed39f3d89fd757d0d2e2064b2cc268fe6 /src
parentd5891036de4622e18cf4d68750610224ad201ee0 (diff)
parent0d1481b4d26997bab9ab9a6200776b27b9826ba6 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Diffstat (limited to 'src')
-rw-r--r--src/gui/painting/qdrawhelper.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp14
-rw-r--r--src/gui/painting/qpainter.cpp5
-rw-r--r--src/gui/util/qktxhandler.cpp30
-rw-r--r--src/gui/vulkan/qvulkanwindow.cpp11
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm30
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json12
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h3
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp9
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp7
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp9
13 files changed, 122 insertions, 22 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 582e403e4c..4b1031daaf 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6499,7 +6499,13 @@ static void qInitDrawhelperFunctions()
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *);
extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *);
+ extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
#endif
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 44d4037c0d..98995f485a 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -1163,6 +1163,20 @@ void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const Q
convertARGBToARGB32PM_neon<true>(buffer, buffer, count);
}
+const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_neon<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_neon<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
#endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 41e81c5fbe..b70b29e54e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1297,7 +1297,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
itself and its bounding rectangle: The bounding rect contains
pixels with alpha == 0 (i.e the pixels surrounding the
primitive). These pixels will overwrite the other image's pixels,
- affectively clearing those, while the primitive only overwrites
+ effectively clearing those, while the primitive only overwrites
its own area.
\table 100%
@@ -1387,7 +1387,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
clip.
\li Composition Modes \c QPainter::CompositionMode_Source and
- QPainter::CompositionMode_SourceOver
+ QPainter::CompositionMode_SourceOver.
\li Rounded rectangle filling using solid color and two-color
linear gradients fills.
@@ -8259,6 +8259,7 @@ void QPainter::setTransform(const QTransform &transform, bool combine )
}
/*!
+ Alias for worldTransform().
Returns the world transformation matrix.
\sa worldTransform()
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
index c7831f8143..7eda4c46fb 100644
--- a/src/gui/util/qktxhandler.cpp
+++ b/src/gui/util/qktxhandler.cpp
@@ -43,6 +43,11 @@
#include <QSize>
//#define KTX_DEBUG
+#ifdef KTX_DEBUG
+#include <QDebug>
+#include <QMetaEnum>
+#include <QOpenGLTexture>
+#endif
QT_BEGIN_NAMESPACE
@@ -68,7 +73,7 @@ struct KTXHeader {
quint32 bytesOfKeyValueData;
};
-static const int headerSize = sizeof(KTXHeader);
+static const quint32 headerSize = sizeof(KTXHeader);
// Currently unused, declared for future reference
struct KTXKeyValuePairItem {
@@ -111,7 +116,8 @@ QTextureFileData QKtxHandler::read()
return QTextureFileData();
QByteArray buf = device()->readAll();
- if (buf.size() < headerSize || !canRead(QByteArray(), buf)) {
+ const quint32 dataSize = quint32(buf.size());
+ if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
return QTextureFileData();
}
@@ -130,13 +136,17 @@ QTextureFileData QKtxHandler::read()
texData.setGLInternalFormat(decode(header->glInternalFormat));
texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
- //### For now, ignore any additional mipmap levels
- texData.setNumLevels(1);
- int preambleSize = headerSize + decode(header->bytesOfKeyValueData);
- if (buf.size() >= preambleSize + int(sizeof(KTXMipmapLevel))) {
- texData.setDataOffset(preambleSize + sizeof(quint32)); // for the imageSize
- const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + preambleSize);
- texData.setDataLength(decode(level->imageSize));
+ texData.setNumLevels(decode(header->numberOfMipmapLevels));
+ quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
+ const int maxLevels = qMin(texData.numLevels(), 32); // Cap iterations in case of corrupt file.
+ for (int i = 0; i < maxLevels; i++) {
+ if (offset + sizeof(KTXMipmapLevel) > dataSize) // Corrupt file; avoid oob read
+ break;
+ const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + offset);
+ quint32 levelLen = decode(level->imageSize);
+ texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
+ texData.setDataLength(levelLen, i);
+ offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - ((levelLen + 3) % 4));
}
if (!texData.isValid()) {
@@ -147,7 +157,7 @@ QTextureFileData QKtxHandler::read()
texData.setLogName(logName());
#ifdef KTX_DEBUG
- qDebug() << "KTX file handler read" << texData.data();
+ qDebug() << "KTX file handler read" << texData;
#endif
return texData;
diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp
index e45a16170e..2e65ab49c5 100644
--- a/src/gui/vulkan/qvulkanwindow.cpp
+++ b/src/gui/vulkan/qvulkanwindow.cpp
@@ -989,7 +989,7 @@ bool QVulkanWindowPrivate::createDefaultRenderPass()
attDesc[1].samples = sampleCount;
attDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attDesc[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attDesc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attDesc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attDesc[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@@ -999,7 +999,7 @@ bool QVulkanWindowPrivate::createDefaultRenderPass()
attDesc[2].format = colorFormat;
attDesc[2].samples = sampleCount;
attDesc[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attDesc[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attDesc[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attDesc[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -2164,8 +2164,8 @@ void QVulkanWindowPrivate::addReadback()
barrier.image = frameGrabImage;
devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
+ VK_PIPELINE_STAGE_HOST_BIT,
0, 0, nullptr, 0, nullptr,
1, &barrier);
}
@@ -2298,6 +2298,11 @@ uint32_t QVulkanWindow::hostVisibleMemoryIndex() const
\note Calling this function is only valid from the invocation of
QVulkanWindowRenderer::initResources() up until
QVulkanWindowRenderer::releaseResources().
+
+ \note It is not guaranteed that this memory type is always suitable. The
+ correct, cross-implementation solution - especially for device local images
+ - is to manually pick a memory type after checking the mask returned from
+ \c{vkGetImageMemoryRequirements}.
*/
uint32_t QVulkanWindow::deviceLocalMemoryIndex() const
{
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 1c21879a89..97309ea990 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -106,6 +106,36 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
return QCocoaScreen::mapToNative(maximizedFrame);
}
+#pragma clang diagnostic push
+// NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated, but the
+// NSAnimationContext API that replaces them doesn't handle the use-case of
+// cross-thread screen update synchronization.
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize
+{
+ qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize)
+ << "- disabling screen updates temporarily";
+
+ // There may be separate threads rendering to CA layers in this window,
+ // and if any of them do a swap while the resize is still in progress,
+ // the visual bounds of that layer will be updated before the visual
+ // bounds of the window frame, resulting in flickering while resizing.
+
+ // To prevent this we disable screen updates for the whole process until
+ // the resize is complete, which makes the whole thing visually atomic.
+ NSDisableScreenUpdates();
+
+ return frameSize;
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ NSWindow *window = notification.object;
+ qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates";
+ NSEnableScreenUpdates();
+}
+#pragma clang diagnostic pop
+
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(window);
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index d1e9f85247..b618d8567a 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -141,6 +141,18 @@
"features": [
"disable_desktopgl", "disable_d3d11", "disable_d3d9"
]
+ },
+ {
+ "id": 12,
+ "description": "Intel HD Graphics 620 crash in conjunction with shader caches (QTBUG-64697)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x5916" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_program_cache"
+ ]
}
]
}
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 4824de5c9c..0694435427 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -418,6 +418,10 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
}
const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
+ if (supportedRenderers.testFlag(QWindowsOpenGLTester::DisableProgramCacheFlag)
+ && !QCoreApplication::testAttribute(Qt::AA_DisableShaderDiskCache)) {
+ QCoreApplication::setAttribute(Qt::AA_DisableShaderDiskCache);
+ }
if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) {
if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) {
if ((supportedRenderers & QWindowsOpenGLTester::DisableRotationFlag)
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 6af9f168a5..9a630aff4f 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -301,6 +301,10 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
qCDebug(lcQpaGl) << "Disabling rotation: " << gpu;
result |= DisableRotationFlag;
}
+ if (features.contains(QStringLiteral("disable_program_cache"))) {
+ qCDebug(lcQpaGl) << "Disabling program cache: " << gpu;
+ result |= DisableProgramCacheFlag;
+ }
srCache->insert(qgpu, result);
return result;
#endif // !QT_NO_OPENGL
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 22170f30b0..bec87c1f86 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -83,7 +83,8 @@ public:
GlesMask = Gles | AngleBackendMask,
SoftwareRasterizer = 0x0020,
RendererMask = 0x00FF,
- DisableRotationFlag = 0x0100
+ DisableRotationFlag = 0x0100,
+ DisableProgramCacheFlag = 0x0200
};
Q_DECLARE_FLAGS(Renderers, Renderer)
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index 547eb2043d..daf9686b5e 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -72,6 +72,7 @@ inline static QString fromSQLTCHAR(const QVarLengthArray<SQLTCHAR>& input, int s
{
QString result;
+ // Remove any trailing \0 as some drivers misguidedly append one
int realsize = qMin(size, input.size());
if(realsize > 0 && input[realsize-1] == 0)
realsize--;
@@ -458,7 +459,6 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
// more data can be fetched, the length indicator does NOT
// contain the number of bytes returned - it contains the
// total number of bytes that CAN be fetched
- // colSize-1: remove 0 termination when there is more data to fetch
int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : int(lengthIndicator / sizeof(SQLTCHAR));
fieldVal += fromSQLTCHAR(buf, rSize);
if (lengthIndicator < SQLLEN(colSize*sizeof(SQLTCHAR))) {
@@ -499,9 +499,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
// more data can be fetched, the length indicator does NOT
// contain the number of bytes returned - it contains the
// total number of bytes that CAN be fetched
- // colSize-1: remove 0 termination when there is more data to fetch
int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator;
- fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
+ // Remove any trailing \0 as some drivers misguidedly append one
+ int realsize = qMin(rSize, buf.size());
+ if (realsize > 0 && buf[realsize - 1] == 0)
+ realsize--;
+ fieldVal += QString::fromUtf8(reinterpret_cast<const char *>(buf.constData()), realsize);
if (lengthIndicator < SQLLEN(colSize)) {
// workaround for Drivermanagers that don't return SQL_NO_DATA
break;
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 5e0f7626b4..5796644d34 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -1465,8 +1465,11 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
precision = -1;
}
QString defVal = query.value(5).toString();
- if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\''))
- defVal = defVal.mid(1, defVal.length() - 2);
+ if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
+ const int end = defVal.lastIndexOf(QLatin1Char('\''));
+ if (end > 0)
+ defVal = defVal.mid(1, end - 1);
+ }
QSqlField f(query.value(0).toString(), qDecodePSQLType(query.value(1).toInt()), tablename);
f.setRequired(query.value(2).toBool());
f.setLength(len);
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index e1bf0f2d47..81b5776a7c 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -917,13 +917,20 @@ static QSqlIndex qGetTableInfo(QSqlQuery &q, const QString &tableName, bool only
if (onlyPIndex && !isPk)
continue;
QString typeName = q.value(2).toString().toLower();
+ QString defVal = q.value(4).toString();
+ if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
+ const int end = defVal.lastIndexOf(QLatin1Char('\''));
+ if (end > 0)
+ defVal = defVal.mid(1, end - 1);
+ }
+
QSqlField fld(q.value(1).toString(), qGetColumnType(typeName), tableName);
if (isPk && (typeName == QLatin1String("integer")))
// INTEGER PRIMARY KEY fields are auto-generated in sqlite
// INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY!
fld.setAutoValue(true);
fld.setRequired(q.value(3).toInt() != 0);
- fld.setDefaultValue(q.value(4));
+ fld.setDefaultValue(defVal);
ind.append(fld);
}
return ind;