Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
This commit is contained in:
commit
9a09af1cb7
40
mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf
Normal file
40
mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf
Normal 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)
|
40
mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h
Normal file
40
mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h
Normal 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"
|
@ -97,21 +97,22 @@ macx-xcode {
|
||||
qmake_pkginfo_typeinfo.value = "????"
|
||||
QMAKE_MAC_XCODE_SETTINGS += qmake_pkginfo_typeinfo
|
||||
|
||||
!isEmpty(VERSION) {
|
||||
l = $$split(VERSION, '.') 0 0 # make sure there are at least three
|
||||
VER_MAJ = $$member(l, 0, 0)
|
||||
VER_MIN = $$member(l, 1, 1)
|
||||
VER_PAT = $$member(l, 2, 2)
|
||||
unset(l)
|
||||
bundle_version = $$VERSION
|
||||
isEmpty(bundle_version): bundle_version = 1.0.0
|
||||
|
||||
qmake_full_version.name = QMAKE_FULL_VERSION
|
||||
qmake_full_version.value = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT}
|
||||
QMAKE_MAC_XCODE_SETTINGS += qmake_full_version
|
||||
l = $$split(bundle_version, '.') 0 0 # make sure there are at least three
|
||||
VER_MAJ = $$member(l, 0, 0)
|
||||
VER_MIN = $$member(l, 1, 1)
|
||||
VER_PAT = $$member(l, 2, 2)
|
||||
unset(l)
|
||||
|
||||
qmake_short_version.name = QMAKE_SHORT_VERSION
|
||||
qmake_short_version.value = $${VER_MAJ}.$${VER_MIN}
|
||||
QMAKE_MAC_XCODE_SETTINGS += qmake_short_version
|
||||
}
|
||||
qmake_full_version.name = QMAKE_FULL_VERSION
|
||||
qmake_full_version.value = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT}
|
||||
QMAKE_MAC_XCODE_SETTINGS += qmake_full_version
|
||||
|
||||
qmake_short_version.name = QMAKE_SHORT_VERSION
|
||||
qmake_short_version.value = $${VER_MAJ}.$${VER_MIN}
|
||||
QMAKE_MAC_XCODE_SETTINGS += qmake_short_version
|
||||
|
||||
!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
|
||||
debug_information_format.name = DEBUG_INFORMATION_FORMAT
|
||||
|
@ -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 documentation of the Qt Toolkit.
|
||||
@ -2891,8 +2891,8 @@
|
||||
On desktop Windows, the default value is the value of the environment
|
||||
variable \c{WindowsSDKVersion}.
|
||||
|
||||
On WinRT, the default value is the value of the environment variable
|
||||
\c{UCRTVERSION}.
|
||||
On Universal Windows Platform (UWP), the default value is the value of the
|
||||
environment variable \c{UCRTVERSION}.
|
||||
|
||||
\target WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
||||
\section1 WINDOWS_TARGET_PLATFORM_MIN_VERSION
|
||||
@ -2905,8 +2905,8 @@
|
||||
\target WINRT_MANIFEST
|
||||
\section1 WINRT_MANIFEST
|
||||
|
||||
Specifies parameters to be passed to the application manifest on \l{Qt for WinRT}{Windows
|
||||
Runtime}. The allowed values are:
|
||||
Specifies parameters to be passed to the application manifest on
|
||||
\l{Qt for UWP}{UWP}. The allowed values are:
|
||||
|
||||
\table
|
||||
\header
|
||||
@ -2941,7 +2941,6 @@
|
||||
\row
|
||||
\li foreground
|
||||
\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
|
||||
\li iconic_tile_icon
|
||||
\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.
|
||||
\row
|
||||
\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
|
||||
\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
|
||||
\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
|
||||
\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
|
||||
\li logo_150x150
|
||||
\li Logo image file of size 150x150 pixels. This is supported on all Windows
|
||||
@ -2980,31 +2979,27 @@
|
||||
Store App platforms.
|
||||
\row
|
||||
\li logo_620x300
|
||||
\li Splash screen image file of size 620x300 pixels. This is not supported on
|
||||
Windows Phone.
|
||||
\li Splash screen image file of size 620x300 pixels.
|
||||
\row
|
||||
\li logo_480x800
|
||||
\li Splash screen image file of size 480x800 pixels. This is only supported on
|
||||
Windows Phone.
|
||||
\li Splash screen image file of size 480x800 pixels.
|
||||
This parameter is obsolete.
|
||||
\row
|
||||
\li logo_large
|
||||
\li Large logo image file. This has to be 150x150 pixels. Supported on all
|
||||
Windows Store App platforms. Default provided by the mkspec.
|
||||
\row
|
||||
\li logo_medium
|
||||
\li Medium logo image file. For Windows Phone the image must have a pixel size
|
||||
of 71x71, for other Windows Store App platforms 70x70. Default provided by
|
||||
the mkspec.
|
||||
\li Medium logo image file. The image must have a pixel size of 70x70.
|
||||
Default provided by the mkspec.
|
||||
\row
|
||||
\li logo_small
|
||||
\li Small logo image file. For Windows Phone the image must have a pixel size
|
||||
of 44x44, for other Windows Store App platforms 30x30. Default provided by
|
||||
the mkspec.
|
||||
\li Small logo image file. The image must have a pixel size of 30x30.
|
||||
Default provided by the mkspec.
|
||||
\row
|
||||
\li logo_splash
|
||||
\li Splash screen image file. For Windows Phone the image must have a pixel size
|
||||
of 480x800, for other Windows Store App platforms 620x300. Default provided
|
||||
by the mkspec.
|
||||
\li Splash screen image file. The image must have a pixel size of
|
||||
620x300. Default provided by the mkspec.
|
||||
\row
|
||||
\li logo_store
|
||||
\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.
|
||||
\row
|
||||
\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
|
||||
\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
|
||||
\li publisher
|
||||
\li Display name of the publisher. Defaults to \c{Default publisher display name}.
|
||||
@ -3071,10 +3068,6 @@
|
||||
WINRT_MANIFEST.CONFIG += verbatim
|
||||
\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
|
||||
\section1 YACCSOURCES
|
||||
|
||||
|
@ -451,6 +451,12 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
|
||||
This signal is emitted when the file at the specified \a path is
|
||||
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()
|
||||
*/
|
||||
|
||||
|
@ -2708,18 +2708,22 @@ QStringList QCoreApplication::libraryPathsLocked()
|
||||
QStringList *app_libpaths = new QStringList;
|
||||
coreappdata()->app_libpaths.reset(app_libpaths);
|
||||
|
||||
QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH");
|
||||
if (!libPathEnv.isEmpty()) {
|
||||
QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
|
||||
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
|
||||
QString canonicalPath = QDir(*it).canonicalPath();
|
||||
if (!canonicalPath.isEmpty()
|
||||
&& !app_libpaths->contains(canonicalPath)) {
|
||||
app_libpaths->append(canonicalPath);
|
||||
auto setPathsFromEnv = [&](QString libPathEnv) {
|
||||
if (!libPathEnv.isEmpty()) {
|
||||
QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts);
|
||||
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
|
||||
QString canonicalPath = QDir(*it).canonicalPath();
|
||||
if (!canonicalPath.isEmpty()
|
||||
&& !app_libpaths->contains(canonicalPath)) {
|
||||
app_libpaths->append(canonicalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH"));
|
||||
#ifdef Q_OS_ANDROID
|
||||
setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"));
|
||||
#endif
|
||||
#ifdef Q_OS_DARWIN
|
||||
// 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
|
||||
|
@ -3908,11 +3908,12 @@ void doActivate(QObject *sender, int signal_index, void **argv)
|
||||
if (connections->currentConnectionId.loadRelaxed() == 0)
|
||||
senderDeleted = true;
|
||||
}
|
||||
if (!senderDeleted)
|
||||
if (!senderDeleted) {
|
||||
sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
|
||||
|
||||
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
|
||||
signal_spy_set->signal_end_callback(sender, signal_index);
|
||||
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
|
||||
signal_spy_set->signal_end_callback(sender, signal_index);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -4399,22 +4400,18 @@ QDebug operator<<(QDebug dbg, const QObject *o)
|
||||
\relates QObject
|
||||
\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
|
||||
system.
|
||||
|
||||
For example:
|
||||
|
||||
\snippet code/src_corelib_kernel_qobject.cpp 38
|
||||
|
||||
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
|
||||
defining it. In addition, the class \e defining the enum has to
|
||||
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}
|
||||
*/
|
||||
|
||||
|
@ -193,7 +193,11 @@ void QFactoryLoader::update()
|
||||
continue;
|
||||
d->loadedPaths << pluginDir;
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
QString path = pluginDir;
|
||||
#else
|
||||
QString path = pluginDir + d->suffix;
|
||||
#endif
|
||||
|
||||
if (qt_debug_component())
|
||||
qDebug() << "QFactoryLoader::QFactoryLoader() checking directory path" << path << "...";
|
||||
@ -202,8 +206,10 @@ void QFactoryLoader::update()
|
||||
continue;
|
||||
|
||||
QStringList plugins = QDir(path).entryList(
|
||||
#ifdef Q_OS_WIN
|
||||
#if defined(Q_OS_WIN)
|
||||
QStringList(QStringLiteral("*.dll")),
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
QStringList(QLatin1String("plugins_%1_*.so").arg(d->suffix)),
|
||||
#endif
|
||||
QDir::Files);
|
||||
QLibraryPrivate *library = 0;
|
||||
@ -339,6 +345,10 @@ QFactoryLoader::QFactoryLoader(const char *iid,
|
||||
#if QT_CONFIG(library)
|
||||
d->cs = cs;
|
||||
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());
|
||||
update();
|
||||
|
@ -236,6 +236,14 @@ bool QLibraryPrivate::load_sys()
|
||||
auto attemptFromBundle = attempt;
|
||||
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
|
||||
|
||||
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
|
||||
|
@ -311,6 +311,16 @@ static QString locatePlugin(const QString& fileName)
|
||||
for (const QString &path : qAsConst(paths)) {
|
||||
for (const QString &prefix : qAsConst(prefixes)) {
|
||||
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;
|
||||
if (debug)
|
||||
qDebug() << "Trying..." << fn;
|
||||
|
@ -960,6 +960,7 @@ public:
|
||||
friend class QApplication;
|
||||
friend class QApplicationPrivate;
|
||||
friend class QQuickPointerTouchEvent;
|
||||
friend class QQuickMultiPointTouchArea;
|
||||
};
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
|
@ -5658,44 +5658,63 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
|
||||
{
|
||||
if (coverage == 0) {
|
||||
// nothing
|
||||
} else if (coverage == 255) {
|
||||
*dst = src;
|
||||
} else if (!colorProfile) {
|
||||
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
|
||||
} else if (coverage == 255 || !colorProfile) {
|
||||
blend_pixel(*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, coverage);
|
||||
} else if (src >= 0xff000000) {
|
||||
grayBlendPixel(dst, coverage, srcLinear, colorProfile);
|
||||
} else {
|
||||
if (*dst >= 0xff000000) {
|
||||
grayBlendPixel(dst, coverage, srcLinear, colorProfile);
|
||||
} else {
|
||||
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
|
||||
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
|
||||
}
|
||||
// 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);
|
||||
grayBlendPixel(dst, coverage, s64, colorProfile);
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_CONFIG(raster_64bit)
|
||||
|
||||
static inline void grayBlendPixel(QRgba64 &dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
|
||||
{
|
||||
// Do a gammacorrected gray alphablend...
|
||||
QRgba64 dstColor = dst;
|
||||
if (colorProfile) {
|
||||
if (dstColor.isOpaque())
|
||||
dstColor = colorProfile->toLinear(dstColor);
|
||||
else if (!dstColor.isTransparent())
|
||||
dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
|
||||
blend_pixel(dstColor, srcLinear, coverage);
|
||||
|
||||
if (colorProfile) {
|
||||
if (dstColor.isOpaque())
|
||||
dstColor = colorProfile->fromLinear(dstColor);
|
||||
else if (!dstColor.isTransparent())
|
||||
dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
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) {
|
||||
dest[x] = src;
|
||||
blend_pixel(dest[x], src);
|
||||
} else if (src.isOpaque()) {
|
||||
grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
|
||||
} else {
|
||||
QRgba64 dstColor = dest[x];
|
||||
if (colorProfile) {
|
||||
if (dstColor.isOpaque())
|
||||
dstColor = colorProfile->toLinear(dstColor);
|
||||
else if (!dstColor.isTransparent())
|
||||
dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
|
||||
dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - coverage);
|
||||
if (colorProfile) {
|
||||
if (dstColor.isOpaque())
|
||||
dstColor = colorProfile->fromLinear(dstColor);
|
||||
else if (!dstColor.isTransparent())
|
||||
dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
dest[x] = dstColor;
|
||||
// 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();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
alignas(8) QRgba64 buffer[BufferSize];
|
||||
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
|
||||
@ -5792,12 +5807,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
|
||||
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
quint32 buffer[BufferSize];
|
||||
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
|
||||
@ -5872,7 +5883,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
|
||||
int mapWidth, int mapHeight, int mapStride,
|
||||
const QClipData *clip, bool useGammaCorrection)
|
||||
{
|
||||
if (useGammaCorrection) {
|
||||
if (useGammaCorrection || !color.isOpaque()) {
|
||||
qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
|
||||
return;
|
||||
}
|
||||
@ -5931,12 +5942,8 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
|
||||
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
if (!clip) {
|
||||
quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
|
||||
@ -6031,48 +6038,62 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
|
||||
#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)
|
||||
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)
|
||||
{
|
||||
if (coverage == 0xff000000) {
|
||||
// nothing
|
||||
} else if (coverage == 0xffffffff) {
|
||||
dest[x] = src;
|
||||
blend_pixel(dest[x], src);
|
||||
} else if (!dest[x].isOpaque()) {
|
||||
// Do a gray alphablend.
|
||||
alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
|
||||
} else if (src.isOpaque()) {
|
||||
rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
|
||||
} else {
|
||||
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.
|
||||
alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, 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 {
|
||||
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,
|
||||
int x, int y, const QRgba64 &color,
|
||||
const uint *src, int mapWidth, int mapHeight, int srcStride,
|
||||
@ -6087,12 +6108,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
|
||||
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
alignas(8) QRgba64 buffer[BufferSize];
|
||||
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
|
||||
@ -6164,12 +6181,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
|
||||
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
quint32 buffer[BufferSize];
|
||||
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
|
||||
@ -6242,12 +6255,8 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
|
||||
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
|
||||
|
||||
QRgba64 srcColor = color;
|
||||
if (colorProfile) {
|
||||
if (color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
else
|
||||
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
|
||||
}
|
||||
if (colorProfile && color.isOpaque())
|
||||
srcColor = colorProfile->toLinear(srcColor);
|
||||
|
||||
if (!clip) {
|
||||
quint32 *dst = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
|
||||
|
@ -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)
|
||||
{
|
||||
if (const_alpha == 255)
|
||||
return blend_pixel(dst, src);
|
||||
if (src != 0) {
|
||||
const quint32 s = BYTE_MUL(src, const_alpha);
|
||||
dst = s + BYTE_MUL(dst, qAlpha(~s));
|
||||
|
@ -842,8 +842,8 @@ void QRasterPaintEngine::updateRasterState()
|
||||
const QPainter::CompositionMode mode = s->composition_mode;
|
||||
s->flags.fast_text = (s->penData.type == QSpanData::Solid)
|
||||
&& s->intOpacity == 256
|
||||
&& (mode == QPainter::CompositionMode_Source
|
||||
|| (mode == QPainter::CompositionMode_SourceOver
|
||||
&& (mode == QPainter::CompositionMode_SourceOver
|
||||
|| (mode == QPainter::CompositionMode_Source
|
||||
&& s->penData.solidColor.isOpaque()));
|
||||
}
|
||||
|
||||
|
@ -1716,8 +1716,8 @@ void QPainter::restore()
|
||||
|
||||
static inline void qt_cleanup_painter_state(QPainterPrivate *d)
|
||||
{
|
||||
qDeleteAll(d->states);
|
||||
d->states.clear();
|
||||
delete d->state;
|
||||
d->state = 0;
|
||||
d->engine = 0;
|
||||
d->device = 0;
|
||||
|
@ -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)
|
||||
{
|
||||
if (const_alpha == 255)
|
||||
return blend_pixel(dst, src);
|
||||
if (!src.isTransparent()) {
|
||||
src = multiplyAlpha255(src, const_alpha);
|
||||
dst = src + multiplyAlpha65535(dst, 65535 - src.alpha());
|
||||
|
@ -3524,7 +3524,10 @@ QSize QMetalSwapChain::surfacePixelSize()
|
||||
if (v) {
|
||||
CAMetalLayer *layer = (CAMetalLayer *) [v 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));
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
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
|
||||
|
||||
QT += \
|
||||
@ -19,7 +15,8 @@ INCLUDEPATH += \
|
||||
$$PWD \
|
||||
$$QT_SOURCE_TREE/src/3rdparty/android
|
||||
|
||||
SOURCES += $$PWD/androidplatformplugin.cpp \
|
||||
SOURCES += $$PWD/main.cpp \
|
||||
$$PWD/androidplatformplugin.cpp \
|
||||
$$PWD/androidcontentfileengine.cpp \
|
||||
$$PWD/androiddeadlockprotector.cpp \
|
||||
$$PWD/androidjnimain.cpp \
|
||||
@ -92,4 +89,5 @@ qtConfig(vulkan) {
|
||||
}
|
||||
|
||||
PLUGIN_TYPE = platforms
|
||||
PLUGIN_CLASS_NAME = QAndroidIntegrationPlugin
|
||||
load(qt_plugin)
|
||||
|
@ -68,8 +68,6 @@
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static JavaVM *m_javaVM = nullptr;
|
||||
|
63
src/plugins/platforms/android/main.cpp
Normal file
63
src/plugins/platforms/android/main.cpp
Normal 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
|
@ -65,8 +65,8 @@ public:
|
||||
void setParent(const QPlatformWindow *window) override;
|
||||
WId winId() const override { return m_windowId; }
|
||||
|
||||
bool setMouseGrabEnabled(bool grab) override { return false; }
|
||||
bool setKeyboardGrabEnabled(bool grab) override { return false; }
|
||||
bool setMouseGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; }
|
||||
bool setKeyboardGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; }
|
||||
|
||||
QAndroidPlatformScreen *platformScreen() const;
|
||||
|
||||
|
@ -161,7 +161,6 @@ public:
|
||||
Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
|
||||
Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState();
|
||||
Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen();
|
||||
Q_NOTIFICATION_HANDLER(NSWindowDidChangeBackingPropertiesNotification) void windowDidChangeBackingProperties();
|
||||
Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose();
|
||||
|
||||
bool windowShouldClose();
|
||||
|
@ -1262,17 +1262,6 @@ void QCocoaWindow::windowDidChangeScreen()
|
||||
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()
|
||||
{
|
||||
|
@ -173,20 +173,6 @@
|
||||
}
|
||||
#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
|
||||
{
|
||||
if (!NSThread.isMainThread) {
|
||||
@ -211,17 +197,16 @@
|
||||
|
||||
- (void)viewDidChangeBackingProperties
|
||||
{
|
||||
CALayer *layer = self.layer;
|
||||
if (!layer)
|
||||
return;
|
||||
qCDebug(lcQpaDrawing) << "Backing properties changed for" << self;
|
||||
|
||||
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
|
||||
if ([layer isKindOfClass:CAMetalLayer.class]) {
|
||||
[self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
// Ideally we would plumb this situation through QPA in a way that lets
|
||||
// clients invalidate their own caches, recreate QBackingStore, etc.
|
||||
// For now we trigger an expose, and let QCocoaBackingStore deal with
|
||||
// buffer invalidation internally.
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -881,6 +881,14 @@ bool QSqlDatabase::rollback()
|
||||
connection name must be passed to addDatabase() at connection
|
||||
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
|
||||
Service Name.
|
||||
|
||||
|
@ -2735,6 +2735,11 @@ static void updateObjects(const QList<const QObject *>& objects)
|
||||
if (auto widget = qobject_cast<QWidget*>(const_cast<QObject*>(object))) {
|
||||
widget->style()->polish(widget);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1726,7 +1726,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
|
||||
option->activeSubControls = d->hoverControl;
|
||||
}
|
||||
|
||||
option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds)
|
||||
option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds, nullptr, this)
|
||||
? stepEnabled()
|
||||
: (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled);
|
||||
|
||||
|
@ -42,7 +42,11 @@ class tst_QNumeric: public QObject
|
||||
private slots:
|
||||
void fuzzyCompare_data();
|
||||
void fuzzyCompare();
|
||||
void qNanInf();
|
||||
void rawNaN_data();
|
||||
void rawNaN();
|
||||
void generalNaN_data();
|
||||
void generalNaN();
|
||||
void infinity();
|
||||
void classifyfp();
|
||||
void floatDistance_data();
|
||||
void floatDistance();
|
||||
@ -53,6 +57,8 @@ private slots:
|
||||
void mulOverflow_data();
|
||||
void mulOverflow();
|
||||
void signedOverflow();
|
||||
private:
|
||||
void checkNaN(double nan);
|
||||
};
|
||||
|
||||
void tst_QNumeric::fuzzyCompare_data()
|
||||
@ -92,44 +98,89 @@ void tst_QNumeric::fuzzyCompare()
|
||||
# pragma GCC optimize "no-fast-math"
|
||||
#endif
|
||||
|
||||
void tst_QNumeric::qNanInf()
|
||||
void tst_QNumeric::checkNaN(double nan)
|
||||
{
|
||||
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404)
|
||||
QSKIP("Non-conformant fast math mode is enabled, cannot run test");
|
||||
#endif
|
||||
double nan = qQNaN();
|
||||
#define CHECKNAN(value) \
|
||||
do { \
|
||||
const double v = (value); \
|
||||
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(!(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);
|
||||
#ifdef Q_LITTLE_ENDIAN
|
||||
const uchar bytes[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f };
|
||||
#else
|
||||
const uchar bytes[] = { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
|
||||
#endif
|
||||
memcpy(&nan, bytes, 8);
|
||||
QVERIFY(!qIsFinite(nan));
|
||||
QVERIFY(!qIsInf(nan));
|
||||
QVERIFY(qIsNaN(nan));
|
||||
QVERIFY(qIsNaN(-nan));
|
||||
QVERIFY(!(nan == nan));
|
||||
QVERIFY(qIsNaN(0.0 * nan));
|
||||
QCOMPARE(qFpClassify(nan), FP_NAN);
|
||||
CHECKNAN(nan);
|
||||
CHECKNAN(nan + 1);
|
||||
CHECKNAN(nan - 1);
|
||||
CHECKNAN(-nan);
|
||||
CHECKNAN(nan * 2.0);
|
||||
CHECKNAN(nan / 2.0);
|
||||
CHECKNAN(1.0 / nan);
|
||||
CHECKNAN(0.0 / nan);
|
||||
CHECKNAN(0.0 * nan);
|
||||
|
||||
// When any NaN is expected, any NaN will do:
|
||||
QCOMPARE(nan, nan);
|
||||
QCOMPARE(nan, -nan);
|
||||
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(qIsInf(inf));
|
||||
@ -138,16 +189,23 @@ void tst_QNumeric::qNanInf()
|
||||
QVERIFY(qIsInf(-inf));
|
||||
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(qFuzzyCompare(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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -568,11 +568,18 @@
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</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">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<Message type="info" file="" line="0">
|
||||
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description>
|
||||
<Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
|
||||
</Message>
|
||||
<Duration msecs="0"/>
|
||||
|
@ -143,9 +143,11 @@ ok 18 - slotEmittingSignalOldSyntax(queued)
|
||||
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
|
||||
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
|
||||
ok 19 - variousTypes()
|
||||
ok 20 - cleanupTestCase()
|
||||
# Signal: QThread(_POINTER_) finished ()
|
||||
1..20
|
||||
# tests 20
|
||||
# pass 20
|
||||
# Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
|
||||
ok 20 - deletingSender()
|
||||
ok 21 - cleanupTestCase()
|
||||
# Signal: QThread(_POINTER_) finished ()
|
||||
1..21
|
||||
# tests 21
|
||||
# pass 21
|
||||
# fail 0
|
||||
|
@ -56,6 +56,9 @@
|
||||
##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[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[testFinished name='cleanupTestCase()' flowId='tst_Signaldumper']
|
||||
##teamcity[testSuiteFinished name='tst_Signaldumper' flowId='tst_Signaldumper']
|
||||
|
@ -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())
|
||||
PASS : tst_Signaldumper::variousTypes()
|
||||
INFO : tst_Signaldumper::deletingSender() Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
|
||||
PASS : tst_Signaldumper::deletingSender()
|
||||
PASS : tst_Signaldumper::cleanupTestCase()
|
||||
INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished ()
|
||||
Totals: 20 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
|
||||
INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished ()
|
||||
Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
|
||||
********* Finished testing of tst_Signaldumper *********
|
||||
|
@ -570,12 +570,19 @@
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</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">
|
||||
<Incident type="pass" file="" line="0" />
|
||||
<Duration msecs="0"/>
|
||||
</TestFunction>
|
||||
<Message type="info" file="" line="0">
|
||||
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description>
|
||||
<Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
|
||||
</Message>
|
||||
<Duration msecs="0"/>
|
||||
</TestCase>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?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>
|
||||
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
|
||||
<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" -->
|
||||
</testcase>
|
||||
<testcase result="pass" name="deletingSender">
|
||||
<!-- message="Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()" type="info" -->
|
||||
</testcase>
|
||||
<testcase result="pass" name="cleanupTestCase">
|
||||
<!-- message="Signal: QThread(_POINTER_) finished ()" type="info" -->
|
||||
<!-- message=" Signal: QThread(_POINTER_) finished ()" type="info" -->
|
||||
</testcase>
|
||||
<system-err>
|
||||
<![CDATA[Signal: QThread(_POINTER_) started ()]]>
|
||||
@ -279,6 +282,7 @@
|
||||
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()]]>
|
||||
<![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>
|
||||
</testsuite>
|
||||
|
@ -56,6 +56,8 @@ private slots:
|
||||
void slotEmittingSignalOldSyntax();
|
||||
|
||||
void variousTypes();
|
||||
|
||||
void deletingSender();
|
||||
};
|
||||
|
||||
void tst_Signaldumper::addConnectionTypeData()
|
||||
@ -413,5 +415,14 @@ void tst_Signaldumper::variousTypes()
|
||||
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)
|
||||
#include "tst_signaldumper.moc"
|
||||
|
@ -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.frag -o shadowmap.frag.qsb
|
||||
qsb --glsl "120,300 es" --hlsl 50 --msl 12 main.vert -o main.vert.qsb
|
||||
|
Loading…
Reference in New Issue
Block a user