From aa5855847c158524ceaa99f2e99fb2eba5b118af Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 18 Mar 2020 12:19:37 +0100 Subject: Add SSE2 optimized solid source composition Very similar to source-over, but have traditionally been inlined. Change-Id: I211f0b1c91c1a00c4769fbbfe2e3d0c7b22d7048 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 6 ++++++ src/gui/painting/qdrawhelper_sse2.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'src') diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 4b0cc2547c..39de1baa17 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4521,6 +4521,10 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; if (spans->coverage == 255) { qt_memfill(target, color, spans->len); +#ifdef __SSE2__ + } else if (spans->len > 16) { + op.funcSolid(target, spans->len, color, spans->coverage); +#endif } else { uint c = BYTE_MUL(color, spans->coverage); int ialpha = 255 - spans->coverage; @@ -6764,10 +6768,12 @@ static void qInitDrawhelperFunctions() 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_Source_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels, int length, uint color, uint const_alpha); extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2; qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2; qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2; + qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_sse2; qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; #ifdef QT_COMPILER_SUPPORTS_SSSE3 diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index c82f41ec88..77b5ab42c5 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -319,6 +319,35 @@ void qt_memfill32_sse2(quint32 *dest, quint32 value, qsizetype count) } #endif // !__AVX2__ +void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels, int length, uint color, uint const_alpha) +{ + if (const_alpha == 255) { + qt_memfill32(destPixels, color, length); + } else { + const quint32 ialpha = 255 - const_alpha; + color = BYTE_MUL(color, const_alpha); + 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 iAlphaVector = _mm_set1_epi16(ialpha); + + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) + destPixels[x] = color + BYTE_MUL(destPixels[x], ialpha); + + for (; x < length-3; x += 4) { + __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + BYTE_MUL_SSE2(dstVector, dstVector, iAlphaVector, colorMask, half); + dstVector = _mm_add_epi8(colorVector, dstVector); + _mm_store_si128((__m128i *)&dst[x], dstVector); + } + SIMD_EPILOGUE(x, length, 3) + destPixels[x] = color + BYTE_MUL(destPixels[x], ialpha); + } +} + void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha) { if ((const_alpha & qAlpha(color)) == 255) { -- cgit v1.2.3