summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/configure.json20
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/doc/snippets/hellotrmain.cpp4
-rw-r--r--src/corelib/global/qlibraryinfo.cpp208
-rw-r--r--src/corelib/global/qlogging.cpp4
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp8
-rw-r--r--src/corelib/global/qoperatingsystemversion.h1
-rw-r--r--src/corelib/global/qrandom.cpp19
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp13
-rw-r--r--src/corelib/io/qtldurl.cpp8
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp13
-rw-r--r--src/corelib/kernel/qcoreapplication.h3
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp23
-rw-r--r--src/corelib/kernel/qpointer.h15
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/thread/qbasicatomic.h12
-rw-r--r--src/corelib/thread/qreadwritelock.cpp50
-rw-r--r--src/corelib/thread/qreadwritelock_p.h32
-rw-r--r--src/corelib/time/qcalendar.cpp484
-rw-r--r--src/corelib/time/qdatetime.cpp53
-rw-r--r--src/corelib/time/qhijricalendar.cpp47
-rw-r--r--src/corelib/time/qislamiccivilcalendar.cpp32
-rw-r--r--src/corelib/time/qromancalendar.cpp20
-rw-r--r--src/corelib/time/qtimezone.cpp23
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp48
-rw-r--r--src/corelib/time/qtimezoneprivate_p.h3
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp42
-rw-r--r--src/corelib/tools/qcontainertools_impl.h4
-rw-r--r--src/gui/image/qiconloader.cpp2
-rw-r--r--src/gui/image/qimage.cpp2
-rw-r--r--src/gui/image/qimage_conversions.cpp218
-rw-r--r--src/gui/image/qimagereader.cpp6
-rw-r--r--src/gui/image/qpicture.cpp3
-rw-r--r--src/gui/kernel/qguiapplication.cpp19
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp9
-rw-r--r--src/gui/kernel/qopenglcontext.cpp11
-rw-r--r--src/gui/kernel/qtouchdevice.cpp10
-rw-r--r--src/gui/painting/qcolormatrix_p.h22
-rw-r--r--src/gui/painting/qcolorspace.cpp39
-rw-r--r--src/gui/painting/qcolorspace.h9
-rw-r--r--src/gui/painting/qcolorspace_p.h6
-rw-r--r--src/gui/painting/qcolortransferfunction_p.h4
-rw-r--r--src/gui/painting/qcolortransform.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp45
-rw-r--r--src/gui/painting/qicc.cpp3
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp20
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/rhi/cs_tdr.h209
-rw-r--r--src/gui/rhi/qrhi.cpp152
-rw-r--r--src/gui/rhi/qrhi_p.h9
-rw-r--r--src/gui/rhi/qrhi_p_p.h6
-rw-r--r--src/gui/rhi/qrhid3d11.cpp509
-rw-r--r--src/gui/rhi/qrhid3d11_p.h3
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h27
-rw-r--r--src/gui/rhi/qrhigles2.cpp219
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h7
-rw-r--r--src/gui/rhi/qrhimetal.mm502
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h4
-rw-r--r--src/gui/rhi/qrhinull.cpp13
-rw-r--r--src/gui/rhi/qrhinull_p_p.h4
-rw-r--r--src/gui/rhi/qrhiprofiler.cpp14
-rw-r--r--src/gui/rhi/qrhiprofiler_p_p.h6
-rw-r--r--src/gui/rhi/qrhivulkan.cpp387
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h5
-rw-r--r--src/gui/rhi/tdr.hlsl9
-rw-r--r--src/gui/text/qtextdocument.cpp5
-rw-r--r--src/gui/text/qtextengine.cpp15
-rw-r--r--src/gui/text/qtextformat.cpp1
-rw-r--r--src/network/access/qhttp2configuration.cpp2
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp25
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp3
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp21
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp8
-rw-r--r--src/network/access/qnetworkrequest.cpp13
-rw-r--r--src/network/access/qnetworkrequest.h12
-rw-r--r--src/network/kernel/qnetconmonitor_win.cpp4
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp5
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp16
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h1
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm201
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h1
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp2
-rw-r--r--src/plugins/platforms/android/android.pro4
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm6
-rw-r--r--src/plugins/platforms/cocoa/qnsview_dragging.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnswindow.mm4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp256
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp3
-rw-r--r--src/plugins/platforms/windows/windows.pri2
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp12
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp26
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h2
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp10
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp18
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp38
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp21
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp11
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp24
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp12
-rw-r--r--src/plugins/styles/windowsvista/main.cpp4
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp113
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp158
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h61
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp39
-rw-r--r--src/widgets/doc/snippets/qsplashscreen/main.cpp7
-rw-r--r--src/widgets/graphicsview/qgraphicsview.h4
-rw-r--r--src/widgets/kernel/qshortcut.cpp6
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp30
-rw-r--r--src/widgets/styles/qwindowsstyle_p_p.h4
-rw-r--r--src/widgets/widgets/qcombobox.cpp36
-rw-r--r--src/widgets/widgets/qcombobox_p.h10
-rw-r--r--src/widgets/widgets/qmenu.cpp17
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp38
-rw-r--r--src/widgets/widgets/qsplashscreen.h4
129 files changed, 3177 insertions, 1959 deletions
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index f7b6d41534..ae360239c6 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -158,21 +158,6 @@
"-latomic"
]
},
- "libdl": {
- "label": "dlopen()",
- "test": {
- "main": [
- "dlclose(dlopen(0, 0));",
- "dlsym(RTLD_DEFAULT, 0);",
- "dlerror();"
- ]
- },
- "headers": "dlfcn.h",
- "sources": [
- "",
- "-ldl"
- ]
- },
"librt": {
"label": "clock_gettime()",
"test": {
@@ -612,11 +597,6 @@
"condition": "features.clock-gettime && tests.clock-monotonic",
"output": [ "feature" ]
},
- "dlopen": {
- "label": "dlopen()",
- "condition": "config.unix && libs.libdl",
- "output": [ "privateFeature" ]
- },
"doubleconversion": {
"label": "DoubleConversion",
"output": [ "privateFeature", "feature" ]
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 121db51eb5..ba5f5adf8d 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -21,7 +21,7 @@ CONFIG += simd optimize_full
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
ANDROID_LIB_DEPENDENCIES = \
- plugins/platforms/android/libqtforandroid.so
+ plugins/platforms/libqtforandroid.so
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
jar/QtAndroid.jar
ANDROID_PERMISSIONS = \
diff --git a/src/corelib/doc/snippets/hellotrmain.cpp b/src/corelib/doc/snippets/hellotrmain.cpp
index 2fab919a47..721a83240b 100644
--- a/src/corelib/doc/snippets/hellotrmain.cpp
+++ b/src/corelib/doc/snippets/hellotrmain.cpp
@@ -56,13 +56,13 @@ int main(int argc, char *argv[])
QTranslator translator;
// look up e.g. :/translations/myapp_de.qm
if (translator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/translations")))
- app.installTranslator(&translator);
+ QCoreApplication::installTranslator(&translator);
QPushButton hello(QCoreApplication::translate("main", "Hello world!"));
hello.resize(100, 30);
hello.show();
- return app.exec();
+ return QCoreApplication::exec();
}
//! [0]
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 4c1b04f05e..c7357f9d13 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -55,15 +55,24 @@ QT_END_NAMESPACE
# include "qcoreapplication.h"
#endif
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
+# include "private/qglobal_p.h"
+# include "qconfig.cpp"
+#endif
+
#ifdef Q_OS_DARWIN
# include "private/qcore_mac_p.h"
-#endif
+#endif // Q_OS_DARWIN
-#ifndef QT_BUILD_QMAKE_BOOTSTRAP
-# include "qconfig.cpp"
+#include "archdetect.cpp"
+
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && QT_CONFIG(dlopen) && !QT_CONFIG(framework)
+# include <dlfcn.h>
#endif
-#include "archdetect.cpp"
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable) && defined(Q_OS_WIN)
+# include <qt_windows.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -453,6 +462,160 @@ void QLibraryInfo::sysrootify(QString *path)
}
#endif // QT_BUILD_QMAKE
+#ifndef QT_BUILD_QMAKE
+static QString prefixFromAppDirHelper()
+{
+ QString appDir;
+
+ if (QCoreApplication::instance()) {
+#ifdef Q_OS_DARWIN
+ CFBundleRef bundleRef = CFBundleGetMainBundle();
+ if (bundleRef) {
+ QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
+ if (urlRef) {
+ QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
+#ifdef Q_OS_MACOS
+ QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
+ if (QDir(bundleContentsDir).exists())
+ return QDir::cleanPath(bundleContentsDir);
+#else
+ return QDir::cleanPath(QString(path)); // iOS
+#endif // Q_OS_MACOS
+ }
+ }
+#endif // Q_OS_DARWIN
+ // We make the prefix path absolute to the executable's directory.
+ appDir = QCoreApplication::applicationDirPath();
+ } else {
+ appDir = QDir::currentPath();
+ }
+
+ return appDir;
+}
+#endif
+
+#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(relocatable)
+static QString prefixFromQtCoreLibraryHelper(const QString &qtCoreLibraryPath)
+{
+ const QString qtCoreLibrary = QDir::fromNativeSeparators(qtCoreLibraryPath);
+ const QString libDir = QFileInfo(qtCoreLibrary).absolutePath();
+ const QString prefixDir = libDir + QLatin1Char('/')
+ + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+ return QDir::cleanPath(prefixDir);
+}
+
+#if defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT)
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+static HMODULE getWindowsModuleHandle()
+{
+ return reinterpret_cast<HMODULE>(&__ImageBase);
+}
+#else // Q_OS_WINRT
+static HMODULE getWindowsModuleHandle()
+{
+ HMODULE hModule = NULL;
+ GetModuleHandleEx(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (LPCTSTR)&QLibraryInfo::isDebugBuild, &hModule);
+ return hModule;
+}
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
+
+static QString getRelocatablePrefix()
+{
+ QString prefixPath;
+
+ // For static builds, the prefix will be the app directory.
+ // For regular builds, the prefix will be relative to the location of the QtCore shared library.
+#if defined(QT_STATIC)
+ prefixPath = prefixFromAppDirHelper();
+#elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
+ CFBundleRef qtCoreBundle = CFBundleGetBundleWithIdentifier(
+ CFSTR("org.qt-project.QtCore"));
+ Q_ASSERT(qtCoreBundle);
+
+ QCFType<CFURLRef> qtCorePath = CFBundleCopyBundleURL(qtCoreBundle);
+ Q_ASSERT(qtCorePath);
+
+ QCFType<CFURLRef> qtCorePathAbsolute = CFURLCopyAbsoluteURL(qtCorePath);
+ Q_ASSERT(qtCorePathAbsolute);
+
+ QCFType<CFURLRef> libDirCFPath = CFURLCreateCopyDeletingLastPathComponent(NULL, qtCorePathAbsolute);
+
+ const QCFString libDirCFString = CFURLCopyFileSystemPath(libDirCFPath, kCFURLPOSIXPathStyle);
+
+ const QString prefixDir = QString(libDirCFString) + QLatin1Char('/')
+ + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+
+ prefixPath = QDir::cleanPath(prefixDir);
+#elif QT_CONFIG(dlopen)
+ Dl_info info;
+ int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info);
+ if (result > 0 && info.dli_fname)
+ prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLatin1(info.dli_fname));
+#elif defined(Q_OS_WIN)
+ HMODULE hModule = getWindowsModuleHandle();
+ const int kBufferSize = 4096;
+ wchar_t buffer[kBufferSize];
+ const int pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
+ if (pathSize > 0)
+ prefixPath = prefixFromQtCoreLibraryHelper(QString::fromWCharArray(buffer, pathSize));
+#else
+#error "The chosen platform / config does not support querying for a dynamic prefix."
+#endif
+
+ Q_ASSERT_X(!prefixPath.isEmpty(), "getRelocatablePrefix",
+ "Failed to find the Qt prefix path.");
+ return prefixPath;
+}
+#endif
+
+#if defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_QMAKE_BOOTSTRAP)
+QString qmake_abslocation();
+
+static QString getPrefixFromHostBinDir(const char *hostBinDirToPrefixPath)
+{
+ const QFileInfo qmfi = QFileInfo(qmake_abslocation()).canonicalFilePath();
+ return QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/')
+ + QLatin1String(hostBinDirToPrefixPath));
+}
+
+static QString getExtPrefixFromHostBinDir()
+{
+ return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH);
+}
+
+static QString getHostPrefixFromHostBinDir()
+{
+ return getPrefixFromHostBinDir(QT_CONFIGURE_HOSTBINDIR_TO_HOSTPREFIX_PATH);
+}
+#endif
+
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
+static const char *getPrefix(
+#ifdef QT_BUILD_QMAKE
+ QLibraryInfo::PathGroup group
+#endif
+ )
+{
+#if defined(QT_BUILD_QMAKE)
+# if QT_CONFIGURE_CROSSBUILD
+ if (group == QLibraryInfo::DevicePaths)
+ return QT_CONFIGURE_PREFIX_PATH;
+# endif
+ static QByteArray extPrefixPath = getExtPrefixFromHostBinDir().toLatin1();
+ return extPrefixPath.constData();
+#elif QT_CONFIG(relocatable)
+ static QByteArray prefixPath = getRelocatablePrefix().toLatin1();
+ return prefixPath.constData();
+#else
+ return QT_CONFIGURE_PREFIX_PATH;
+#endif
+}
+#endif // QT_BUILD_QMAKE_BOOTSTRAP
+
/*!
Returns the location specified by \a loc.
*/
@@ -564,12 +727,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
if (!fromConf) {
const char * volatile path = 0;
if (loc == PrefixPath) {
- path =
-# ifdef QT_BUILD_QMAKE
- (group != DevicePaths) ?
- QT_CONFIGURE_EXT_PREFIX_PATH :
-# endif
- QT_CONFIGURE_PREFIX_PATH;
+ path = getPrefix(
+#ifdef QT_BUILD_QMAKE
+ group
+#endif
+ );
} else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
#ifndef Q_OS_WIN // On Windows we use the registry
@@ -578,7 +740,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
#endif
# ifdef QT_BUILD_QMAKE
} else if (loc == HostPrefixPath) {
- path = QT_CONFIGURE_HOST_PREFIX_PATH;
+ static const QByteArray hostPrefixPath = getHostPrefixFromHostBinDir().toLatin1();
+ path = hostPrefixPath.constData();
# endif
}
@@ -612,28 +775,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
}
#else
if (loc == PrefixPath) {
- if (QCoreApplication::instance()) {
-#ifdef Q_OS_DARWIN
- CFBundleRef bundleRef = CFBundleGetMainBundle();
- if (bundleRef) {
- QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
- if (urlRef) {
- QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
-#ifdef Q_OS_OSX
- QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
- if (QDir(bundleContentsDir).exists())
- return QDir::cleanPath(bundleContentsDir + ret);
-#else
- return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
-#endif // Q_OS_OSX
- }
- }
-#endif // Q_OS_DARWIN
- // We make the prefix path absolute to the executable's directory.
- baseDir = QCoreApplication::applicationDirPath();
- } else {
- baseDir = QDir::currentPath();
- }
+ baseDir = prefixFromAppDirHelper();
} else {
// we make any other path absolute to the prefix directory
baseDir = location(PrefixPath);
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index cebab1daef..17f2246082 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1803,8 +1803,8 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
#ifndef QT_BOOTSTRAPPED
Q_TRACE(qt_message_print, msgType, context.category, context.function, context.file, context.line, message);
- // qDebug, qWarning, ... macros do not check whether category is enabled
- if (isDefaultCategory(context.category)) {
+ // qDebug, qWarning, ... macros do not check whether category is enabledgc
+ if (msgType != QtFatalMsg && isDefaultCategory(context.category)) {
if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
if (!defaultCategory->isEnabled(msgType))
return;
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 886aedb4f3..cce88782e9 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -3287,7 +3287,7 @@
the application object is created, or by setting the QT_SCALE_FACTOR_ROUNDING_POLICY
environment variable.
- \sa QGuiApplication::setHighDdpiScaleFactorRoundingPolicy()
+ \sa QGuiApplication::setHighDpiScaleFactorRoundingPolicy()
\sa AA_EnableHighDpiScaling.
\omitvalue Unset
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index ded86cbc4e..33793ca168 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -356,14 +356,6 @@ bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) c
}
/*!
- \variable QOperatingSystemVersion::WindowsVista
- \brief a version corresponding to Windows Vista (version 6.0).
- \since 6.0
- */
-const QOperatingSystemVersion QOperatingSystemVersion::WindowsVista =
- QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 0);
-
-/*!
\variable QOperatingSystemVersion::Windows7
\brief a version corresponding to Windows 7 (version 6.1).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index 879bd379b0..f22878de89 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -60,7 +60,6 @@ public:
Android
};
- static const QOperatingSystemVersion WindowsVista;
static const QOperatingSystemVersion Windows7;
static const QOperatingSystemVersion Windows8;
static const QOperatingSystemVersion Windows8_1;
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 711eb8f4d5..e5b2399566 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -103,17 +103,22 @@ static QT_FUNCTION_TARGET(RDRND) qsizetype qt_random_cpu(void *buffer, qsizetype
{
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
unsigned *end = ptr + count;
+ int retries = 10;
while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
- if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)) == 0)
+ if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
+ ptr += sizeof(qregisteruint)/sizeof(*ptr);
+ else if (--retries == 0)
goto out;
- ptr += sizeof(qregisteruint)/sizeof(*ptr);
}
- if (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
- if (_rdrand32_step(ptr))
- goto out;
- ++ptr;
+ while (sizeof(*ptr) != sizeof(qregisteruint) && ptr != end) {
+ bool ok = _rdrand32_step(ptr);
+ if (!ok && --retries)
+ continue;
+ if (ok)
+ ++ptr;
+ break;
}
out:
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 64c422c55a..a4705136a2 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -41,9 +41,9 @@
#include "qfilesystemwatcher_p.h"
#include <qdatetime.h>
-#include <qdebug.h>
#include <qdir.h>
#include <qfileinfo.h>
+#include <qloggingcategory.h>
#include <qset.h>
#include <qtimer.h>
@@ -67,6 +67,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcWatcher, "qt.core.filesystemwatcher")
+
QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent)
{
#if defined(Q_OS_WIN)
@@ -137,6 +139,7 @@ void QFileSystemWatcherPrivate::initPollerEngine()
void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed)
{
Q_Q(QFileSystemWatcher);
+ qCDebug(lcWatcher) << "file changed" << path << "removed?" << removed << "watching?" << files.contains(path);
if (!files.contains(path)) {
// the path was removed after a change was detected, but before we delivered the signal
return;
@@ -149,6 +152,7 @@ void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
{
Q_Q(QFileSystemWatcher);
+ qCDebug(lcWatcher) << "directory changed" << path << "removed?" << removed << "watching?" << directories.contains(path);
if (!directories.contains(path)) {
// perhaps the path was removed after a change was detected, but before we delivered the signal
return;
@@ -355,7 +359,7 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
qWarning("QFileSystemWatcher::addPaths: list is empty");
return p;
}
-
+ qCDebug(lcWatcher) << "adding" << paths;
const auto selectEngine = [this, d]() -> QFileSystemWatcherEngine* {
#ifdef QT_BUILD_INTERNAL
const QString on = objectName();
@@ -364,11 +368,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
// Autotest override case - use the explicitly selected engine only
const QStringRef forceName = on.midRef(26);
if (forceName == QLatin1String("poller")) {
- qDebug("QFileSystemWatcher: skipping native engine, using only polling engine");
+ qCDebug(lcWatcher, "QFileSystemWatcher: skipping native engine, using only polling engine");
d_func()->initPollerEngine();
return d->poller;
} else if (forceName == QLatin1String("native")) {
- qDebug("QFileSystemWatcher: skipping polling engine, using only native engine");
+ qCDebug(lcWatcher, "QFileSystemWatcher: skipping polling engine, using only native engine");
return d->native;
}
return nullptr;
@@ -431,6 +435,7 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
qWarning("QFileSystemWatcher::removePaths: list is empty");
return p;
}
+ qCDebug(lcWatcher) << "removing" << paths;
if (d->native)
p = d->native->removePaths(p, &d->files, &d->directories);
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index 912609ec91..fc3e16b241 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -125,10 +125,10 @@ Q_CORE_EXPORT bool qIsEffectiveTLD(const QStringRef &domain)
return true;
const int dot = domain.indexOf(QLatin1Char('.'));
- if (dot >= 0) {
- if (containsTLDEntry(domain.mid(dot), SuffixMatch)) // 2
- return !containsTLDEntry(domain, ExceptionMatch); // 3
- }
+ if (dot < 0) // Actual TLD: may be effective if the subject of a wildcard rule:
+ return containsTLDEntry(QString(QLatin1Char('.') + domain), SuffixMatch);
+ if (containsTLDEntry(domain.mid(dot), SuffixMatch)) // 2
+ return !containsTLDEntry(domain, ExceptionMatch); // 3
return false;
}
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6647ea99f5..c537e8f51b 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2693,7 +2693,14 @@ Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
QStringList QCoreApplication::libraryPaths()
{
QMutexLocker locker(libraryPathMutex());
+ return libraryPathsLocked();
+}
+/*!
+ \internal
+*/
+QStringList QCoreApplication::libraryPathsLocked()
+{
if (coreappdata()->manual_libpaths)
return *(coreappdata()->manual_libpaths);
@@ -2769,7 +2776,7 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
// When the application is constructed it should still amend the paths. So we keep the originals
// around, and even create them if they don't exist, yet.
if (!coreappdata()->app_libpaths)
- libraryPaths();
+ libraryPathsLocked();
if (coreappdata()->manual_libpaths)
*(coreappdata()->manual_libpaths) = paths;
@@ -2812,7 +2819,7 @@ void QCoreApplication::addLibraryPath(const QString &path)
return;
} else {
// make sure that library paths are initialized
- libraryPaths();
+ libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (app_libpaths->contains(canonicalPath))
return;
@@ -2851,7 +2858,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
return;
} else {
// make sure that library paths is initialized
- libraryPaths();
+ libraryPathsLocked();
QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths->contains(canonicalPath))
return;
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index b7df004736..71ea124fbe 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -208,6 +208,9 @@ private:
static bool notifyInternal2(QObject *receiver, QEvent *);
static bool forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent = nullptr);
#endif
+#if QT_CONFIG(library)
+ static QStringList libraryPathsLocked();
+#endif
static QCoreApplication *self;
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 600c6c38fd..f7a1f969a8 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -44,12 +44,13 @@
#include <QtCore/QHash>
#include <QtCore/QMutex>
#include <QtCore/QSemaphore>
-#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
#include <functional>
+#include <memory>
+
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.system.threading.h>
@@ -300,19 +301,19 @@ HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &d
if (QThread::currentThread() == QCoreApplication::instance()->thread())
return delegate();
- auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore);
- auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore);
- auto result = QSharedPointer<HRESULT>(new HRESULT);
- auto ptrResult = new QSharedPointer<HRESULT>(result);
+ struct State {
+ QSemaphore semaphore;
+ HRESULT result;
+ };
+
+ const auto state = std::make_shared<State>();
- QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() {
- **ptrResult = delegate();
- delete ptrResult;
- (*ptrSemaphore)->release();
- delete ptrSemaphore;
+ QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, state]() {
+ const QSemaphoreReleaser releaser{state->semaphore};
+ state->result = delegate();
}, nullptr);
- return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL;
+ return state->semaphore.tryAcquire(1, timeout) ? state->result : E_FAIL;
}
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index 7052bcf0d4..5efdb0b395 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -54,20 +54,11 @@ class QPointer
{
Q_STATIC_ASSERT_X(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
- template<typename U>
- struct TypeSelector
- {
- typedef QObject Type;
- };
- template<typename U>
- struct TypeSelector<const U>
- {
- typedef const QObject Type;
- };
- typedef typename TypeSelector<T>::Type QObjectType;
+ using QObjectType =
+ typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
QWeakPointer<QObjectType> wp;
public:
- inline QPointer() { }
+ QPointer() = default;
inline QPointer(T *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine!
// compiler-generated dtor is fine!
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 1ace28c93f..98a198df43 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
# define QLIBRARY_AS_DEBUG true
#endif
-#if defined(Q_OS_UNIX) || defined(Q_CC_MINGW)
+#if defined(Q_OS_UNIX)
// We don't use separate debug and release libs on UNIX, so we want
// to allow loading plugins, regardless of how they were built.
# define QT_NO_DEBUG_PLUGIN_CHECK
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index dc976819ef..9804e60119 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -99,8 +99,10 @@ public:
typename Ops::Type _q_value;
// Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h
- T load() const noexcept { return loadRelaxed(); }
- void store(T newValue) noexcept { storeRelaxed(newValue); }
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") T load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(T newValue) noexcept { storeRelaxed(newValue); }
+#endif
T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
@@ -238,8 +240,10 @@ public:
AtomicType _q_value;
- Type load() const noexcept { return loadRelaxed(); }
- void store(Type newValue) noexcept { storeRelaxed(newValue); }
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") Type load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(Type newValue) noexcept { storeRelaxed(newValue); }
+#endif
Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 30e9b95a52..5aba05c1b9 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -48,6 +48,9 @@
#include "qreadwritelock_p.h"
#include "qelapsedtimer.h"
#include "private/qfreelist_p.h"
+#include "private/qlocking_p.h"
+
+#include <chrono>
QT_BEGIN_NAMESPACE
@@ -64,6 +67,9 @@ QT_BEGIN_NAMESPACE
*/
namespace {
+
+using ms = std::chrono::milliseconds;
+
enum {
StateMask = 0x3,
StateLockedForRead = 0x1,
@@ -262,7 +268,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
if (d->recursive)
return d->recursiveLockForRead(timeout);
- QMutexLocker lock(&d->mutex);
+ auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) {
// d_ptr has changed: this QReadWriteLock was unlocked before we had
// time to lock d->mutex.
@@ -273,7 +279,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
d = d_ptr.loadAcquire();
continue;
}
- return d->lockForRead(timeout);
+ return d->lockForRead(lock, timeout);
}
}
@@ -369,7 +375,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
if (d->recursive)
return d->recursiveLockForWrite(timeout);
- QMutexLocker lock(&d->mutex);
+ auto lock = qt_unique_lock(d->mutex);
if (d != d_ptr.loadRelaxed()) {
// The mutex was unlocked before we had time to lock the mutex.
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
@@ -377,7 +383,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
d = d_ptr.loadAcquire();
continue;
}
- return d->lockForWrite(timeout);
+ return d->lockForWrite(lock, timeout);
}
}
@@ -418,7 +424,7 @@ void QReadWriteLock::unlock()
return;
}
- QMutexLocker locker(&d->mutex);
+ const auto lock = qt_scoped_lock(d->mutex);
if (d->writerCount) {
Q_ASSERT(d->writerCount == 1);
Q_ASSERT(d->readerCount == 0);
@@ -460,9 +466,9 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
}
-bool QReadWriteLockPrivate::lockForRead(int timeout)
+bool QReadWriteLockPrivate::lockForRead(std::unique_lock<std::mutex> &lock, int timeout)
{
- Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+ Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
QElapsedTimer t;
if (timeout > 0)
@@ -476,10 +482,10 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
if (elapsed > timeout)
return false;
waitingReaders++;
- readerCond.wait(&mutex, timeout - elapsed);
+ readerCond.wait_for(lock, ms{timeout - elapsed});
} else {
waitingReaders++;
- readerCond.wait(&mutex);
+ readerCond.wait(lock);
}
waitingReaders--;
}
@@ -488,9 +494,9 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
return true;
}
-bool QReadWriteLockPrivate::lockForWrite(int timeout)
+bool QReadWriteLockPrivate::lockForWrite(std::unique_lock<std::mutex> &lock, int timeout)
{
- Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+ Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
QElapsedTimer t;
if (timeout > 0)
@@ -505,15 +511,15 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
if (waitingReaders && !waitingWriters && !writerCount) {
// We timed out and now there is no more writers or waiting writers, but some
// readers were queueud (probably because of us). Wake the waiting readers.
- readerCond.wakeAll();
+ readerCond.notify_all();
}
return false;
}
waitingWriters++;
- writerCond.wait(&mutex, timeout - elapsed);
+ writerCond.wait_for(lock, ms{timeout - elapsed});
} else {
waitingWriters++;
- writerCond.wait(&mutex);
+ writerCond.wait(lock);
}
waitingWriters--;
}
@@ -526,17 +532,17 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
void QReadWriteLockPrivate::unlock()
{
- Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+ Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function
if (waitingWriters)
- writerCond.wakeOne();
+ writerCond.notify_one();
else if (waitingReaders)
- readerCond.wakeAll();
+ readerCond.notify_all();
}
bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
@@ -546,7 +552,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
return true;
}
- if (!lockForRead(timeout))
+ if (!lockForRead(lock, timeout))
return false;
currentReaders.insert(self, 1);
@@ -556,7 +562,7 @@ bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
if (currentWriter == self) {
@@ -564,7 +570,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
return true;
}
- if (!lockForWrite(timeout))
+ if (!lockForWrite(lock, timeout))
return false;
currentWriter = self;
@@ -574,7 +580,7 @@ bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
void QReadWriteLockPrivate::recursiveUnlock()
{
Q_ASSERT(recursive);
- QMutexLocker lock(&mutex);
+ auto lock = qt_unique_lock(mutex);
Qt::HANDLE self = QThread::currentThreadId();
if (self == currentWriter) {
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 31da2401c0..b2e782f9ee 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -54,7 +54,9 @@
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qhash.h>
-#include <QtCore/qwaitcondition.h>
+
+#include <mutex>
+#include <condition_variable>
QT_REQUIRE_CONFIG(thread);
@@ -63,38 +65,36 @@ QT_BEGIN_NAMESPACE
class QReadWriteLockPrivate
{
public:
- QReadWriteLockPrivate(bool isRecursive = false)
- : readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
- recursive(isRecursive), id(0), currentWriter(nullptr) {}
+ explicit QReadWriteLockPrivate(bool isRecursive = false)
+ : recursive(isRecursive) {}
- QMutex mutex;
- QWaitCondition writerCond;
- QWaitCondition readerCond;
- int readerCount;
- int writerCount;
- int waitingReaders;
- int waitingWriters;
+ std::mutex mutex;
+ std::condition_variable writerCond;
+ std::condition_variable readerCond;
+ int readerCount = 0;
+ int writerCount = 0;
+ int waitingReaders = 0;
+ int waitingWriters = 0;
const bool recursive;
//Called with the mutex locked
- bool lockForWrite(int timeout);
- bool lockForRead(int timeout);
+ bool lockForWrite(std::unique_lock<std::mutex> &lock, int timeout);
+ bool lockForRead(std::unique_lock<std::mutex> &lock, int timeout);
void unlock();
//memory management
- int id;
+ int id = 0;
void release();
static QReadWriteLockPrivate *allocate();
// Recusive mutex handling
- Qt::HANDLE currentWriter;
+ Qt::HANDLE currentWriter = {};
QHash<Qt::HANDLE, int> currentReaders;
// called with the mutex unlocked
bool recursiveLockForWrite(int timeout);
bool recursiveLockForRead(int timeout);
void recursiveUnlock();
-
};
QT_END_NAMESPACE
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index d31eee6632..d706f1d5ab 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -201,7 +201,7 @@ QCalendar::System QCalendarBackend::calendarSystem() const
}
/*!
- The primary name of this calendar.
+ The primary name of this calendar.
*/
QString QCalendar::name() const
{
@@ -221,8 +221,8 @@ QString QCalendar::name() const
Calendars with intercallary days may represent these as extra days of the
preceding month, or as short months separate from the usual ones. In the
former case, daysInMonth(month, year) should be the number of ordinary days
- in the month, although \c{isDateValid(year, month, day)} might return \c true for
- some larger values of \c day.
+ in the month, although \c{isDateValid(year, month, day)} might return \c true
+ for some larger values of \c day.
\sa daysInYear(), monthsInYear(), minimumDaysInMonth(), maximumDaysInMonth()
*/
@@ -440,101 +440,104 @@ int QCalendarBackend::dayOfWeek(qint64 jd) const
// Month and week-day name look-ups (implemented in qlocale.cpp):
/*!
- \fn QString QCalendarBackend::monthName(const QLocale &locale, int month, int year,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::monthName(const QLocale &locale, int month, int year,
+ QLocale::FormatType format) const
- Returns the name of the specified \a month in the given \a year for the chosen
- \a locale, using the given \a format to determine how complete the name is.
+ Returns the name of the specified \a month in the given \a year for the
+ chosen \a locale, using the given \a format to determine how complete the
+ name is.
- If \a year is Unspecified, return the name for the month that usually has this
- number within a typical year. Calendars with a leap month that isn't always
- the last may need to take account of the year to map the month number to the
- particular year's month with that number.
+ If \a year is Unspecified, return the name for the month that usually has
+ this number within a typical year. Calendars with a leap month that isn't
+ always the last may need to take account of the year to map the month number
+ to the particular year's month with that number.
- \note Backends for which CLDR provides data can configure the default
- implementation of the two month name look-up methods by arranging for
- localeMonthIndexData() and localeMonthData() to provide access to the CLDR
- data (see cldr2qlocalexml.py, qlocalexml2cpp.py and existing backends).
- Conversely, backends that override both month name look-up methods need not
- return anything meaningful from localeMonthIndexData() or localeMonthData().
+ \note Backends for which CLDR provides data can configure the default
+ implementation of the two month name look-up methods by arranging for
+ localeMonthIndexData() and localeMonthData() to provide access to the CLDR
+ data (see cldr2qlocalexml.py, qlocalexml2cpp.py and existing backends).
+ Conversely, backends that override both month name look-up methods need not
+ return anything meaningful from localeMonthIndexData() or localeMonthData().
- \sa standaloneMonthName(), QLocale::monthName()
+ \sa standaloneMonthName(), QLocale::monthName()
*/
/*!
- \fn QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int year
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int year
+ QLocale::FormatType format) const
- Returns the standalone name of the specified \a month in the chosen \a locale,
- using the specified \a format to determine how complete the name is.
+ Returns the standalone name of the specified \a month in the chosen \a
+ locale, using the specified \a format to determine how complete the name is.
- If \a year is Unspecified, return the standalone name for the month that
- usually has this number within a typical year. Calendars with a leap month
- that isn't always the last may need to take account of the year to map the
- month number to the particular year's month with that number.
+ If \a year is Unspecified, return the standalone name for the month that
+ usually has this number within a typical year. Calendars with a leap month
+ that isn't always the last may need to take account of the year to map the
+ month number to the particular year's month with that number.
- \sa monthName(), QLocale::standaloneMonthName()
+ \sa monthName(), QLocale::standaloneMonthName()
*/
/*!
- \fn QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
+ QLocale::FormatType format) const
- Returns the name of the specified \a day of the week in the chosen \a locale,
- using the specified \a format to determine how complete the name is.
+ Returns the name of the specified \a day of the week in the chosen \a
+ locale, using the specified \a format to determine how complete the name is.
- The base implementation handles \a day values from 1 to 7 using the day names
- CLDR provides, which are suitable for calendards that use the same
- (Hebrew-derived) week as the Gregorian calendar.
+ The base implementation handles \a day values from 1 to 7 using the day
+ names CLDR provides, which are suitable for calendards that use the same
+ (Hebrew-derived) week as the Gregorian calendar.
- Calendars whose dayOfWeek() returns a value outside the range from 1 to 7 need
- to reimplement this method to handle such extra week-day values. They can
- assume that \a day is a value returned by the same calendar's dayOfWeek().
+ Calendars whose dayOfWeek() returns a value outside the range from 1 to 7
+ need to reimplement this method to handle such extra week-day values. They
+ can assume that \a day is a value returned by the same calendar's
+ dayOfWeek().
- \sa dayOfWeek(), standaloneWeekDayName(), QLocale::dayName()
+ \sa dayOfWeek(), standaloneWeekDayName(), QLocale::dayName()
*/
/*!
- \fn QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
- QLocale::FormatType format) const
+ \fn QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
+ QLocale::FormatType format) const
- Returns the standalone name of the specified \a day of the week in the chosen
- \a locale, using the specified \a format to determine how complete the name
- is.
+ Returns the standalone name of the specified \a day of the week in the
+ chosen \a locale, using the specified \a format to determine how complete
+ the name is.
- The base implementation handles \a day values from 1 to 7 using the standalone
- day names CLDR provides, which are suitable for calendards that use the same
- (Hebrew-derived) week as the Gregorian calendar.
+ The base implementation handles \a day values from 1 to 7 using the
+ standalone day names CLDR provides, which are suitable for calendards that
+ use the same (Hebrew-derived) week as the Gregorian calendar.
- Calendars whose dayOfWeek() returns a value outside the range from 1 to 7 need
- to reimplement this method to handle such extra week-day values. They can
- assume that \a day is a value returned by the same calendar's dayOfWeek().
+ Calendars whose dayOfWeek() returns a value outside the range from 1 to 7
+ need to reimplement this method to handle such extra week-day values. They
+ can assume that \a day is a value returned by the same calendar's
+ dayOfWeek().
- \sa dayOfWeek(), weekDayName(), QLocale::standaloneDayName()
+ \sa dayOfWeek(), weekDayName(), QLocale::standaloneDayName()
*/
/*!
- \fn QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
- const QDate &dateOnly, const QTime &timeOnly,
- const QLocale &locale) const
-
- Returns a string representing a given date, time or date-time.
-
- If \a datetime is specified and valid, it is used and both date and time
- format tokens are converted to appropriate representations of the parts of the
- datetime. Otherwise, if \a dateOnly is valid, only date format tokens are
- converted; else, if \a timeOnly is valid, only time format tokens are
- converted. If none are valid, an empty string is returned.
-
- The specified \a locale influences how some format tokens are converted; for
- example, when substituting day and month names and their short-forms. For the
- supported formatting tokens, see QDate::toString() and QTime::toString(). As
- described above, the provided date, time and date-time determine which of
- these tokens are recognized: where these appear in \a format they are replaced
- by data. Any text in \a format not recognized as a format token is copied
- verbatim into the result string.
-
- \sa QDate::toString(), QTime::toString(), QDateTime::toString()
+ \fn QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
+ const QLocale &locale) const
+
+ Returns a string representing a given date, time or date-time.
+
+ If \a datetime is specified and valid, it is used and both date and time
+ format tokens are converted to appropriate representations of the parts of
+ the datetime. Otherwise, if \a dateOnly is valid, only date format tokens
+ are converted; else, if \a timeOnly is valid, only time format tokens are
+ converted. If none are valid, an empty string is returned.
+
+ The specified \a locale influences how some format tokens are converted; for
+ example, when substituting day and month names and their short-forms. For
+ the supported formatting tokens, see QDate::toString() and
+ QTime::toString(). As described above, the provided date, time and date-time
+ determine which of these tokens are recognized: where these appear in \a
+ format they are replaced by data. Any text in \a format not recognized as a
+ format token is copied verbatim into the result string.
+
+ \sa QDate::toString(), QTime::toString(), QDateTime::toString()
*/
// End of methods implemented in qlocale.cpp
@@ -571,16 +574,16 @@ bool QCalendarBackend::registerAlias(const QString &name)
}
/*!
- Returns a pointer to a named calendar backend.
+ Returns a pointer to a named calendar backend.
- If the given \a name is present in availableCalendars(), the backend matching
- it is returned; otherwise, \c nullptr is returned. Matching of names ignores
- case. Note that this won't provoke construction of a calendar backend, it will
- only return ones that have been instantiated (and not yet destroyed) by some
- other means. However, calendars available via the QCalendar::System enum are
- always registered when this is called.
+ If the given \a name is present in availableCalendars(), the backend
+ matching it is returned; otherwise, \c nullptr is returned. Matching of
+ names ignores case. Note that this won't provoke construction of a calendar
+ backend, it will only return ones that have been instantiated (and not yet
+ destroyed) by some other means. However, calendars available via the
+ QCalendar::System enum are always registered when this is called.
- \sa availableCalendars(), registerAlias(), fromEnum()
+ \sa availableCalendars(), registerAlias(), fromEnum()
*/
const QCalendarBackend *QCalendarBackend::fromName(QStringView name)
{
@@ -592,7 +595,7 @@ const QCalendarBackend *QCalendarBackend::fromName(QStringView name)
}
/*!
- \overload
+ \overload
*/
const QCalendarBackend *QCalendarBackend::fromName(QLatin1String name)
{
@@ -604,11 +607,11 @@ const QCalendarBackend *QCalendarBackend::fromName(QLatin1String name)
}
/*!
- Returns a pointer to a calendar backend, specified by enum.
+ Returns a pointer to a calendar backend, specified by enum.
- This will instantiate the indicated calendar (which will enable fromName() to
- return it subsequently), but only for the Qt-supported calendars for which
- (where relevant) the appropriate feature has been enabled.
+ This will instantiate the indicated calendar (which will enable fromName()
+ to return it subsequently), but only for the Qt-supported calendars for
+ which (where relevant) the appropriate feature has been enabled.
*/
const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
{
@@ -643,28 +646,29 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
}
/*!
- \since 5.14
-
- \class QCalendar
- \inmodule QtCore
- \reentrant
- \brief The QCalendar class describes calendar systems.
-
- A QCalendar object maps a year, month, and day-number to a specific day
- (ultimately identified by its Julian day number), using the rules of a
- particular system.
+ \since 5.14
- The default QCalendar() is a proleptic Gregorian calendar, which has no year
- zero. Other calendars may be supported by enabling suitable features or
- loading plugins. Calendars supported as features can be constructed by passing
- the QCalendar::System enumeration to the constructor. All supported calendars
- may be constructed by name, once they have been constructed. (Thus plugins
- instantiate their calendar backend to register it.) Built-in backends,
- accessible via QCalendar::System, are also always available by name.
+ \class QCalendar
+ \inmodule QtCore
+ \reentrant
+ \brief The QCalendar class describes calendar systems.
+
+ A QCalendar object maps a year, month, and day-number to a specific day
+ (ultimately identified by its Julian day number), using the rules of a
+ particular system.
+
+ The default QCalendar() is a proleptic Gregorian calendar, which has no year
+ zero. Other calendars may be supported by enabling suitable features or
+ loading plugins. Calendars supported as features can be constructed by
+ passing the QCalendar::System enumeration to the constructor. All supported
+ calendars may be constructed by name, once they have been constructed. (Thus
+ plugins instantiate their calendar backend to register it.) Built-in
+ backends, accessible via QCalendar::System, are also always available by
+ name.
- A QCalendar value is immutable.
+ A QCalendar value is immutable.
- \sa QDate, QDateTime
+ \sa QDate, QDateTime
*/
/*!
@@ -684,20 +688,20 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
*/
/*!
- \fn QCalendar::QCalendar()
- \fn QCalendar::QCalendar(QCalendar::System system)
- \fn QCalendar::QCalendar(QLatin1String name)
- \fn QCalendar::QCalendar(QStringView name)
+ \fn QCalendar::QCalendar()
+ \fn QCalendar::QCalendar(QCalendar::System system)
+ \fn QCalendar::QCalendar(QLatin1String name)
+ \fn QCalendar::QCalendar(QStringView name)
- Constructs a calendar object.
+ Constructs a calendar object.
- The choice of calendar to use may be indicated as \a system, using the
- enumeration QCalendar::System, or by \a name, using a string (either Unicode
- or Latin 1). Construction by name may depend on an instance of the given
- calendar being constructed by other means first. With no argument, the default
- constructor returns the Gregorian calendar.
+ The choice of calendar to use may be indicated as \a system, using the
+ enumeration QCalendar::System, or by \a name, using a string (either Unicode
+ or Latin 1). Construction by name may depend on an instance of the given
+ calendar being constructed by other means first. With no argument, the
+ default constructor returns the Gregorian calendar.
- \sa QCalendar, System
+ \sa QCalendar, System
*/
QCalendar::QCalendar()
@@ -722,12 +726,13 @@ QCalendar::QCalendar(QStringView name)
// Date queries:
/*!
- Returns the number of days in the given \a month of the given \a year.
+ Returns the number of days in the given \a month of the given \a year.
- Months are numbered consecutively, starting with 1 for the first month of each
- year.
+ Months are numbered consecutively, starting with 1 for the first month of
+ each year. If \a year is \c Unspecified (its default, if not passed), the
+ month's length in a normal year is returned.
- \sa maximumDaysInMonth(), minimumDaysInMonth()
+ \sa maximumDaysInMonth(), minimumDaysInMonth()
*/
int QCalendar::daysInMonth(int month, int year) const
{
@@ -735,7 +740,7 @@ int QCalendar::daysInMonth(int month, int year) const
}
/*!
- Returns the number of days in the given \a year.
+ Returns the number of days in the given \a year.
*/
int QCalendar::daysInYear(int year) const
{
@@ -751,12 +756,12 @@ int QCalendar::monthsInYear(int year) const
}
/*!
- Returns \c true precisely if the given \a year, \a month, and \a day specify a
- valid date in this calendar.
+ Returns \c true precisely if the given \a year, \a month, and \a day specify
+ a valid date in this calendar.
- Usually this means 1 <= month <= monthsInYear(year) and 1 <= day <=
- daysInMonth(month, year). However, calendars with intercallary days or months
- may complicate that.
+ Usually this means 1 <= month <= monthsInYear(year) and 1 <= day <=
+ daysInMonth(month, year). However, calendars with intercallary days or
+ months may complicate that.
*/
bool QCalendar::isDateValid(int year, int month, int day) const
{
@@ -776,13 +781,13 @@ bool QCalendar::isGregorian() const
}
/*!
- Returns \c true if the given \a year is a leap year.
+ Returns \c true if the given \a year is a leap year.
- Since the year is not a whole number of days long, some years are longer than
- others. The difference may be a whole month or just a single day; the details
- vary between calendars.
+ Since the year is not a whole number of days long, some years are longer
+ than others. The difference may be a whole month or just a single day; the
+ details vary between calendars.
- \sa isDateValid()
+ \sa isDateValid()
*/
bool QCalendar::isLeapYear(int year) const
{
@@ -790,9 +795,9 @@ bool QCalendar::isLeapYear(int year) const
}
/*!
- Returns \c true if this calendar is a lunar calendar.
+ Returns \c true if this calendar is a lunar calendar.
- A lunar calendar is one based primarily on the phases of the moon.
+ A lunar calendar is one based primarily on the phases of the moon.
*/
bool QCalendar::isLunar() const
{
@@ -800,11 +805,11 @@ bool QCalendar::isLunar() const
}
/*!
- Returns \c true if this calendar is luni-solar.
+ Returns \c true if this calendar is luni-solar.
- A luni-solar calendar expresses the phases of the moon but adapts itself to
- also keep track of the Sun's varying position in the sky, relative to the
- fixed stars.
+ A luni-solar calendar expresses the phases of the moon but adapts itself to
+ also keep track of the Sun's varying position in the sky, relative to the
+ fixed stars.
*/
bool QCalendar::isLuniSolar() const
{
@@ -812,10 +817,10 @@ bool QCalendar::isLuniSolar() const
}
/*!
- Returns \c true if this calendar is solar.
+ Returns \c true if this calendar is solar.
- A solar calendar is based primarily on the Sun's varying position in the sky,
- relative to the fixed stars.
+ A solar calendar is based primarily on the Sun's varying position in the
+ sky, relative to the fixed stars.
*/
bool QCalendar::isSolar() const
{
@@ -823,13 +828,13 @@ bool QCalendar::isSolar() const
}
/*!
- Returns \c true if this calendar is proleptic.
+ Returns \c true if this calendar is proleptic.
- A proleptic calendar is able to describe years arbitrarily long before its
- first. These are represented by negative year numbers and possibly by a year
- zero.
+ A proleptic calendar is able to describe years arbitrarily long before its
+ first. These are represented by negative year numbers and possibly by a year
+ zero.
- \sa hasYearZero()
+ \sa hasYearZero()
*/
bool QCalendar::isProleptic() const
{
@@ -837,29 +842,29 @@ bool QCalendar::isProleptic() const
}
/*!
- Returns \c true if this calendar has a year zero.
-
- A non-proleptic calendar with no year zero represents years from its first
- year onwards but provides no way to describe years before its first; such a
- calendar has no year zero and is not proleptic.
-
- A calendar which represents years before its first may number these years
- simply by following the usual integer counting, so that the year before the
- first is year zero, with negative-numbered years preceding this; such a
- calendar is proleptic and has a year zero. A calendar might also have a year
- zero (for example, the year of some great event, with subsequent years being
- the first year after that event, the second year after, and so on) without
- describing years before its year zero. Such a calendar would have a year zero
- without being proleptic.
-
- Some calendars, however, represent years before their first by an alternate
- numbering; for example, the proleptic Gregorian calendar's first year is 1 CE
- and the year before it is 1 BCE, preceded by 2 BCE and so on. In this case,
- we use negative year numbers, with year -1 as the year before year 1, year -2
- as the year before year -1 and so on. Such a calendar is proleptic but has no
- year zero.
-
- \sa isProleptic()
+ Returns \c true if this calendar has a year zero.
+
+ A calendar may represent years from its first year onwards but provide no
+ way to describe years before its first; such a calendar has no year zero and
+ is not proleptic.
+
+ A calendar which represents years before its first may number these years
+ simply by following the usual integer counting, so that the year before the
+ first is year zero, with negative-numbered years preceding this; such a
+ calendar is proleptic and has a year zero. A calendar might also have a year
+ zero (for example, the year of some great event, with subsequent years being
+ the first year after that event, the second year after, and so on) without
+ describing years before its year zero. Such a calendar would have a year
+ zero without being proleptic.
+
+ Some calendars, however, represent years before their first by an alternate
+ numbering; for example, the proleptic Gregorian calendar's first year is 1
+ CE and the year before it is 1 BCE, preceded by 2 BCE and so on. In this
+ case, we use negative year numbers for this alternate numbering, with year
+ -1 as the year before year 1, year -2 as the year before year -1 and so
+ on. Such a calendar is proleptic but has no year zero.
+
+ \sa isProleptic()
*/
bool QCalendar::hasYearZero() const
{
@@ -867,9 +872,9 @@ bool QCalendar::hasYearZero() const
}
/*!
- Returns the number of days in the longest month in the calendar, in any year.
+ Returns the number of days in the longest month in the calendar, in any year.
- \sa daysInMonth(), minimumDaysInMonth()
+ \sa daysInMonth(), minimumDaysInMonth()
*/
int QCalendar::maximumDaysInMonth() const
{
@@ -877,9 +882,9 @@ int QCalendar::maximumDaysInMonth() const
}
/*!
- Returns the number of days in the shortest month in the calendar, in any year.
+ Returns the number of days in the shortest month in the calendar, in any year.
- \sa daysInMonth(), maximumDaysInMonth()
+ \sa daysInMonth(), maximumDaysInMonth()
*/
int QCalendar::minimumDaysInMonth() const
{
@@ -887,9 +892,9 @@ int QCalendar::minimumDaysInMonth() const
}
/*!
- Returns the largest number of months that any year may contain.
+ Returns the largest number of months that any year may contain.
- \sa monthName(), standaloneMonthName(), monthsInYear()
+ \sa monthName(), standaloneMonthName(), monthsInYear()
*/
int QCalendar::maximumMonthsInYear() const
{
@@ -939,13 +944,13 @@ QCalendar::YearMonthDay QCalendar::partsFromDate(QDate date) const
}
/*!
- Returns the day of the week number for the given \a date.
+ Returns the day of the week number for the given \a date.
- Returns zero if the calendar is unable to represent the indicated date.
- Returns 1 for Monday through 7 for Sunday. Calendars with intercallary days
- may use other numbers to represent these.
+ Returns zero if the calendar is unable to represent the indicated date.
+ Returns 1 for Monday through 7 for Sunday. Calendars with intercallary days
+ may use other numbers to represent these.
- \sa partsFromDate(), Qt::DayOfWeek
+ \sa partsFromDate(), Qt::DayOfWeek
*/
int QCalendar::dayOfWeek(QDate date) const
{
@@ -955,23 +960,23 @@ int QCalendar::dayOfWeek(QDate date) const
// Locale data access
/*!
- Returns a suitably localised name for a month.
+ Returns a suitably localised name for a month.
- The month is indicated by a number, with \a month = 1 meaning the first month
- of the year and subsequent months numbered accordingly. Returns an empty
- string if the \a month number is unrecognized.
+ The month is indicated by a number, with \a month = 1 meaning the first
+ month of the year and subsequent months numbered accordingly. Returns an
+ empty string if the \a month number is unrecognized.
- The \a year may be Unspecified, in which case the mapping from numbers to
- names for a typical year's months should be used. Some calendars have leap
- months that aren't always at the end of the year; their mapping of month
- numbers to names may then depend on the placement of a leap month. Thus the
- year should normally be specified, if known.
+ The \a year may be Unspecified, in which case the mapping from numbers to
+ names for a typical year's months should be used. Some calendars have leap
+ months that aren't always at the end of the year; their mapping of month
+ numbers to names may then depend on the placement of a leap month. Thus the
+ year should normally be specified, if known.
- The name is returned in the form that would normally be used in a full date,
- in the specified \a locale; the \a format determines how fully it shall be
- expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would normally be used in a full date,
+ in the specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa standaloneMonthName(), maximumMonthsInYear(), dateTimeToString()
+ \sa standaloneMonthName(), maximumMonthsInYear(), dateTimeToString()
*/
QString QCalendar::monthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const
@@ -984,23 +989,23 @@ QString QCalendar::monthName(const QLocale &locale, int month, int year,
}
/*!
- Returns a suitably localised standalone name for a month.
+ Returns a suitably localised standalone name for a month.
- The month is indicated by a number, with \a month = 1 meaning the first month
- of the year and subsequent months numbered accordingly. Returns an empty
- string if the \a month number is unrecognized.
+ The month is indicated by a number, with \a month = 1 meaning the first
+ month of the year and subsequent months numbered accordingly. Returns an
+ empty string if the \a month number is unrecognized.
- The \a year may be Unspecified, in which case the mapping from numbers to
- names for a typical year's months should be used. Some calendars have leap
- months that aren't always at the end of the year; their mapping of month
- numbers to names may then depend on the placement of a leap month. Thus the
- year should normally be specified, if known.
+ The \a year may be Unspecified, in which case the mapping from numbers to
+ names for a typical year's months should be used. Some calendars have leap
+ months that aren't always at the end of the year; their mapping of month
+ numbers to names may then depend on the placement of a leap month. Thus the
+ year should normally be specified, if known.
- The name is returned in the form that would be used in isolation in the
- specified \a locale; the \a format determines how fully it shall be expressed
- (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would be used in isolation in the
+ specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa monthName(), maximumMonthsInYear(), dateTimeToString()
+ \sa monthName(), maximumMonthsInYear(), dateTimeToString()
*/
QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int year,
QLocale::FormatType format) const
@@ -1013,18 +1018,18 @@ QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int yea
}
/*!
- Returns a suitably localised name for a day of the week.
+ Returns a suitably localised name for a day of the week.
- The days of the week are numbered from 1 for Monday through 7 for Sunday. Some
- calendars may support higher numbers for other days (e.g. intercallary days,
- that are not part of any week). Returns an empty string if the \a day number
- is unrecognized.
+ The days of the week are numbered from 1 for Monday through 7 for
+ Sunday. Some calendars may support higher numbers for other days
+ (e.g. intercallary days, that are not part of any week). Returns an empty
+ string if the \a day number is unrecognized.
- The name is returned in the form that would normally be used in a full date,
- in the specified \a locale; the \a format determines how fully it shall be
- expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would normally be used in a full date,
+ in the specified \a locale; the \a format determines how fully it shall be
+ expressed (i.e. to what extent it is abbreviated).
- \sa standaloneWeekDayName(), dayOfWeek()
+ \sa standaloneWeekDayName(), dayOfWeek()
*/
QString QCalendar::weekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const
@@ -1033,19 +1038,20 @@ QString QCalendar::weekDayName(const QLocale &locale, int day,
}
/*!
- Returns a suitably localised standalone name for a day of the week.
+ Returns a suitably localised standalone name for a day of the week.
- The days of the week are numbered from 1 for Monday through 7 for Sunday. Some
- calendars may support higher numbers for other days (e.g. intercallary days,
- that are not part of any week). Returns an empty string if the \a day number
- is unrecognized.
+ The days of the week are numbered from 1 for Monday through 7 for
+ Sunday. Some calendars may support higher numbers for other days
+ (e.g. intercallary days, that are not part of any week). Returns an empty
+ string if the \a day number is unrecognized.
- The name is returned in the form that would be used in isolation (for example
- as a column heading in a calendar's tabular display of a month with successive
- weeks as rows) in the specified \a locale; the \a format determines how fully
- it shall be expressed (i.e. to what extent it is abbreviated).
+ The name is returned in the form that would be used in isolation (for
+ example as a column heading in a calendar's tabular display of a month with
+ successive weeks as rows) in the specified \a locale; the \a format
+ determines how fully it shall be expressed (i.e. to what extent it is
+ abbreviated).
- \sa weekDayName(), dayOfWeek()
+ \sa weekDayName(), dayOfWeek()
*/
QString QCalendar::standaloneWeekDayName(const QLocale &locale, int day,
QLocale::FormatType format) const
@@ -1054,23 +1060,23 @@ QString QCalendar::standaloneWeekDayName(const QLocale &locale, int day,
}
/*!
- Returns a string representing a given date, time or date-time.
-
- If \a datetime is valid, it is represented and format specifiers for both date
- and time fields are recognized; otherwise, if \a dateOnly is valid, it is
- represented and only format specifiers for date fields are recognized;
- finally, if \a timeOnly is valid, it is represented and only format specifiers
- for time fields are recognized. If none of these is valid, an empty string is
- returned.
-
- See QDate::toString and QTime::toString() for the supported field specifiers.
- Characters in \a format that are recognized as field specifiers are replaced
- by text representing appropriate data from the date and/or time being
- represented. The texts to represent them may depend on the \a locale
- specified. Other charagers in \a format are copied verbatim into the returned
- string.
-
- \sa monthName(), weekDayName(), QDate::toString(), QTime::toString()
+ Returns a string representing a given date, time or date-time.
+
+ If \a datetime is valid, it is represented and format specifiers for both
+ date and time fields are recognized; otherwise, if \a dateOnly is valid, it
+ is represented and only format specifiers for date fields are recognized;
+ finally, if \a timeOnly is valid, it is represented and only format
+ specifiers for time fields are recognized. If none of these is valid, an
+ empty string is returned.
+
+ See QDate::toString and QTime::toString() for the supported field
+ specifiers. Characters in \a format that are recognized as field specifiers
+ are replaced by text representing appropriate data from the date and/or time
+ being represented. The texts to represent them may depend on the \a locale
+ specified. Other charagers in \a format are copied verbatim into the
+ returned string.
+
+ \sa monthName(), weekDayName(), QDate::toString(), QTime::toString()
*/
QString QCalendar::dateTimeToString(QStringView format, const QDateTime &datetime,
const QDate &dateOnly, const QTime &timeOnly,
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 8b1665e7dd..13a54c1210 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -3432,15 +3432,15 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
datetime by adding a number of seconds, days, months, or years.
QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local
- time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset
- from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction
- with the QTimeZone class. For example, a time zone of "Europe/Berlin" will
- apply the daylight-saving rules as used in Germany since 1970. In contrast,
- an offset from UTC of +3600 seconds is one hour ahead of UTC (usually
- written in ISO standard notation as "UTC+01:00"), with no daylight-saving
- offset or changes. When using either local time or a specified time zone,
- time-zone transitions such as the starts and ends of daylight-saving time
- (DST) are taken into account. The choice of system used to represent a
+ time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset from
+ UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the
+ QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the
+ daylight-saving rules as used in Germany since 1970. In contrast, an offset
+ from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO
+ standard notation as "UTC+01:00"), with no daylight-saving offset or
+ changes. When using either local time or a specified time zone, time-zone
+ transitions such as the starts and ends of daylight-saving time (DST; but
+ see below) are taken into account. The choice of system used to represent a
datetime is described as its "timespec".
A QDateTime object is typically created either by giving a date and time
@@ -3528,11 +3528,13 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
The range of valid dates taking DST into account is 1970-01-01 to the
present, and rules are in place for handling DST correctly until 2037-12-31,
- but these could change. For dates falling outside that range, QDateTime
- makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
- guarantee accuracy. This means QDateTime doesn't take into account changes
- in a time zone before 1970, even if the system's time zone database provides
- that information.
+ but these could change. For dates after 2037, QDateTime makes a \e{best
+ guess} using the rules for year 2037, but we can't guarantee accuracy;
+ indeed, for \e{any} future date, the time-zone may change its rules before
+ that date comes around. For dates before 1970, QDateTime doesn't take DST
+ changes into account, even if the system's time zone database provides that
+ information, although it does take into account changes to the time-zone's
+ standard offset, where this information is available.
\section2 Offsets From UTC
@@ -3797,17 +3799,22 @@ QTimeZone QDateTime::timeZone() const
/*!
\since 5.2
- Returns the current Offset From UTC in seconds.
+ Returns this date-time's Offset From UTC in seconds.
- If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set.
-
- If the timeSpec() is Qt::TimeZone this will be the offset effective in the
- Time Zone including any Daylight-Saving Offset.
-
- If the timeSpec() is Qt::LocalTime this will be the difference between the
- Local Time and UTC including any Daylight-Saving Offset.
+ The result depends on timeSpec():
+ \list
+ \li \c Qt::UTC The offset is 0.
+ \li \c Qt::OffsetFromUTC The offset is the value originally set.
+ \li \c Qt::LocalTime The local time's offset from UTC is returned.
+ \li \c Qt::TimeZone The offset used by the time-zone is returned.
+ \endlist
- If the timeSpec() is Qt::UTC this will be 0.
+ For the last two, the offset at this date and time will be returned, taking
+ account of Daylight-Saving Offset unless the date precedes the start of
+ 1970. The offset is the difference between the local time or time in the
+ given time-zone and UTC time; it is positive in time-zones ahead of UTC
+ (East of The Prime Meridian), negative for those behind UTC (West of The
+ Prime Meridian).
\sa setOffsetFromUtc()
*/
diff --git a/src/corelib/time/qhijricalendar.cpp b/src/corelib/time/qhijricalendar.cpp
index 9aabe46570..b5d89fbc5c 100644
--- a/src/corelib/time/qhijricalendar.cpp
+++ b/src/corelib/time/qhijricalendar.cpp
@@ -44,36 +44,37 @@
QT_BEGIN_NAMESPACE
/*!
- \since 5.14
+ \since 5.14
+ \internal
- \class QHijriCalendar
- \inmodule QtCore
- \brief The QHijriCalendar class supports Islamic (Hijri) calendar implementations.
+ \class QHijriCalendar
+ \inmodule QtCore
+ \brief The QHijriCalendar class supports Islamic (Hijri) calendar implementations.
- \section1 Islamic Calendar System
+ \section1 Islamic Calendar System
- The Islamic, Muslim, or Hijri calendar is a lunar calendar consisting of 12
- months in a year of 354 or 355 days. It is used (often alongside the
- Gregorian calendar) to date events in many Muslim countries. It is also used
- by Muslims to determine the proper days of Islamic holidays and rituals,
- such as the annual period of fasting and the proper time for the pilgrimage
- to Mecca.
+ The Islamic, Muslim, or Hijri calendar is a lunar calendar consisting of 12
+ months in a year of 354 or 355 days. It is used (often alongside the
+ Gregorian calendar) to date events in many Muslim countries. It is also used
+ by Muslims to determine the proper days of Islamic holidays and rituals,
+ such as the annual period of fasting and the proper time for the pilgrimage
+ to Mecca.
- Source: \l {https://en.wikipedia.org/wiki/Islamic_calendar}{Wikipedia page on
- Hijri Calendar}
+ Source: \l {https://en.wikipedia.org/wiki/Islamic_calendar}{Wikipedia page
+ on Hijri Calendar}
- \section1 Support for variants
+ \section1 Support for variants
- This base class provides the common details shared by all variants on the
- Islamic calendar. Each year comprises 12 months of 29 or 30 days each; most
- years have as many of 29 as of 30, but leap years extend one 29-day month to
- 30 days. In tabular versions of the calendar (where mathematical rules are
- used to determine the details), odd-numbered months have 30 days, as does the
- last (twelfth) month of a leap year; all other months have 29 days. Other
- versions are based on actual astronomical observations of the moon's phase at
- sunset, which vary from place to place.
+ This base class provides the common details shared by all variants on the
+ Islamic calendar. Each year comprises 12 months of 29 or 30 days each; most
+ years have as many of 29 as of 30, but leap years extend one 29-day month to
+ 30 days. In tabular versions of the calendar (where mathematical rules are
+ used to determine the details), odd-numbered months have 30 days, as does
+ the last (twelfth) month of a leap year; all other months have 29
+ days. Other versions are based on actual astronomical observations of the
+ moon's phase at sunset, which vary from place to place.
- \sa QIslamicCivilCalendar, QCalendar
+ \sa QIslamicCivilCalendar, QCalendar
*/
bool QHijriCalendar::isLunar() const
diff --git a/src/corelib/time/qislamiccivilcalendar.cpp b/src/corelib/time/qislamiccivilcalendar.cpp
index 27c93f5c00..a6a2afd207 100644
--- a/src/corelib/time/qislamiccivilcalendar.cpp
+++ b/src/corelib/time/qislamiccivilcalendar.cpp
@@ -47,27 +47,29 @@ QT_BEGIN_NAMESPACE
using namespace QRoundingDown;
/*!
- \since 5.14
+ \since 5.14
+ \internal
- \class QIslamicCivilCalendar
- \inmodule QtCore
- \brief Implements a commonly-used computed version of the Islamic calendar.
+ \class QIslamicCivilCalendar
+ \inmodule QtCore
+ \brief Implements a commonly-used computed version of the Islamic calendar.
- \section1 Civil Islamic Calendar
+ \section1 Civil Islamic Calendar
- QIslamicCivilCalendar implements a tabular version of the Hijri calendar which
- is known as the Islamic Civil Calendar. It has the same numbering of years and
- months, but the months are determined by arithmetical rules rather than by
- observation or astronomical calculations.
+ QIslamicCivilCalendar implements a tabular version of the Hijri calendar
+ which is known as the Islamic Civil Calendar. It has the same numbering of
+ years and months, but the months are determined by arithmetical rules rather
+ than by observation or astronomical calculations.
- \section2 Calendar Organization
+ \section2 Calendar Organization
- The civil calendar follows the usual tabular scheme of odd-numbered months and
- the last month of each leap year being 30 days long, the rest being 29 days
- long. Its determination of leap years follows a 30-year cycle, in each of
- which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap years.
+ The civil calendar follows the usual tabular scheme of odd-numbered months
+ and the last month of each leap year being 30 days long, the rest being 29
+ days long. Its determination of leap years follows a 30-year cycle, in each
+ of which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap
+ years.
- \sa QJijriCalendar, QCalendar
+ \sa QHijriCalendar, QCalendar
*/
QIslamicCivilCalendar::QIslamicCivilCalendar()
diff --git a/src/corelib/time/qromancalendar.cpp b/src/corelib/time/qromancalendar.cpp
index 36cad01b81..c3cd134490 100644
--- a/src/corelib/time/qromancalendar.cpp
+++ b/src/corelib/time/qromancalendar.cpp
@@ -44,20 +44,20 @@
QT_BEGIN_NAMESPACE
/*!
- \since 5.14
+ \since 5.14
- \class QRomanCalendar
- \inmodule QtCore
- \brief The QRomanCalendar class is a shared base for calendars based on the
- ancient Roman calendar.
+ \class QRomanCalendar
+ \inmodule QtCore
+ \brief The QRomanCalendar class is a shared base for calendars based on the
+ ancient Roman calendar.
- \section1
+ \section1
- Calendars based on the ancient Roman calendar share the names of months, whose
- lengths depend in a common way on whether the year is a leap year. They differ
- in how they determine which years are leap years.
+ Calendars based on the ancient Roman calendar share the names of months,
+ whose lengths depend in a common way on whether the year is a leap
+ year. They differ in how they determine which years are leap years.
- \sa QGregorianCalendar, QJulianCalendar, QMilankovicCalendar
+ \sa QGregorianCalendar, QJulianCalendar, QMilankovicCalendar
*/
int QRomanCalendar::daysInMonth(int month, int year) const
diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp
index ef323de14a..410a16e3c5 100644
--- a/src/corelib/time/qtimezone.cpp
+++ b/src/corelib/time/qtimezone.cpp
@@ -325,20 +325,33 @@ QTimeZone::QTimeZone() noexcept
/*!
Creates an instance of the requested time zone \a ianaId.
- The ID must be one of the available system IDs otherwise an invalid
- time zone will be returned.
+ The ID must be one of the available system IDs or a valid UTC-with-offset
+ ID, otherwise an invalid time zone will be returned.
\sa availableTimeZoneIds()
*/
QTimeZone::QTimeZone(const QByteArray &ianaId)
{
- // Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
+ // Try and see if it's a CLDR UTC offset ID - just as quick by creating as
+ // by looking up.
d = new QUtcTimeZonePrivate(ianaId);
- // If not a valid UTC offset ID then try create it with the system backend
- // Relies on backend not creating valid tz with invalid name
+ // If not a CLDR UTC offset ID then try creating it with the system backend.
+ // Relies on backend not creating valid TZ with invalid name.
if (!d->isValid())
d = newBackendTimeZone(ianaId);
+ // Can also handle UTC with arbitrary (valid) offset, but only do so as
+ // fall-back, since either of the above may handle it more informatively.
+ if (!d->isValid()) {
+ qint64 offset = QUtcTimeZonePrivate::offsetFromUtcString(ianaId);
+ if (offset != QTimeZonePrivate::invalidSeconds()) {
+ // Should have abs(offset) < 24 * 60 * 60 = 86400.
+ qint32 seconds = qint32(offset);
+ Q_ASSERT(qint64(seconds) == offset);
+ // NB: this canonicalises the name, so it might not match ianaId
+ d = new QUtcTimeZonePrivate(seconds);
+ }
+ }
}
/*!
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp
index 569b343187..72a0e3c24e 100644
--- a/src/corelib/time/qtimezoneprivate.cpp
+++ b/src/corelib/time/qtimezoneprivate.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2013 John Layt <jlayt@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -761,6 +762,39 @@ QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QByteArray &id)
}
}
+qint64 QUtcTimeZonePrivate::offsetFromUtcString(const QByteArray &id)
+{
+ // Convert reasonable UTC[+-]\d+(:\d+){,2} to offset in seconds.
+ // Assumption: id has already been tried as a CLDR UTC offset ID (notably
+ // including plain "UTC" itself) and a system offset ID; it's neither.
+ if (!id.startsWith("UTC") || id.size() < 5)
+ return invalidSeconds(); // Doesn't match
+ const char signChar = id.at(3);
+ if (signChar != '-' && signChar != '+')
+ return invalidSeconds(); // No sign
+ const int sign = signChar == '-' ? -1 : 1;
+
+ const auto offsets = id.mid(4).split(':');
+ if (offsets.isEmpty() || offsets.size() > 3)
+ return invalidSeconds(); // No numbers, or too many.
+
+ qint32 seconds = 0;
+ int prior = 0; // Number of fields parsed thus far
+ for (const auto &offset : offsets) {
+ bool ok = false;
+ unsigned short field = offset.toUShort(&ok);
+ // Bound hour above at 24, minutes and seconds at 60:
+ if (!ok || field >= (prior ? 60 : 24))
+ return invalidSeconds();
+ seconds = seconds * 60 + field;
+ ++prior;
+ }
+ while (prior++ < 3)
+ seconds *= 60;
+
+ return seconds * sign;
+}
+
// Create offset from UTC
QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds)
{
@@ -874,22 +908,25 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
{
+ // Only the zone IDs supplied by CLDR and recognized by constructor.
for (int i = 0; i < utcDataTableSize; ++i) {
const QUtcData *data = utcData(i);
- if (utcId(data) == ianaId) {
+ if (utcId(data) == ianaId)
return true;
- }
}
+ // But see offsetFromUtcString(), which lets us accept some "unavailable" IDs.
return false;
}
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
{
+ // Only the zone IDs supplied by CLDR and recognized by constructor.
QList<QByteArray> result;
result.reserve(utcDataTableSize);
for (int i = 0; i < utcDataTableSize; ++i)
result << utcId(utcData(i));
- std::sort(result.begin(), result.end()); // ### or already sorted??
+ // Not guaranteed to be sorted, so sort:
+ std::sort(result.begin(), result.end());
// ### assuming no duplicates
return result;
}
@@ -904,13 +941,16 @@ QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(QLocale::Country cou
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(qint32 offsetSeconds) const
{
+ // Only if it's present in CLDR. (May get more than one ID: UTC, UTC+00:00
+ // and UTC-00:00 all have the same offset.)
QList<QByteArray> result;
for (int i = 0; i < utcDataTableSize; ++i) {
const QUtcData *data = utcData(i);
if (data->offsetFromUtc == offsetSeconds)
result << utcId(data);
}
- std::sort(result.begin(), result.end()); // ### or already sorted??
+ // Not guaranteed to be sorted, so sort:
+ std::sort(result.begin(), result.end());
// ### assuming no duplicates
return result;
}
diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h
index 5f6491ef81..a57f61f381 100644
--- a/src/corelib/time/qtimezoneprivate_p.h
+++ b/src/corelib/time/qtimezoneprivate_p.h
@@ -188,6 +188,9 @@ public:
QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other);
virtual ~QUtcTimeZonePrivate();
+ // Fall-back for UTC[+-]\d+(:\d+){,2} IDs.
+ static qint64 offsetFromUtcString(const QByteArray &id);
+
QUtcTimeZonePrivate *clone() const override;
Data data(qint64 forMSecsSinceEpoch) const override;
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp
index 1bf2366748..5a480222e0 100644
--- a/src/corelib/time/qtimezoneprivate_win.cpp
+++ b/src/corelib/time/qtimezoneprivate_win.cpp
@@ -371,6 +371,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
// Otherwise, the rule date is annual and relative:
const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
QDate date(year, rule.wMonth, 1);
+ Q_ASSERT(date.isValid());
// How many days before was last dayOfWeek before target month ?
int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
if (adjust >= 0) // Ensure -7 <= adjust < 0:
@@ -401,6 +402,7 @@ qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)
{
// TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
// WinTransitionRule; do this in init() once and store the results.
+ Q_ASSERT(year);
const QDate date = calculateTransitionLocalDate(rule, year);
const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
if (date.isValid() && time.isValid())
@@ -479,6 +481,7 @@ struct TransitionTimePair
int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
{
+ Q_ASSERT(year);
int offset = rule.standardTimeBias;
// Only needed to help another TransitionTimePair work out year + 1's start
// offset; and the oldYearOffset we use only affects an alleged transition
@@ -743,11 +746,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
+ const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
@@ -755,7 +759,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
} else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
isDst = true;
} else {
- --year; // Try an earlier year for this rule (once).
+ year = prior; // Try an earlier year for this rule (once).
+ prior = year == 1 ? -1 : year - 1; // No year 0.
continue;
}
return ruleToData(rule, forMSecsSinceEpoch,
@@ -767,8 +772,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
// No transition, no DST, use the year's standard time.
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
}
- if (year >= rule.startYear)
+ if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule.
+ if (!year)
+ --year;
+ }
}
// We don't have relevant data :-(
return invalidData();
@@ -795,9 +803,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
year = rule.startYear; // Seek first transition in this rule.
const int endYear = ruleIndex + 1 < m_tranRules.count()
? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
while (year < endYear) {
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
@@ -810,7 +819,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
newYearOffset = rule.standardTimeBias;
if (pair.dst > pair.std)
newYearOffset += rule.daylightTimeBias;
- ++year; // Try a later year for this rule (once).
+ // Try a later year for this rule (once).
+ prior = year;
+ year = year == -1 ? 1 : year + 1; // No year 0
continue;
}
@@ -837,11 +848,12 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
// Does this rule's period include any transition at all ?
if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
+ int prior = year == 1 ? -1 : year - 1; // No year 0.
+ const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) {
const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
const TransitionTimePair pair(rule, year, newYearOffset);
bool isDst = false;
if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
@@ -849,7 +861,8 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
} else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
isDst = true;
} else {
- --year; // Try an earlier year for this rule (once).
+ year = prior; // Try an earlier year for this rule (once).
+ prior = year == 1 ? -1 : year - 1; // No year 0.
continue;
}
if (isDst)
@@ -863,8 +876,11 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
// rule:
return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
} // else: no transition during rule's period
- if (year >= rule.startYear)
+ if (year >= rule.startYear) {
year = rule.startYear - 1; // Seek last transition in new rule
+ if (!year)
+ --year;
+ }
}
// Apparently no transition before the given time:
return invalidData();
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index 86a16eb32b..3a0c4381f1 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -49,8 +49,6 @@
#include <QtCore/qglobal.h>
#include <iterator>
-#ifndef Q_QDOC
-
QT_BEGIN_NAMESPACE
namespace QtPrivate
@@ -131,6 +129,4 @@ using IfAssociativeIteratorHasFirstAndSecond =
QT_END_NAMESPACE
-#endif // Q_QDOC
-
#endif // QCONTAINERTOOLS_IMPL_H
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 1d0c93f26f..27c82bc09f 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -281,7 +281,7 @@ static quint32 icon_name_hash(const char *p)
QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name)
{
QVector<const char *> ret;
- if (!isValid())
+ if (!isValid() || name.isEmpty())
return ret;
QByteArray nameUtf8 = name.toUtf8();
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 86130132a4..dda407181a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3370,7 +3370,7 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
\sa {QImage#Image Transformations}{Image Transformations}
*/
-inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
+static inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
{
const RbSwapFunc func = layout->rbSwap;
if (!func) {
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 539bac222a..9e1df7058c 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -564,6 +564,67 @@ static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFl
return true;
}
+static void convert_rgbswap_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const RbSwapFunc func = qPixelLayouts[src->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ func(dest_data, src_data, src->width);
+
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
+static bool convert_rgbswap_generic_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ const RbSwapFunc func = qPixelLayouts[data->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype bpl = data->bytes_per_line;
+ uchar *line_data = data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ func(line_data, line_data, data->width);
+ line_data += bpl;
+ }
+
+ switch (data->format) {
+ case QImage::Format_RGB888:
+ data->format = QImage::Format_BGR888;
+ break;
+ case QImage::Format_BGR888:
+ data->format = QImage::Format_RGB888;
+ break;
+ case QImage::Format_BGR30:
+ data->format = QImage::Format_RGB30;
+ break;
+ case QImage::Format_A2BGR30_Premultiplied:
+ data->format = QImage::Format_A2RGB30_Premultiplied;
+ break;
+ case QImage::Format_RGB30:
+ data->format = QImage::Format_BGR30;
+ break;
+ case QImage::Format_A2RGB30_Premultiplied:
+ data->format = QImage::Format_A2BGR30_Premultiplied;
+ break;
+ default:
+ Q_UNREACHABLE();
+ data->format = QImage::Format_Invalid;
+ return false;
+ }
+ return true;
+}
+
template<QtPixelOrder PixelOrder, bool RGBA>
static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -693,74 +754,10 @@ static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConve
return true;
}
-static void convert_BGR30_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB30 || src->format == QImage::Format_BGR30 ||
- src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30 ||
- dest->format == QImage::Format_A2RGB30_Premultiplied || dest->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = qRgbSwapRgb30(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30 ||
- data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- uint *rgb_data = (uint *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const uint *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = qRgbSwapRgb30(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
-
- switch (data->format) {
- case QImage::Format_BGR30:
- data->format = QImage::Format_RGB30;
- break;
- case QImage::Format_A2BGR30_Premultiplied:
- data->format = QImage::Format_A2RGB30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- data->format = QImage::Format_BGR30;
- break;
- case QImage::Format_A2RGB30_Premultiplied:
- data->format = QImage::Format_A2BGR30_Premultiplied;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversionFlags flags)
{
Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30);
- if (!convert_BGR30_to_RGB30_inplace(data, flags))
+ if (!convert_rgbswap_generic_inplace(data, flags))
return false;
if (data->format == QImage::Format_RGB30)
@@ -1421,69 +1418,6 @@ static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt
}
}
-static void convert_RGB888_to_BGR888(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
- Q_ASSERT(dest->format == QImage::Format_RGB888 || dest->format == QImage::Format_BGR888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const qsizetype sbpl = src->bytes_per_line;
- const qsizetype dbpl = dest->bytes_per_line;
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- int pixel = 0;
- // Handle 4 pixels (12 bytes) at a time
- for (; pixel + 3 < src->width; pixel += 4) {
- const uchar *src = src_data + pixel * 3;
- quint32 *dest_packed = (quint32 *) (dest_data + pixel * 3);
- dest_packed[0] = (src[5] << 24) | (src[0] << 16) | (src[1] << 8) | (src[2] << 0);
- dest_packed[1] = (src[7] << 24) | (src[8] << 16) | (src[3] << 8) | (src[4] << 0);
- dest_packed[2] = (src[9] << 24) | (src[10] << 16) | (src[11] << 8) | (src[6] << 0);
- }
-
- // epilog: handle left over pixels
- for (; pixel < src->width; ++pixel) {
- dest_data[pixel * 3 + 0] = src_data[pixel * 3 + 2];
- dest_data[pixel * 3 + 1] = src_data[pixel * 3 + 1];
- dest_data[pixel * 3 + 2] = src_data[pixel * 3 + 0];
- }
-
- src_data += sbpl;
- dest_data += dbpl;
- }
-}
-
-static bool convert_RGB888_to_BGR888_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB888 || data->format == QImage::Format_BGR888);
-
- const qsizetype bpl = data->bytes_per_line;
- uchar *line_data = data->data;
-
- for (int i = 0; i < data->height; ++i) {
- for (int j = 0; j < data->width; ++j)
- qSwap(line_data[j * 3 + 0], line_data[j * 3 + 2]);
- line_data += bpl;
- }
-
- switch (data->format) {
- case QImage::Format_RGB888:
- data->format = QImage::Format_BGR888;
- break;
- case QImage::Format_BGR888:
- data->format = QImage::Format_RGB888;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2635,7 +2569,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
}, // Format_RGB888
{
@@ -2781,8 +2715,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
convert_passthrough,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_BGR30
@@ -2809,7 +2743,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<false>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
@@ -2833,8 +2767,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0,
convert_passthrough,
0, 0, 0, 0, 0, 0, 0
@@ -2860,7 +2794,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
convert_A2RGB30_PM_to_RGB30<false>,
0,
0, 0,
@@ -3013,7 +2947,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
0,
0,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
@@ -3161,7 +3095,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_ARGB8555_Premultiplied
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace
+ convert_rgbswap_generic_inplace
}, // Format_RGB888
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -3267,7 +3201,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0, // self
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, 0,
0, 0, 0, 0, 0
@@ -3295,7 +3229,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
{
@@ -3318,7 +3252,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
@@ -3345,7 +3279,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
0, 0,
@@ -3427,7 +3361,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_Grayscale16
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_BGR888
};
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 6a0763e696..dff24b449a 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -150,7 +150,7 @@
// factory loader
#include <qcoreapplication.h>
#include <private/qfactoryloader_p.h>
-#include <QMutexLocker>
+#include <QtCore/private/qlocking_p.h>
// for qt_getImageText
#include <private/qimage_p.h>
@@ -186,8 +186,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray suffix;
#ifndef QT_NO_IMAGEFORMATPLUGIN
- static QMutex mutex;
- QMutexLocker locker(&mutex);
+ static QBasicMutex mutex;
+ const auto locker = qt_scoped_lock(mutex);
typedef QMultiMap<int, QString> PluginKeyMap;
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 8548f1857e..978a07b9f9 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -57,6 +57,7 @@
#include "qregexp.h"
#include "qregion.h"
#include "qdebug.h"
+#include <QtCore/private/qlocking_p.h>
#include <algorithm>
@@ -1427,7 +1428,7 @@ void qt_init_picture_plugins()
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
static QBasicMutex mutex;
- QMutexLocker locker(&mutex);
+ const auto locker = qt_scoped_lock(mutex);
static QFactoryLoader loader(QPictureFormatInterface_iid,
QStringLiteral("/pictureformats"));
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index cb7a0b8ac9..a3ef3b2314 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -58,6 +58,7 @@
#include <QtCore/private/qabstracteventdispatcher_p.h>
#include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h>
+#include <QtCore/private/qlocking_p.h>
#include <QtCore/qdir.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qnumeric.h>
@@ -2762,7 +2763,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QWindow *window = e->window.data();
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
- bool stationaryTouchPointChangedVelocity = false;
+ bool stationaryTouchPointChangedProperty = false;
for (int i = 0; i < e->points.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
@@ -2842,7 +2843,11 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (touchPoint.state() == Qt::TouchPointStationary) {
if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) {
touchInfo.touchPoint.setVelocity(touchPoint.velocity());
- stationaryTouchPointChangedVelocity = true;
+ stationaryTouchPointChangedProperty = true;
+ }
+ if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) {
+ touchInfo.touchPoint.setPressure(touchPoint.pressure());
+ stationaryTouchPointChangedProperty = true;
}
} else {
touchInfo.touchPoint = touchPoint;
@@ -2883,7 +2888,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
break;
case Qt::TouchPointStationary:
// don't send the event if nothing changed
- if (!stationaryTouchPointChangedVelocity)
+ if (!stationaryTouchPointChangedProperty)
continue;
Q_FALLTHROUGH();
default:
@@ -3301,7 +3306,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
QFont QGuiApplication::font()
{
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
- QMutexLocker locker(&applicationFontMutex);
+ const auto locker = qt_scoped_lock(applicationFontMutex);
initFontUnlocked();
return *QGuiApplicationPrivate::app_font;
}
@@ -3313,7 +3318,7 @@ QFont QGuiApplication::font()
*/
void QGuiApplication::setFont(const QFont &font)
{
- QMutexLocker locker(&applicationFontMutex);
+ auto locker = qt_unique_lock(applicationFontMutex);
const bool emitChange = !QGuiApplicationPrivate::app_font
|| (*QGuiApplicationPrivate::app_font != font);
if (!QGuiApplicationPrivate::app_font)
@@ -3501,7 +3506,7 @@ Qt::ApplicationState QGuiApplication::applicationState()
\since 5.14
Sets the high-DPI scale factor rounding policy for the application. The
- policy decides how non-integer scale factors (such as Windows 150%) are
+ \a policy decides how non-integer scale factors (such as Windows 150%) are
handled, for applications that have AA_EnableHighDpiScaling enabled.
The two principal options are whether fractional scale factors should
@@ -4077,7 +4082,7 @@ void QGuiApplicationPrivate::notifyThemeChanged()
sendApplicationPaletteChange();
}
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
- QMutexLocker locker(&applicationFontMutex);
+ const auto locker = qt_scoped_lock(applicationFontMutex);
clearFontUnlocked();
initFontUnlocked();
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index ec4feeba8b..ee54fd4fa1 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -538,7 +538,7 @@ void QHighDpiScaling::updateHighDpiScaling()
++i;
}
}
- m_active = m_globalScalingActive || m_usePixelDensity;
+ m_active = m_globalScalingActive || m_screenFactorSet || m_usePixelDensity;
}
/*
@@ -680,8 +680,11 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
if (!screen || !screen->handle())
return QDpi(96, 96);
- if (!m_usePixelDensity)
- return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
+ if (!m_usePixelDensity) {
+ const qreal screenScaleFactor = screenSubfactor(screen->handle());
+ const QDpi dpi = QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
+ return QDpi{ dpi.first / screenScaleFactor, dpi.second / screenScaleFactor };
+ }
const qreal scaleFactor = rawScaleFactor(screen->handle());
const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 6f51fe3095..638eb1d12f 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QThreadStorage>
#include <QtCore/QThread>
+#include <QtCore/private/qlocking_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qopengl_p.h>
@@ -1442,7 +1443,7 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
m_refs.ref();
m_shares << ctx;
}
@@ -1454,7 +1455,7 @@ void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
bool deleteObject = false;
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
m_shares.removeOne(ctx);
if (ctx == m_context && !m_shares.isEmpty())
@@ -1502,7 +1503,7 @@ void QOpenGLContextGroupPrivate::cleanup()
void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
{
- QMutexLocker locker(&m_mutex);
+ const auto locker = qt_scoped_lock(m_mutex);
const QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
m_pendingDeletion.clear();
@@ -1543,7 +1544,7 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
: m_group(group)
{
- QMutexLocker locker(&m_group->d_func()->m_mutex);
+ const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources << this;
}
@@ -1559,7 +1560,7 @@ void QOpenGLSharedResource::free()
return;
}
- QMutexLocker locker(&m_group->d_func()->m_mutex);
+ const auto locker = qt_scoped_lock(m_group->d_func()->m_mutex);
m_group->d_func()->m_sharedResources.removeOne(this);
m_group->d_func()->m_pendingDeletion << this;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index ea187f54aa..8293fddc59 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -228,7 +228,7 @@ TouchDevices::TouchDevices()
*/
QList<const QTouchDevice *> QTouchDevice::devices()
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list;
}
@@ -237,13 +237,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
*/
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
- QMutexLocker locker(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
return deviceList->list.contains(dev);
}
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{
- QMutexLocker locker(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev;
@@ -255,7 +255,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
*/
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.append(dev);
}
@@ -264,7 +264,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
*/
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{
- QMutexLocker lock(&devicesMutex);
+ const auto locker = qt_scoped_lock(devicesMutex);
deviceList->list.removeOne(dev);
}
diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h
index 66db95df7e..edb2d32258 100644
--- a/src/gui/painting/qcolormatrix_p.h
+++ b/src/gui/painting/qcolormatrix_p.h
@@ -62,17 +62,16 @@ class QColorVector
{
public:
QColorVector() = default;
- Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { }
+ Q_DECL_CONSTEXPR QColorVector(float x, float y, float z) : x(x), y(y), z(z) { }
explicit Q_DECL_CONSTEXPR QColorVector(const QPointF &chr) // from XY chromaticity
: x(chr.x() / chr.y())
, y(1.0f)
, z((1.0 - chr.x() - chr.y()) / chr.y())
- , _unused(0.0f)
{ }
- float x; // X, x or red
- float y; // Y, y or green
- float z; // Z, Y or blue
- float _unused;
+ float x = 0.0f; // X, x or red
+ float y = 0.0f; // Y, y or green
+ float z = 0.0f; // Z, Y or blue
+ float _unused = 0.0f;
friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
@@ -81,7 +80,6 @@ public:
return !x && !y && !z;
}
- static Q_DECL_CONSTEXPR QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
static bool isValidChromaticity(const QPointF &chr)
{
if (chr.x() < qreal(0.0) || chr.x() > qreal(1.0))
@@ -187,10 +185,6 @@ public:
{ r.z, g.z, b.z } };
}
- static QColorMatrix null()
- {
- return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
- }
static QColorMatrix identity()
{
return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
@@ -226,12 +220,6 @@ public:
{ 0.1351922452f, 0.7118769884f, 0.0000000000f },
{ 0.0313525312f, 0.0000856627f, 0.8251883388f } };
}
- static QColorMatrix toXyzFromBt2020()
- {
- return QColorMatrix { { 0.6506130099f, 0.2695676684f, -0.0018652577f },
- { 0.1865101457f, 0.6840794086f, 0.0172256753f },
- { 0.1270887405f, 0.0463530831f, 0.8098278046f } };
- }
};
inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2)
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index 39ab358879..937bb505c9 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -70,12 +70,6 @@ QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries)
bluePoint = QPointF(0.150, 0.060);
whitePoint = QColorVector::D65Chromaticity();
break;
- case QColorSpace::Primaries::Bt2020:
- redPoint = QPointF(0.708, 0.292);
- greenPoint = QPointF(0.190, 0.797);
- bluePoint = QPointF(0.131, 0.046);
- whitePoint = QColorVector::D65Chromaticity();
- break;
case QColorSpace::Primaries::AdobeRgb:
redPoint = QPointF(0.640, 0.330);
greenPoint = QPointF(0.210, 0.710);
@@ -152,17 +146,11 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const
}
QColorSpacePrivate::QColorSpacePrivate()
- : primaries(QColorSpace::Primaries::Custom)
- , transferFunction(QColorSpace::TransferFunction::Custom)
- , gamma(0.0f)
- , whitePoint(QColorVector::null())
- , toXyz(QColorMatrix::null())
{
}
QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSpace)
: namedColorSpace(namedColorSpace)
- , gamma(0.0f)
{
switch (namedColorSpace) {
case QColorSpace::SRgb:
@@ -191,11 +179,6 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSp
transferFunction = QColorSpace::TransferFunction::ProPhotoRgb;
description = QStringLiteral("ProPhoto RGB");
break;
- case QColorSpace::Bt2020:
- primaries = QColorSpace::Primaries::Bt2020;
- transferFunction = QColorSpace::TransferFunction::Bt2020;
- description = QStringLiteral("BT.2020");
- break;
default:
Q_UNREACHABLE();
}
@@ -277,14 +260,6 @@ void QColorSpacePrivate::identifyColorSpace()
}
}
break;
- case QColorSpace::Primaries::Bt2020:
- if (transferFunction == QColorSpace::TransferFunction::Bt2020) {
- namedColorSpace = QColorSpace::Bt2020;
- if (description.isEmpty())
- description = QStringLiteral("BT.2020");
- return;
- }
- break;
default:
break;
}
@@ -301,7 +276,7 @@ void QColorSpacePrivate::initialize()
void QColorSpacePrivate::setToXyzMatrix()
{
if (primaries == QColorSpace::Primaries::Custom) {
- toXyz = QColorMatrix::null();
+ toXyz = QColorMatrix();
whitePoint = QColorVector::D50();
return;
}
@@ -335,12 +310,6 @@ void QColorSpacePrivate::setTransferFunction()
if (qFuzzyIsNull(gamma))
gamma = 1.8f;
break;
- case QColorSpace::TransferFunction::Bt2020:
- trc[0].m_type = QColorTrc::Type::Function;
- trc[0].m_fun = QColorTransferFunction::fromBt2020();
- if (qFuzzyIsNull(gamma))
- gamma = 1.961f;
- break;
case QColorSpace::TransferFunction::Custom:
break;
default:
@@ -415,8 +384,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\l{http://www.color.org/chardata/rgb/DCIP3.xalter}{ICC registration of DCI-P3}
\value ProPhotoRgb The Pro Photo RGB color space, also known as ROMM RGB is a very wide gamut color space.
\l{http://www.color.org/chardata/rgb/rommrgb.xalter}{ICC registration of ROMM RGB}
- \value Bt2020 BT.2020 also known as Rec.2020 is the color space of HDR TVs.
- \l{http://www.color.org/chardata/rgb/BT2020.xalter}{ICC registration of BT.2020}
*/
/*!
@@ -429,7 +396,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value AdobeRgb The Adobe RGB primaries
\value DciP3D65 The DCI-P3 primaries with the D65 whitepoint
\value ProPhotoRgb The ProPhoto RGB primaries with the D50 whitepoint
- \value Bt2020 The BT.2020 primaries
*/
/*!
@@ -442,7 +408,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value Gamma A transfer function that is a real gamma curve based on the value of gamma()
\value SRgb The sRGB transfer function, composed of linear and gamma parts
\value ProPhotoRgb The ProPhoto RGB transfer function, composed of linear and gamma parts
- \value Bt2020 The BT.2020 transfer function, composed of linear and gamma parts
*/
/*!
@@ -457,7 +422,7 @@ QColorSpace::QColorSpace()
*/
QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
{
- static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::Bt2020 + 1];
+ static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::ProPhotoRgb + 1];
if (!predefinedColorspacePrivates[namedColorSpace]) {
predefinedColorspacePrivates[namedColorSpace] = new QColorSpacePrivate(namedColorSpace);
predefinedColorspacePrivates[namedColorSpace]->ref.ref();
diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h
index 11987b9a37..e6bc62d58a 100644
--- a/src/gui/painting/qcolorspace.h
+++ b/src/gui/painting/qcolorspace.h
@@ -59,8 +59,7 @@ public:
SRgbLinear,
AdobeRgb,
DisplayP3,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(NamedColorSpace)
enum class Primaries {
@@ -68,8 +67,7 @@ public:
SRgb,
AdobeRgb,
DciP3D65,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(Primaries)
enum class TransferFunction {
@@ -77,8 +75,7 @@ public:
Linear,
Gamma,
SRgb,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(TransferFunction)
diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h
index c06681df6b..e7add19ed3 100644
--- a/src/gui/painting/qcolorspace_p.h
+++ b/src/gui/painting/qcolorspace_p.h
@@ -124,9 +124,9 @@ public:
static constexpr QColorSpace::NamedColorSpace Unknown = QColorSpace::NamedColorSpace(0);
QColorSpace::NamedColorSpace namedColorSpace = Unknown;
- QColorSpace::Primaries primaries;
- QColorSpace::TransferFunction transferFunction;
- float gamma;
+ QColorSpace::Primaries primaries = QColorSpace::Primaries::Custom;
+ QColorSpace::TransferFunction transferFunction = QColorSpace::TransferFunction::Custom;
+ float gamma = 0.0f;
QColorVector whitePoint;
QColorTrc trc[3];
diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h
index fd7cfa2b2b..0575dbd888 100644
--- a/src/gui/painting/qcolortransferfunction_p.h
+++ b/src/gui/painting/qcolortransferfunction_p.h
@@ -130,10 +130,6 @@ public:
{
return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f);
}
- static QColorTransferFunction fromBt2020()
- {
- return QColorTransferFunction(1.0f / 1.0993f, 0.0993f / 1.0993f, 1.0f / 4.5f, 0.08145f, 0.0f, 0.0f, 2.2f);
- }
static QColorTransferFunction fromProPhotoRgb()
{
return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f);
diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp
index 53fd1dfbaa..10ccefed74 100644
--- a/src/gui/painting/qcolortransform.cpp
+++ b/src/gui/painting/qcolortransform.cpp
@@ -612,6 +612,15 @@ static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *bu
static constexpr qsizetype WorkBlockSize = 256;
+template <typename T, int Count = 1>
+class QUninitialized
+{
+public:
+ operator T*() { return reinterpret_cast<T *>(this); }
+private:
+ alignas(T) char data[sizeof(T) * Count];
+};
+
template<typename T>
void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
{
@@ -623,7 +632,8 @@ void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, Transf
bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
- QColorVector buffer[WorkBlockSize];
+ QUninitialized<QColorVector, WorkBlockSize> buffer;
+
qsizetype i = 0;
while (i < count) {
const qsizetype len = qMin(count - i, WorkBlockSize);
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c17bf2ddfd..edb363ac69 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -669,8 +669,7 @@ static void QT_FASTCALL rbSwap_rgb30(uchar *d, const uchar *s, int count)
{
const uint *src = reinterpret_cast<const uint *>(s);
uint *dest = reinterpret_cast<uint *>(d);
- for (int i = 0; i < count; ++i)
- dest[i] = qRgbSwapRgb30(src[i]);
+ UNALIASED_CONVERSION_LOOP(dest, src, count, qRgbSwapRgb30);
}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
@@ -6774,6 +6773,9 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
+ extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count);
+ qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
+ qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
}
#endif // SSSE3
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 35d61c3e6c..14d7047bb6 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -40,7 +40,7 @@
#include <private/qdrawhelper_x86_p.h>
-#ifdef QT_COMPILER_SUPPORTS_SSSE3
+#if defined(QT_COMPILER_SUPPORTS_SSSE3)
#include <private/qdrawingprimitive_sse2_p.h>
@@ -254,6 +254,49 @@ void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count)
}
}
+void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count)
+{
+ int i = 0;
+
+ const static __m128i shuffleMask1 = _mm_setr_epi8(2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, /*!!*/15);
+ const static __m128i shuffleMask2 = _mm_setr_epi8(0, /*!!*/1, 4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11, /*!!*/14, 15);
+ const static __m128i shuffleMask3 = _mm_setr_epi8(/*!!*/0, 3, 2, 1, 6, 5, 4, 9, 8, 7, 12, 11, 10, 15, 14, 13);
+
+ for (; i + 15 < count; i += 16) {
+ __m128i s1 = _mm_loadu_si128((const __m128i *)src);
+ __m128i s2 = _mm_loadu_si128((const __m128i *)(src + 16));
+ __m128i s3 = _mm_loadu_si128((const __m128i *)(src + 32));
+ s1 = _mm_shuffle_epi8(s1, shuffleMask1);
+ s2 = _mm_shuffle_epi8(s2, shuffleMask2);
+ s3 = _mm_shuffle_epi8(s3, shuffleMask3);
+ _mm_storeu_si128((__m128i *)dst, s1);
+ _mm_storeu_si128((__m128i *)(dst + 16), s2);
+ _mm_storeu_si128((__m128i *)(dst + 32), s3);
+
+ // Now fix the last four misplaced values
+ std::swap(dst[15], dst[17]);
+ std::swap(dst[30], dst[32]);
+
+ src += 48;
+ dst += 48;
+ }
+
+ if (src != dst) {
+ SIMD_EPILOGUE(i, count, 15) {
+ dst[0] = src[2];
+ dst[1] = src[1];
+ dst[2] = src[0];
+ dst += 3;
+ src += 3;
+ }
+ } else {
+ SIMD_EPILOGUE(i, count, 15) {
+ std::swap(dst[0], dst[2]);
+ dst += 3;
+ }
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_COMPILER_SUPPORTS_SSSE3
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
index 45b64de960..18f212f8e9 100644
--- a/src/gui/painting/qicc.cpp
+++ b/src/gui/painting/qicc.cpp
@@ -687,9 +687,6 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
- } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) {
- qCDebug(lcIcc) << "fromIccProfile: BT.2020 primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::Bt2020;
}
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c71d82546a..601dc97be1 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -446,14 +446,22 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->setRedBlueSwizzle(false);
}
- // There is no way to tell if the OpenGL-rendered content is premultiplied or not.
- // For compatibility, assume that it is not, and use normal alpha blend always.
- if (d_ptr->premultiplied)
- funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
-
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
+ bool blendIsPremultiplied = d_ptr->premultiplied;
for (int i = 0; i < textures->count(); ++i) {
- if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
+ const QPlatformTextureList::Flags flags = textures->flags(i);
+ if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
+ if (!blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = true;
+ }
+ } else {
+ if (blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = false;
+ }
+ }
+ if (flags.testFlag(QPlatformTextureList::StacksOnTop))
blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 414d2bf0de..4f08b0092f 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -81,7 +81,8 @@ class Q_GUI_EXPORT QPlatformTextureList : public QObject
public:
enum Flag {
StacksOnTop = 0x01,
- TextureIsSrgb = 0x02
+ TextureIsSrgb = 0x02,
+ NeedsPremultipliedAlphaBlending = 0x04
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/gui/rhi/cs_tdr.h b/src/gui/rhi/cs_tdr.h
new file mode 100644
index 0000000000..f80cb3a498
--- /dev/null
+++ b/src/gui/rhi/cs_tdr.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Gui module
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#ifdef Q_OS_WIN
+
+#include <qt_windows.h>
+
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ConstantBuffer
+// {
+//
+// uint zero; // Offset: 0 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// uav UAV uint buf u0 1
+// ConstantBuffer cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// no Input
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// no Output
+cs_5_0
+dcl_globalFlags refactoringAllowed
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_uav_typed_buffer (uint,uint,uint,uint) u0
+dcl_input vThreadID.x
+dcl_thread_group 256, 1, 1
+loop
+ breakc_nz cb0[0].x
+ store_uav_typed u0.xyzw, vThreadID.xxxx, cb0[0].xxxx
+endloop
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_killDeviceByTimingOut[] =
+{
+ 68, 88, 66, 67, 217, 62,
+ 220, 38, 136, 51, 86, 245,
+ 161, 96, 18, 35, 141, 17,
+ 26, 13, 1, 0, 0, 0,
+ 164, 2, 0, 0, 5, 0,
+ 0, 0, 52, 0, 0, 0,
+ 100, 1, 0, 0, 116, 1,
+ 0, 0, 132, 1, 0, 0,
+ 8, 2, 0, 0, 82, 68,
+ 69, 70, 40, 1, 0, 0,
+ 1, 0, 0, 0, 144, 0,
+ 0, 0, 2, 0, 0, 0,
+ 60, 0, 0, 0, 0, 5,
+ 83, 67, 0, 1, 0, 0,
+ 0, 1, 0, 0, 82, 68,
+ 49, 49, 60, 0, 0, 0,
+ 24, 0, 0, 0, 32, 0,
+ 0, 0, 40, 0, 0, 0,
+ 36, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0,
+ 124, 0, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 0,
+ 1, 0, 0, 0, 255, 255,
+ 255, 255, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 128, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 117, 97,
+ 118, 0, 67, 111, 110, 115,
+ 116, 97, 110, 116, 66, 117,
+ 102, 102, 101, 114, 0, 171,
+ 128, 0, 0, 0, 1, 0,
+ 0, 0, 168, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 208, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0,
+ 2, 0, 0, 0, 220, 0,
+ 0, 0, 0, 0, 0, 0,
+ 255, 255, 255, 255, 0, 0,
+ 0, 0, 255, 255, 255, 255,
+ 0, 0, 0, 0, 122, 101,
+ 114, 111, 0, 100, 119, 111,
+ 114, 100, 0, 171, 0, 0,
+ 19, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 213, 0, 0, 0, 77, 105,
+ 99, 114, 111, 115, 111, 102,
+ 116, 32, 40, 82, 41, 32,
+ 72, 76, 83, 76, 32, 83,
+ 104, 97, 100, 101, 114, 32,
+ 67, 111, 109, 112, 105, 108,
+ 101, 114, 32, 49, 48, 46,
+ 49, 0, 73, 83, 71, 78,
+ 8, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0,
+ 79, 83, 71, 78, 8, 0,
+ 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 83, 72,
+ 69, 88, 124, 0, 0, 0,
+ 80, 0, 5, 0, 31, 0,
+ 0, 0, 106, 8, 0, 1,
+ 89, 0, 0, 4, 70, 142,
+ 32, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 156, 8,
+ 0, 4, 0, 224, 17, 0,
+ 0, 0, 0, 0, 68, 68,
+ 0, 0, 95, 0, 0, 2,
+ 18, 0, 2, 0, 155, 0,
+ 0, 4, 0, 1, 0, 0,
+ 1, 0, 0, 0, 1, 0,
+ 0, 0, 48, 0, 0, 1,
+ 3, 0, 4, 4, 10, 128,
+ 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 164, 0,
+ 0, 7, 242, 224, 17, 0,
+ 0, 0, 0, 0, 6, 0,
+ 2, 0, 6, 128, 32, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 22, 0, 0, 1,
+ 62, 0, 0, 1, 83, 84,
+ 65, 84, 148, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0
+};
+
+#endif // Q_OS_WIN
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 4414b61d55..858be0159b 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -439,6 +439,18 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
visible in external GPU debugging tools will not be available and functions
like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid
enabling in production builds as it may involve a performance penalty.
+
+ \value PreferSoftwareRenderer Indicates that backends should prefer
+ choosing an adapter or physical device that renders in software on the CPU.
+ For example, with Direct3D there is typically a "Basic Render Driver"
+ adapter available with \c{DXGI_ADAPTER_FLAG_SOFTWARE}. Setting this flag
+ requests the backend to choose that adapter over any other, as long as no
+ specific adapter was forced by other backend-specific means. With Vulkan
+ this maps to preferring physical devices with
+ \c{VK_PHYSICAL_DEVICE_TYPE_CPU}. When not available, or when it is not
+ possible to decide if an adapter/device is software-based, this flag is
+ ignored. It may also be ignored with graphics APIs that have no concept and
+ means of enumerating adapters/devices.
*/
/*!
@@ -455,8 +467,8 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value FrameOpDeviceLost The graphics device was lost. This can be
recoverable by attempting to repeat the operation (such as, beginFrame())
- and releasing and reinitializing all objects backed by native graphics
- resources.
+ after releasing and reinitializing all objects backed by native graphics
+ resources. See isDeviceLost().
*/
/*!
@@ -673,7 +685,7 @@ bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClear
*/
uint qHash(const QRhiDepthStencilClearValue &v, uint seed) Q_DECL_NOTHROW
{
- return seed * (qFloor(v.depthClearValue() * 100) + v.stencilClearValue());
+ return seed * (uint(qFloor(qreal(v.depthClearValue()) * 100)) + v.stencilClearValue());
}
#ifndef QT_NO_DEBUG_STREAM
@@ -768,7 +780,8 @@ bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW
uint qHash(const QRhiViewport &v, uint seed) Q_DECL_NOTHROW
{
const std::array<float, 4> r = v.viewport();
- return seed + r[0] + r[1] + r[2] + r[3] + qFloor(v.minDepth() * 100) + qFloor(v.maxDepth() * 100);
+ return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3])
+ + uint(qFloor(qreal(v.minDepth()) * 100)) + uint(qFloor(qreal(v.maxDepth()) * 100));
}
#ifndef QT_NO_DEBUG_STREAM
@@ -850,7 +863,7 @@ bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW
uint qHash(const QRhiScissor &v, uint seed) Q_DECL_NOTHROW
{
const std::array<int, 4> r = v.scissor();
- return seed + r[0] + r[1] + r[2] + r[3];
+ return seed + uint(r[0]) + uint(r[1]) + uint(r[2]) + uint(r[3]);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -1136,7 +1149,7 @@ bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribut
*/
uint qHash(const QRhiVertexInputAttribute &v, uint seed) Q_DECL_NOTHROW
{
- return seed + v.binding() + v.location() + v.format() + v.offset();
+ return seed + uint(v.binding()) + uint(v.location()) + uint(v.format()) + v.offset();
}
#ifndef QT_NO_DEBUG_STREAM
@@ -3001,7 +3014,7 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
{
const char *u = reinterpret_cast<const char *>(&b.d->u);
- return seed + b.d->binding + 10 * b.d->stage + 100 * b.d->type
+ return seed + uint(b.d->binding) + 10 * uint(b.d->stage) + 100 * uint(b.d->type)
+ qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
}
@@ -3457,10 +3470,18 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
Flag values to describe swapchain properties
\value SurfaceHasPreMulAlpha Indicates that the target surface has
- transparency with premultiplied alpha.
+ transparency with premultiplied alpha. For example, this is what Qt Quick
+ uses when the alpha channel is enabled on the target QWindow, because the
+ scenegraph rendrerer always outputs fragments with alpha multiplied into
+ the red, green, and blue values. To ensure identical behavior across
+ platforms, always set QSurfaceFormat::alphaBufferSize() to a non-zero value
+ on the target QWindow whenever this flag is set on the swapchain.
\value SurfaceHasNonPreMulAlpha Indicates the target surface has
- transparencyt with non-premultiplied alpha.
+ transparency with non-premultiplied alpha. Be aware that this may not be
+ supported on some systems, if the system compositor always expects content
+ with premultiplied alpha. In that case the behavior with this flag set is
+ expected to be equivalent to SurfaceHasPreMulAlpha.
\value sRGB Requests to pick an sRGB format for the swapchain and/or its
render target views, where applicable. Note that this implies that sRGB
@@ -3823,8 +3844,8 @@ void QRhiImplementation::compressedFormatInfo(QRhiTexture::Format format, const
break;
}
- const quint32 wblocks = (size.width() + xdim - 1) / xdim;
- const quint32 hblocks = (size.height() + ydim - 1) / ydim;
+ const quint32 wblocks = uint((size.width() + xdim - 1) / xdim);
+ const quint32 hblocks = uint((size.height() + ydim - 1) / ydim);
if (bpl)
*bpl = wblocks * blockSize;
@@ -3880,9 +3901,9 @@ void QRhiImplementation::textureFormatInfo(QRhiTexture::Format format, const QSi
}
if (bpl)
- *bpl = size.width() * bpc;
+ *bpl = uint(size.width()) * bpc;
if (byteSize)
- *byteSize = size.width() * size.height() * bpc;
+ *byteSize = uint(size.width() * size.height()) * bpc;
}
// Approximate because it excludes subresource alignment or multisampling.
@@ -3892,12 +3913,12 @@ quint32 QRhiImplementation::approxByteSizeForTexture(QRhiTexture::Format format,
quint32 approxSize = 0;
for (int level = 0; level < mipCount; ++level) {
quint32 byteSize = 0;
- const QSize size(qFloor(float(qMax(1, baseSize.width() >> level))),
- qFloor(float(qMax(1, baseSize.height() >> level))));
+ const QSize size(qFloor(qreal(qMax(1, baseSize.width() >> level))),
+ qFloor(qreal(qMax(1, baseSize.height() >> level))));
textureFormatInfo(format, size, nullptr, &byteSize);
approxSize += byteSize;
}
- approxSize *= layerCount;
+ approxSize *= uint(layerCount);
return approxSize;
}
@@ -5001,10 +5022,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
has to ensure external OpenGL code provided by the application can still
run like it did before with direct usage of OpenGL, as long as the QRhi is
using the OpenGL backend.
+
+ \return false when failed, similarly to QOpenGLContext::makeCurrent(). When
+ the operation failed, isDeviceLost() can be called to determine if there
+ was a loss of context situation. Such a check is equivalent to checking via
+ QOpenGLContext::isValid().
+
+ \sa QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()
*/
-void QRhi::makeThreadLocalNativeContextCurrent()
+bool QRhi::makeThreadLocalNativeContextCurrent()
{
- d->makeThreadLocalNativeContextCurrent();
+ return d->makeThreadLocalNativeContextCurrent();
}
/*!
@@ -5020,6 +5048,70 @@ QRhiProfiler *QRhi::profiler()
}
/*!
+ Attempts to release resources in the backend's caches. This can include both
+ CPU and GPU resources. Only memory and resources that can be recreated
+ automatically are in scope. As an example, if the backend's
+ QRhiGraphicsPipeline implementation maintains a cache of shader compilation
+ results, calling this function leads to emptying that cache, thus
+ potentially freeing up memory and graphics resources.
+
+ Calling this function makes sense in resource constrained environments,
+ where at a certain point there is a need to ensure minimal resource usage,
+ at the expense of performance.
+ */
+void QRhi::releaseCachedResources()
+{
+ d->releaseCachedResources();
+}
+
+/*!
+ \return true if the graphics device was lost.
+
+ The loss of the device is typically detected in beginFrame(), endFrame() or
+ QRhiSwapChain::buildOrResize(), depending on the backend and the underlying
+ native APIs. The most common is endFrame() because that is where presenting
+ happens. With some backends QRhiSwapChain::buildOrResize() can also fail
+ due to a device loss. Therefore this function is provided as a generic way
+ to check if a device loss was detected by a previous operation.
+
+ When the device is lost, no further operations should be done via the QRhi.
+ Rather, all QRhi resources should be released, followed by destroying the
+ QRhi. A new QRhi can then be attempted to be created. If successful, all
+ graphics resources must be reinitialized. If not, try again later,
+ repeatedly.
+
+ While simple applications may decide to not care about device loss,
+ on the commonly used desktop platforms a device loss can happen
+ due to a variety of reasons, including physically disconnecting the
+ graphics adapter, disabling the device or driver, uninstalling or upgrading
+ the graphics driver, or due to errors that lead to a graphics device reset.
+ Some of these can happen under perfectly normal circumstances as well, for
+ example the upgrade of the graphics driver to a newer version is a common
+ task that can happen at any time while a Qt application is running. Users
+ may very well expect applications to be able to survive this, even when the
+ application is actively using an API like OpenGL or Direct3D.
+
+ Qt's own frameworks built on top of QRhi, such as, Qt Quick, can be
+ expected to handle and take appropriate measures when a device loss occurs.
+ If the data for graphics resources, such as textures and buffers, are still
+ available on the CPU side, such an event may not be noticeable on the
+ application level at all since graphics resources can seamlessly be
+ reinitialized then. However, applications and libraries working directly
+ with QRhi are expected to be prepared to check and handle device loss
+ situations themselves.
+
+ \note With OpenGL, applications may need to opt-in to context reset
+ notifications by setting QSurfaceFormat::ResetNotification on the
+ QOpenGLContext. This is typically done by enabling the flag in
+ QRhiGles2InitParams::format. Keep in mind however that some systems may
+ generate context resets situations even when this flag is not set.
+ */
+bool QRhi::isDeviceLost() const
+{
+ return d->isDeviceLost();
+}
+
+/*!
\return a new graphics pipeline resource.
\sa QRhiResource::release()
@@ -5180,7 +5272,17 @@ QRhiSwapChain *QRhi::newSwapChain()
\endlist
- \sa endFrame(), beginOffscreenFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa endFrame(), beginOffscreenFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
{
@@ -5205,7 +5307,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
Passing QRhi::SkipPresent skips queuing the Present command or calling
swapBuffers.
- \sa beginFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa beginFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
{
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 2d36c19e99..c73f03cf72 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1294,7 +1294,8 @@ public:
enum Flag {
EnableProfiling = 1 << 0,
- EnableDebugMarkers = 1 << 1
+ EnableDebugMarkers = 1 << 1,
+ PreferSoftwareRenderer = 1 << 2
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -1413,13 +1414,17 @@ public:
int resourceLimit(ResourceLimit limit) const;
const QRhiNativeHandles *nativeHandles();
- void makeThreadLocalNativeContextCurrent();
+ bool makeThreadLocalNativeContextCurrent();
QRhiProfiler *profiler();
static const int MAX_LAYERS = 6; // cubemaps only
static const int MAX_LEVELS = 16; // a width and/or height of 65536 should be enough for everyone
+ void releaseCachedResources();
+
+ bool isDeviceLost() const;
+
protected:
QRhi();
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 0914cf268b..63f27b6de4 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -156,7 +156,9 @@ public:
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
virtual const QRhiNativeHandles *nativeHandles() = 0;
virtual void sendVMemStatsToProfiler() = 0;
- virtual void makeThreadLocalNativeContextCurrent() = 0;
+ virtual bool makeThreadLocalNativeContextCurrent() = 0;
+ virtual void releaseCachedResources() = 0;
+ virtual bool isDeviceLost() const = 0;
bool isCompressedFormat(QRhiTexture::Format format) const;
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size,
@@ -205,6 +207,8 @@ public:
QRhi *q;
+ static const int MAX_SHADER_CACHE_ENTRIES = 128;
+
protected:
bool debugMarkers = false;
int currentFrameSlot = 0; // for vk, mtl, and similar. unused by gl and d3d11.
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 3e136cdb80..1d2f3cfa80 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -36,6 +36,7 @@
#include "qrhid3d11_p_p.h"
#include "qshader_p.h"
+#include "cs_tdr.h"
#include <QWindow>
#include <QOperatingSystemVersion>
#include <qmath.h>
@@ -118,10 +119,20 @@ QT_BEGIN_NAMESPACE
\c{ID3D11Texture2D *}.
*/
+// help mingw with its ancient sdk headers
+#ifndef DXGI_ADAPTER_FLAG_SOFTWARE
+#define DXGI_ADAPTER_FLAG_SOFTWARE 2
+#endif
+
QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice)
- : ofr(this)
+ : ofr(this),
+ deviceCurse(this)
{
debugLayer = params->enableDebugLayer;
+
+ deviceCurse.framesToActivate = params->framesUntilKillingDeviceViaTdr;
+ deviceCurse.permanent = params->repeatDeviceKill;
+
importedDevice = importDevice != nullptr;
if (importedDevice) {
dev = reinterpret_cast<ID3D11Device *>(importDevice->dev);
@@ -155,7 +166,7 @@ static QString comErrorMessage(HRESULT hr)
}
template <class Int>
-static inline Int aligned(Int v, Int byteAlign)
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -166,7 +177,7 @@ static IDXGIFactory1 *createDXGIFactory2()
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **);
QSystemLibrary dxgilib(QStringLiteral("dxgi"));
- if (auto createDXGIFactory2 = (PtrCreateDXGIFactory2)dxgilib.resolve("CreateDXGIFactory2")) {
+ if (auto createDXGIFactory2 = reinterpret_cast<PtrCreateDXGIFactory2>(dxgilib.resolve("CreateDXGIFactory2"))) {
const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result));
if (FAILED(hr)) {
qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr)));
@@ -221,11 +232,29 @@ bool QRhiD3D11::create(QRhi::Flags flags)
int requestedAdapterIndex = -1;
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX");
- for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
+
+ if (requestedAdapterIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
+ for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
+ DXGI_ADAPTER_DESC1 desc;
+ adapter->GetDesc1(&desc);
+ adapter->Release();
+ if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
+ requestedAdapterIndex = adapterIndex;
+ break;
+ }
+ }
+ }
+
+ for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
- const QString name = QString::fromUtf16((char16_t *) desc.Description);
- qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags);
+ const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description));
+ qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (vendor 0x%X device 0x%X flags 0x%X)",
+ adapterIndex,
+ qPrintable(name),
+ desc.VendorId,
+ desc.DeviceId,
+ desc.Flags);
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
adapterToUse = adapter;
qCDebug(QRHI_LOG_INFO, " using this adapter");
@@ -261,16 +290,33 @@ bool QRhiD3D11::create(QRhi::Flags flags)
if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations))))
annotations = nullptr;
+ deviceLost = false;
+
nativeHandlesStruct.dev = dev;
nativeHandlesStruct.context = context;
+ if (deviceCurse.framesToActivate > 0)
+ deviceCurse.initResources();
+
return true;
}
+void QRhiD3D11::clearShaderCache()
+{
+ for (Shader &s : m_shaderCache)
+ s.s->Release();
+
+ m_shaderCache.clear();
+}
+
void QRhiD3D11::destroy()
{
finishActiveReadbacks();
+ clearShaderCache();
+
+ deviceCurse.releaseResources();
+
if (annotations) {
annotations->Release();
annotations = nullptr;
@@ -322,9 +368,9 @@ DXGI_SAMPLE_DESC QRhiD3D11::effectiveSampleCount(int sampleCount) const
return desc;
}
- desc.Count = s;
+ desc.Count = UINT(s);
if (s > 1)
- desc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
+ desc.Quality = UINT(D3D11_STANDARD_MULTISAMPLE_PATTERN);
else
desc.Quality = 0;
@@ -456,9 +502,20 @@ void QRhiD3D11::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiD3D11::makeThreadLocalNativeContextCurrent()
+bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
+}
+
+void QRhiD3D11::releaseCachedResources()
+{
+ clearShaderCache();
+}
+
+bool QRhiD3D11::isDeviceLost() const
+{
+ return deviceLost;
}
QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -640,7 +697,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
- const uint binding = dynOfs.first;
+ const uint binding = uint(dynOfs.first);
Q_ASSERT(aligned(dynOfs.second, quint32(256)) == dynOfs.second);
const uint offsetInConstants = dynOfs.second / 16;
*p++ = binding;
@@ -776,10 +833,10 @@ void QRhiD3D11::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BlendConstants;
cmd.args.blendConstants.ps = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
- cmd.args.blendConstants.c[0] = c.redF();
- cmd.args.blendConstants.c[1] = c.greenF();
- cmd.args.blendConstants.c[2] = c.blueF();
- cmd.args.blendConstants.c[3] = c.alphaF();
+ cmd.args.blendConstants.c[0] = float(c.redF());
+ cmd.args.blendConstants.c[1] = float(c.greenF());
+ cmd.args.blendConstants.c[2] = float(c.blueF());
+ cmd.args.blendConstants.c[3] = float(c.alphaF());
cbD->commands.append(cmd);
}
@@ -977,8 +1034,14 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
if (!flags.testFlag(QRhi::SkipPresent)) {
const UINT presentFlags = 0;
HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags);
- if (FAILED(hr))
+ if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
+ qWarning("Device loss detected in Present()");
+ deviceLost = true;
+ return QRhi::FrameOpDeviceLost;
+ } else if (FAILED(hr)) {
qWarning("Failed to present: %s", qPrintable(comErrorMessage(hr)));
+ return QRhi::FrameOpError;
+ }
// move on to the next buffer
swapChainD->currentFrameSlot = (swapChainD->currentFrameSlot + 1) % QD3D11SwapChain::BUFFER_COUNT;
@@ -988,6 +1051,20 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
swapChainD->frameCount += 1;
contextState.currentSwapChain = nullptr;
+
+ if (deviceCurse.framesToActivate > 0) {
+ deviceCurse.framesLeft -= 1;
+ if (deviceCurse.framesLeft == 0) {
+ deviceCurse.framesLeft = deviceCurse.framesToActivate;
+ if (!deviceCurse.permanent)
+ deviceCurse.framesToActivate = -1;
+
+ deviceCurse.activate();
+ } else if (deviceCurse.framesLeft % 100 == 0) {
+ qDebug("Impending doom: %d frames left", deviceCurse.framesLeft);
+ }
+ }
+
return QRhi::FrameOpSuccess;
}
@@ -1161,7 +1238,7 @@ QRhi::FrameOpResult QRhiD3D11::finish()
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
{
- UINT subres = D3D11CalcSubresource(level, layer, texD->mipLevelCount);
+ UINT subres = D3D11CalcSubresource(UINT(level), UINT(layer), texD->mipLevelCount);
const QPoint dp = subresDesc.destinationTopLeft();
D3D11_BOX box;
box.front = 0;
@@ -1192,13 +1269,13 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
} else {
cmd.args.updateSubRes.src = cbD->retainImage(img);
}
- box.left = dp.x();
- box.top = dp.y();
- box.right = dp.x() + size.width();
- box.bottom = dp.y() + size.height();
+ box.left = UINT(dp.x());
+ box.top = UINT(dp.y());
+ box.right = UINT(dp.x() + size.width());
+ box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
- cmd.args.updateSubRes.srcRowPitch = bpl;
+ cmd.args.updateSubRes.srcRowPitch = UINT(bpl);
} else if (!subresDesc.data().isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
@@ -1208,10 +1285,10 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
// Everything must be a multiple of the block width and
// height, so e.g. a mip level of size 2x2 will be 4x4 when it
// comes to the actual data.
- box.left = aligned(dp.x(), blockDim.width());
- box.top = aligned(dp.y(), blockDim.height());
- box.right = aligned(dp.x() + size.width(), blockDim.width());
- box.bottom = aligned(dp.y() + size.height(), blockDim.height());
+ box.left = UINT(aligned(dp.x(), blockDim.width()));
+ box.top = UINT(aligned(dp.y(), blockDim.height()));
+ box.right = UINT(aligned(dp.x() + size.width(), blockDim.width()));
+ box.bottom = UINT(aligned(dp.y() + size.height(), blockDim.height()));
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@@ -1220,12 +1297,11 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
quint32 bpl = 0;
- QSize blockDim;
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
- box.left = dp.x();
- box.top = dp.y();
- box.right = dp.x() + size.width();
- box.bottom = dp.y() + size.height();
+ box.left = UINT(dp.x());
+ box.top = UINT(dp.y());
+ box.right = UINT(dp.x() + size.width());
+ box.bottom = UINT(dp.y() + size.height());
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
cmd.args.updateSubRes.src = cbD->retainData(subresDesc.data());
@@ -1247,7 +1323,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : ud->dynamicBufferUpdates) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
- memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), u.data.size());
+ memcpy(bufD->dynBuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
bufD->hasPendingDynamicUpdates = true;
}
@@ -1265,10 +1341,10 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
// since the ID3D11Buffer's size is rounded up to be a multiple of 256
// while the data we have has the original size.
D3D11_BOX box;
- box.left = u.offset;
+ box.left = UINT(u.offset);
box.top = box.front = 0;
box.back = box.bottom = 1;
- box.right = u.offset + u.data.size(); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
+ box.right = UINT(u.offset + u.data.size()); // no -1: right, bottom, back are exclusive, see D3D11_BOX doc
cmd.args.updateSubRes.hasDstBox = true;
cmd.args.updateSubRes.dstBox = box;
cbD->commands.append(cmd);
@@ -1287,25 +1363,25 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
Q_ASSERT(u.copy.src && u.copy.dst);
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.copy.src);
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.copy.dst);
- UINT srcSubRes = D3D11CalcSubresource(u.copy.desc.sourceLevel(), u.copy.desc.sourceLayer(), srcD->mipLevelCount);
- UINT dstSubRes = D3D11CalcSubresource(u.copy.desc.destinationLevel(), u.copy.desc.destinationLayer(), dstD->mipLevelCount);
+ UINT srcSubRes = D3D11CalcSubresource(UINT(u.copy.desc.sourceLevel()), UINT(u.copy.desc.sourceLayer()), srcD->mipLevelCount);
+ UINT dstSubRes = D3D11CalcSubresource(UINT(u.copy.desc.destinationLevel()), UINT(u.copy.desc.destinationLayer()), dstD->mipLevelCount);
const QPoint dp = u.copy.desc.destinationTopLeft();
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
const QPoint sp = u.copy.desc.sourceTopLeft();
D3D11_BOX srcBox;
- srcBox.left = sp.x();
- srcBox.top = sp.y();
+ srcBox.left = UINT(sp.x());
+ srcBox.top = UINT(sp.y());
srcBox.front = 0;
// back, right, bottom are exclusive
- srcBox.right = srcBox.left + size.width();
- srcBox.bottom = srcBox.top + size.height();
+ srcBox.right = srcBox.left + UINT(size.width());
+ srcBox.bottom = srcBox.top + UINT(size.height());
srcBox.back = 1;
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
cmd.args.copySubRes.dst = dstD->tex;
cmd.args.copySubRes.dstSubRes = dstSubRes;
- cmd.args.copySubRes.dstX = dp.x();
- cmd.args.copySubRes.dstY = dp.y();
+ cmd.args.copySubRes.dstX = UINT(dp.x());
+ cmd.args.copySubRes.dstY = UINT(dp.y());
cmd.args.copySubRes.src = srcD->tex;
cmd.args.copySubRes.srcSubRes = srcSubRes;
cmd.args.copySubRes.hasSrcBox = true;
@@ -1333,7 +1409,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
dxgiFormat = texD->dxgiFormat;
pixelSize = u.read.rb.level() > 0 ? q->sizeForMipLevel(u.read.rb.level(), texD->m_pixelSize) : texD->m_pixelSize;
format = texD->m_format;
- subres = D3D11CalcSubresource(u.read.rb.level(), u.read.rb.layer(), texD->mipLevelCount);
+ subres = D3D11CalcSubresource(UINT(u.read.rb.level()), UINT(u.read.rb.layer()), texD->mipLevelCount);
} else {
Q_ASSERT(contextState.currentSwapChain);
swapChainD = QRHI_RES(QD3D11SwapChain, contextState.currentSwapChain);
@@ -1362,8 +1438,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = pixelSize.width();
- desc.Height = pixelSize.height();
+ desc.Width = UINT(pixelSize.width());
+ desc.Height = UINT(pixelSize.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = dxgiFormat;
@@ -1376,7 +1452,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
qWarning("Failed to create readback staging texture: %s", qPrintable(comErrorMessage(hr)));
return;
}
- QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(stagingTex)),
+ QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(stagingTex)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
bufSize));
@@ -1419,7 +1495,7 @@ void QRhiD3D11::finishActiveReadbacks()
const QRhiD3D11::ActiveReadback &aRb(activeReadbacks[i]);
aRb.result->format = aRb.format;
aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
+ aRb.result->data.resize(int(aRb.bufSize));
D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(aRb.stagingTex, 0, D3D11_MAP_READ, 0, &mp);
@@ -1440,7 +1516,7 @@ void QRhiD3D11::finishActiveReadbacks()
context->Unmap(aRb.stagingTex, 0);
aRb.stagingTex->Release();
- QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.stagingTex))));
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.stagingTex))));
if (aRb.result->completed)
completedCallbacks.append(aRb.result->completed);
@@ -1509,10 +1585,10 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= QD3D11CommandBuffer::Command::Depth | QD3D11CommandBuffer::Command::Stencil;
- clearCmd.args.clear.c[0] = colorClearValue.redF();
- clearCmd.args.clear.c[1] = colorClearValue.greenF();
- clearCmd.args.clear.c[2] = colorClearValue.blueF();
- clearCmd.args.clear.c[3] = colorClearValue.alphaF();
+ clearCmd.args.clear.c[0] = float(colorClearValue.redF());
+ clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
+ clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
+ clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd);
@@ -1543,8 +1619,8 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex;
- cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel(),
- colorAtt.resolveLayer(),
+ cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
+ UINT(colorAtt.resolveLayer()),
dstTexD->mipLevelCount);
if (srcTexD) {
cmd.args.resolveSubRes.src = srcTexD->tex;
@@ -1571,7 +1647,7 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
continue;
}
}
- cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, colorAtt.layer(), 1);
+ cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, UINT(colorAtt.layer()), 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
cbD->commands.append(cmd);
}
@@ -1638,9 +1714,9 @@ void QRhiD3D11::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::Dispatch;
- cmd.args.dispatch.x = x;
- cmd.args.dispatch.y = y;
- cmd.args.dispatch.z = z;
+ cmd.args.dispatch.x = UINT(x);
+ cmd.args.dispatch.y = UINT(y);
+ cmd.args.dispatch.z = UINT(z);
cbD->commands.append(cmd);
}
@@ -1682,11 +1758,11 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
// dynamic ubuf offsets are not considered here, those are baked in
// at a later stage, which is good as vsubufoffsets and friends are
// per-srb, not per-setShaderResources call
- const uint offsetInConstants = b->u.ubuf.offset / 16;
+ const uint offsetInConstants = uint(b->u.ubuf.offset) / 16;
// size must be 16 mult. (in constants, i.e. multiple of 256 bytes).
// We can round up if needed since the buffers's actual size
// (ByteWidth) is always a multiple of 256.
- const uint sizeInConstants = aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16;
+ const uint sizeInConstants = uint(aligned(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size, 256) / 16);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
srbD->vsubufs.feed(b->binding, bufD->buffer);
srbD->vsubufoffsets.feed(b->binding, offsetInConstants);
@@ -1804,7 +1880,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
if (SUCCEEDED(hr)) {
- memcpy(mp.pData, bufD->dynBuf.constData(), bufD->dynBuf.size());
+ memcpy(mp.pData, bufD->dynBuf.constData(), size_t(bufD->dynBuf.size()));
context->Unmap(bufD->buffer, 0);
} else {
qWarning("Failed to map buffer: %s", qPrintable(comErrorMessage(hr)));
@@ -1817,13 +1893,13 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
QRhiBatchedBindings<UINT> *ubufoffsets,
const uint *dynOfsPairs, int dynOfsPairCount)
{
- const UINT count = ubufs->batches[batchIndex].resources.count();
+ const int count = ubufs->batches[batchIndex].resources.count();
const UINT startBinding = ubufs->batches[batchIndex].startBinding;
*offsets = ubufoffsets->batches[batchIndex].resources;
- for (UINT b = 0; b < count; ++b) {
+ for (int b = 0; b < count; ++b) {
for (int di = 0; di < dynOfsPairCount; ++di) {
const uint binding = dynOfsPairs[2 * di];
- if (binding == startBinding + b) {
+ if (binding == startBinding + UINT(b)) {
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
(*offsets)[b] = offsetInConstants;
break;
@@ -1838,37 +1914,37 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
{
if (!offsetOnlyChange) {
for (const auto &batch : srbD->vssamplers.batches)
- context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->VSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->vsshaderresources.batches) {
- context->VSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->VSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.vsHighestActiveSrvBinding = qMax<int>(contextState.vsHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
for (const auto &batch : srbD->fssamplers.batches)
- context->PSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->PSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->fsshaderresources.batches) {
- context->PSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->PSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.fsHighestActiveSrvBinding = qMax<int>(contextState.fsHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
for (const auto &batch : srbD->cssamplers.batches)
- context->CSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->CSSetSamplers(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
for (const auto &batch : srbD->csshaderresources.batches) {
- context->CSSetShaderResources(batch.startBinding, batch.resources.count(), batch.resources.constData());
+ context->CSSetShaderResources(batch.startBinding, UINT(batch.resources.count()), batch.resources.constData());
contextState.csHighestActiveSrvBinding = qMax<int>(contextState.csHighestActiveSrvBinding,
- batch.startBinding + batch.resources.count() - 1);
+ int(batch.startBinding) + batch.resources.count() - 1);
}
}
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
- srbD->vsubufs.batches[i].resources.count(),
+ UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(),
srbD->vsubufoffsets.batches[i].resources.constData(),
srbD->vsubufsizes.batches[i].resources.constData());
@@ -1876,7 +1952,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->vsubufs, &srbD->vsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
- srbD->vsubufs.batches[i].resources.count(),
+ UINT(srbD->vsubufs.batches[i].resources.count()),
srbD->vsubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->vsubufsizes.batches[i].resources.constData());
@@ -1886,7 +1962,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->fsubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
- srbD->fsubufs.batches[i].resources.count(),
+ UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(),
srbD->fsubufoffsets.batches[i].resources.constData(),
srbD->fsubufsizes.batches[i].resources.constData());
@@ -1894,7 +1970,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->fsubufs, &srbD->fsubufoffsets, dynOfsPairs, dynOfsPairCount);
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
- srbD->fsubufs.batches[i].resources.count(),
+ UINT(srbD->fsubufs.batches[i].resources.count()),
srbD->fsubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->fsubufsizes.batches[i].resources.constData());
@@ -1904,7 +1980,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csubufs.batches.count(); i != ie; ++i) {
if (!dynOfsPairCount) {
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
- srbD->csubufs.batches[i].resources.count(),
+ UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(),
srbD->csubufoffsets.batches[i].resources.constData(),
srbD->csubufsizes.batches[i].resources.constData());
@@ -1912,7 +1988,7 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
QVarLengthArray<UINT, 4> offsets;
applyDynamicOffsets(&offsets, i, &srbD->csubufs, &srbD->csubufoffsets, dynOfsPairs, dynOfsPairCount);
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
- srbD->csubufs.batches[i].resources.count(),
+ UINT(srbD->csubufs.batches[i].resources.count()),
srbD->csubufs.batches[i].resources.constData(),
offsets.constData(),
srbD->csubufsizes.batches[i].resources.constData());
@@ -1921,13 +1997,13 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
for (int i = 0, ie = srbD->csUAVs.batches.count(); i != ie; ++i) {
const uint startBinding = srbD->csUAVs.batches[i].startBinding;
- const uint count = srbD->csUAVs.batches[i].resources.count();
+ const uint count = uint(srbD->csUAVs.batches[i].resources.count());
context->CSSetUnorderedAccessViews(startBinding,
count,
srbD->csUAVs.batches[i].resources.constData(),
nullptr);
contextState.csHighestActiveUavBinding = qMax<int>(contextState.csHighestActiveUavBinding,
- startBinding + count - 1);
+ int(startBinding + count - 1));
}
}
@@ -1951,7 +2027,7 @@ void QRhiD3D11::resetShaderResources()
QVarLengthArray<UINT, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> nulloffsets(count);
for (int i = 0; i < count; ++i)
nulloffsets[i] = 0;
- context->IASetVertexBuffers(0, count, nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
+ context->IASetVertexBuffers(0, UINT(count), nullbufs.constData(), nullstrides.constData(), nulloffsets.constData());
contextState.vsHighestActiveVertexBufferBinding = -1;
}
@@ -1964,15 +2040,15 @@ void QRhiD3D11::resetShaderResources()
for (int i = 0; i < nullsrvs.count(); ++i)
nullsrvs[i] = nullptr;
if (contextState.vsHighestActiveSrvBinding >= 0) {
- context->VSSetShaderResources(0, contextState.vsHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->VSSetShaderResources(0, UINT(contextState.vsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.vsHighestActiveSrvBinding = -1;
}
if (contextState.fsHighestActiveSrvBinding >= 0) {
- context->PSSetShaderResources(0, contextState.fsHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->PSSetShaderResources(0, UINT(contextState.fsHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.fsHighestActiveSrvBinding = -1;
}
if (contextState.csHighestActiveSrvBinding >= 0) {
- context->CSSetShaderResources(0, contextState.csHighestActiveSrvBinding + 1, nullsrvs.constData());
+ context->CSSetShaderResources(0, UINT(contextState.csHighestActiveSrvBinding + 1), nullsrvs.constData());
contextState.csHighestActiveSrvBinding = -1;
}
}
@@ -1983,7 +2059,7 @@ void QRhiD3D11::resetShaderResources()
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> nulluavs(nulluavCount);
for (int i = 0; i < nulluavCount; ++i)
nulluavs[i] = nullptr;
- context->CSSetUnorderedAccessViews(0, nulluavCount, nulluavs.constData(), nullptr);
+ context->CSSetUnorderedAccessViews(0, UINT(nulluavCount), nulluavs.constData(), nullptr);
contextState.csHighestActiveUavBinding = -1;
}
}
@@ -2005,7 +2081,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
// writing the first timestamp only afterwards.
context->Begin(tsDisjoint);
QD3D11RenderTargetData *rtD = rtData(&timestampSwapChain->rt);
- context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
+ context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
context->End(tsStart); // just record a timestamp, no Begin needed
}
}
@@ -2018,7 +2094,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
case QD3D11CommandBuffer::Command::SetRenderTarget:
{
QD3D11RenderTargetData *rtD = rtData(cmd.args.setRenderTarget.rt);
- context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
+ context->OMSetRenderTargets(UINT(rtD->colorAttCount), rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
}
break;
case QD3D11CommandBuffer::Command::Clear:
@@ -2034,7 +2110,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Stencil)
ds |= D3D11_CLEAR_STENCIL;
if (ds)
- context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, cmd.args.clear.s);
+ context->ClearDepthStencilView(rtD->dsv, ds, cmd.args.clear.d, UINT8(cmd.args.clear.s));
}
break;
case QD3D11CommandBuffer::Command::Viewport:
@@ -2064,8 +2140,8 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
contextState.vsHighestActiveVertexBufferBinding = qMax<int>(
contextState.vsHighestActiveVertexBufferBinding,
cmd.args.bindVertexBuffers.startSlot + cmd.args.bindVertexBuffers.slotCount - 1);
- context->IASetVertexBuffers(cmd.args.bindVertexBuffers.startSlot,
- cmd.args.bindVertexBuffers.slotCount,
+ context->IASetVertexBuffers(UINT(cmd.args.bindVertexBuffers.startSlot),
+ UINT(cmd.args.bindVertexBuffers.slotCount),
cmd.args.bindVertexBuffers.buffers,
cmd.args.bindVertexBuffers.strides,
cmd.args.bindVertexBuffers.offsets);
@@ -2208,7 +2284,7 @@ static inline uint toD3DBufferUsage(QRhiBuffer::UsageFlags usage)
u |= D3D11_BIND_CONSTANT_BUFFER;
if (usage.testFlag(QRhiBuffer::StorageBuffer))
u |= D3D11_BIND_UNORDERED_ACCESS;
- return u;
+ return uint(u);
}
bool QD3D11Buffer::build()
@@ -2231,7 +2307,7 @@ bool QD3D11Buffer::build()
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.ByteWidth = roundedSize;
+ desc.ByteWidth = UINT(roundedSize);
desc.Usage = m_type == Dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
desc.BindFlags = toD3DBufferUsage(m_usage);
desc.CPUAccessFlags = m_type == Dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
@@ -2250,10 +2326,10 @@ bool QD3D11Buffer::build()
}
if (!m_objectName.isEmpty())
- buffer->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ buffer->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newBuffer(this, roundedSize, m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
+ QRHI_PROF_F(newBuffer(this, quint32(roundedSize), m_type == Dynamic ? 2 : 1, m_type == Dynamic ? 1 : 0));
generation += 1;
rhiD->registerResource(this);
@@ -2271,7 +2347,7 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
desc.Format = DXGI_FORMAT_R32_TYPELESS;
desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
desc.Buffer.FirstElement = 0;
- desc.Buffer.NumElements = aligned(m_size, 4) / 4;
+ desc.Buffer.NumElements = UINT(aligned(m_size, 4) / 4);
desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
QRHI_RES_RHI(QRhiD3D11);
@@ -2332,8 +2408,8 @@ bool QD3D11RenderBuffer::build()
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = m_pixelSize.width();
- desc.Height = m_pixelSize.height();
+ desc.Width = UINT(m_pixelSize.width());
+ desc.Height = UINT(m_pixelSize.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc = sampleDesc;
@@ -2382,10 +2458,10 @@ bool QD3D11RenderBuffer::build()
}
if (!m_objectName.isEmpty())
- tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newRenderBuffer(this, false, false, sampleDesc.Count));
+ QRHI_PROF_F(newRenderBuffer(this, false, false, int(sampleDesc.Count)));
rhiD->registerResource(this);
return true;
@@ -2475,7 +2551,7 @@ bool QD3D11Texture::prepareBuild(QSize *adjustedSize)
QRHI_RES_RHI(QRhiD3D11);
dxgiFormat = toD3DTextureFormat(m_format, m_flags);
- mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
+ mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
if (sampleDesc.Count > 1) {
if (isCube) {
@@ -2561,8 +2637,8 @@ bool QD3D11Texture::build()
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = size.width();
- desc.Height = size.height();
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
desc.MipLevels = mipLevelCount;
desc.ArraySize = isCube ? 6 : 1;
desc.Format = dxgiFormat;
@@ -2582,10 +2658,10 @@ bool QD3D11Texture::build()
return false;
if (!m_objectName.isEmpty())
- tex->SetPrivateData(WKPDID_D3DDebugObjectName, m_objectName.size(), m_objectName.constData());
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, sampleDesc.Count));
+ QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, int(sampleDesc.Count)));
owns = true;
rhiD->registerResource(this);
@@ -2607,7 +2683,7 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
return false;
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, sampleDesc.Count));
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, int(sampleDesc.Count)));
owns = false;
QRHI_RES_RHI(QRhiD3D11);
@@ -2631,12 +2707,12 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
desc.Format = dxgiFormat;
if (isCube) {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
- desc.Texture2DArray.MipSlice = level;
+ desc.Texture2DArray.MipSlice = UINT(level);
desc.Texture2DArray.FirstArraySlice = 0;
desc.Texture2DArray.ArraySize = 6;
} else {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
- desc.Texture2D.MipSlice = level;
+ desc.Texture2D.MipSlice = UINT(level);
}
QRHI_RES_RHI(QRhiD3D11);
@@ -2896,15 +2972,15 @@ bool QD3D11TextureRenderTarget::build()
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = colorAttachments[i].level();
- rtvDesc.Texture2DArray.FirstArraySlice = colorAttachments[i].layer();
+ rtvDesc.Texture2DArray.MipSlice = UINT(colorAttachments[i].level());
+ rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAttachments[i].layer());
rtvDesc.Texture2DArray.ArraySize = 1;
} else {
if (texD->sampleDesc.Count > 1) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
} else {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = colorAttachments[i].level();
+ rtvDesc.Texture2D.MipSlice = UINT(colorAttachments[i].level());
}
}
HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
@@ -2915,7 +2991,7 @@ bool QD3D11TextureRenderTarget::build()
ownsRtv[i] = true;
if (i == 0) {
d.pixelSize = texD->pixelSize();
- d.sampleCount = texD->sampleDesc.Count;
+ d.sampleCount = int(texD->sampleDesc.Count);
}
} else if (rb) {
QD3D11RenderBuffer *rbD = QRHI_RES(QD3D11RenderBuffer, rb);
@@ -2923,7 +2999,7 @@ bool QD3D11TextureRenderTarget::build()
rtv[i] = rbD->rtv;
if (i == 0) {
d.pixelSize = rbD->pixelSize();
- d.sampleCount = rbD->sampleDesc.Count;
+ d.sampleCount = int(rbD->sampleDesc.Count);
}
}
}
@@ -2945,7 +3021,7 @@ bool QD3D11TextureRenderTarget::build()
}
if (d.colorAttCount == 0) {
d.pixelSize = depthTexD->pixelSize();
- d.sampleCount = depthTexD->sampleDesc.Count;
+ d.sampleCount = int(depthTexD->sampleDesc.Count);
}
} else {
ownsDsv = false;
@@ -2953,7 +3029,7 @@ bool QD3D11TextureRenderTarget::build()
dsv = depthRbD->dsv;
if (d.colorAttCount == 0) {
d.pixelSize = m_desc.depthStencilBuffer()->pixelSize();
- d.sampleCount = depthRbD->sampleDesc.Count;
+ d.sampleCount = int(depthRbD->sampleDesc.Count);
}
}
d.dsAttCount = 1;
@@ -3177,9 +3253,9 @@ static inline D3D11_PRIMITIVE_TOPOLOGY toD3DTopology(QRhiGraphicsPipeline::Topol
}
}
-static inline uint toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
+static inline UINT8 toD3DColorWriteMask(QRhiGraphicsPipeline::ColorMask c)
{
- uint f = 0;
+ UINT8 f = 0;
if (c.testFlag(QRhiGraphicsPipeline::R))
f |= D3D11_COLOR_WRITE_ENABLE_RED;
if (c.testFlag(QRhiGraphicsPipeline::G))
@@ -3314,22 +3390,22 @@ static QByteArray compileHlslShaderSource(const QShader &shader, QShader::Varian
ID3DBlob *bytecode = nullptr;
ID3DBlob *errors = nullptr;
- HRESULT hr = d3dCompile(hlslSource.shader().constData(), hlslSource.shader().size(),
+ HRESULT hr = d3dCompile(hlslSource.shader().constData(), SIZE_T(hlslSource.shader().size()),
nullptr, nullptr, nullptr,
hlslSource.entryPoint().constData(), target, 0, 0, &bytecode, &errors);
if (FAILED(hr) || !bytecode) {
qWarning("HLSL shader compilation failed: 0x%x", uint(hr));
if (errors) {
*error = QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()),
- errors->GetBufferSize());
+ int(errors->GetBufferSize()));
errors->Release();
}
return QByteArray();
}
QByteArray result;
- result.resize(bytecode->GetBufferSize());
- memcpy(result.data(), bytecode->GetBufferPointer(), result.size());
+ result.resize(int(bytecode->GetBufferSize()));
+ memcpy(result.data(), bytecode->GetBufferPointer(), size_t(result.size()));
bytecode->Release();
return result;
}
@@ -3361,8 +3437,8 @@ bool QD3D11GraphicsPipeline::build()
dsDesc.DepthFunc = toD3DCompareOp(m_depthOp);
dsDesc.StencilEnable = m_stencilTest;
if (m_stencilTest) {
- dsDesc.StencilReadMask = m_stencilReadMask;
- dsDesc.StencilWriteMask = m_stencilWriteMask;
+ dsDesc.StencilReadMask = UINT8(m_stencilReadMask);
+ dsDesc.StencilWriteMask = UINT8(m_stencilWriteMask);
dsDesc.FrontFace.StencilFailOp = toD3DStencilOp(m_stencilFront.failOp);
dsDesc.FrontFace.StencilDepthFailOp = toD3DStencilOp(m_stencilFront.depthFailOp);
dsDesc.FrontFace.StencilPassOp = toD3DStencilOp(m_stencilFront.passOp);
@@ -3409,30 +3485,57 @@ bool QD3D11GraphicsPipeline::build()
QByteArray vsByteCode;
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- hr = rhiD->dev->CreateVertexShader(bytecode.constData(), bytecode.size(), nullptr, &vs);
- if (FAILED(hr)) {
- qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ auto cacheIt = rhiD->m_shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ vs = static_cast<ID3D11VertexShader *>(cacheIt->s);
+ vs->AddRef();
+ vsByteCode = cacheIt->bytecode;
+ break;
+ case QRhiShaderStage::Fragment:
+ fs = static_cast<ID3D11PixelShader *>(cacheIt->s);
+ fs->AddRef();
+ break;
+ default:
+ break;
}
- vsByteCode = bytecode;
- break;
- case QRhiShaderStage::Fragment:
- hr = rhiD->dev->CreatePixelShader(bytecode.constData(), bytecode.size(), nullptr, &fs);
- if (FAILED(hr)) {
- qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(shaderStage.shader(), shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL shader compilation failed: %s", qPrintable(error));
return false;
}
- break;
- default:
- break;
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ rhiD->clearShaderCache();
+ }
+
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ hr = rhiD->dev->CreateVertexShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &vs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create vertex shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ vsByteCode = bytecode;
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(vs, bytecode));
+ vs->AddRef();
+ break;
+ case QRhiShaderStage::Fragment:
+ hr = rhiD->dev->CreatePixelShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &fs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create pixel shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ rhiD->m_shaderCache.insert(shaderStage, QRhiD3D11::Shader(fs, bytecode));
+ fs->AddRef();
+ break;
+ default:
+ break;
+ }
}
}
@@ -3447,20 +3550,21 @@ bool QD3D11GraphicsPipeline::build()
memset(&desc, 0, sizeof(desc));
// the output from SPIRV-Cross uses TEXCOORD<location> as the semantic
desc.SemanticName = "TEXCOORD";
- desc.SemanticIndex = attribute.location();
+ desc.SemanticIndex = UINT(attribute.location());
desc.Format = toD3DAttributeFormat(attribute.format());
- desc.InputSlot = attribute.binding();
+ desc.InputSlot = UINT(attribute.binding());
desc.AlignedByteOffset = attribute.offset();
const QRhiVertexInputBinding &binding(bindings[attribute.binding()]);
if (binding.classification() == QRhiVertexInputBinding::PerInstance) {
desc.InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
- desc.InstanceDataStepRate = binding.instanceStepRate();
+ desc.InstanceDataStepRate = UINT(binding.instanceStepRate());
} else {
desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
}
inputDescs.append(desc);
}
- hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), inputDescs.count(), vsByteCode, vsByteCode.size(), &inputLayout);
+ hr = rhiD->dev->CreateInputLayout(inputDescs.constData(), UINT(inputDescs.count()),
+ vsByteCode, SIZE_T(vsByteCode.size()), &inputLayout);
if (FAILED(hr)) {
qWarning("Failed to create input layout: %s", qPrintable(comErrorMessage(hr)));
return false;
@@ -3502,19 +3606,31 @@ bool QD3D11ComputePipeline::build()
QRHI_RES_RHI(QRhiD3D11);
- QString error;
- QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
- if (bytecode.isEmpty()) {
- qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
- return false;
- }
+ auto cacheIt = rhiD->m_shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->m_shaderCache.constEnd()) {
+ cs = static_cast<ID3D11ComputeShader *>(cacheIt->s);
+ } else {
+ QString error;
+ const QByteArray bytecode = compileHlslShaderSource(m_shaderStage.shader(), m_shaderStage.shaderVariant(), &error);
+ if (bytecode.isEmpty()) {
+ qWarning("HLSL compute shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
- HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), bytecode.size(), nullptr, &cs);
- if (FAILED(hr)) {
- qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ HRESULT hr = rhiD->dev->CreateComputeShader(bytecode.constData(), SIZE_T(bytecode.size()), nullptr, &cs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+
+ if (rhiD->m_shaderCache.count() >= QRhiD3D11::MAX_SHADER_CACHE_ENTRIES)
+ rhiD->clearShaderCache();
+
+ rhiD->m_shaderCache.insert(m_shaderStage, QRhiD3D11::Shader(cs, bytecode));
}
+ cs->AddRef();
+
generation += 1;
rhiD->registerResource(this);
return true;
@@ -3637,8 +3753,8 @@ bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI
{
D3D11_TEXTURE2D_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = size.width();
- desc.Height = size.height();
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = format;
@@ -3694,11 +3810,23 @@ bool QD3D11SwapChain::buildOrResize()
const UINT swapChainFlags = 0;
QRHI_RES_RHI(QRhiD3D11);
- const bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
+ bool useFlipDiscard = rhiD->hasDxgi2 && rhiD->supportsFlipDiscardSwapchain;
if (!swapChain) {
HWND hwnd = reinterpret_cast<HWND>(window->winId());
sampleDesc = rhiD->effectiveSampleCount(m_sampleCount);
+ // Take a shortcut for alpha: our QWindow is OpenGLSurface so whatever
+ // the platform plugin does to enable transparency for OpenGL window
+ // will be sufficient for us too on the legacy (DISCARD) path. For
+ // FLIP_DISCARD we'd need to use DirectComposition (create a
+ // IDCompositionDevice/Target/Visual), avoid that for now.
+ if (m_flags.testFlag(SurfaceHasPreMulAlpha) || m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
+ useFlipDiscard = false;
+ if (window->requestedFormat().alphaBufferSize() <= 0)
+ qWarning("Swapchain says surface has alpha but the window has no alphaBufferSize set. "
+ "This may lead to problems.");
+ }
+
HRESULT hr;
if (useFlipDiscard) {
// We use FLIP_DISCARD which implies a buffer count of 2 (as opposed to the
@@ -3709,18 +3837,17 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC1 desc;
memset(&desc, 0, sizeof(desc));
- desc.Width = pixelSize.width();
- desc.Height = pixelSize.height();
+ desc.Width = UINT(pixelSize.width());
+ desc.Height = UINT(pixelSize.height());
desc.Format = colorFormat;
desc.SampleDesc.Count = 1;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = BUFFER_COUNT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
- if (m_flags.testFlag(SurfaceHasPreMulAlpha))
- desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
- else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha))
- desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
+ // Do not bother with AlphaMode, if won't work unless we go through
+ // DirectComposition. Instead, we just take the other (DISCARD)
+ // path for now when alpha is requested.
desc.Flags = swapChainFlags;
IDXGISwapChain1 *sc1;
@@ -3735,8 +3862,8 @@ bool QD3D11SwapChain::buildOrResize()
DXGI_SWAP_CHAIN_DESC desc;
memset(&desc, 0, sizeof(desc));
- desc.BufferDesc.Width = pixelSize.width();
- desc.BufferDesc.Height = pixelSize.height();
+ desc.BufferDesc.Width = UINT(pixelSize.width());
+ desc.BufferDesc.Height = UINT(pixelSize.height());
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferDesc.Format = colorFormat;
@@ -3758,9 +3885,13 @@ bool QD3D11SwapChain::buildOrResize()
} else {
releaseBuffers();
const UINT count = useFlipDiscard ? BUFFER_COUNT : 1;
- HRESULT hr = swapChain->ResizeBuffers(count, pixelSize.width(), pixelSize.height(),
+ HRESULT hr = swapChain->ResizeBuffers(count, UINT(pixelSize.width()), UINT(pixelSize.height()),
colorFormat, swapChainFlags);
- if (FAILED(hr)) {
+ if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) {
+ qWarning("Device loss detected in ResizeBuffers()");
+ rhiD->deviceLost = true;
+ return false;
+ } else if (FAILED(hr)) {
qWarning("Failed to resize D3D11 swapchain: %s", qPrintable(comErrorMessage(hr)));
return false;
}
@@ -3821,13 +3952,13 @@ bool QD3D11SwapChain::buildOrResize()
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
rtD->d.rp = QRHI_RES(QD3D11RenderPassDescriptor, m_renderPassDesc);
rtD->d.pixelSize = pixelSize;
- rtD->d.dpr = window->devicePixelRatio();
- rtD->d.sampleCount = sampleDesc.Count;
+ rtD->d.dpr = float(window->devicePixelRatio());
+ rtD->d.sampleCount = int(sampleDesc.Count);
rtD->d.colorAttCount = 1;
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
QRHI_PROF;
- QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, sampleDesc.Count));
+ QRHI_PROF_F(resizeSwapChain(this, BUFFER_COUNT, sampleDesc.Count > 1 ? BUFFER_COUNT : 0, int(sampleDesc.Count)));
if (rhiP) {
D3D11_QUERY_DESC queryDesc;
memset(&queryDesc, 0, sizeof(queryDesc));
@@ -3861,4 +3992,34 @@ bool QD3D11SwapChain::buildOrResize()
return true;
}
+void QRhiD3D11::DeviceCurse::initResources()
+{
+ framesLeft = framesToActivate;
+
+ HRESULT hr = q->dev->CreateComputeShader(g_killDeviceByTimingOut, sizeof(g_killDeviceByTimingOut), nullptr, &cs);
+ if (FAILED(hr)) {
+ qWarning("Failed to create compute shader: %s", qPrintable(comErrorMessage(hr)));
+ return;
+ }
+}
+
+void QRhiD3D11::DeviceCurse::releaseResources()
+{
+ if (cs) {
+ cs->Release();
+ cs = nullptr;
+ }
+}
+
+void QRhiD3D11::DeviceCurse::activate()
+{
+ if (!cs)
+ return;
+
+ qDebug("Activating Curse. Goodbye Cruel World.");
+
+ q->context->CSSetShader(cs, nullptr, 0);
+ q->context->Dispatch(256, 1, 1);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/rhi/qrhid3d11_p.h b/src/gui/rhi/qrhid3d11_p.h
index 3e2e492d9c..5df1843b1e 100644
--- a/src/gui/rhi/qrhid3d11_p.h
+++ b/src/gui/rhi/qrhid3d11_p.h
@@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
struct Q_GUI_EXPORT QRhiD3D11InitParams : public QRhiInitParams
{
bool enableDebugLayer = false;
+
+ int framesUntilKillingDeviceViaTdr = -1;
+ bool repeatDeviceKill = false;
};
struct Q_GUI_EXPORT QRhiD3D11NativeHandles : public QRhiNativeHandles
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 582146315d..cf4808510c 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -631,7 +631,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
void enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc);
@@ -646,6 +648,7 @@ public:
DXGI_SAMPLE_DESC effectiveSampleCount(int sampleCount) const;
void finishActiveReadbacks();
void reportLiveObjects(ID3D11Device *device);
+ void clearShaderCache();
bool debugLayer = false;
bool importedDevice = false;
@@ -656,6 +659,7 @@ public:
IDXGIFactory1 *dxgiFactory = nullptr;
bool hasDxgi2 = false;
bool supportsFlipDiscardSwapchain = false;
+ bool deviceLost = false;
QRhiD3D11NativeHandles nativeHandlesStruct;
struct {
@@ -684,6 +688,27 @@ public:
QRhiTexture::Format format;
};
QVector<ActiveReadback> activeReadbacks;
+
+ struct Shader {
+ Shader() = default;
+ Shader(IUnknown *s, const QByteArray &bytecode) : s(s), bytecode(bytecode) { }
+ IUnknown *s;
+ QByteArray bytecode;
+ };
+ QHash<QRhiShaderStage, Shader> m_shaderCache;
+
+ struct DeviceCurse {
+ DeviceCurse(QRhiD3D11 *impl) : q(impl) { }
+ QRhiD3D11 *q;
+ int framesToActivate = -1;
+ bool permanent = false;
+ int framesLeft = 0;
+ ID3D11ComputeShader *cs = nullptr;
+
+ void initResources();
+ void releaseResources();
+ void activate();
+ } deviceCurse;
};
Q_DECLARE_TYPEINFO(QRhiD3D11::ActiveReadback, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index f4e711e33e..2d51d892e3 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -371,7 +371,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
return true;
if (!ctx->makeCurrent(surface)) {
- qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ if (ctx->isValid()) {
+ qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ } else {
+ qWarning("QRhiGles2: Context is lost.");
+ contextLost = true;
+ }
return false;
}
@@ -491,6 +496,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
nativeHandlesStruct.context = ctx;
+ contextLost = false;
+
return true;
}
@@ -502,6 +509,10 @@ void QRhiGles2::destroy()
ensureContext();
executeDeferredReleases();
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+ m_shaderCache.clear();
+
if (!importedContext) {
delete ctx;
ctx = nullptr;
@@ -650,7 +661,7 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh
bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const
{
if (isCompressedFormat(format))
- return supportedCompressedFormats.contains(toGlCompressedTextureFormat(format, flags));
+ return supportedCompressedFormats.contains(GLint(toGlCompressedTextureFormat(format, flags)));
switch (format) {
case QRhiTexture::D16:
@@ -749,12 +760,28 @@ void QRhiGles2::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiGles2::makeThreadLocalNativeContextCurrent()
+bool QRhiGles2::makeThreadLocalNativeContextCurrent()
{
if (inFrame && !ofr.active)
- ensureContext(currentSwapChain->surface);
+ return ensureContext(currentSwapChain->surface);
else
- ensureContext();
+ return ensureContext();
+}
+
+void QRhiGles2::releaseCachedResources()
+{
+ if (!ensureContext())
+ return;
+
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader);
+
+ m_shaderCache.clear();
+}
+
+bool QRhiGles2::isDeviceLost() const
+{
+ return contextLost;
}
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -915,7 +942,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
- *p++ = dynOfs.first;
+ *p++ = uint(dynOfs.first);
*p++ = dynOfs.second;
}
} else {
@@ -1008,10 +1035,10 @@ void QRhiGles2::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::BlendConstants;
- cmd.args.blendConstants.r = c.redF();
- cmd.args.blendConstants.g = c.greenF();
- cmd.args.blendConstants.b = c.blueF();
- cmd.args.blendConstants.a = c.alphaF();
+ cmd.args.blendConstants.r = float(c.redF());
+ cmd.args.blendConstants.g = float(c.greenF());
+ cmd.args.blendConstants.b = float(c.blueF());
+ cmd.args.blendConstants.a = float(c.alphaF());
cbD->commands.append(cmd);
}
@@ -1141,7 +1168,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
currentSwapChain = swapChainD;
@@ -1164,7 +1191,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&swapChainD->cb);
@@ -1188,7 +1215,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
{
Q_UNUSED(flags);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
ofr.active = true;
@@ -1210,7 +1237,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
@@ -1224,14 +1251,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
Q_ASSERT(!currentSwapChain);
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
ofr.cbWrapper.resetCommands();
} else {
Q_ASSERT(currentSwapChain);
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext(currentSwapChain->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&currentSwapChain->cb);
currentSwapChain->cb.resetCommands();
}
@@ -1299,7 +1326,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
}
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
- cmd.args.subImage.faceTarget = faceTargetBase + layer;
+ cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y();
@@ -1318,7 +1345,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage;
cmd.args.compressedSubImage.target = texD->target;
cmd.args.compressedSubImage.texture = texD->texture;
- cmd.args.compressedSubImage.faceTarget = faceTargetBase + layer;
+ cmd.args.compressedSubImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedSubImage.level = level;
cmd.args.compressedSubImage.dx = dp.x();
cmd.args.compressedSubImage.dy = dp.y();
@@ -1333,7 +1360,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::CompressedImage;
cmd.args.compressedImage.target = texD->target;
cmd.args.compressedImage.texture = texD->texture;
- cmd.args.compressedImage.faceTarget = faceTargetBase + layer;
+ cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.compressedImage.level = level;
cmd.args.compressedImage.glintformat = texD->glintformat;
cmd.args.compressedImage.w = size.width();
@@ -1351,7 +1378,7 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
- cmd.args.subImage.faceTarget = faceTargetBase + layer;
+ cmd.args.subImage.faceTarget = faceTargetBase + uint(layer);
cmd.args.subImage.level = level;
cmd.args.subImage.dx = dp.x();
cmd.args.subImage.dy = dp.y();
@@ -1379,7 +1406,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
- memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
+ memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
} else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
QGles2CommandBuffer::Command cmd;
@@ -1398,7 +1425,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
Q_ASSERT(bufD->m_type != QRhiBuffer::Dynamic);
Q_ASSERT(u.offset + u.data.size() <= bufD->m_size);
if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) {
- memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size());
+ memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), size_t(u.data.size()));
} else {
trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate);
QGles2CommandBuffer::Command cmd;
@@ -1443,7 +1470,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::CopyTex;
- cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + u.copy.desc.sourceLayer();
+ cmd.args.copyTex.srcFaceTarget = srcFaceTargetBase + uint(u.copy.desc.sourceLayer());
cmd.args.copyTex.srcTexture = srcD->texture;
cmd.args.copyTex.srcLevel = u.copy.desc.sourceLevel();
cmd.args.copyTex.srcX = sp.x();
@@ -1451,7 +1478,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copyTex.dstTarget = dstD->target;
cmd.args.copyTex.dstTexture = dstD->texture;
- cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + u.copy.desc.destinationLayer();
+ cmd.args.copyTex.dstFaceTarget = dstFaceTargetBase + uint(u.copy.desc.destinationLayer());
cmd.args.copyTex.dstLevel = u.copy.desc.destinationLevel();
cmd.args.copyTex.dstX = dp.x();
cmd.args.copyTex.dstY = dp.y();
@@ -1465,7 +1492,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
cmd.args.readPixels.result = u.read.result;
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture());
- trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
+ if (texD)
+ trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead);
cmd.args.readPixels.texture = texD ? texD->texture : 0;
if (texD) {
cmd.args.readPixels.w = texD->m_pixelSize.width();
@@ -1473,7 +1501,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.readPixels.format = texD->m_format;
const GLenum faceTargetBase = texD->m_flags.testFlag(QRhiTexture::CubeMap)
? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
- cmd.args.readPixels.readTarget = faceTargetBase + u.read.rb.layer();
+ cmd.args.readPixels.readTarget = faceTargetBase + uint(u.read.rb.layer());
cmd.args.readPixels.level = u.read.rb.level();
}
cbD->commands.append(cmd);
@@ -1833,7 +1861,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glBindVertexArray(0);
break;
case QGles2CommandBuffer::Command::Viewport:
- f->glViewport(cmd.args.viewport.x, cmd.args.viewport.y, cmd.args.viewport.w, cmd.args.viewport.h);
+ f->glViewport(GLint(cmd.args.viewport.x), GLint(cmd.args.viewport.y), GLsizei(cmd.args.viewport.w), GLsizei(cmd.args.viewport.h));
f->glDepthRangef(cmd.args.viewport.d0, cmd.args.viewport.d1);
break;
case QGles2CommandBuffer::Command::Scissor:
@@ -1846,8 +1874,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
{
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.stencilRef.ps);
if (psD) {
- f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
- f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), cmd.args.stencilRef.ref, psD->m_stencilReadMask);
+ f->glStencilFuncSeparate(GL_FRONT, toGlCompareOp(psD->m_stencilFront.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
+ f->glStencilFuncSeparate(GL_BACK, toGlCompareOp(psD->m_stencilBack.compareOp), GLint(cmd.args.stencilRef.ref), psD->m_stencilReadMask);
} else {
qWarning("No graphics pipeline active for setStencilRef; ignored");
}
@@ -1867,7 +1895,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
// we do not support more than one vertex buffer
f->glBindBuffer(GL_ARRAY_BUFFER, cmd.args.bindVertexBuffer.buffer);
- const int stride = bindings[bindingIdx].stride();
+ const int stride = int(bindings[bindingIdx].stride());
int size = 1;
GLenum type = GL_FLOAT;
bool normalize = false;
@@ -1909,13 +1937,13 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
const int locationIdx = a.location();
quint32 ofs = a.offset() + cmd.args.bindVertexBuffer.offset;
- f->glVertexAttribPointer(locationIdx, size, type, normalize, stride,
+ f->glVertexAttribPointer(GLuint(locationIdx), size, type, normalize, stride,
reinterpret_cast<const GLvoid *>(quintptr(ofs)));
- f->glEnableVertexAttribArray(locationIdx);
+ f->glEnableVertexAttribArray(GLuint(locationIdx));
if (bindings[bindingIdx].classification() == QRhiVertexInputBinding::PerInstance
&& caps.instancing)
{
- f->glVertexAttribDivisor(locationIdx, bindings[bindingIdx].instanceStepRate());
+ f->glVertexAttribDivisor(GLuint(locationIdx), GLuint(bindings[bindingIdx].instanceStepRate()));
}
}
} else {
@@ -1934,10 +1962,10 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, cmd.args.draw.ps);
if (psD) {
if (cmd.args.draw.instanceCount == 1 || !caps.instancing) {
- f->glDrawArrays(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount);
+ f->glDrawArrays(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount));
} else {
- f->glDrawArraysInstanced(psD->drawMode, cmd.args.draw.firstVertex, cmd.args.draw.vertexCount,
- cmd.args.draw.instanceCount);
+ f->glDrawArraysInstanced(psD->drawMode, GLint(cmd.args.draw.firstVertex), GLsizei(cmd.args.draw.vertexCount),
+ GLsizei(cmd.args.draw.instanceCount));
}
} else {
qWarning("No graphics pipeline active for draw; ignored");
@@ -1953,30 +1981,30 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
if (cmd.args.drawIndexed.instanceCount == 1 || !caps.instancing) {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsBaseVertex(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
cmd.args.drawIndexed.baseVertex);
} else {
f->glDrawElements(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs);
}
} else {
if (cmd.args.drawIndexed.baseVertex != 0 && caps.baseVertex) {
f->glDrawElementsInstancedBaseVertex(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
- cmd.args.drawIndexed.instanceCount,
+ GLsizei(cmd.args.drawIndexed.instanceCount),
cmd.args.drawIndexed.baseVertex);
} else {
f->glDrawElementsInstanced(psD->drawMode,
- cmd.args.drawIndexed.indexCount,
+ GLsizei(cmd.args.drawIndexed.indexCount),
indexType,
ofs,
- cmd.args.drawIndexed.instanceCount);
+ GLsizei(cmd.args.drawIndexed.instanceCount));
}
}
} else {
@@ -2001,7 +2029,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount;
QVarLengthArray<GLenum, 8> bufs;
for (int i = 0; i < colorAttCount; ++i)
- bufs.append(GL_COLOR_ATTACHMENT0 + i);
+ bufs.append(GL_COLOR_ATTACHMENT0 + uint(i));
f->glDrawBuffers(colorAttCount, bufs.constData());
}
} else {
@@ -2029,7 +2057,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
f->glClearDepthf(cmd.args.clear.d);
}
if (cmd.args.clear.mask & GL_STENCIL_BUFFER_BIT)
- f->glClearStencil(cmd.args.clear.s);
+ f->glClearStencil(GLint(cmd.args.clear.s));
f->glClear(cmd.args.clear.mask);
break;
case QGles2CommandBuffer::Command::BufferSubData:
@@ -2273,7 +2301,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
if (dynOfsCount) {
for (int j = 0; j < dynOfsCount; ++j) {
if (dynOfsPairs[2 * j] == uint(b->binding)) {
- viewOffset = dynOfsPairs[2 * j + 1];
+ viewOffset = int(dynOfsPairs[2 * j + 1]);
break;
}
}
@@ -2364,20 +2392,20 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
for (QGles2SamplerDescription &sampler : samplers) {
if (sampler.binding == b->binding) {
- f->glActiveTexture(GL_TEXTURE0 + texUnit);
+ f->glActiveTexture(GL_TEXTURE0 + uint(texUnit));
f->glBindTexture(texD->target, texD->texture);
if (texD->samplerState != samplerD->d) {
- f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, samplerD->d.glminfilter);
- f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, samplerD->d.glmagfilter);
- f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, samplerD->d.glwraps);
- f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, samplerD->d.glwrapt);
+ f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER, GLint(samplerD->d.glminfilter));
+ f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER, GLint(samplerD->d.glmagfilter));
+ f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S, GLint(samplerD->d.glwraps));
+ f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T, GLint(samplerD->d.glwrapt));
// 3D textures not supported by GLES 2.0 or by us atm...
//f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_R, samplerD->d.glwrapr);
if (caps.textureCompareMode) {
if (samplerD->d.gltexcomparefunc != GL_NEVER) {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, samplerD->d.gltexcomparefunc);
+ f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_FUNC, GLint(samplerD->d.gltexcomparefunc));
} else {
f->glTexParameteri(texD->target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
@@ -2404,7 +2432,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
access = GL_READ_ONLY;
else if (b->type == QRhiShaderResourceBinding::ImageStore)
access = GL_WRITE_ONLY;
- f->glBindImageTexture(b->binding, texD->texture,
+ f->glBindImageTexture(GLuint(b->binding), texD->texture,
b->u.simage.level, layered, 0,
access, texD->glsizedintformat);
}
@@ -2417,9 +2445,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
{
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0)
- f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer);
+ f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer);
else
- f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer,
+ f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, GLuint(b->binding), bufD->buffer,
b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size);
}
break;
@@ -2541,10 +2569,10 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb,
clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
if (rtD->dsAttCount && wantsDsClear)
clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- clearCmd.args.clear.c[0] = colorClearValue.redF();
- clearCmd.args.clear.c[1] = colorClearValue.greenF();
- clearCmd.args.clear.c[2] = colorClearValue.blueF();
- clearCmd.args.clear.c[3] = colorClearValue.alphaF();
+ clearCmd.args.clear.c[0] = float(colorClearValue.redF());
+ clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
+ clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
+ clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
cbD->commands.append(clearCmd);
@@ -2582,7 +2610,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
QGles2Texture *colorTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture());
const GLenum faceTargetBase = colorTexD->m_flags.testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X
: colorTexD->target;
- cmd.args.blitFromRb.target = faceTargetBase + colorAtt.resolveLayer();
+ cmd.args.blitFromRb.target = faceTargetBase + uint(colorAtt.resolveLayer());
cmd.args.blitFromRb.texture = colorTexD->texture;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel();
cbD->commands.append(cmd);
@@ -2649,9 +2677,9 @@ void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Dispatch;
- cmd.args.dispatch.x = x;
- cmd.args.dispatch.y = y;
- cmd.args.dispatch.z = z;
+ cmd.args.dispatch.x = GLuint(x);
+ cmd.args.dispatch.y = GLuint(y);
+ cmd.args.dispatch.z = GLuint(z);
cbD->commands.append(cmd);
}
@@ -2673,7 +2701,6 @@ static inline GLenum toGlShaderType(QRhiShaderStage::Type type)
bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage,
QShaderDescription *desc, int *glslVersionUsed)
{
- GLuint shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
const QShader bakedShader = shaderStage.shader();
QVector<int> versionsToTry;
QByteArray source;
@@ -2733,27 +2760,40 @@ bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage
return false;
}
- const char *srcStr = source.constData();
- const GLint srcLength = source.count();
- f->glShaderSource(shader, 1, &srcStr, &srcLength);
- f->glCompileShader(shader);
- GLint compiled = 0;
- f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- GLint infoLogLength = 0;
- f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
- QByteArray log;
- if (infoLogLength > 1) {
- GLsizei length = 0;
- log.resize(infoLogLength);
- f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
+ GLuint shader;
+ auto cacheIt = m_shaderCache.constFind(shaderStage);
+ if (cacheIt != m_shaderCache.constEnd()) {
+ shader = *cacheIt;
+ } else {
+ shader = f->glCreateShader(toGlShaderType(shaderStage.type()));
+ const char *srcStr = source.constData();
+ const GLint srcLength = source.count();
+ f->glShaderSource(shader, 1, &srcStr, &srcLength);
+ f->glCompileShader(shader);
+ GLint compiled = 0;
+ f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLogLength = 0;
+ f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+ QByteArray log;
+ if (infoLogLength > 1) {
+ GLsizei length = 0;
+ log.resize(infoLogLength);
+ f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data());
+ }
+ qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
+ return false;
}
- qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData());
- return false;
+ if (m_shaderCache.count() >= MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (uint shader : m_shaderCache)
+ f->glDeleteShader(shader); // does not actually get released yet when attached to a not-yet-released program
+ m_shaderCache.clear();
+ }
+ m_shaderCache.insert(shaderStage, shader);
}
f->glAttachShader(program, shader);
- f->glDeleteShader(shader);
*desc = bakedShader.description();
return true;
@@ -2791,7 +2831,7 @@ void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::Uniform
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
if (uniform.glslLocation >= 0) {
uniform.binding = ub.binding;
- uniform.offset = blockMember.offset;
+ uniform.offset = uint(blockMember.offset);
uniform.size = blockMember.size;
dst->append(uniform);
}
@@ -2855,7 +2895,7 @@ bool QGles2Buffer::build()
return false;
}
ubuf.resize(nonZeroSize);
- QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 0, 1));
return true;
}
@@ -2874,7 +2914,7 @@ bool QGles2Buffer::build()
usageState.access = AccessNone;
- QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), 1, 0));
rhiD->registerResource(this);
return true;
}
@@ -3145,13 +3185,13 @@ bool QGles2Texture::build()
for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) {
for (int level = 0; level != mipLevelCount; ++level) {
const QSize mipSize = rhiD->q->sizeForMipLevel(level, size);
- rhiD->f->glTexImage2D(faceTargetBase + layer, level, glintformat,
+ rhiD->f->glTexImage2D(faceTargetBase + uint(layer), level, GLint(glintformat),
mipSize.width(), mipSize.height(), 0,
glformat, gltype, nullptr);
}
}
} else {
- rhiD->f->glTexImage2D(target, 0, glintformat, size.width(), size.height(),
+ rhiD->f->glTexImage2D(target, 0, GLint(glintformat), size.width(), size.height(),
0, glformat, gltype, nullptr);
}
} else {
@@ -3354,14 +3394,15 @@ bool QGles2TextureRenderTarget::build()
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified);
const GLenum faceTargetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
- rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, faceTargetBase + colorAtt.layer(), texD->texture, colorAtt.level());
+ rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), faceTargetBase + uint(colorAtt.layer()),
+ texD->texture, colorAtt.level());
if (i == 0) {
d.pixelSize = texD->pixelSize();
d.sampleCount = 1;
}
} else if (renderBuffer) {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
- rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, rbD->renderbuffer);
+ rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uint(i), GL_RENDERBUFFER, rbD->renderbuffer);
if (i == 0) {
d.pixelSize = rbD->pixelSize();
d.sampleCount = rbD->samples;
@@ -3511,7 +3552,7 @@ bool QGles2GraphicsPipeline::build()
for (auto inVar : vsDesc.inputVariables()) {
const QByteArray name = inVar.name.toUtf8();
- rhiD->f->glBindAttribLocation(program, inVar.location, name.constData());
+ rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), name.constData());
}
if (!rhiD->linkProgram(program))
@@ -3657,7 +3698,7 @@ bool QGles2SwapChain::buildOrResize()
rt.d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
rt.d.pixelSize = pixelSize;
- rt.d.dpr = m_window->devicePixelRatio();
+ rt.d.dpr = float(m_window->devicePixelRatio());
rt.d.sampleCount = qBound(1, m_sampleCount, 64);
rt.d.colorAttCount = 1;
rt.d.dsAttCount = m_depthStencil ? 1 : 0;
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 6da529be92..e7bcb626b6 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -664,7 +664,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
bool ensureContext(QSurface *surface = nullptr) const;
void executeDeferredReleases();
@@ -768,6 +770,7 @@ public:
QVector<GLint> supportedCompressedFormats;
mutable QVector<int> supportedSampleCountList;
QRhiGles2NativeHandles nativeHandlesStruct;
+ mutable bool contextLost = false;
struct DeferredReleaseEntry {
enum Type {
@@ -804,6 +807,8 @@ public:
bool active = false;
QGles2CommandBuffer cbWrapper;
} ofr;
+
+ QHash<QRhiShaderStage, uint> m_shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiGles2::DeferredReleaseEntry, Q_MOVABLE_TYPE);
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 07753c985c..0b1ab72c2c 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -138,6 +138,20 @@ QT_BEGIN_NAMESPACE
\l{QRhiCommandBuffer::endPass()}.
*/
+struct QMetalShader
+{
+ id<MTLLibrary> lib = nil;
+ id<MTLFunction> func = nil;
+ std::array<uint, 3> localSize;
+
+ void release() {
+ [lib release];
+ lib = nil;
+ [func release];
+ func = nil;
+ }
+};
+
struct QRhiMetalData
{
QRhiMetalData(QRhiImplementation *rhi) : ofr(rhi) { }
@@ -206,6 +220,8 @@ struct QRhiMetalData
API_AVAILABLE(macos(10.13), ios(11.0)) id<MTLCaptureScope> captureScope = nil;
static const int TEXBUF_ALIGN = 256; // probably not accurate
+
+ QHash<QRhiShaderStage, QMetalShader> shaderCache;
};
Q_DECLARE_TYPEINFO(QRhiMetalData::DeferredReleaseEntry, Q_MOVABLE_TYPE);
@@ -289,17 +305,14 @@ struct QMetalGraphicsPipelineData
MTLPrimitiveType primitiveType;
MTLWinding winding;
MTLCullMode cullMode;
- id<MTLLibrary> vsLib = nil;
- id<MTLFunction> vsFunc = nil;
- id<MTLLibrary> fsLib = nil;
- id<MTLFunction> fsFunc = nil;
+ QMetalShader vs;
+ QMetalShader fs;
};
struct QMetalComputePipelineData
{
id<MTLComputePipelineState> ps = nil;
- id<MTLLibrary> csLib = nil;
- id<MTLFunction> csFunc = nil;
+ QMetalShader cs;
MTLSize localSize;
};
@@ -339,7 +352,8 @@ QRhiMetal::~QRhiMetal()
delete d;
}
-static inline uint aligned(uint v, uint byteAlign)
+template <class Int>
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -404,6 +418,10 @@ void QRhiMetal::destroy()
executeDeferredReleases(true);
finishActiveReadbacks(true);
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+ d->shaderCache.clear();
+
if (@available(macOS 10.13, iOS 11.0, *)) {
[d->captureScope release];
d->captureScope = nil;
@@ -565,9 +583,23 @@ void QRhiMetal::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiMetal::makeThreadLocalNativeContextCurrent()
+bool QRhiMetal::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
+}
+
+void QRhiMetal::releaseCachedResources()
+{
+ for (QMetalShader &s : d->shaderCache)
+ s.release();
+
+ d->shaderCache.clear();
+}
+
+bool QRhiMetal::isDeviceLost() const
+{
+ return false;
}
QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -630,7 +662,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
{
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.ubuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[bufD->d->slotted ? currentFrameSlot : 0];
- uint offset = b->u.ubuf.offset;
+ uint offset = uint(b->u.ubuf.offset);
for (int i = 0; i < dynamicOffsetCount; ++i) {
const QRhiCommandBuffer::DynamicOffset &dynOfs(dynamicOffsets[i]);
if (dynOfs.first == b->binding) {
@@ -694,7 +726,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
{
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, b->u.sbuf.buf);
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
- uint offset = b->u.sbuf.offset;
+ uint offset = uint(b->u.sbuf.offset);
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
res[0].buffers.feed(b->binding, mtlbuf);
res[0].bufferOffsets.feed(b->binding, offset);
@@ -726,17 +758,17 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
case 0:
[cbD->d->currentRenderPassEncoder setVertexBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setBuffers: bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -755,15 +787,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) {
case 0:
[cbD->d->currentRenderPassEncoder setVertexTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setTextures: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -775,15 +807,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
switch (idx) {
case 0:
[cbD->d->currentRenderPassEncoder setVertexSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 1:
[cbD->d->currentRenderPassEncoder setFragmentSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
case 2:
[cbD->d->currentComputePassEncoder setSamplerStates: batch.resources.constData()
- withRange: NSMakeRange(batch.startBinding, batch.resources.count())];
+ withRange: NSMakeRange(batch.startBinding, NSUInteger(batch.resources.count()))];
break;
default:
Q_UNREACHABLE();
@@ -981,7 +1013,7 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
[cbD->d->currentRenderPassEncoder setVertexBuffers:
bufferBatch.resources.constData()
offsets: offsetBatch.resources.constData()
- withRange: NSMakeRange(firstVertexBinding + bufferBatch.startBinding, bufferBatch.resources.count())];
+ withRange: NSMakeRange(uint(firstVertexBinding) + bufferBatch.startBinding, NSUInteger(bufferBatch.resources.count()))];
}
}
@@ -997,11 +1029,44 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
}
}
+QSize safeOutputSize(QRhiMetal *rhiD, QMetalCommandBuffer *cbD)
+{
+ QSize size = cbD->currentTarget->pixelSize();
+
+ // So now we have the issue that the texture (drawable) size may have
+ // changed again since swapchain buildOrResize() was called. This can
+ // happen for example when interactively resizing the window a lot in one
+ // go, and command buffer building happens on a dedicated thread (f.ex.
+ // using the threaded render loop of Qt Quick).
+ //
+ // This is only an issue when running in debug mode with XCode because Metal
+ // validation will fail when setting viewport or scissor with the real size
+ // being smaller than what we think it is. So query the drawable size right
+ // here, in debug mode at least.
+ //
+ // In addition, we have to take the smaller of the two widths and heights
+ // to be safe, apparently. In some cases validation seems to think that the
+ // "render pass width" (or height) is the old(?) value.
+
+#ifdef QT_DEBUG
+ if (cbD->currentTarget->resourceType() == QRhiResource::RenderTarget) {
+ Q_ASSERT(rhiD->currentSwapChain);
+ const QSize otherSize = rhiD->currentSwapChain->surfacePixelSize();
+ size.setWidth(qMin(size.width(), otherSize.width()));
+ size.setHeight(qMin(size.height(), otherSize.height()));
+ }
+#else
+ Q_UNUSED(rhiD);
+#endif
+
+ return size;
+}
+
void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
{
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
- const QSize outputSize = cbD->currentTarget->pixelSize();
+ const QSize outputSize = safeOutputSize(this, cbD);
// x,y is top-left in MTLViewportRect but bottom-left in QRhiViewport
float x, y, w, h;
@@ -1009,21 +1074,21 @@ void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
return;
MTLViewport vp;
- vp.originX = x;
- vp.originY = y;
- vp.width = w;
- vp.height = h;
- vp.znear = viewport.minDepth();
- vp.zfar = viewport.maxDepth();
+ vp.originX = double(x);
+ vp.originY = double(y);
+ vp.width = double(w);
+ vp.height = double(h);
+ vp.znear = double(viewport.minDepth());
+ vp.zfar = double(viewport.maxDepth());
[cbD->d->currentRenderPassEncoder setViewport: vp];
if (!QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
MTLScissorRect s;
- s.x = x;
- s.y = y;
- s.width = w;
- s.height = h;
+ s.x = NSUInteger(x);
+ s.y = NSUInteger(y);
+ s.width = NSUInteger(w);
+ s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s];
}
}
@@ -1033,7 +1098,7 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
Q_ASSERT(QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor));
- const QSize outputSize = cbD->currentTarget->pixelSize();
+ const QSize outputSize = safeOutputSize(this, cbD);
// x,y is top-left in MTLScissorRect but bottom-left in QRhiScissor
int x, y, w, h;
@@ -1041,10 +1106,10 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
return;
MTLScissorRect s;
- s.x = x;
- s.y = y;
- s.width = w;
- s.height = h;
+ s.x = NSUInteger(x);
+ s.y = NSUInteger(y);
+ s.width = NSUInteger(w);
+ s.height = NSUInteger(h);
[cbD->d->currentRenderPassEncoder setScissorRect: s];
}
@@ -1054,7 +1119,8 @@ void QRhiMetal::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
- [cbD->d->currentRenderPassEncoder setBlendColorRed: c.redF() green: c.greenF() blue: c.blueF() alpha: c.alphaF()];
+ [cbD->d->currentRenderPassEncoder setBlendColorRed: float(c.redF())
+ green: float(c.greenF()) blue: float(c.blueF()) alpha: float(c.alphaF())];
}
void QRhiMetal::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue)
@@ -1086,7 +1152,7 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
return;
const quint32 indexOffset = cbD->currentIndexOffset + firstIndex * (cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? 2 : 4);
- Q_ASSERT(indexOffset == aligned(indexOffset, 4));
+ Q_ASSERT(indexOffset == aligned<quint32>(indexOffset, 4));
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
@@ -1344,7 +1410,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
MTLClearColor c = MTLClearColorMake(colorClearValue.redF(), colorClearValue.greenF(), colorClearValue.blueF(),
colorClearValue.alphaF());
- for (int i = 0; i < colorAttCount; ++i) {
+ for (uint i = 0; i < uint(colorAttCount); ++i) {
rp.colorAttachments[i].loadAction = MTLLoadActionClear;
rp.colorAttachments[i].storeAction = MTLStoreActionStore;
rp.colorAttachments[i].clearColor = c;
@@ -1355,7 +1421,7 @@ MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthSte
rp.depthAttachment.storeAction = MTLStoreActionDontCare;
rp.stencilAttachment.loadAction = MTLLoadActionClear;
rp.stencilAttachment.storeAction = MTLStoreActionDontCare;
- rp.depthAttachment.clearDepth = depthStencilClearValue.depthClearValue();
+ rp.depthAttachment.clearDepth = double(depthStencilClearValue.depthClearValue());
rp.stencilAttachment.clearStencil = depthStencilClearValue.stencilClearValue();
}
@@ -1368,7 +1434,7 @@ qsizetype QRhiMetal::subresUploadByteSize(const QRhiTextureSubresourceUploadDesc
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
subresDesc.data().size() : subresDesc.image().sizeInBytes();
if (imageSizeBytes > 0)
- size += aligned(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
+ size += aligned<qsizetype>(imageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
return size;
}
@@ -1396,31 +1462,31 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
h = subresDesc.sourceSize().height();
}
if (img.depth() == 32) {
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
srcOffset = sy * bpl + sx * 4;
// bpl remains set to the original image's row stride
} else {
img = img.copy(sx, sy, w, h);
bpl = img.bytesPerLine();
Q_ASSERT(img.sizeInBytes() <= fullImageSizeBytes);
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), img.sizeInBytes());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(img.sizeInBytes()));
}
} else {
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), fullImageSizeBytes);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, img.constBits(), size_t(fullImageSizeBytes));
}
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs + srcOffset
- sourceBytesPerRow: bpl
+ sourceOffset: NSUInteger(*curOfs + srcOffset)
+ sourceBytesPerRow: NSUInteger(bpl)
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone];
- *curOfs += aligned(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
+ *curOfs += aligned<qsizetype>(fullImageSizeBytes, QRhiMetalData::TEXBUF_ALIGN);
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
const QSize subresSize = q->sizeForMipLevel(level, texD->m_pixelSize);
const int subresw = subresSize.width();
@@ -1445,17 +1511,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
if (dy + h != subresh)
h = aligned(h, blockDim.height());
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs
+ sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dx, dy, 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dx), NSUInteger(dy), 0)
options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@@ -1474,17 +1540,17 @@ void QRhiMetal::enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEnc
quint32 bpl = 0;
textureFormatInfo(texD->m_format, QSize(w, h), &bpl, nullptr);
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), rawData.size());
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, rawData.constData(), size_t(rawData.size()));
[blitEnc copyFromBuffer: texD->d->stagingBuf[currentFrameSlot]
- sourceOffset: *curOfs
+ sourceOffset: NSUInteger(*curOfs)
sourceBytesPerRow: bpl
sourceBytesPerImage: 0
- sourceSize: MTLSizeMake(w, h, 1)
+ sourceSize: MTLSizeMake(NSUInteger(w), NSUInteger(h), 1)
toTexture: texD->d->tex
- destinationSlice: layer
- destinationLevel: level
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)
+ destinationSlice: NSUInteger(layer)
+ destinationLevel: NSUInteger(level)
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)
options: MTLBlitOptionNone];
*curOfs += aligned(rawData.size(), QRhiMetalData::TEXBUF_ALIGN);
@@ -1538,9 +1604,9 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
ensureBlit();
Q_ASSERT(!utexD->d->stagingBuf[currentFrameSlot]);
- utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: stagingSize
+ utexD->d->stagingBuf[currentFrameSlot] = [d->dev newBufferWithLength: NSUInteger(stagingSize)
options: MTLResourceStorageModeShared];
- QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
+ QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
void *mp = [utexD->d->stagingBuf[currentFrameSlot] contents];
qsizetype curOfs = 0;
@@ -1570,14 +1636,14 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
ensureBlit();
[blitEnc copyFromTexture: srcD->d->tex
- sourceSlice: u.copy.desc.sourceLayer()
- sourceLevel: u.copy.desc.sourceLevel()
- sourceOrigin: MTLOriginMake(sp.x(), sp.y(), 0)
- sourceSize: MTLSizeMake(size.width(), size.height(), 1)
+ sourceSlice: NSUInteger(u.copy.desc.sourceLayer())
+ sourceLevel: NSUInteger(u.copy.desc.sourceLevel())
+ sourceOrigin: MTLOriginMake(NSUInteger(sp.x()), NSUInteger(sp.y()), 0)
+ sourceSize: MTLSizeMake(NSUInteger(size.width()), NSUInteger(size.height()), 1)
toTexture: dstD->d->tex
- destinationSlice: u.copy.desc.destinationLayer()
- destinationLevel: u.copy.desc.destinationLevel()
- destinationOrigin: MTLOriginMake(dp.x(), dp.y(), 0)];
+ destinationSlice: NSUInteger(u.copy.desc.destinationLayer())
+ destinationLevel: NSUInteger(u.copy.desc.destinationLevel())
+ destinationOrigin: MTLOriginMake(NSUInteger(dp.x()), NSUInteger(dp.y()), 0)];
srcD->lastActiveFrameSlot = dstD->lastActiveFrameSlot = currentFrameSlot;
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Read) {
@@ -1617,16 +1683,16 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
textureFormatInfo(aRb.format, aRb.pixelSize, &bpl, &aRb.bufSize);
aRb.buf = [d->dev newBufferWithLength: aRb.bufSize options: MTLResourceStorageModeShared];
- QRHI_PROF_F(newReadbackBuffer(quint64(quintptr(aRb.buf)),
+ QRHI_PROF_F(newReadbackBuffer(qint64(qintptr(aRb.buf)),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
aRb.bufSize));
ensureBlit();
[blitEnc copyFromTexture: src
- sourceSlice: u.read.rb.layer()
- sourceLevel: u.read.rb.level()
+ sourceSlice: NSUInteger(u.read.rb.layer())
+ sourceLevel: NSUInteger(u.read.rb.level())
sourceOrigin: MTLOriginMake(0, 0, 0)
- sourceSize: MTLSizeMake(srcSize.width(), srcSize.height(), 1)
+ sourceSize: MTLSizeMake(NSUInteger(srcSize.width()), NSUInteger(srcSize.height()), 1)
toBuffer: aRb.buf
destinationOffset: 0
destinationBytesPerRow: bpl
@@ -1664,14 +1730,14 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
int changeEnd = -1;
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
- memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size());
+ memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin)
changeBegin = u.offset;
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
changeEnd = u.offset + u.data.size();
}
if (changeBegin >= 0 && bufD->d->managed)
- [bufD->d->buf[idx] didModifyRange: NSMakeRange(changeBegin, changeEnd - changeBegin)];
+ [bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
updates.clear();
}
@@ -1728,7 +1794,7 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
rtD = rtTex->d;
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
- for (int i = 0; i < rtD->colorAttCount; ++i)
+ for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
}
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
@@ -1755,15 +1821,15 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
break;
}
- for (int i = 0; i < rtD->colorAttCount; ++i) {
+ for (uint i = 0; i < uint(rtD->colorAttCount); ++i) {
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
- cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer;
- cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
+ cbD->d->currentPassRpDesc.colorAttachments[i].slice = NSUInteger(rtD->fb.colorAtt[i].layer);
+ cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
if (rtD->fb.colorAtt[i].resolveTex) {
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
- cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = rtD->fb.colorAtt[i].resolveLayer;
- cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = rtD->fb.colorAtt[i].resolveLevel;
+ cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
+ cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
}
}
@@ -1845,7 +1911,7 @@ void QRhiMetal::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::ComputePass);
QMetalComputePipeline *psD = QRHI_RES(QMetalComputePipeline, cbD->currentComputePipeline);
- [cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(x, y, z)
+ [cbD->d->currentComputePassEncoder dispatchThreadgroups: MTLSizeMake(NSUInteger(x), NSUInteger(y), NSUInteger(z))
threadsPerThreadgroup: psD->d->localSize];
}
@@ -1913,12 +1979,12 @@ void QRhiMetal::finishActiveReadbacks(bool forced)
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
aRb.result->format = aRb.format;
aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
+ aRb.result->data.resize(int(aRb.bufSize));
void *p = [aRb.buf contents];
memcpy(aRb.result->data.data(), p, aRb.bufSize);
[aRb.buf release];
- QRHI_PROF_F(releaseReadbackBuffer(quint64(quintptr(aRb.buf))));
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(qintptr(aRb.buf))));
if (aRb.result->completed)
completedCallbacks.append(aRb.result->completed);
@@ -1977,8 +2043,8 @@ bool QMetalBuffer::build()
return false;
}
- const int nonZeroSize = m_size <= 0 ? 256 : m_size;
- const int roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned(nonZeroSize, 256) : nonZeroSize;
+ const uint nonZeroSize = m_size <= 0 ? 256 : uint(m_size);
+ const uint roundedSize = m_usage.testFlag(QRhiBuffer::UniformBuffer) ? aligned<uint>(nonZeroSize, 256) : nonZeroSize;
d->managed = false;
MTLResourceOptions opts = MTLResourceStorageModeShared;
@@ -2065,10 +2131,10 @@ bool QMetalRenderBuffer::build()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
- desc.width = m_pixelSize.width();
- desc.height = m_pixelSize.height();
+ desc.width = NSUInteger(m_pixelSize.width());
+ desc.height = NSUInteger(m_pixelSize.height());
if (samples > 1)
- desc.sampleCount = samples;
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget;
@@ -2335,11 +2401,11 @@ bool QMetalTexture::build()
else
desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
desc.pixelFormat = d->format;
- desc.width = size.width();
- desc.height = size.height();
- desc.mipmapLevelCount = mipLevelCount;
+ desc.width = NSUInteger(size.width());
+ desc.height = NSUInteger(size.height());
+ desc.mipmapLevelCount = NSUInteger(mipLevelCount);
if (samples > 1)
- desc.sampleCount = samples;
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageShaderRead;
@@ -2405,7 +2471,7 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level)
const MTLTextureType type = [tex textureType];
const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap);
id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type
- levels: NSMakeRange(level, 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
+ levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : 1)];
perLevelViews[level] = view;
return view;
@@ -2615,13 +2681,13 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc
for (int i = 0, ie = colorAttachments.count(); i != ie; ++i) {
QMetalTexture *texD = QRHI_RES(QMetalTexture, colorAttachments[i].texture());
QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, colorAttachments[i].renderBuffer());
- rpD->colorFormat[i] = texD ? texD->d->format : rbD->d->format;
+ rpD->colorFormat[i] = int(texD ? texD->d->format : rbD->d->format);
}
if (m_desc.depthTexture())
- rpD->dsFormat = QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format;
+ rpD->dsFormat = int(QRHI_RES(QMetalTexture, m_desc.depthTexture())->d->format);
else if (m_desc.depthStencilBuffer())
- rpD->dsFormat = QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format;
+ rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format);
return rpD;
}
@@ -2810,36 +2876,17 @@ void QMetalGraphicsPipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (!d->ps)
- return;
-
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ d->vs.release();
+ d->fs.release();
- if (d->ds) {
- [d->ds release];
- d->ds = nil;
- }
+ [d->ds release];
+ d->ds = nil;
- if (d->vsFunc) {
- [d->vsFunc release];
- d->vsFunc = nil;
- }
- if (d->vsLib) {
- [d->vsLib release];
- d->vsLib = nil;
- }
+ if (!d->ps)
+ return;
- if (d->fsFunc) {
- [d->fsFunc release];
- d->fsFunc = nil;
- }
- if (d->fsLib) {
- [d->fsLib release];
- d->fsLib = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3040,7 +3087,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
if (!mtllib.shader().isEmpty()) {
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
- mtllib.shader().size(),
+ size_t(mtllib.shader().size()),
dispatch_get_global_queue(0, 0),
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
NSError *err = nil;
@@ -3100,19 +3147,19 @@ bool QMetalGraphicsPipeline::build()
MTLVertexDescriptor *inputLayout = [MTLVertexDescriptor vertexDescriptor];
const QVector<QRhiVertexInputAttribute> attributes = m_vertexInputLayout.attributes();
for (const QRhiVertexInputAttribute &attribute : attributes) {
- const int loc = attribute.location();
+ const uint loc = uint(attribute.location());
inputLayout.attributes[loc].format = toMetalAttributeFormat(attribute.format());
- inputLayout.attributes[loc].offset = attribute.offset();
- inputLayout.attributes[loc].bufferIndex = firstVertexBinding + attribute.binding();
+ inputLayout.attributes[loc].offset = NSUInteger(attribute.offset());
+ inputLayout.attributes[loc].bufferIndex = NSUInteger(firstVertexBinding + attribute.binding());
}
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
for (int i = 0, ie = bindings.count(); i != ie; ++i) {
const QRhiVertexInputBinding &binding(bindings[i]);
- const int layoutIdx = firstVertexBinding + i;
+ const uint layoutIdx = uint(firstVertexBinding + i);
inputLayout.layouts[layoutIdx].stepFunction =
binding.classification() == QRhiVertexInputBinding::PerInstance
? MTLVertexStepFunctionPerInstance : MTLVertexStepFunctionPerVertex;
- inputLayout.layouts[layoutIdx].stepRate = binding.instanceStepRate();
+ inputLayout.layouts[layoutIdx].stepRate = NSUInteger(binding.instanceStepRate());
inputLayout.layouts[layoutIdx].stride = binding.stride();
}
@@ -3126,34 +3173,66 @@ bool QMetalGraphicsPipeline::build()
// buffers not just the resource binding layout) so leave it at the default
for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) {
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
- }
- switch (shaderStage.type()) {
- case QRhiShaderStage::Vertex:
- rpDesc.vertexFunction = func;
- d->vsLib = lib;
- d->vsFunc = func;
- break;
- case QRhiShaderStage::Fragment:
- rpDesc.fragmentFunction = func;
- d->fsLib = lib;
- d->fsFunc = func;
- break;
- default:
- [func release];
- [lib release];
- break;
+ auto cacheIt = rhiD->d->shaderCache.constFind(shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs = *cacheIt;
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = d->vs.func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs = *cacheIt;
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = d->fs.func;
+ break;
+ default:
+ break;
+ }
+ } else {
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ // Use the simplest strategy: too many cached shaders -> drop them all.
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ switch (shaderStage.type()) {
+ case QRhiShaderStage::Vertex:
+ d->vs.lib = lib;
+ d->vs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->vs);
+ [d->vs.lib retain];
+ [d->vs.func retain];
+ rpDesc.vertexFunction = func;
+ break;
+ case QRhiShaderStage::Fragment:
+ d->fs.lib = lib;
+ d->fs.func = func;
+ rhiD->d->shaderCache.insert(shaderStage, d->fs);
+ [d->fs.lib retain];
+ [d->fs.func retain];
+ rpDesc.fragmentFunction = func;
+ break;
+ default:
+ [func release];
+ [lib release];
+ break;
+ }
}
}
@@ -3168,8 +3247,8 @@ bool QMetalGraphicsPipeline::build()
Q_ASSERT(m_targetBlends.count() == rpD->colorAttachmentCount
|| (m_targetBlends.isEmpty() && rpD->colorAttachmentCount == 1));
- for (int i = 0, ie = m_targetBlends.count(); i != ie; ++i) {
- const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[i]);
+ for (uint i = 0, ie = uint(m_targetBlends.count()); i != ie; ++i) {
+ const QRhiGraphicsPipeline::TargetBlend &b(m_targetBlends[int(i)]);
rpDesc.colorAttachments[i].pixelFormat = MTLPixelFormat(rpD->colorFormat[i]);
rpDesc.colorAttachments[i].blendingEnabled = b.enable;
rpDesc.colorAttachments[i].sourceRGBBlendFactor = toMetalBlendFactor(b.srcColor);
@@ -3191,7 +3270,7 @@ bool QMetalGraphicsPipeline::build()
rpDesc.stencilAttachmentPixelFormat = fmt;
}
- rpDesc.sampleCount = rhiD->effectiveSampleCount(m_sampleCount);
+ rpDesc.sampleCount = NSUInteger(rhiD->effectiveSampleCount(m_sampleCount));
NSError *err = nil;
d->ps = [rhiD->d->dev newRenderPipelineStateWithDescriptor: rpDesc error: &err];
@@ -3253,22 +3332,13 @@ void QMetalComputePipeline::release()
{
QRHI_RES_RHI(QRhiMetal);
- if (d->csFunc) {
- [d->csFunc release];
- d->csFunc = nil;
- }
- if (d->csLib) {
- [d->csLib release];
- d->csLib = nil;
- }
+ d->cs.release();
if (!d->ps)
return;
- if (d->ps) {
- [d->ps release];
- d->ps = nil;
- }
+ [d->ps release];
+ d->ps = nil;
rhiD->unregisterResource(this);
}
@@ -3280,28 +3350,44 @@ bool QMetalComputePipeline::build()
QRHI_RES_RHI(QRhiMetal);
- const QShader shader = m_shaderStage.shader();
- QString error;
- QByteArray entryPoint;
- id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
- &error, &entryPoint);
- if (!lib) {
- qWarning("MSL shader compilation failed: %s", qPrintable(error));
- return false;
- }
- id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
- if (!func) {
- qWarning("MSL function for entry point %s not found", entryPoint.constData());
- [lib release];
- return false;
+ auto cacheIt = rhiD->d->shaderCache.constFind(m_shaderStage);
+ if (cacheIt != rhiD->d->shaderCache.constEnd()) {
+ d->cs = *cacheIt;
+ } else {
+ const QShader shader = m_shaderStage.shader();
+ QString error;
+ QByteArray entryPoint;
+ id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
+ &error, &entryPoint);
+ if (!lib) {
+ qWarning("MSL shader compilation failed: %s", qPrintable(error));
+ return false;
+ }
+ id<MTLFunction> func = rhiD->d->createMSLShaderFunction(lib, entryPoint);
+ if (!func) {
+ qWarning("MSL function for entry point %s not found", entryPoint.constData());
+ [lib release];
+ return false;
+ }
+ d->cs.lib = lib;
+ d->cs.func = func;
+ d->cs.localSize = shader.description().computeShaderLocalSize();
+
+ if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
+ for (QMetalShader &s : rhiD->d->shaderCache)
+ s.release();
+ rhiD->d->shaderCache.clear();
+ }
+ rhiD->d->shaderCache.insert(m_shaderStage, d->cs);
}
- d->csLib = lib;
- d->csFunc = func;
- std::array<uint, 3> localSize = shader.description().computeShaderLocalSize();
- d->localSize = MTLSizeMake(localSize[0], localSize[1], localSize[2]);
+
+ [d->cs.lib retain];
+ [d->cs.func retain];
+
+ d->localSize = MTLSizeMake(d->cs.localSize[0], d->cs.localSize[1], d->cs.localSize[2]);
NSError *err = nil;
- d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->csFunc error: &err];
+ d->ps = [rhiD->d->dev newComputePipelineStateWithFunction: d->cs.func error: &err];
if (!d->ps) {
const QString msg = QString::fromNSString(err.localizedDescription);
qWarning("Failed to create render pipeline state: %s", qPrintable(msg));
@@ -3439,7 +3525,7 @@ QSize QMetalSwapChain::surfacePixelSize()
CAMetalLayer *layer = (CAMetalLayer *) [v layer];
if (layer) {
CGSize size = [layer drawableSize];
- return QSize(size.width, size.height);
+ return QSize(int(size.width), int(size.height));
}
}
return QSize();
@@ -3454,7 +3540,7 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
rpD->colorAttachmentCount = 1;
rpD->hasDepthStencil = m_depthStencil != nullptr;
- rpD->colorFormat[0] = d->colorFormat;
+ rpD->colorFormat[0] = int(d->colorFormat);
// m_depthStencil may not be built yet so cannot rely on computed fields in it
rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported
@@ -3511,6 +3597,18 @@ bool QMetalSwapChain::buildOrResize()
}
#endif
+ if (m_flags.testFlag(SurfaceHasPreMulAlpha)) {
+ d->layer.opaque = NO;
+ } else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha)) {
+ // The CoreAnimation compositor is said to expect premultiplied alpha,
+ // so this is then wrong when it comes to the blending operations but
+ // there's nothing we can do. Fortunately Qt Quick always outputs
+ // premultiplied alpha so it is not a problem there.
+ d->layer.opaque = NO;
+ } else {
+ d->layer.opaque = YES;
+ }
+
m_currentPixelSize = surfacePixelSize();
pixelSize = m_currentPixelSize;
@@ -3538,7 +3636,7 @@ bool QMetalSwapChain::buildOrResize()
}
rtWrapper.d->pixelSize = pixelSize;
- rtWrapper.d->dpr = window->devicePixelRatio();
+ rtWrapper.d->dpr = float(window->devicePixelRatio());
rtWrapper.d->sampleCount = samples;
rtWrapper.d->colorAttCount = 1;
rtWrapper.d->dsAttCount = ds ? 1 : 0;
@@ -3549,9 +3647,9 @@ bool QMetalSwapChain::buildOrResize()
MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init];
desc.textureType = MTLTextureType2DMultisample;
desc.pixelFormat = d->colorFormat;
- desc.width = pixelSize.width();
- desc.height = pixelSize.height();
- desc.sampleCount = samples;
+ desc.width = NSUInteger(pixelSize.width());
+ desc.height = NSUInteger(pixelSize.height());
+ desc.sampleCount = NSUInteger(samples);
desc.resourceOptions = MTLResourceStorageModePrivate;
desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget;
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index c448865f4d..a08f56072a 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -416,7 +416,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
void executeDeferredReleases(bool forced = false);
void finishActiveReadbacks(bool forced = false);
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index dff6e05268..60d620813b 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -169,11 +169,22 @@ void QRhiNull::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiNull::makeThreadLocalNativeContextCurrent()
+bool QRhiNull::makeThreadLocalNativeContextCurrent()
+{
+ // not applicable
+ return false;
+}
+
+void QRhiNull::releaseCachedResources()
{
// nothing to do here
}
+bool QRhiNull::isDeviceLost() const
+{
+ return false;
+}
+
QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index bdf0d59724..ee301d247b 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -282,7 +282,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
QRhiNullNativeHandles nativeHandlesStruct;
QRhiSwapChain *currentSwapChain = nullptr;
diff --git a/src/gui/rhi/qrhiprofiler.cpp b/src/gui/rhi/qrhiprofiler.cpp
index e74e446a1c..1521c0f36e 100644
--- a/src/gui/rhi/qrhiprofiler.cpp
+++ b/src/gui/rhi/qrhiprofiler.cpp
@@ -319,7 +319,7 @@ void QRhiProfilerPrivate::writeFloat(const char *key, float f)
Q_ASSERT(key[0] == 'F');
buf.append(key);
buf.append(',');
- buf.append(QByteArray::number(f));
+ buf.append(QByteArray::number(double(f)));
buf.append(',');
}
@@ -385,7 +385,7 @@ void QRhiProfilerPrivate::newRenderBuffer(QRhiRenderBuffer *rb, bool transientBa
const QRhiTexture::Format assumedFormat = type == QRhiRenderBuffer::DepthStencil ? QRhiTexture::D32F : QRhiTexture::RGBA8;
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(assumedFormat, sz, 1, 1);
if (sampleCount > 1)
- byteSize *= sampleCount;
+ byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewRenderBuffer, ts.elapsed(), rb);
writeInt("type", type);
@@ -416,7 +416,7 @@ void QRhiProfilerPrivate::newTexture(QRhiTexture *tex, bool owns, int mipCount,
const QSize sz = tex->pixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(format, sz, mipCount, layerCount);
if (sampleCount > 1)
- byteSize *= sampleCount;
+ byteSize *= uint(sampleCount);
startEntry(QRhiProfiler::NewTexture, ts.elapsed(), tex);
writeInt("width", sz.width());
@@ -467,7 +467,7 @@ void QRhiProfilerPrivate::resizeSwapChain(QRhiSwapChain *sc, int bufferCount, in
const QSize sz = sc->currentPixelSize();
quint32 byteSize = rhiDWhenEnabled->approxByteSizeForTexture(QRhiTexture::BGRA8, sz, 1, 1);
- byteSize = byteSize * bufferCount + byteSize * msaaBufferCount * sampleCount;
+ byteSize = byteSize * uint(bufferCount) + byteSize * uint(msaaBufferCount) * uint(sampleCount);
startEntry(QRhiProfiler::ResizeSwapChain, ts.elapsed(), sc);
writeInt("width", sz.width());
@@ -569,7 +569,7 @@ void QRhiProfilerPrivate::swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTime
}
}
-void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size)
+void QRhiProfilerPrivate::newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size)
{
if (!outputDevice)
return;
@@ -580,7 +580,7 @@ void QRhiProfilerPrivate::newReadbackBuffer(quint64 id, QRhiResource *src, quint
endEntry();
}
-void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
+void QRhiProfilerPrivate::releaseReadbackBuffer(qint64 id)
{
if (!outputDevice)
return;
@@ -590,7 +590,7 @@ void QRhiProfilerPrivate::releaseReadbackBuffer(quint64 id)
endEntry();
}
-void QRhiProfilerPrivate::vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize)
+void QRhiProfilerPrivate::vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize)
{
if (!outputDevice)
return;
diff --git a/src/gui/rhi/qrhiprofiler_p_p.h b/src/gui/rhi/qrhiprofiler_p_p.h
index 49c6bd78ed..7d0f183fb1 100644
--- a/src/gui/rhi/qrhiprofiler_p_p.h
+++ b/src/gui/rhi/qrhiprofiler_p_p.h
@@ -79,10 +79,10 @@ public:
void endSwapChainFrame(QRhiSwapChain *sc, int frameCount);
void swapChainFrameGpuTime(QRhiSwapChain *sc, float gpuTimeMs);
- void newReadbackBuffer(quint64 id, QRhiResource *src, quint32 size);
- void releaseReadbackBuffer(quint64 id);
+ void newReadbackBuffer(qint64 id, QRhiResource *src, quint32 size);
+ void releaseReadbackBuffer(qint64 id);
- void vmemStat(int realAllocCount, int subAllocCount, quint32 totalSize, quint32 unusedSize);
+ void vmemStat(uint realAllocCount, uint subAllocCount, quint32 totalSize, quint32 unusedSize);
void startEntry(QRhiProfiler::StreamOp op, qint64 timestamp, QRhiResource *res);
void writeInt(const char *key, qint64 v);
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index dfc85fb853..444c91dd75 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -211,7 +211,8 @@ QT_BEGIN_NAMESPACE
\brief Holds the Vulkan render pass object backing a QRhiRenderPassDescriptor.
*/
-static inline VkDeviceSize aligned(VkDeviceSize v, VkDeviceSize byteAlign)
+template <class Int>
+inline Int aligned(Int v, Int byteAlign)
{
return (v + byteAlign - 1) & ~(byteAlign - 1);
}
@@ -370,7 +371,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
auto queryQueueFamilyProps = [this, &queueFamilyProps] {
uint32_t queueCount = 0;
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
- queueFamilyProps.resize(queueCount);
+ queueFamilyProps.resize(int(queueCount));
f->vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueFamilyProps.data());
};
@@ -387,22 +388,42 @@ bool QRhiVulkan::create(QRhi::Flags flags)
qWarning("Failed to enumerate physical devices: %d", err);
return false;
}
+
int physDevIndex = -1;
int requestedPhysDevIndex = -1;
if (qEnvironmentVariableIsSet("QT_VK_PHYSICAL_DEVICE_INDEX"))
requestedPhysDevIndex = qEnvironmentVariableIntValue("QT_VK_PHYSICAL_DEVICE_INDEX");
- for (uint32_t i = 0; i < physDevCount; ++i) {
+
+ if (requestedPhysDevIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) {
+ for (int i = 0; i < int(physDevCount); ++i) {
+ f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties);
+ if (physDevProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+ requestedPhysDevIndex = i;
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < int(physDevCount); ++i) {
f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties);
- qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d", i,
+ qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d (api %d.%d.%d vendor 0x%X device 0x%X type %d)",
+ i,
physDevProperties.deviceName,
VK_VERSION_MAJOR(physDevProperties.driverVersion),
VK_VERSION_MINOR(physDevProperties.driverVersion),
- VK_VERSION_PATCH(physDevProperties.driverVersion));
+ VK_VERSION_PATCH(physDevProperties.driverVersion),
+ VK_VERSION_MAJOR(physDevProperties.apiVersion),
+ VK_VERSION_MINOR(physDevProperties.apiVersion),
+ VK_VERSION_PATCH(physDevProperties.apiVersion),
+ physDevProperties.vendorID,
+ physDevProperties.deviceID,
+ physDevProperties.deviceType);
if (physDevIndex < 0 && (requestedPhysDevIndex < 0 || requestedPhysDevIndex == int(i))) {
physDevIndex = i;
qCDebug(QRHI_LOG_INFO, " using this physical device");
}
}
+
if (physDevIndex < 0) {
qWarning("No matching physical device");
return false;
@@ -423,7 +444,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount);
if (gfxQueueFamilyIdx == -1
&& (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
- && (!maybeWindow || inst->supportsPresent(physDev, i, maybeWindow)))
+ && (!maybeWindow || inst->supportsPresent(physDev, uint32_t(i), maybeWindow)))
{
if (queueFamilyProps[i].queueFlags & VK_QUEUE_COMPUTE_BIT)
gfxQueueFamilyIdx = i;
@@ -444,7 +465,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
const float prio[] = { 0 };
memset(queueInfo, 0, sizeof(queueInfo));
queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queueInfo[0].queueFamilyIndex = gfxQueueFamilyIdx;
+ queueInfo[0].queueFamilyIndex = uint32_t(gfxQueueFamilyIdx);
queueInfo[0].queueCount = 1;
queueInfo[0].pQueuePriorities = prio;
@@ -480,9 +501,9 @@ bool QRhiVulkan::create(QRhi::Flags flags)
devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
devInfo.queueCreateInfoCount = 1;
devInfo.pQueueCreateInfos = queueInfo;
- devInfo.enabledLayerCount = devLayers.count();
+ devInfo.enabledLayerCount = uint32_t(devLayers.count());
devInfo.ppEnabledLayerNames = devLayers.constData();
- devInfo.enabledExtensionCount = requestedDevExts.count();
+ devInfo.enabledExtensionCount = uint32_t(requestedDevExts.count());
devInfo.ppEnabledExtensionNames = requestedDevExts.constData();
err = f->vkCreateDevice(physDev, &devInfo, nullptr, &dev);
@@ -498,7 +519,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
VkCommandPoolCreateInfo poolInfo;
memset(&poolInfo, 0, sizeof(poolInfo));
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- poolInfo.queueFamilyIndex = gfxQueueFamilyIdx;
+ poolInfo.queueFamilyIndex = uint32_t(gfxQueueFamilyIdx);
VkResult err = df->vkCreateCommandPool(dev, &poolInfo, nullptr, &cmdPool);
if (err != VK_SUCCESS) {
qWarning("Failed to create command pool: %d", err);
@@ -508,7 +529,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
if (gfxQueueFamilyIdx != -1) {
if (!gfxQueue)
- df->vkGetDeviceQueue(dev, gfxQueueFamilyIdx, 0, &gfxQueue);
+ df->vkGetDeviceQueue(dev, uint32_t(gfxQueueFamilyIdx), 0, &gfxQueue);
if (queueFamilyProps.isEmpty())
queryQueueFamilyProps();
@@ -588,6 +609,8 @@ bool QRhiVulkan::create(QRhi::Flags flags)
vkDebugMarkerSetObjectName = reinterpret_cast<PFN_vkDebugMarkerSetObjectNameEXT>(f->vkGetDeviceProcAddr(dev, "vkDebugMarkerSetObjectNameEXT"));
}
+ deviceLost = false;
+
nativeHandlesStruct.physDev = physDev;
nativeHandlesStruct.dev = dev;
nativeHandlesStruct.gfxQueueFamilyIdx = gfxQueueFamilyIdx;
@@ -603,7 +626,8 @@ void QRhiVulkan::destroy()
if (!df)
return;
- df->vkDeviceWaitIdle(dev);
+ if (!deviceLost)
+ df->vkDeviceWaitIdle(dev);
executeDeferredReleases(true);
finishActiveReadbacks(true);
@@ -691,7 +715,7 @@ bool QRhiVulkan::allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, V
df->vkResetDescriptorPool(dev, descriptorPools[i].pool, 0);
descriptorPools[i].allocedDescSets = 0;
}
- if (descriptorPools[i].allocedDescSets + allocInfo->descriptorSetCount <= QVK_DESC_SETS_PER_POOL) {
+ if (descriptorPools[i].allocedDescSets + int(allocInfo->descriptorSetCount) <= QVK_DESC_SETS_PER_POOL) {
VkResult err = tryAllocate(i);
if (err == VK_SUCCESS) {
descriptorPools[i].allocedDescSets += allocInfo->descriptorSetCount;
@@ -901,8 +925,8 @@ bool QRhiVulkan::createTransientImage(VkFormat format,
imgInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imgInfo.imageType = VK_IMAGE_TYPE_2D;
imgInfo.format = format;
- imgInfo.extent.width = pixelSize.width();
- imgInfo.extent.height = pixelSize.height();
+ imgInfo.extent.width = uint32_t(pixelSize.width());
+ imgInfo.extent.height = uint32_t(pixelSize.height());
imgInfo.extent.depth = 1;
imgInfo.mipLevels = imgInfo.arrayLayers = 1;
imgInfo.samples = samples;
@@ -925,7 +949,7 @@ bool QRhiVulkan::createTransientImage(VkFormat format,
VkMemoryAllocateInfo memInfo;
memset(&memInfo, 0, sizeof(memInfo));
memInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- memInfo.allocationSize = aligned(memReq.size, memReq.alignment) * count;
+ memInfo.allocationSize = aligned(memReq.size, memReq.alignment) * VkDeviceSize(count);
uint32_t startIndex = 0;
do {
@@ -1175,7 +1199,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
VkSubpassDescription subpassDesc;
memset(&subpassDesc, 0, sizeof(subpassDesc));
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpassDesc.colorAttachmentCount = colorRefs.count();
+ subpassDesc.colorAttachmentCount = uint32_t(colorRefs.count());
Q_ASSERT(colorRefs.count() == resolveRefs.count());
subpassDesc.pColorAttachments = !colorRefs.isEmpty() ? colorRefs.constData() : nullptr;
subpassDesc.pDepthStencilAttachment = hasDepthStencil ? &dsRef : nullptr;
@@ -1184,7 +1208,7 @@ bool QRhiVulkan::createOffscreenRenderPass(VkRenderPass *rp,
VkRenderPassCreateInfo rpInfo;
memset(&rpInfo, 0, sizeof(rpInfo));
rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- rpInfo.attachmentCount = attDescs.count();
+ rpInfo.attachmentCount = uint32_t(attDescs.count());
rpInfo.pAttachments = attDescs.constData();
rpInfo.subpassCount = 1;
rpInfo.pSubpasses = &subpassDesc;
@@ -1325,7 +1349,7 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
}
if (actualSwapChainBufferCount != reqBufferCount)
qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount);
- swapChainD->bufferCount = actualSwapChainBufferCount;
+ swapChainD->bufferCount = int(actualSwapChainBufferCount);
VkImage swapChainImages[QVkSwapChain::MAX_BUFFER_COUNT];
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages);
@@ -1424,7 +1448,8 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain)
if (swapChainD->sc == VK_NULL_HANDLE)
return;
- df->vkDeviceWaitIdle(dev);
+ if (!deviceLost)
+ df->vkDeviceWaitIdle(dev);
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) {
QVkSwapChain::FrameResources &frame(swapChainD->frameRes[i]);
@@ -1487,15 +1512,6 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain)
// NB! surface and similar must remain intact
}
-static inline bool checkDeviceLost(VkResult err)
-{
- if (err == VK_ERROR_DEVICE_LOST) {
- qWarning("Device lost");
- return true;
- }
- return false;
-}
-
QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags)
{
QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain);
@@ -1522,10 +1538,12 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
} else if (err == VK_ERROR_OUT_OF_DATE_KHR) {
return QRhi::FrameOpSwapChainOutOfDate;
} else {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkAcquireNextImageKHR()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to acquire next swapchain image: %d", err);
+ }
+ qWarning("Failed to acquire next swapchain image: %d", err);
return QRhi::FrameOpError;
}
}
@@ -1540,12 +1558,12 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
// will make B wait for A's frame 0 commands, so if a resource is written
// in B's frame or when B checks for pending resource releases, that won't
// mess up A's in-flight commands (as they are not in flight anymore).
- waitCommandCompletion(swapChainD->currentFrameSlot);
+ waitCommandCompletion(int(swapChainD->currentFrameSlot));
// Now is the time to read the timestamps for the previous frame for this slot.
if (frame.timestampQueryIndex >= 0) {
quint64 timestamp[2] = { 0, 0 };
- VkResult err = df->vkGetQueryPoolResults(dev, timestampQueryPool, frame.timestampQueryIndex, 2,
+ VkResult err = df->vkGetQueryPoolResults(dev, timestampQueryPool, uint32_t(frame.timestampQueryIndex), 2,
2 * sizeof(quint64), timestamp, sizeof(quint64),
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
timestampQueryPoolMap.clearBit(frame.timestampQueryIndex / 2);
@@ -1585,10 +1603,10 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
}
}
if (timestampQueryIdx >= 0) {
- df->vkCmdResetQueryPool(frame.cmdBuf, timestampQueryPool, timestampQueryIdx, 2);
+ df->vkCmdResetQueryPool(frame.cmdBuf, timestampQueryPool, uint32_t(timestampQueryIdx), 2);
// record timestamp at the start of the command buffer
df->vkCmdWriteTimestamp(frame.cmdBuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- timestampQueryPool, timestampQueryIdx);
+ timestampQueryPool, uint32_t(timestampQueryIdx));
frame.timestampQueryIndex = timestampQueryIdx;
}
@@ -1598,7 +1616,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImageIndex]);
swapChainD->rtWrapper.d.fb = image.fb;
- currentFrameSlot = swapChainD->currentFrameSlot;
+ currentFrameSlot = int(swapChainD->currentFrameSlot);
currentSwapChain = swapChainD;
if (swapChainD->ds)
swapChainD->ds->lastActiveFrameSlot = currentFrameSlot;
@@ -1653,7 +1671,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
// record another timestamp, when enabled
if (frame.timestampQueryIndex >= 0) {
df->vkCmdWriteTimestamp(frame.cmdBuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
- timestampQueryPool, frame.timestampQueryIndex + 1);
+ timestampQueryPool, uint32_t(frame.timestampQueryIndex + 1));
}
// stop recording and submit to the queue
@@ -1689,10 +1707,12 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
return QRhi::FrameOpSwapChainOutOfDate;
} else if (err != VK_SUBOPTIMAL_KHR) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkQueuePresentKHR()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to present: %d", err);
+ }
+ qWarning("Failed to present: %d", err);
return QRhi::FrameOpError;
}
}
@@ -1749,10 +1769,12 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
VkResult err = df->vkAllocateCommandBuffers(dev, &cmdBufInfo, cb);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkAllocateCommandBuffers()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to allocate frame command buffer: %d", err);
+ }
+ qWarning("Failed to allocate frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1762,10 +1784,12 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
err = df->vkBeginCommandBuffer(*cb, &cmdBufBeginInfo);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkBeginCommandBuffer()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to begin frame command buffer: %d", err);
+ }
+ qWarning("Failed to begin frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1777,10 +1801,12 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
{
VkResult err = df->vkEndCommandBuffer(cb);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkEndCommandBuffer()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to end frame command buffer: %d", err);
+ }
+ qWarning("Failed to end frame command buffer: %d", err);
return QRhi::FrameOpError;
}
@@ -1802,10 +1828,12 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
err = df->vkQueueSubmit(gfxQueue, 1, &submitInfo, cmdFence);
if (err != VK_SUCCESS) {
- if (checkDeviceLost(err))
+ if (err == VK_ERROR_DEVICE_LOST) {
+ qWarning("Device loss detected in vkQueueSubmit()");
+ deviceLost = true;
return QRhi::FrameOpDeviceLost;
- else
- qWarning("Failed to submit to graphics queue: %d", err);
+ }
+ qWarning("Failed to submit to graphics queue: %d", err);
return QRhi::FrameOpError;
}
@@ -1932,8 +1960,8 @@ static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const
{
QRhiPassResourceTracker::UsageState u;
u.layout = 0; // unused with buffers
- u.access = bufUsage.access;
- u.stage = bufUsage.stage;
+ u.access = int(bufUsage.access);
+ u.stage = int(bufUsage.stage);
return u;
}
@@ -1941,8 +1969,8 @@ static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const
{
QRhiPassResourceTracker::UsageState u;
u.layout = texUsage.layout;
- u.access = texUsage.access;
- u.stage = texUsage.stage;
+ u.access = int(texUsage.access);
+ u.stage = int(texUsage.stage);
return u;
}
@@ -2106,8 +2134,8 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb,
rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rpBeginInfo.renderPass = rtD->rp->rp;
rpBeginInfo.framebuffer = rtD->fb;
- rpBeginInfo.renderArea.extent.width = rtD->pixelSize.width();
- rpBeginInfo.renderArea.extent.height = rtD->pixelSize.height();
+ rpBeginInfo.renderArea.extent.width = uint32_t(rtD->pixelSize.width());
+ rpBeginInfo.renderArea.extent.height = uint32_t(rtD->pixelSize.height());
QVarLengthArray<VkClearValue, 4> cvs;
for (int i = 0; i < rtD->colorAttCount; ++i) {
@@ -2127,7 +2155,7 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb,
float(colorClearValue.alphaF()) } };
cvs.append(cv);
}
- rpBeginInfo.clearValueCount = cvs.count();
+ rpBeginInfo.clearValueCount = uint32_t(cvs.count());
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::BeginRenderPass;
@@ -2229,7 +2257,7 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z)
Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::ComputePass);
if (cbD->useSecondaryCb) {
- df->vkCmdDispatch(cbD->secondaryCbs.last(), x, y, z);
+ df->vkCmdDispatch(cbD->secondaryCbs.last(), uint32_t(x), uint32_t(y), uint32_t(z));
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::Dispatch;
@@ -2245,7 +2273,7 @@ VkShaderModule QRhiVulkan::createShader(const QByteArray &spirv)
VkShaderModuleCreateInfo shaderInfo;
memset(&shaderInfo, 0, sizeof(shaderInfo));
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
- shaderInfo.codeSize = spirv.size();
+ shaderInfo.codeSize = size_t(spirv.size());
shaderInfo.pCode = reinterpret_cast<const quint32 *>(spirv.constData());
VkShaderModule shaderModule;
VkResult err = df->vkCreateShaderModule(dev, &shaderInfo, nullptr, &shaderModule);
@@ -2292,7 +2320,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
memset(&writeInfo, 0, sizeof(writeInfo));
writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfo.dstSet = srbD->descSets[frameSlot];
- writeInfo.dstBinding = b->binding;
+ writeInfo.dstBinding = uint32_t(b->binding);
writeInfo.descriptorCount = 1;
switch (b->type) {
@@ -2306,8 +2334,8 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
bd.ubuf.generation = bufD->generation;
VkDescriptorBufferInfo bufInfo;
bufInfo.buffer = bufD->m_type == QRhiBuffer::Dynamic ? bufD->buffers[frameSlot] : bufD->buffers[0];
- bufInfo.offset = b->u.ubuf.offset;
- bufInfo.range = b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size;
+ bufInfo.offset = VkDeviceSize(b->u.ubuf.offset);
+ bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size);
// be nice and assert when we know the vulkan device would die a horrible death due to non-aligned reads
Q_ASSERT(aligned(bufInfo.offset, ubufAlign) == bufInfo.offset);
bufferInfos.append(bufInfo);
@@ -2364,8 +2392,8 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
bd.sbuf.generation = bufD->generation;
VkDescriptorBufferInfo bufInfo;
bufInfo.buffer = bufD->m_type == QRhiBuffer::Dynamic ? bufD->buffers[frameSlot] : bufD->buffers[0];
- bufInfo.offset = b->u.ubuf.offset;
- bufInfo.range = b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size;
+ bufInfo.offset = VkDeviceSize(b->u.ubuf.offset);
+ bufInfo.range = VkDeviceSize(b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size);
bufferInfos.append(bufInfo);
writeInfo.pBufferInfo = &bufferInfos.last();
}
@@ -2379,7 +2407,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
++frameSlot;
}
- df->vkUpdateDescriptorSets(dev, writeInfos.count(), writeInfos.constData(), 0, nullptr);
+ df->vkUpdateDescriptorSets(dev, uint32_t(writeInfos.count()), writeInfos.constData(), 0, nullptr);
}
static inline bool accessIsWrite(VkAccessFlags access)
@@ -2487,10 +2515,10 @@ void QRhiVulkan::subresourceBarrier(QVkCommandBuffer *cbD, VkImage image,
memset(&barrier, 0, sizeof(barrier));
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- barrier.subresourceRange.baseMipLevel = startLevel;
- barrier.subresourceRange.levelCount = levelCount;
- barrier.subresourceRange.baseArrayLayer = startLayer;
- barrier.subresourceRange.layerCount = layerCount;
+ barrier.subresourceRange.baseMipLevel = uint32_t(startLevel);
+ barrier.subresourceRange.levelCount = uint32_t(levelCount);
+ barrier.subresourceRange.baseArrayLayer = uint32_t(startLayer);
+ barrier.subresourceRange.layerCount = uint32_t(layerCount);
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.srcAccessMask = srcAccess;
@@ -2511,7 +2539,7 @@ VkDeviceSize QRhiVulkan::subresUploadByteSize(const QRhiTextureSubresourceUpload
const qsizetype imageSizeBytes = subresDesc.image().isNull() ?
subresDesc.data().size() : subresDesc.image().sizeInBytes();
if (imageSizeBytes > 0)
- size += aligned(imageSizeBytes, texbufAlign);
+ size += aligned(VkDeviceSize(imageSizeBytes), texbufAlign);
return size;
}
@@ -2528,8 +2556,8 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
memset(&copyInfo, 0, sizeof(copyInfo));
copyInfo.bufferOffset = *curOfs;
copyInfo.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- copyInfo.imageSubresource.mipLevel = level;
- copyInfo.imageSubresource.baseArrayLayer = layer;
+ copyInfo.imageSubresource.mipLevel = uint32_t(level);
+ copyInfo.imageSubresource.baseArrayLayer = uint32_t(layer);
copyInfo.imageSubresource.layerCount = 1;
copyInfo.imageExtent.depth = 1;
@@ -2544,7 +2572,7 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// be taken into account for bufferRowLength.
int bpc = qMax(1, image.depth() / 8);
// this is in pixels, not bytes, to make it more complicated...
- copyInfo.bufferRowLength = image.bytesPerLine() / bpc;
+ copyInfo.bufferRowLength = uint32_t(image.bytesPerLine() / bpc);
if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
const int sx = subresDesc.sourceTopLeft().x();
const int sy = subresDesc.sourceTopLeft().y();
@@ -2554,7 +2582,7 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// The staging buffer will get the full image
// regardless, just adjust the vk
// buffer-to-image copy start offset.
- copyInfo.bufferOffset += sy * image.bytesPerLine() + sx * 4;
+ copyInfo.bufferOffset += VkDeviceSize(sy * image.bytesPerLine() + sx * 4);
// bufferRowLength remains set to the original image's width
} else {
image = image.copy(sx, sy, size.width(), size.height());
@@ -2563,13 +2591,13 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
// space reserved for this mip will be unused.
copySizeBytes = image.sizeInBytes();
bpc = qMax(1, image.depth() / 8);
- copyInfo.bufferRowLength = image.bytesPerLine() / bpc;
+ copyInfo.bufferRowLength = uint32_t(image.bytesPerLine() / bpc);
}
}
copyInfo.imageOffset.x = dp.x();
copyInfo.imageOffset.y = dp.y();
- copyInfo.imageExtent.width = size.width();
- copyInfo.imageExtent.height = size.height();
+ copyInfo.imageExtent.width = uint32_t(size.width());
+ copyInfo.imageExtent.height = uint32_t(size.height());
copyInfos->append(copyInfo);
} else if (!rawData.isEmpty() && isCompressedFormat(texD->m_format)) {
copySizeBytes = imageSizeBytes = rawData.size();
@@ -2588,8 +2616,8 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
copyInfo.imageOffset.y = aligned(dp.y(), blockDim.height());
// width and height must be multiples of the block width and height
// or x + width and y + height must equal the subresource width and height
- copyInfo.imageExtent.width = dp.x() + w == subresw ? w : aligned(w, blockDim.width());
- copyInfo.imageExtent.height = dp.y() + h == subresh ? h : aligned(h, blockDim.height());
+ copyInfo.imageExtent.width = uint32_t(dp.x() + w == subresw ? w : aligned(w, blockDim.width()));
+ copyInfo.imageExtent.height = uint32_t(dp.y() + h == subresh ? h : aligned(h, blockDim.height()));
copyInfos->append(copyInfo);
} else if (!rawData.isEmpty()) {
copySizeBytes = imageSizeBytes = rawData.size();
@@ -2599,15 +2627,15 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
size = subresDesc.sourceSize();
copyInfo.imageOffset.x = dp.x();
copyInfo.imageOffset.y = dp.y();
- copyInfo.imageExtent.width = size.width();
- copyInfo.imageExtent.height = size.height();
+ copyInfo.imageExtent.width = uint32_t(size.width());
+ copyInfo.imageExtent.height = uint32_t(size.height());
copyInfos->append(copyInfo);
} else {
qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
}
- memcpy(reinterpret_cast<char *>(mp) + *curOfs, src, copySizeBytes);
- *curOfs += aligned(imageSizeBytes, texbufAlign);
+ memcpy(reinterpret_cast<char *>(mp) + *curOfs, src, size_t(copySizeBytes));
+ *curOfs += aligned(VkDeviceSize(imageSizeBytes), texbufAlign);
}
void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates)
@@ -2633,7 +2661,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
// must cover the entire buffer - this way multiple, partial updates per frame
// are supported even when the staging buffer is reused (Static)
- bufferInfo.size = bufD->m_size;
+ bufferInfo.size = VkDeviceSize(bufD->m_size);
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VmaAllocationCreateInfo allocInfo;
@@ -2645,7 +2673,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
&bufD->stagingBuffers[currentFrameSlot], &allocation, nullptr);
if (err == VK_SUCCESS) {
bufD->stagingAllocations[currentFrameSlot] = allocation;
- QRHI_PROF_F(newBufferStagingArea(bufD, currentFrameSlot, bufD->m_size));
+ QRHI_PROF_F(newBufferStagingArea(bufD, currentFrameSlot, quint32(bufD->m_size)));
} else {
qWarning("Failed to create staging buffer of size %d: %d", bufD->m_size, err);
continue;
@@ -2659,18 +2687,18 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
qWarning("Failed to map buffer: %d", err);
continue;
}
- memcpy(static_cast<uchar *>(p) + u.offset, u.data.constData(), u.data.size());
+ memcpy(static_cast<uchar *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
vmaUnmapMemory(toVmaAllocator(allocator), a);
- vmaFlushAllocation(toVmaAllocator(allocator), a, u.offset, u.data.size());
+ vmaFlushAllocation(toVmaAllocator(allocator), a, VkDeviceSize(u.offset), VkDeviceSize(u.data.size()));
trackedBufferBarrier(cbD, bufD, 0,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
VkBufferCopy copyInfo;
memset(&copyInfo, 0, sizeof(copyInfo));
- copyInfo.srcOffset = u.offset;
- copyInfo.dstOffset = u.offset;
- copyInfo.size = u.data.size();
+ copyInfo.srcOffset = VkDeviceSize(u.offset);
+ copyInfo.dstOffset = VkDeviceSize(u.offset);
+ copyInfo.size = VkDeviceSize(u.data.size());
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::CopyBuffer;
@@ -2732,7 +2760,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
continue;
}
utexD->stagingAllocations[currentFrameSlot] = allocation;
- QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, stagingSize));
+ QRHI_PROF_F(newTextureStagingArea(utexD, currentFrameSlot, quint32(stagingSize)));
BufferImageCopyList copyInfos;
size_t curOfs = 0;
@@ -2799,24 +2827,24 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
memset(&region, 0, sizeof(region));
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.srcSubresource.mipLevel = u.copy.desc.sourceLevel();
- region.srcSubresource.baseArrayLayer = u.copy.desc.sourceLayer();
+ region.srcSubresource.mipLevel = uint32_t(u.copy.desc.sourceLevel());
+ region.srcSubresource.baseArrayLayer = uint32_t(u.copy.desc.sourceLayer());
region.srcSubresource.layerCount = 1;
region.srcOffset.x = u.copy.desc.sourceTopLeft().x();
region.srcOffset.y = u.copy.desc.sourceTopLeft().y();
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.dstSubresource.mipLevel = u.copy.desc.destinationLevel();
- region.dstSubresource.baseArrayLayer = u.copy.desc.destinationLayer();
+ region.dstSubresource.mipLevel = uint32_t(u.copy.desc.destinationLevel());
+ region.dstSubresource.baseArrayLayer = uint32_t(u.copy.desc.destinationLayer());
region.dstSubresource.layerCount = 1;
region.dstOffset.x = u.copy.desc.destinationTopLeft().x();
region.dstOffset.y = u.copy.desc.destinationTopLeft().y();
const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize();
- region.extent.width = size.width();
- region.extent.height = size.height();
+ region.extent.width = uint32_t(size.width());
+ region.extent.height = uint32_t(size.height());
region.extent.depth = 1;
trackedImageBarrier(cbD, srcD, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
@@ -2883,7 +2911,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
VkResult err = vmaCreateBuffer(toVmaAllocator(allocator), &bufferInfo, &allocInfo, &aRb.buf, &allocation, nullptr);
if (err == VK_SUCCESS) {
aRb.bufAlloc = allocation;
- QRHI_PROF_F(newReadbackBuffer(quint64(aRb.buf),
+ QRHI_PROF_F(newReadbackBuffer(qint64(aRb.buf),
texD ? static_cast<QRhiResource *>(texD) : static_cast<QRhiResource *>(swapChainD),
aRb.bufSize));
} else {
@@ -2896,11 +2924,11 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
memset(&copyDesc, 0, sizeof(copyDesc));
copyDesc.bufferOffset = 0;
copyDesc.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- copyDesc.imageSubresource.mipLevel = u.read.rb.level();
- copyDesc.imageSubresource.baseArrayLayer = u.read.rb.layer();
+ copyDesc.imageSubresource.mipLevel = uint32_t(u.read.rb.level());
+ copyDesc.imageSubresource.baseArrayLayer = uint32_t(u.read.rb.layer());
copyDesc.imageSubresource.layerCount = 1;
- copyDesc.imageExtent.width = aRb.pixelSize.width();
- copyDesc.imageExtent.height = aRb.pixelSize.height();
+ copyDesc.imageExtent.width = uint32_t(aRb.pixelSize.width());
+ copyDesc.imageExtent.height = uint32_t(aRb.pixelSize.height());
copyDesc.imageExtent.depth = 1;
if (texD) {
@@ -2953,7 +2981,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
if (!origStage)
origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- for (uint level = 1; level < utexD->mipLevelCount; ++level) {
+ for (int level = 1; level < int(utexD->mipLevelCount); ++level) {
if (level == 1) {
subresourceBarrier(cbD, utexD->image,
origLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
@@ -2981,8 +3009,8 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
memset(&region, 0, sizeof(region));
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.srcSubresource.mipLevel = level - 1;
- region.srcSubresource.baseArrayLayer = u.mipgen.layer;
+ region.srcSubresource.mipLevel = uint32_t(level) - 1;
+ region.srcSubresource.baseArrayLayer = uint32_t(u.mipgen.layer);
region.srcSubresource.layerCount = 1;
region.srcOffsets[1].x = qMax(1, w);
@@ -2990,8 +3018,8 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
region.srcOffsets[1].z = 1;
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.dstSubresource.mipLevel = level;
- region.dstSubresource.baseArrayLayer = u.mipgen.layer;
+ region.dstSubresource.mipLevel = uint32_t(level);
+ region.dstSubresource.baseArrayLayer = uint32_t(u.mipgen.layer);
region.dstSubresource.layerCount = 1;
region.dstOffsets[1].x = qMax(1, w >> 1);
@@ -3018,13 +3046,13 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
VK_ACCESS_TRANSFER_READ_BIT, origAccess,
VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
u.mipgen.layer, 1,
- 0, utexD->mipLevelCount - 1);
+ 0, int(utexD->mipLevelCount) - 1);
subresourceBarrier(cbD, utexD->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, origLayout,
VK_ACCESS_TRANSFER_WRITE_BIT, origAccess,
VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
u.mipgen.layer, 1,
- utexD->mipLevelCount - 1, 1);
+ int(utexD->mipLevelCount) - 1, 1);
}
utexD->lastActiveFrameSlot = currentFrameSlot;
@@ -3055,7 +3083,7 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
int changeEnd = -1;
for (const QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate &u : updates) {
Q_ASSERT(bufD == QRHI_RES(QVkBuffer, u.buf));
- memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), u.data.size());
+ memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin)
changeBegin = u.offset;
if (changeEnd == -1 || u.offset + u.data.size() > changeEnd)
@@ -3063,7 +3091,7 @@ void QRhiVulkan::executeBufferHostWritesForCurrentFrame(QVkBuffer *bufD)
}
vmaUnmapMemory(toVmaAllocator(allocator), a);
if (changeBegin >= 0)
- vmaFlushAllocation(toVmaAllocator(allocator), a, changeBegin, changeEnd - changeBegin);
+ vmaFlushAllocation(toVmaAllocator(allocator), a, VkDeviceSize(changeBegin), VkDeviceSize(changeEnd - changeBegin));
updates.clear();
}
@@ -3164,7 +3192,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced)
if (forced || currentFrameSlot == aRb.activeFrameSlot || aRb.activeFrameSlot < 0) {
aRb.result->format = aRb.format;
aRb.result->pixelSize = aRb.pixelSize;
- aRb.result->data.resize(aRb.bufSize);
+ aRb.result->data.resize(int(aRb.bufSize));
void *p = nullptr;
VmaAllocation a = toVmaAllocation(aRb.bufAlloc);
VkResult err = vmaMapMemory(toVmaAllocator(allocator), a, &p);
@@ -3176,7 +3204,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced)
vmaUnmapMemory(toVmaAllocator(allocator), a);
vmaDestroyBuffer(toVmaAllocator(allocator), aRb.buf, a);
- QRHI_PROF_F(releaseReadbackBuffer(quint64(aRb.buf)));
+ QRHI_PROF_F(releaseReadbackBuffer(qint64(aRb.buf)));
if (aRb.result->completed)
completedCallbacks.append(aRb.result->completed);
@@ -3266,7 +3294,7 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
case QVkCommandBuffer::Command::CopyBufferToImage:
df->vkCmdCopyBufferToImage(cbD->cb, cmd.args.copyBufferToImage.src, cmd.args.copyBufferToImage.dst,
cmd.args.copyBufferToImage.dstLayout,
- cmd.args.copyBufferToImage.count,
+ uint32_t(cmd.args.copyBufferToImage.count),
cbD->pools.bufferImageCopy.constData() + cmd.args.copyBufferToImage.bufferImageCopyIndex);
break;
case QVkCommandBuffer::Command::CopyImage:
@@ -3315,13 +3343,13 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
df->vkCmdBindDescriptorSets(cbD->cb, cmd.args.bindDescriptorSet.bindPoint,
cmd.args.bindDescriptorSet.pipelineLayout,
0, 1, &cmd.args.bindDescriptorSet.descSet,
- cmd.args.bindDescriptorSet.dynamicOffsetCount,
+ uint32_t(cmd.args.bindDescriptorSet.dynamicOffsetCount),
offsets);
}
break;
case QVkCommandBuffer::Command::BindVertexBuffer:
- df->vkCmdBindVertexBuffers(cbD->cb, cmd.args.bindVertexBuffer.startBinding,
- cmd.args.bindVertexBuffer.count,
+ df->vkCmdBindVertexBuffers(cbD->cb, uint32_t(cmd.args.bindVertexBuffer.startBinding),
+ uint32_t(cmd.args.bindVertexBuffer.count),
cbD->pools.vertexBuffer.constData() + cmd.args.bindVertexBuffer.vertexBufferIndex,
cbD->pools.vertexBufferOffset.constData() + cmd.args.bindVertexBuffer.vertexBufferOffsetIndex);
break;
@@ -3367,7 +3395,7 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
recordTransitionPassResources(cbD, cbD->passResTrackers[cmd.args.transitionResources.trackerIndex]);
break;
case QVkCommandBuffer::Command::Dispatch:
- df->vkCmdDispatch(cbD->cb, cmd.args.dispatch.x, cmd.args.dispatch.y, cmd.args.dispatch.z);
+ df->vkCmdDispatch(cbD->cb, uint32_t(cmd.args.dispatch.x), uint32_t(cmd.args.dispatch.y), uint32_t(cmd.args.dispatch.z));
break;
case QVkCommandBuffer::Command::ExecuteSecondary:
df->vkCmdExecuteCommands(cbD->cb, 1, &cmd.args.executeSecondary.cb);
@@ -3421,8 +3449,8 @@ static inline VkPipelineStageFlags toVkPipelineStage(QRhiPassResourceTracker::Bu
static inline QVkBuffer::UsageState toVkBufferUsageState(QRhiPassResourceTracker::UsageState usage)
{
QVkBuffer::UsageState u;
- u.access = usage.access;
- u.stage = usage.stage;
+ u.access = VkAccessFlags(usage.access);
+ u.stage = VkPipelineStageFlags(usage.stage);
return u;
}
@@ -3494,8 +3522,8 @@ static inline QVkTexture::UsageState toVkTextureUsageState(QRhiPassResourceTrack
{
QVkTexture::UsageState u;
u.layout = VkImageLayout(usage.layout);
- u.access = usage.access;
- u.stage = usage.stage;
+ u.access = VkAccessFlags(usage.access);
+ u.stage = VkPipelineStageFlags(usage.stage);
return u;
}
@@ -3603,7 +3631,7 @@ QRhiBuffer *QRhiVulkan::createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFla
int QRhiVulkan::ubufAlignment() const
{
- return ubufAlign; // typically 256 (bytes)
+ return int(ubufAlign); // typically 256 (bytes)
}
bool QRhiVulkan::isYUpInFramebuffer() const
@@ -3711,9 +3739,9 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const
case QRhi::TextureSizeMin:
return 1;
case QRhi::TextureSizeMax:
- return physDevProperties.limits.maxImageDimension2D;
+ return int(physDevProperties.limits.maxImageDimension2D);
case QRhi::MaxColorAttachments:
- return physDevProperties.limits.maxColorAttachments;
+ return int(physDevProperties.limits.maxColorAttachments);
case QRhi::FramesInFlight:
return QVK_FRAMES_IN_FLIGHT;
default:
@@ -3736,14 +3764,25 @@ void QRhiVulkan::sendVMemStatsToProfiler()
VmaStats stats;
vmaCalculateStats(toVmaAllocator(allocator), &stats);
QRHI_PROF_F(vmemStat(stats.total.blockCount, stats.total.allocationCount,
- stats.total.usedBytes, stats.total.unusedBytes));
+ quint32(stats.total.usedBytes), quint32(stats.total.unusedBytes)));
+}
+
+bool QRhiVulkan::makeThreadLocalNativeContextCurrent()
+{
+ // not applicable
+ return false;
}
-void QRhiVulkan::makeThreadLocalNativeContextCurrent()
+void QRhiVulkan::releaseCachedResources()
{
// nothing to do here
}
+bool QRhiVulkan::isDeviceLost() const
+{
+ return deviceLost;
+}
+
QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
{
@@ -4003,7 +4042,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE,
gfxPsD ? gfxPsD->layout : compPsD->layout,
0, 1, &srbD->descSets[descSetIdx],
- dynOfs.count(),
+ uint32_t(dynOfs.count()),
dynOfs.count() ? dynOfs.constData() : nullptr);
} else {
QVkCommandBuffer::Command cmd;
@@ -4073,8 +4112,8 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb,
}
if (cbD->useSecondaryCb) {
- df->vkCmdBindVertexBuffers(cbD->secondaryCbs.last(), startBinding,
- bufs.count(), bufs.constData(), ofs.constData());
+ df->vkCmdBindVertexBuffers(cbD->secondaryCbs.last(), uint32_t(startBinding),
+ uint32_t(bufs.count()), bufs.constData(), ofs.constData());
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::BindVertexBuffer;
@@ -4155,10 +4194,10 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport
if (!QRHI_RES(QVkGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor)) {
VkRect2D *s = &cmd.args.setScissor.scissor;
- s->offset.x = x;
- s->offset.y = y;
- s->extent.width = w;
- s->extent.height = h;
+ s->offset.x = int32_t(x);
+ s->offset.y = int32_t(y);
+ s->extent.width = uint32_t(w);
+ s->extent.height = uint32_t(h);
if (cbD->useSecondaryCb) {
df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s);
} else {
@@ -4184,8 +4223,8 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
VkRect2D *s = &cmd.args.setScissor.scissor;
s->offset.x = x;
s->offset.y = y;
- s->extent.width = w;
- s->extent.height = h;
+ s->extent.width = uint32_t(w);
+ s->extent.height = uint32_t(h);
if (cbD->useSecondaryCb) {
df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s);
@@ -4206,10 +4245,10 @@ void QRhiVulkan::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c)
} else {
QVkCommandBuffer::Command cmd;
cmd.cmd = QVkCommandBuffer::Command::SetBlendConstants;
- cmd.args.setBlendConstants.c[0] = c.redF();
- cmd.args.setBlendConstants.c[1] = c.greenF();
- cmd.args.setBlendConstants.c[2] = c.blueF();
- cmd.args.setBlendConstants.c[3] = c.alphaF();
+ cmd.args.setBlendConstants.c[0] = float(c.redF());
+ cmd.args.setBlendConstants.c[1] = float(c.greenF());
+ cmd.args.setBlendConstants.c[2] = float(c.blueF());
+ cmd.args.setBlendConstants.c[3] = float(c.alphaF());
cbD->commands.append(cmd);
}
}
@@ -4838,7 +4877,7 @@ bool QVkBuffer::build()
VkBufferCreateInfo bufferInfo;
memset(&bufferInfo, 0, sizeof(bufferInfo));
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- bufferInfo.size = nonZeroSize;
+ bufferInfo.size = uint32_t(nonZeroSize);
bufferInfo.usage = toVkBufferUsage(m_usage);
VmaAllocationCreateInfo allocInfo;
@@ -4885,7 +4924,7 @@ bool QVkBuffer::build()
}
QRHI_PROF;
- QRHI_PROF_F(newBuffer(this, nonZeroSize, m_type != Dynamic ? 1 : QVK_FRAMES_IN_FLIGHT, 0));
+ QRHI_PROF_F(newBuffer(this, uint(nonZeroSize), m_type != Dynamic ? 1 : QVK_FRAMES_IN_FLIGHT, 0));
lastActiveFrameSlot = -1;
generation += 1;
@@ -5076,7 +5115,7 @@ bool QVkTexture::prepareBuild(QSize *adjustedSize)
const bool isCube = m_flags.testFlag(CubeMap);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
- mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1;
+ mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
const int maxLevels = QRhi::MAX_LEVELS;
if (mipLevelCount > maxLevels) {
qWarning("Too many mip levels (%d, max is %d), truncating mip chain", mipLevelCount, maxLevels);
@@ -5155,8 +5194,8 @@ bool QVkTexture::build()
imageInfo.flags = isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format = vkformat;
- imageInfo.extent.width = size.width();
- imageInfo.extent.height = size.height();
+ imageInfo.extent.width = uint32_t(size.width());
+ imageInfo.extent.height = uint32_t(size.height());
imageInfo.extent.depth = 1;
imageInfo.mipLevels = mipLevelCount;
imageInfo.arrayLayers = isCube ? 6 : 1;
@@ -5197,7 +5236,7 @@ bool QVkTexture::build()
rhiD->setObjectName(uint64_t(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, m_objectName);
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, samples));
owns = true;
rhiD->registerResource(this);
@@ -5219,7 +5258,7 @@ bool QVkTexture::buildFrom(const QRhiNativeHandles *src)
return false;
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, samples));
usageState.layout = h->layout;
@@ -5255,7 +5294,7 @@ VkImageView QVkTexture::imageViewForLevel(int level)
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = level;
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(level);
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
@@ -5496,9 +5535,9 @@ bool QVkTextureRenderTarget::build()
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = colorAttachments[i].level();
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(colorAttachments[i].level());
viewInfo.subresourceRange.levelCount = 1;
- viewInfo.subresourceRange.baseArrayLayer = colorAttachments[i].layer();
+ viewInfo.subresourceRange.baseArrayLayer = uint32_t(colorAttachments[i].layer());
viewInfo.subresourceRange.layerCount = 1;
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[i]);
if (err != VK_SUCCESS) {
@@ -5560,9 +5599,9 @@ bool QVkTextureRenderTarget::build()
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- viewInfo.subresourceRange.baseMipLevel = colorAttachments[i].resolveLevel();
+ viewInfo.subresourceRange.baseMipLevel = uint32_t(colorAttachments[i].resolveLevel());
viewInfo.subresourceRange.levelCount = 1;
- viewInfo.subresourceRange.baseArrayLayer = colorAttachments[i].resolveLayer();
+ viewInfo.subresourceRange.baseArrayLayer = uint32_t(colorAttachments[i].resolveLayer());
viewInfo.subresourceRange.layerCount = 1;
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[i]);
if (err != VK_SUCCESS) {
@@ -5583,10 +5622,10 @@ bool QVkTextureRenderTarget::build()
memset(&fbInfo, 0, sizeof(fbInfo));
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbInfo.renderPass = d.rp->rp;
- fbInfo.attachmentCount = d.colorAttCount + d.dsAttCount + d.resolveAttCount;
+ fbInfo.attachmentCount = uint32_t(d.colorAttCount + d.dsAttCount + d.resolveAttCount);
fbInfo.pAttachments = views.constData();
- fbInfo.width = d.pixelSize.width();
- fbInfo.height = d.pixelSize.height();
+ fbInfo.width = uint32_t(d.pixelSize.width());
+ fbInfo.height = uint32_t(d.pixelSize.height());
fbInfo.layers = 1;
VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo, nullptr, &d.fb);
@@ -5670,7 +5709,7 @@ bool QVkShaderResourceBindings::build()
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
VkDescriptorSetLayoutBinding vkbinding;
memset(&vkbinding, 0, sizeof(vkbinding));
- vkbinding.binding = b->binding;
+ vkbinding.binding = uint32_t(b->binding);
vkbinding.descriptorType = toVkDescriptorType(b);
vkbinding.descriptorCount = 1; // no array support yet
vkbinding.stageFlags = toVkShaderStageFlags(b->stage);
@@ -5787,7 +5826,7 @@ bool QVkGraphicsPipeline::build()
shaderStageCreateInfos.append(shaderInfo);
}
}
- pipelineInfo.stageCount = shaderStageCreateInfos.count();
+ pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.count());
pipelineInfo.pStages = shaderStageCreateInfos.constData();
const QVector<QRhiVertexInputBinding> bindings = m_vertexInputLayout.bindings();
@@ -5828,15 +5867,15 @@ bool QVkGraphicsPipeline::build()
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
memset(&vertexInputInfo, 0, sizeof(vertexInputInfo));
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
- vertexInputInfo.vertexBindingDescriptionCount = vertexBindings.count();
+ vertexInputInfo.vertexBindingDescriptionCount = uint32_t(vertexBindings.count());
vertexInputInfo.pVertexBindingDescriptions = vertexBindings.constData();
- vertexInputInfo.vertexAttributeDescriptionCount = vertexAttributes.count();
+ vertexInputInfo.vertexAttributeDescriptionCount = uint32_t(vertexAttributes.count());
vertexInputInfo.pVertexAttributeDescriptions = vertexAttributes.constData();
VkPipelineVertexInputDivisorStateCreateInfoEXT divisorInfo;
if (!nonOneStepRates.isEmpty()) {
memset(&divisorInfo, 0, sizeof(divisorInfo));
divisorInfo.sType = VkStructureType(1000190001); // VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT
- divisorInfo.vertexBindingDivisorCount = nonOneStepRates.count();
+ divisorInfo.vertexBindingDivisorCount = uint32_t(nonOneStepRates.count());
divisorInfo.pVertexBindingDivisors = nonOneStepRates.constData();
vertexInputInfo.pNext = &divisorInfo;
}
@@ -5853,7 +5892,7 @@ bool QVkGraphicsPipeline::build()
VkPipelineDynamicStateCreateInfo dynamicInfo;
memset(&dynamicInfo, 0, sizeof(dynamicInfo));
dynamicInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
- dynamicInfo.dynamicStateCount = dynEnable.count();
+ dynamicInfo.dynamicStateCount = uint32_t(dynEnable.count());
dynamicInfo.pDynamicStates = dynEnable.constData();
pipelineInfo.pDynamicState = &dynamicInfo;
@@ -5925,7 +5964,7 @@ bool QVkGraphicsPipeline::build()
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
vktargetBlends.append(blend);
}
- blendInfo.attachmentCount = vktargetBlends.count();
+ blendInfo.attachmentCount = uint32_t(vktargetBlends.count());
blendInfo.pAttachments = vktargetBlends.constData();
pipelineInfo.pColorBlendState = &blendInfo;
@@ -6126,11 +6165,11 @@ QSize QVkSwapChain::surfacePixelSize()
QRHI_RES_RHI(QRhiVulkan);
rhiD->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(rhiD->physDev, surface, &surfaceCaps);
VkExtent2D bufferSize = surfaceCaps.currentExtent;
- if (bufferSize.width == quint32(-1)) {
- Q_ASSERT(bufferSize.height == quint32(-1));
+ if (bufferSize.width == uint32_t(-1)) {
+ Q_ASSERT(bufferSize.height == uint32_t(-1));
return m_window->size() * m_window->devicePixelRatio();
}
- return QSize(bufferSize.width, bufferSize.height);
+ return QSize(int(bufferSize.width), int(bufferSize.height));
}
QRhiRenderPassDescriptor *QVkSwapChain::newCompatibleRenderPassDescriptor()
@@ -6198,7 +6237,7 @@ bool QVkSwapChain::ensureSurface()
QRHI_RES_RHI(QRhiVulkan);
if (rhiD->gfxQueueFamilyIdx != -1) {
- if (!rhiD->inst->supportsPresent(rhiD->physDev, rhiD->gfxQueueFamilyIdx, m_window)) {
+ if (!rhiD->inst->supportsPresent(rhiD->physDev, uint32_t(rhiD->gfxQueueFamilyIdx), m_window)) {
qWarning("Presenting not supported on this window");
return false;
}
@@ -6227,7 +6266,7 @@ bool QVkSwapChain::ensureSurface()
rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev, surface, &formatCount, formats.data());
const bool srgbRequested = m_flags.testFlag(sRGB);
- for (quint32 i = 0; i < formatCount; ++i) {
+ for (int i = 0; i < int(formatCount); ++i) {
if (formats[i].format != VK_FORMAT_UNDEFINED && srgbRequested == isSrgbFormat(formats[i].format)) {
colorFormat = formats[i].format;
colorSpace = formats[i].colorSpace;
@@ -6288,7 +6327,7 @@ bool QVkSwapChain::buildOrResize()
Q_ASSERT(rtWrapper.d.rp && rtWrapper.d.rp->rp);
rtWrapper.d.pixelSize = pixelSize;
- rtWrapper.d.dpr = window->devicePixelRatio();
+ rtWrapper.d.dpr = float(window->devicePixelRatio());
rtWrapper.d.sampleCount = samples;
rtWrapper.d.colorAttCount = 1;
if (m_depthStencil) {
@@ -6315,10 +6354,10 @@ bool QVkSwapChain::buildOrResize()
memset(&fbInfo, 0, sizeof(fbInfo));
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbInfo.renderPass = rtWrapper.d.rp->rp;
- fbInfo.attachmentCount = rtWrapper.d.colorAttCount + rtWrapper.d.dsAttCount + rtWrapper.d.resolveAttCount;
+ fbInfo.attachmentCount = uint32_t(rtWrapper.d.colorAttCount + rtWrapper.d.dsAttCount + rtWrapper.d.resolveAttCount);
fbInfo.pAttachments = views;
- fbInfo.width = pixelSize.width();
- fbInfo.height = pixelSize.height();
+ fbInfo.width = uint32_t(pixelSize.width());
+ fbInfo.height = uint32_t(pixelSize.height());
fbInfo.layers = 1;
VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo, nullptr, &image.fb);
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index 962a1b8eb7..a390bc3707 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -711,7 +711,9 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
+ void releaseCachedResources() override;
+ bool isDeviceLost() const override;
VkResult createDescriptorPool(VkDescriptorPool *pool);
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex);
@@ -803,6 +805,7 @@ public:
VkDeviceSize ubufAlign;
VkDeviceSize texbufAlign;
bool hasWideLines = false;
+ bool deviceLost = false;
bool debugMarkersAvailable = false;
bool vertexAttribDivisorAvailable = false;
diff --git a/src/gui/rhi/tdr.hlsl b/src/gui/rhi/tdr.hlsl
new file mode 100644
index 0000000000..f79de91c4a
--- /dev/null
+++ b/src/gui/rhi/tdr.hlsl
@@ -0,0 +1,9 @@
+RWBuffer<uint> uav;
+cbuffer ConstantBuffer { uint zero; }
+
+[numthreads(256, 1, 1)]
+void killDeviceByTimingOut(uint3 id: SV_DispatchThreadID)
+{
+ while (zero == 0)
+ uav[id.x] = zero;
+}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index c80617f929..3652a180a8 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2067,8 +2067,9 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\enum QTextDocument::ResourceType
This enum describes the types of resources that can be loaded by
- QTextDocument's loadResource() function.
+ QTextDocument's loadResource() function or by QTextBrowser::setSource().
+ \value UnknownResource No resource is loaded, or the resource type is not known.
\value HtmlResource The resource contains HTML.
\value ImageResource The resource contains image data.
Currently supported data types are QVariant::Pixmap and
@@ -2082,7 +2083,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
\value UserResource The first available value for user defined
resource types.
- \sa loadResource()
+ \sa loadResource(), QTextBrowser::sourceType()
*/
/*!
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c267ade0c2..b37353bf2c 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -399,6 +399,7 @@ struct QBidiAlgorithm {
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
runHasContent = true;
lastRunWithContent = -1;
+ ++isolatePairPosition;
}
int runBeforeIsolate = runs.size();
ushort newLevel = isRtl ? ((stack.top().level + 1) | 1) : ((stack.top().level + 2) & ~1);
@@ -440,21 +441,19 @@ struct QBidiAlgorithm {
doEmbed(true, true, false);
break;
case QChar::DirLRI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(false, false, true);
- ++isolatePairPosition;
break;
case QChar::DirRLI:
- Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(true, false, true);
- ++isolatePairPosition;
break;
case QChar::DirFSI: {
- const auto &pair = isolatePairs.at(isolatePairPosition);
- Q_ASSERT(pair.start == i);
- bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ bool isRtl = false;
+ if (isolatePairPosition < isolatePairs.size()) {
+ const auto &pair = isolatePairs.at(isolatePairPosition);
+ Q_ASSERT(pair.start == i);
+ isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
+ }
doEmbed(isRtl, false, true);
- ++isolatePairPosition;
break;
}
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 47a38db3ad..e3bd49a15e 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -650,6 +650,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value TableColumns
\value TableColumnWidthConstraints
\value TableHeaderRowCount
+ \value TableBorderCollapse Specifies the \l QTextTableFormat::borderCollapse property.
Table cell properties
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp
index a32bccfd09..bd4318d4e9 100644
--- a/src/network/access/qhttp2configuration.cpp
+++ b/src/network/access/qhttp2configuration.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QHttp2Configuration
- \brief The QHttp2Configuration class controls HTTP/2 parameters and settings
+ \brief The QHttp2Configuration class controls HTTP/2 parameters and settings.
\since 5.14
\reentrant
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index c1053882af..9bf5547f15 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -58,6 +58,8 @@
#include <QtNetwork/qnetworkproxy.h>
#endif
+#include <qcoreapplication.h>
+
#include <algorithm>
#include <vector>
@@ -195,6 +197,29 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
}
}
+void QHttp2ProtocolHandler::handleConnectionClosure()
+{
+ // The channel has just received RemoteHostClosedError and since it will
+ // not try (for HTTP/2) to re-connect, it's time to finish all replies
+ // with error.
+
+ // Maybe we still have some data to read and can successfully finish
+ // a stream/request?
+ _q_receiveReply();
+
+ // Finish all still active streams. If we previously had GOAWAY frame,
+ // we probably already closed some (or all) streams with ContentReSend
+ // error, but for those still active, not having any data to finish,
+ // we now report RemoteHostClosedError.
+ const auto errorString = QCoreApplication::translate("QHttp", "Connection closed");
+ for (auto it = activeStreams.begin(), eIt = activeStreams.end(); it != eIt; ++it)
+ finishStreamWithError(it.value(), QNetworkReply::RemoteHostClosedError, errorString);
+
+ // Make sure we'll never try to read anything later:
+ activeStreams.clear();
+ goingAway = true;
+}
+
void QHttp2ProtocolHandler::_q_uploadDataReadyRead()
{
if (!sender()) // QueuedConnection, firing after sender (byte device) was deleted.
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index 1943827e23..43fdb136cd 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -92,6 +92,8 @@ public:
QHttp2ProtocolHandler &operator = (const QHttp2ProtocolHandler &rhs) = delete;
QHttp2ProtocolHandler &operator = (QHttp2ProtocolHandler &&rhs) = delete;
+ Q_INVOKABLE void handleConnectionClosure();
+
private slots:
void _q_uploadDataReadyRead();
void _q_replyDestroyed(QObject* reply);
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 13be1aa6b5..21c6359807 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -1235,7 +1235,8 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
} else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
- || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) {
+ || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
// emit error for all replies
QHttpNetworkReply *currentReply = spdyPair.second;
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 716ea6c8b2..39f392a79b 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -854,8 +854,11 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
state = QHttpNetworkConnectionChannel::IdleState;
-
- requeueCurrentlyPipelinedRequests();
+ if (alreadyPipelinedRequests.length()) {
+ // If nothing was in a pipeline, no need in calling
+ // _q_startNextRequest (which it does):
+ requeueCurrentlyPipelinedRequests();
+ }
pendingEncrypt = false;
}
@@ -977,7 +980,18 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (!reply && state == QHttpNetworkConnectionChannel::IdleState) {
// Not actually an error, it is normal for Keep-Alive connections to close after some time if no request
// is sent on them. No need to error the other replies below. Just bail out here.
- // The _q_disconnected will handle the possibly pipelined replies
+ // The _q_disconnected will handle the possibly pipelined replies. HTTP/2 is special for now,
+ // we do not resend, but must report errors if any request is in progress (note, while
+ // not in its sendRequest(), protocol handler switches the channel to IdleState, thus
+ // this check is under this condition in 'if'):
+ if (protocolHandler.data()) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
+ auto h2Handler = static_cast<QHttp2ProtocolHandler *>(protocolHandler.data());
+ h2Handler->handleConnectionClosure();
+ protocolHandler.reset();
+ }
+ }
return;
} else if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) {
// Try to reconnect/resend before sending an error.
@@ -1094,6 +1108,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|| !connection->d_func()->lowPriorityQueue.isEmpty());
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#ifndef QT_NO_SSL
|| connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 1900397eab..63a3c4f204 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -297,6 +297,11 @@ void QHttpThreadDelegate::startRequest()
connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
}
+#if QT_CONFIG(ssl)
+ // See qnetworkreplyhttpimpl, delegate's initialization code.
+ Q_ASSERT(!ssl || incomingSslConfiguration.data());
+#endif // QT_CONFIG(ssl)
+
const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
if (isH2) {
#if QT_CONFIG(ssl)
@@ -316,9 +321,6 @@ void QHttpThreadDelegate::startRequest()
}
#ifndef QT_NO_SSL
- if (ssl && !incomingSslConfiguration.data())
- incomingSslConfiguration.reset(new QSslConfiguration);
-
if (!isH2 && httpRequest.isSPDYAllowed() && ssl) {
connectionType = QHttpNetworkConnection::ConnectionTypeSPDY;
urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 118fb6b1fb..cedb1597de 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -277,23 +277,30 @@ QT_BEGIN_NAMESPACE
Indicates whether the QNetworkAccessManager code is
allowed to use SPDY with this request. This applies only
to SSL requests, and depends on the server supporting SPDY.
+ Obsolete, use Http2 instead of Spdy.
\value SpdyWasUsedAttribute
Replies only, type: QMetaType::Bool
Indicates whether SPDY was used for receiving
- this reply.
+ this reply. Obsolete, use Http2 instead of Spdy.
- \value HTTP2AllowedAttribute
+ \value Http2AllowedAttribute
Requests only, type: QMetaType::Bool (default: false)
Indicates whether the QNetworkAccessManager code is
allowed to use HTTP/2 with this request. This applies
to SSL requests or 'cleartext' HTTP/2.
- \value HTTP2WasUsedAttribute
+ \value Http2WasUsedAttribute
Replies only, type: QMetaType::Bool (default: false)
Indicates whether HTTP/2 was used for receiving this reply.
(This value was introduced in 5.9.)
+ \value HTTP2AllowedAttribute
+ Obsolete alias for Http2AllowedAttribute.
+
+ \value HTTP2WasUsedAttribute
+ Obsolete alias for Http2WasUsedAttribute.
+
\value EmitAllUploadProgressSignalsAttribute
Requests only, type: QMetaType::Bool (default: false)
Indicates whether all upload signals should be emitted.
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index e09ff8aaae..72a6555d91 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -89,12 +89,18 @@ public:
DownloadBufferAttribute, // internal
SynchronousRequestAttribute, // internal
BackgroundRequestAttribute,
+#if QT_DEPRECATED_SINCE(5, 15)
SpdyAllowedAttribute,
SpdyWasUsedAttribute,
- EmitAllUploadProgressSignalsAttribute,
+#endif // QT_DEPRECATED_SINCE(5, 15)
+ EmitAllUploadProgressSignalsAttribute = BackgroundRequestAttribute + 3,
FollowRedirectsAttribute,
- HTTP2AllowedAttribute,
- HTTP2WasUsedAttribute,
+ Http2AllowedAttribute,
+ Http2WasUsedAttribute,
+#if QT_DEPRECATED_SINCE(5, 15)
+ HTTP2AllowedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2AllowedAttribute") = Http2AllowedAttribute,
+ HTTP2WasUsedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2WasUsedAttribute"),
+#endif // QT_DEPRECATED_SINCE(5, 15)
OriginalContentLengthAttribute,
RedirectPolicyAttribute,
Http2DirectAttribute,
diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp
index a010df8e3a..1566e7f914 100644
--- a/src/network/kernel/qnetconmonitor_win.cpp
+++ b/src/network/kernel/qnetconmonitor_win.cpp
@@ -103,7 +103,7 @@ class QNetworkConnectionEvents : public INetworkConnectionEvents
{
public:
QNetworkConnectionEvents(QNetworkConnectionMonitorPrivate *monitor);
- ~QNetworkConnectionEvents();
+ virtual ~QNetworkConnectionEvents();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
@@ -471,7 +471,7 @@ class QNetworkListManagerEvents : public INetworkListManagerEvents
{
public:
QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor);
- ~QNetworkListManagerEvents();
+ virtual ~QNetworkListManagerEvents();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ca6c58117d..e302aa1761 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1512,7 +1512,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index 28be4f2e79..1d935c5217 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -143,13 +143,12 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
if (!s_loadRootCertsOnDemand)
setDefaultCaCertificates(systemCaCertificates());
#ifdef Q_OS_WIN
- //Enabled for fetching additional root certs from windows update on windows 6+
+ //Enabled for fetching additional root certs from windows update on windows.
//This flag is set false by setDefaultCaCertificates() indicating the app uses
//its own cert bundle rather than the system one.
//Same logic that disables the unix on demand cert loading.
//Unlike unix, we do preload the certificates from the cert store.
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::WindowsVista)
- s_loadRootCertsOnDemand = true;
+ s_loadRootCertsOnDemand = true;
#endif
}
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index 1db26ee9a1..d7fb080b49 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -828,12 +828,17 @@ bool QSslSocketBackendPrivate::acceptContext()
&expiry // ptsTimeStamp
);
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ // Need more data
+ return true;
+ }
+
if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
// https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
// inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
// be stored.
intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
- } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
+ } else { /* No 'extra' data, message not incomplete */
intermediateBuffer.clear();
}
@@ -1069,7 +1074,6 @@ bool QSslSocketBackendPrivate::verifyHandshake()
}
schannelState = SchannelState::Done;
- peerCertVerified = true;
return true;
}
@@ -1152,7 +1156,6 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
- peerCertVerified = false;
renegotiating = false;
}
@@ -1315,7 +1318,9 @@ void QSslSocketBackendPrivate::transmit()
#endif
intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
}
- } else if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ }
+
+ if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data before we can decrypt.. to the buffer it goes!
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
@@ -1360,6 +1365,7 @@ void QSslSocketBackendPrivate::transmit()
#endif
schannelState = SchannelState::Renegotiate;
renegotiating = true;
+
// We need to call 'continueHandshake' or else there's no guarantee it ever gets called
continueHandshake();
break;
@@ -1525,7 +1531,7 @@ void QSslSocketBackendPrivate::continueHandshake()
case SchannelState::VerifyHandshake:
// if we're in shutdown or renegotiating then we might not need to verify
// (since we already did)
- if (!peerCertVerified && !verifyHandshake()) {
+ if (!verifyHandshake()) {
shutdown = true; // Skip sending shutdown alert
q->abort(); // We don't want to send buffered data
disconnectFromHost();
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 9879e2fc60..6ab200e1f9 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -147,7 +147,6 @@ private:
ULONG contextAttributes = 0;
bool renegotiating = false;
- bool peerCertVerified = false;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 047773d8e3..a52e157768 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -100,20 +100,6 @@ static const char *languageForWritingSystem[] = {
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-#ifdef Q_OS_OSX
-static NSInteger languageMapSort(id obj1, id obj2, void *context)
-{
- NSArray<NSString *> *map1 = reinterpret_cast<NSArray<NSString *> *>(obj1);
- NSArray<NSString *> *map2 = reinterpret_cast<NSArray<NSString *> *>(obj2);
- NSArray<NSString *> *languages = reinterpret_cast<NSArray<NSString *> *>(context);
-
- NSString *lang1 = [map1 objectAtIndex:0];
- NSString *lang2 = [map2 objectAtIndex:0];
-
- return [languages indexOfObject:lang1] - [languages indexOfObject:lang2];
-}
-#endif
-
QCoreTextFontDatabase::QCoreTextFontDatabase()
: m_hasPopulatedAliases(false)
{
@@ -406,142 +392,99 @@ template class QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>;
template class QCoreTextFontDatabaseEngineFactory<QFontEngineFT>;
#endif
-QFont::StyleHint styleHintFromNSString(NSString *style)
+QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family)
{
- if ([style isEqual: @"sans-serif"])
- return QFont::SansSerif;
- else if ([style isEqual: @"monospace"])
- return QFont::Monospace;
- else if ([style isEqual: @"cursive"])
- return QFont::Cursive;
- else if ([style isEqual: @"serif"])
- return QFont::Serif;
- else if ([style isEqual: @"fantasy"])
- return QFont::Fantasy;
- else // if ([style isEqual: @"default"])
- return QFont::AnyStyle;
-}
+ if (family.isEmpty())
+ return QStringList();
-#ifdef Q_OS_OSX
-static QString familyNameFromPostScriptName(NSString *psName)
-{
- QCFType<CTFontDescriptorRef> fontDescriptor = (CTFontDescriptorRef) CTFontDescriptorCreateWithNameAndSize((CFStringRef)psName, 12.0);
- QCFString familyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute);
- QString name = QString::fromCFString(familyName);
- if (name.isEmpty())
- qWarning() << "QCoreTextFontDatabase: Failed to resolve family name for PostScript name " << QString::fromCFString((CFStringRef)psName);
+ auto attributes = @{ id(kCTFontFamilyNameAttribute): family.toNSString() };
+ QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(CFDictionaryRef(attributes));
+ if (!fontDescriptor) {
+ qWarning() << "Failed to create fallback font descriptor for" << family;
+ return QStringList();
+ }
- return name;
-}
-#endif
+ QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(fontDescriptor, 12.0, 0);
+ if (!font) {
+ qWarning() << "Failed to create fallback font for" << family;
+ return QStringList();
+ }
-static void addExtraFallbacks(QStringList *fallbackList)
-{
-#if defined(Q_OS_MACOS)
- // Since we are only returning a list of default fonts for the current language, we do not
- // cover all unicode completely. This was especially an issue for some of the common script
- // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
- // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
- // of Unicode 2.1.
- if (!fallbackList->contains(QStringLiteral("Arial Unicode MS")))
- fallbackList->append(QStringLiteral("Arial Unicode MS"));
- // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
- // add Apple Symbols to cover those too.
- if (!fallbackList->contains(QStringLiteral("Apple Symbols")))
- fallbackList->append(QStringLiteral("Apple Symbols"));
-#else
- Q_UNUSED(fallbackList)
-#endif
+ QCFType<CFArrayRef> cascadeList = CFArrayRef(CTFontCopyDefaultCascadeListForLanguages(font,
+ (CFArrayRef)[NSUserDefaults.standardUserDefaults stringArrayForKey:@"AppleLanguages"]));
+ if (!cascadeList) {
+ qWarning() << "Failed to create fallback cascade list for" << family;
+ return QStringList();
+ }
+
+ QStringList fallbackList;
+ const int numCascades = CFArrayGetCount(cascadeList);
+ for (int i = 0; i < numCascades; ++i) {
+ CTFontDescriptorRef fontFallback = CTFontDescriptorRef(CFArrayGetValueAtIndex(cascadeList, i));
+ QCFString fallbackFamilyName = CFStringRef(CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute));
+ fallbackList.append(QString::fromCFString(fallbackFamilyName));
+ }
+
+ return fallbackList;
}
QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(style);
- Q_UNUSED(script);
QMacAutoReleasePool pool;
- static QHash<QString, QStringList> fallbackLists;
-
- if (!family.isEmpty()) {
- QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(family));
- if (QCFType<CTFontDescriptorRef> fontDescriptor = CTFontDescriptorCreateWithAttributes(attributes)) {
- if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(fontDescriptor, 12.0, 0)) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
-
- QCFType<CFArrayRef> cascadeList = (CFArrayRef) CTFontCopyDefaultCascadeListForLanguages(font, (CFArrayRef) languages);
- if (cascadeList) {
- QStringList fallbackList;
- const int numCascades = CFArrayGetCount(cascadeList);
- for (int i = 0; i < numCascades; ++i) {
- CTFontDescriptorRef fontFallback = (CTFontDescriptorRef) CFArrayGetValueAtIndex(cascadeList, i);
- QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute);
- fallbackList.append(QString::fromCFString(fallbackFamilyName));
- }
-
- addExtraFallbacks(&fallbackList);
- extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
- fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
-
- return fallbackList;
+ QStringList fallbackList = fallbacksForFamily(family);
+
+ if (fallbackList.isEmpty()) {
+ // We were not able to find a fallback for the specific family,
+ // or the family was empty, so we fall back to the style hint.
+ QString styleFamily = [styleHint]{
+ switch (styleHint) {
+ case QFont::SansSerif: return QStringLiteral("Helvetica");
+ case QFont::Serif: return QStringLiteral("Times New Roman");
+ case QFont::Monospace: return QStringLiteral("Menlo");
+#ifdef Q_OS_MACOS
+ case QFont::Cursive: return QStringLiteral("Apple Chancery");
+#endif
+ case QFont::Fantasy: return QStringLiteral("Zapfino");
+ case QFont::TypeWriter: return QStringLiteral("American Typewriter");
+ case QFont::AnyStyle: Q_FALLTHROUGH();
+ case QFont::System: {
+ QCFType<CTFontRef> font = CTFontCreateUIFontForLanguage(kCTFontUIFontSystem, 12.0, NULL);
+ return static_cast<QString>(QCFString(CTFontCopyFullName(font)));
}
+ default: return QString(); // No matching font on this platform
}
+ }();
+ if (!styleFamily.isEmpty()) {
+ fallbackList = fallbacksForFamily(styleFamily);
+ if (!fallbackList.contains(styleFamily))
+ fallbackList.prepend(styleFamily);
}
}
- // We were not able to find a fallback for the specific family,
- // so we fall back to the stylehint.
-
- static const QString styleLookupKey = QString::fromLatin1(".QFontStyleHint_%1");
-
- static bool didPopulateStyleFallbacks = false;
- if (!didPopulateStyleFallbacks) {
-#if defined(Q_OS_MACX)
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray<NSString *> *languages = [defaults stringArrayForKey:@"AppleLanguages"];
-
- NSDictionary<NSString *, id> *fallbackDict = [NSDictionary<NSString *, id> dictionaryWithContentsOfFile:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
-
- for (NSString *style in [fallbackDict allKeys]) {
- NSArray *list = [fallbackDict valueForKey:style];
- QFont::StyleHint fallbackStyleHint = styleHintFromNSString(style);
- QStringList fallbackList;
- for (id item in list) {
- // sort the array based on system language preferences
- if ([item isKindOfClass:[NSArray class]]) {
- NSArray *langs = [reinterpret_cast<NSArray *>(item)
- sortedArrayUsingFunction:languageMapSort context:languages];
- for (NSArray<NSString *> *map in langs)
- fallbackList.append(familyNameFromPostScriptName([map objectAtIndex:1]));
- }
- else if ([item isKindOfClass: [NSString class]])
- fallbackList.append(familyNameFromPostScriptName(item));
- }
-
- fallbackList.append(QLatin1String("Apple Color Emoji"));
+ if (fallbackList.isEmpty())
+ return fallbackList;
- addExtraFallbacks(&fallbackList);
- fallbackLists[styleLookupKey.arg(fallbackStyleHint)] = fallbackList;
- }
-#else
- QStringList staticFallbackList;
- staticFallbackList << QString::fromLatin1("Helvetica,Apple Color Emoji,Geeza Pro,Arial Hebrew,Thonburi,Kailasa"
- "Hiragino Kaku Gothic ProN,.Heiti J,Apple SD Gothic Neo,.Heiti K,Heiti SC,Heiti TC"
- "Bangla Sangam MN,Devanagari Sangam MN,Gujarati Sangam MN,Gurmukhi MN,Kannada Sangam MN"
- "Malayalam Sangam MN,Oriya Sangam MN,Sinhala Sangam MN,Tamil Sangam MN,Telugu Sangam MN"
- "Euphemia UCAS,.PhoneFallback").split(QLatin1String(","));
-
- for (int i = QFont::Helvetica; i <= QFont::Fantasy; ++i)
- fallbackLists[styleLookupKey.arg(i)] = staticFallbackList;
+#if defined(Q_OS_MACOS)
+ // Since we are only returning a list of default fonts for the current language, we do not
+ // cover all Unicode completely. This was especially an issue for some of the common script
+ // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
+ // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
+ // of Unicode 2.1.
+ if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
+ fallbackList.append(QStringLiteral("Arial Unicode MS"));
+ // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
+ // add Apple Symbols to cover those too.
+ if (!fallbackList.contains(QStringLiteral("Apple Symbols")))
+ fallbackList.append(QStringLiteral("Apple Symbols"));
#endif
- didPopulateStyleFallbacks = true;
- }
+ extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
+ fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
- Q_ASSERT(!fallbackLists.isEmpty());
- return fallbackLists[styleLookupKey.arg(styleHint)];
+ return fallbackList;
}
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 05f6ed641c..45e74b99be 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -92,6 +92,7 @@ protected:
private:
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
+ static QStringList fallbacksForFamily(const QString &family);
mutable QString defaultFontName;
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 737d85d5c3..a6e5c9b5ab 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -535,7 +535,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_currentData.state = Qt::TouchPointReleased;
if (m_typeB)
m_contacts[m_currentSlot].maj = m_currentData.maj;
- } else if (data->code == ABS_PRESSURE) {
+ } else if (data->code == ABS_PRESSURE || data->code == ABS_MT_PRESSURE) {
m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max);
if (m_typeB || m_singleTouch)
m_contacts[m_currentSlot].pressure = m_currentData.pressure;
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index 78632a9bea..346df84038 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -93,7 +93,3 @@ qtConfig(vulkan) {
PLUGIN_TYPE = platforms
load(qt_plugin)
-
-#Non-standard install directory, QTBUG-29859
-DESTDIR = $$DESTDIR/android
-target.path = $${target.path}/android
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 9b6dc94d33..cb25bd7d81 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -52,6 +52,8 @@
@property (class, strong, readonly) NSColor *unemphasizedSelectedTextColor NS_AVAILABLE_MAC(10_14);
@property (class, strong, readonly) NSColor *unemphasizedSelectedContentBackgroundColor NS_AVAILABLE_MAC(10_14);
@property (class, strong, readonly) NSArray<NSColor *> *alternatingContentBackgroundColors NS_AVAILABLE_MAC(10_14);
+// Missing from non-Mojave SDKs, even if introduced in 10.10
+@property (class, strong, readonly) NSColor *linkColor NS_AVAILABLE_MAC(10_10);
@end
#endif
@@ -111,6 +113,8 @@ QPalette * qt_mac_createSystemPalette()
palette->setBrush(QPalette::ToolTipBase, qt_mac_toQBrush([NSColor controlColor]));
+ palette->setColor(QPalette::Normal, QPalette::Link, qt_mac_toQColor([NSColor linkColor]));
+
return palette;
}
diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm
index 37e972dba9..41b96b2df6 100644
--- a/src/plugins/platforms/cocoa/qnsview_dragging.mm
+++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm
@@ -270,6 +270,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
// The drag was started from within the application
response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(),
point, qtAllowed, buttons, modifiers);
+ nativeDrag->setAcceptedAction(response.acceptedAction());
} else {
QCocoaDropData mimeData(sender.draggingPasteboard);
response = QWindowSystemInterface::handleDrop(target, &mimeData,
@@ -282,6 +283,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
{
Q_UNUSED(session);
Q_UNUSED(screenPoint);
+ Q_UNUSED(operation);
if (!m_platformWindow)
return;
@@ -290,8 +292,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
if (!target)
return;
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
+ QCocoaIntegration::instance()->drag();
// Qt starts drag-and-drop on a mouse button press event. Cococa in
// this case won't send the matching release event, so we have to
diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm
index 68cb270457..6b4e110af2 100644
--- a/src/plugins/platforms/cocoa/qnswindow.mm
+++ b/src/plugins/platforms/cocoa/qnswindow.mm
@@ -255,8 +255,8 @@ static bool isMouseEvent(NSEvent *ev)
- (NSColor *)backgroundColor
{
- return self.styleMask & NSWindowStyleMaskTexturedBackground ?
- [super backgroundColor] : [NSColor clearColor];
+ return self.styleMask == NSWindowStyleMaskBorderless ?
+ [NSColor clearColor] : [super backgroundColor];
}
- (void)sendEvent:(NSEvent*)theEvent
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index 89c2e89f58..8768f9dd8c 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -59,6 +59,8 @@
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/private/qinputdevicemanager_p.h>
+#include <QtCore/qvector.h>
+
QT_BEGIN_NAMESPACE
class QOpenGLShaderProgram;
@@ -143,7 +145,7 @@ private:
int cursorsPerRow;
int width, height; // width and height of the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
- QList<QPoint> hotSpots;
+ QVector<QPoint> hotSpots;
QImage image; // valid until it's uploaded
} m_cursorAtlas;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
index c96dd585d3..d47b579238 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
@@ -41,7 +41,7 @@
#define QEGLFSKMSGBMCURSOR_H
#include <qpa/qplatformcursor.h>
-#include <QtCore/QList>
+#include <QtCore/QVector>
#include <QtGui/QImage>
#include <QtGui/private/qinputdevicemanager_p.h>
@@ -110,7 +110,7 @@ private:
int cursorsPerRow;
int width, height; // width and height of the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
- QList<QPoint> hotSpots;
+ QVector<QPoint> hotSpots;
QImage image;
} m_cursorAtlas;
};
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index dcdf9a5622..3591b2c505 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -196,6 +196,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists"));
wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers"));
wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat"));
+ wglDescribePixelFormat = reinterpret_cast<int (WINAPI *)(HDC, int, UINT, PIXELFORMATDESCRIPTOR *)>(resolve("wglDescribePixelFormat"));
glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
@@ -214,6 +215,11 @@ BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRI
return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
}
+int QWindowsOpengl32DLL::describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd)
+{
+ return moduleIsNotOpengl32() ? wglDescribePixelFormat(dc, pf, size, pfd) : DescribePixelFormat(dc, pf, size, pfd);
+}
+
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
{
return new QWindowsGLContext(this, context);
@@ -322,11 +328,11 @@ static inline bool
static void describeFormats(HDC hdc)
{
- const int pfiMax = DescribePixelFormat(hdc, 0, 0, nullptr);
+ const int pfiMax = QOpenGLStaticContext::opengl32.describePixelFormat(hdc, 0, 0, nullptr);
for (int i = 1; i <= pfiMax; i++) {
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
- DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -617,7 +623,7 @@ static int choosePixelFormat(HDC hdc,
// Verify if format is acceptable. Note that the returned
// formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
initPixelFormatDescriptor(obtainedPfd);
- DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
<< " not acceptable=" << *obtainedPfd;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 1abe2eb390..e962af39c2 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -107,6 +107,7 @@ struct QWindowsOpengl32DLL
// Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc.
BOOL swapBuffers(HDC dc);
BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
// WGL
HGLRC (WINAPI * wglCreateContext)(HDC dc);
@@ -130,6 +131,7 @@ private:
// For Mesa llvmpipe shipped with a name other than opengl32.dll
BOOL (WINAPI * wglSwapBuffers)(HDC dc);
BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int (WINAPI * wglDescribePixelFormat)(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
};
class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index afc1991e2c..63ecbfe0ea 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qstandardpaths.h>
+#include <QtCore/qlibrary.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qhash.h>
@@ -57,6 +58,8 @@
#include <QtCore/qt_windows.h>
#include <private/qsystemlibrary_p.h>
#include <d3d9.h>
+#include <d3d10.h>
+#include <dxgi.h>
QT_BEGIN_NAMESPACE
@@ -80,52 +83,259 @@ static GpuDescription adapterIdentifierToGpuDescription(const D3DADAPTER_IDENTIF
return result;
}
-class QDirect3D9Handle
+class QGraphicsAdapterInfo
{
public:
- Q_DISABLE_COPY_MOVE(QDirect3D9Handle)
+ Q_DISABLE_COPY_MOVE(QGraphicsAdapterInfo)
- QDirect3D9Handle();
- ~QDirect3D9Handle();
+ QGraphicsAdapterInfo();
+ ~QGraphicsAdapterInfo();
- bool isValid() const { return m_direct3D9 != nullptr; }
+ bool isValid() const;
- UINT adapterCount() const { return m_direct3D9 ? m_direct3D9->GetAdapterCount() : 0u; }
+ UINT adapterCount() const;
bool retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const;
private:
+ QSystemLibrary m_dxgilib;
+ IDXGIFactory1 *m_dxgiFactory1 = nullptr;
+
QSystemLibrary m_d3d9lib;
IDirect3D9 *m_direct3D9 = nullptr;
+
+ /* This is a value from the DXGI_ADAPTER_FLAG enum.
+ * However, it's not available in dxgi.h from MinGW,
+ * so define it here in any case. */
+ enum { DXGI_ADAPTER_FLAG_SOFTWARE = 2 };
+
+ UINT adapterCountDXGI() const;
+ bool retrieveAdapterIdentifierDXGI(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const;
+
+ UINT adapterCountD3D9() const;
+ bool retrieveAdapterIdentifierD3D9(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const;
};
-QDirect3D9Handle::QDirect3D9Handle() :
+QGraphicsAdapterInfo::QGraphicsAdapterInfo() :
+ m_dxgilib(QStringLiteral("dxgi")),
m_d3d9lib(QStringLiteral("d3d9"))
{
- using PtrDirect3DCreate9 = IDirect3D9 *(WINAPI *)(UINT);
+ using PtrCreateDXGIFactory1 = HRESULT (WINAPI *)(REFIID, void**);
- if (m_d3d9lib.load()) {
- if (auto direct3DCreate9 = (PtrDirect3DCreate9)m_d3d9lib.resolve("Direct3DCreate9"))
- m_direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
+ if (m_dxgilib.load()) {
+ if (auto createDXGIFactory1 = (PtrCreateDXGIFactory1)m_dxgilib.resolve("CreateDXGIFactory1"))
+ createDXGIFactory1(IID_PPV_ARGS(&m_dxgiFactory1));
+ }
+
+ if (!m_dxgiFactory1) {
+ using PtrDirect3DCreate9 = IDirect3D9 *(WINAPI *)(UINT);
+
+ if (m_d3d9lib.load()) {
+ if (auto direct3DCreate9 = (PtrDirect3DCreate9)m_d3d9lib.resolve("Direct3DCreate9"))
+ m_direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
+ }
}
}
-QDirect3D9Handle::~QDirect3D9Handle()
+QGraphicsAdapterInfo::~QGraphicsAdapterInfo()
{
+ if (m_dxgiFactory1)
+ m_dxgiFactory1->Release();
if (m_direct3D9)
m_direct3D9->Release();
}
-bool QDirect3D9Handle::retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
+bool QGraphicsAdapterInfo::isValid() const
+{
+ return m_dxgiFactory1 != nullptr || m_direct3D9 != nullptr;
+}
+
+UINT QGraphicsAdapterInfo::adapterCount() const
+{
+ if (m_dxgiFactory1)
+ return adapterCountDXGI();
+ if (m_direct3D9)
+ return adapterCountD3D9();
+ return 0;
+}
+
+bool QGraphicsAdapterInfo::retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
+{
+ if (m_dxgiFactory1)
+ return retrieveAdapterIdentifierDXGI(n, adapterIdentifier);
+ if (m_direct3D9)
+ return retrieveAdapterIdentifierD3D9(n, adapterIdentifier);
+ return false;
+}
+
+UINT QGraphicsAdapterInfo::adapterCountDXGI() const
+{
+ /* DXGI doesn't have an adapterCount(), instead we have to call EnumAdapters1()
+ * until DXGI_ERROR_NOT_FOUND is returned. */
+ UINT n = 0;
+
+ IDXGIAdapter1 *adapter;
+ while (SUCCEEDED(m_dxgiFactory1->EnumAdapters1(n, &adapter))) {
+ adapter->Release();
+ ++n;
+ }
+
+ return n;
+}
+
+// Detect whether we are running under 64-bit Windows.
+static bool isWow64Process()
+{
+ typedef BOOL (WINAPI *IsWow64ProcessPtr)(HANDLE hProcess, PBOOL Wow64Process);
+ IsWow64ProcessPtr IsWow64Process = (IsWow64ProcessPtr)QLibrary::resolve(
+ QStringLiteral("kernel32.dll"), "IsWow64Process");
+
+ if (IsWow64Process) {
+ BOOL IsWow64 = FALSE;
+ if (IsWow64Process(GetCurrentProcess(), &IsWow64))
+ return IsWow64;
+ }
+ return false;
+}
+
+// Read a string value from registry
+static QString regGetString(HKEY key, const wchar_t* valueName)
+{
+ QVarLengthArray<wchar_t, MAX_PATH> buf (MAX_PATH);
+ LRESULT res;
+ DWORD bufSize = buf.size() * sizeof(wchar_t);
+ res = RegGetValue(key, nullptr, valueName,
+ RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, nullptr,
+ buf.data(), &bufSize);
+ if (res == ERROR_MORE_DATA) {
+ buf.resize(bufSize / sizeof(wchar_t));
+ bufSize = buf.size() * sizeof(wchar_t);
+ res = RegGetValue(key, nullptr, valueName,
+ RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, nullptr,
+ buf.data(), &bufSize);
+ }
+ /* In case of REG_MULTI_SZ, this returns just the first string,
+ * but that is sufficient for our purposes. */
+ if (res == ERROR_SUCCESS)
+ return QString::fromWCharArray(buf.data());
+ return QString();
+}
+
+// Read driver name given a DeviceKey
+static QString retrieveDriverName(const wchar_t *driverKey)
+{
+ /* Kernel-style prefix, maps to HKLM
+ * (see https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/registry-key-object-routines) */
+ static const wchar_t prefixMappingHKLM[] = L"\\Registry\\Machine\\";
+ const size_t prefixMappingHKLMLen = wcslen(prefixMappingHKLM);
+ if (wcsnicmp(driverKey, prefixMappingHKLM, prefixMappingHKLMLen) != 0)
+ return QString();
+
+ driverKey += prefixMappingHKLMLen;
+ QString driverPath;
+ HKEY key;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, driverKey, 0, KEY_READ | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS) {
+ const wchar_t *valueName =
+ isWow64Process() ? L"UserModeDriverNameWow" : L"UserModeDriverName";
+ driverPath = regGetString(key, valueName);
+ RegCloseKey(key);
+ }
+ if (!driverPath.isEmpty()) {
+ int fileNameSep = driverPath.lastIndexOf(QLatin1Char('\\'));
+ if (fileNameSep >= 0)
+ driverPath = driverPath.mid(fileNameSep + 1);
+ return driverPath;
+ }
+ return QString();
+}
+
+// Retrieve driver name for a display device from registry.
+static QString driverNameForDevice(const wchar_t *displayDevice)
+{
+ QString driverName;
+ DISPLAY_DEVICE dd;
+ memset(&dd, 0, sizeof(dd));
+ dd.cb = sizeof(dd);
+ for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) {
+ if (wcsicmp(displayDevice, dd.DeviceName) == 0) {
+ // DeviceKey is documented as "internal", but it's a registry key in kernel format
+ driverName = retrieveDriverName(dd.DeviceKey);
+ break;
+ }
+ }
+ if (driverName.isEmpty()) {
+ /* Fall back to driver name from EnumDisplaySettings.
+ * This is only a fallback as on Windows 10 this just returns an device-independent
+ * name. OTOH, it's possible to recognize RDP connections from the driver name. */
+ DEVMODE devMode;
+ if (EnumDisplaySettings(displayDevice, ENUM_CURRENT_SETTINGS, &devMode))
+ driverName = QString::fromWCharArray(devMode.dmDeviceName);
+ }
+ return driverName;
+}
+
+bool QGraphicsAdapterInfo::retrieveAdapterIdentifierDXGI(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
+{
+ IDXGIAdapter1 *adapter;
+ if (FAILED(m_dxgiFactory1->EnumAdapters1(n, &adapter)))
+ return false;
+
+ bool result = false;
+
+ DXGI_ADAPTER_DESC1 adapterDesc;
+ if (SUCCEEDED(adapter->GetDesc1(&adapterDesc))) {
+ if ((adapterDesc.VendorId != 0) && (adapterDesc.DeviceId != 0) // Don't use adapter description of Software Devices
+ && ((adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0)) {
+ memset(adapterIdentifier, 0, sizeof(*adapterIdentifier));
+ WideCharToMultiByte(1252, 0, adapterDesc.Description, -1,
+ adapterIdentifier->Description,
+ sizeof(adapterIdentifier->Description), nullptr, nullptr);
+ adapterIdentifier->Description[sizeof(adapterIdentifier->Description) - 1] = 0;
+ adapterIdentifier->VendorId = adapterDesc.VendorId;
+ adapterIdentifier->DeviceId = adapterDesc.DeviceId;
+ adapterIdentifier->SubSysId = adapterDesc.SubSysId;
+ adapterIdentifier->Revision = adapterDesc.Revision;
+
+ LARGE_INTEGER umdVersion;
+ if (SUCCEEDED(adapter->CheckInterfaceSupport(__uuidof(ID3D10Device), &umdVersion))) {
+ adapterIdentifier->DriverVersion = umdVersion;
+ result = true;
+ }
+
+ /* DXGI doesn't expose the driver name, but we can get it from the registry.
+ * But we need a device name to follow. */
+ IDXGIOutput *output = nullptr;
+ if (SUCCEEDED(adapter->EnumOutputs (0, &output))) {
+ DXGI_OUTPUT_DESC outputDesc;
+ if (SUCCEEDED(output->GetDesc (&outputDesc))) {
+ QString driverName = driverNameForDevice(outputDesc.DeviceName);
+ qstrncpy(adapterIdentifier->Driver, driverName.toLatin1().constData(),
+ sizeof(adapterIdentifier->Driver));
+ }
+ output->Release();
+ }
+ }
+ }
+
+ adapter->Release();
+
+ return result;
+}
+
+UINT QGraphicsAdapterInfo::adapterCountD3D9() const
+{
+ return m_direct3D9->GetAdapterCount();
+}
+
+bool QGraphicsAdapterInfo::retrieveAdapterIdentifierD3D9(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
{
- return m_direct3D9
- && SUCCEEDED(m_direct3D9->GetAdapterIdentifier(n, 0, adapterIdentifier));
+ return SUCCEEDED(m_direct3D9->GetAdapterIdentifier(n, 0, adapterIdentifier));
}
GpuDescription GpuDescription::detect()
{
GpuDescription result;
- QDirect3D9Handle direct3D9;
- if (!direct3D9.isValid())
+ QGraphicsAdapterInfo adapterInfo;
+ if (!adapterInfo.isValid())
return result;
D3DADAPTER_IDENTIFIER9 adapterIdentifier;
@@ -136,7 +346,7 @@ GpuDescription GpuDescription::detect()
// and D3D uses by default. Therefore querying any additional adapters is
// futile and not useful for our purposes in general, except for
// identifying a few special cases later on.
- if (direct3D9.retrieveAdapterIdentifier(0, &adapterIdentifier)) {
+ if (adapterInfo.retrieveAdapterIdentifier(0, &adapterIdentifier)) {
result = adapterIdentifierToGpuDescription(adapterIdentifier);
isAMD = result.vendorId == VENDOR_ID_AMD;
}
@@ -145,9 +355,9 @@ GpuDescription GpuDescription::detect()
// when starting apps on a screen connected to the Intel card) by looking
// for a default AMD adapter and an additional non-AMD one.
if (isAMD) {
- const UINT adapterCount = direct3D9.adapterCount();
+ const UINT adapterCount = adapterInfo.adapterCount();
for (UINT adp = 1; adp < adapterCount; ++adp) {
- if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier)
+ if (adapterInfo.retrieveAdapterIdentifier(adp, &adapterIdentifier)
&& adapterIdentifier.VendorId != VENDOR_ID_AMD) {
// Bingo. Now figure out the display for the AMD card.
DISPLAY_DEVICE dd;
@@ -172,11 +382,11 @@ GpuDescription GpuDescription::detect()
QVector<GpuDescription> GpuDescription::detectAll()
{
QVector<GpuDescription> result;
- QDirect3D9Handle direct3D9;
- if (const UINT adapterCount = direct3D9.adapterCount()) {
+ QGraphicsAdapterInfo adapterInfo;
+ if (const UINT adapterCount = adapterInfo.adapterCount()) {
for (UINT adp = 0; adp < adapterCount; ++adp) {
D3DADAPTER_IDENTIFIER9 adapterIdentifier;
- if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier))
+ if (adapterInfo.retrieveAdapterIdentifier(adp, &adapterIdentifier))
result.append(adapterIdentifierToGpuDescription(adapterIdentifier));
}
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 8cd09a34eb..df63adf558 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -42,6 +42,7 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowscursor.h"
+#include "qwindowstheme.h"
#include <QtCore/qt_windows.h>
@@ -543,10 +544,13 @@ bool QWindowsScreenManager::handleScreenChanges()
// Look for changed monitors, add new ones
const WindowsScreenDataList newDataList = monitorData();
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
+ bool primaryScreenChanged = false;
for (const QWindowsScreenData &newData : newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
m_screens.at(existingIndex)->handleChanges(newData);
+ if (existingIndex == 0)
+ primaryScreenChanged = true;
} else {
auto *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
@@ -563,6 +567,8 @@ bool QWindowsScreenManager::handleScreenChanges()
removeScreen(i);
} // for existing screens
} // not lock screen
+ if (primaryScreenChanged)
+ QWindowsTheme::instance()->refreshFonts();
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 4e24308445..07120230ce 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -85,6 +85,8 @@ public:
static bool useNativeMenus();
+ void refreshFonts();
+
static const char *name;
private:
@@ -92,7 +94,6 @@ private:
void clearPalettes();
void refreshPalettes();
void clearFonts();
- void refreshFonts();
void refreshIconPixmapSizes();
static QWindowsTheme *m_instance;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
index 8e395669f8..d8b8f7281d 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
@@ -48,6 +48,7 @@
#include <QtGui/qaccessible.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
@@ -227,7 +228,7 @@ HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal)
return UIA_E_ELEMENTNOTAVAILABLE;
int len = textInterface->characterCount();
- QList<QRect> rectList;
+ QVarLengthArray<QRect> rectList;
if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) {
int start, end;
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 95ba961df1..7de6369541 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -12,6 +12,8 @@ LIBS += -lshlwapi -lwtsapi32
QMAKE_USE_PRIVATE += \
advapi32 \
d3d9/nolink \
+ d3d11/nolink \
+ dxgi/nolink \
ole32 \
shell32 \
user32 \
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
index 524000b618..355dbf7d20 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
if (QAccessibleInterface *table = tableCellInterface->table()) {
- **ptrElementId = idForAccessible(table);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(table);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
index e469991de2..3bd90f6850 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column
*returnValue = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
- **ptrElementId = idForAccessible(cell);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ *elementId = idForAccessible(cell);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
index 6f3ad6dcd2..0b1db306bd 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
@@ -64,6 +64,8 @@
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
using namespace QWinRTUiAutomation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen
}
// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
-HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
+HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds,
UINT32 *returnValueSize,
IIRawElementProviderSimple ***returnValue)
{
@@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q
QList<IIRawElementProviderSimple *> rawProviderList;
- for (auto elementId : qAsConst(elementIds)) {
+ for (auto elementId : elementIds) {
IIRawElementProviderSimple *rawProvider;
if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
rawProviderList.append(rawProvider);
@@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
*returnValue = nullptr;
auto accid = id();
- auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
+ auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
if (!childAcc->state().invisible)
- (*ptrChildren)->append(childId);
+ children->append(childId);
}
}
}
- delete ptrChildren;
return S_OK;
}))) {
return E_FAIL;
@@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat
ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
- for (auto childId : qAsConst(*children)) {
+ for (auto childId : *children) {
if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
IAutomationPeer *peer;
if (SUCCEEDED(provider.CopyTo(&peer)))
@@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// Scale coordinates from High DPI screens?
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() {
// Controls can be embedded within grouping elements. By default returns the innermost control.
QAccessibleInterface *target = accessibleForId(accid);
while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
@@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo
// For accessibility tools it may be better to return the text element instead of its subcomponents.
if (target->textInterface()) break;
}
- **ptrElementId = idForAccessible(target);
- QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
- delete ptrElementId;
+ *elementId = idForAccessible(target);
+ QWinRTUiaMetadataCache::instance()->load(*elementId);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
index 384a166cf7..23a6e56ae7 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
@@ -69,7 +69,7 @@ public:
virtual ~QWinRTUiaMainProvider();
static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
- static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
+ static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
static void notifyFocusChange(QAccessibleEvent *event);
static void notifyVisibilityChange(QAccessibleEvent *event);
static void notifyStateChange(QAccessibleStateChangeEvent *event);
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
index 9bc88272ba..2cb5aa685c 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer
*value = nullptr;
auto accid = id();
- auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
- auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+ auto elementId = std::make_shared<QAccessible::Id>(0);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
// Radio buttons do not require a container.
if (accessible->role() == QAccessible::ListItem) {
if (QAccessibleInterface *parent = accessible->parent()) {
if (parent->role() == QAccessible::List) {
- **ptrElementId = idForAccessible(parent);
+ *elementId = idForAccessible(parent);
}
}
}
}
- delete ptrElementId;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
index 9e61a8df61..4d825351c8 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
*value = false;
auto accid = id();
- auto selectionRequired = QSharedPointer<bool>(new bool(false));
- auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
+ auto selectionRequired = std::make_shared<bool>(false);
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() {
// Initially returns false if none are selected. After the first selection, it may be required.
bool anySelected = false;
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
@@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo
}
}
}
- **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
+ *selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
}
- delete ptrSelectionRequired;
return S_OK;
}))) {
return E_FAIL;
@@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
int childCount = accessible->childCount();
for (int i = 0; i < childCount; ++i) {
@@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur
if (childAcc->state().selected) {
QAccessible::Id childId = idForAccessible(childAcc);
QWinRTUiaMetadataCache::instance()->load(childId);
- (*ptrElementIds)->append(childId);
+ elementIds->append(childId);
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
index 1af74a8b72..7cd953de87 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
index e71ade3c1f..d763b320b1 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->columnCount(); ++i) {
@@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
@@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
*returnValue = nullptr;
auto accid = id();
- auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
- auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+ auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
for (int i = 0; i < tableInterface->rowCount(); ++i) {
@@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa
for (auto header : qAsConst(headers)) {
QAccessible::Id headerId = idForAccessible(header);
QWinRTUiaMetadataCache::instance()->load(headerId);
- (*ptrElementIds)->append(headerId);
+ elementIds->append(headerId);
}
}
}
}
}
}
- delete ptrElementIds;
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
index aa120377df..cd7420f360 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
*returnValueSize = 0;
*returnValue = nullptr;
+ struct Selection { int startOffset, endOffset; };
+
auto accid = id();
- auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
- auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
+ auto selections = std::make_shared<QVarLengthArray<Selection>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
for (int i = 0; i < textInterface->selectionCount(); ++i) {
- QPair<int,int> sel;
- textInterface->selection(i, &sel.first, &sel.second);
- (*ptrSelections)->append(sel);
+ int startOffset, endOffset;
+ textInterface->selection(i, &startOffset, &endOffset);
+ selections->append({startOffset, endOffset});
}
- if ((*ptrSelections)->size() == 0) {
+ if (selections->size() == 0) {
// If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
- QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
- (*ptrSelections)->append(sel);
+ auto cur = textInterface->cursorPosition();
+ selections->append({cur, cur});
}
}
}
- delete ptrSelections;
return S_OK;
}))) {
return E_FAIL;
@@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu
if (!providerArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < selCount; ++i) {
- ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
- textRangeProvider.CopyTo(&providerArray[i]);
+ auto dst = providerArray;
+ for (auto sel : *selections) {
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider
+ = Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset);
+ textRangeProvider.CopyTo(dst++);
}
*returnValueSize = selCount;
*returnValue = providerArray;
@@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo
const QPoint pt(screenLocation.X, screenLocation.Y);
auto accid = id();
- auto offset = QSharedPointer<int>(new int);
- auto ptrOffset = new QSharedPointer<int>(offset);
+ auto offset = std::make_shared<int>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() {
if (QAccessibleInterface *accessible = accessibleForId(accid))
if (QAccessibleTextInterface *textInterface = accessible->textInterface())
- **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
- delete ptrOffset;
+ *offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
return S_OK;
}))) {
return E_FAIL;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
index fc3778d652..ca15feaff9 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
@@ -51,6 +51,8 @@
#include <QtCore/QString>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
using namespace QWinRTUiAutomation;
@@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
auto accid = id();
auto startOffset = m_startOffset;
auto endOffset = m_endOffset;
- auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
- auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
+ auto rects = std::make_shared<QVarLengthArray<QRect>>();
- if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
int len = textInterface->characterCount();
@@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
qMin(startRect.y(), endRect.y()),
qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
- (*ptrRects)->append(lineRect);
+ rects->append(lineRect);
}
if (end >= len) break;
textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
@@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
}
}
}
- delete ptrRects;
return S_OK;
}))) {
return E_FAIL;
@@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT
if (!doubleArray)
return E_OUTOFMEMORY;
- for (int i = 0; i < rects->size(); ++i) {
- doubleArray[i*4] = (*rects)[i].left();
- doubleArray[i*4+1] = (*rects)[i].top();
- doubleArray[i*4+2] = (*rects)[i].width();
- doubleArray[i*4+3] = (*rects)[i].height();
+ DOUBLE *dst = doubleArray;
+ for (auto rect : *rects) {
+ *dst++ = rect.left();
+ *dst++ = rect.top();
+ *dst++ = rect.width();
+ *dst++ = rect.height();
}
*returnValue = doubleArray;
*returnValueSize = 4 * rects->size();
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
index 21389b74d2..255d8ee49e 100644
--- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
@@ -96,24 +96,22 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
auto accid = id();
- auto tmpValue = QSharedPointer<QString>(new QString);
- auto ptrValue = new QSharedPointer<QString>(tmpValue);
- *tmpValue = hStrToQStr(value);
+ QString tmpValue = hStrToQStr(value);
- QEventDispatcherWinRT::runOnMainThread([accid, ptrValue]() {
+ QEventDispatcherWinRT::runOnMainThread([accid, tmpValue]() {
if (QAccessibleInterface *accessible = accessibleForId(accid)) {
// First sets the value as a text.
- accessible->setText(QAccessible::Value, **ptrValue);
+ accessible->setText(QAccessible::Value, tmpValue);
// Then, if the control supports the value interface (range value)
// and the supplied text can be converted to a number, and that number
// lies within the min/max limits, sets it as the control's current (numeric) value.
if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
bool ok = false;
- double numval = (*ptrValue)->toDouble(&ok);
+ double numval = tmpValue.toDouble(&ok);
if (ok) {
double minimum = valueInterface->minimumValue().toDouble();
double maximum = valueInterface->maximumValue().toDouble();
@@ -124,7 +122,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
}
}
QWinRTUiaMetadataCache::instance()->load(accid);
- delete ptrValue;
return S_OK;
}, 0);
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 5e5fefca90..2b77062b16 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -63,6 +63,7 @@
QT_BEGIN_NAMESPACE
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+typedef const GLubyte *(*glGetStringiProc)(GLenum, GLuint);
#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
@@ -145,6 +146,27 @@ static inline QByteArray getGlString(GLenum param)
return QByteArray();
}
+static bool hasGlExtension(const QSurfaceFormat &format, const char *ext)
+{
+ if (format.majorVersion() < 3) {
+ auto exts = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ return exts && strstr(exts, ext);
+ } else {
+ auto glGetStringi = reinterpret_cast<glGetStringiProc>(
+ glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGetStringi")));
+ if (glGetStringi) {
+ GLint n = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+ for (GLint i = 0; i < n; ++i) {
+ const char *p = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+ if (p && !strcmp(p, ext))
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
static void updateFormatFromContext(QSurfaceFormat &format)
{
// Update the version, profile, and context bit of the format
@@ -163,7 +185,7 @@ static void updateFormatFromContext(QSurfaceFormat &format)
format.setOption(QSurfaceFormat::StereoBuffers);
if (format.renderableType() == QSurfaceFormat::OpenGL) {
- if (format.version() >= qMakePair(4, 0)) {
+ if (hasGlExtension(format, "GL_ARB_robustness")) {
GLint value = 0;
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &value);
if (value == GL_LOSE_CONTEXT_ON_RESET_ARB)
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 0bae45382d..28be7bdc38 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -428,12 +428,14 @@ static QVariant::Type qDecodePSQLType(int t)
void QPSQLResultPrivate::deallocatePreparedStmt()
{
- const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId;
- PGresult *result = drv_d_func()->exec(stmt);
+ if (drv_d_func()) {
+ const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId;
+ PGresult *result = drv_d_func()->exec(stmt);
- if (PQresultStatus(result) != PGRES_COMMAND_OK)
- qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
- PQclear(result);
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
+ PQclear(result);
+ }
preparedStmtId.clear();
}
diff --git a/src/plugins/styles/windowsvista/main.cpp b/src/plugins/styles/windowsvista/main.cpp
index d5048e45b7..5e7bcf5e6e 100644
--- a/src/plugins/styles/windowsvista/main.cpp
+++ b/src/plugins/styles/windowsvista/main.cpp
@@ -48,7 +48,7 @@ class QWindowsVistaStylePlugin : public QStylePlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "windowsvistastyle.json")
public:
- QStyle *create(const QString &key);
+ QStyle *create(const QString &key) override;
};
QStyle *QWindowsVistaStylePlugin::create(const QString &key)
@@ -56,7 +56,7 @@ QStyle *QWindowsVistaStylePlugin::create(const QString &key)
if (key.compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) == 0)
return new QWindowsVistaStyle();
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index c4ada66ca9..e213d65946 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -44,7 +44,6 @@
#include <qwindow.h>
#include <private/qstyleanimation_p.h>
#include <private/qstylehelper_p.h>
-#include <private/qapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
QT_BEGIN_NAMESPACE
@@ -84,15 +83,14 @@ static const int windowsRightBorder = 15; // right border on windows
*/
bool QWindowsVistaStylePrivate::useVista()
{
- return QOperatingSystemVersion::current() >= QOperatingSystemVersion::WindowsVista
- && QWindowsVistaStylePrivate::useXP();
+ return QWindowsVistaStylePrivate::useXP();
}
/* \internal
Checks and returns the style object
*/
inline QObject *styleObject(const QStyleOption *option) {
- return option ? option->styleObject : 0;
+ return option ? option->styleObject : nullptr;
}
/* \internal
@@ -117,7 +115,7 @@ static inline QImage createAnimationBuffer(const QStyleOption *option, const QWi
Used by animations to clone a styleoption and shift its offset
*/
QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) {
- QStyleOption *styleOption = 0;
+ QStyleOption *styleOption = nullptr;
if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option))
styleOption = new QStyleOptionSlider(*slider);
else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option))
@@ -298,7 +296,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
int oldState = styleObject->property("_q_stylestate").toInt();
oldRect = styleObject->property("_q_stylerect").toRect();
newRect = option->rect;
- styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylestate", int(option->state));
styleObject->setProperty("_q_stylerect", option->rect);
bool doTransition = oldState &&
@@ -316,7 +314,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (doTransition) {
QStyleOption *styleOption = clonedAnimationStyleOption(option);
- styleOption->state = (QStyle::State)oldState;
+ styleOption->state = QStyle::State(oldState);
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
@@ -341,7 +339,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
// The end state of the transition is simply the result we would have painted
// if the style was not animated.
- styleOption->styleObject = 0;
+ styleOption->styleObject = nullptr;
styleOption->state = option->state;
proxy()->drawPrimitive(element, styleOption, &endPainter, widget);
@@ -356,7 +354,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
//translate state flags to UXTHEME states :
if (element == PE_FrameLineEdit) {
- theme = OpenThemeData(0, L"Edit");
+ theme = OpenThemeData(nullptr, L"Edit");
partId = EP_EDITBORDER_NOSCROLL;
if (oldState & State_MouseOver)
@@ -374,7 +372,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
toState = ETS_NORMAL;
} else {
- theme = OpenThemeData(0, L"Button");
+ theme = OpenThemeData(nullptr, L"Button");
if (element == PE_IndicatorRadioButton)
partId = BP_RADIOBUTTON;
else if (element == PE_IndicatorCheckBox)
@@ -390,7 +388,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (theme
&& SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState,
TMT_TRANSITIONDURATIONS, &duration))) {
- t->setDuration(duration);
+ t->setDuration(int(duration));
}
t->setStartTime(QTime::currentTime());
@@ -535,7 +533,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
else if (state & State_MouseOver)
stateId = EBS_HOT;
- XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme,
+ XPThemeData theme(nullptr, painter, QWindowsXPStylePrivate::EditTheme,
partId, stateId, rect);
if (!theme.isValid()) {
QWindowsStyle::drawPrimitive(element, option, painter, widget);
@@ -582,27 +580,26 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
p->drawRect(option->rect.adjusted(0, 0, -1, -1));
p->setPen(oldPen);
return;
- } else {
- int stateId = ETS_NORMAL;
- if (!(state & State_Enabled))
- stateId = ETS_DISABLED;
- else if (state & State_ReadOnly)
- stateId = ETS_READONLY;
- else if (state & State_MouseOver)
- stateId = ETS_HOT;
- else if (state & State_HasFocus)
- stateId = ETS_SELECTED;
- XPThemeData theme(widget, painter,
- QWindowsXPStylePrivate::EditTheme,
- EP_EDITBORDER_NOSCROLL, stateId, option->rect);
- theme.noContent = true;
- painter->save();
- QRegion clipRegion = option->rect;
- clipRegion -= option->rect.adjusted(2, 2, -2, -2);
- painter->setClipRegion(clipRegion);
- d->drawBackground(theme);
- painter->restore();
}
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = ETS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter,
+ QWindowsXPStylePrivate::EditTheme,
+ EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+ theme.noContent = true;
+ painter->save();
+ QRegion clipRegion = option->rect;
+ clipRegion -= option->rect.adjusted(2, 2, -2, -2);
+ painter->setClipRegion(clipRegion);
+ d->drawBackground(theme);
+ painter->restore();
}
break;
@@ -725,7 +722,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
d->drawBackground(theme);
} else {
QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
- break;;
+ break;
}
QPixmapCache::insert(key, pixmap);
}
@@ -771,7 +768,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
case PE_Widget:
{
#if QT_CONFIG(dialogbuttonbox)
- const QDialogButtonBox *buttonBox = 0;
+ const QDialogButtonBox *buttonBox = nullptr;
if (qobject_cast<const QMessageBox *> (widget))
buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
@@ -845,7 +842,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int oldState = styleObject->property("_q_stylestate").toInt();
oldRect = styleObject->property("_q_stylerect").toRect();
newRect = option->rect;
- styleObject->setProperty("_q_stylestate", (int)option->state);
+ styleObject->setProperty("_q_stylestate", int(option->state));
styleObject->setProperty("_q_stylerect", option->rect);
bool wasDefault = false;
@@ -871,7 +868,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject);
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
QStyleOption *styleOption = clonedAnimationStyleOption(option);
- styleOption->state = (QStyle::State)oldState;
+ styleOption->state = QStyle::State(oldState);
QImage startImage = createAnimationBuffer(option, widget);
QPainter startPainter(&startImage);
@@ -893,12 +890,12 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
DWORD duration = 0;
- const HTHEME theme = OpenThemeData(0, L"Button");
+ const HTHEME theme = OpenThemeData(nullptr, L"Button");
int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
int toState = buttonStateId(option->state, BP_PUSHBUTTON);
if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- t->setDuration(duration);
+ t->setDuration(int(duration));
else
t->setDuration(0);
t->setStartTime(QTime::currentTime());
@@ -984,7 +981,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option);
@@ -993,7 +990,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
mbih = qRound(size.height());
}
}
- QRect ir = subElementRect(SE_PushButtonContents, option, 0);
+ QRect ir = subElementRect(SE_PushButtonContents, option, nullptr);
QStyleOptionButton newBtn = *btn;
newBtn.rect = QStyle::visualRect(option->direction, option->rect,
QRect(ir.right() - mbiw - 2,
@@ -1138,7 +1135,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
alignment |= Qt::TextHideMnemonic;
@@ -1178,7 +1175,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int checkcol = qRound(qreal(25) * factor);
const int gutterWidth = qRound(qreal(3) * factor);
{
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme,
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme,
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
@@ -1395,7 +1392,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
- bool isFloating = dw != 0 && dw->isFloating();
+ bool isFloating = dw && dw->isFloating();
QRect r = option->rect.adjusted(0, 2, -1, -3);
QRect titleRect = r;
@@ -1412,7 +1409,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
} else {
titleRect.adjust(mw, 0, 0, 0);
@@ -1518,8 +1515,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
int oldActiveControls = styleObject->property("_q_stylecontrols").toInt();
QRect oldRect = styleObject->property("_q_stylerect").toRect();
- styleObject->setProperty("_q_stylestate", (int)option->state);
- styleObject->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+ styleObject->setProperty("_q_stylestate", int(option->state));
+ styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls));
styleObject->setProperty("_q_stylerect", option->rect);
bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
@@ -1563,8 +1560,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
// Draw transition source
if (!anim) {
- styleOption->state = (QStyle::State)oldState;
- styleOption->activeSubControls = (QStyle::SubControl)oldActiveControls;
+ styleOption->state = QStyle::State(oldState);
+ styleOption->activeSubControls = QStyle::SubControl(oldActiveControls);
proxy()->drawComplexControl(control, styleOption, &startPainter, widget);
} else {
anim->paint(&startPainter, option);
@@ -1815,7 +1812,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
// That however breaks with QtQuickControls where this results in transparent
// spinbox background, so if there's no "widget" passed (QtQuickControls case),
// let ftheme.noContent be false, which fixes the spinbox rendering in QQC
- ftheme.noContent = (widget != NULL);
+ ftheme.noContent = (widget != nullptr);
d->drawBackground(ftheme);
}
if (sub & SC_SpinBoxUp) {
@@ -1872,7 +1869,7 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption
sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
int minimumHeight;
{
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::MenuTheme,
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
XPThemeData themeSize = theme;
@@ -1940,7 +1937,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
case SE_PushButtonContents:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
MARGINS borderSize;
- const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
+ const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"Button");
if (theme) {
int stateId = PBS_NORMAL;
if (!(option->state & State_Enabled))
@@ -1955,7 +1952,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
rect = option->rect.adjusted(border, border, -border, -border);
- if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) {
+ if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) {
rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
-borderSize.cxRightWidth, -borderSize.cyBottomHeight);
rect = visualRect(option->direction, option->rect, rect);
@@ -1973,7 +1970,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int y = option->rect.y();
int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::HeaderTheme,
HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
@@ -2046,7 +2043,7 @@ static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBa
bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- const uint flags = tb->titleBarFlags;
+ const auto flags = tb->titleBarFlags;
bool retVal = false;
switch (sc) {
case QStyle::SC_TitleBarContextHelpButton:
@@ -2104,7 +2101,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
if (option) {
if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
ret = true;
- XPThemeData themeData(widget, 0,
+ XPThemeData themeData(widget, nullptr,
QWindowsXPStylePrivate::ToolTipTheme,
TTP_STANDARD, TTSS_NORMAL, option->rect);
mask->region = d->region(themeData);
@@ -2113,7 +2110,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
break;
case SH_Table_GridLineColor:
if (option)
- ret = option->palette.color(QPalette::Base).darker(118).rgb();
+ ret = int(option->palette.color(QPalette::Base).darker(118).rgb());
else
ret = -1;
break;
@@ -2324,7 +2321,7 @@ void QWindowsVistaStyle::polish(QWidget *widget)
//we do not have to care about unpolishing
widget->setContentsMargins(3, 0, 4, 0);
COLORREF bgRef;
- HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
+ HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"TOOLTIP");
if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) {
QColor textColor = QColor::fromRgb(bgRef);
QPalette pal;
@@ -2464,7 +2461,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon,
switch(standardIcon) {
case SP_CommandLink:
{
- XPThemeData theme(0, 0,
+ XPThemeData theme(nullptr, nullptr,
QWindowsXPStylePrivate::ButtonTheme,
BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
if (theme.isValid()) {
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
index d66b17e9f8..8fef9f9927 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
@@ -162,7 +162,7 @@ class QWindowsVistaAnimation : public QBlendStyleAnimation
public:
QWindowsVistaAnimation(Type type, QObject *target) : QBlendStyleAnimation(type, target) { }
- virtual bool isUpdateNeeded() const;
+ bool isUpdateNeeded() const override;
void paint(QPainter *painter, const QStyleOption *option);
};
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index e2c5bdc924..bf80138b32 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -117,7 +117,7 @@ static inline QBackingStore *backingStoreForWidget(const QWidget *widget)
if (const QWidget *topLevel = widget->nativeParentWidget())
if (QBackingStore *topLevelBackingStore = topLevel->backingStore())
return topLevelBackingStore;
- return 0;
+ return nullptr;
}
static inline HDC hdcForWidgetBackingStore(const QWidget *widget)
@@ -127,7 +127,7 @@ static inline HDC hdcForWidgetBackingStore(const QWidget *widget)
if (nativeInterface)
return static_cast<HDC>(nativeInterface->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), backingStore));
}
- return 0;
+ return nullptr;
}
// Theme data helper ------------------------------------------------------------------------------
@@ -148,7 +148,7 @@ bool XPThemeData::isValid()
HTHEME XPThemeData::handle()
{
if (!QWindowsXPStylePrivate::useXP())
- return 0;
+ return nullptr;
if (!htheme)
htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget));
@@ -175,10 +175,10 @@ RECT XPThemeData::toRECT(const QRect &qr)
HRGN XPThemeData::mask(QWidget *widget)
{
if (!IsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
- return 0;
+ return nullptr;
HRGN hrgn;
- HDC dc = 0;
+ HDC dc = nullptr;
if (widget)
dc = hdcForWidgetBackingStore(widget);
RECT nativeRect = toRECT(rect);
@@ -188,7 +188,7 @@ HRGN XPThemeData::mask(QWidget *widget)
// QWindowsXPStylePrivate -------------------------------------------------------------------------
// Static initializations
-HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = 0;
+HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = nullptr;
HTHEME QWindowsXPStylePrivate::m_themes[NThemes];
bool QWindowsXPStylePrivate::use_xp = false;
QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
@@ -227,7 +227,7 @@ bool QWindowsXPStylePrivate::useXP(bool update)
{
if (!update)
return use_xp;
- return use_xp = IsThemeActive() && (IsAppThemed() || !QApplication::instance());
+ return use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance());
}
/* \internal
@@ -241,7 +241,7 @@ void QWindowsXPStylePrivate::init(bool force)
ref.ref();
useXP(true);
- std::fill(m_themes, m_themes + NThemes, HTHEME(0));
+ std::fill(m_themes, m_themes + NThemes, nullptr);
}
/* \internal
@@ -253,12 +253,12 @@ void QWindowsXPStylePrivate::cleanup(bool force)
if (bufferDC && nullBitmap)
SelectObject(bufferDC, nullBitmap);
DeleteObject(bufferBitmap);
- bufferBitmap = 0;
+ bufferBitmap = nullptr;
}
if(bufferDC)
DeleteDC(bufferDC);
- bufferDC = 0;
+ bufferDC = nullptr;
if (ref.deref() && !force)
return;
@@ -282,7 +282,7 @@ void QWindowsXPStylePrivate::cleanup(bool force)
static inline HWND createTreeViewHelperWindow()
{
if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) {
- void *hwnd = 0;
+ void *hwnd = nullptr;
void *wndProc = reinterpret_cast<void *>(DefWindowProc);
if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
Q_RETURN_ARG(void*, hwnd),
@@ -292,7 +292,7 @@ static inline HWND createTreeViewHelperWindow()
return reinterpret_cast<HWND>(hwnd);
}
}
- return 0;
+ return nullptr;
}
bool QWindowsXPStylePrivate::initVistaTreeViewTheming()
@@ -305,7 +305,7 @@ bool QWindowsXPStylePrivate::initVistaTreeViewTheming()
qWarning("Unable to create the treeview helper window.");
return false;
}
- if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", NULL))) {
+ if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", nullptr))) {
qErrnoWarning("SetWindowTheme() failed.");
cleanupVistaTreeViewTheming();
return false;
@@ -317,7 +317,7 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming()
{
if (m_vistaTreeViewHelper) {
DestroyWindow(m_vistaTreeViewHelper);
- m_vistaTreeViewHelper = 0;
+ m_vistaTreeViewHelper = nullptr;
}
}
@@ -328,11 +328,12 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming()
*/
void QWindowsXPStylePrivate::cleanupHandleMap()
{
- for (int i = 0; i < NThemes; ++i)
- if (m_themes[i]) {
- CloseThemeData(m_themes[i]);
- m_themes[i] = 0;
+ for (auto &theme : m_themes) {
+ if (theme) {
+ CloseThemeData(theme);
+ theme = nullptr;
}
+ }
QWindowsXPStylePrivate::cleanupVistaTreeViewTheming();
}
@@ -340,7 +341,7 @@ HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
{
if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) {
qWarning("Invalid parameters #%d, %p", theme, hwnd);
- return 0;
+ return nullptr;
}
if (!m_themes[theme]) {
const wchar_t *name = themeNames[theme];
@@ -427,16 +428,16 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
if (bufferDC && nullBitmap)
SelectObject(bufferDC, nullBitmap);
DeleteObject(bufferBitmap);
- bufferBitmap = 0;
+ bufferBitmap = nullptr;
}
w = qMax(bufferW, w);
h = qMax(bufferH, h);
if (!bufferDC) {
- HDC displayDC = GetDC(0);
+ HDC displayDC = GetDC(nullptr);
bufferDC = CreateCompatibleDC(displayDC);
- ReleaseDC(0, displayDC);
+ ReleaseDC(nullptr, displayDC);
}
// Define the header
@@ -450,22 +451,22 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
bmi.bmiHeader.biCompression = BI_RGB;
// Create the pixmap
- bufferPixels = 0;
- bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
+ bufferPixels = nullptr;
+ bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&bufferPixels), nullptr, 0);
GdiFlush();
- nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
+ nullBitmap = static_cast<HBITMAP>(SelectObject(bufferDC, bufferBitmap));
if (Q_UNLIKELY(!bufferBitmap)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h);
bufferW = 0;
bufferH = 0;
- return 0;
+ return nullptr;
}
if (Q_UNLIKELY(!bufferPixels)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h);
bufferW = 0;
bufferH = 0;
- return 0;
+ return nullptr;
}
bufferW = w;
bufferH = h;
@@ -493,7 +494,7 @@ bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
*/
QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
{
- HRGN hRgn = 0;
+ HRGN hRgn = nullptr;
const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.widget);
RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor));
if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
@@ -502,12 +503,12 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
}
HRGN dest = CreateRectRgn(0, 0, 0, 0);
- const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
+ const bool success = CombineRgn(dest, hRgn, nullptr, RGN_COPY) != ERROR;
QRegion region;
if (success) {
- int numBytes = GetRegionData(dest, 0, 0);
+ const auto numBytes = GetRegionData(dest, 0, nullptr);
if (numBytes == 0)
return QRegion();
@@ -551,7 +552,7 @@ bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
int firstAlpha = -1;
for (int y = startY; y < h/2; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<const DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
int alpha = (*buffer) >> 24;
if (firstAlpha == -1)
@@ -580,7 +581,7 @@ bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
bool hasFixedAlphaValue = false;
for (int y = startY; y < h; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
uint pixel = *buffer;
int alpha = qAlpha(pixel);
@@ -612,7 +613,7 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
// Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
for (int y = startY; y < h; ++y) {
- DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW);
for (int x = startX; x < w; ++x, ++buffer) {
if (allPixels) {
*buffer |= 0xFF000000;
@@ -668,7 +669,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
return true;
QPainter *painter = themeData.painter;
- Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
+ Q_ASSERT_X(painter != nullptr, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
if (!painter || !painter->isActive())
return false;
@@ -706,7 +707,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
}
}
- const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0);
+ const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : nullptr;
const bool result = dc
? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio)
: drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio);
@@ -740,7 +741,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
{
QPainter *painter = themeData.painter;
- const auto deviceTransform = painter->deviceTransform();
+ const auto &deviceTransform = painter->deviceTransform();
const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy());
const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect();
@@ -771,7 +772,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
| (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
const HRESULT result = DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
- SelectClipRgn(dc, 0);
+ SelectClipRgn(dc, nullptr);
DeleteObject(hrgn);
return SUCCEEDED(result);
}
@@ -1099,9 +1100,7 @@ QWindowsXPStyle::QWindowsXPStyle()
/*!
Destroys the style.
*/
-QWindowsXPStyle::~QWindowsXPStyle()
-{
-}
+QWindowsXPStyle::~QWindowsXPStyle() = default;
/*! \reimp */
void QWindowsXPStyle::unpolish(QApplication *app)
@@ -1157,7 +1156,7 @@ void QWindowsXPStyle::polish(QWidget *widget)
if (!d->hasInitColors) {
// Get text color for group box labels
COLORREF cref;
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0);
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, 0, 0);
GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
@@ -1270,7 +1269,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option,
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
MARGINS borderSize;
if (widget) {
- XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme);
+ XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme);
HTHEME theme = buttontheme.handle();
if (theme) {
int stateId;
@@ -1288,7 +1287,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option,
int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
rect = option->rect.adjusted(border, border, -border, -border);
- if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) {
+ if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) {
rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
-borderSize.cxRightWidth, -borderSize.cyBottomHeight);
rect = visualRect(option->direction, option->rect, rect);
@@ -1468,7 +1467,7 @@ case PE_Frame:
return;
themeNumber = QWindowsXPStylePrivate::ListViewTheme;
partId = LVP_LISTGROUP;
- XPThemeData theme(widget, 0, themeNumber, partId, 0);
+ XPThemeData theme(widget, nullptr, themeNumber, partId);
if (!(flags & State_Enabled))
stateId = ETS_DISABLED;
@@ -1496,9 +1495,9 @@ case PE_Frame:
p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment));
p->setPen(oldPen);
return;
- } else if (fillType == BT_NONE) {
- return;
}
+ if (fillType == BT_NONE)
+ return;
}
break;
}
@@ -1514,7 +1513,8 @@ case PE_Frame:
p->drawRect(option->rect.adjusted(0, 0, -1, -1));
p->setPen(oldPen);
return;
- } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ }
+ if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
themeNumber = QWindowsXPStylePrivate::EditTheme;
partId = EP_EDITTEXT;
noContent = true;
@@ -1538,7 +1538,7 @@ case PE_Frame:
if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) {
p->fillRect(panel->rect, panel->palette.brush(QPalette::Base));
} else {
- XPThemeData theme(0, p, themeNumber, partId, stateId, rect);
+ XPThemeData theme(nullptr, p, themeNumber, partId, stateId, rect);
if (!theme.isValid()) {
QWindowsStyle::drawPrimitive(pe, option, p, widget);
return;
@@ -1587,9 +1587,9 @@ case PE_Frame:
wchar_t themeFileName[maxlength];
wchar_t themeColor[maxlength];
// Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
- if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
- wchar_t *offset = 0;
- if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
+ if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, nullptr, 0) == S_OK) {
+ wchar_t *offset = nullptr;
+ if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != nullptr) {
offset++;
if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
useGradient = false;
@@ -1820,7 +1820,7 @@ case PE_Frame:
bef_v -= delta;
aft_h += delta;
aft_v += delta;
- XPThemeData theme(0, p, QWindowsXPStylePrivate::XpTreeViewTheme);
+ XPThemeData theme(nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme);
theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
theme.partId = TVP_GLYPH;
theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
@@ -1912,7 +1912,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
{
themeNumber = QWindowsXPStylePrivate::StatusTheme;
partId = SP_GRIPPER;
- XPThemeData theme(0, p, themeNumber, partId, 0);
+ XPThemeData theme(nullptr, p, themeNumber, partId);
QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
size.rheight()--;
if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
@@ -1980,7 +1980,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
if (btn->features & QStyleOptionButton::HasMenu) {
int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0,
+ XPThemeData theme(widget, nullptr,
QWindowsXPStylePrivate::ToolBarTheme,
TP_SPLITBUTTONDROPDOWN);
if (theme.isValid()) {
@@ -2309,7 +2309,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
if (isFloating) {
titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ if (widget != nullptr && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
} else {
titleRect.adjust(mw, 0, 0, 0);
@@ -2775,7 +2775,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
break;
v = nextInterval;
}
- if (lines.size() > 0) {
+ if (!lines.isEmpty()) {
p->save();
p->translate(slrect.topLeft());
p->drawLines(lines.constData(), lines.size());
@@ -2923,7 +2923,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
p->save();
p->setClipRect(menuarea);
tool.rect = option->rect;
- proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, nullptr);
p->restore();
}
// Draw arrow
@@ -3223,7 +3223,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
}
}
-static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = 0)
+static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = nullptr)
{
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option))
return pb->orientation;
@@ -3234,27 +3234,27 @@ int QWindowsXPStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, cons
{
switch (pm) {
case QStyle::PM_IndicatorWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width();
case QStyle::PM_IndicatorHeight:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height();
case QStyle::PM_ExclusiveIndicatorWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width();
case QStyle::PM_ExclusiveIndicatorHeight:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height();
case QStyle::PM_ProgressBarChunkWidth:
return progressBarOrientation(option) == Qt::Horizontal
- ? XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width()
- : XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height();
+ ? XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width()
+ : XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height();
case QStyle::PM_SliderThickness:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height();
case QStyle::PM_TitleBarHeight:
return widget && (widget->windowType() == Qt::Tool)
? GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME)
: GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
case QStyle::PM_MdiSubWindowFrameWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width();
case QStyle::PM_DockWidgetFrameWidth:
- return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width();
+ return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width();
default:
break;
}
@@ -3620,7 +3620,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
case CT_LineEdit:
case CT_ComboBox:
{
- XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
+ XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
if (buttontheme.isValid()) {
const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget);
const QMarginsF borderSize = buttontheme.margins() * factor;
@@ -3741,11 +3741,11 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
titleBarRect.setHeight(tbHeight);
XPThemeData themeData;
if (titlebar->titleBarState & Qt::WindowMinimized) {
- themeData = XPThemeData(widget, 0,
+ themeData = XPThemeData(widget, nullptr,
QWindowsXPStylePrivate::WindowTheme,
WP_MINCAPTION, CS_ACTIVE, titleBarRect);
} else
- themeData = XPThemeData(widget, 0,
+ themeData = XPThemeData(widget, nullptr,
QWindowsXPStylePrivate::WindowTheme,
WP_CAPTION, CS_ACTIVE, titleBarRect);
mask->region = d->region(themeData) +
@@ -3774,10 +3774,8 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
/*! \reimp */
QPalette QWindowsXPStyle::standardPalette() const
{
- if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
- return *QApplicationPrivate::sys_pal;
- else
- return QWindowsStyle::standardPalette();
+ return QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal
+ ? *QApplicationPrivate::sys_pal : QWindowsStyle::standardPalette();
}
/*!
@@ -3795,7 +3793,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (widget && widget->isWindow()) {
- XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size);
@@ -3826,9 +3824,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_MAXBUTTON, MAXBS_NORMAL);
if (theme.isValid()) {
const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
@@ -3862,7 +3860,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockClose.isNull()) {
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
@@ -3896,9 +3894,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
{
if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+ XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme,
WP_RESTOREBUTTON, RBS_NORMAL);
if (theme.isValid()) {
const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize();
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
index 60f9d7e9b7..ad7754e3d4 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
@@ -100,11 +100,11 @@ class QDebug;
class XPThemeData
{
public:
- explicit XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ explicit XPThemeData(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, const QRect &r = QRect())
- : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state),
+ : widget(w), painter(p), theme(themeIn), partId(part), stateId(state),
mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
- noContent(false), rotate(0), rect(r)
+ noContent(false), rect(r)
{}
HRGN mask(QWidget *widget);
@@ -117,17 +117,17 @@ public:
QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS);
QMarginsF margins(int propId = TMT_CONTENTMARGINS);
- static QSizeF themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0);
- static QMarginsF themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ static QSizeF themeSize(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0);
+ static QMarginsF themeMargins(const QRect &rect, const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
- static QMarginsF themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ static QMarginsF themeMargins(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1,
int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
const QWidget *widget;
QPainter *painter;
int theme;
- HTHEME htheme;
+ HTHEME htheme = nullptr;
int partId;
int stateId;
@@ -135,18 +135,18 @@ public:
uint mirrorVertically : 1;
uint noBorder : 1;
uint noContent : 1;
- uint rotate;
+ uint rotate = 0;
QRect rect;
};
struct ThemeMapKey {
- int theme;
- int partId;
- int stateId;
- bool noBorder;
- bool noContent;
+ int theme = 0;
+ int partId = -1;
+ int stateId = -1;
+ bool noBorder = false;
+ bool noContent = false;
- ThemeMapKey() : partId(-1), stateId(-1) {}
+ ThemeMapKey() = default;
ThemeMapKey(const XPThemeData &data)
: theme(data.theme), partId(data.partId), stateId(data.stateId),
noBorder(data.noBorder), noContent(data.noContent) {}
@@ -171,7 +171,7 @@ enum AlphaChannelType {
};
struct ThemeMapData {
- AlphaChannelType alphaType; // Which type of alpha on part & state
+ AlphaChannelType alphaType = UnknownAlpha; // Which type of alpha on part & state
bool dataValid : 1; // Only used to detect if hash value is ok
bool partIsTransparent : 1;
@@ -217,15 +217,13 @@ public:
};
QWindowsXPStylePrivate()
- : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
- bufferPixels(0), bufferW(0), bufferH(0)
{ init(); }
~QWindowsXPStylePrivate()
{ cleanup(); }
- static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
- static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
+ static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr);
+ static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr);
static HWND winId(const QWidget *widget);
@@ -251,10 +249,10 @@ public:
bool fixAlphaChannel(const QRect &rect);
bool swapAlphaChannel(const QRect &rect, bool allPixels = false);
- QRgb groupBoxTextColor;
- QRgb groupBoxTextColorDisabled;
- QRgb sliderTickColor;
- bool hasInitColors;
+ QRgb groupBoxTextColor = 0;
+ QRgb groupBoxTextColorDisabled = 0;
+ QRgb sliderTickColor = 0;
+ bool hasInitColors = false;
static HTHEME createTheme(int theme, HWND hwnd);
static QString themeName(int theme);
@@ -277,11 +275,12 @@ private:
static bool use_xp;
QHash<ThemeMapKey, ThemeMapData> alphaCache;
- HDC bufferDC;
- HBITMAP bufferBitmap;
- HBITMAP nullBitmap;
- uchar *bufferPixels;
- int bufferW, bufferH;
+ HDC bufferDC = nullptr;
+ HBITMAP bufferBitmap = nullptr;
+ HBITMAP nullBitmap = nullptr;
+ uchar *bufferPixels = nullptr;
+ int bufferW = 0;
+ int bufferH = 0;
static HWND m_vistaTreeViewHelper;
static HTHEME m_themes[NThemes];
@@ -292,7 +291,7 @@ inline QSizeF XPThemeData::size()
QSizeF result(0, 0);
if (isValid()) {
SIZE size;
- if (SUCCEEDED(GetThemePartSize(handle(), 0, partId, stateId, 0, TS_TRUE, &size)))
+ if (SUCCEEDED(GetThemePartSize(handle(), nullptr, partId, stateId, nullptr, TS_TRUE, &size)))
result = QSize(size.cx, size.cy);
}
return result;
@@ -304,7 +303,7 @@ inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId)
if (isValid()) {
MARGINS margins;
RECT rect = XPThemeData::toRECT(qRect);
- if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, &rect, &margins)))
+ if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, &rect, &margins)))
result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight);
}
return result;
@@ -315,7 +314,7 @@ inline QMarginsF XPThemeData::margins(int propId)
QMarginsF result(0, 0, 0 ,0);
if (isValid()) {
MARGINS margins;
- if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, NULL, &margins)))
+ if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, nullptr, &margins)))
result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight);
}
return result;
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index e9e49e0c33..a04189513a 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -57,6 +57,9 @@
#ifdef Q_OS_WIN
# include <QtCore/QVarLengthArray>
# include <qt_windows.h>
+# ifndef Q_OS_WINRT
+# include <shlobj.h>
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -837,8 +840,8 @@ QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const
{
#if defined(Q_OS_WIN)
QFileSystemNode *dirNode = node(index);
- if (!dirNode->volumeName.isNull())
- return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')');
+ if (!dirNode->volumeName.isEmpty())
+ return dirNode->volumeName;
#endif
return name(index);
}
@@ -1773,6 +1776,27 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
removeNode(parentNode, toRemove[i]);
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+static QString volumeName(const QString &path)
+{
+ IShellItem *item = nullptr;
+ const QString native = QDir::toNativeSeparators(path);
+ HRESULT hr = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
+ nullptr, IID_IShellItem,
+ reinterpret_cast<void **>(&item));
+ if (FAILED(hr))
+ return QString();
+ LPWSTR name = nullptr;
+ hr = item->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
+ if (FAILED(hr))
+ return QString();
+ QString result = QString::fromWCharArray(name);
+ CoTaskMemFree(name);
+ item->Release();
+ return result;
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
/*!
\internal
@@ -1791,15 +1815,8 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
//The parentNode is "" so we are listing the drives
- if (parentNode->fileName.isEmpty()) {
- wchar_t name[MAX_PATH + 1];
- //GetVolumeInformation requires to add trailing backslash
- const QString nodeName = fileName + QLatin1String("\\");
- BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()),
- name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0);
- if (success && name[0])
- node->volumeName = QString::fromWCharArray(name);
- }
+ if (parentNode->fileName.isEmpty())
+ node->volumeName = volumeName(fileName);
#endif
Q_ASSERT(!parentNode->children.contains(fileName));
parentNode->children.insert(fileName, node);
diff --git a/src/widgets/doc/snippets/qsplashscreen/main.cpp b/src/widgets/doc/snippets/qsplashscreen/main.cpp
index 843932ca83..2512035879 100644
--- a/src/widgets/doc/snippets/qsplashscreen/main.cpp
+++ b/src/widgets/doc/snippets/qsplashscreen/main.cpp
@@ -71,3 +71,10 @@ int main(int argc, char *argv[])
return app.exec();
}
//! [1]
+
+//! [2]
+QScreen *screen = QGuiApplication::screens().at(1);
+QPixmap pixmap(":/splash.png");
+QSplashScreen splash(screen, pixmap);
+splash.show();
+//! [2]
diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h
index e02fba69c9..1389796c3f 100644
--- a/src/widgets/graphicsview/qgraphicsview.h
+++ b/src/widgets/graphicsview/qgraphicsview.h
@@ -107,7 +107,9 @@ public:
Q_ENUM(ViewportUpdateMode)
enum OptimizationFlag {
- DontClipPainter = 0x1, // obsolete
+#if QT_DEPRECATED_SINCE(5, 14)
+ DontClipPainter Q_DECL_ENUMERATOR_DEPRECATED_X("This flag is unused") = 0x1, // obsolete
+#endif
DontSavePainterState = 0x2,
DontAdjustForAntialiasing = 0x4,
IndirectPainting = 0x8
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index 39b08dbc1e..eec65c8625 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -659,24 +659,22 @@ int QShortcut::id() const
bool QShortcut::event(QEvent *e)
{
Q_D(QShortcut);
- bool handled = false;
if (d->sc_enabled && e->type() == QEvent::Shortcut) {
auto se = static_cast<QShortcutEvent *>(e);
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
#if QT_CONFIG(whatsthis)
if (QWhatsThis::inWhatsThisMode()) {
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
- handled = true;
} else
#endif
if (se->isAmbiguous())
emit activatedAmbiguously();
else
emit activated();
- handled = true;
+ return true;
}
}
- return handled;
+ return QObject::event(e);
}
#endif // QT_NO_SHORTCUT
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 5b3efd598f..01cadd9a86 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1760,7 +1760,7 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
\value Exclusive The item is an exclusive check item (like a radio button).
\value NonExclusive The item is a non-exclusive check item (like a check box).
- \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusive
+ \sa checkType, QAction::checkable, QAction::checked, QActionGroup::exclusionPolicy
*/
/*!
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 72c803cb99..8496a2c223 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -120,10 +120,7 @@ enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
\internal
*/
-QWindowsStylePrivate::QWindowsStylePrivate()
- : alt_down(false), menuBarTimer(0)
-{
-}
+QWindowsStylePrivate::QWindowsStylePrivate() = default;
qreal QWindowsStylePrivate::appDevicePixelRatio()
{
@@ -157,7 +154,7 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
QList<QWidget *> l = widget->findChildren<QWidget *>();
auto ignorable = [](QWidget *w) {
return w->isWindow() || !w->isVisible()
- || w->style()->styleHint(SH_UnderlineShortcut, 0, w);
+ || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w);
};
l.erase(std::remove_if(l.begin(), l.end(), ignorable), l.end());
// Update states before repainting
@@ -242,7 +239,7 @@ void QWindowsStyle::polish(QApplication *app)
QCommonStyle::polish(app);
QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
// We only need the overhead when shortcuts are sometimes hidden
- if (!proxy()->styleHint(SH_UnderlineShortcut, 0) && app)
+ if (!proxy()->styleHint(SH_UnderlineShortcut, nullptr) && app)
app->installEventFilter(this);
const auto &palette = QGuiApplication::palette();
@@ -343,7 +340,6 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)
case QStyle::PM_MenuVMargin:
case QStyle::PM_ToolBarItemMargin:
return 1;
- break;
case QStyle::PM_DockWidgetSeparatorExtent:
return 4;
#if QT_CONFIG(tabbar)
@@ -396,8 +392,6 @@ static QScreen *screenOf(const QWidget *w)
// and account for secondary screens with differing logical DPI.
qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget)
{
- if (!QHighDpiScaling::isActive())
- return 1;
qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget);
if (QGuiApplicationPrivate::screen_list.size() > 1) {
const QScreen *primaryScreen = QGuiApplication::primaryScreen();
@@ -698,17 +692,17 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
x -= 2;
if (opt->rect.height() > 4) {
qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
}
} else {
if (opt->rect.width() > 4) {
int y = opt->rect.height() / 2 - 4;
qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
+ opt->palette, false, 1, nullptr);
}
}
p->restore();
@@ -759,7 +753,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
}
} else {
qDrawWinButton(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), panel ? &fill : 0);
+ opt->state & (State_Sunken | State_On), panel ? &fill : nullptr);
}
} else {
p->fillRect(opt->rect, fill);
@@ -980,7 +974,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
if (opt->state & (State_Raised | State_On | State_Sunken)) {
qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
- panel ? &fill : 0);
+ panel ? &fill : nullptr);
} else {
if (panel)
p->fillRect(opt->rect, fill);
@@ -1005,7 +999,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
#endif // QT_CONFIG(dockwidget)
case PE_FrameStatusBarItem:
- qDrawShadePanel(p, opt->rect, opt->palette, true, 1, 0);
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1, nullptr);
break;
case PE_IndicatorProgressChunk:
@@ -1043,7 +1037,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
break;
case PE_FrameTabWidget: {
- qDrawWinButton(p, opt->rect, opt->palette, false, 0);
+ qDrawWinButton(p, opt->rect, opt->palette, false, nullptr);
break;
}
default:
@@ -1585,6 +1579,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
case QStyleOptionToolBar::Beginning:
case QStyleOptionToolBar::OnlyOne:
paintBottomBorder = false;
+ break;
default:
break;
}
@@ -1600,6 +1595,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
case QStyleOptionToolBar::OnlyOne:
paintRightBorder = false;
paintLeftBorder = false;
+ break;
default:
break;
}
diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h
index e6ea809f11..4f6ffcefc2 100644
--- a/src/widgets/styles/qwindowsstyle_p_p.h
+++ b/src/widgets/styles/qwindowsstyle_p_p.h
@@ -77,9 +77,9 @@ public:
bool hasSeenAlt(const QWidget *widget) const;
bool altDown() const { return alt_down; }
- bool alt_down;
+ bool alt_down = false;
QList<const QWidget *> seenAlt;
- int menuBarTimer;
+ int menuBarTimer = 0;
QColor inactiveCaptionText;
QColor activeCaptionColor;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e73c63f657..9a0e969e1c 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -862,6 +862,16 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
when the choice is not changed. If you need to know when the
choice actually changes, use signal currentIndexChanged().
+ \obsolete Use QComboBox::textActivated() instead
+*/
+/*!
+ \fn void QComboBox::textActivated(const QString &text)
+ \since 5.14
+
+ This signal is sent when the user chooses an item in the combobox.
+ The item's \a text is passed. Note that this signal is sent even
+ when the choice is not changed. If you need to know when the
+ choice actually changes, use signal currentIndexChanged().
*/
/*!
@@ -876,6 +886,15 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
This signal is sent when an item in the combobox popup list is
highlighted by the user. The item's \a text is passed.
+
+ \obsolete Use textHighlighted() instead
+*/
+/*!
+ \fn void QComboBox::textHighlighted(const QString &text)
+ \since 5.14
+
+ This signal is sent when an item in the combobox popup list is
+ highlighted by the user. The item's \a text is passed.
*/
/*!
@@ -888,7 +907,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
currentIndex was reset.
*/
-#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QComboBox::currentIndexChanged(const QString &text)
\since 4.1
@@ -897,7 +915,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
changes either through user interaction or programmatically. The
item's \a text is passed.
*/
-#endif
/*!
\fn void QComboBox::currentTextChanged(const QString &text)
@@ -2522,21 +2539,6 @@ QSize QComboBox::sizeHint() const
}
#ifdef Q_OS_MAC
-
-namespace {
-struct IndexSetter {
- int index;
- QComboBox *cb;
-
- void operator()(void)
- {
- cb->setCurrentIndex(index);
- emit cb->activated(index);
- emit cb->activated(cb->itemText(index));
- }
-};
-}
-
void QComboBoxPrivate::cleanupNativePopup()
{
if (!m_platformMenu)
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index eadb21628f..5967776a61 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -390,6 +390,16 @@ public:
#ifdef Q_OS_MAC
void cleanupNativePopup();
bool showNativePopup();
+ struct IndexSetter {
+ int index;
+ QComboBox *cb;
+
+ void operator()(void)
+ {
+ cb->setCurrentIndex(index);
+ cb->d_func()->emitActivated(cb->d_func()->currentIndex);
+ }
+ };
#endif
QAbstractItemModel *model;
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index e38490dabd..51b458f03a 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2332,14 +2332,17 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
// However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
// then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
// Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
- const int screenIndex = d->topData()->initialScreenIndex;
- if (screenIndex >= 0)
- d->popupScreen = screenIndex;
- if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
- if (d->setScreen(s))
+ // However if eventLoop exists, then exec() already did this by calling createWinId(); so leave it alone. (QTBUG-76162)
+ if (!d->eventLoop) {
+ const int screenIndex = d->topData()->initialScreenIndex;
+ if (screenIndex >= 0)
+ d->popupScreen = screenIndex;
+ if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
+ if (d->setScreen(s))
+ d->itemsDirty = true;
+ } else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
- } else if (d->setScreenForPoint(p)) {
- d->itemsDirty = true;
+ }
}
const bool contextMenu = d->isContextMenu();
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index e39ef6d1cd..b7c3426e08 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -123,6 +123,11 @@ public:
wish to do your own drawing you can get a pointer to the pixmap
used in the splash screen with pixmap(). Alternatively, you can
subclass QSplashScreen and reimplement drawContents().
+
+ In case of having multiple screens, it is also possible to show the
+ splash screen on a different screen than the primary one. For example:
+
+ \snippet qsplashscreen/main.cpp 2
*/
/*!
@@ -139,6 +144,23 @@ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f)
/*!
\overload
+ \since 5.15
+
+ This function allows you to specify the screen for your splashscreen. The
+ typical use for this constructor is if you have multiple screens and
+ prefer to have the splash screen on a different screen than your primary
+ one. In that case pass the proper \a screen.
+*/
+QSplashScreen::QSplashScreen(QScreen *screen, const QPixmap &pixmap, Qt::WindowFlags f)
+ : QWidget(*(new QSplashScreenPrivate()), nullptr, Qt::SplashScreen | Qt::FramelessWindowHint | f)
+{
+ d_func()->setPixmap(pixmap, screen);
+}
+
+#if QT_DEPRECATED_SINCE(5, 15)
+/*!
+ \overload
+ \obsolete
This function allows you to specify a parent for your splashscreen. The
typical use for this constructor is if you have a multiple screens and
@@ -152,6 +174,7 @@ QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap, Qt::WindowF
// is still 0 here due to QWidget's special handling.
d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(parent));
}
+#endif
/*!
Destructor.
@@ -286,26 +309,35 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap)
}
// In setPixmap(), resize and try to position on a screen according to:
-// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
+// 1) If the screen for the given widget is available, use that
+// 2) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
// QSplashScreen(QWidget *, QPixmap).
-// 2) If a widget with associated QWindow is found, use that
-// 3) When nothing can be found, try to center it over the cursor
+// 3) If a widget with associated QWindow is found, use that
+// 4) When nothing can be found, try to center it over the cursor
+#if QT_DEPRECATED_SINCE(5, 15)
static inline int screenNumberOf(const QDesktopScreenWidget *dsw)
{
auto desktopWidgetPrivate =
static_cast<QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop()));
return desktopWidgetPrivate->screens.indexOf(const_cast<QDesktopScreenWidget *>(dsw));
}
+#endif
const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w)
{
+ if (w && w->screen())
+ return w->screen();
+
for (const QWidget *p = w; p !=nullptr ; p = p->parentWidget()) {
+#if QT_DEPRECATED_SINCE(5, 15)
if (auto dsw = qobject_cast<const QDesktopScreenWidget *>(p))
return QGuiApplication::screens().value(screenNumberOf(dsw));
+#endif
if (QWindow *window = p->windowHandle())
return window->screen();
}
+
#if QT_CONFIG(cursor)
// Note: We could rely on QPlatformWindow::initialGeometry() to center it
// over the cursor, but not all platforms (namely Android) use that.
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
index 8bdf4e7749..1877493fcf 100644
--- a/src/widgets/widgets/qsplashscreen.h
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -55,7 +55,11 @@ class Q_WIDGETS_EXPORT QSplashScreen : public QWidget
Q_OBJECT
public:
explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+ QSplashScreen(QScreen *screen, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use the constructor taking a QScreen *")
QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags());
+#endif
virtual ~QSplashScreen();
void setPixmap(const QPixmap &pixmap);