diff options
Diffstat (limited to 'src/gui/painting/qdrawingprimitive_sse2_p.h')
-rw-r--r-- | src/gui/painting/qdrawingprimitive_sse2_p.h | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 1a7dddf0d5..c74055e440 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -35,6 +35,7 @@ #define QDRAWINGPRIMITIVE_SSE2_P_H #include <private/qsimd_p.h> +#include "qdrawhelper_p.h" #ifdef __SSE2__ @@ -256,6 +257,43 @@ inline QRgb qUnpremultiply_sse4(QRgb p) vl = _mm_packus_epi16(vl, vl); return _mm_cvtsi128_si32(vl); } + +template<enum QtPixelOrder PixelOrder> +QT_FUNCTION_TARGET(SSE4_1) +inline uint qConvertArgb32ToA2rgb30_sse4(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255) + return qConvertRgb32ToRgb30<PixelOrder>(p); + if (alpha == 0) + return 0; + Q_CONSTEXPR uint mult = 255 / (255 >> 6); + const uint invAlpha = qt_inv_premul_factor[alpha]; + const uint newalpha = (alpha >> 6); + const __m128i via = _mm_set1_epi32(invAlpha); + const __m128i vna = _mm_set1_epi32(mult * newalpha); + const __m128i vr1 = _mm_set1_epi32(0x1000); + const __m128i vr2 = _mm_set1_epi32(0x80); + __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p)); + vl = _mm_mullo_epi32(vl, via); + vl = _mm_add_epi32(vl, vr1); + vl = _mm_srli_epi32(vl, 14); + vl = _mm_mullo_epi32(vl, vna); + vl = _mm_add_epi32(vl, _mm_srli_epi32(vl, 8)); + vl = _mm_add_epi32(vl, vr2); + vl = _mm_srli_epi32(vl, 8); + vl = _mm_packus_epi32(vl, vl); + uint rgb30 = (newalpha << 30); + rgb30 |= ((uint)_mm_extract_epi16(vl, 1)) << 10; + if (PixelOrder == PixelOrderRGB) { + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)); + } else { + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)); + } + return rgb30; +} #endif QT_END_NAMESPACE |