Add SSE2 optimized solid source composition

Very similar to source-over, but have traditionally been inlined.

Change-Id: I211f0b1c91c1a00c4769fbbfe2e3d0c7b22d7048
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
bb10
Allan Sandfeld Jensen 2020-03-18 12:19:37 +01:00
parent 6c5b42b678
commit aa5855847c
2 changed files with 35 additions and 0 deletions

View File

@ -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

View File

@ -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) {