From fd6370d89f789f78cecbaabedc60b92cbecb6404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Tue, 11 Sep 2018 12:26:10 +0300 Subject: [PATCH 01/15] Extend opensuse blacklistings to opensuse-leap In openSUSE 15.0 /etc/os-release the ID of the OS was changed from "opensuse" to "opensuse-leap". So every blacklisting we did for opensuse, didn't cover opensuse-leap. This one adds opensuse-leap as a blacklisted platform whenever opensuse was blacklisted. Task-number: QTBUG-70463 Task-number: QTBUG-51399 Change-Id: I5879eb34926757163973d8b9442eae58f47d2f11 Reviewed-by: Liang Qi --- tests/auto/gui/kernel/qwindow/BLACKLIST | 1 + tests/auto/other/gestures/BLACKLIST | 1 + tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST | 1 + tests/auto/widgets/kernel/qapplication/BLACKLIST | 1 + tests/auto/widgets/kernel/qwidget/BLACKLIST | 2 ++ tests/auto/widgets/widgets/qspinbox/BLACKLIST | 1 + 6 files changed, 7 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index d1f14de794..e9a0d44ba7 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -8,6 +8,7 @@ osx-10.12 ci ubuntu-16.04 # QTBUG-66851 opensuse +opensuse-leap # QTBUG-69160 android [setVisible] diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST index ff6d2fa48e..269bac5750 100644 --- a/tests/auto/other/gestures/BLACKLIST +++ b/tests/auto/other/gestures/BLACKLIST @@ -5,6 +5,7 @@ ubuntu-18.04 # QTBUG-67254 ubuntu opensuse +opensuse-leap [graphicsItemGesture] ubuntu-18.04 [graphicsItemTreeGesture] diff --git a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST index 0f7c377194..c6aeebc8f8 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST +++ b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST @@ -5,3 +5,4 @@ opensuse-42.3 ci [comboBox] # QTBUG-67282 opensuse +opensuse-leap diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST index ca0efdff8a..d7de7bf16e 100644 --- a/tests/auto/widgets/kernel/qapplication/BLACKLIST +++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST @@ -1,3 +1,4 @@ [touchEventPropagation] # QTBUG-66745 opensuse +opensuse-leap diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 2be016e99b..d8654e5768 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -16,6 +16,7 @@ linux [raise] # QTBUG-68175 opensuse +opensuse-leap [setWindowGeometry] osx [windowMoveResize] @@ -36,6 +37,7 @@ osx-10.12 ci osx-10.13 ci [maskedUpdate] opensuse +opensuse-leap [moveInResizeEvent] ubuntu-16.04 [moveChild:right] diff --git a/tests/auto/widgets/widgets/qspinbox/BLACKLIST b/tests/auto/widgets/widgets/qspinbox/BLACKLIST index cc049df942..a38511bfb4 100644 --- a/tests/auto/widgets/widgets/qspinbox/BLACKLIST +++ b/tests/auto/widgets/widgets/qspinbox/BLACKLIST @@ -1,2 +1,3 @@ [stepModifierPressAndHold] opensuse ci # QTBUG-69492 +opensuse-leap ci From dff9bb2f9b981e263d8d3d5b1ef67054297e731c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 3 Sep 2018 12:45:05 +0200 Subject: [PATCH 02/15] Windows: Disable shader disk cache for Intel HD Graphics 620 Set Qt::AA_DisableShaderDiskCache when the feature "disable_program_cache" (modeled after the Chromium driver bug list) is present and set it for the Intel HD Graphics 620 card. Task-number: QTBUG-64697 Change-Id: Ibba588d2ab296b5c959ab8ee9712b47ec7cc906e Reviewed-by: Laszlo Agocs --- .../platforms/windows/openglblacklists/default.json | 12 ++++++++++++ .../platforms/windows/qwindowsintegration.cpp | 4 ++++ .../platforms/windows/qwindowsopengltester.cpp | 4 ++++ src/plugins/platforms/windows/qwindowsopengltester.h | 3 ++- 4 files changed, 22 insertions(+), 1 deletion(-) 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) From 017ac02ec459378074a44487f171cc909e947f4a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 3 Sep 2018 14:05:55 +0200 Subject: [PATCH 03/15] Clean up time-zone matching logic in tst_QLocale::macDefaultLocale() The test was computing GMT with a suffix added to it for the offset; but when the offset is zero there's no need for it. Cleaned up the logic so that it only checks for a "padded to two digits with zero" if the number is single-digit (and use string arithmetic in preference to wantonly complex .arg()ing; and use simpler names). Since we don't try to check anything unless GMT does appear in the string (because the actual zone ID was used, instead of GMT with an offset), the case of zero offset has nothing more to check than that GMT was present, the precondition for checking anything. Task-number: QTBUG-70322 Change-Id: I0b8abe7e63d9d72fa9cf32f188b47a78a849044b Reviewed-by: Qt CI Bot Reviewed-by: Thiago Macieira --- .../corelib/tools/qlocale/tst_qlocale.cpp | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 2556c7e618..261689d401 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1802,24 +1802,23 @@ void tst_QLocale::macDefaultLocale() // Depending on the configured time zone, the time string might not // contain a GMT specifier. (Sometimes it just names the zone, like "CEST") - if (timeString.contains(QString("GMT"))) { - QString expectedGMTSpecifierBase("GMT"); - if (diff >= 0) - expectedGMTSpecifierBase.append(QLatin1Char('+')); - else - expectedGMTSpecifierBase.append(QLatin1Char('-')); + QLatin1String gmt("GMT"); + if (timeString.contains(gmt) && diff) { + QLatin1Char sign(diff < 0 ? '-' : '+'); + QString number(QString::number(qAbs(diff))); + const QString expect = gmt + sign + number; - QString expectedGMTSpecifier = expectedGMTSpecifierBase + QString("%1").arg(qAbs(diff)); - QString expectedGMTSpecifierZeroExtended - = expectedGMTSpecifierBase + QString("0%1").arg(qAbs(diff)); + if (diff < 10) { + const QString zeroed = gmt + sign + QLatin1Char('0') + number; - QVERIFY2(timeString.contains(expectedGMTSpecifier) - || timeString.contains(expectedGMTSpecifierZeroExtended), - qPrintable(QString("timeString `%1', expectedGMTSpecifier `%2' or `%3'") - .arg(timeString) - .arg(expectedGMTSpecifier) - .arg(expectedGMTSpecifierZeroExtended) - )); + QVERIFY2(timeString.contains(expect) || timeString.contains(zeroed), + qPrintable(QString("timeString `%1', expected GMT specifier `%2' or `%3'") + .arg(timeString).arg(expect).arg(zeroed))); + } else { + QVERIFY2(timeString.contains(expect), + qPrintable(QString("timeString `%1', expected GMT specifier `%2'") + .arg(timeString).arg(expect))); + } } QCOMPARE(locale.dayName(1), QString("Monday")); QCOMPARE(locale.dayName(7), QString("Sunday")); From d8c210d7f576fc54b41ad06c061ece7cadeed648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Sep 2018 22:36:21 +0200 Subject: [PATCH 04/15] macOS: Prevent flickering when resizing window rendered to by separate thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a window is resized AppKit groups all updates to the view frames and corresponding layer bounds, so that the result of the resize is visually atomic, but this only works for the main thread. http://openradar.appspot.com/radar?id=4990815088672768 When a separate thread renders to one of the views in the window, it may result in the view and its layer updating its bounds visually before the resize has been visually reflected for the window itself and its border. To ensure visually atomic updates, we disable all screen updates for the process during resizing. This is the same workaround used by e.g. the NSOpenPanel class, which renders the content of the view out of process, and by Chromium for a similar use-case: https://chromium-review.googlesource.com/c/chromium/src/+/798774 Ideally we'd do this only for the window that is being resized, but there's no known API to do that. The deprecated [NSWindow disableScreenUpdatesUntilFlush] is a no-op these days, and used NSDisableScreenUpdates internally anyways). Fixes: QTBUG-69321 Change-Id: I84de714782278f2e0b2b2e1eb245c30810cb3023 Reviewed-by: Morten Johan Sørvig Reviewed-by: Simon Hausmann --- .../platforms/cocoa/qnswindowdelegate.mm | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) 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); From a3e8b92d971aef58174aefaa60741d16af8271ae Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 6 Sep 2018 12:39:31 +0200 Subject: [PATCH 05/15] ODBC: Remove the trailing \0 in the case of a non unicode string Some ODBC drivers, such as old Informix ODBC drivers will incorrectly include a trailing \0 in a string when this should not exist. For unicode strings this was already accounted for, but for non-unicode ones this was not covered. The change also fixes up the comments a bit to make this clearer and also added one for the unicode case. Task-number: QTBUG-62406 Change-Id: Id932a58d9e5fdff2f4d1aacf8cc9fdaeb34f95f4 Reviewed-by: Edward Welbourne --- src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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& 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(buf.constData()), realsize); if (lengthIndicator < SQLLEN(colSize)) { // workaround for Drivermanagers that don't return SQL_NO_DATA break; From 003a35640379a4529d776b7be1a0c164b8fc879f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 10 Sep 2018 12:16:08 +0200 Subject: [PATCH 06/15] winrt: Fix build with MSVC >= 15.8 39cb9ac873cc moved the _ENABLE_EXTENDED_ALIGNED_STORAGE define from msvc-version.conf to msvc-desktop.conf which basically removed the define from winrt builds. By adding it to winrt's common qmake.conf these builds are fixed. Change-Id: I3d87c55fb52685859713f7466012b45c46145678 Reviewed-by: Friedemann Kleint --- mkspecs/common/winrt_winphone/qmake.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index 8c1a767dfa..375e084127 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -8,7 +8,9 @@ MAKEFILE_GENERATOR = MSBUILD QMAKE_COMPILER = msvc QMAKE_PLATFORM = winrt win32 CONFIG = package_manifest $$CONFIG incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target rtti -DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN +# MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without +# _ENABLE_EXTENDED_ALIGNED_STORAGE flag since the fix breaks binary compatibility. +DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN _ENABLE_EXTENDED_ALIGNED_STORAGE QMAKE_COMPILER_DEFINES += _WIN32 DEPLOYMENT_PLUGIN += qwinrt From cfb8d70888c88b1f7c74b4787b1f22e5636d32d1 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 11 Sep 2018 13:01:52 +0200 Subject: [PATCH 07/15] Doc: Fix typo and add precision to method description As transform() returns worldTransform(), point out that it is an alias in its description. Fixes: QTBUG-18117 Change-Id: I0eb1f78c6955b499906024105f9969cdccf13303 Reviewed-by: Martin Smith --- src/gui/painting/qpainter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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() From 2aa779e893bd7526c97a1968c6835204e4e985e2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 10 Sep 2018 17:33:09 +0200 Subject: [PATCH 08/15] syncqt: fix forwarding injected headers, take ~3 in non-prefix builds, the forwarding headers always end up in qtbase's build dir, while the injected headers always live in the build dir of the module they belong to. to deal with that, we now record the target path relative to the module root dir instead of relative to the base directory of the forwarding header itself. Fixes: QTBUG-70056 Change-Id: Ic4346148a125b13e2610f6965cdf4f5266ac763e Reviewed-by: Lars Knoll --- bin/syncqt.pl | 2 +- mkspecs/features/qt_build_paths.prf | 3 ++- mkspecs/features/qt_module_headers.prf | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index 8890b31770..77ce90c164 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -1111,7 +1111,7 @@ foreach my $lib (@modules_to_sync) { elsif (!$shadow) { $pri_install_pfiles.= "$pri_install_iheader ";; } - $pri_injections .= fixPaths($iheader, "$out_basedir/include/$lib") + $pri_injections .= fixPaths($iheader, $out_basedir) .":".($no_stamp ? "^" : "").fixPaths($oheader, "$out_basedir/include/$lib") .$injection." " if ($shadow); } diff --git a/mkspecs/features/qt_build_paths.prf b/mkspecs/features/qt_build_paths.prf index 1848f00e90..3bb3823a8e 100644 --- a/mkspecs/features/qt_build_paths.prf +++ b/mkspecs/features/qt_build_paths.prf @@ -12,7 +12,8 @@ # Find the module's source root dir. isEmpty(_QMAKE_CONF_): error("Project has no top-level .qmake.conf file.") MODULE_BASE_INDIR = $$dirname(_QMAKE_CONF_) -MODULE_BASE_OUTDIR = $$shadowed($$MODULE_BASE_INDIR) +REAL_MODULE_BASE_OUTDIR = $$shadowed($$MODULE_BASE_INDIR) +MODULE_BASE_OUTDIR = $$REAL_MODULE_BASE_OUTDIR !isEmpty(MODULE_BASE_DIR): MODULE_SYNCQT_DIR = $$MODULE_BASE_DIR # compat for webkit isEmpty(MODULE_SYNCQT_DIR): MODULE_SYNCQT_DIR = $$MODULE_BASE_INDIR isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$MODULE_BASE_OUTDIR diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index bbded56b42..70d3520e5c 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -123,7 +123,7 @@ MODULE_INC_OUTDIR = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME isEmpty(MODULE_CFG_FILE): MODULE_CFG_FILE = qt$${MODULE}-config exists($$OUT_PWD/$${MODULE_CFG_FILE}.h) { - fwd_rel = $$relative_path($$OUT_PWD, $$MODULE_INC_OUTDIR) + fwd_rel = $$relative_path($$OUT_PWD, $$REAL_MODULE_BASE_OUTDIR) SYNCQT.INJECTIONS += \ $$fwd_rel/$${MODULE_CFG_FILE}.h:$${MODULE_CFG_FILE}.h \ $$fwd_rel/$${MODULE_CFG_FILE}_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/$${MODULE_CFG_FILE}_p.h @@ -131,7 +131,7 @@ exists($$OUT_PWD/$${MODULE_CFG_FILE}.h) { for (injection, SYNCQT.INJECTIONS) { injects = $$split(injection, :) - dst_hdr = $$absolute_path($$member(injects, 0), $$MODULE_INC_OUTDIR) + dst_hdr = $$absolute_path($$member(injects, 0), $$REAL_MODULE_BASE_OUTDIR) ofwd_hdr = $$member(injects, 1) fwd_hdr = $$replace(ofwd_hdr, ^\\^, ) MAIN_FWD = $$MODULE_INC_OUTDIR/$$fwd_hdr From 73af8e75534732f64b606131d53460bd22d212de Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 6 Sep 2018 11:18:38 +0200 Subject: [PATCH 09/15] Add optimized fetch ARGB32 routines for NEON After convert and fetch were split, only convert was still NEON vectorized, while fetch is the more commonly used version. Change-Id: Iea2af7ccee6589b3d6e9908afeaae2d1ad2753be Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 6 ++++++ src/gui/painting/qdrawhelper_neon.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+) 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 *); extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const QVector *); + extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); + extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, + const QVector *, 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(buffer, buffer, count); } +const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToARGB32PM_neon(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + +const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToARGB32PM_neon(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + #endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN QT_END_NAMESPACE From 48897f97e726dd34559b9fa213501ea24bfb692d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 10 Sep 2018 09:45:16 +0200 Subject: [PATCH 10/15] Fix src access with staging buffer in hellovulkantexture Change-Id: Iafcd94ec812a61dcfae6da43b1ca9f5771e05e56 Reviewed-by: Andy Nichols --- examples/vulkan/hellovulkantexture/hellovulkantexture.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp index 67ae0ca5dc..c3dc891efa 100644 --- a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp +++ b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp @@ -294,12 +294,12 @@ void VulkanRenderer::ensureTexture() barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.srcAccessMask = 0; // VK_ACCESS_HOST_WRITE_BIT ### no, keep validation layer happy (??) + barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); @@ -312,7 +312,7 @@ void VulkanRenderer::ensureTexture() barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; barrier.image = m_texStaging; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); From 1c6bd414dd1c8d1e87b5310cf704a2a8a2966ee4 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 10 Sep 2018 10:04:36 +0200 Subject: [PATCH 11/15] Fix device local alloc in hellovulkantexture Running with QT_VK_FORCE_STAGE_TEX does not work at all with recent NVIDIA drivers due to QVulkanWindow's and the example's naive way of picking the memory index. Enhance this and add a warning note to the QVulkanWindow docs as well. Change-Id: I7f200e11d982b56e3da3b71ee3915bd7bfca5cc1 Reviewed-by: Andy Nichols --- .../vulkan/hellovulkantexture/hellovulkantexture.cpp | 10 ++++++++++ src/gui/vulkan/qvulkanwindow.cpp | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp index c3dc891efa..257191ef4e 100644 --- a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp +++ b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp @@ -223,6 +223,16 @@ bool VulkanRenderer::createTextureImage(const QSize &size, VkImage *image, VkDev VkMemoryRequirements memReq; m_devFuncs->vkGetImageMemoryRequirements(dev, *image, &memReq); + if (!(memReq.memoryTypeBits & (1 << memIndex))) { + VkPhysicalDeviceMemoryProperties physDevMemProps; + m_window->vulkanInstance()->functions()->vkGetPhysicalDeviceMemoryProperties(m_window->physicalDevice(), &physDevMemProps); + for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) { + if (!(memReq.memoryTypeBits & (1 << i))) + continue; + memIndex = i; + } + } + VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr, diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index e45a16170e..9f3655505c 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -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 { From d6c7089e6cccfd907f90640a83ce42a7ebf49f0a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 10 Sep 2018 10:27:22 +0200 Subject: [PATCH 12/15] QVulkanWindow: Fix bogus stage masks in readback Change-Id: I08882a02204c95272b100647923c9903f825912c Reviewed-by: Andy Nichols --- src/gui/vulkan/qvulkanwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index 9f3655505c..87e21b7784 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -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); } From 2d82cb7d779c2fa1fc54ecc7c98f66b125856dff Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 10 Sep 2018 10:24:20 +0200 Subject: [PATCH 13/15] QVulkanWindow: Fix some load/store ops in the default renderpass Stencil is - very likely - cleared just like depth. Also, switch to STORE_OP_STORE for the multisample buffer, for correctness. Change-Id: I31b56658286205af8551018115ca2abbe541be67 Reviewed-by: Andy Nichols --- src/gui/vulkan/qvulkanwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index 87e21b7784..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; From 9d1c881f491363f330284ddb177cbee5f3e9952d Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 15 Aug 2018 10:58:12 +0200 Subject: [PATCH 14/15] Texture file support: add mipmap reading to ktx handler Change-Id: Ic2c10b3e64d63d2272a8a3922d2b3f99dfd45bdb Reviewed-by: Laszlo Agocs --- src/gui/util/qktxhandler.cpp | 30 ++++++++++----- .../qtexturefilereader/qtexturefilereader.qrc | 1 + .../texturefiles/car_mips.ktx | Bin 0 -> 8088 bytes .../tst_qtexturefilereader.cpp | 36 ++++++++++++------ 4 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx 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 //#define KTX_DEBUG +#ifdef KTX_DEBUG +#include +#include +#include +#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(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(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/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc index 74f33d57ad..ab882b5db2 100644 --- a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc +++ b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc @@ -2,5 +2,6 @@ texturefiles/car.ktx texturefiles/pattern.pkm + texturefiles/car_mips.ktx diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx b/tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx new file mode 100644 index 0000000000000000000000000000000000000000..82822e6c0b2ee78c8948fc6a130d3e144cad424c GIT binary patch literal 8088 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 o("size"); QTest::addColumn("glFormat"); QTest::addColumn("glInternalFormat"); - // todo: glBaseInternalFormat + QTest::addColumn("glBaseInternalFormat"); QTest::addColumn("levels"); - QTest::addColumn("dataOffset"); - QTest::addColumn("dataLength"); + QTest::addColumn>("dataOffsets"); + QTest::addColumn>("dataLengths"); QTest::addRow("pattern.pkm") << QStringLiteral(":/texturefiles/pattern.pkm") << QSize(64, 64) << quint32(0x0) << quint32(0x8d64) + << quint32(0x0) << 1 - << 16 - << 2048; + << (QList() << 16) + << (QList() << 2048); QTest::addRow("car.ktx") << QStringLiteral(":/texturefiles/car.ktx") << QSize(146, 80) << quint32(0x0) << quint32(0x9278) + << quint32(0x1908) << 1 - << 68 - << 11840; + << (QList() << 68) + << (QList() << 11840); + + QTest::addRow("car_mips.ktx") << QStringLiteral(":/texturefiles/car_mips.ktx") + << QSize(146, 80) + << quint32(0x0) + << quint32(0x9274) + << quint32(0x1907) + << 8 + << (QList() << 68 << 5992 << 7516 << 7880 << 8004 << 8056 << 8068 << 8080) + << (QList() << 5920 << 1520 << 360 << 120 << 48 << 8 << 8 << 8); + } void tst_qtexturefilereader::checkHandlers() @@ -73,8 +85,8 @@ void tst_qtexturefilereader::checkHandlers() QFETCH(quint32, glFormat); QFETCH(quint32, glInternalFormat); QFETCH(int, levels); - QFETCH(int, dataOffset); - QFETCH(int, dataLength); + QFETCH(QList, dataOffsets); + QFETCH(QList, dataLengths); QFile f(fileName); QVERIFY(f.open(QIODevice::ReadOnly)); @@ -88,8 +100,10 @@ void tst_qtexturefilereader::checkHandlers() QCOMPARE(tex.glFormat(), glFormat); QCOMPARE(tex.glInternalFormat(), glInternalFormat); QCOMPARE(tex.numLevels(), levels); - QCOMPARE(tex.dataOffset(), dataOffset); - QCOMPARE(tex.dataLength(), dataLength); + for (int i = 0; i < tex.numLevels(); i++) { + QCOMPARE(tex.dataOffset(i), dataOffsets.at(i)); + QCOMPARE(tex.dataLength(i), dataLengths.at(i)); + } } QTEST_MAIN(tst_qtexturefilereader) From 0d1481b4d26997bab9ab9a6200776b27b9826ba6 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 5 Sep 2018 21:32:14 +0200 Subject: [PATCH 15/15] SQL PostgreSQL/SQlite: Properly decode default varchar parameter The default values for varchar columns were not decoded properly. Task-number: QTBUG-46968 Change-Id: Ie13d48c316cd694240f7e287010b97afc8c6c341 Reviewed-by: Robert Szefner Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 7 +++++-- src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 9 ++++++++- .../sql/kernel/qsqldriver/tst_qsqldriver.cpp | 20 +++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) 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; diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp index 7bfa29ec8e..15190b0f3e 100644 --- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp @@ -54,6 +54,18 @@ private slots: void formatValue(); }; +static bool driverSupportsDefaultValues(QSqlDriver::DbmsType dbType) +{ + switch (dbType) { + case QSqlDriver::SQLite: + case QSqlDriver::PostgreSQL: + case QSqlDriver::Oracle: + return true; + default: + break; + } + return false; +} void tst_QSqlDriver::initTestCase_data() { @@ -81,8 +93,9 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) doubleField = "more_data double precision"; else doubleField = "more_data double(8,7)"; + const QString defValue(driverSupportsDefaultValues(dbType) ? QStringLiteral("DEFAULT 'defaultVal'") : QString()); QVERIFY_SQL( q, exec("create table " + relTEST1 + - " (id int not null primary key, name varchar(20), title_key int, another_title_key int, " + doubleField + QLatin1Char(')'))); + " (id int not null primary key, name varchar(20) " + defValue + ", title_key int, another_title_key int, " + doubleField + QLatin1Char(')'))); QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(1, 'harry', 1, 2, 1.234567)")); QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(2, 'trond', 2, 1, 8.901234)")); QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(3, 'vohi', 1, 2, 5.678901)")); @@ -127,7 +140,7 @@ void tst_QSqlDriver::record() //check we can get records using an unquoted mixed case table name QSqlRecord rec = db.driver()->record(tablename); - QCOMPARE(rec.count(), 5); + QCOMPARE(rec.count(), fields.size()); QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); // QTBUG-1363: QSqlField::length() always return -1 when using QODBC3 driver and QSqlDatabase::record() @@ -141,6 +154,9 @@ void tst_QSqlDriver::record() for (int i = 0; i < fields.count(); ++i) QCOMPARE(rec.fieldName(i), fields[i]); + if (driverSupportsDefaultValues(dbType)) + QCOMPARE(rec.field(QStringLiteral("name")).defaultValue().toString(), QStringLiteral("defaultVal")); + if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2) tablename = tablename.toUpper(); else if (dbType == QSqlDriver::PostgreSQL)