summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp2
-rw-r--r--src/gui/image/image.pri2
-rw-r--r--src/gui/image/qbmphandler.cpp2
-rw-r--r--src/gui/image/qicon_p.h2
-rw-r--r--src/gui/image/qimage.cpp24
-rw-r--r--src/gui/image/qimage_avx2.cpp61
-rw-r--r--src/gui/image/qimage_conversions.cpp54
-rw-r--r--src/gui/image/qimage_sse4.cpp70
-rw-r--r--src/gui/image/qimage_ssse3.cpp4
-rw-r--r--src/gui/image/qjpeghandler.cpp2
-rw-r--r--src/gui/image/qpicture.cpp4
-rw-r--r--src/gui/image/qpixmap.cpp3
-rw-r--r--src/gui/image/qpnghandler.cpp8
-rw-r--r--src/gui/kernel/qcursor.cpp4
-rw-r--r--src/gui/kernel/qguiapplication.cpp16
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qinputdevicemanager.cpp24
-rw-r--r--src/gui/kernel/qinputdevicemanager_p.h3
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp7
-rw-r--r--src/gui/kernel/qplatformmenu.h1
-rw-r--r--src/gui/kernel/qwindow.cpp2
-rw-r--r--src/gui/opengl/qopengl_p.h18
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp2
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp12
-rw-r--r--src/gui/painting/painting.pri2
-rw-r--r--src/gui/painting/qblendfunctions.cpp4
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp119
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp54
-rw-r--r--src/gui/painting/qdrawhelper_p.h18
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp8
-rw-r--r--src/gui/painting/qdrawhelper_sse4.cpp79
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp6
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h4
-rw-r--r--src/gui/painting/qimagescale.cpp44
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp12
-rw-r--r--src/gui/painting/qpaintengineex.cpp24
-rw-r--r--src/gui/painting/qpainter.cpp13
-rw-r--r--src/gui/painting/qpainter_p.h4
-rw-r--r--src/gui/text/qfontengine.cpp3
-rw-r--r--src/gui/text/qfontengine_ft.cpp84
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/qfontsubset.cpp2
-rw-r--r--src/gui/text/qzip.cpp6
-rw-r--r--src/gui/text/text.pri2
46 files changed, 569 insertions, 263 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 18af0e8092..fb30b5f8ee 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -1718,7 +1718,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
return d;
}
d.nospace();
- d << "QAccessibleInterface(" << hex << (void *) iface << dec;
+ d << "QAccessibleInterface(" << hex << (const void *) iface << dec;
if (iface->isValid()) {
d << " name=" << iface->text(QAccessible::Name) << " ";
d << "role=" << qAccessibleRoleString(iface->role()) << " ";
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 7022a6efd0..8db944e5e3 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -80,6 +80,8 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD
SSE2_SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.cpp
+SSE4_1_SOURCES += image/qimage_sse4.cpp
+AVX2_SOURCES += image/qimage_avx2.cpp
NEON_SOURCES += image/qimage_neon.cpp
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 61353ebe6d..7a491d8736 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -639,7 +639,7 @@ bool qt_write_dib(QDataStream &s, QImage image)
if (nbits == 1 || nbits == 8) { // direct output
for (y=image.height()-1; y>=0; y--) {
- if (d->write((char*)image.constScanLine(y), bpl) == -1)
+ if (d->write((const char*)image.constScanLine(y), bpl) == -1)
return false;
}
return true;
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index e0fec112b5..8b42e770fa 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -99,7 +99,7 @@ inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const
pixmap.setDevicePixelRatio(1.0);
}
-class QPixmapIconEngine : public QIconEngine {
+class Q_GUI_EXPORT QPixmapIconEngine : public QIconEngine {
public:
QPixmapIconEngine();
QPixmapIconEngine(const QPixmapIconEngine &);
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index e33ab24243..8ca58d4e5e 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -1433,6 +1433,10 @@ void QImage::setDevicePixelRatio(qreal scaleFactor)
{
if (!d)
return;
+
+ if (scaleFactor == d->devicePixelRatio)
+ return;
+
detach();
d->devicePixelRatio = scaleFactor;
}
@@ -2049,7 +2053,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format,
if (format == QImage::Format_Indexed8) {
for (int y=0; y<h; ++y) {
- QRgb *src_pixels = (QRgb *) src.scanLine(y);
+ const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
uchar *dest_pixels = (uchar *) dest.scanLine(y);
for (int x=0; x<w; ++x) {
int src_pixel = src_pixels[x];
@@ -2065,7 +2069,7 @@ static QImage convertWithPalette(const QImage &src, QImage::Format format,
QVector<QRgb> table = clut;
table.resize(2);
for (int y=0; y<h; ++y) {
- QRgb *src_pixels = (QRgb *) src.scanLine(y);
+ const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
for (int x=0; x<w; ++x) {
int src_pixel = src_pixels[x];
int value = cache.value(src_pixel, -1);
@@ -2676,7 +2680,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
return img32.createHeuristicMask(clipTight);
}
-#define PIX(x,y) (*((QRgb*)scanLine(y)+x) & 0x00ffffff)
+#define PIX(x,y) (*((const QRgb*)scanLine(y)+x) & 0x00ffffff)
int w = width();
int h = height();
@@ -2710,7 +2714,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
ypp = ypc;
ypc = ypn;
ypn = (y == h-1) ? 0 : m.scanLine(y+1);
- QRgb *p = (QRgb *)scanLine(y);
+ const QRgb *p = (const QRgb *)scanLine(y);
for (x = 0; x < w; x++) {
// slowness here - it's possible to do six of these tests
// together in one go. oh well.
@@ -2736,7 +2740,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
ypp = ypc;
ypc = ypn;
ypn = (y == h-1) ? 0 : m.scanLine(y+1);
- QRgb *p = (QRgb *)scanLine(y);
+ const QRgb *p = (const QRgb *)scanLine(y);
for (x = 0; x < w; x++) {
if ((*p & 0x00ffffff) != background) {
if (x > 0)
@@ -2780,7 +2784,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
if (depth() == 32) {
for (int h = 0; h < d->height; h++) {
- const uint *sl = (uint *) scanLine(h);
+ const uint *sl = (const uint *) scanLine(h);
for (int w = 0; w < d->width; w++) {
if (sl[w] == color)
*(s + (w >> 3)) |= (1 << (w & 7));
@@ -3873,7 +3877,7 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth
case 16: // 16 bpp transform
while (dptr < maxp) {
if (trigx < maxws && trigy < maxhs)
- *((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>12) +
+ *((ushort*)dptr) = *((const ushort *)(sptr+sbpl*(trigy>>12) +
((trigx>>12)<<1)));
trigx += m11;
trigy += m12;
@@ -3899,7 +3903,7 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth
case 32: // 32 bpp transform
while (dptr < maxp) {
if (trigx < maxws && trigy < maxhs)
- *((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>12) +
+ *((uint*)dptr) = *((const uint *)(sptr+sbpl*(trigy>>12) +
((trigx>>12)<<2)));
trigx += m11;
trigy += m12;
@@ -4046,7 +4050,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
// Slight optimization since alphachannels are returned as 8-bit grays.
if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) {
const uchar *src_data = alphaChannel.d->data;
- const uchar *dest_data = d->data;
+ uchar *dest_data = d->data;
for (int y=0; y<h; ++y) {
const uchar *src = src_data;
QRgb *dest = (QRgb *)dest_data;
@@ -4067,7 +4071,7 @@ void QImage::setAlphaChannel(const QImage &alphaChannel)
} else {
const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
const uchar *src_data = sourceImage.d->data;
- const uchar *dest_data = d->data;
+ uchar *dest_data = d->data;
for (int y=0; y<h; ++y) {
const QRgb *src = (const QRgb *) src_data;
QRgb *dest = (QRgb *) dest_data;
diff --git a/src/gui/image/qimage_avx2.cpp b/src/gui/image/qimage_avx2.cpp
new file mode 100644
index 0000000000..c52baec948
--- /dev/null
+++ b/src/gui/image/qimage_avx2.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qimage.h>
+#include <private/qdrawhelper_p.h>
+#include <private/qimage_p.h>
+#include <private/qsimd_p.h>
+
+#ifdef QT_COMPILER_SUPPORTS_AVX2
+
+QT_BEGIN_NAMESPACE
+
+void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const uint *src_data = (uint *) src->data;
+ uint *dest_data = (uint *) dest->data;
+ for (int i = 0; i < src->height; ++i) {
+ qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width);
+ src_data += src->bytes_per_line >> 2;
+ dest_data += dest->bytes_per_line >> 2;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_COMPILER_SUPPORTS_AVX2
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 5103d820d6..417c185c78 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include <private/qdrawhelper_p.h>
-#include <private/qdrawingprimitive_sse2_p.h>
#include <private/qguiapplication_p.h>
#include <private/qsimd_p.h>
#include <private/qimage_p.h>
@@ -110,17 +109,6 @@ static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint
return buffer;
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]);
- return buffer;
-}
-#endif
-
static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -129,6 +117,10 @@ static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *
return buffer;
}
+#ifdef QT_COMPILER_SUPPORTS_SSE4_1
+extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+#endif
+
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
// Cannot be used with indexed formats.
@@ -152,7 +144,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
if (src->format == QImage::Format_RGB32)
convertToARGB32PM = convertRGB32ToARGB32PM;
if (dest->format == QImage::Format_RGB32) {
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
+#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
else
@@ -201,7 +193,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (data->format == QImage::Format_RGB32)
convertToARGB32PM = convertRGB32ToARGB32PM;
if (dst_format == QImage::Format_RGB32) {
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
+#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
else
@@ -257,7 +249,7 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla
return true;
}
-static inline void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
@@ -281,15 +273,6 @@ static inline void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *s
}
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
-QT_FUNCTION_TARGET(SSE4_1)
-static void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- // Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
- convert_ARGB_to_ARGB_PM(dest, src, flags);
-}
-#endif
-
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, const uchar *src_data, int len)
{
int pixel = 0;
@@ -303,7 +286,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, con
// Handle 4 pixels at a time 12 bytes input to 16 bytes output.
for (; pixel + 3 < len; pixel += 4) {
- const quint32 *src_packed = (quint32 *) src_data;
+ const quint32 *src_packed = (const quint32 *) src_data;
const quint32 src1 = qFromBigEndian(src_packed[0]);
const quint32 src2 = qFromBigEndian(src_packed[1]);
const quint32 src3 = qFromBigEndian(src_packed[2]);
@@ -338,7 +321,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgbx8888(quint32 *dest_data,
// Handle 4 pixels at a time 12 bytes input to 16 bytes output.
for (; pixel + 3 < len; pixel += 4) {
- const quint32 *src_packed = (quint32 *) src_data;
+ const quint32 *src_packed = (const quint32 *) src_data;
const quint32 src1 = src_packed[0];
const quint32 src2 = src_packed[1];
const quint32 src3 = src_packed[2];
@@ -1109,12 +1092,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src,
} else { // 32 bit image
if (fromalpha) {
while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
+ *b2++ = 255 - (*(const uint*)p >> 24);
p += 4;
}
} else {
while (p < end) {
- *b2++ = qGray(*(uint*)p);
+ *b2++ = qGray(*(const uint*)p);
p += 4;
}
}
@@ -1132,12 +1115,12 @@ void dither_to_Mono(QImageData *dst, const QImageData *src,
} else { // 24 bit image
if (fromalpha) {
while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
+ *b2++ = 255 - (*(const uint*)p >> 24);
p += 4;
}
} else {
while (p < end) {
- *b2++ = qGray(*(uint*)p);
+ *b2++ = qGray(*(const uint*)p);
p += 4;
}
}
@@ -2804,13 +2787,22 @@ void qInitImageConversions()
}
#endif
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
+#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__)
if (qCpuHasFeature(SSE4_1)) {
+ extern void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
}
#endif
+#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__)
+ if (qCpuHasFeature(AVX2)) {
+ extern void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2;
+ qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2;
+ }
+#endif
+
#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
diff --git a/src/gui/image/qimage_sse4.cpp b/src/gui/image/qimage_sse4.cpp
new file mode 100644
index 0000000000..5fad4f572a
--- /dev/null
+++ b/src/gui/image/qimage_sse4.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qimage.h>
+#include <private/qdrawhelper_p.h>
+#include <private/qdrawingprimitive_sse2_p.h>
+#include <private/qimage_p.h>
+#include <private/qsimd_p.h>
+
+#ifdef QT_COMPILER_SUPPORTS_SSE4_1
+
+QT_BEGIN_NAMESPACE
+
+const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]);
+ return buffer;
+}
+
+void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const uint *src_data = (uint *) src->data;
+ uint *dest_data = (uint *) dest->data;
+ for (int i = 0; i < src->height; ++i) {
+ qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width);
+ src_data += src->bytes_per_line >> 2;
+ dest_data += dest->bytes_per_line >> 2;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_COMPILER_SUPPORTS_SSE4_1
diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp
index 0f8244689e..4597661776 100644
--- a/src/gui/image/qimage_ssse3.cpp
+++ b/src/gui/image/qimage_ssse3.cpp
@@ -65,7 +65,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con
// Mask to have alpha = 0xff
const __m128i alphaMask = _mm_set1_epi32(0xff000000);
- __m128i *inVectorPtr = (__m128i *)src;
+ const __m128i *inVectorPtr = (const __m128i *)src;
__m128i *dstVectorPtr = (__m128i *)dst;
const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels
@@ -110,7 +110,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con
_mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
++dstVectorPtr;
}
- src = (uchar *)inVectorPtr;
+ src = (const uchar *)inVectorPtr;
dst = (quint32 *)dstVectorPtr;
while (dst != end) {
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index b1146c4297..aff7b79807 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -514,7 +514,7 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
comment += it.value().toLatin1();
if (comment.length() > 65530)
comment.truncate(65530);
- jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)comment.constData(), comment.size());
+ jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
}
}
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 8b62183c20..b63be19153 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -1362,7 +1362,7 @@ void QPictureIO::init()
QPictureIO::~QPictureIO()
{
if (d->parameters)
- delete [] (char*)d->parameters;
+ delete [] d->parameters;
delete d;
}
@@ -1671,7 +1671,7 @@ const char *QPictureIO::parameters() const
void QPictureIO::setParameters(const char *parameters)
{
if (d->parameters)
- delete [] (char*)d->parameters;
+ delete [] d->parameters;
d->parameters = qstrdup(parameters);
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 0a9b55ed24..db6ae54d26 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -682,6 +682,9 @@ void QPixmap::setDevicePixelRatio(qreal scaleFactor)
if (isNull())
return;
+ if (scaleFactor == data->devicePixelRatio())
+ return;
+
detach();
data->setDevicePixelRatio(scaleFactor);
}
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index c3ffd00e15..3c88d2e9c1 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -942,7 +942,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
// 0123456789aBC
data[0xB] = looping%0x100;
data[0xC] = looping/0x100;
- png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13);
+ png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13);
}
if (ms_delay >= 0 || disposal!=Unspecified) {
uchar data[4];
@@ -950,7 +950,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
data[1] = 0;
data[2] = (ms_delay/10)/0x100; // hundredths
data[3] = (ms_delay/10)%0x100;
- png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4);
+ png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4);
}
int height = image.height();
@@ -966,7 +966,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
{
png_bytep* row_pointers = new png_bytep[height];
for (int y=0; y<height; y++)
- row_pointers[y] = (png_bytep)image.constScanLine(y);
+ row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
png_write_image(png_ptr, row_pointers);
delete [] row_pointers;
}
@@ -978,7 +978,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, vo
png_bytep row_pointers[1];
for (int y=0; y<height; y++) {
row = image.copy(0, y, width, 1).convertToFormat(fmt);
- row_pointers[0] = png_bytep(row.constScanLine(0));
+ row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
png_write_rows(png_ptr, row_pointers, 1);
}
}
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 954efa38ed..7e073370f2 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -33,8 +33,6 @@
#include "qcursor.h"
-#ifndef QT_NO_CURSOR
-
#include <qcoreapplication.h>
#include <qbitmap.h>
#include <qimage.h>
@@ -259,6 +257,8 @@ void QCursor::setPos(int x, int y)
QCursor::setPos(QGuiApplication::primaryScreen(), x, y);
}
+#ifndef QT_NO_CURSOR
+
/*!
\fn void QCursor::setPos (const QPoint &p)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 8c49b3a2b5..3d21b4affc 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -147,12 +147,15 @@ QString *QGuiApplicationPrivate::displayName = 0;
QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
+
ulong QGuiApplicationPrivate::mousePressTime = 0;
Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
int QGuiApplicationPrivate::mousePressX = 0;
int QGuiApplicationPrivate::mousePressY = 0;
int QGuiApplicationPrivate::mouse_double_click_distance = -1;
+QWindow *QGuiApplicationPrivate::currentMousePressWindow = 0;
+
static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
static bool force_reverse = false;
@@ -1703,6 +1706,17 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (e->nullWindow()) {
window = QGuiApplication::topLevelAt(globalPoint.toPoint());
if (window) {
+ // Moves and the release following a press must go to the same
+ // window, even if the cursor has moved on over another window.
+ if (e->buttons != Qt::NoButton) {
+ if (!currentMousePressWindow)
+ currentMousePressWindow = window;
+ else
+ window = currentMousePressWindow;
+ } else if (currentMousePressWindow) {
+ window = currentMousePressWindow;
+ currentMousePressWindow = 0;
+ }
QPointF delta = globalPoint - globalPoint.toPoint();
localPoint = window->mapFromGlobal(globalPoint.toPoint()) + delta;
}
@@ -2554,7 +2568,7 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
}
if (availableGeometryChanged)
- emit s->availableGeometryChanged(s->geometry());
+ emit s->availableGeometryChanged(s->availableGeometry());
if (geometryChanged || availableGeometryChanged) {
foreach (QScreen* sibling, s->virtualSiblings())
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 0c00e06499..7ae6e64b26 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -200,6 +200,7 @@ public:
static Qt::MouseButtons tabletState;
static QWindow *tabletPressTarget;
static QWindow *currentMouseWindow;
+ static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
#ifndef QT_NO_CLIPBOARD
diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp
index 1a3e6b8119..d0dd8a4e7c 100644
--- a/src/gui/kernel/qinputdevicemanager.cpp
+++ b/src/gui/kernel/qinputdevicemanager.cpp
@@ -36,6 +36,25 @@
QT_BEGIN_NAMESPACE
+/*!
+ \class QInputDeviceManager
+ \internal
+
+ \brief QInputDeviceManager acts as a communication hub between QtGui and the input handlers.
+
+ On embedded platforms the input handling code is either compiled into the platform
+ plugin or is loaded dynamically as a generic plugin without any interface. The input
+ handler in use may also change between each run (e.g. evdevmouse/keyboard/touch
+ vs. libinput). QWindowSystemInterface is too limiting when Qt (the platform plugin) is
+ acting as a windowing system, and is one way only.
+
+ QInputDeviceManager solves this by providing a global object that is used to communicate
+ from the input handlers to the rest of Qt (e.g. the number of connected mice, which may
+ be important information for the cursor drawing code), and vice-versa (e.g. to indicate
+ to the input handler that a manual cursor position change was requested by the
+ application via QCursor::setPos and thus any internal state has to be updated accordingly).
+*/
+
QInputDeviceManager::QInputDeviceManager(QObject *parent)
: QObject(*new QInputDeviceManagerPrivate, parent)
{
@@ -61,4 +80,9 @@ void QInputDeviceManagerPrivate::setDeviceCount(QInputDeviceManager::DeviceType
}
}
+void QInputDeviceManager::setCursorPos(const QPoint &pos)
+{
+ emit cursorPositionChangeRequested(pos);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h
index cc55c8b4e5..15c84d1a82 100644
--- a/src/gui/kernel/qinputdevicemanager_p.h
+++ b/src/gui/kernel/qinputdevicemanager_p.h
@@ -68,8 +68,11 @@ public:
int deviceCount(DeviceType type) const;
+ void setCursorPos(const QPoint &pos);
+
signals:
void deviceListChanged(DeviceType type);
+ void cursorPositionChangeRequested(const QPoint &pos);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 7da95ffcec..2749b05691 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -112,6 +112,7 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
bool *swizzleRandB,
const QRect &subRect)
{
+#ifndef QT_NO_OPENGL
if (!QOpenGLContext::currentContext())
return false;
@@ -172,6 +173,12 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
return true;
+#else
+ Q_UNUSED(graphicsBuffer)
+ Q_UNUSED(swizzleRandB)
+ Q_UNUSED(subRect)
+ return false;
+#endif // QT_NO_OPENGL
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 0536c3688c..baa1e460d7 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -103,6 +103,7 @@ public:
virtual void setText(const QString &text) = 0;
virtual void setIcon(const QIcon &icon) = 0;
virtual void setEnabled(bool enabled) = 0;
+ virtual bool isEnabled() const { return true; }
virtual void setVisible(bool visible) = 0;
virtual void setMinimumWidth(int width) { Q_UNUSED(width); }
virtual void setFont(const QFont &font) { Q_UNUSED(font); }
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 06db4e81fa..06674d204d 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1599,6 +1599,8 @@ void QWindow::destroy()
QGuiApplicationPrivate::focus_window = parent();
if (QGuiApplicationPrivate::currentMouseWindow == this)
QGuiApplicationPrivate::currentMouseWindow = parent();
+ if (QGuiApplicationPrivate::currentMousePressWindow == this)
+ QGuiApplicationPrivate::currentMousePressWindow = parent();
if (QGuiApplicationPrivate::tabletPressTarget == this)
QGuiApplicationPrivate::tabletPressTarget = parent();
diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h
index 377440455a..e04ae05120 100644
--- a/src/gui/opengl/qopengl_p.h
+++ b/src/gui/opengl/qopengl_p.h
@@ -77,6 +77,9 @@ public:
struct Gpu {
Gpu() : vendorId(0), deviceId(0) {}
bool isValid() const { return deviceId; }
+ bool equals(const Gpu &other) const {
+ return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion;
+ }
uint vendorId;
uint deviceId;
@@ -93,6 +96,21 @@ public:
static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName);
};
+inline bool operator==(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
+{
+ return a.equals(b);
+}
+
+inline bool operator!=(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
+{
+ return !a.equals(b);
+}
+
+inline uint qHash(const QOpenGLConfig::Gpu &gpu)
+{
+ return qHash(gpu.vendorId) + qHash(gpu.deviceId) + qHash(gpu.driverVersion);
+}
+
QT_END_NAMESPACE
#endif // QOPENGL_H
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index e87f7bfcef..a9a4adaddc 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -1229,7 +1229,7 @@ void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stop
GLenum primitive)
{
// Now setup the pointer to the vertex array:
- setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)data);
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
int previousStop = 0;
for (int i=0; i<stopCount; ++i) {
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index 386c4af232..3635a7dd1b 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -40,8 +40,16 @@ QT_BEGIN_NAMESPACE
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
{
- // Resolve EXT_direct_state_access entry points if present
- if (!context->isOpenGLES()
+ // Resolve EXT_direct_state_access entry points if present.
+
+ // However, disable it on some systems where DSA is known to be unreliable.
+ bool allowDSA = true;
+ const char *renderer = reinterpret_cast<const char *>(context->functions()->glGetString(GL_RENDERER));
+ // QTBUG-40653, QTBUG-44988
+ if (renderer && strstr(renderer, "AMD Radeon HD"))
+ allowDSA = false;
+
+ if (allowDSA && !context->isOpenGLES()
&& context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT")));
TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 0507cc128f..3010d4052a 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -94,6 +94,8 @@ SOURCES += \
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp
+AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
!ios {
CONFIG += no_clang_integrated_as
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 1564e25016..478fe6564c 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -245,7 +245,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
}
quint16 *dst = (quint16 *) destPixels;
- quint32 *src = (quint32 *) srcPixels;
+ const quint32 *src = (const quint32 *) srcPixels;
for (int y=0; y<h; ++y) {
for (int x=0; x<w; ++x) {
@@ -282,7 +282,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
}
}
dst = (quint16 *) (((uchar *) dst) + dbpl);
- src = (quint32 *) (((uchar *) src) + sbpl);
+ src = (const quint32 *) (((const uchar *) src) + sbpl);
}
}
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 93c95e4a86..f82b098012 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -437,8 +437,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
+ int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
- x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
+ x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
if (swapped) {
lastPixel.x = x >> 16;
@@ -468,8 +469,9 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6;
+ int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
- y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
+ y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
if (swapped) {
lastPixel.x = x;
@@ -762,9 +764,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
+ int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
- x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
+ x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
// calculate first and last pixel and perform dropout control
QCosmeticStroker::Point first;
@@ -837,9 +840,10 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6;
+ int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
- y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
+ y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
// calculate first and last pixel to perform dropout control
QCosmeticStroker::Point first;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 04857fb0d6..538389f15f 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -355,24 +355,11 @@ static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
return src;
}
-static inline const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = qPremultiply(src[i]);
- return buffer;
-}
-
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *clut)
+static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- // Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
- return convertARGB32ToARGB32PM(buffer, src, count, layout, clut);
+ return qt_convertARGB32ToARGB32PM(buffer, src, count);
}
-#endif
-
static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
@@ -382,24 +369,12 @@ static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const u
return buffer;
}
-static inline const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count,
+static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
- return buffer;
+ return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *clut)
-{
- // Twice as fast autovectorized due to SSE4.1 PMULLD instructions.
- return convertRGBA8888ToARGB32PM(buffer, src, count, layout, clut);
-}
-#endif
-
static const uint *QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -424,18 +399,6 @@ static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uin
return buffer;
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = qUnpremultiply_sse4(src[i]);
- return buffer;
-}
-#endif
-
-
static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -452,17 +415,6 @@ static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const u
return buffer;
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i]));
- return buffer;
-}
-#endif
-
static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
@@ -479,17 +431,6 @@ static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint
return buffer;
}
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
-QT_FUNCTION_TARGET(SSE4_1)
-static const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i]));
- return buffer;
-}
-#endif
-
template<QtPixelOrder PixelOrder>
static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
@@ -1454,7 +1395,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
lim -= 3;
for (; f < lim; x += 4, f += 4) {
// Load 4 pixels from s1, and split the alpha-green and red-blue component
- __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x));
+ __m128i top = _mm_loadu_si128((const __m128i*)((const uint *)(s1)+x));
__m128i topAG = _mm_srli_epi16(top, 8);
__m128i topRB = _mm_and_si128(top, colorMask);
// Multiplies each colour component by idisty
@@ -1462,7 +1403,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
topRB = _mm_mullo_epi16 (topRB, idisty_);
// Same for the s2 vector
- __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x));
+ __m128i bottom = _mm_loadu_si128((const __m128i*)((const uint *)(s2)+x));
__m128i bottomAG = _mm_srli_epi16(bottom, 8);
__m128i bottomRB = _mm_and_si128(bottom, colorMask);
bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
@@ -4741,7 +4682,7 @@ static void blend_untransformed_argb(int count, const QSpan *spans, void *userDa
length = image_width - sx;
if (length > 0) {
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
- const uint *src = (uint *)data->texture.scanLine(sy) + sx;
+ const uint *src = (const uint *)data->texture.scanLine(sy) + sx;
uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
op.func(dest, src, length, coverage);
}
@@ -4840,7 +4781,7 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans, void *user
length = image_width - sx;
if (length > 0) {
quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + x;
- const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx;
if (coverage == 255) {
memcpy(dest, src, length * sizeof(quint16));
} else {
@@ -4939,7 +4880,7 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData)
int l = qMin(image_width - sx, length);
if (buffer_size < l)
l = buffer_size;
- const uint *src = (uint *)data->texture.scanLine(sy) + sx;
+ const uint *src = (const uint *)data->texture.scanLine(sy) + sx;
uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
op.func(dest, src, l, coverage);
x += l;
@@ -4998,7 +4939,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
if (buffer_size < l)
l = buffer_size;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx;
- const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx;
memcpy(dest, src, l * sizeof(quint16));
length -= l;
tx += l;
@@ -5032,7 +4973,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
if (buffer_size < l)
l = buffer_size;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x;
- const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx;
blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
x += l;
length -= l;
@@ -5108,8 +5049,8 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, voi
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
- const quint16 *src1 = (quint16*)data->texture.scanLine(y1);
- const quint16 *src2 = (quint16*)data->texture.scanLine(y2);
+ const quint16 *src1 = (const quint16*)data->texture.scanLine(y1);
+ const quint16 *src2 = (const quint16*)data->texture.scanLine(y2);
quint16 tl = src1[x1];
const quint16 tr = src1[x2];
quint16 bl = src2[x1];
@@ -5195,8 +5136,8 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, voi
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
- const quint16 *src1 = (quint16 *)data->texture.scanLine(y1);
- const quint16 *src2 = (quint16 *)data->texture.scanLine(y2);
+ const quint16 *src1 = (const quint16 *)data->texture.scanLine(y1);
+ const quint16 *src2 = (const quint16 *)data->texture.scanLine(y2);
quint16 tl = src1[x1];
const quint16 tr = src1[x2];
quint16 bl = src2[x1];
@@ -5392,7 +5333,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, void *userDa
const int px = qBound(0, x >> 16, image_width - 1);
const int py = qBound(0, y >> 16, image_height - 1);
- *b = ((quint16 *)data->texture.scanLine(py))[px];
+ *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
@@ -5451,7 +5392,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, void *userDa
const int px = qBound(0, int(tx) - (tx < 0), image_width - 1);
const int py = qBound(0, int(ty) - (ty < 0), image_height - 1);
- *b = ((quint16 *)data->texture.scanLine(py))[px];
+ *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
@@ -5495,7 +5436,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
+ const uint *image_bits = (const uint *)data->texture.imageData;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5550,7 +5491,7 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
+ const uint *image_bits = (const uint *)data->texture.imageData;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5661,7 +5602,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *
if (py < 0)
py += image_height;
- *b = ((quint16 *)data->texture.scanLine(py))[px];
+ *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
@@ -5727,7 +5668,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *
if (py < 0)
py += image_height;
- *b = ((quint16 *)data->texture.scanLine(py))[px];
+ *b = ((const quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
@@ -6793,18 +6734,32 @@ void qInitDrawhelperAsm()
}
#endif // SSSE3
-#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
+#if QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1)) {
#if !defined(__SSE4_1__)
+ extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+ extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
#endif
+ extern const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+ extern const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+ extern const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4;
}
#endif
+#if QT_COMPILER_SUPPORTS_AVX2 && !defined(__AVX2__)
+ if (qCpuHasFeature(AVX2)) {
+ extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+ extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *);
+ qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
+ qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
+ }
+#endif
+
functionForModeAsm = qt_functionForMode_SSE2;
functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
new file mode 100644
index 0000000000..5716be682b
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+
+#if defined(QT_COMPILER_SUPPORTS_AVX2)
+
+QT_BEGIN_NAMESPACE
+
+const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ return qt_convertARGB32ToARGB32PM(buffer, src, count);
+}
+
+const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 08bc0776f7..480ba4c97b 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -769,7 +769,7 @@ do { \
do { \
/* Duff's device */ \
ushort *_d = (ushort*)(dest); \
- const ushort *_s = (ushort*)(src); \
+ const ushort *_s = (const ushort*)(src); \
int n = ((length) + 7) / 8; \
switch ((length) & 0x07) \
{ \
@@ -893,6 +893,22 @@ inline int qBlue565(quint16 rgb) {
return (b << 3) | (b >> 2);
}
+
+static Q_ALWAYS_INLINE const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(src[i]);
+ return buffer;
+}
+
+static Q_ALWAYS_INLINE const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
+ return buffer;
+}
+
+
const uint qt_bayer_matrix[16][16] = {
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 93d2d94626..84eb3b7909 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -111,7 +111,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
}
for (; x < w-3; x += 4) {
- __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]);
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) {
const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
__m128i result;
@@ -162,7 +162,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin
// 2) composition with SSE2
for (; x < length - 3; x += 4) {
- const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]);
const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
const __m128i result = _mm_adds_epu8(srcVector, dstVector);
@@ -185,7 +185,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin
const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
// 2) composition with SSE2
for (; x < length - 3; x += 4) {
- const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]);
const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
__m128i result = _mm_adds_epu8(srcVector, dstVector);
@@ -218,7 +218,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u
const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha);
for (; x < length - 3; x += 4) {
- const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]);
__m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half)
_mm_store_si128((__m128i *)&dst[x], dstVector);
diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp
new file mode 100644
index 0000000000..43a3958997
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_sse4.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+#include <private/qdrawingprimitive_sse2_p.h>
+
+#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
+
+QT_BEGIN_NAMESPACE
+
+const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ return qt_convertARGB32ToARGB32PM(buffer, src, count);
+}
+
+const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
+}
+
+const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qUnpremultiply_sse4(src[i]);
+ return buffer;
+}
+
+const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i]));
+ return buffer;
+}
+
+const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i]));
+ return buffer;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index cb4bd35d33..fff4145d21 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -53,7 +53,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src)
*/
#define BLENDING_LOOP(palignrOffset, length)\
for (; x-minusOffsetToAlignSrcOn16Bytes < length-7; x += 4) { \
- const __m128i srcVectorLastLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\
+ const __m128i srcVectorLastLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\
const __m128i srcVector = _mm_alignr_epi8(srcVectorLastLoaded, srcVectorPrevLoaded, palignrOffset); \
const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
@@ -97,7 +97,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src)
See the SSE2 version for more documentation on the algorithm itself. */\
const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\
for (; x < length-3; x += 4) { \
- const __m128i srcVector = _mm_load_si128((__m128i *)&src[x]); \
+ const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); \
const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
_mm_store_si128((__m128i *)&dst[x], srcVector); \
@@ -113,7 +113,7 @@ inline static void blend_pixel(quint32 &dst, const quint32 src)
} /* end for() */\
} else if ((length - x) >= 8) {\
/* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\
- __m128i srcVectorPrevLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\
+ __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\
const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\
\
const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index aded999cdd..4d0790a502 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -171,7 +171,7 @@ QT_BEGIN_NAMESPACE
} \
\
for (; x < length-3; x += 4) { \
- const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \
+ const __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); \
BLEND_SOURCE_OVER_ARGB32_SSE2_helper(dst, srcVector, nullVector, half, one, colorMask, alphaMask) \
} \
for (; x < length; ++x) { \
@@ -207,7 +207,7 @@ QT_BEGIN_NAMESPACE
} \
\
for (; x < length-3; x += 4) { \
- __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \
+ __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); \
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { \
BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half); \
\
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 9ae95dff78..58e9112dd6 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -107,12 +107,12 @@ qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB;
namespace QImageScale {
struct QImageScaleInfo {
int *xpoints;
- unsigned int **ypoints;
+ const unsigned int **ypoints;
int *xapoints, *yapoints;
int xup_yup;
};
- unsigned int** qimageCalcYPoints(unsigned int *src, int sw, int sh,
+ const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh,
int dh);
int* qimageCalcXPoints(int sw, int dw);
int* qimageCalcApoints(int s, int d, int up);
@@ -139,10 +139,10 @@ using namespace QImageScale;
#define INV_YAP (256 - yapoints[dyy + y])
#define YAP (yapoints[dyy + y])
-unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src,
+const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
int sw, int sh, int dh)
{
- unsigned int **p;
+ const unsigned int **p;
int i, j = 0, rv = 0;
qint64 val, inc;
@@ -150,7 +150,7 @@ unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src,
dh = -dh;
rv = 1;
}
- p = new unsigned int* [dh+1];
+ p = new const unsigned int* [dh+1];
int up = qAbs(dh) >= sh;
val = up ? 0x8000 * sh / dh - 0x8000 : 0;
@@ -161,7 +161,7 @@ unsigned int** QImageScale::qimageCalcYPoints(unsigned int *src,
}
if(rv){
for(i = dh / 2; --i >= 0; ){
- unsigned int *tmp = p[i];
+ const unsigned int *tmp = p[i];
p[i] = p[dh - i - 1];
p[dh - i - 1] = tmp;
}
@@ -282,7 +282,7 @@ QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
isi->xpoints = qimageCalcXPoints(img.width(), scw);
if(!isi->xpoints)
return(qimageFreeScaleInfo(isi));
- isi->ypoints = qimageCalcYPoints((unsigned int *)img.scanLine(0),
+ isi->ypoints = qimageCalcYPoints((const unsigned int *)img.scanLine(0),
img.bytesPerLine() / 4, img.height(), sch);
if (!isi->ypoints)
return(qimageFreeScaleInfo(isi));
@@ -304,9 +304,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
int dxx, int dyy, int dx, int dy, int dw,
int dh, int dow, int sow)
{
- unsigned int *sptr, *dptr;
+ const unsigned int *sptr;
+ unsigned int *dptr;
int x, y, end;
- unsigned int **ypoints = isi->ypoints;
+ const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
@@ -323,7 +324,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
for(x = dxx; x < end; x++){
int r, g, b, a;
int rr, gg, bb, aa;
- unsigned int *pix;
+ const unsigned int *pix;
if(XAP > 0){
pix = ypoints[dyy + y] + xpoints[x];
@@ -374,7 +375,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
else{
for(x = dxx; x < end; x++){
int r, g, b, a;
- unsigned int *pix;
+ const unsigned int *pix;
if(XAP > 0){
pix = ypoints[dyy + y] + xpoints[x];
@@ -403,7 +404,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
else if(isi->xup_yup == 1){
/*\ 'Correct' version, with math units prepared for MMXification \*/
int Cy, j;
- unsigned int *pix;
+ const unsigned int *pix;
int r, g, b, a, rr, gg, bb, aa;
int yap;
@@ -477,7 +478,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
else if(isi->xup_yup == 2){
/*\ 'Correct' version, with math units prepared for MMXification \*/
int Cx, j;
- unsigned int *pix;
+ const unsigned int *pix;
int r, g, b, a, rr, gg, bb, aa;
int xap;
@@ -555,7 +556,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
|*| psllw (16 - d), %mmb; pmulh %mmc, %mmb
\*/
int Cx, Cy, i, j;
- unsigned int *pix;
+ const unsigned int *pix;
int a, r, g, b, ax, rx, gx, bx;
int xap, yap;
@@ -663,9 +664,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
int dxx, int dyy, int dx, int dy, int dw,
int dh, int dow, int sow)
{
- unsigned int *sptr, *dptr;
+ const unsigned int *sptr;
+ unsigned int *dptr;
int x, y, end;
- unsigned int **ypoints = isi->ypoints;
+ const unsigned int **ypoints = isi->ypoints;
int *xpoints = isi->xpoints;
int *xapoints = isi->xapoints;
int *yapoints = isi->yapoints;
@@ -682,7 +684,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
for(x = dxx; x < end; x++){
int r = 0, g = 0, b = 0;
int rr = 0, gg = 0, bb = 0;
- unsigned int *pix;
+ const unsigned int *pix;
if(XAP > 0){
pix = ypoints[dyy + y] + xpoints[x];
@@ -725,7 +727,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
else{
for(x = dxx; x < end; x++){
int r = 0, g = 0, b = 0;
- unsigned int *pix;
+ const unsigned int *pix;
if(XAP > 0){
pix = ypoints[dyy + y] + xpoints[x];
@@ -751,7 +753,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
else if(isi->xup_yup == 1){
/*\ 'Correct' version, with math units prepared for MMXification \*/
int Cy, j;
- unsigned int *pix;
+ const unsigned int *pix;
int r, g, b, rr, gg, bb;
int yap;
@@ -816,7 +818,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
else if(isi->xup_yup == 2){
/*\ 'Correct' version, with math units prepared for MMXification \*/
int Cx, j;
- unsigned int *pix;
+ const unsigned int *pix;
int r, g, b, rr, gg, bb;
int xap;
@@ -882,7 +884,7 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
else{
/*\ 'Correct' version, with math units prepared for MMXification \*/
int Cx, Cy, i, j;
- unsigned int *pix;
+ const unsigned int *pix;
int r, g, b, rx, gx, bx;
int xap, yap;
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index 7c33dbe266..a2bab58922 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -531,7 +531,7 @@ void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
{
Q_D(QBlitterPaintEngine);
if (path.shape() == QVectorPath::RectangleHint) {
- QRectF rect(((QPointF *) path.points())[0], ((QPointF *) path.points())[2]);
+ QRectF rect(((const QPointF *) path.points())[0], ((const QPointF *) path.points())[2]);
fillRect(rect, brush);
} else {
d->lock();
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 1a1f63844c..18522cb6d0 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1864,7 +1864,7 @@ void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, Poly
}
// Compose polygon fill..,
- QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
+ QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
ensureOutlineMapper();
QT_FT_Outline *outline = d->outlineMapper->convertPath(vp);
@@ -1889,7 +1889,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((const qreal *) points, pointCount)) {
QRectF r(points[0], points[2]);
drawRects(&r, 1);
return;
@@ -1905,7 +1905,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
// Do the outline...
if (s->penData.blend) {
- QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
+ QVectorPath vp((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
@@ -1930,7 +1930,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
qDebug() << " - " << points[i];
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((const int *) points, pointCount)) {
QRect r(points[0].x(),
points[0].y(),
points[2].x() - points[0].x(),
@@ -1968,7 +1968,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
int count = pointCount * 2;
QVarLengthArray<qreal> fpoints(count);
for (int i=0; i<count; ++i)
- fpoints[i] = ((int *) points)[i];
+ fpoints[i] = ((const int *) points)[i];
QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
@@ -2695,7 +2695,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
scanline += bpl;
}
} else { // 32-bit alpha...
- uint *sl = (uint *) scanline;
+ const uint *sl = (const uint *) scanline;
for (int y = y0; y < y1; ++y) {
for (int x = x0; x < x1; ) {
// Skip those with 0 coverage
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 1de821e1c4..0f80cd18a0 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -521,23 +521,23 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
while (points < lastPoint) {
switch (*types) {
case QPainterPath::MoveToElement: {
- QPointF pt = (*(QPointF *) points) * state()->matrix;
+ QPointF pt = (*(const QPointF *) points) * state()->matrix;
d->activeStroker->moveTo(pt.x(), pt.y());
points += 2;
++types;
break;
}
case QPainterPath::LineToElement: {
- QPointF pt = (*(QPointF *) points) * state()->matrix;
+ QPointF pt = (*(const QPointF *) points) * state()->matrix;
d->activeStroker->lineTo(pt.x(), pt.y());
points += 2;
++types;
break;
}
case QPainterPath::CurveToElement: {
- QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
- QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
- QPointF e = ((QPointF *) points)[2] * state()->matrix;
+ QPointF c1 = ((const QPointF *) points)[0] * state()->matrix;
+ QPointF c2 = ((const QPointF *) points)[1] * state()->matrix;
+ QPointF e = ((const QPointF *) points)[2] * state()->matrix;
d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
points += 6;
types += 3;
@@ -549,16 +549,16 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
}
}
if (path.hasImplicitClose()) {
- QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
+ QPointF pt = * ((const QPointF *) path.points()) * state()->matrix;
d->activeStroker->lineTo(pt.x(), pt.y());
}
} else {
- QPointF p = ((QPointF *)points)[0] * state()->matrix;
+ QPointF p = ((const QPointF *)points)[0] * state()->matrix;
d->activeStroker->moveTo(p.x(), p.y());
points += 2;
while (points < lastPoint) {
- QPointF p = ((QPointF *)points)[0] * state()->matrix;
+ QPointF p = ((const QPointF *)points)[0] * state()->matrix;
d->activeStroker->lineTo(p.x(), p.y());
points += 2;
}
@@ -786,7 +786,7 @@ void QPaintEngineEx::drawLines(const QLine *lines, int lineCount)
qreal pts[64];
int count2 = count<<1;
for (int i=0; i<count2; ++i)
- pts[i] = ((int *) lines)[i];
+ pts[i] = ((const int *) lines)[i];
QVectorPath path(pts, count, qpaintengineex_line_types_16, QVectorPath::LinesHint);
stroke(path, state()->pen);
@@ -802,7 +802,7 @@ void QPaintEngineEx::drawLines(const QLineF *lines, int lineCount)
while (elementCount > 0) {
int count = qMin(elementCount, 32);
- QVectorPath path((qreal *) lines, count, qpaintengineex_line_types_16,
+ QVectorPath path((const qreal *) lines, count, qpaintengineex_line_types_16,
QVectorPath::LinesHint);
stroke(path, state()->pen);
@@ -906,7 +906,7 @@ void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount)
void QPaintEngineEx::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
- QVectorPath path((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
+ QVectorPath path((const qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (mode == PolylineMode)
stroke(path, state()->pen);
@@ -920,7 +920,7 @@ void QPaintEngineEx::drawPolygon(const QPoint *points, int pointCount, PolygonDr
QVarLengthArray<qreal> pts(count);
for (int i=0; i<count; ++i)
- pts[i] = ((int *) points)[i];
+ pts[i] = ((const int *) points)[i];
QVectorPath path(pts.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index bdbb49ff51..6f00abfc5f 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -4626,7 +4626,7 @@ void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
{
Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF));
- drawLines((QLineF*)pointPairs, lineCount);
+ drawLines((const QLineF*)pointPairs, lineCount);
}
/*!
@@ -4639,7 +4639,7 @@ void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
{
Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint));
- drawLines((QLine*)pointPairs, lineCount);
+ drawLines((const QLine*)pointPairs, lineCount);
}
@@ -5565,22 +5565,19 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
- d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(),
- glyphRun.underline(), glyphRun.strikeOut());
+ d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, fontD->fontEngine,
+ glyphRun.overline(), glyphRun.underline(), glyphRun.strikeOut());
}
void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
int glyphCount,
- const QRawFont &font, bool overline, bool underline,
+ QFontEngine *fontEngine, bool overline, bool underline,
bool strikeOut)
{
Q_Q(QPainter);
updateState(state);
- QRawFontPrivate *fontD = QRawFontPrivate::get(font);
- QFontEngine *fontEngine = fontD->fontEngine;
-
QFixed leftMost;
QFixed rightMost;
QFixed baseLine;
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index dde01d32fa..7c32dc1694 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -70,7 +70,7 @@ struct DataPtrContainer {
void *ptr;
};
-inline void *data_ptr(const QTransform &t) { return (DataPtrContainer *) &t; }
+inline const void *data_ptr(const QTransform &t) { return (const DataPtrContainer *) &t; }
inline bool qtransform_fast_equals(const QTransform &a, const QTransform &b) { return data_ptr(a) == data_ptr(b); }
// QPen inline functions...
@@ -226,7 +226,7 @@ public:
#if !defined(QT_NO_RAWFONT)
void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
- const QRawFont &font, bool overline = false, bool underline = false,
+ QFontEngine *fontEngine, bool overline = false, bool underline = false,
bool strikeOut = false);
#endif
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 6834222f08..b028d868b9 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1622,7 +1622,8 @@ void QFontEngineMulti::setFallbackFamiliesList(const QStringList &fallbackFamili
void QFontEngineMulti::ensureEngineAt(int at)
{
- Q_ASSERT(m_fallbackFamiliesQueried);
+ if (!m_fallbackFamiliesQueried)
+ ensureFallbackFamiliesQueried();
Q_ASSERT(at < m_engines.size());
if (!m_engines.at(at)) {
QFontEngine *engine = loadEngine(at);
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index b79f971156..8ae178c6ad 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -891,8 +891,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
FT_Matrix_Multiply(&m, &matrix);
}
- FT_Library library = qt_getFreetype();
-
info.xOff = TRUNC(ROUND(slot->advance.x));
info.yOff = 0;
@@ -930,12 +928,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
return g;
}
- uchar *glyph_buffer = 0;
int glyph_buffer_size = 0;
+ QScopedArrayPointer<uchar> glyph_buffer;
#if defined(QT_USE_FREETYPE_LCDFILTER)
bool useFreetypeRenderGlyph = false;
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
- err = FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType);
+ err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
if (err == FT_Err_Ok)
useFreetypeRenderGlyph = true;
}
@@ -946,7 +944,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
if (err != FT_Err_Ok)
qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- FT_Library_SetLcdFilter(library, FT_LCD_FILTER_NONE);
+ FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);
info.height = slot->bitmap.rows / vfactor;
info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width;
@@ -954,12 +952,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
info.y = slot->bitmap_top;
glyph_buffer_size = info.width * info.height * 4;
- glyph_buffer = new uchar[glyph_buffer_size];
+ glyph_buffer.reset(new uchar[glyph_buffer_size]);
if (hsubpixel)
- convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
+ convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
else if (vfactor != 1)
- convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
+ convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
} else
#endif
{
@@ -1030,26 +1028,30 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|| ((signed char)(info.xOff) != info.xOff));
if (large_glyph) {
- delete [] glyph_buffer;
return 0;
}
int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :
(format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));
- glyph_buffer_size = pitch * info.height;
- glyph_buffer = new uchar[glyph_buffer_size];
- memset(glyph_buffer, 0, glyph_buffer_size);
+ if (glyph_buffer_size < pitch * info.height) {
+ glyph_buffer_size = pitch * info.height;
+ glyph_buffer.reset(new uchar[glyph_buffer_size]);
+ }
+ memset(glyph_buffer.data(), 0, glyph_buffer_size);
if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_Bitmap bitmap;
bitmap.rows = info.height*vfactor;
bitmap.width = hpixels;
bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3);
- if (!hsubpixel && vfactor == 1 && format != Format_A32)
- bitmap.buffer = glyph_buffer;
- else
- bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch];
- memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch);
+ int bitmap_buffer_size = bitmap.rows * bitmap.pitch;
+ if (!hsubpixel && vfactor == 1 && format != Format_A32) {
+ Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size);
+ bitmap.buffer = glyph_buffer.data();
+ } else {
+ bitmap.buffer = new uchar[bitmap_buffer_size];
+ memset(bitmap.buffer, 0, bitmap_buffer_size);
+ }
bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY;
FT_Matrix matrix;
matrix.xx = (hsubpixel ? 3 : 1) << 16;
@@ -1058,11 +1060,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
FT_Outline_Transform(&slot->outline, &matrix);
FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor);
- FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap);
+ FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap);
if (hsubpixel) {
Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
Q_ASSERT(antialias);
- uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch];
+ uchar *convoluted = new uchar[bitmap_buffer_size];
bool useLegacyLcdFilter = false;
#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
@@ -1072,20 +1074,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
buffer = convoluted;
}
- convertRGBToARGB(buffer + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter);
+ convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter);
delete [] convoluted;
} else if (vfactor != 1) {
- convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true);
+ convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true);
} else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
- convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch);
+ convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch);
}
- if (bitmap.buffer != glyph_buffer)
+ if (bitmap.buffer != glyph_buffer.data())
delete [] bitmap.buffer;
} else if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO);
uchar *src = slot->bitmap.buffer;
- uchar *dst = glyph_buffer;
+ uchar *dst = glyph_buffer.data();
int h = slot->bitmap.rows;
if (format == Format_Mono) {
int bytes = ((info.width + 7) & ~7) >> 3;
@@ -1130,7 +1132,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
}
} else {
qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format);
- delete [] glyph_buffer;
return 0;
}
}
@@ -1149,7 +1150,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
g->advance = info.xOff;
g->format = format;
delete [] g->data;
- g->data = glyph_buffer;
+ g->data = glyph_buffer.take();
if (set)
set->setGlyph(glyph, subPixelPosition, g);
@@ -1333,14 +1334,14 @@ static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix)
return m;
}
-QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransform &matrix)
+QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
{
if (matrix.type() > QTransform::TxShear || !cacheEnabled)
return 0;
// FT_Set_Transform only supports scalable fonts
if (!FT_IS_SCALABLE(freetype->face))
- return 0;
+ return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : Q_NULLPTR;
FT_Matrix m = QTransformToFTMatrix(matrix);
@@ -1757,15 +1758,11 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe
QFontEngineFT::Glyph *glyph;
QScopedPointer<QFontEngineFT::Glyph> glyphGuard;
if (cacheEnabled) {
- QFontEngineFT::QGlyphSet *gset = &defaultGlyphSet;
+ QGlyphSet *gset = loadGlyphSet(t);
QFontEngine::HintStyle hintStyle = default_hint_style;
if (t.type() >= QTransform::TxScale) {
// disable hinting if the glyphs are transformed
default_hint_style = HintNone;
- if (t.isAffine())
- gset = loadTransformedGlyphSet(t);
- else
- gset = 0;
}
if (gset) {
@@ -1842,31 +1839,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
const QTransform &t,
bool fetchBoundingBox)
{
- FT_Face face = 0;
- QGlyphSet *glyphSet = 0;
- FT_Matrix ftMatrix = QTransformToFTMatrix(t);
- if (cacheEnabled) {
- if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face))
- glyphSet = loadTransformedGlyphSet(t);
- else
- glyphSet = &defaultGlyphSet;
- Q_ASSERT(glyphSet != 0);
- }
-
+ QGlyphSet *glyphSet = loadGlyphSet(t);
if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox)
return 0;
Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
- if (!glyph || glyph->format != format) {
- face = lockFace();
+ if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) {
+ lockFace();
FT_Matrix m = this->matrix;
+ FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
FT_Matrix_Multiply(&ftMatrix, &m);
freetype->matrix = m;
glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false);
- }
-
- if (face)
unlockFace();
+ }
return glyph;
}
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 1218893e19..e9d058d50c 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -268,7 +268,7 @@ private:
Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const;
Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false);
- QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix);
+ QGlyphSet *loadGlyphSet(const QTransform &matrix);
QFontEngineFT(const QFontDef &fd);
virtual ~QFontEngineFT();
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 24dda422fc..9f652084be 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -420,7 +420,7 @@ static quint32 checksum(const QByteArray &table)
{
quint32 sum = 0;
int offset = 0;
- const uchar *d = (uchar *)table.constData();
+ const uchar *d = (const uchar *)table.constData();
while (offset <= table.size()-3) {
sum += qFromBigEndian<quint32>(d + offset);
offset += 4;
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 321c7937f7..9f561dcb02 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -194,7 +194,7 @@ static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourc
z_stream stream;
int err;
- stream.next_in = (Bytef*)source;
+ stream.next_in = const_cast<Bytef*>(source);
stream.avail_in = (uInt)sourceLen;
if ((uLong)stream.avail_in != sourceLen)
return Z_BUF_ERROR;
@@ -229,7 +229,7 @@ static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sour
z_stream stream;
int err;
- stream.next_in = (Bytef*)source;
+ stream.next_in = const_cast<Bytef*>(source);
stream.avail_in = (uInt)sourceLen;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
@@ -1008,7 +1008,7 @@ QByteArray QZipReader::fileData(const QString &fileName) const
do {
baunzip.resize(len);
res = inflate((uchar*)baunzip.data(), &len,
- (uchar*)compressed.constData(), compressed_size);
+ (const uchar*)compressed.constData(), compressed_size);
switch (res) {
case Z_OK:
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 091129f5be..61e239f678 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -86,7 +86,7 @@ HEADERS += \
contains(QT_CONFIG, harfbuzz)|contains(QT_CONFIG, system-harfbuzz) {
DEFINES += QT_ENABLE_HARFBUZZ_NG
- include($$PWD/../../3rdparty/harfbuzzng.pri)
+ include($$PWD/../../3rdparty/harfbuzz_dependency.pri)
SOURCES += text/qharfbuzzng.cpp
HEADERS += text/qharfbuzzng_p.h