diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-13 01:00:38 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-09-13 01:00:39 +0200 |
commit | f5bf8ca9c31d98fbfd2d7691724f5339deacbe1c (patch) | |
tree | a606b82ed39f3d89fd757d0d2e2064b2cc268fe6 /src | |
parent | d5891036de4622e18cf4d68750610224ad201ee0 (diff) | |
parent | 0d1481b4d26997bab9ab9a6200776b27b9826ba6 (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: Icd201bf6b634e44e0e2ab05eaf91a7d8588d7f05
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_neon.cpp | 14 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 5 | ||||
-rw-r--r-- | src/gui/util/qktxhandler.cpp | 30 | ||||
-rw-r--r-- | src/gui/vulkan/qvulkanwindow.cpp | 11 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnswindowdelegate.mm | 30 | ||||
-rw-r--r-- | src/plugins/platforms/windows/openglblacklists/default.json | 12 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsintegration.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopengltester.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopengltester.h | 3 | ||||
-rw-r--r-- | src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 9 | ||||
-rw-r--r-- | src/plugins/sqldrivers/psql/qsql_psql.cpp | 7 | ||||
-rw-r--r-- | src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 9 |
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; |