From 3b3e79adb17fa2b28eca9528bfc585a5d113a429 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 9 Aug 2016 19:56:37 +0000 Subject: [PATCH] no need for SIMD in imageconversions and drawing now now that image format is not changed when scaling the performance impact with this change is almost none, in most cases you will (should) not notice a difference. if you care about performance you most likely build with -mtune=native anyway so that the compiler can better optimize things for the hardware. Signed-off-by: Ivailo Monev --- src/gui/image/image.cmake | 7 - src/gui/image/qimage.cpp | 29 - src/gui/image/qimage_neon.cpp | 116 ---- src/gui/image/qimage_p.h | 1 - src/gui/image/qimage_sse2.cpp | 111 --- src/gui/image/qimage_ssse3.cpp | 151 ---- src/gui/image/qjpeghandler.cpp | 16 - src/gui/kernel/qapplication.cpp | 3 - src/gui/painting/painting.cmake | 23 - src/gui/painting/qdrawhelper.cpp | 248 +------ src/gui/painting/qdrawhelper_arm_simd.cpp | 115 --- src/gui/painting/qdrawhelper_arm_simd_p.h | 76 -- src/gui/painting/qdrawhelper_iwmmxt.cpp | 151 ---- src/gui/painting/qdrawhelper_mmx.cpp | 159 ----- src/gui/painting/qdrawhelper_mmx3dnow.cpp | 130 ---- src/gui/painting/qdrawhelper_mmx_p.h | 892 ------------------------ src/gui/painting/qdrawhelper_neon.cpp | 1005 --------------------------- src/gui/painting/qdrawhelper_neon_asm.S | 297 -------- src/gui/painting/qdrawhelper_neon_p.h | 146 ---- src/gui/painting/qdrawhelper_sse.cpp | 172 ----- src/gui/painting/qdrawhelper_sse2.cpp | 547 --------------- src/gui/painting/qdrawhelper_sse3dnow.cpp | 145 ---- src/gui/painting/qdrawhelper_sse_p.h | 182 ----- src/gui/painting/qdrawhelper_ssse3.cpp | 185 ----- src/gui/painting/qdrawhelper_x86_p.h | 141 ---- src/gui/painting/qdrawingprimitive_sse2_p.h | 241 ------- src/gui/painting/qwmatrix.h | 57 -- 27 files changed, 5 insertions(+), 5341 deletions(-) delete mode 100644 src/gui/image/qimage_neon.cpp delete mode 100644 src/gui/image/qimage_sse2.cpp delete mode 100644 src/gui/image/qimage_ssse3.cpp delete mode 100644 src/gui/painting/qdrawhelper_arm_simd.cpp delete mode 100644 src/gui/painting/qdrawhelper_arm_simd_p.h delete mode 100644 src/gui/painting/qdrawhelper_iwmmxt.cpp delete mode 100644 src/gui/painting/qdrawhelper_mmx.cpp delete mode 100644 src/gui/painting/qdrawhelper_mmx3dnow.cpp delete mode 100644 src/gui/painting/qdrawhelper_mmx_p.h delete mode 100644 src/gui/painting/qdrawhelper_neon.cpp delete mode 100644 src/gui/painting/qdrawhelper_neon_asm.S delete mode 100644 src/gui/painting/qdrawhelper_neon_p.h delete mode 100644 src/gui/painting/qdrawhelper_sse.cpp delete mode 100644 src/gui/painting/qdrawhelper_sse2.cpp delete mode 100644 src/gui/painting/qdrawhelper_sse3dnow.cpp delete mode 100644 src/gui/painting/qdrawhelper_sse_p.h delete mode 100644 src/gui/painting/qdrawhelper_ssse3.cpp delete mode 100644 src/gui/painting/qdrawhelper_x86_p.h delete mode 100644 src/gui/painting/qdrawingprimitive_sse2_p.h delete mode 100644 src/gui/painting/qwmatrix.h diff --git a/src/gui/image/image.cmake b/src/gui/image/image.cmake index bfa7a50d2..7870d217a 100644 --- a/src/gui/image/image.cmake +++ b/src/gui/image/image.cmake @@ -61,13 +61,6 @@ set(GUI_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/image/qgifhandler.cpp ) -katie_setup_sources( - GUI_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/image/qimage_neon.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/image/qimage_sse2.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/image/qimage_ssse3.cpp -) - if(WITH_PNG) set(GUI_HEADERS ${GUI_HEADERS} diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3f8166bf7..001e5e5d7 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3374,35 +3374,6 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma } // Format_ARGB4444_Premultiplied }; -void qInitImageConversions() -{ - const uint features = qDetectCPUFeatures(); - Q_UNUSED(features); - -#ifdef QT_HAVE_SSE2 - if (features & SSE2) { - extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); - inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; - } -#endif -#ifdef QT_HAVE_SSSE3 - if (features & SSSE3) { - extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); - converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3; - converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3; - converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; - } -#endif -#ifdef QT_HAVE_NEON - if (features & NEON) { - extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); - converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; - converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon; - converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon; - } -#endif -} - void qGamma_correct_back_to_linear_cs(QImage *image) { extern uchar qt_pow_rgb_gamma[256]; diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp deleted file mode 100644 index 79ef8bdb6..000000000 --- a/src/gui/image/qimage_neon.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 -#include -#include - -#ifdef QT_HAVE_NEON - -QT_BEGIN_NAMESPACE - -Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len) -{ - if (!len) - return; - - const quint32 *const end = dst + len; - - // align dst on 64 bits - const int offsetToAlignOn8Bytes = (reinterpret_cast(dst) >> 2) & 0x1; - for (int i = 0; i < offsetToAlignOn8Bytes; ++i) { - *dst++ = qRgb(src[0], src[1], src[2]); - src += 3; - } - - if ((len - offsetToAlignOn8Bytes) >= 8) { - const quint32 *const simdEnd = end - 7; - register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff); - do { -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - asm volatile ( - "vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t" - "vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "d4", "d5", "d6" - ); -#else - asm volatile ( - "vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t" - "vswp d0, d2\n\t" - "vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "d0", "d1", "d2" - ); -#endif - } while (dst < simdEnd); - } - - while (dst != end) { - *dst++ = qRgb(src[0], src[1], src[2]); - src += 3; - } -} - -void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGB888); - Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const uchar *src_data = (uchar *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - qt_convert_rgb888_to_rgb32_neon(dest_data, src_data, src->width); - src_data += src->bytes_per_line; - dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line); - } -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_NEON - - diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 0c489988b..50856c428 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -107,7 +107,6 @@ struct Q_GUI_EXPORT QImageData { // internal image data QPaintEngine *paintEngine; }; -void qInitImageConversions(); Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image); inline int qt_depthForFormat(QImage::Format format) diff --git a/src/gui/image/qimage_sse2.cpp b/src/gui/image/qimage_sse2.cpp deleted file mode 100644 index 259cbcac2..000000000 --- a/src/gui/image/qimage_sse2.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 "qimage.h" -#include -#include -#include -#include - -#ifdef QT_HAVE_SSE2 - -QT_BEGIN_NAMESPACE - -bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags) -{ - Q_ASSERT(data->format == QImage::Format_ARGB32); - - // extra pixels on each line - const int spare = data->width & 3; - // width in pixels of the pad at the end of each line - const int pad = (data->bytes_per_line >> 2) - data->width; - const int iter = data->width >> 2; - int height = data->height; - - const __m128i alphaMask = _mm_set1_epi32(0xff000000); - const __m128i nullVector = _mm_setzero_si128(); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - - __m128i *d = reinterpret_cast<__m128i*>(data->data); - while (height--) { - const __m128i *end = d + iter; - - for (; d != end; ++d) { - const __m128i srcVector = _mm_loadu_si128(d); - const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { - // opaque, data is unchanged - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) == 0xffff) { - // fully transparent - _mm_storeu_si128(d, nullVector); - } else { - __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); - alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); - - __m128i result; - BYTE_MUL_SSE2(result, srcVector, alphaChannel, colorMask, half); - result = _mm_or_si128(_mm_andnot_si128(alphaMask, result), srcVectorAlpha); - _mm_storeu_si128(d, result); - } - } - - QRgb *p = reinterpret_cast(d); - QRgb *pe = p+spare; - for (; p != pe; ++p) { - if (*p < 0x00ffffff) - *p = 0; - else if (*p < 0xff000000) - *p = PREMUL(*p); - } - - d = reinterpret_cast<__m128i*>(p+pad); - } - - data->format = QImage::Format_ARGB32_Premultiplied; - return true; -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSE2 - - diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp deleted file mode 100644 index dfcbbc4a5..000000000 --- a/src/gui/image/qimage_ssse3.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 -#include -#include - -#ifdef QT_HAVE_SSSE3 - -QT_BEGIN_NAMESPACE - -// Convert a scanline of RGB888 (src) to RGB32 (dst) -// src must be at least len * 3 bytes -// dst must be at least len * 4 bytes -Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len) -{ - quint32 *const end = dst + len; - - // Prologue, align dst to 16 bytes. The alignment is done on dst because it has 4 store() - // for each 3 load() of src. - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(len, offsetToAlignOn16Bytes); - - for (int i = 0; i < prologLength; ++i) { - *dst++ = qRgb(src[0], src[1], src[2]); - src += 3; - } - - // Mask the 4 first colors of the RGB888 vector - const __m128i shuffleMask = _mm_set_epi8(char(0xff), 9, 10, 11, char(0xff), 6, 7, 8, char(0xff), 3, 4, 5, char(0xff), 0, 1, 2); - - // Mask the 4 last colors of a RGB888 vector with an offset of 1 (so the last 3 bytes are RGB) - const __m128i shuffleMaskEnd = _mm_set_epi8(char(0xff), 13, 14, 15, char(0xff), 10, 11, 12, char(0xff), 7, 8, 9, char(0xff), 4, 5, 6); - - // Mask to have alpha = 0xff - const __m128i alphaMask = _mm_set1_epi32(0xff000000); - - __m128i *inVectorPtr = (__m128i *)src; - __m128i *dstVectorPtr = (__m128i *)dst; - - const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels - for (int i = 0; i < simdRoundCount; ++i) { - /* - RGB888 has 5 pixels per vector, + 1 byte from the next pixel. The idea here is - to load vectors of RGB888 and use palignr to select a vector out of two vectors. - - After 3 loads of RGB888 and 3 stores of RGB32, we have 4 pixels left in the last - vector of RGB888, we can mask it directly to get a last store or RGB32. After that, - the first next byte is a R, and we can loop for the next 16 pixels. - - The conversion itself is done with a byte permutation (pshufb). - */ - __m128i firstSrcVector = _mm_lddqu_si128(inVectorPtr); - __m128i outputVector = _mm_shuffle_epi8(firstSrcVector, shuffleMask); - _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); - ++inVectorPtr; - ++dstVectorPtr; - - // There are 4 unused bytes left in srcVector, we need to load the next 16 bytes - // and load the next input with palignr - __m128i secondSrcVector = _mm_lddqu_si128(inVectorPtr); - __m128i srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 12); - outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); - _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); - ++inVectorPtr; - ++dstVectorPtr; - firstSrcVector = secondSrcVector; - - // We now have 8 unused bytes left in firstSrcVector - secondSrcVector = _mm_lddqu_si128(inVectorPtr); - srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 8); - outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); - _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); - ++inVectorPtr; - ++dstVectorPtr; - - // There are now 12 unused bytes in firstSrcVector. - // We can mask them directly, almost there. - outputVector = _mm_shuffle_epi8(secondSrcVector, shuffleMaskEnd); - _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); - ++dstVectorPtr; - } - src = (uchar *)inVectorPtr; - dst = (quint32 *)dstVectorPtr; - - while (dst != end) { - *dst++ = qRgb(src[0], src[1], src[2]); - src += 3; - } -} - -void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGB888); - Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const uchar *src_data = (uchar *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - qt_convert_rgb888_to_rgb32_ssse3(dest_data, src_data, src->width); - src_data += src->bytes_per_line; - dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line); - } -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSSE3 - - diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 11486112c..cda6c0df2 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -779,22 +779,6 @@ bool QJpegHandlerPrivate::read(QImage *image) QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) { - const uint features = qDetectCPUFeatures(); - Q_UNUSED(features); -#if defined(QT_HAVE_NEON) - // from qimage_neon.cpp - Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); - - if (features & NEON) - rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon; -#endif // QT_HAVE_NEON -#if defined(QT_HAVE_SSSE3) - // from qimage_ssse3.cpp - Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); - - if (features & SSSE3) - rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3; -#endif // QT_HAVE_SSSE3 } QJpegHandler::~QJpegHandler() diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index b6376ffdf..b013d358a 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -824,7 +824,6 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv, #endif // Q_WS_X11 extern void qInitDrawhelperAsm(); -extern void qInitImageConversions(); extern int qRegisterGuiVariant(); extern int qUnregisterGuiVariant(); #ifndef QT_NO_STATEMACHINE @@ -881,8 +880,6 @@ void QApplicationPrivate::initialize() // Set up which span functions should be used in raster engine... qInitDrawhelperAsm(); - // and QImage conversion functions - qInitImageConversions(); #ifndef QT_NO_WHEELEVENT QApplicationPrivate::wheel_scroll_lines = 3; diff --git a/src/gui/painting/painting.cmake b/src/gui/painting/painting.cmake index 00583012a..8189a768c 100644 --- a/src/gui/painting/painting.cmake +++ b/src/gui/painting/painting.cmake @@ -41,7 +41,6 @@ set(GUI_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/painting/qtextureglyphcache_p.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qtransform.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qwindowsurface_p.h - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qwmatrix.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qpaintengine_raster_p.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_p.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qblendfunctions_p.h @@ -56,14 +55,6 @@ set(GUI_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/painting/qgraphicssystemfactory_p.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qgraphicssystemplugin_p.h ${CMAKE_CURRENT_SOURCE_DIR}/painting/qwindowsurface_raster_p.h - - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_x86_p.h - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_mmx_p.h - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_sse_p.h - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawingprimitive_sse2_p.h - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_neon_p.h - - # XXX: obsolete? ${CMAKE_CURRENT_SOURCE_DIR}/painting/qrgb.h ) @@ -113,20 +104,6 @@ set(GUI_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/painting/qwindowsurface_raster.cpp ) -katie_setup_sources( - GUI_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_mmx.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_mmx3dnow.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_sse3dnow.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_sse.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_sse2.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_ssse3.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_iwmmxt.cpp - # TODO: link to pixman for arm-neon? - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_neon.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/painting/qdrawhelper_neon_asm.S -) - if(WITH_X11 AND X11_FOUND) set(GUI_HEADERS ${GUI_HEADERS} diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 490347edc..e54a45588 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -42,11 +42,6 @@ #include #include #include -#include -#ifdef QT_HAVE_ARM_SIMD -#include -#endif -#include #include #include @@ -1493,32 +1488,11 @@ static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Op return b; } -#if defined(Q_CC_RVCT) -// Force ARM code generation for comp_func_* -methods -# pragma push -# pragma arm -# if defined(QT_HAVE_ARMV6) -static __forceinline void preload(const uint *start) -{ - asm( "pld [start]" ); -} -static const uint L2CacheLineLength = 32; -static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint); -# define PRELOAD_INIT(x) preload(x); -# define PRELOAD_INIT2(x,y) PRELOAD_INIT(x) PRELOAD_INIT(y) -# define PRELOAD_COND(x) if (((uint)&x[i])%L2CacheLineLength == 0) preload(&x[i] + L2CacheLineLengthInInts); -// Two consecutive preloads stall, so space them out a bit by using different modulus. -# define PRELOAD_COND2(x,y) if (((uint)&x[i])%L2CacheLineLength == 0) preload(&x[i] + L2CacheLineLengthInInts); \ - if (((uint)&y[i])%L2CacheLineLength == 16) preload(&y[i] + L2CacheLineLengthInInts); -# endif // QT_HAVE_ARMV6 -#endif // Q_CC_RVCT - -#if !defined(Q_CC_RVCT) || !defined(QT_HAVE_ARMV6) -# define PRELOAD_INIT(x) -# define PRELOAD_INIT2(x,y) -# define PRELOAD_COND(x) -# define PRELOAD_COND2(x,y) -#endif +// TODO: get rid of those +#define PRELOAD_INIT(x) +#define PRELOAD_INIT2(x,y) +#define PRELOAD_COND(x) +#define PRELOAD_COND2(x,y) /* The constant alpha factor describes an alpha factor that gets applied to the result of the composition operation combining it with the destination. @@ -6918,218 +6892,6 @@ void qInitDrawhelperAsm() qt_memfill32 = qt_memfill_template; qt_memfill16 = qt_memfill_quint16; //qt_memfill_template; - CompositionFunction *functionForModeAsm = 0; - CompositionFunctionSolid *functionForModeSolidAsm = 0; - - const uint features = qDetectCPUFeatures(); - if (false) { -#ifdef QT_HAVE_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; -#endif -#ifdef QT_HAVE_SSE - } else if (features & SSE) { -// qt_memfill32 = qt_memfill32_sse; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse; -#ifdef QT_HAVE_3DNOW - if (features & MMX3DNOW) { - qt_memfill32 = qt_memfill32_sse3dnow; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse3dnow; - } -#endif -#endif // SSE - } -#ifdef QT_HAVE_MMX - if (features & MMX) { - functionForModeAsm = qt_functionForMode_MMX; - - functionForModeSolidAsm = qt_functionForModeSolid_MMX; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx; -#ifdef QT_HAVE_3DNOW - if (features & MMX3DNOW) { - functionForModeAsm = qt_functionForMode_MMX3DNOW; - functionForModeSolidAsm = qt_functionForModeSolid_MMX3DNOW; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx3dnow; - } -#endif // 3DNOW - - extern void qt_blend_rgb32_on_rgb32_mmx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - extern void qt_blend_argb32_on_argb32_mmx(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_mmx; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mmx; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx; - - } -#endif // MMX - -#ifdef QT_HAVE_SSE - if (features & SSE) { - extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - extern void qt_blend_argb32_on_argb32_sse(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_sse; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; - } -#endif // SSE - -#ifdef QT_HAVE_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; - - 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_HAVE_SSSE3 - if (features & SSSE3) { - extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - - 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; - } -#endif // SSSE3 - -#endif // SSE2 - -#ifdef QT_HAVE_SSE - if (features & SSE) { - functionForModeAsm = qt_functionForMode_SSE; - functionForModeSolidAsm = qt_functionForModeSolid_SSE; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_sse; -#ifdef QT_HAVE_3DNOW - if (features & MMX3DNOW) { - functionForModeAsm = qt_functionForMode_SSE3DNOW; - functionForModeSolidAsm = qt_functionForModeSolid_SSE3DNOW; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_sse3dnow; - } -#endif // 3DNOW - - -#ifdef QT_HAVE_SSE2 - if (features & SSE2) { - extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, - const uint *srcPixels, - int length, - uint const_alpha); - extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); - extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha); - extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha); - - functionForModeAsm[0] = comp_func_SourceOver_sse2; - functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2; - functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; - functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2; - } -#endif - } -#elif defined(QT_HAVE_SSE2) - // this is the special case when SSE2 is usable but MMX/SSE is not usable (e.g.: Windows x64 + visual studio) - if (features & SSE2) { - functionForModeAsm = qt_functionForMode_onlySSE2; - functionForModeSolidAsm = qt_functionForModeSolid_onlySSE2; - } -#endif - -#ifdef QT_HAVE_IWMMXT - if (features & IWMMXT) { - functionForModeAsm = qt_functionForMode_IWMMXT; - functionForModeSolidAsm = qt_functionForModeSolid_IWMMXT; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_iwmmxt; - } -#endif // IWMMXT - -#if defined(QT_HAVE_ARM_SIMD) - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; -#elif defined(QT_HAVE_NEON) - 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; - - 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; - - 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; - - qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; - qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; - qt_memfill32 = qt_memfill32_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); - - qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; - } -#endif - - if (functionForModeSolidAsm) { - const int destinationMode = QPainter::CompositionMode_Destination; - functionForModeSolidAsm[destinationMode] = functionForModeSolid_C[destinationMode]; - - // use the default qdrawhelper implementation for the - // extended composition modes - for (int mode = 12; mode < 24; ++mode) - functionForModeSolidAsm[mode] = functionForModeSolid_C[mode]; - - functionForModeSolid = functionForModeSolidAsm; - } - if (functionForModeAsm) - functionForMode = functionForModeAsm; - qt_build_pow_tables(); } diff --git a/src/gui/painting/qdrawhelper_arm_simd.cpp b/src/gui/painting/qdrawhelper_arm_simd.cpp deleted file mode 100644 index 69e1f79c2..000000000 --- a/src/gui/painting/qdrawhelper_arm_simd.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 "qdrawhelper_arm_simd_p.h" - -#include -#include - -#ifdef QT_HAVE_ARM_SIMD - - - -// TODO: add GNU assembler instructions and support for other platforms. -// Default to C code for now - -void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const uint *src = (const uint *) srcPixels; - uint *dst = (uint *) destPixels; - if (const_alpha == 256) { - for (int y=0; y= 0xff000000) - dst[x] = s; - else if (s != 0) - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); - } - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } - } else if (const_alpha != 0) { - const_alpha = (const_alpha * 255) >> 8; - for (int y=0; y - -QT_BEGIN_NAMESPACE - -#if defined(QT_HAVE_ARM_SIMD) - -void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_rgb32_on_rgb32_arm_simd(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -#endif // QT_HAVE_ARM_SIMD - -QT_END_NAMESPACE - -#endif // QDRAWHELPER_ARM_SIMD_P_H diff --git a/src/gui/painting/qdrawhelper_iwmmxt.cpp b/src/gui/painting/qdrawhelper_iwmmxt.cpp deleted file mode 100644 index 610fa38db..000000000 --- a/src/gui/painting/qdrawhelper_iwmmxt.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifdef QT_HAVE_IWMMXT - -#include -#if defined(Q_OS_WINCE) -# include "qplatformdefs.h" -#endif -#if !defined(__IWMMXT__) && !defined(Q_OS_WINCE) -# include -#elif defined(Q_OS_WINCE_STD) && defined(_X86_) -# pragma warning(disable: 4391) -# include -#endif - -#include - -QT_BEGIN_NAMESPACE - -#ifndef _MM_SHUFFLE -#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \ - (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0)) -#endif - -struct QIWMMXTIntrinsics : public QMMXCommonIntrinsics -{ - static inline m64 alpha(m64 x) { - return _mm_shuffle_pi16 (x, _MM_SHUFFLE(3, 3, 3, 3)); - } - - static inline m64 _load_alpha(uint x, const m64 &mmx_0x0000) { - m64 t = _mm_unpacklo_pi8(_mm_cvtsi32_si64(x), mmx_0x0000); - return _mm_shuffle_pi16(t, _MM_SHUFFLE(0, 0, 0, 0)); - } - - static inline void end() { - } -}; - -CompositionFunctionSolid qt_functionForModeSolid_IWMMXT[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - 0, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // svg 1.2 modes - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_IWMMXT[] = { - comp_func_SourceOver, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData) -{ - qt_blend_color_argb_x86(count, spans, userData, - (CompositionFunctionSolid*)qt_functionForModeSolid_IWMMXT); -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_IWMMXT - - - diff --git a/src/gui/painting/qdrawhelper_mmx.cpp b/src/gui/painting/qdrawhelper_mmx.cpp deleted file mode 100644 index d5c23ff99..000000000 --- a/src/gui/painting/qdrawhelper_mmx.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#if defined(QT_HAVE_MMX) - -#include - -QT_BEGIN_NAMESPACE - -CompositionFunctionSolid qt_functionForModeSolid_MMX[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - 0, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // svg 1.2 modes - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_MMX[numCompositionFunctions] = { - comp_func_SourceOver, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_blend_color_argb_mmx(int count, const QSpan *spans, void *userData) -{ - qt_blend_color_argb_x86(count, spans, userData, - (CompositionFunctionSolid*)qt_functionForModeSolid_MMX); -} - - -void qt_blend_argb32_on_argb32_mmx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const uint *src = (const uint *) srcPixels; - uint *dst = (uint *) destPixels; - - uint ca = const_alpha - 1; - - for (int y=0; y(dst, src, w, ca); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } -} - -void qt_blend_rgb32_on_rgb32_mmx(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const uint *src = (const uint *) srcPixels; - uint *dst = (uint *) destPixels; - - uint ca = const_alpha - 1; - - for (int y=0; y(dst, src, w, ca); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_MMX - - - - - diff --git a/src/gui/painting/qdrawhelper_mmx3dnow.cpp b/src/gui/painting/qdrawhelper_mmx3dnow.cpp deleted file mode 100644 index 37eac9c1d..000000000 --- a/src/gui/painting/qdrawhelper_mmx3dnow.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#ifdef QT_HAVE_3DNOW - -#include -#include - -QT_BEGIN_NAMESPACE - -struct QMMX3DNOWIntrinsics : public QMMXCommonIntrinsics -{ - static inline void end() { - _m_femms(); - } -}; - -CompositionFunctionSolid qt_functionForModeSolid_MMX3DNOW[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - 0, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // svg 1.2 modes - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_MMX3DNOW[numCompositionFunctions] = { - comp_func_SourceOver, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_blend_color_argb_mmx3dnow(int count, const QSpan *spans, void *userData) -{ - qt_blend_color_argb_x86(count, spans, userData, - (CompositionFunctionSolid*)qt_functionForModeSolid_MMX3DNOW); -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_3DNOW - - - diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h deleted file mode 100644 index 0539a7fa7..000000000 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ /dev/null @@ -1,892 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QDRAWHELPER_MMX_P_H -#define QDRAWHELPER_MMX_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -#ifdef QT_HAVE_MMX -#include -#endif - -#define C_FF const m64 mmx_0x00ff = _mm_set1_pi16(0xff) -#define C_80 const m64 mmx_0x0080 = _mm_set1_pi16(0x80) -#define C_00 const m64 mmx_0x0000 = _mm_setzero_si64() - -#ifdef Q_CC_MSVC -# pragma warning(disable: 4799) // No EMMS at end of function -#endif - -typedef __m64 m64; - -QT_BEGIN_NAMESPACE - -struct QMMXCommonIntrinsics -{ - static inline m64 alpha(m64 x) { - x = _mm_unpackhi_pi16(x, x); - x = _mm_unpackhi_pi16(x, x); - return x; - } - - static inline m64 _negate(const m64 &x, const m64 &mmx_0x00ff) { - return _mm_xor_si64(x, mmx_0x00ff); - } - - static inline m64 add(const m64 &a, const m64 &b) { - return _mm_adds_pu16 (a, b); - } - - static inline m64 _byte_mul(const m64 &a, const m64 &b, - const m64 &mmx_0x0080) - { - m64 res = _mm_mullo_pi16(a, b); - res = _mm_adds_pu16(res, mmx_0x0080); - res = _mm_adds_pu16(res, _mm_srli_pi16 (res, 8)); - return _mm_srli_pi16(res, 8); - } - - static inline m64 interpolate_pixel_256(const m64 &x, const m64 &a, - const m64 &y, const m64 &b) - { - m64 res = _mm_adds_pu16(_mm_mullo_pi16(x, a), _mm_mullo_pi16(y, b)); - return _mm_srli_pi16(res, 8); - } - - static inline m64 _interpolate_pixel_255(const m64 &x, const m64 &a, - const m64 &y, const m64 &b, - const m64 &mmx_0x0080) - { - m64 res = _mm_adds_pu16(_mm_mullo_pi16(x, a), _mm_mullo_pi16(y, b)); - res = _mm_adds_pu16(res, mmx_0x0080); - res = _mm_adds_pu16(res, _mm_srli_pi16 (res, 8)); - return _mm_srli_pi16(res, 8); - } - - static inline m64 _premul(m64 x, const m64 &mmx_0x0080) { - m64 a = alpha(x); - return _byte_mul(x, a, mmx_0x0080); - } - - static inline m64 _load(uint x, const m64 &mmx_0x0000) { - return _mm_unpacklo_pi8(_mm_cvtsi32_si64(x), mmx_0x0000); - } - - static inline m64 _load_alpha(uint x, const m64 &) { - x |= (x << 16); - return _mm_set1_pi32(x); - } - - static inline uint _store(const m64 &x, const m64 &mmx_0x0000) { - return _mm_cvtsi64_si32(_mm_packs_pu16(x, mmx_0x0000)); - } -}; - -#define negate(x) _negate(x, mmx_0x00ff) -#define byte_mul(a, b) _byte_mul(a, b, mmx_0x0080) -#define interpolate_pixel_255(x, a, y, b) _interpolate_pixel_255(x, a, y, b, mmx_0x0080) -#define premul(x) _premul(x, mmx_0x0080) -#define load(x) _load(x, mmx_0x0000) -#define load_alpha(x) _load_alpha(x, mmx_0x0000) -#define store(x) _store(x, mmx_0x0000) - -/* - result = 0 - d = d * cia -*/ -#define comp_func_Clear_impl(dest, length, const_alpha)\ -{\ - if (const_alpha == 255) {\ - qt_memfill(static_cast(dest), quint32(0), length);\ - } else {\ - C_FF; C_80; C_00;\ - m64 ia = MM::negate(MM::load_alpha(const_alpha));\ - for (int i = 0; i < length; ++i) {\ - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\ - }\ - MM::end();\ - }\ -} - -template -static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) -{ - comp_func_Clear_impl(dest, length, const_alpha); -} - -template -static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) -{ - comp_func_Clear_impl(dest, length, const_alpha); -} - -/* - result = s - dest = s * ca + d * cia -*/ -template -static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint src, uint const_alpha) -{ - if (const_alpha == 255) { - qt_memfill(static_cast(dest), quint32(src), length); - } else { - C_FF; C_80; C_00; - const m64 a = MM::load_alpha(const_alpha); - const m64 ia = MM::negate(a); - const m64 s = MM::byte_mul(MM::load(src), a); - for (int i = 0; i < length; ++i) { - dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); - } - MM::end(); - } -} - -template -static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha) -{ - if (const_alpha == 255) { - ::memcpy(dest, src, length * sizeof(uint)); - } else { - C_FF; C_80; C_00; - const m64 a = MM::load_alpha(const_alpha); - const m64 ia = MM::negate(a); - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::interpolate_pixel_255(MM::load(src[i]), a, - MM::load(dest[i]), ia)); - } - MM::end(); -} - -/* - result = s + d * sia - dest = (s + d * sia) * ca + d * cia - = s * ca + d * (sia * ca + cia) - = s * ca + d * (1 - sa*ca) -*/ -template -static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint src, uint const_alpha) -{ - if ((const_alpha & qAlpha(src)) == 255) { - qt_memfill(static_cast(dest), quint32(src), length); - } else { - C_FF; C_80; C_00; - m64 s = MM::load(src); - if (const_alpha != 255) { - m64 ca = MM::load_alpha(const_alpha); - s = MM::byte_mul(s, ca); - } - m64 a = MM::negate(MM::alpha(s)); - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), a))); - MM::end(); - } -} - -template -static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - const uint alphaMaskedSource = 0xff000000 & src[i]; - if (alphaMaskedSource == 0) - continue; - if (alphaMaskedSource == 0xff000000) { - dest[i] = src[i]; - } else { - m64 s = MM::load(src[i]); - m64 ia = MM::negate(MM::alpha(s)); - dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); - } - } - } else { - m64 ca = MM::load_alpha(const_alpha); - for (int i = 0; i < length; ++i) { - if ((0xff000000 & src[i]) == 0) - continue; - m64 s = MM::byte_mul(MM::load(src[i]), ca); - m64 ia = MM::negate(MM::alpha(s)); - dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); - } - } - MM::end(); -} - -/* - result = d + s * dia - dest = (d + s * dia) * ca + d * cia - = d + s * dia * ca -*/ -template -static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 s = MM::load(src); - if (const_alpha != 255) - s = MM::byte_mul(s, MM::load_alpha(const_alpha)); - - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 dia = MM::negate(MM::alpha(d)); - dest[i] = MM::store(MM::add(d, MM::byte_mul(s, dia))); - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 ia = MM::negate(MM::alpha(d)); - dest[i] = MM::store(MM::add(d, MM::byte_mul(MM::load(src[i]), ia))); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 dia = MM::negate(MM::alpha(d)); - dia = MM::byte_mul(dia, ca); - dest[i] = MM::store(MM::add(d, MM::byte_mul(MM::load(src[i]), dia))); - } - } - MM::end(); -} - -/* - result = s * da - dest = s * da * ca + d * cia -*/ -template -static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint src, uint const_alpha) -{ - C_80; C_00; - if (const_alpha == 255) { - m64 s = MM::load(src); - for (int i = 0; i < length; ++i) { - m64 da = MM::alpha(MM::load(dest[i])); - dest[i] = MM::store(MM::byte_mul(s, da)); - } - } else { - C_FF; - m64 s = MM::load(src); - m64 ca = MM::load_alpha(const_alpha); - s = MM::byte_mul(s, ca); - m64 cia = MM::negate(ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, cia)); - } - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 a = MM::alpha(MM::load(dest[i])); - dest[i] = MM::store(MM::byte_mul(MM::load(src[i]), a)); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 da = MM::byte_mul(MM::alpha(d), ca); - dest[i] = MM::store(MM::interpolate_pixel_255( - MM::load(src[i]), da, d, cia)); - } - } - MM::end(); -} - -/* - result = d * sa - dest = d * sa * ca + d * cia - = d * (sa * ca + cia) -*/ -template -static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint src, uint const_alpha) -{ - C_80; C_00; - m64 a = MM::alpha(MM::load(src)); - if (const_alpha != 255) { - C_FF; - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - a = MM::byte_mul(a, ca); - a = MM::add(a, cia); - } - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a)); - MM::end(); -} - -template -static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 a = MM::alpha(MM::load(src[i])); - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a)); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 a = MM::alpha(MM::load(src[i])); - a = MM::byte_mul(a, ca); - a = MM::add(a, cia); - dest[i] = MM::store(MM::byte_mul(d, a)); - } - } - MM::end(); -} - -/* - result = s * dia - dest = s * dia * ca + d * cia -*/ -template -static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 s = MM::load(src); - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 dia = MM::negate(MM::alpha(MM::load(dest[i]))); - dest[i] = MM::store(MM::byte_mul(s, dia)); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - s = MM::byte_mul(s, ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), d, cia)); - } - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 ia = MM::negate(MM::alpha(MM::load(dest[i]))); - dest[i] = MM::store(MM::byte_mul(MM::load(src[i]), ia)); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 dia = MM::byte_mul(MM::negate(MM::alpha(d)), ca); - dest[i] = MM::store(MM::interpolate_pixel_255(MM::load(src[i]), dia, d, cia)); - } - } - MM::end(); -} - -/* - result = d * sia - dest = d * sia * ca + d * cia - = d * (sia * ca + cia) -*/ -template -static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 a = MM::negate(MM::alpha(MM::load(src))); - if (const_alpha != 255) { - m64 ca = MM::load_alpha(const_alpha); - a = MM::byte_mul(a, ca); - a = MM::add(a, MM::negate(ca)); - } - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a)); - MM::end(); -} - -template -static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 a = MM::negate(MM::alpha(MM::load(src[i]))); - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a)); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - m64 cia = MM::negate(ca); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - m64 a = MM::negate(MM::alpha(MM::load(src[i]))); - a = MM::byte_mul(a, ca); - a = MM::add(a, cia); - dest[i] = MM::store(MM::byte_mul(d, a)); - } - } - MM::end(); -} - -/* - result = s*da + d*sia - dest = s*da*ca + d*sia*ca + d *cia - = s*ca * da + d * (sia*ca + cia) - = s*ca * da + d * (1 - sa*ca) -*/ -template -static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 s = MM::load(src); - if (const_alpha != 255) { - m64 ca = MM::load_alpha(const_alpha); - s = MM::byte_mul(s, ca); - } - m64 a = MM::negate(MM::alpha(s)); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, a)); - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, - MM::negate(MM::alpha(s)))); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - s = MM::byte_mul(s, ca); - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, - MM::negate(MM::alpha(s)))); - } - } - MM::end(); -} - -/* - result = d*sa + s*dia - dest = d*sa*ca + s*dia*ca + d *cia - = s*ca * dia + d * (sa*ca + cia) -*/ -template -static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 s = MM::load(src); - m64 a = MM::alpha(s); - if (const_alpha != 255) { - m64 ca = MM::load_alpha(const_alpha); - s = MM::byte_mul(s, ca); - a = MM::alpha(s); - a = MM::add(a, MM::negate(ca)); - } - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), d, a)); - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(d, MM::alpha(s), s, - MM::negate(MM::alpha(d)))); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - s = MM::byte_mul(s, ca); - m64 d = MM::load(dest[i]); - m64 a = MM::alpha(s); - a = MM::add(a, MM::negate(ca)); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), - d, a)); - } - } - MM::end(); -} - -/* - result = d*sia + s*dia - dest = d*sia*ca + s*dia*ca + d *cia - = s*ca * dia + d * (sia*ca + cia) - = s*ca * dia + d * (1 - sa*ca) -*/ -template -static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint src, uint const_alpha) -{ - C_FF; C_80; C_00; - m64 s = MM::load(src); - if (const_alpha != 255) { - m64 ca = MM::load_alpha(const_alpha); - s = MM::byte_mul(s, ca); - } - m64 a = MM::negate(MM::alpha(s)); - for (int i = 0; i < length; ++i) { - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), - d, a)); - } - MM::end(); -} - -template -static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) -{ - C_FF; C_80; C_00; - if (const_alpha == 255) { - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), - d, MM::negate(MM::alpha(s)))); - } - } else { - m64 ca = MM::load_alpha(const_alpha); - for (int i = 0; i < length; ++i) { - m64 s = MM::load(src[i]); - s = MM::byte_mul(s, ca); - m64 d = MM::load(dest[i]); - dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), - d, MM::negate(MM::alpha(s)))); - } - } - MM::end(); -} - -template -static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - Q_UNUSED(const_alpha); - - if ((quintptr)(dest) & 0x7) { - *dest++ |= color; - --length; - } - - const int length64 = length / 2; - if (length64) { - __m64 *dst64 = reinterpret_cast<__m64*>(dest); - const __m64 color64 = _mm_set_pi32(color, color); - - int n = (length64 + 3) / 4; - switch (length64 & 0x3) { - case 0: do { *dst64 = _mm_or_si64(*dst64, color64); ++dst64; - case 3: *dst64 = _mm_or_si64(*dst64, color64); ++dst64; - case 2: *dst64 = _mm_or_si64(*dst64, color64); ++dst64; - case 1: *dst64 = _mm_or_si64(*dst64, color64); ++dst64; - } while (--n > 0); - } - } - - if (length & 0x1) { - dest[length - 1] |= color; - } - - MM::end(); -} - -template -static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - Q_UNUSED(const_alpha); - - color |= 0xff000000; - - if ((quintptr)(dest) & 0x7) { // align - *dest++ &= color; - --length; - } - - const int length64 = length / 2; - if (length64) { - __m64 *dst64 = reinterpret_cast<__m64*>(dest); - const __m64 color64 = _mm_set_pi32(color, color); - - int n = (length64 + 3) / 4; - switch (length64 & 0x3) { - case 0: do { *dst64 = _mm_and_si64(*dst64, color64); ++dst64; - case 3: *dst64 = _mm_and_si64(*dst64, color64); ++dst64; - case 2: *dst64 = _mm_and_si64(*dst64, color64); ++dst64; - case 1: *dst64 = _mm_and_si64(*dst64, color64); ++dst64; - } while (--n > 0); - } - } - - if (length & 0x1) { - dest[length - 1] &= color; - } - - MM::end(); -} - -template -static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - Q_UNUSED(const_alpha); - - color &= 0x00ffffff; - - if ((quintptr)(dest) & 0x7) { - *dest++ ^= color; - --length; - } - - const int length64 = length / 2; - if (length64) { - __m64 *dst64 = reinterpret_cast<__m64*>(dest); - const __m64 color64 = _mm_set_pi32(color, color); - - int n = (length64 + 3) / 4; - switch (length64 & 0x3) { - case 0: do { *dst64 = _mm_xor_si64(*dst64, color64); ++dst64; - case 3: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64; - case 2: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64; - case 1: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64; - } while (--n > 0); - } - } - - if (length & 0x1) { - dest[length - 1] ^= color; - } - - MM::end(); -} - -template -static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - - Q_UNUSED(const_alpha); - - if ((quintptr)(dest) & 0x7) { - *dest = (color & ~(*dest)) | 0xff000000; - ++dest; - --length; - } - - const int length64 = length / 2; - if (length64) { - __m64 *dst64 = reinterpret_cast<__m64*>(dest); - const __m64 color64 = _mm_set_pi32(color, color); - const m64 mmx_0xff000000 = _mm_set1_pi32(0xff000000); - __m64 tmp1, tmp2, tmp3, tmp4; - - int n = (length64 + 3) / 4; - switch (length64 & 0x3) { - case 0: do { tmp1 = _mm_andnot_si64(*dst64, color64); - *dst64++ = _mm_or_si64(tmp1, mmx_0xff000000); - case 3: tmp2 = _mm_andnot_si64(*dst64, color64); - *dst64++ = _mm_or_si64(tmp2, mmx_0xff000000); - case 2: tmp3 = _mm_andnot_si64(*dst64, color64); - *dst64++ = _mm_or_si64(tmp3, mmx_0xff000000); - case 1: tmp4 = _mm_andnot_si64(*dst64, color64); - *dst64++ = _mm_or_si64(tmp4, mmx_0xff000000); - } while (--n > 0); - } - } - - if (length & 0x1) { - dest[length - 1] = (color & ~(dest[length - 1])) | 0xff000000; - } - - MM::end(); -} - -template -static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - rasterop_solid_SourceAndNotDestination(dest, length, - ~color, const_alpha); -} - -template -static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - Q_UNUSED(const_alpha); - color = ~color | 0xff000000; - while (length--) { - *dest = color | ~(*dest); - ++dest; - } -} - -template -static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - rasterop_solid_SourceXorDestination(dest, length, ~color, const_alpha); -} - -template -static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, - uint color, uint const_alpha) -{ - Q_UNUSED(const_alpha); - qt_memfill((quint32*)dest, ~color | 0xff000000, length); -} - -template -static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, - int length, - uint color, - uint const_alpha) -{ - rasterop_solid_SourceAndDestination(dest, length, - ~color, const_alpha); -} - -template -static inline void qt_blend_color_argb_x86(int count, const QSpan *spans, - void *userData, - CompositionFunctionSolid *solidFunc) -{ - QSpanData *data = reinterpret_cast(userData); - if (data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source - || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver - && qAlpha(data->solid.color) == 255)) { - // inline for performance - C_FF; C_80; C_00; - while (count--) { - uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; - if (spans->coverage == 255) { - qt_memfill(static_cast(target), quint32(data->solid.color), spans->len); - } else { - // dest = s * ca + d * (1 - sa*ca) --> dest = s * ca + d * (1-ca) - m64 ca = MM::load_alpha(spans->coverage); - m64 s = MM::byte_mul(MM::load(data->solid.color), ca); - m64 ica = MM::negate(ca); - for (int i = 0; i < spans->len; ++i) - target[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(target[i]), ica))); - } - ++spans; - } - MM::end(); - return; - } - CompositionFunctionSolid func = solidFunc[data->rasterBuffer->compositionMode]; - while (count--) { - uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; - func(target, spans->len, data->solid.color, spans->coverage); - ++spans; - } -} - -#ifdef QT_HAVE_MMX -struct QMMXIntrinsics : public QMMXCommonIntrinsics -{ - static inline void end() { -#if !defined(Q_OS_WINCE) || defined(_X86_) - _mm_empty(); -#endif - } -}; -#endif // QT_HAVE_MMX - -QT_END_NAMESPACE - -#endif // QDRAWHELPER_MMX_P_H diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp deleted file mode 100644 index d477461a0..000000000 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ /dev/null @@ -1,1005 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 -#include -#include - -#ifdef QT_HAVE_NEON - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -void qt_memfill32_neon(quint32 *dest, quint32 value, int count) -{ - const int epilogueSize = count % 16; - if (count >= 16) { - quint32 *const neonEnd = dest + count - epilogueSize; - register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value); - register uint32x4_t valueVector2 asm ("q1") = valueVector1; - while (dest != neonEnd) { - asm volatile ( - "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" - "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" - : [DST]"+r" (dest) - : [VALUE1]"w"(valueVector1), [VALUE2]"w"(valueVector2) - : "memory" - ); - } - } - - switch (epilogueSize) - { - case 15: *dest++ = value; - case 14: *dest++ = value; - case 13: *dest++ = value; - case 12: *dest++ = value; - case 11: *dest++ = value; - case 10: *dest++ = value; - case 9: *dest++ = value; - case 8: *dest++ = value; - case 7: *dest++ = value; - case 6: *dest++ = value; - case 5: *dest++ = value; - case 4: *dest++ = value; - case 3: *dest++ = value; - case 2: *dest++ = value; - case 1: *dest++ = value; - } -} - -static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half) -{ - // result = (x + (x >> 8) + 0x80) >> 8 - - const uint16x8_t temp = vshrq_n_u16(x, 8); // x >> 8 - const uint16x8_t sum_part = vaddq_u16(x, half); // x + 0x80 - const uint16x8_t sum = vaddq_u16(temp, sum_part); - - return vshrq_n_u16(sum, 8); -} - -static inline uint16x8_t qvbyte_mul_u16(uint16x8_t x, uint16x8_t alpha, uint16x8_t half) -{ - // t = qRound(x * alpha / 255.0) - - const uint16x8_t t = vmulq_u16(x, alpha); // t - return qvdiv_255_u16(t, half); -} - -static inline uint16x8_t qvinterpolate_pixel_255(uint16x8_t x, uint16x8_t a, uint16x8_t y, uint16x8_t b, uint16x8_t half) -{ - // t = x * a + y * b - - const uint16x8_t ta = vmulq_u16(x, a); - const uint16x8_t tb = vmulq_u16(y, b); - - return qvdiv_255_u16(vaddq_u16(ta, tb), half); -} - -static inline uint16x8_t qvsource_over_u16(uint16x8_t src16, uint16x8_t dst16, uint16x8_t half, uint16x8_t full) -{ - const uint16x4_t alpha16_high = vdup_lane_u16(vget_high_u16(src16), 3); - const uint16x4_t alpha16_low = vdup_lane_u16(vget_low_u16(src16), 3); - - const uint16x8_t alpha16 = vsubq_u16(full, vcombine_u16(alpha16_low, alpha16_high)); - - return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half)); -} - -extern "C" void -pixman_composite_over_8888_0565_asm_neon (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint32_t *src, - int32_t src_stride); - -extern "C" void -pixman_composite_over_8888_8888_asm_neon (int32_t w, - int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint32_t *src, - int32_t src_stride); - -extern "C" void -pixman_composite_src_0565_8888_asm_neon (int32_t w, - int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint16_t *src, - int32_t src_stride); - -extern "C" void -pixman_composite_over_n_8_0565_asm_neon (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint32_t src, - int32_t unused, - uint8_t *mask, - int32_t mask_stride); - -extern "C" void -pixman_composite_scanline_over_asm_neon (int32_t w, - const uint32_t *dst, - const uint32_t *src); - -extern "C" void -pixman_composite_src_0565_0565_asm_neon (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint16_t *src, - int32_t src_stride); - -// qblendfunctions.cpp -void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - dbpl /= 4; - sbpl /= 2; - - quint32 *dst = (quint32 *) destPixels; - quint16 *src = (quint16 *) srcPixels; - - if (const_alpha != 256) { - quint8 a = (255 * const_alpha) >> 8; - quint8 ia = 255 - a; - - while (h--) { - for (int x=0; x -static inline void scanLineBlit16(quint16 *dst, quint16 *src, int dstride) -{ - if (N >= 2) { - ((quint32 *)dst)[0] = ((quint32 *)src)[0]; - __builtin_prefetch(dst + dstride, 1, 0); - } - for (int i = 1; i < N/2; ++i) - ((quint32 *)dst)[i] = ((quint32 *)src)[i]; - if (N & 1) - dst[N-1] = src[N-1]; -} - -template -static inline void blockBlit16(quint16 *dst, quint16 *src, int dstride, int sstride, int h) -{ - union { - quintptr address; - quint16 *pointer; - } u; - - u.pointer = dst; - - if (u.address & 2) { - while (h--) { - // align dst - dst[0] = src[0]; - if (Width > 1) - scanLineBlit16(dst + 1, src + 1, dstride); - dst += dstride; - src += sstride; - } - } else { - while (h--) { - scanLineBlit16(dst, src, dstride); - - dst += dstride; - src += sstride; - } - } -} - -void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - // testing show that the default memcpy is faster for widths 150 and up - if (const_alpha != 256 || w >= 150) { - qt_blend_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); - return; - } - - int dstride = dbpl / 2; - int sstride = sbpl / 2; - - quint16 *dst = (quint16 *) destPixels; - quint16 *src = (quint16 *) srcPixels; - - switch (w) { -#define BLOCKBLIT(n) case n: blockBlit16(dst, src, dstride, sstride, h); return; - BLOCKBLIT(1); - BLOCKBLIT(2); - BLOCKBLIT(3); - BLOCKBLIT(4); - BLOCKBLIT(5); - BLOCKBLIT(6); - BLOCKBLIT(7); - BLOCKBLIT(8); - BLOCKBLIT(9); - BLOCKBLIT(10); - BLOCKBLIT(11); - BLOCKBLIT(12); - BLOCKBLIT(13); - BLOCKBLIT(14); - BLOCKBLIT(15); -#undef BLOCKBLIT - default: - break; - } - - pixman_composite_src_0565_0565_asm_neon (w, h, dst, dstride, src, sstride); -} - -extern "C" void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha); - -void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - quint16 *dst = (quint16 *) destPixels; - quint32 *src = (quint32 *) srcPixels; - - if (const_alpha != 256) { - for (int y=0; y> 8; - uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha); - for (int y = 0; y < h; ++y) { - int x = 0; - for (; x < w-3; x += 4) { - if (src[x] | src[x+1] | src[x+2] | src[x+3]) { - uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); - uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - - const uint8x16_t src8 = vreinterpretq_u8_u32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); - - const uint8x8_t src8_low = vget_low_u8(src8); - const uint8x8_t dst8_low = vget_low_u8(dst8); - - const uint8x8_t src8_high = vget_high_u8(src8); - const uint8x8_t dst8_high = vget_high_u8(dst8); - - const uint16x8_t src16_low = vmovl_u8(src8_low); - const uint16x8_t dst16_low = vmovl_u8(dst8_low); - - const uint16x8_t src16_high = vmovl_u8(src8_high); - const uint16x8_t dst16_high = vmovl_u8(dst8_high); - - const uint16x8_t srcalpha16_low = qvbyte_mul_u16(src16_low, const_alpha16, half); - const uint16x8_t srcalpha16_high = qvbyte_mul_u16(src16_high, const_alpha16, half); - - const uint16x8_t result16_low = qvsource_over_u16(srcalpha16_low, dst16_low, half, full); - const uint16x8_t result16_high = qvsource_over_u16(srcalpha16_high, dst16_high, half, full); - - const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); - const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - - vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); - } - } - for (; x> 8; - int one_minus_const_alpha = 255 - const_alpha; - uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha); - uint16x8_t one_minus_const_alpha16 = vdupq_n_u16(255 - const_alpha); - for (int y = 0; y < h; ++y) { - int x = 0; - for (; x < w-3; x += 4) { - uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); - uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - - const uint8x16_t src8 = vreinterpretq_u8_u32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); - - const uint8x8_t src8_low = vget_low_u8(src8); - const uint8x8_t dst8_low = vget_low_u8(dst8); - - const uint8x8_t src8_high = vget_high_u8(src8); - const uint8x8_t dst8_high = vget_high_u8(dst8); - - const uint16x8_t src16_low = vmovl_u8(src8_low); - const uint16x8_t dst16_low = vmovl_u8(dst8_low); - - const uint16x8_t src16_high = vmovl_u8(src8_high); - const uint16x8_t dst16_high = vmovl_u8(dst8_high); - - const uint16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half); - const uint16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half); - - const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); - const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - - vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); - } - for (; x(rasterBuffer->scanLine(y)) + x; - const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); - - uchar *mask = const_cast(bitmap); - - pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, color, 0, mask, mapStride); -} - -extern "C" void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha); - -template -struct Blend_on_RGB16_SourceAndConstAlpha_Neon { - Blend_on_RGB16_SourceAndConstAlpha_Neon(BlendFunc blender, int const_alpha) - : m_index(0) - , m_blender(blender) - , m_const_alpha(const_alpha) - { - } - - inline void write(quint16 *dst, quint32 src) - { - srcBuffer[m_index++] = src; - - if (m_index == 8) { - m_blender(dst - 7, srcBuffer, m_const_alpha); - m_index = 0; - } - } - - inline void flush(quint16 *dst) - { - if (m_index > 0) { - quint16 dstBuffer[8]; - for (int i = 0; i < m_index; ++i) - dstBuffer[i] = dst[i - m_index]; - - m_blender(dstBuffer, srcBuffer, m_const_alpha); - - for (int i = 0; i < m_index; ++i) - dst[i - m_index] = dstBuffer[i]; - - m_index = 0; - } - } - - SRC srcBuffer[8]; - - int m_index; - BlendFunc m_blender; - int m_const_alpha; -}; - -template -Blend_on_RGB16_SourceAndConstAlpha_Neon -Blend_on_RGB16_SourceAndConstAlpha_Neon_create(BlendFunc blender, int const_alpha) -{ - return Blend_on_RGB16_SourceAndConstAlpha_Neon(blender, const_alpha); -} - -void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, int sh, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha) -{ - if (const_alpha == 0) - return; - - qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, sh, targetRect, sourceRect, clip, - Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); -} - -void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, int sh, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha); - -void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, int sh, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha) -{ - if (const_alpha == 0) - return; - - if (const_alpha == 256) { - qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, sh, targetRect, sourceRect, clip, const_alpha); - return; - } - - qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, sh, targetRect, sourceRect, clip, - Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); -} - -extern void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - int const_alpha); - -void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - int const_alpha) -{ - if (const_alpha == 0) - return; - - if (const_alpha == 256) { - qt_transform_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, targetRectTransform, const_alpha); - return; - } - - qt_transform_image(reinterpret_cast(destPixels), dbpl, - reinterpret_cast(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, - Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); -} - -void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - int const_alpha) -{ - if (const_alpha == 0) - return; - - qt_transform_image(reinterpret_cast(destPixels), dbpl, - reinterpret_cast(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, - Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); -} - -static inline void convert_8_pixels_rgb16_to_argb32(quint32 *dst, const quint16 *src) -{ - asm volatile ( - "vld1.16 { d0, d1 }, [%[SRC]]\n\t" - - /* convert 8 r5g6b5 pixel data from {d0, d1} to planar 8-bit format - and put data into d4 - red, d3 - green, d2 - blue */ - "vshrn.u16 d4, q0, #8\n\t" - "vshrn.u16 d3, q0, #3\n\t" - "vsli.u16 q0, q0, #5\n\t" - "vsri.u8 d4, d4, #5\n\t" - "vsri.u8 d3, d3, #6\n\t" - "vshrn.u16 d2, q0, #2\n\t" - - /* fill d5 - alpha with 0xff */ - "mov r2, #255\n\t" - "vdup.8 d5, r2\n\t" - - "vst4.8 { d2, d3, d4, d5 }, [%[DST]]" - : : [DST]"r" (dst), [SRC]"r" (src) - : "memory", "r2", "d0", "d1", "d2", "d3", "d4", "d5" - ); -} - -uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) -{ - const ushort *data = (const ushort *)rasterBuffer->scanLine(y) + x; - - int i = 0; - for (; i < length - 7; i += 8) - convert_8_pixels_rgb16_to_argb32(&buffer[i], &data[i]); - - if (i < length) { - quint16 srcBuffer[8]; - quint32 dstBuffer[8]; - - int tail = length - i; - for (int j = 0; j < tail; ++j) - srcBuffer[j] = data[i + j]; - - convert_8_pixels_rgb16_to_argb32(dstBuffer, srcBuffer); - - for (int j = 0; j < tail; ++j) - buffer[i + j] = dstBuffer[j]; - } - - return buffer; -} - -static inline void convert_8_pixels_argb32_to_rgb16(quint16 *dst, const quint32 *src) -{ - asm volatile ( - "vld4.8 { d0, d1, d2, d3 }, [%[SRC]]\n\t" - - /* convert to r5g6b5 and store it into {d28, d29} */ - "vshll.u8 q14, d2, #8\n\t" - "vshll.u8 q8, d1, #8\n\t" - "vshll.u8 q9, d0, #8\n\t" - "vsri.u16 q14, q8, #5\n\t" - "vsri.u16 q14, q9, #11\n\t" - - "vst1.16 { d28, d29 }, [%[DST]]" - : : [DST]"r" (dst), [SRC]"r" (src) - : "memory", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d28", "d29" - ); -} - -void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) -{ - quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x; - - int i = 0; - for (; i < length - 7; i += 8) - convert_8_pixels_argb32_to_rgb16(&data[i], &buffer[i]); - - if (i < length) { - quint32 srcBuffer[8]; - quint16 dstBuffer[8]; - - int tail = length - i; - for (int j = 0; j < tail; ++j) - srcBuffer[j] = buffer[i + j]; - - convert_8_pixels_argb32_to_rgb16(dstBuffer, srcBuffer); - - for (int j = 0; j < tail; ++j) - data[i + j] = dstBuffer[j]; - } -} - -void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha) -{ - if ((const_alpha & qAlpha(color)) == 255) { - QT_MEMFILL_UINT(destPixels, length, color); - } else { - if (const_alpha != 255) - color = BYTE_MUL(color, const_alpha); - - const quint32 minusAlphaOfColor = qAlpha(~color); - int x = 0; - - uint32_t *dst = (uint32_t *) destPixels; - const uint32x4_t colorVector = vdupq_n_u32(color); - uint16x8_t half = vdupq_n_u16(0x80); - const uint16x8_t minusAlphaOfColorVector = vdupq_n_u16(minusAlphaOfColor); - - for (; x < length-3; x += 4) { - uint32x4_t dstVector = vld1q_u32(&dst[x]); - - const uint8x16_t dst8 = vreinterpretq_u8_u32(dstVector); - - const uint8x8_t dst8_low = vget_low_u8(dst8); - const uint8x8_t dst8_high = vget_high_u8(dst8); - - const uint16x8_t dst16_low = vmovl_u8(dst8_low); - const uint16x8_t dst16_high = vmovl_u8(dst8_high); - - const uint16x8_t result16_low = qvbyte_mul_u16(dst16_low, minusAlphaOfColorVector, half); - const uint16x8_t result16_high = qvbyte_mul_u16(dst16_high, minusAlphaOfColorVector, half); - - const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); - const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - - uint32x4_t blendedPixels = vcombine_u32(result32_low, result32_high); - uint32x4_t colorPlusBlendedPixels = vaddq_u32(colorVector, blendedPixels); - vst1q_u32(&dst[x], colorPlusBlendedPixels); - } - - for (;x < length; ++x) - destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); - } -} - -void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha) -{ - if (const_alpha == 255) { - uint *const end = dst + length; - uint *const neonEnd = end - 3; - - while (dst < neonEnd) { - asm volatile ( - "vld2.8 { d0, d1 }, [%[SRC]] !\n\t" - "vld2.8 { d2, d3 }, [%[DST]]\n\t" - "vqadd.u8 q0, q0, q1\n\t" - "vst2.8 { d0, d1 }, [%[DST]] !\n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : - : "memory", "d0", "d1", "d2", "d3", "q0", "q1" - ); - } - - while (dst != end) { - *dst = comp_func_Plus_one_pixel(*dst, *src); - ++dst; - ++src; - } - } else { - int x = 0; - const int one_minus_const_alpha = 255 - const_alpha; - const uint16x8_t constAlphaVector = vdupq_n_u16(const_alpha); - const uint16x8_t oneMinusconstAlphaVector = vdupq_n_u16(one_minus_const_alpha); - - const uint16x8_t half = vdupq_n_u16(0x80); - for (; x < length - 3; x += 4) { - const uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); - const uint8x16_t src8 = vreinterpretq_u8_u32(src32); - uint8x16_t dst8 = vld1q_u8((uint8_t *)&dst[x]); - uint8x16_t result = vqaddq_u8(dst8, src8); - - uint16x8_t result_low = vmovl_u8(vget_low_u8(result)); - uint16x8_t result_high = vmovl_u8(vget_high_u8(result)); - - uint16x8_t dst_low = vmovl_u8(vget_low_u8(dst8)); - uint16x8_t dst_high = vmovl_u8(vget_high_u8(dst8)); - - result_low = qvinterpolate_pixel_255(result_low, constAlphaVector, dst_low, oneMinusconstAlphaVector, half); - result_high = qvinterpolate_pixel_255(result_high, constAlphaVector, dst_high, oneMinusconstAlphaVector, half); - - const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result_low)); - const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result_high)); - vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); - } - - for (; x < length; ++x) - dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); - } -} - -static const int tileSize = 32; - -extern "C" void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count); - -void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sstride, uchar *destPixels, int dstride) -{ - const ushort *src = (const ushort *)srcPixels; - ushort *dest = (ushort *)destPixels; - - sstride /= sizeof(ushort); - dstride /= sizeof(ushort); - - const int pack = sizeof(quint32) / sizeof(ushort); - const int unaligned = - qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(ushort)), uint(h)); - const int restX = w % tileSize; - const int restY = (h - unaligned) % tileSize; - const int unoptimizedY = restY % pack; - const int numTilesX = w / tileSize + (restX > 0); - const int numTilesY = (h - unaligned) / tileSize + (restY >= pack); - - for (int tx = 0; tx < numTilesX; ++tx) { - const int startx = w - tx * tileSize - 1; - const int stopx = qMax(startx - tileSize, 0); - - if (unaligned) { - for (int x = startx; x >= stopx; --x) { - ushort *d = dest + (w - x - 1) * dstride; - for (int y = 0; y < unaligned; ++y) { - *d++ = src[y * sstride + x]; - } - } - } - - for (int ty = 0; ty < numTilesY; ++ty) { - const int starty = ty * tileSize + unaligned; - const int stopy = qMin(starty + tileSize, h - unoptimizedY); - - int x = startx; - // qt_rotate90_16_neon writes to eight rows, four pixels at a time - for (; x >= stopx + 7; x -= 8) { - ushort *d = dest + (w - x - 1) * dstride + starty; - const ushort *s = &src[starty * sstride + x - 7]; - qt_rotate90_16_neon(d, s, sstride * 2, dstride * 2, stopy - starty); - } - - for (; x >= stopx; --x) { - quint32 *d = reinterpret_cast(dest + (w - x - 1) * dstride + starty); - for (int y = starty; y < stopy; y += pack) { - quint32 c = src[y * sstride + x]; - for (int i = 1; i < pack; ++i) { - const int shift = (sizeof(int) * 8 / pack * i); - const ushort color = src[(y + i) * sstride + x]; - c |= color << shift; - } - *d++ = c; - } - } - } - - if (unoptimizedY) { - const int starty = h - unoptimizedY; - for (int x = startx; x >= stopx; --x) { - ushort *d = dest + (w - x - 1) * dstride + starty; - for (int y = starty; y < h; ++y) { - *d++ = src[y * sstride + x]; - } - } - } - } -} - -extern "C" void qt_rotate270_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count); - -void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, - int sstride, - uchar *destPixels, int dstride) -{ - const ushort *src = (const ushort *)srcPixels; - ushort *dest = (ushort *)destPixels; - - sstride /= sizeof(ushort); - dstride /= sizeof(ushort); - - const int pack = sizeof(quint32) / sizeof(ushort); - const int unaligned = - qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(ushort)), uint(h)); - const int restX = w % tileSize; - const int restY = (h - unaligned) % tileSize; - const int unoptimizedY = restY % pack; - const int numTilesX = w / tileSize + (restX > 0); - const int numTilesY = (h - unaligned) / tileSize + (restY >= pack); - - for (int tx = 0; tx < numTilesX; ++tx) { - const int startx = tx * tileSize; - const int stopx = qMin(startx + tileSize, w); - - if (unaligned) { - for (int x = startx; x < stopx; ++x) { - ushort *d = dest + x * dstride; - for (int y = h - 1; y >= h - unaligned; --y) { - *d++ = src[y * sstride + x]; - } - } - } - - for (int ty = 0; ty < numTilesY; ++ty) { - const int starty = h - 1 - unaligned - ty * tileSize; - const int stopy = qMax(starty - tileSize, unoptimizedY); - - int x = startx; - // qt_rotate90_16_neon writes to eight rows, four pixels at a time - for (; x < stopx - 7; x += 8) { - ushort *d = dest + x * dstride + h - 1 - starty; - const ushort *s = &src[starty * sstride + x]; - qt_rotate90_16_neon(d + 7 * dstride, s, -sstride * 2, -dstride * 2, starty - stopy); - } - - for (; x < stopx; ++x) { - quint32 *d = reinterpret_cast(dest + x * dstride - + h - 1 - starty); - for (int y = starty; y > stopy; y -= pack) { - quint32 c = src[y * sstride + x]; - for (int i = 1; i < pack; ++i) { - const int shift = (sizeof(int) * 8 / pack * i); - const ushort color = src[(y - i) * sstride + x]; - c |= color << shift; - } - *d++ = c; - } - } - } - if (unoptimizedY) { - const int starty = unoptimizedY - 1; - for (int x = startx; x < stopx; ++x) { - ushort *d = dest + x * dstride + h - 1 - starty; - for (int y = starty; y >= 0; --y) { - *d++ = src[y * sstride + x]; - } - } - } - } -} - -class QSimdNeon -{ -public: - typedef int32x4_t Int32x4; - typedef float32x4_t Float32x4; - - union Vect_buffer_i { Int32x4 v; int i[4]; }; - union Vect_buffer_f { Float32x4 v; float f[4]; }; - - static inline Float32x4 v_dup(float x) { return vdupq_n_f32(x); } - static inline Int32x4 v_dup(int x) { return vdupq_n_s32(x); } - static inline Int32x4 v_dup(uint x) { return vdupq_n_s32(x); } - - static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return vaddq_f32(a, b); } - static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return vaddq_s32(a, b); } - - static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return vmaxq_f32(a, b); } - static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return vminq_f32(a, b); } - static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return vminq_s32(a, b); } - - static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return vandq_s32(a, b); } - - static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return vsubq_f32(a, b); } - static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return vsubq_s32(a, b); } - - static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return vmulq_f32(a, b); } - - static inline Float32x4 v_sqrt(Float32x4 x) { Float32x4 y = vrsqrteq_f32(x); y = vmulq_f32(y, vrsqrtsq_f32(x, vmulq_f32(y, y))); return vmulq_f32(x, y); } - - static inline Int32x4 v_toInt(Float32x4 x) { return vcvtq_s32_f32(x); } - - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return vreinterpretq_s32_u32(vcgeq_f32(a, b)); } -}; - -const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) -{ - return qt_fetch_radial_gradient_template >(buffer, op, data, y, x, length); -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_NEON - - - - - diff --git a/src/gui/painting/qdrawhelper_neon_asm.S b/src/gui/painting/qdrawhelper_neon_asm.S deleted file mode 100644 index 561acc155..000000000 --- a/src/gui/painting/qdrawhelper_neon_asm.S +++ /dev/null @@ -1,297 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -/* Prevent the stack from becoming executable for no reason... */ -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - -.text -.fpu neon -.arch armv7a -.altmacro - -/* void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha) */ - - .func blend_8_pixels_argb32_on_rgb16_neon - .global blend_8_pixels_argb32_on_rgb16_neon - /* For ELF format also set function visibility to hidden */ -#ifdef __ELF__ - .hidden blend_8_pixels_argb32_on_rgb16_neon - .type blend_8_pixels_argb32_on_rgb16_neon, %function -#endif -blend_8_pixels_argb32_on_rgb16_neon: - vld4.8 { d0, d1, d2, d3 }, [r1] - vld1.16 { d4, d5 }, [r0] - - cmp r2, #256 - beq .blend_32_inner - - vdup.8 d6, r2 - - /* multiply by const_alpha */ - vmull.u8 q8, d6, d0 - vmull.u8 q9, d6, d1 - vmull.u8 q10, d6, d2 - vmull.u8 q11, d6, d3 - - vshrn.u16 d0, q8, #8 - vshrn.u16 d1, q9, #8 - vshrn.u16 d2, q10, #8 - vshrn.u16 d3, q11, #8 - -.blend_32_inner: - /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format - and put data into d6 - red, d7 - green, d30 - blue */ - vshrn.u16 d6, q2, #8 - vshrn.u16 d7, q2, #3 - vsli.u16 q2, q2, #5 - vsri.u8 d6, d6, #5 - vmvn.8 d3, d3 - vsri.u8 d7, d7, #6 - vshrn.u16 d30, q2, #2 - - pld [r0, #128] - - /* now do alpha blending, storing results in 8-bit planar format - into d16 - red, d19 - green, d18 - blue */ - vmull.u8 q10, d3, d6 - vmull.u8 q11, d3, d7 - vmull.u8 q12, d3, d30 - vrshr.u16 q13, q10, #8 - vrshr.u16 q3, q11, #8 - vrshr.u16 q15, q12, #8 - vraddhn.u16 d20, q10, q13 - vraddhn.u16 d23, q11, q3 - vraddhn.u16 d22, q12, q15 - vqadd.u8 d16, d2, d20 - vqadd.u8 q9, q0, q11 - /* convert the result to r5g6b5 and store it into {d28, d29} */ - vshll.u8 q14, d16, #8 - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 - - vst1.16 { d28, d29 }, [r0] - - bx lr - - .endfunc - -/* void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha) */ - - .func blend_8_pixels_rgb16_on_rgb16_neon - .global blend_8_pixels_rgb16_on_rgb16_neon - /* For ELF format also set function visibility to hidden */ -#ifdef __ELF__ - .hidden blend_8_pixels_rgb16_on_rgb16_neon - .type blend_8_pixels_rgb16_on_rgb16_neon, %function -#endif -blend_8_pixels_rgb16_on_rgb16_neon: - vld1.16 { d0, d1 }, [r0] - vld1.16 { d2, d3 }, [r1] - - rsb r3, r2, #256 - vdup.8 d4, r2 - vdup.8 d5, r3 - - /* convert 8 r5g6b5 pixel data from {d0, d1} to planar 8-bit format - and put data into d6 - red, d7 - green, d30 - blue */ - vshrn.u16 d6, q0, #8 - vshrn.u16 d7, q0, #3 - vsli.u16 q0, q0, #5 - vsri.u8 d6, d6, #5 - vsri.u8 d7, d7, #6 - vshrn.u16 d30, q0, #2 - - /* same from {d2, d3} into {d26, d27, d28} */ - vshrn.u16 d26, q1, #8 - vshrn.u16 d27, q1, #3 - vsli.u16 q1, q1, #5 - vsri.u8 d26, d26, #5 - vsri.u8 d27, d27, #6 - vshrn.u16 d28, q1, #2 - - /* multiply dst by inv const_alpha */ - vmull.u8 q10, d5, d6 - vmull.u8 q11, d5, d7 - vmull.u8 q12, d5, d30 - - vshrn.u16 d6, q10, #8 - vshrn.u16 d7, q11, #8 - vshrn.u16 d30, q12, #8 - - /* multiply src by const_alpha */ - vmull.u8 q10, d4, d26 - vmull.u8 q11, d4, d27 - vmull.u8 q12, d4, d28 - - vshrn.u16 d26, q10, #8 - vshrn.u16 d27, q11, #8 - vshrn.u16 d28, q12, #8 - - /* preload dst + 128 */ - pld [r0, #128] - - /* add components, storing results in 8-bit planar format - into d16 - red, d19 - green, d18 - blue */ - vadd.u8 d16, d26, d6 - vadd.u8 d19, d27, d7 - vadd.u8 d18, d28, d30 - - /* convert the result to r5g6b5 and store it into {d28, d29} */ - vshll.u8 q14, d16, #8 - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 - - vst1.16 { d28, d29 }, [r0] - - bx lr - - .endfunc - -/* void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count) */ - .func qt_rotate90_16_neon - .global qt_rotate90_16_neon - /* For ELF format also set function visibility to hidden */ -#ifdef __ELF__ - .hidden qt_rotate90_16_neon - .type qt_rotate90_16_neon, %function -#endif -qt_rotate90_16_neon: - push { r4-r11, lr } - ldr r5, [sp, #(9*4)] - - /* The preloads are the key to getting good performance */ - pld [r1] - - mov r4, r5, asr #2 - add r6, r0, r3 - add r7, r6, r3 - - add r8, r7, r3 - add r9, r8, r3 - - pld [r1, r2] - - add r10, r9, r3 - add r11, r10, r3 - - add r3, r3, r11 - and r5, r5, #3 - - pld [r1, r2, lsl #1] - - cmp r4, #0 - beq .rotate90_16_tail - -.rotate90_16_loop: - vld1.16 { q8 }, [r1], r2 - - pld [r1, r2, lsl #1] - - vld1.16 { q9 }, [r1], r2 - vld1.16 { q10 }, [r1], r2 - vld1.16 { q11 }, [r1], r2 - - pld [r1] - - /* Could have used four quad-word zips instead, - but those take three cycles as opposed to one. */ - vzip.16 d16, d20 - vzip.16 d17, d21 - - vzip.16 d18, d22 - - pld [r1, r2] - - vzip.16 d19, d23 - - vzip.16 d16, d18 - vzip.16 d17, d19 - - pld [r1, r2, lsl #1] - - vzip.16 d20, d22 - vzip.16 d21, d23 - - vst1.16 { d23 }, [r0]! - vst1.16 { d21 }, [r6]! - vst1.16 { d19 }, [r7]! - vst1.16 { d17 }, [r8]! - vst1.16 { d22 }, [r9]! - vst1.16 { d20 }, [r10]! - vst1.16 { d18 }, [r11]! - vst1.16 { d16 }, [r3]! - - sub r4, r4, #1 - cmp r4, #0 - bne .rotate90_16_loop - b .rotate90_16_tail - -.rotate90_16_tail_loop: - sub r5, r5, #2 - - vld1.16 { q8 }, [r1], r2 - vld1.16 { q9 }, [r1], r2 - - vzip.16 d16, d18 - vzip.16 d17, d19 - - vst1.32 { d19[1] }, [r0]! - vst1.32 { d19[0] }, [r6]! - vst1.32 { d17[1] }, [r7]! - vst1.32 { d17[0] }, [r8]! - vst1.32 { d18[1] }, [r9]! - vst1.32 { d18[0] }, [r10]! - vst1.32 { d16[1] }, [r11]! - vst1.32 { d16[0] }, [r3]! - -.rotate90_16_tail: - cmp r5, #0 - bgt .rotate90_16_tail_loop - - pop { r4-r11, pc } - - .endfunc diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h deleted file mode 100644 index b8db44a72..000000000 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QDRAWHELPER_NEON_P_H -#define QDRAWHELPER_NEON_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -#ifdef QT_HAVE_NEON - -void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, - const uint *src, - int length, - uint const_alpha); - -void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, - int x, int y, quint32 color, - const uchar *bitmap, - int mapWidth, int mapHeight, int mapStride, - const QClipData *clip); - -void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, int sh, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha); - -void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, int sh, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - int const_alpha); - -void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - int const_alpha); - -void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - int const_alpha); - -void qt_memfill32_neon(quint32 *dest, quint32 value, int count); -void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); -void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); - -uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, - QRasterBuffer *rasterBuffer, - int x, int y, int length); - -void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, - int x, int y, const uint *buffer, int length); - -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_HAVE_NEON - -QT_END_NAMESPACE - -#endif // QDRAWHELPER_NEON_P_H diff --git a/src/gui/painting/qdrawhelper_sse.cpp b/src/gui/painting/qdrawhelper_sse.cpp deleted file mode 100644 index 10d4c7bb3..000000000 --- a/src/gui/painting/qdrawhelper_sse.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#ifdef QT_HAVE_SSE - -#include - -QT_BEGIN_NAMESPACE - -CompositionFunctionSolid qt_functionForModeSolid_SSE[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - 0, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // svg 1.2 modes - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_SSE[numCompositionFunctions] = { - comp_func_SourceOver, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_blend_color_argb_sse(int count, const QSpan *spans, void *userData) -{ - qt_blend_color_argb_x86(count, spans, userData, - (CompositionFunctionSolid*)qt_functionForModeSolid_SSE); -} - -void qt_memfill32_sse(quint32 *dest, quint32 value, int count) -{ - return qt_memfill32_sse_template(dest, value, count); -} - -void qt_bitmapblit16_sse(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, - int width, int height, int stride) -{ - return qt_bitmapblit16_sse_template(rasterBuffer, x,y, - color, src, width, - height, stride); -} - -void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const uint *src = (const uint *) srcPixels; - uint *dst = (uint *) destPixels; - - uint ca = const_alpha - 1; - - for (int y=0; y(dst, src, w, ca); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } -} - -void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const uint *src = (const uint *) srcPixels; - uint *dst = (uint *) destPixels; - - uint ca = const_alpha - 1; - - for (int y=0; y(dst, src, w, ca); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSE - - - - diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp deleted file mode 100644 index ef7eb4149..000000000 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ /dev/null @@ -1,547 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#ifdef QT_HAVE_SSE2 - -#include -#include - -QT_BEGIN_NAMESPACE - -void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const quint32 *src = (const quint32 *) srcPixels; - quint32 *dst = (quint32 *) destPixels; - if (const_alpha == 256) { - const __m128i alphaMask = _mm_set1_epi32(0xff000000); - const __m128i nullVector = _mm_set1_epi32(0); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i one = _mm_set1_epi16(0xff); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - for (int y = 0; y < h; ++y) { - BLEND_SOURCE_OVER_ARGB32_SSE2(dst, src, w, nullVector, half, one, colorMask, alphaMask); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } - } else if (const_alpha != 0) { - // dest = (s + d * sia) * ca + d * cia - // = s * ca + d * (sia * ca + cia) - // = s * ca + d * (1 - sa*ca) - const_alpha = (const_alpha * 255) >> 8; - const __m128i nullVector = _mm_set1_epi32(0); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i one = _mm_set1_epi16(0xff); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); - for (int y = 0; y < h; ++y) { - BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, w, nullVector, half, one, colorMask, constAlphaVector) - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } - } -} - -// qblendfunctions.cpp -void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const quint32 *src = (const quint32 *) srcPixels; - quint32 *dst = (quint32 *) destPixels; - if (const_alpha != 256) { - if (const_alpha != 0) { - const __m128i nullVector = _mm_set1_epi32(0); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - - const_alpha = (const_alpha * 255) >> 8; - int one_minus_const_alpha = 255 - const_alpha; - const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); - const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); - for (int y = 0; y < h; ++y) { - int x = 0; - - // First, align dest to 16 bytes: - ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { - dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); - } - - for (; x < w-3; x += 4) { - __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); - __m128i result; - INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half); - _mm_store_si128((__m128i *)&dst[x], result); - } - } - for (; x(dest); - const __m128i value128 = _mm_set_epi32(value, value, value, value); - - int n = (count128 + 3) / 4; - switch (count128 & 0x3) { - case 0: do { _mm_stream_si128(dst128++, value128); - case 3: _mm_stream_si128(dst128++, value128); - case 2: _mm_stream_si128(dst128++, value128); - case 1: _mm_stream_si128(dst128++, value128); - } while (--n > 0); - } - - const int rest = count & 0x3; - if (rest) { - switch (rest) { - case 3: dest[count - 3] = value; - case 2: dest[count - 2] = value; - case 1: dest[count - 1] = value; - } - } -} - -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); - } else { - if (const_alpha != 255) - color = BYTE_MUL(color, const_alpha); - - const quint32 minusAlphaOfColor = qAlpha(~color); - int x = 0; - - quint32 *dst = (quint32 *) destPixels; - const __m128i colorVector = _mm_set1_epi32(color); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i minusAlphaOfColorVector = _mm_set1_epi16(minusAlphaOfColor); - - ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) - destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); - - for (; x < length-3; x += 4) { - __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); - BYTE_MUL_SSE2(dstVector, dstVector, minusAlphaOfColorVector, colorMask, half); - dstVector = _mm_add_epi8(colorVector, dstVector); - _mm_store_si128((__m128i *)&dst[x], dstVector); - } - for (;x < length; ++x) - destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); - } -} - -CompositionFunctionSolid qt_functionForModeSolid_onlySSE2[numCompositionFunctions] = { - comp_func_solid_SourceOver_sse2, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - comp_func_solid_Destination, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - comp_func_solid_Plus, - comp_func_solid_Multiply, - comp_func_solid_Screen, - comp_func_solid_Overlay, - comp_func_solid_Darken, - comp_func_solid_Lighten, - comp_func_solid_ColorDodge, - comp_func_solid_ColorBurn, - comp_func_solid_HardLight, - comp_func_solid_SoftLight, - comp_func_solid_Difference, - comp_func_solid_Exclusion, - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_onlySSE2[numCompositionFunctions] = { - comp_func_SourceOver_sse2, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source_sse2, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus_sse2, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_memfill16_sse2(quint16 *dest, quint16 value, int count) -{ - if (count < 3) { - switch (count) { - case 2: *dest++ = value; - case 1: *dest = value; - } - return; - } - - const int align = (quintptr)(dest) & 0x3; - switch (align) { - case 2: *dest++ = value; --count; - } - - const quint32 value32 = (value << 16) | value; - qt_memfill32_sse2(reinterpret_cast(dest), value32, count / 2); - - if (count & 0x1) - dest[count - 1] = value; -} - -void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride) -{ - quint32 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; - const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32); - - const __m128i c128 = _mm_set1_epi32(color); - const __m128i maskmask1 = _mm_set_epi32(0x10101010, 0x20202020, - 0x40404040, 0x80808080); - const __m128i maskadd1 = _mm_set_epi32(0x70707070, 0x60606060, - 0x40404040, 0x00000000); - - if (width > 4) { - const __m128i maskmask2 = _mm_set_epi32(0x01010101, 0x02020202, - 0x04040404, 0x08080808); - const __m128i maskadd2 = _mm_set_epi32(0x7f7f7f7f, 0x7e7e7e7e, - 0x7c7c7c7c, 0x78787878); - while (height--) { - for (int x = 0; x < width; x += 8) { - const quint8 s = src[x >> 3]; - if (!s) - continue; - __m128i mask1 = _mm_set1_epi8(s); - __m128i mask2 = mask1; - - mask1 = _mm_and_si128(mask1, maskmask1); - mask1 = _mm_add_epi8(mask1, maskadd1); - _mm_maskmoveu_si128(c128, mask1, (char*)(dest + x)); - mask2 = _mm_and_si128(mask2, maskmask2); - mask2 = _mm_add_epi8(mask2, maskadd2); - _mm_maskmoveu_si128(c128, mask2, (char*)(dest + x + 4)); - } - dest += destStride; - src += stride; - } - } else { - while (height--) { - const quint8 s = *src; - if (s) { - __m128i mask1 = _mm_set1_epi8(s); - mask1 = _mm_and_si128(mask1, maskmask1); - mask1 = _mm_add_epi8(mask1, maskadd1); - _mm_maskmoveu_si128(c128, mask1, (char*)(dest)); - } - dest += destStride; - src += stride; - } - } -} - -void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride) -{ - const quint16 c = qt_colorConvert(color, 0); - quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; - const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); - - const __m128i c128 = _mm_set1_epi16(c); -#if defined(Q_CC_MSVC) -# pragma warning(disable: 4309) // truncation of constant value -#endif - const __m128i maskmask = _mm_set_epi16(0x0101, 0x0202, 0x0404, 0x0808, - 0x1010, 0x2020, 0x4040, 0x8080); - const __m128i maskadd = _mm_set_epi16(0x7f7f, 0x7e7e, 0x7c7c, 0x7878, - 0x7070, 0x6060, 0x4040, 0x0000); - - while (height--) { - for (int x = 0; x < width; x += 8) { - const quint8 s = src[x >> 3]; - if (!s) - continue; - __m128i mask = _mm_set1_epi8(s); - mask = _mm_and_si128(mask, maskmask); - mask = _mm_add_epi8(mask, maskadd); - _mm_maskmoveu_si128(c128, mask, (char*)(dest + x)); - } - dest += destStride; - src += stride; - } -} - -class QSimdSse2 -{ -public: - typedef __m128i Int32x4; - typedef __m128 Float32x4; - - union Vect_buffer_i { Int32x4 v; int i[4]; }; - union Vect_buffer_f { Float32x4 v; float f[4]; }; - - static inline Float32x4 v_dup(float x) { return _mm_set1_ps(x); } - static inline Float32x4 v_dup(double x) { return _mm_set1_ps(x); } - static inline Int32x4 v_dup(int x) { return _mm_set1_epi32(x); } - static inline Int32x4 v_dup(uint x) { return _mm_set1_epi32(x); } - - static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); } - static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); } - - static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); } - static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); } - static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); } - - static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); } - - static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); } - static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); } - - static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); } - - static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } - - static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } - - // pre-VS 2008 doesn't have cast intrinsics, whereas 2008 and later requires it - // (same deal with gcc prior to 4.0) -#if (defined(Q_CC_MSVC) && _MSC_VER < 1500) || (defined(Q_CC_GNU) && __GNUC__ < 4) - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) - { - union Convert { Int32x4 vi; Float32x4 vf; } convert; - convert.vf = _mm_cmpgt_ps(a, b); - return convert.vi; - } -#else - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } -#endif -}; - -const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) -{ - return qt_fetch_radial_gradient_template >(buffer, op, data, y, x, length); -} - - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSE2 - - diff --git a/src/gui/painting/qdrawhelper_sse3dnow.cpp b/src/gui/painting/qdrawhelper_sse3dnow.cpp deleted file mode 100644 index e99e258f2..000000000 --- a/src/gui/painting/qdrawhelper_sse3dnow.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#if defined(QT_HAVE_3DNOW) && defined(QT_HAVE_SSE) - -#include -#include - -QT_BEGIN_NAMESPACE - -struct QSSE3DNOWIntrinsics : public QSSEIntrinsics -{ - static inline void end() { - _m_femms(); - } -}; - -CompositionFunctionSolid qt_functionForModeSolid_SSE3DNOW[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - 0, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // svg 1.2 modes - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -CompositionFunction qt_functionForMode_SSE3DNOW[numCompositionFunctions] = { - comp_func_SourceOver, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -void qt_blend_color_argb_sse3dnow(int count, const QSpan *spans, void *userData) -{ - qt_blend_color_argb_x86(count, spans, userData, - (CompositionFunctionSolid*)qt_functionForModeSolid_SSE3DNOW); -} - -void qt_memfill32_sse3dnow(quint32 *dest, quint32 value, int count) -{ - return qt_memfill32_sse_template(dest, value, count); -} - - -void qt_bitmapblit16_sse3dnow(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, - int width, int height, int stride) -{ - return qt_bitmapblit16_sse_template(rasterBuffer, x,y, - color, src, width, - height, stride); -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_3DNOW && QT_HAVE_SSE - - diff --git a/src/gui/painting/qdrawhelper_sse_p.h b/src/gui/painting/qdrawhelper_sse_p.h deleted file mode 100644 index 544b04e0d..000000000 --- a/src/gui/painting/qdrawhelper_sse_p.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QDRAWHELPER_SSE_P_H -#define QDRAWHELPER_SSE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#ifdef QT_HAVE_SSE - -#ifdef QT_LINUXBASE -// this is an evil hack - the posix_memalign declaration in LSB -// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431 -# define posix_memalign _lsb_hack_posix_memalign -# include -# undef posix_memalign -#else -# include -#endif - -QT_BEGIN_NAMESPACE - -#ifndef _MM_SHUFFLE -#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \ - (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0)) -#endif - -struct QSSEIntrinsics : public QMMXIntrinsics -{ - static inline m64 alpha(m64 x) { - return _mm_shuffle_pi16 (x, _MM_SHUFFLE(3, 3, 3, 3)); - } - - static inline m64 _load_alpha(uint x, const m64 &mmx_0x0000) { - m64 t = _mm_unpacklo_pi8(_mm_cvtsi32_si64(x), mmx_0x0000); - return _mm_shuffle_pi16 (t, _MM_SHUFFLE(0, 0, 0, 0)); - } -}; - -template -inline void qt_memfill32_sse_template(quint32 *dest, quint32 value, int count) -{ - if (count < 7) { - switch (count) { - case 6: *dest++ = value; - case 5: *dest++ = value; - case 4: *dest++ = value; - case 3: *dest++ = value; - case 2: *dest++ = value; - case 1: *dest = value; - } - return; - }; - - __m64 *dst64 = reinterpret_cast<__m64*>(dest); - const __m64 value64 = _mm_set_pi32(value, value); - int count64 = count / 2; - - int n = (count64 + 3) / 4; - switch (count64 & 0x3) { - case 0: do { _mm_stream_pi(dst64++, value64); - case 3: _mm_stream_pi(dst64++, value64); - case 2: _mm_stream_pi(dst64++, value64); - case 1: _mm_stream_pi(dst64++, value64); - } while (--n > 0); - } - - if (count & 0x1) - dest[count - 1] = value; - - MM::end(); -} - -template -inline void qt_bitmapblit16_sse_template(QRasterBuffer *rasterBuffer, - int x, int y, - quint32 color, - const uchar *src, - int width, int height, int stride) -{ - const quint16 c = qt_colorConvert(color, 0); - quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; - const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); - - const __m64 c64 = _mm_set1_pi16(c); -#ifdef Q_CC_MSVC -# pragma warning(disable: 4309) // truncation of constant value -#endif - const __m64 maskmask1 = _mm_set_pi16(0x1010, 0x2020, 0x4040, 0x8080); - const __m64 maskadd1 = _mm_set_pi16(0x7070, 0x6060, 0x4040, 0x0000); - - if (width > 4) { - const __m64 maskmask2 = _mm_set_pi16(0x0101, 0x0202, 0x0404, 0x0808); - const __m64 maskadd2 = _mm_set_pi16(0x7f7f, 0x7e7e, 0x7c7c, 0x7878); - - while (height--) { - for (int x = 0; x < width; x += 8) { - const quint8 s = src[x >> 3]; - if (!s) - continue; - __m64 mask1 = _mm_set1_pi8(s); - __m64 mask2 = mask1; - mask1 = _m_pand(mask1, maskmask1); - mask1 = _mm_add_pi16(mask1, maskadd1); - _mm_maskmove_si64(c64, mask1, (char*)(dest + x)); - mask2 = _m_pand(mask2, maskmask2); - mask2 = _mm_add_pi16(mask2, maskadd2); - _mm_maskmove_si64(c64, mask2, (char*)(dest + x + 4)); - } - dest += destStride; - src += stride; - } - } else { - while (height--) { - const quint8 s = *src; - if (s) { - __m64 mask1 = _mm_set1_pi8(s); - mask1 = _m_pand(mask1, maskmask1); - mask1 = _mm_add_pi16(mask1, maskadd1); - _mm_maskmove_si64(c64, mask1, (char*)(dest)); - } - dest += destStride; - src += stride; - } - } - - MM::end(); -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSE -#endif // QDRAWHELPER_SSE_P_H diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp deleted file mode 100644 index b21f5c24c..000000000 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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 - -#ifdef QT_HAVE_SSSE3 - -#include - -QT_BEGIN_NAMESPACE - -inline static void blend_pixel(quint32 &dst, const quint32 src) -{ - if (src >= 0xff000000) - dst = src; - else if (src != 0) - dst = src + BYTE_MUL(dst, qAlpha(~src)); -} - - -/* The instruction palignr uses direct arguments, so we have to generate the code fo the different - shift (4, 8, 12). Checking the alignment inside the loop is unfortunatelly way too slow. - */ -#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 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) { \ - _mm_store_si128((__m128i *)&dst[x], srcVector); \ - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ - __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - srcVectorPrevLoaded = srcVectorLastLoaded;\ - } - - -// Basically blend src over dst with the const alpha defined as constAlphaVector. -// nullVector, half, one, colorMask are constant across the whole image/texture, and should be defined as: -//const __m128i nullVector = _mm_set1_epi32(0); -//const __m128i half = _mm_set1_epi16(0x80); -//const __m128i one = _mm_set1_epi16(0xff); -//const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); -//const __m128i alphaMask = _mm_set1_epi32(0xff000000); -// -// The computation being done is: -// result = s + d * (1-alpha) -// with shortcuts if fully opaque or fully transparent. -#define BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ - int x = 0; \ -\ - /* First, get dst aligned. */ \ - ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ - blend_pixel(dst[x], src[x]); \ - } \ -\ - const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast(&(src[x])) >> 2) & 0x3;\ -\ - if (!minusOffsetToAlignSrcOn16Bytes) {\ - /* src is aligned, usual algorithm but with aligned operations.\ - 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 srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ - _mm_store_si128((__m128i *)&dst[x], srcVector); \ - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ - __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - } /* 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]);\ - 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);\ - switch (palignrOffset) {\ - case 4:\ - BLENDING_LOOP(4, length)\ - break;\ - case 8:\ - BLENDING_LOOP(8, length)\ - break;\ - case 12:\ - BLENDING_LOOP(12, length)\ - break;\ - }\ - }\ - for (; x < length; ++x) \ - blend_pixel(dst[x], src[x]); \ -} - -void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) -{ - const quint32 *src = (const quint32 *) srcPixels; - quint32 *dst = (quint32 *) destPixels; - if (const_alpha == 256) { - const __m128i alphaMask = _mm_set1_epi32(0xff000000); - const __m128i nullVector = _mm_setzero_si128(); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i one = _mm_set1_epi16(0xff); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - - for (int y = 0; y < h; ++y) { - BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask); - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } - } else if (const_alpha != 0) { - // dest = (s + d * sia) * ca + d * cia - // = s * ca + d * (sia * ca + cia) - // = s * ca + d * (1 - sa*ca) - const_alpha = (const_alpha * 255) >> 8; - const __m128i nullVector = _mm_setzero_si128(); - const __m128i half = _mm_set1_epi16(0x80); - const __m128i one = _mm_set1_epi16(0xff); - const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); - for (int y = 0; y < h; ++y) { - BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, w, nullVector, half, one, colorMask, constAlphaVector) - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } - } -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSSE3 - - diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h deleted file mode 100644 index 3302a7eb1..000000000 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QDRAWHELPER_X86_P_H -#define QDRAWHELPER_X86_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -#ifdef QT_HAVE_MMX -extern CompositionFunction qt_functionForMode_MMX[]; -extern CompositionFunctionSolid qt_functionForModeSolid_MMX[]; -void qt_blend_color_argb_mmx(int count, const QSpan *spans, void *userData); -#endif - -#ifdef QT_HAVE_SSE -void qt_memfill32_mmxext(quint32 *dest, quint32 value, int count); -void qt_bitmapblit16_mmxext(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, const uchar *src, - int width, int height, int stride); -#endif - -#ifdef QT_HAVE_3DNOW -#if defined(QT_HAVE_MMX) || !defined(QT_HAVE_SSE) -extern CompositionFunction qt_functionForMode_MMX3DNOW[]; -extern CompositionFunctionSolid qt_functionForModeSolid_MMX3DNOW[]; - -void qt_blend_color_argb_mmx3dnow(int count, const QSpan *spans, - void *userData); -#endif // MMX - -#ifdef QT_HAVE_SSE -extern CompositionFunction qt_functionForMode_SSE3DNOW[]; -extern CompositionFunctionSolid qt_functionForModeSolid_SSE3DNOW[]; - -void qt_memfill32_sse3dnow(quint32 *dest, quint32 value, int count); -void qt_bitmapblit16_sse3dnow(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, - int stride); -void qt_blend_color_argb_sse3dnow(int count, const QSpan *spans, - void *userData); -#endif // SSE -#endif // QT_HAVE_3DNOW - -#ifdef QT_HAVE_SSE -void qt_memfill32_sse(quint32 *dest, quint32 value, int count); -void qt_bitmapblit16_sse(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride); - -void qt_blend_color_argb_sse(int count, const QSpan *spans, void *userData); - -extern CompositionFunction qt_functionForMode_SSE[]; -extern CompositionFunctionSolid qt_functionForModeSolid_SSE[]; -#endif // QT_HAVE_SSE - -#ifdef QT_HAVE_SSE2 -void qt_memfill32_sse2(quint32 *dest, quint32 value, int count); -void qt_memfill16_sse2(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); -void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, - quint32 color, - const uchar *src, int width, int height, int stride); -void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); -void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha); - -extern CompositionFunction qt_functionForMode_onlySSE2[]; -extern CompositionFunctionSolid qt_functionForModeSolid_onlySSE2[]; -#endif // QT_HAVE_SSE2 - -#ifdef QT_HAVE_IWMMXT -void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData); - -extern CompositionFunction qt_functionForMode_IWMMXT[]; -extern CompositionFunctionSolid qt_functionForModeSolid_IWMMXT[]; -#endif - -static const int numCompositionFunctions = 33; - -QT_END_NAMESPACE - -#endif // QDRAWHELPER_X86_P_H diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h deleted file mode 100644 index 05397b611..000000000 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QDRAWINGPRIMITIVE_SSE2_P_H -#define QDRAWINGPRIMITIVE_SSE2_P_H - -#include - -#ifdef QT_HAVE_SSE2 - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -/* - * Multiply the components of pixelVector by alphaChannel - * Each 32bits components of alphaChannel must be in the form 0x00AA00AA - * colorMask must have 0x00ff00ff on each 32 bits component - * half must have the value 128 (0x80) for each 32 bits compnent - */ -#define BYTE_MUL_SSE2(result, pixelVector, alphaChannel, colorMask, half) \ -{ \ - /* 1. separate the colors in 2 vectors so each color is on 16 bits \ - (in order to be multiplied by the alpha \ - each 32 bit of dstVectorAG are in the form 0x00AA00GG \ - each 32 bit of dstVectorRB are in the form 0x00RR00BB */\ - __m128i pixelVectorAG = _mm_srli_epi16(pixelVector, 8); \ - __m128i pixelVectorRB = _mm_and_si128(pixelVector, colorMask); \ - \ - /* 2. multiply the vectors by the alpha channel */\ - pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); \ - pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); \ - \ - /* 3. divide by 255, that's the tricky part. \ - we do it like for BYTE_MUL(), with bit shift: X/255 ~= (X + X/256 + rounding)/256 */ \ - /** so first (X + X/256 + rounding) */\ - pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); \ - pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); \ - pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); \ - pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); \ - \ - /** second divide by 256 */\ - pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); \ - /** for AG, we could >> 8 to divide followed by << 8 to put the \ - bytes in the correct position. By masking instead, we execute \ - only one instruction */\ - pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); \ - \ - /* 4. combine the 2 pairs of colors */ \ - result = _mm_or_si128(pixelVectorAG, pixelVectorRB); \ -} - -/* - * Each 32bits components of alphaChannel must be in the form 0x00AA00AA - * oneMinusAlphaChannel must be 255 - alpha for each 32 bits component - * colorMask must have 0x00ff00ff on each 32 bits component - * half must have the value 128 (0x80) for each 32 bits compnent - */ -#define INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, alphaChannel, oneMinusAlphaChannel, colorMask, half) { \ - /* interpolate AG */\ - __m128i srcVectorAG = _mm_srli_epi16(srcVector, 8); \ - __m128i dstVectorAG = _mm_srli_epi16(dstVector, 8); \ - __m128i srcVectorAGalpha = _mm_mullo_epi16(srcVectorAG, alphaChannel); \ - __m128i dstVectorAGoneMinusAlphalpha = _mm_mullo_epi16(dstVectorAG, oneMinusAlphaChannel); \ - __m128i finalAG = _mm_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlphalpha); \ - finalAG = _mm_add_epi16(finalAG, _mm_srli_epi16(finalAG, 8)); \ - finalAG = _mm_add_epi16(finalAG, half); \ - finalAG = _mm_andnot_si128(colorMask, finalAG); \ - \ - /* interpolate RB */\ - __m128i srcVectorRB = _mm_and_si128(srcVector, colorMask); \ - __m128i dstVectorRB = _mm_and_si128(dstVector, colorMask); \ - __m128i srcVectorRBalpha = _mm_mullo_epi16(srcVectorRB, alphaChannel); \ - __m128i dstVectorRBoneMinusAlphalpha = _mm_mullo_epi16(dstVectorRB, oneMinusAlphaChannel); \ - __m128i finalRB = _mm_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlphalpha); \ - finalRB = _mm_add_epi16(finalRB, _mm_srli_epi16(finalRB, 8)); \ - finalRB = _mm_add_epi16(finalRB, half); \ - finalRB = _mm_srli_epi16(finalRB, 8); \ - \ - /* combine */\ - result = _mm_or_si128(finalAG, finalRB); \ -} - -// Basically blend src over dst with the const alpha defined as constAlphaVector. -// nullVector, half, one, colorMask are constant across the whole image/texture, and should be defined as: -//const __m128i nullVector = _mm_set1_epi32(0); -//const __m128i half = _mm_set1_epi16(0x80); -//const __m128i one = _mm_set1_epi16(0xff); -//const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); -//const __m128i alphaMask = _mm_set1_epi32(0xff000000); -// -// The computation being done is: -// result = s + d * (1-alpha) -// with shortcuts if fully opaque or fully transparent. -#define BLEND_SOURCE_OVER_ARGB32_SSE2(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ - int x = 0; \ -\ - /* First, get dst aligned. */ \ - ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ - uint s = src[x]; \ - if (s >= 0xff000000) \ - dst[x] = s; \ - else if (s != 0) \ - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ - } \ -\ - for (; x < length-3; x += 4) { \ - const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ - const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ - /* all opaque */ \ - _mm_store_si128((__m128i *)&dst[x], srcVector); \ - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ - /* not fully transparent */ \ - /* extract the alpha channel on 2 x 16 bits */ \ - /* so we have room for the multiplication */ \ - /* each 32 bits will be in the form 0x00AA00AA */ \ - /* with A being the 1 - alpha */ \ - __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); \ - alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - \ - /* result = s + d * (1-alpha) */\ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - } \ - for (; x < length; ++x) { \ - uint s = src[x]; \ - if (s >= 0xff000000) \ - dst[x] = s; \ - else if (s != 0) \ - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ - } \ -} - -// Basically blend src over dst with the const alpha defined as constAlphaVector. -// nullVector, half, one, colorMask are constant across the whole image/texture, and should be defined as: -//const __m128i nullVector = _mm_set1_epi32(0); -//const __m128i half = _mm_set1_epi16(0x80); -//const __m128i one = _mm_set1_epi16(0xff); -//const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); -// -// The computation being done is: -// dest = (s + d * sia) * ca + d * cia -// = s * ca + d * (sia * ca + cia) -// = s * ca + d * (1 - sa*ca) -#define BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, length, nullVector, half, one, colorMask, constAlphaVector) \ -{ \ - int x = 0; \ -\ - ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ - quint32 s = src[x]; \ - if (s != 0) { \ - s = BYTE_MUL(s, const_alpha); \ - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ - } \ - } \ -\ - for (; x < length-3; x += 4) { \ - __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { \ - BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half); \ -\ - __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); \ - alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - \ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - } \ - for (; x < length; ++x) { \ - quint32 s = src[x]; \ - if (s != 0) { \ - s = BYTE_MUL(s, const_alpha); \ - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ - } \ - } \ -} - -QT_END_NAMESPACE - -#endif // QT_HAVE_SSE2 - -#endif // QDRAWINGPRIMITIVE_SSE2_P_H diff --git a/src/gui/painting/qwmatrix.h b/src/gui/painting/qwmatrix.h deleted file mode 100644 index 121dbcca1..000000000 --- a/src/gui/painting/qwmatrix.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** 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:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see 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. -** -** 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$ -** -****************************************************************************/ - -#ifndef QWMATRIX_H -#define QWMATRIX_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QWMATRIX_H -- 2.11.0