summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 12:19:37 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-20 09:56:15 +0100
commitaa5855847c158524ceaa99f2e99fb2eba5b118af (patch)
tree685f539323d8ba455b041b5d7887d6e4bdc705df /src/gui
parent6c5b42b678b8e54cbb58f75d5d8abb50eff46dd9 (diff)
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>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/painting/qdrawhelper.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp29
2 files changed, 35 insertions, 0 deletions
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) {