diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index bd853ad934..5e71972c2e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1313,7 +1313,7 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length) { for (int i = 0; i < length; ++i) { - dest[i] = src[i].toArgb32(); + dest[i] = toArgb32(src[i]); } } @@ -1404,7 +1404,7 @@ static void QT_FASTCALL destStore64ARGB32(QRasterBuffer *rasterBuffer, int x, in { uint *dest = (uint*)rasterBuffer->scanLine(y) + x; for (int i = 0; i < length; ++i) { - dest[i] = buffer[i].unpremultiplied().toArgb32(); + dest[i] = toArgb32(buffer[i].unpremultiplied()); } } @@ -1412,7 +1412,7 @@ static void QT_FASTCALL destStore64RGBA8888(QRasterBuffer *rasterBuffer, int x, { uint *dest = (uint*)rasterBuffer->scanLine(y) + x; for (int i = 0; i < length; ++i) { - dest[i] = ARGB2RGBA(buffer[i].unpremultiplied().toArgb32()); + dest[i] = toRgba8888(buffer[i].unpremultiplied()); } } diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h index 0dadc038fa..08e73942df 100644 --- a/src/gui/painting/qrgba64_p.h +++ b/src/gui/painting/qrgba64_p.h @@ -185,6 +185,55 @@ inline QRgba64 addWithSaturation(QRgba64 a, QRgba64 b) qMin(a.alpha() + b.alpha(), 65535)); } +#if defined __SSE2__ +Q_ALWAYS_INLINE uint toArgb32(__m128i v) +{ + v = _mm_unpacklo_epi16(v, _mm_setzero_si128()); + v = _mm_add_epi32(v, _mm_set1_epi32(128)); + v = _mm_sub_epi32(v, _mm_srli_epi32(v, 8)); + v = _mm_srli_epi32(v, 8); + v = _mm_packs_epi32(v, v); + v = _mm_packus_epi16(v, v); + return _mm_cvtsi128_si32(v); +} +#elif defined __ARM_NEON__ +Q_ALWAYS_INLINE uint toArgb32(uint16x4_t v) +{ + v = vsub_u16(v, vrshr_n_u16(v, 8)); + v = vrshr_n_u16(v, 8); + uint8x8_t v8 = vmovn_u16(vcombine_u16(v, v)); + return vget_lane_u32(vreinterpret_u32_u8(v8), 0); +} +#endif + +inline uint toArgb32(QRgba64 rgba64) +{ +#if defined __SSE2__ + __m128i v = _mm_loadl_epi64((const __m128i *)&rgba64); + v = _mm_shufflelo_epi16(v, _MM_SHUFFLE(3, 0, 1, 2)); + return toArgb32(v); +#elif defined __ARM_NEON__ + uint16x4_t v = vreinterpret_u16_u64(vld1_u64(reinterpret_cast(&rgba64))); + v = vext_u16(v, v, 1); + return toArgb32(v); +#else + return rgba64.toArgb32(); +#endif +} + +inline uint toRgba8888(QRgba64 rgba64) +{ +#if defined __SSE2__ + __m128i v = _mm_loadl_epi64((const __m128i *)&rgba64); + return toArgb32(v); +#elif defined __ARM_NEON__ + uint16x4_t v = vreinterpret_u16_u64(vld1_u64(reinterpret_cast(&rgba64))); + return toArgb32(v); +#else + return ARGB2RGBA(toArgb32(rgba64)); +#endif +} + #if defined(__SSE2__) Q_ALWAYS_INLINE __m128i addWithSaturation(__m128i a, __m128i b) {