Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"

This commit is contained in:
Qt Forward Merge Bot 2019-09-24 01:00:42 +02:00
commit 9a09af1cb7
36 changed files with 517 additions and 251 deletions

View File

@ -0,0 +1,40 @@
# qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D
# graphics stack. (not the Broadcom stack)
#
# This supports accelerated OpenGL both for X11 and DRM/KMS. Perhaps
# Wayland too.
#
# Tested with a sysroot created from Raspbian Buster and a gcc 7.4
# toolchain from Linaro.
#
# Example configure command line, assuming installation to
# /usr/local/qt5pi on device and ~/rpi/qt5 on the host:
#
# ./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/rpi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- \
# -sysroot ~/rpi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/rpi/qt5 -v
#
# Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11
# should all be 'yes'. Otherwise something is wrong.
#
# If getting linker errors like "undefined reference to `_dl_stack_flags'" check the
# symlinks in the sysroot, they were probably not adjusted
# correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to
# sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad
# things will happen.
include(../common/linux_device_pre.conf)
QMAKE_LIBS_EGL += -lEGL
QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL
QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
DISTRO_OPTS += hard-float
DISTRO_OPTS += deb-multi-arch
EGLFS_DEVICE_INTEGRATION = eglfs_kms
include(../common/linux_arm_device_post.conf)
load(qt_config)

View File

@ -0,0 +1,40 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "../../linux-g++/qplatformdefs.h"

View File

@ -97,8 +97,10 @@ macx-xcode {
qmake_pkginfo_typeinfo.value = "????" qmake_pkginfo_typeinfo.value = "????"
QMAKE_MAC_XCODE_SETTINGS += qmake_pkginfo_typeinfo QMAKE_MAC_XCODE_SETTINGS += qmake_pkginfo_typeinfo
!isEmpty(VERSION) { bundle_version = $$VERSION
l = $$split(VERSION, '.') 0 0 # make sure there are at least three isEmpty(bundle_version): bundle_version = 1.0.0
l = $$split(bundle_version, '.') 0 0 # make sure there are at least three
VER_MAJ = $$member(l, 0, 0) VER_MAJ = $$member(l, 0, 0)
VER_MIN = $$member(l, 1, 1) VER_MIN = $$member(l, 1, 1)
VER_PAT = $$member(l, 2, 2) VER_PAT = $$member(l, 2, 2)
@ -111,7 +113,6 @@ macx-xcode {
qmake_short_version.name = QMAKE_SHORT_VERSION qmake_short_version.name = QMAKE_SHORT_VERSION
qmake_short_version.value = $${VER_MAJ}.$${VER_MIN} qmake_short_version.value = $${VER_MAJ}.$${VER_MIN}
QMAKE_MAC_XCODE_SETTINGS += qmake_short_version QMAKE_MAC_XCODE_SETTINGS += qmake_short_version
}
!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) { !isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
debug_information_format.name = DEBUG_INFORMATION_FORMAT debug_information_format.name = DEBUG_INFORMATION_FORMAT

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the documentation of the Qt Toolkit. ** This file is part of the documentation of the Qt Toolkit.
@ -2891,8 +2891,8 @@
On desktop Windows, the default value is the value of the environment On desktop Windows, the default value is the value of the environment
variable \c{WindowsSDKVersion}. variable \c{WindowsSDKVersion}.
On WinRT, the default value is the value of the environment variable On Universal Windows Platform (UWP), the default value is the value of the
\c{UCRTVERSION}. environment variable \c{UCRTVERSION}.
\target WINDOWS_TARGET_PLATFORM_MIN_VERSION \target WINDOWS_TARGET_PLATFORM_MIN_VERSION
\section1 WINDOWS_TARGET_PLATFORM_MIN_VERSION \section1 WINDOWS_TARGET_PLATFORM_MIN_VERSION
@ -2905,8 +2905,8 @@
\target WINRT_MANIFEST \target WINRT_MANIFEST
\section1 WINRT_MANIFEST \section1 WINRT_MANIFEST
Specifies parameters to be passed to the application manifest on \l{Qt for WinRT}{Windows Specifies parameters to be passed to the application manifest on
Runtime}. The allowed values are: \l{Qt for UWP}{UWP}. The allowed values are:
\table \table
\header \header
@ -2941,7 +2941,6 @@
\row \row
\li foreground \li foreground
\li Tile foreground (text) color. Defaults to \c{light}. \li Tile foreground (text) color. Defaults to \c{light}.
This option is only available for Windows Store apps on Windows 8 and Windows RT.
\row \row
\li iconic_tile_icon \li iconic_tile_icon
\li Image file for the \c{iconic} tile template icon. Default provided by \li Image file for the \c{iconic} tile template icon. Default provided by
@ -2956,16 +2955,16 @@
manifest's UUID, or generates a new UUID if none is present. manifest's UUID, or generates a new UUID if none is present.
\row \row
\li logo_30x30 \li logo_30x30
\li Logo image file of size 30x30 pixels. This is not supported on Windows Phone. \li Logo image file of size 30x30 pixels.
\row \row
\li logo_41x41 \li logo_41x41
\li Logo image file of size 41x41 pixels. This is only supported on Windows Phone. \li Logo image file of size 41x41 pixels. This parameter is obsolete.
\row \row
\li logo_70x70 \li logo_70x70
\li Logo image file of size 70x70 pixels. This is not supported on Windows Phone. \li Logo image file of size 70x70 pixels.
\row \row
\li logo_71x71 \li logo_71x71
\li Logo image file of size 71x71 pixels. This is only supported on Windows Phone. \li Logo image file of size 71x71 pixels. This parameter is obsolete.
\row \row
\li logo_150x150 \li logo_150x150
\li Logo image file of size 150x150 pixels. This is supported on all Windows \li Logo image file of size 150x150 pixels. This is supported on all Windows
@ -2980,31 +2979,27 @@
Store App platforms. Store App platforms.
\row \row
\li logo_620x300 \li logo_620x300
\li Splash screen image file of size 620x300 pixels. This is not supported on \li Splash screen image file of size 620x300 pixels.
Windows Phone.
\row \row
\li logo_480x800 \li logo_480x800
\li Splash screen image file of size 480x800 pixels. This is only supported on \li Splash screen image file of size 480x800 pixels.
Windows Phone. This parameter is obsolete.
\row \row
\li logo_large \li logo_large
\li Large logo image file. This has to be 150x150 pixels. Supported on all \li Large logo image file. This has to be 150x150 pixels. Supported on all
Windows Store App platforms. Default provided by the mkspec. Windows Store App platforms. Default provided by the mkspec.
\row \row
\li logo_medium \li logo_medium
\li Medium logo image file. For Windows Phone the image must have a pixel size \li Medium logo image file. The image must have a pixel size of 70x70.
of 71x71, for other Windows Store App platforms 70x70. Default provided by Default provided by the mkspec.
the mkspec.
\row \row
\li logo_small \li logo_small
\li Small logo image file. For Windows Phone the image must have a pixel size \li Small logo image file. The image must have a pixel size of 30x30.
of 44x44, for other Windows Store App platforms 30x30. Default provided by Default provided by the mkspec.
the mkspec.
\row \row
\li logo_splash \li logo_splash
\li Splash screen image file. For Windows Phone the image must have a pixel size \li Splash screen image file. The image must have a pixel size of
of 480x800, for other Windows Store App platforms 620x300. Default provided 620x300. Default provided by the mkspec.
by the mkspec.
\row \row
\li logo_store \li logo_store
\li Logo image file for Windows Store. Default provided by the mkspec. \li Logo image file for Windows Store. Default provided by the mkspec.
@ -3017,10 +3012,12 @@
\li The name of the package as displayed to the user. Defaults to TARGET. \li The name of the package as displayed to the user. Defaults to TARGET.
\row \row
\li phone_product_id \li phone_product_id
\li The GUID of the product. Defaults to the value of WINRT_MANIFEST.identity. (Windows Phone only) \li The GUID of the product.
This parameter is obsolete.
\row \row
\li phone_publisher_id \li phone_publisher_id
\li The GUID of the publisher. Defaults to an invalid GUID. (Windows Phone only) \li The GUID of the publisher.
This parameter is obsolete.
\row \row
\li publisher \li publisher
\li Display name of the publisher. Defaults to \c{Default publisher display name}. \li Display name of the publisher. Defaults to \c{Default publisher display name}.
@ -3071,10 +3068,6 @@
WINRT_MANIFEST.CONFIG += verbatim WINRT_MANIFEST.CONFIG += verbatim
\endcode \endcode
\note The required image sizes of \e logo_small, \e logo_medium, and \e logo_large
depend on the target platform. The general descriptions are overwritten if a
description that specifies the size is provided.
\target YACCSOURCES \target YACCSOURCES
\section1 YACCSOURCES \section1 YACCSOURCES

View File

@ -451,6 +451,12 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
This signal is emitted when the file at the specified \a path is This signal is emitted when the file at the specified \a path is
modified, renamed or removed from disk. modified, renamed or removed from disk.
\note As a safety measure, many applications save an open file by
writing a new file and then deleting the old one. In your slot
function, you can check \c watcher.files().contains(path).
If it returns \c false, check whether the file still exists
and then call \c addPath() to continue watching it.
\sa directoryChanged() \sa directoryChanged()
*/ */

View File

@ -2708,7 +2708,7 @@ QStringList QCoreApplication::libraryPathsLocked()
QStringList *app_libpaths = new QStringList; QStringList *app_libpaths = new QStringList;
coreappdata()->app_libpaths.reset(app_libpaths); coreappdata()->app_libpaths.reset(app_libpaths);
QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH"); auto setPathsFromEnv = [&](QString libPathEnv) {
if (!libPathEnv.isEmpty()) { if (!libPathEnv.isEmpty()) {
QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
@ -2719,7 +2719,11 @@ QStringList QCoreApplication::libraryPathsLocked()
} }
} }
} }
};
setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH"));
#ifdef Q_OS_ANDROID
setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"));
#endif
#ifdef Q_OS_DARWIN #ifdef Q_OS_DARWIN
// Check the main bundle's PlugIns directory as this is a standard location for Apple OSes. // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
// Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value

View File

@ -3908,11 +3908,12 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (connections->currentConnectionId.loadRelaxed() == 0) if (connections->currentConnectionId.loadRelaxed() == 0)
senderDeleted = true; senderDeleted = true;
} }
if (!senderDeleted) if (!senderDeleted) {
sp->connections.loadRelaxed()->cleanOrphanedConnections(sender); sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
signal_spy_set->signal_end_callback(sender, signal_index); signal_spy_set->signal_end_callback(sender, signal_index);
}
} }
/*! /*!
@ -4399,22 +4400,18 @@ QDebug operator<<(QDebug dbg, const QObject *o)
\relates QObject \relates QObject
\obsolete \obsolete
In new code, you should prefer the use of the Q_ENUM() macro, which makes the
type available also to the meta type system.
For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS().
This macro registers one or several enum types to the meta-object This macro registers one or several enum types to the meta-object
system. system.
For example:
\snippet code/src_corelib_kernel_qobject.cpp 38
If you want to register an enum that is declared in another class, If you want to register an enum that is declared in another class,
the enum must be fully qualified with the name of the class the enum must be fully qualified with the name of the class
defining it. In addition, the class \e defining the enum has to defining it. In addition, the class \e defining the enum has to
inherit QObject as well as declare the enum using Q_ENUMS(). inherit QObject as well as declare the enum using Q_ENUMS().
In new code, you should prefer the use of the Q_ENUM() macro, which makes the
type available also to the meta type system.
For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS().
\sa {Qt's Property System} \sa {Qt's Property System}
*/ */

View File

@ -193,7 +193,11 @@ void QFactoryLoader::update()
continue; continue;
d->loadedPaths << pluginDir; d->loadedPaths << pluginDir;
#ifdef Q_OS_ANDROID
QString path = pluginDir;
#else
QString path = pluginDir + d->suffix; QString path = pluginDir + d->suffix;
#endif
if (qt_debug_component()) if (qt_debug_component())
qDebug() << "QFactoryLoader::QFactoryLoader() checking directory path" << path << "..."; qDebug() << "QFactoryLoader::QFactoryLoader() checking directory path" << path << "...";
@ -202,8 +206,10 @@ void QFactoryLoader::update()
continue; continue;
QStringList plugins = QDir(path).entryList( QStringList plugins = QDir(path).entryList(
#ifdef Q_OS_WIN #if defined(Q_OS_WIN)
QStringList(QStringLiteral("*.dll")), QStringList(QStringLiteral("*.dll")),
#elif defined(Q_OS_ANDROID)
QStringList(QLatin1String("plugins_%1_*.so").arg(d->suffix)),
#endif #endif
QDir::Files); QDir::Files);
QLibraryPrivate *library = 0; QLibraryPrivate *library = 0;
@ -339,6 +345,10 @@ QFactoryLoader::QFactoryLoader(const char *iid,
#if QT_CONFIG(library) #if QT_CONFIG(library)
d->cs = cs; d->cs = cs;
d->suffix = suffix; d->suffix = suffix;
# ifdef Q_OS_ANDROID
if (!d->suffix.isEmpty() && d->suffix.at(0) == QLatin1Char('/'))
d->suffix.remove(0, 1);
# endif
QMutexLocker locker(qt_factoryloader_mutex()); QMutexLocker locker(qt_factoryloader_mutex());
update(); update();

View File

@ -236,6 +236,14 @@ bool QLibraryPrivate::load_sys()
auto attemptFromBundle = attempt; auto attemptFromBundle = attempt;
pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags); pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
} }
if (pHnd) {
using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved);
JniOnLoadPtr jniOnLoad = reinterpret_cast<JniOnLoadPtr>(dlsym(pHnd, "JNI_OnLoad"));
if (jniOnLoad && jniOnLoad(QtAndroidPrivate::javaVM(), nullptr) == JNI_ERR) {
dlclose(pHnd);
pHnd = nullptr;
}
}
#endif #endif
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) { if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {

View File

@ -311,6 +311,16 @@ static QString locatePlugin(const QString& fileName)
for (const QString &path : qAsConst(paths)) { for (const QString &path : qAsConst(paths)) {
for (const QString &prefix : qAsConst(prefixes)) { for (const QString &prefix : qAsConst(prefixes)) {
for (const QString &suffix : qAsConst(suffixes)) { for (const QString &suffix : qAsConst(suffixes)) {
#ifdef Q_OS_ANDROID
{
QString pluginPath = basePath + prefix + baseName + suffix;
const QString fn = path + QLatin1String("/lib") + pluginPath.replace(QLatin1Char('/'), QLatin1Char('_'));
if (debug)
qDebug() << "Trying..." << fn;
if (QFileInfo(fn).isFile())
return fn;
}
#endif
const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix; const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix;
if (debug) if (debug)
qDebug() << "Trying..." << fn; qDebug() << "Trying..." << fn;

View File

@ -960,6 +960,7 @@ public:
friend class QApplication; friend class QApplication;
friend class QApplicationPrivate; friend class QApplicationPrivate;
friend class QQuickPointerTouchEvent; friend class QQuickPointerTouchEvent;
friend class QQuickMultiPointTouchArea;
}; };
#if QT_DEPRECATED_SINCE(5, 0) #if QT_DEPRECATED_SINCE(5, 0)

View File

@ -5658,29 +5658,29 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
{ {
if (coverage == 0) { if (coverage == 0) {
// nothing // nothing
} else if (coverage == 255) { } else if (coverage == 255 || !colorProfile) {
*dst = src; blend_pixel(*dst, src, coverage);
} else if (!colorProfile) { } else if (*dst < 0xff000000) {
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
} else { blend_pixel(*dst, src, coverage);
if (*dst >= 0xff000000) { } else if (src >= 0xff000000) {
grayBlendPixel(dst, coverage, srcLinear, colorProfile); grayBlendPixel(dst, coverage, srcLinear, colorProfile);
} else { } else {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 // First do naive blend with text-color
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); QRgb s = *dst;
} blend_pixel(s, src);
// Then gamma-corrected blend with glyph shape
QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
grayBlendPixel(dst, coverage, s64, colorProfile);
} }
} }
#if QT_CONFIG(raster_64bit) #if QT_CONFIG(raster_64bit)
static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
static inline void grayBlendPixel(QRgba64 &dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
{ {
if (coverage == 0) { // Do a gammacorrected gray alphablend...
// nothing QRgba64 dstColor = dst;
} else if (coverage == 255) {
dest[x] = src;
} else {
QRgba64 dstColor = dest[x];
if (colorProfile) { if (colorProfile) {
if (dstColor.isOpaque()) if (dstColor.isOpaque())
dstColor = colorProfile->toLinear(dstColor); dstColor = colorProfile->toLinear(dstColor);
@ -5688,14 +5688,33 @@ static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, con
dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied(); dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
} }
dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - coverage); blend_pixel(dstColor, srcLinear, coverage);
if (colorProfile) { if (colorProfile) {
if (dstColor.isOpaque()) if (dstColor.isOpaque())
dstColor = colorProfile->fromLinear(dstColor); dstColor = colorProfile->fromLinear(dstColor);
else if (!dstColor.isTransparent()) else if (!dstColor.isTransparent())
dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied(); dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
} }
dest[x] = dstColor; dst = dstColor;
}
static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
} else if (coverage == 255) {
blend_pixel(dest[x], src);
} else if (src.isOpaque()) {
grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
} else {
// First do naive blend with text-color
QRgba64 s = dest[x];
blend_pixel(s, src);
// Then gamma-corrected blend with glyph shape
if (colorProfile)
s = colorProfile->toLinear(s);
grayBlendPixel(dest[x], coverage, s, colorProfile);
} }
} }
@ -5714,12 +5733,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
alignas(8) QRgba64 buffer[BufferSize]; alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@ -5792,12 +5807,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
quint32 buffer[BufferSize]; quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format]; const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@ -5872,7 +5883,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
int mapWidth, int mapHeight, int mapStride, int mapWidth, int mapHeight, int mapStride,
const QClipData *clip, bool useGammaCorrection) const QClipData *clip, bool useGammaCorrection)
{ {
if (useGammaCorrection) { if (useGammaCorrection || !color.isOpaque()) {
qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection); qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
return; return;
} }
@ -5931,12 +5942,8 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
if (!clip) { if (!clip) {
quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x; quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
@ -6031,48 +6038,62 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
#endif #endif
} }
static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
} else if (coverage == 0xffffffff && qAlpha(src) == 255) {
blend_pixel(*dst, src);
} else if (!colorProfile) {
*dst = rgbBlend(*dst, src, coverage);
} else if (*dst < 0xff000000) {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
blend_pixel(*dst, src, qRgbAvg(coverage));
} else if (srcLinear.isOpaque()) {
rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
// First do naive blend with text-color
QRgb s = *dst;
blend_pixel(s, src);
// Then gamma-corrected blend with glyph shape
QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
rgbBlendPixel(dst, coverage, s64, colorProfile);
}
}
#if QT_CONFIG(raster_64bit) #if QT_CONFIG(raster_64bit)
static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected RGB alphablend...
const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
}
static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{ {
if (coverage == 0xff000000) { if (coverage == 0xff000000) {
// nothing // nothing
} else if (coverage == 0xffffffff) { } else if (coverage == 0xffffffff) {
dest[x] = src; blend_pixel(dest[x], src);
} else { } else if (!dest[x].isOpaque()) {
QRgba64 dstColor = dest[x];
if (dstColor.isOpaque()) {
if (colorProfile)
dstColor = colorProfile->toLinear(dstColor);
dstColor = rgbBlend(dstColor, srcLinear, coverage);
if (colorProfile)
dstColor = colorProfile->fromLinear(dstColor);
dest[x] = dstColor;
} else {
// Do a gray alphablend. // Do a gray alphablend.
alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile); alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
} } else if (src.isOpaque()) {
} rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
}
#endif
static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
} else if (coverage == 0xffffffff) {
*dst = src;
} else if (*dst < 0xff000000) {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
const int a = qRgbAvg(coverage);
*dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a);
} else if (!colorProfile) {
*dst = rgbBlend(*dst, src, coverage);
} else { } else {
rgbBlendPixel(dst, coverage, srcLinear, colorProfile); // First do naive blend with text-color
QRgba64 s = dest[x];
blend_pixel(s, src);
// Then gamma-corrected blend with glyph shape
if (colorProfile)
s = colorProfile->toLinear(s);
rgbBlendPixel(dest[x], coverage, s, colorProfile);
} }
} }
#if QT_CONFIG(raster_64bit)
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color, int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride, const uint *src, int mapWidth, int mapHeight, int srcStride,
@ -6087,12 +6108,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
alignas(8) QRgba64 buffer[BufferSize]; alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@ -6164,12 +6181,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
quint32 buffer[BufferSize]; quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format]; const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@ -6242,12 +6255,8 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color; QRgba64 srcColor = color;
if (colorProfile) { if (colorProfile && color.isOpaque())
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor); srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
if (!clip) { if (!clip) {
quint32 *dst = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x; quint32 *dst = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;

View File

@ -671,6 +671,8 @@ static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src)
static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha) static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha)
{ {
if (const_alpha == 255)
return blend_pixel(dst, src);
if (src != 0) { if (src != 0) {
const quint32 s = BYTE_MUL(src, const_alpha); const quint32 s = BYTE_MUL(src, const_alpha);
dst = s + BYTE_MUL(dst, qAlpha(~s)); dst = s + BYTE_MUL(dst, qAlpha(~s));

View File

@ -842,8 +842,8 @@ void QRasterPaintEngine::updateRasterState()
const QPainter::CompositionMode mode = s->composition_mode; const QPainter::CompositionMode mode = s->composition_mode;
s->flags.fast_text = (s->penData.type == QSpanData::Solid) s->flags.fast_text = (s->penData.type == QSpanData::Solid)
&& s->intOpacity == 256 && s->intOpacity == 256
&& (mode == QPainter::CompositionMode_Source && (mode == QPainter::CompositionMode_SourceOver
|| (mode == QPainter::CompositionMode_SourceOver || (mode == QPainter::CompositionMode_Source
&& s->penData.solidColor.isOpaque())); && s->penData.solidColor.isOpaque()));
} }

View File

@ -1716,8 +1716,8 @@ void QPainter::restore()
static inline void qt_cleanup_painter_state(QPainterPrivate *d) static inline void qt_cleanup_painter_state(QPainterPrivate *d)
{ {
qDeleteAll(d->states);
d->states.clear(); d->states.clear();
delete d->state;
d->state = 0; d->state = 0;
d->engine = 0; d->engine = 0;
d->device = 0; d->device = 0;

View File

@ -284,6 +284,8 @@ static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src)
static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src, const int const_alpha) static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src, const int const_alpha)
{ {
if (const_alpha == 255)
return blend_pixel(dst, src);
if (!src.isTransparent()) { if (!src.isTransparent()) {
src = multiplyAlpha255(src, const_alpha); src = multiplyAlpha255(src, const_alpha);
dst = src + multiplyAlpha65535(dst, 65535 - src.alpha()); dst = src + multiplyAlpha65535(dst, 65535 - src.alpha());

View File

@ -3524,7 +3524,10 @@ QSize QMetalSwapChain::surfacePixelSize()
if (v) { if (v) {
CAMetalLayer *layer = (CAMetalLayer *) [v layer]; CAMetalLayer *layer = (CAMetalLayer *) [v layer];
if (layer) { if (layer) {
CGSize size = [layer drawableSize]; CGSize size = layer.bounds.size;
size.width *= layer.contentsScale;
size.height *= layer.contentsScale;
layer.drawableSize = size;
return QSize(int(size.width), int(size.height)); return QSize(int(size.width), int(size.height));
} }
} }

View File

@ -1,9 +1,5 @@
TARGET = qtforandroid TARGET = qtforandroid
# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
# Yes, the plugin imports itself statically
DEFINES += QT_STATICPLUGIN
LIBS += -ljnigraphics -landroid LIBS += -ljnigraphics -landroid
QT += \ QT += \
@ -19,7 +15,8 @@ INCLUDEPATH += \
$$PWD \ $$PWD \
$$QT_SOURCE_TREE/src/3rdparty/android $$QT_SOURCE_TREE/src/3rdparty/android
SOURCES += $$PWD/androidplatformplugin.cpp \ SOURCES += $$PWD/main.cpp \
$$PWD/androidplatformplugin.cpp \
$$PWD/androidcontentfileengine.cpp \ $$PWD/androidcontentfileengine.cpp \
$$PWD/androiddeadlockprotector.cpp \ $$PWD/androiddeadlockprotector.cpp \
$$PWD/androidjnimain.cpp \ $$PWD/androidjnimain.cpp \
@ -92,4 +89,5 @@ qtConfig(vulkan) {
} }
PLUGIN_TYPE = platforms PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QAndroidIntegrationPlugin
load(qt_plugin) load(qt_plugin)

View File

@ -68,8 +68,6 @@
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static JavaVM *m_javaVM = nullptr; static JavaVM *m_javaVM = nullptr;

View File

@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2019 BogDan Vatra <bogdan@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qpa/qplatformintegrationplugin.h>
#include "qandroidplatformintegration.h"
QT_BEGIN_NAMESPACE
class QAndroidIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json")
public:
QPlatformIntegration *create(const QString& system, const QStringList& paramList) override;
};
QPlatformIntegration *QAndroidIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
if (!system.compare(QLatin1String("android"), Qt::CaseInsensitive))
return new QAndroidPlatformIntegration(paramList);
return nullptr;
}
QT_END_NAMESPACE

View File

@ -65,8 +65,8 @@ public:
void setParent(const QPlatformWindow *window) override; void setParent(const QPlatformWindow *window) override;
WId winId() const override { return m_windowId; } WId winId() const override { return m_windowId; }
bool setMouseGrabEnabled(bool grab) override { return false; } bool setMouseGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; }
bool setKeyboardGrabEnabled(bool grab) override { return false; } bool setKeyboardGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; }
QAndroidPlatformScreen *platformScreen() const; QAndroidPlatformScreen *platformScreen() const;

View File

@ -161,7 +161,6 @@ public:
Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState();
Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidChangeBackingPropertiesNotification) void windowDidChangeBackingProperties();
Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose(); Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose();
bool windowShouldClose(); bool windowShouldClose();

View File

@ -1262,17 +1262,6 @@ void QCocoaWindow::windowDidChangeScreen()
currentScreen->requestUpdate(); currentScreen->requestUpdate();
} }
} }
/*
The window's backing scale factor or color space has changed.
*/
void QCocoaWindow::windowDidChangeBackingProperties()
{
// Ideally we would plumb this thought QPA in a way that lets clients
// invalidate their own caches, and recreate QBackingStore. For now we
// trigger an expose, and let QCocoaBackingStore deal with its own
// buffer invalidation.
[m_view setNeedsDisplay:YES];
}
void QCocoaWindow::windowWillClose() void QCocoaWindow::windowWillClose()
{ {

View File

@ -173,20 +173,6 @@
} }
#endif #endif
- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
{
CGSize drawableSize = layer.bounds.size;
drawableSize.width *= layer.contentsScale;
drawableSize.height *= layer.contentsScale;
layer.drawableSize = drawableSize;
}
- (void)layoutSublayersOfLayer:(CALayer *)layer
{
if ([layer isKindOfClass:CAMetalLayer.class])
[self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
}
- (void)displayLayer:(CALayer *)layer - (void)displayLayer:(CALayer *)layer
{ {
if (!NSThread.isMainThread) { if (!NSThread.isMainThread) {
@ -211,17 +197,16 @@
- (void)viewDidChangeBackingProperties - (void)viewDidChangeBackingProperties
{ {
CALayer *layer = self.layer; qCDebug(lcQpaDrawing) << "Backing properties changed for" << self;
if (!layer)
return;
layer.contentsScale = self.window.backingScaleFactor; if (self.layer)
self.layer.contentsScale = self.window.backingScaleFactor;
// Metal layers must be manually updated on e.g. screen change // Ideally we would plumb this situation through QPA in a way that lets
if ([layer isKindOfClass:CAMetalLayer.class]) { // clients invalidate their own caches, recreate QBackingStore, etc.
[self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)]; // For now we trigger an expose, and let QCocoaBackingStore deal with
// buffer invalidation internally.
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
}
} }
@end @end

View File

@ -881,6 +881,14 @@ bool QSqlDatabase::rollback()
connection name must be passed to addDatabase() at connection connection name must be passed to addDatabase() at connection
object create time. object create time.
For the QSQLITE driver, if the database name specified does not
exist, then it will create the file for you unless the
QSQLITE_OPEN_READONLY option is set.
Additionally, \a name can be set to \c ":memory:" which will
create a temporary database which is only available for the
lifetime of the application.
For the QOCI (Oracle) driver, the database name is the TNS For the QOCI (Oracle) driver, the database name is the TNS
Service Name. Service Name.

View File

@ -2735,6 +2735,11 @@ static void updateObjects(const QList<const QObject *>& objects)
if (auto widget = qobject_cast<QWidget*>(const_cast<QObject*>(object))) { if (auto widget = qobject_cast<QWidget*>(const_cast<QObject*>(object))) {
widget->style()->polish(widget); widget->style()->polish(widget);
QCoreApplication::sendEvent(widget, &event); QCoreApplication::sendEvent(widget, &event);
QList<const QObject *> children;
children.reserve(widget->children().size() + 1);
for (auto child: qAsConst(widget->children()))
children.append(child);
updateObjects(children);
} }
} }
} }

View File

@ -1726,7 +1726,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->activeSubControls = d->hoverControl; option->activeSubControls = d->hoverControl;
} }
option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds) option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds, nullptr, this)
? stepEnabled() ? stepEnabled()
: (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled); : (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled);

View File

@ -42,7 +42,11 @@ class tst_QNumeric: public QObject
private slots: private slots:
void fuzzyCompare_data(); void fuzzyCompare_data();
void fuzzyCompare(); void fuzzyCompare();
void qNanInf(); void rawNaN_data();
void rawNaN();
void generalNaN_data();
void generalNaN();
void infinity();
void classifyfp(); void classifyfp();
void floatDistance_data(); void floatDistance_data();
void floatDistance(); void floatDistance();
@ -53,6 +57,8 @@ private slots:
void mulOverflow_data(); void mulOverflow_data();
void mulOverflow(); void mulOverflow();
void signedOverflow(); void signedOverflow();
private:
void checkNaN(double nan);
}; };
void tst_QNumeric::fuzzyCompare_data() void tst_QNumeric::fuzzyCompare_data()
@ -92,44 +98,89 @@ void tst_QNumeric::fuzzyCompare()
# pragma GCC optimize "no-fast-math" # pragma GCC optimize "no-fast-math"
#endif #endif
void tst_QNumeric::qNanInf() void tst_QNumeric::checkNaN(double nan)
{ {
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404) #define CHECKNAN(value) \
QSKIP("Non-conformant fast math mode is enabled, cannot run test"); do { \
#endif const double v = (value); \
double nan = qQNaN(); QCOMPARE(qFpClassify(v), FP_NAN); \
QVERIFY(qIsNaN(v)); \
QVERIFY(!qIsFinite(v)); \
QVERIFY(!qIsInf(v)); \
} while (0)
QVERIFY(!(0 > nan)); QVERIFY(!(0 > nan));
QVERIFY(!(0 < nan)); QVERIFY(!(0 < nan));
QVERIFY(!(0 == nan)); QVERIFY(!(0 == nan));
QVERIFY(!(nan == nan)); QVERIFY(!(nan == nan));
QVERIFY(qIsNaN(nan));
QVERIFY(qIsNaN(nan + 1));
QVERIFY(qIsNaN(-nan));
QVERIFY(qIsNaN(1.0 / nan));
QVERIFY(qIsNaN(0.0 / nan));
QVERIFY(qIsNaN(0.0 * nan));
QCOMPARE(nan, nan);
QCOMPARE(nan, -nan);
Q_STATIC_ASSERT(sizeof(double) == 8); CHECKNAN(nan);
#ifdef Q_LITTLE_ENDIAN CHECKNAN(nan + 1);
const uchar bytes[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f }; CHECKNAN(nan - 1);
#else CHECKNAN(-nan);
const uchar bytes[] = { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; CHECKNAN(nan * 2.0);
#endif CHECKNAN(nan / 2.0);
memcpy(&nan, bytes, 8); CHECKNAN(1.0 / nan);
QVERIFY(!qIsFinite(nan)); CHECKNAN(0.0 / nan);
QVERIFY(!qIsInf(nan)); CHECKNAN(0.0 * nan);
QVERIFY(qIsNaN(nan));
QVERIFY(qIsNaN(-nan)); // When any NaN is expected, any NaN will do:
QVERIFY(!(nan == nan));
QVERIFY(qIsNaN(0.0 * nan));
QCOMPARE(qFpClassify(nan), FP_NAN);
QCOMPARE(nan, nan); QCOMPARE(nan, nan);
QCOMPARE(nan, -nan); QCOMPARE(nan, -nan);
QCOMPARE(nan, qQNaN()); QCOMPARE(nan, qQNaN());
#undef CHECKNAN
}
double inf = qInf(); void tst_QNumeric::rawNaN_data()
{
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404)
QSKIP("Non-conformant fast math mode is enabled, cannot run test");
#endif
QTest::addColumn<double>("nan");
QTest::newRow("quiet") << qQNaN();
}
void tst_QNumeric::rawNaN()
{
QFETCH(double, nan);
checkNaN(nan);
}
void tst_QNumeric::generalNaN_data()
{
QTest::addColumn<int>("most");
QTest::addColumn<int>("next");
QTest::addColumn<int>("least");
// Every value with every bit of the exponent set is a NaN.
// Sign and mantissa can be anything without interfering with that.
// The 0x7f bits of most and the 0xf0 bits of next are the exponent.
QTest::newRow("lowload") << 0x7f << 0xf0 << 1;
QTest::newRow("sign-lowload") << 0xff << 0xf0 << 1;
QTest::newRow("highload") << 0x7f << 0xf1 << 0;
QTest::newRow("sign-highload") << 0xff << 0xf1 << 0;
}
void tst_QNumeric::generalNaN()
{
QFETCH(int, most);
QFETCH(int, next);
QFETCH(int, least);
double nan;
Q_STATIC_ASSERT(sizeof(double) == 8);
#ifdef Q_LITTLE_ENDIAN
const uchar bytes[] = { uchar(least), 0, 0, 0, 0, 0, uchar(next), uchar(most) };
#else
const uchar bytes[] = { uchar(most), uchar(next), 0, 0, 0, 0, 0, uchar(least) };
#endif
memcpy(&nan, bytes, 8);
checkNaN(nan);
}
void tst_QNumeric::infinity()
{
const double inf = qInf();
QVERIFY(inf > 0); QVERIFY(inf > 0);
QVERIFY(-inf < 0); QVERIFY(-inf < 0);
QVERIFY(qIsInf(inf)); QVERIFY(qIsInf(inf));
@ -138,16 +189,23 @@ void tst_QNumeric::qNanInf()
QVERIFY(qIsInf(-inf)); QVERIFY(qIsInf(-inf));
QVERIFY(qIsInf(inf + 1)); QVERIFY(qIsInf(inf + 1));
QVERIFY(qIsInf(inf - 1)); QVERIFY(qIsInf(inf - 1));
QVERIFY(qIsInf(-inf - 1));
QVERIFY(qIsInf(-inf + 1));
QVERIFY(qIsInf(inf * 2.0)); QVERIFY(qIsInf(inf * 2.0));
QVERIFY(qIsInf(-inf * 2.0));
QVERIFY(qIsInf(inf / 2.0)); QVERIFY(qIsInf(inf / 2.0));
QVERIFY(qIsInf(-inf / 2.0));
QVERIFY(qFuzzyCompare(1.0 / inf, 0.0)); QVERIFY(qFuzzyCompare(1.0 / inf, 0.0));
QCOMPARE(1.0 / inf, 0.0); QCOMPARE(1.0 / inf, 0.0);
QVERIFY(qFuzzyCompare(1.0 / -inf, 0.0));
QCOMPARE(1.0 / -inf, 0.0);
QVERIFY(qIsNaN(0.0 * inf)); QVERIFY(qIsNaN(0.0 * inf));
QVERIFY(qIsNaN(0.0 * -inf));
} }
void tst_QNumeric::classifyfp() void tst_QNumeric::classifyfp()
{ {
QCOMPARE(qFpClassify(qQNaN()), FP_NAN); // NaNs already handled, see checkNaN()'s callers.
QCOMPARE(qFpClassify(qInf()), FP_INFINITE); QCOMPARE(qFpClassify(qInf()), FP_INFINITE);
QCOMPARE(qFpClassify(-qInf()), FP_INFINITE); QCOMPARE(qFpClassify(-qInf()), FP_INFINITE);

View File

@ -568,11 +568,18 @@
<Incident type="pass" file="" line="0" /> <Incident type="pass" file="" line="0" />
<Duration msecs="0"/> <Duration msecs="0"/>
</TestFunction> </TestFunction>
<TestFunction name="deletingSender">
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase"> <TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" /> <Incident type="pass" file="" line="0" />
<Duration msecs="0"/> <Duration msecs="0"/>
</TestFunction> </TestFunction>
<Message type="info" file="" line="0"> <Message type="info" file="" line="0">
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description> <Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
</Message> </Message>
<Duration msecs="0"/> <Duration msecs="0"/>

View File

@ -143,9 +143,11 @@ ok 18 - slotEmittingSignalOldSyntax(queued)
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) # Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) # Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
ok 19 - variousTypes() ok 19 - variousTypes()
ok 20 - cleanupTestCase() # Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
ok 20 - deletingSender()
ok 21 - cleanupTestCase()
# Signal: QThread(_POINTER_) finished () # Signal: QThread(_POINTER_) finished ()
1..20 1..21
# tests 20 # tests 21
# pass 20 # pass 21
# fail 0 # fail 0

View File

@ -56,6 +56,9 @@
##teamcity[testStarted name='variousTypes()' flowId='tst_Signaldumper'] ##teamcity[testStarted name='variousTypes()' flowId='tst_Signaldumper']
##teamcity[testStdOut name='variousTypes()' out='INFO: Signal: SignalSlotClass(_POINTER_) qStringSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qStringRefSignal ((QString&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qStringConstRefSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qByteArraySignal (QByteArray(Test bytearray))|nINFO: Signal: SignalSlotClass(_POINTER_) qListSignal (QList<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorRefSignal ((QVector<int>&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstRefSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstPointerSignal ((const QVector<int>*)_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())' flowId='tst_Signaldumper'] ##teamcity[testStdOut name='variousTypes()' out='INFO: Signal: SignalSlotClass(_POINTER_) qStringSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qStringRefSignal ((QString&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qStringConstRefSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qByteArraySignal (QByteArray(Test bytearray))|nINFO: Signal: SignalSlotClass(_POINTER_) qListSignal (QList<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorRefSignal ((QVector<int>&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstRefSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstPointerSignal ((const QVector<int>*)_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())' flowId='tst_Signaldumper']
##teamcity[testFinished name='variousTypes()' flowId='tst_Signaldumper'] ##teamcity[testFinished name='variousTypes()' flowId='tst_Signaldumper']
##teamcity[testStarted name='deletingSender()' flowId='tst_Signaldumper']
##teamcity[testStdOut name='deletingSender()' out='INFO: Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()' flowId='tst_Signaldumper']
##teamcity[testFinished name='deletingSender()' flowId='tst_Signaldumper']
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Signaldumper'] ##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Signaldumper']
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Signaldumper'] ##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Signaldumper']
##teamcity[testSuiteFinished name='tst_Signaldumper' flowId='tst_Signaldumper'] ##teamcity[testSuiteFinished name='tst_Signaldumper' flowId='tst_Signaldumper']

View File

@ -143,7 +143,9 @@ INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVe
INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
PASS : tst_Signaldumper::variousTypes() PASS : tst_Signaldumper::variousTypes()
INFO : tst_Signaldumper::deletingSender() Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
PASS : tst_Signaldumper::deletingSender()
PASS : tst_Signaldumper::cleanupTestCase() PASS : tst_Signaldumper::cleanupTestCase()
INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished () INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished ()
Totals: 20 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of tst_Signaldumper ********* ********* Finished testing of tst_Signaldumper *********

View File

@ -570,12 +570,19 @@
<Incident type="pass" file="" line="0" /> <Incident type="pass" file="" line="0" />
<Duration msecs="0"/> <Duration msecs="0"/>
</TestFunction> </TestFunction>
<TestFunction name="deletingSender">
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase"> <TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" /> <Incident type="pass" file="" line="0" />
<Duration msecs="0"/> <Duration msecs="0"/>
</TestFunction> </TestFunction>
<Message type="info" file="" line="0"> <Message type="info" file="" line="0">
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description> <Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
</Message> </Message>
<Duration msecs="0"/> <Duration msecs="0"/>
</TestCase> </TestCase>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="125" failures="0" tests="12" name="tst_Signaldumper"> <testsuite errors="126" failures="0" tests="13" name="tst_Signaldumper">
<properties> <properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/> <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/> <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@ -151,8 +151,11 @@
<!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" --> <!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" -->
<!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" --> <!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" -->
</testcase> </testcase>
<testcase result="pass" name="deletingSender">
<!-- message="Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()" type="info" -->
</testcase>
<testcase result="pass" name="cleanupTestCase"> <testcase result="pass" name="cleanupTestCase">
<!-- message="Signal: QThread(_POINTER_) finished ()" type="info" --> <!-- message=" Signal: QThread(_POINTER_) finished ()" type="info" -->
</testcase> </testcase>
<system-err> <system-err>
<![CDATA[Signal: QThread(_POINTER_) started ()]]> <![CDATA[Signal: QThread(_POINTER_) started ()]]>
@ -279,6 +282,7 @@
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()]]> <![CDATA[Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()]]>
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]> <![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]>
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]> <![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]>
<![CDATA[Signal: QThread(_POINTER_) finished ()]]> <![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]>
<![CDATA[ Signal: QThread(_POINTER_) finished ()]]>
</system-err> </system-err>
</testsuite> </testsuite>

View File

@ -56,6 +56,8 @@ private slots:
void slotEmittingSignalOldSyntax(); void slotEmittingSignalOldSyntax();
void variousTypes(); void variousTypes();
void deletingSender();
}; };
void tst_Signaldumper::addConnectionTypeData() void tst_Signaldumper::addConnectionTypeData()
@ -413,5 +415,14 @@ void tst_Signaldumper::variousTypes()
emit signalSlotOwner.qVariantSignal(variant); emit signalSlotOwner.qVariantSignal(variant);
} }
void tst_Signaldumper::deletingSender()
{
SignalSlotClass *signalSlotOwner = new SignalSlotClass();
connect(signalSlotOwner, &SignalSlotClass::signalWithoutParameters, [signalSlotOwner]() {
delete signalSlotOwner;
});
emit signalSlotOwner->signalWithoutParameters();
}
QTEST_MAIN(tst_Signaldumper) QTEST_MAIN(tst_Signaldumper)
#include "tst_signaldumper.moc" #include "tst_signaldumper.moc"

View File

@ -1,3 +1,4 @@
#!/bin/sh
qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.vert -o shadowmap.vert.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.vert -o shadowmap.vert.qsb
qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.frag -o shadowmap.frag.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.frag -o shadowmap.frag.qsb
qsb --glsl "120,300 es" --hlsl 50 --msl 12 main.vert -o main.vert.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 main.vert -o main.vert.qsb