diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/painting.pri | 13 | ||||
-rw-r--r-- | src/gui/painting/qbrush.cpp | 81 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 433 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_avx.cpp | 70 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_neon.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_neon_p.h | 4 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 22 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_sse2.cpp | 8 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_x86_p.h | 27 | ||||
-rw-r--r-- | src/gui/painting/qdrawingprimitive_sse2_p.h | 4 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine.cpp | 1 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine.h | 1 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 24 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qpen.cpp | 4 |
15 files changed, 310 insertions, 390 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index aadcc0f686..6bf80eddbd 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -87,14 +87,15 @@ SOURCES += \ painting/qpaintbuffer.cpp \ painting/qpathsimplifier.cpp -SSE2_SOURCES += painting/qdrawhelper_sse2.cpp -SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp +contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) { + SOURCES += painting/qdrawhelper_sse2.cpp + SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp +} IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp -AVX_SOURCES += painting/qdrawhelper_avx.cpp -!ios { - NEON_SOURCES += painting/qdrawhelper_neon.cpp - NEON_HEADERS += painting/qdrawhelper_neon_p.h +!ios:contains(QT_CPU_FEATURES.$$QT_ARCH, neon) { + SOURCES += painting/qdrawhelper_neon.cpp + HEADERS += painting/qdrawhelper_neon_p.h NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S } diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 8bbe6b6f42..b35fa38ce0 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -56,44 +56,49 @@ QT_BEGIN_NAMESPACE const uchar *qt_patternForBrush(int brushStyle, bool invert) { Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern); - if(invert) { - static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff }; - static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff }; - static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee }; - static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }; - static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 }; - static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }; - static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 }; - static const uchar hor_pat[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }; - static const uchar ver_pat[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }; - static const uchar cross_pat[] = { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 }; - static const uchar bdiag_pat[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; - static const uchar fdiag_pat[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; - static const uchar dcross_pat[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }; - static const uchar *const pat_tbl[] = { - dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat, - dense6_pat, dense7_pat, - hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat }; - return pat_tbl[brushStyle - Qt::Dense1Pattern]; - } - static const uchar dense1_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 }; - static const uchar dense2_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }; - static const uchar dense3_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 }; - static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa }; - static const uchar dense5_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee }; - static const uchar dense6_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff }; - static const uchar dense7_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff }; - static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff }; - static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef }; - static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef }; - static const uchar bdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe }; - static const uchar fdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; - static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e }; - static const uchar *const pat_tbl[] = { - dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat, - dense6_pat, dense7_pat, - hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat }; - return pat_tbl[brushStyle - Qt::Dense1Pattern]; + static const uchar pat_tbl[][2][8] = { + { + /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 }, + /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff }, + }, { + /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }, + /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff }, + }, { + /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 }, + /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee }, + }, { + /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa }, + /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }, + }, { + /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee }, + /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 }, + }, { + /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff }, + /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }, + }, { + /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff }, + /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 }, + }, { + /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff }, + /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, + }, { + /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef }, + /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, + }, { + /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef }, + /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 }, + }, { + /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe }, + /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, + }, { + /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }, + /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, + }, { + /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e }, + /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, + }, + }; + return pat_tbl[brushStyle - Qt::Dense1Pattern][invert]; } QPixmap qt_pixmapForBrush(int brushStyle, bool invert) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index d3e5b645c4..39193dd093 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -53,6 +53,13 @@ # endif #endif +#include <qglobal.h> +#ifdef Q_OS_IOS +// We don't build the NEON drawhelpers as they are implemented partly +// in GAS syntax assembly, which is not supported by the iOS toolchain. +#undef __ARM_NEON__ +#endif + #include <qstylehints.h> #include <qguiapplication.h> #include <qatomic.h> @@ -102,7 +109,7 @@ static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int, return src; } -static const uint *QT_FASTCALL convertRGB16ToARGB32PM(uint *buffer, const uint *src, int count, +static const uint *QT_FASTCALL convertRGB16ToRGB32(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { for (int i = 0; i < count; ++i) @@ -118,6 +125,22 @@ static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint return buffer; } +static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = RGBA2ARGB(src[i]); + return buffer; +} + +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] = PREMUL(RGBA2ARGB(src[i])); + return buffer; +} + static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count, const QPixelLayout *layout, const QRgb *) { @@ -206,6 +229,14 @@ static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, return buffer; } +static const uint *QT_FASTCALL convertRGB16FromRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertRgb32To16(src[i]); + return buffer; +} + static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -222,6 +253,38 @@ static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uin return buffer; } +static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(src[i]); + return buffer; +} + +static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(INV_PREMUL(src[i])); + return buffer; +} + +static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(0xff000000 | src[i]); + return buffer; +} + +static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = ARGB2RGBA(0xff000000 | INV_PREMUL(src[i])); + return buffer; +} + static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *layout, const QRgb *) { @@ -242,7 +305,7 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src if (!layout->premultiplied) { for (int i = 0; i < count; ++i) - buffer[i] = qAlpha(src[i]) == 255 ? src[i] : INV_PREMUL(src[i]); + buffer[i] = INV_PREMUL(src[i]); src = buffer; } for (int i = 0; i < count; ++i) { @@ -255,13 +318,14 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src return buffer; } -static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *) +static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *) { Q_ASSERT(layout->redWidth <= 8); Q_ASSERT(layout->greenWidth <= 8); Q_ASSERT(layout->blueWidth <= 8); Q_ASSERT(layout->alphaWidth == 0); + Q_ASSERT(!layout->premultiplied); const uint redMask = (1 << layout->redWidth) - 1; const uint greenMask = (1 << layout->greenWidth) - 1; @@ -272,12 +336,10 @@ static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint * const uchar blueRightShift = 8 - layout->blueWidth; for (int i = 0; i < count; ++i) { - uint color = INV_PREMUL(src[i]); - uint red = ((color >> redRightShift) & redMask) << layout->redShift; - uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift; - uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift; - uint alpha = 0xff << layout->alphaShift; - buffer[i] = red | green | blue | alpha; + uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift; + uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift; + uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift; + buffer[i] = red | green | blue; } return buffer; } @@ -392,30 +454,32 @@ inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint // convertFromArgb32() assumes that no color channel is more than 8 bits. // QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits. QPixelLayout qPixelLayouts[QImage::NImageFormats] = { - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0 }, // Format_Invalid - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0 }, // Format_Mono - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0 }, // Format_MonoLSB - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0 }, // Format_Indexed8 - { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_RGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM }, // Format_ARGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied - { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToARGB32PM, convertRGB16FromARGB32PM }, // Format_RGB16 - { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8565_Premultiplied - { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB666 - { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB6666_Premultiplied - { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB555 - { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied - { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888 - { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444 - { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0 }, // Format_Invalid + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0 }, // Format_Mono + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0 }, // Format_MonoLSB + { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0 }, // Format_Indexed8 + // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong, + // but everywhere this generic conversion would be wrong is currently overloaed. + { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_RGB32 + { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, 0 }, // Format_ARGB32 + { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, 0 }, // Format_ARGB32_Premultiplied + { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToRGB32, convertRGB16FromARGB32PM, convertRGB16FromRGB32 }, // Format_RGB16 + { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8565_Premultiplied + { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB666 + { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB6666_Premultiplied + { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB555 + { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8555_Premultiplied + { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB888 + { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB444 + { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB4444_Premultiplied #if Q_BYTE_ORDER == Q_BIG_ENDIAN - { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888 - { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 - { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied + { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 + { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 + { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied #else - { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888 - { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32) - { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied + { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 + { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 (ABGR32) + { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 } // Format_RGBA8888_Premultiplied #endif }; @@ -630,7 +694,12 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con uchar *dest = rasterBuffer->scanLine(y); while (length) { int l = qMin(length, buffer_size); - const uint *ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); + const uint *ptr = 0; + if (layout->convertFromRGB32) { + Q_ASSERT(!layout->premultiplied && !layout->alphaWidth); + ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0); + } else + ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); store(dest, ptr, x, l); length -= l; buffer += l; @@ -5071,13 +5140,13 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us int l = qMin(length, buffer_size); const uint *end = buffer + l; uint *b = buffer; + int px16 = x % (image_width << 16); + int py16 = y % (image_height << 16); + int px_delta = fdx % (image_width << 16); + int py_delta = fdy % (image_height << 16); while (b < end) { - int px = x >> 16; - int py = y >> 16; - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; + int px = px16 >> 16; + int py = py16 >> 16; int y_offset = py * scanline_offset; Q_ASSERT(px >= 0 && px < image_width); @@ -5086,6 +5155,14 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us *b = image_bits[y_offset + px]; x += fdx; y += fdy; + px16 += px_delta; + if (px16 >= image_width << 16) + px16 -= image_width << 16; + py16 += py_delta; + if (py16 >= image_height << 16) + py16 -= image_height << 16; + if (px16 < 0) px16 += image_width << 16; + if (py16 < 0) py16 += image_height << 16; ++b; } func(target, buffer, l, coverage); @@ -6140,110 +6217,73 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count) } #endif -static void qt_memfill_quint16(quint16 *dest, quint16 color, int count) +#if !defined(__SSE2__) +void qt_memfill16(quint16 *dest, quint16 color, int count) { qt_memfill_template<quint16>(dest, color, count); } - -typedef void (*qt_memfill32_func)(quint32 *dest, quint32 value, int count); -typedef void (*qt_memfill16_func)(quint16 *dest, quint16 value, int count); -static void qt_memfill32_setup(quint32 *dest, quint32 value, int count); -static void qt_memfill16_setup(quint16 *dest, quint16 value, int count); - -qt_memfill32_func qt_memfill32 = qt_memfill32_setup; -qt_memfill16_func qt_memfill16 = qt_memfill16_setup; +#endif +#if !defined(__SSE2__) && !defined(__ARM_NEON__) +void qt_memfill32(quint32 *dest, quint32 color, int count) +{ +# ifdef QT_COMPILER_SUPPORTS_MIPS_DSP + extern "C" qt_memfill32_asm_mips_dsp(quint32 *, quint32, int); + qt_memfill32_asm_mips_dsp(dest, color, count); +# else + qt_memfill_template<quint32>(dest, color, count); +# endif +} +#endif void qInitDrawhelperAsm() { - - qt_memfill32 = qt_memfill_template<quint32>; - qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16>; - CompositionFunction *functionForModeAsm = 0; CompositionFunctionSolid *functionForModeSolidAsm = 0; const uint features = qCpuFeatures(); - if (false) { - Q_UNUSED(features); -#ifdef QT_COMPILER_SUPPORTS_AVX - } else if (features & AVX) { - qt_memfill32 = qt_memfill32_avx; - qt_memfill16 = qt_memfill16_avx; - qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_avx; - qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx; - qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx; - qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx; - qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx; - - extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha); - qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; - qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; - qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; -#endif -#endif -#ifdef QT_COMPILER_SUPPORTS_SSE2 - } else if (features & SSE2) { - qt_memfill32 = qt_memfill32_sse2; - qt_memfill16 = qt_memfill16_sse2; - qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2; - qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2; - qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2; - qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2; - qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; - - extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha); - qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; - qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; - qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; -#endif -#endif - } - -#ifdef QT_COMPILER_SUPPORTS_SSE2 - if (features & SSE2) { - extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; -#endif - - extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length); - - qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; - } + Q_UNUSED(features); +#ifdef __SSE2__ + qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2; + qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; + + extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha); + qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; + qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; + qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; + qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; + + extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); + + qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; #ifdef QT_COMPILER_SUPPORTS_SSSE3 if (features & SSSE3) { @@ -6254,65 +6294,13 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; -#endif } #endif // SSSE3 -#ifdef QT_COMPILER_SUPPORTS_AVX - if (features & AVX) { - extern void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - extern void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx; - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx; -#endif - - extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length); - - qt_fetch_radial_gradient = qt_fetch_radial_gradient_avx; - } -#endif // AVX - -#endif // SSE2 - -#ifdef QT_COMPILER_SUPPORTS_SSE2 - if (features & SSE2) { - functionForModeAsm = qt_functionForMode_SSE2; - functionForModeSolidAsm = qt_functionForModeSolid_SSE2; - } -#endif -#ifdef QT_COMPILER_SUPPORTS_AVX - if (features & AVX) { - extern void QT_FASTCALL comp_func_SourceOver_avx(uint *destPixels, - const uint *srcPixels, - int length, - uint const_alpha); - extern void QT_FASTCALL comp_func_solid_SourceOver_avx(uint *destPixels, int length, uint color, uint const_alpha); - extern void QT_FASTCALL comp_func_Plus_avx(uint *dst, const uint *src, int length, uint const_alpha); - extern void QT_FASTCALL comp_func_Source_avx(uint *dst, const uint *src, int length, uint const_alpha); - - functionForModeAsm[0] = comp_func_SourceOver_avx; - functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_avx; - functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_avx; - functionForModeSolidAsm[0] = comp_func_solid_SourceOver_avx; - } + functionForModeAsm = qt_functionForMode_SSE2; + functionForModeSolidAsm = qt_functionForModeSolid_SSE2; #endif // SSE2 #ifdef QT_COMPILER_SUPPORTS_IWMMXT @@ -6323,45 +6311,42 @@ void qInitDrawhelperAsm() } #endif // IWMMXT -#if defined(QT_COMPILER_SUPPORTS_NEON) && !defined(Q_OS_IOS) - if (features & NEON) { - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; - qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; - qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; +#if defined(__ARM_NEON__) && !defined(Q_OS_IOS) + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; - qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; #endif - qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; - qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; - qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; - qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; - qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; + qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; - functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; - functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; - functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; - destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; - destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; + functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; + functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; + functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; + destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; + destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; - qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; - qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; - qt_memfill32 = qt_memfill32_neon; + qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; + qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; - extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length); + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); - qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; - } + qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; #endif #if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) @@ -6385,8 +6370,6 @@ void qInitDrawhelperAsm() functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp; functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp; - qt_memfill32 = qt_memfill32_asm_mips_dsp; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp; @@ -6427,16 +6410,4 @@ void qInitDrawhelperAsm() functionForMode = functionForModeAsm; } -static void qt_memfill32_setup(quint32 *dest, quint32 value, int count) -{ - qInitDrawhelperAsm(); - qt_memfill32(dest, value, count); -} - -static void qt_memfill16_setup(quint16 *dest, quint16 value, int count) -{ - qInitDrawhelperAsm(); - qt_memfill16(dest, value, count); -} - QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper_avx.cpp b/src/gui/painting/qdrawhelper_avx.cpp deleted file mode 100644 index 7da6ce6a20..0000000000 --- a/src/gui/painting/qdrawhelper_avx.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Intel Corporation -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qsimd_p.h> - -#ifdef QT_COMPILER_SUPPORTS_AVX -#define QDRAWHELPER_AVX - -#ifndef __AVX__ -#error "AVX not enabled in this file, cannot proceed" -#endif - -#define qt_blend_argb32_on_argb32_ssse3 qt_blend_argb32_on_argb32_avx -#include "qdrawhelper_ssse3.cpp" - -//#define qt_blend_argb32_on_argb32_sse2 qt_blend_argb32_on_argb32_avx -#define qt_blend_rgb32_on_rgb32_sse2 qt_blend_rgb32_on_rgb32_avx -#define comp_func_SourceOver_sse2 comp_func_SourceOver_avx -#define comp_func_Plus_sse2 comp_func_Plus_avx -#define comp_func_Source_sse2 comp_func_Source_avx -#define comp_func_solid_SourceOver_sse2 comp_func_solid_SourceOver_avx -#define qt_memfill32_sse2 qt_memfill32_avx -#define qt_memfill16_sse2 qt_memfill16_avx -#define qt_bitmapblit32_sse2 qt_bitmapblit32_avx -#define qt_bitmapblit16_sse2 qt_bitmapblit16_avx -#define QSimdSse2 QSimdAvx -#define qt_fetch_radial_gradient_sse2 qt_fetch_radial_gradient_avx -#define qt_scale_image_argb32_on_argb32_sse2 qt_scale_image_argb32_on_argb32_avx - -#include "qdrawhelper_sse2.cpp" - -#endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 541b3ef619..a40166d5be 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -43,7 +43,7 @@ #include <private/qblendfunctions_p.h> #include <private/qmath_p.h> -#ifdef QT_COMPILER_SUPPORTS_NEON +#ifdef __ARM_NEON__ #include <private/qdrawhelper_neon_p.h> #include <private/qpaintengine_raster_p.h> @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE -void qt_memfill32_neon(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, int count) { const int epilogueSize = count % 16; if (count >= 16) { @@ -998,5 +998,5 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Opera QT_END_NAMESPACE -#endif // QT_COMPILER_SUPPORTS_NEON +#endif // __ARM_NEON__ diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 475df639f8..cad6fe22e9 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE -#ifdef QT_COMPILER_SUPPORTS_NEON +#ifdef __ARM_NEON__ void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, @@ -139,7 +139,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha); void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha); -#endif // QT_COMPILER_SUPPORTS_NEON +#endif // __ARM_NEON__ QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 418294c56d..3c945338a6 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -171,6 +171,8 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3]; extern DrawHelper qDrawHelper[QImage::NImageFormats]; void qBlendTexture(int count, const QSpan *spans, void *userData); +extern void qt_memfill32(quint32 *dest, quint32 value, int count); +extern void qt_memfill16(quint16 *dest, quint16 value, int count); typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha); @@ -386,8 +388,6 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) return (b * b) - (4 * a * c); } -extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count); - template <class RadialFetchFunc> Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length) @@ -691,12 +691,16 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) { return t; } -#define INV_PREMUL(p) \ - (qAlpha(p) == 0 ? 0 : \ - ((qAlpha(p) << 24) \ - | (((255*qRed(p))/ qAlpha(p)) << 16) \ - | (((255*qGreen(p)) / qAlpha(p)) << 8) \ - | ((255*qBlue(p)) / qAlpha(p)))) +static Q_ALWAYS_INLINE uint INV_PREMUL(uint p) { + const uint alpha = qAlpha(p); + if (alpha == 255) + return p; + if (alpha == 0) + return 0; + // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256. + const uint invAlpha = 0x00ff00ffU / alpha; + return qRgba((qRed(p)*invAlpha)>>16, (qGreen(p)*invAlpha)>>16, (qBlue(p)*invAlpha)>>16, alpha); +} struct quint24 { quint24(uint value); @@ -726,7 +730,6 @@ template<> inline void qt_memfill(quint32 *dest, quint32 color, int count) template<> inline void qt_memfill(quint16 *dest, quint16 color, int count) { - extern void (*qt_memfill16)(quint16 *dest, quint16 value, int count); qt_memfill16(dest, color, count); } @@ -1031,6 +1034,7 @@ struct QPixelLayout BPP bpp; ConvertFunc convertToARGB32PM; ConvertFunc convertFromARGB32PM; + ConvertFunc convertFromRGB32; }; typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count); diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index a9dc5a7fb7..d11ba0b26c 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -238,7 +238,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u } } -void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, int count) { if (count < 7) { switch (count) { @@ -285,7 +285,7 @@ void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha) { if ((const_alpha & qAlpha(color)) == 255) { - qt_memfill32_sse2(destPixels, color, length); + qt_memfill32(destPixels, color, length); } else { if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); @@ -397,7 +397,7 @@ CompositionFunction qt_functionForMode_SSE2[numCompositionFunctions] = { }; #endif -void qt_memfill16_sse2(quint16 *dest, quint16 value, int count) +void qt_memfill16(quint16 *dest, quint16 value, int count) { if (count < 3) { switch (count) { @@ -413,7 +413,7 @@ void qt_memfill16_sse2(quint16 *dest, quint16 value, int count) } const quint32 value32 = (value << 16) | value; - qt_memfill32_sse2(reinterpret_cast<quint32*>(dest), value32, count / 2); + qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2); if (count & 0x1) dest[count - 1] = value; diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index d64b9cec39..699c586cb0 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -57,9 +57,9 @@ QT_BEGIN_NAMESPACE -#ifdef QT_COMPILER_SUPPORTS_SSE2 -void qt_memfill32_sse2(quint32 *dest, quint32 value, int count); -void qt_memfill16_sse2(quint16 *dest, quint16 value, int count); +#ifdef __SSE2__ +void qt_memfill32(quint32 *dest, quint32 value, int count); +void qt_memfill16(quint16 *dest, quint16 value, int count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *src, int width, int height, int stride); @@ -77,26 +77,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, extern CompositionFunction qt_functionForMode_SSE2[]; extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[]; -#endif // QT_COMPILER_SUPPORTS_SSE2 - -#ifdef QT_COMPILER_SUPPORTS_AVX -void qt_memfill32_avx(quint32 *dest, quint32 value, int count); -void qt_memfill16_avx(quint16 *dest, quint16 value, int count); -void qt_bitmapblit32_avx(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride); -void qt_bitmapblit16_avx(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride); -void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); -void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); -#endif // QT_COMPILER_SUPPORTS_AVX +#endif // __SSE2__ #ifdef QT_COMPILER_SUPPORTS_IWMMXT void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData); diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 0e0c06f56c..cdf68b932d 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -44,7 +44,7 @@ #include <private/qsimd_p.h> -#ifdef QT_COMPILER_SUPPORTS_SSE2 +#ifdef __SSE2__ // // W A R N I N G @@ -242,6 +242,6 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -#endif // QT_COMPILER_SUPPORTS_SSE2 +#endif // __SSE2__ #endif // QDRAWINGPRIMITIVE_SSE2_P_H diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index f1eaea0f6b..acab08e794 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -387,6 +387,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw \value OpenGL2 \value PaintBuffer \value Blitter + \value Direct2D Windows only, Direct2D based engine */ /*! diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h index 18b6d84146..7b928ba5f6 100644 --- a/src/gui/painting/qpaintengine.h +++ b/src/gui/painting/qpaintengine.h @@ -207,6 +207,7 @@ public: OpenGL2, PaintBuffer, Blitter, + Direct2D, User = 50, // first user type id MaxUser = 100 // last user type id diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 156e411154..aa2b9bea54 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1738,8 +1738,8 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QMatrix &matrix) const //same as qt_polygon_isect_line in qpolygon.cpp static void qt_painterpath_isect_line(const QPointF &p1, - const QPointF &p2, - const QPointF &pos, + const QPointF &p2, + const QPointF &pos, int *winding) { qreal x1 = p1.x(); @@ -2551,6 +2551,26 @@ QPainterPathStroker::QPainterPathStroker() } /*! + Creates a new stroker based on \a pen. + + \since 5.3 + */ +QPainterPathStroker::QPainterPathStroker(const QPen &pen) + : d_ptr(new QPainterPathStrokerPrivate) +{ + setWidth(pen.widthF()); + setCapStyle(pen.capStyle()); + setJoinStyle(pen.joinStyle()); + setMiterLimit(pen.miterLimit()); + setDashOffset(pen.dashOffset()); + + if (pen.style() == Qt::CustomDashLine) + setDashPattern(pen.dashPattern()); + else + setDashPattern(pen.style()); +} + +/*! Destroys the stroker. */ QPainterPathStroker::~QPainterPathStroker() diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index e22c1729f3..c922867eb9 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -57,6 +57,7 @@ class QPainterPathPrivate; struct QPainterPathPrivateDeleter; class QPainterPathData; class QPainterPathStrokerPrivate; +class QPen; class QPolygonF; class QRegion; class QVectorPath; @@ -243,6 +244,7 @@ class Q_GUI_EXPORT QPainterPathStroker Q_DECLARE_PRIVATE(QPainterPathStroker) public: QPainterPathStroker(); + QPainterPathStroker(const QPen &pen); ~QPainterPathStroker(); void setWidth(qreal width); diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index 6a3eacd67a..c0b3769c2d 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -455,15 +455,19 @@ QVector<qreal> QPen::dashPattern() const switch (d->style) { case Qt::DashLine: + dd->dashPattern.reserve(2); dd->dashPattern << dash << space; break; case Qt::DotLine: + dd->dashPattern.reserve(2); dd->dashPattern << dot << space; break; case Qt::DashDotLine: + dd->dashPattern.reserve(4); dd->dashPattern << dash << space << dot << space; break; case Qt::DashDotDotLine: + dd->dashPattern.reserve(6); dd->dashPattern << dash << space << dot << space << dot << space; break; default: |