diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 41 | ||||
-rw-r--r-- | src/gui/painting/qrgba64_p.h | 5 |
2 files changed, 24 insertions, 22 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 4671c5cecf..654be5690b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1144,6 +1144,11 @@ static QRgba64 *QT_FASTCALL destFetch64uint32(QRgba64 *buffer, QRasterBuffer *ra return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, 0, 0)); } +static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *, int, int, int) +{ + return buffer; +} + static DestFetchProc destFetchProc[QImage::NImageFormats] = { 0, // Format_Invalid @@ -1176,8 +1181,8 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = { 0, // Format_Invalid - destFetch64, // Format_Mono, - destFetch64, // Format_MonoLSB + 0, // Format_Mono, + 0, // Format_MonoLSB 0, // Format_Indexed8 destFetch64uint32, // Format_RGB32 destFetch64uint32, // Format_ARGB32, @@ -3737,27 +3742,23 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in op.destFetch = destFetchProc[data->rasterBuffer->format]; op.destFetch64 = destFetchProc64[data->rasterBuffer->format]; - if (op.mode == QPainter::CompositionMode_Source) { - switch (data->rasterBuffer->format) { - case QImage::Format_RGB32: - case QImage::Format_ARGB32_Premultiplied: - // don't clear destFetch as it sets up the pointer correctly to save one copy - break; - default: { - if (data->type == QSpanData::Texture && data->texture.const_alpha != 256) + if (op.mode == QPainter::CompositionMode_Source && + (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) { + const QSpan *lastSpan = spans + spanCount; + bool alphaSpans = false; + while (spans < lastSpan) { + if (spans->coverage != 255) { + alphaSpans = true; break; - const QSpan *lastSpan = spans + spanCount; - bool alphaSpans = false; - while (spans < lastSpan) { - if (spans->coverage != 255) { - alphaSpans = true; - break; - } - ++spans; } - if (!alphaSpans) - op.destFetch = 0; + ++spans; } + if (!alphaSpans) { + // If all spans are opaque we do not need to fetch dest. + // But don't clear passthrough destFetch as they are just as fast and save destStore. + if (op.destFetch != destFetchARGB32P) + op.destFetch = 0; + op.destFetch64 = destFetch64Undefined; } } diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h index 2a17d8a624..7776a5b08a 100644 --- a/src/gui/painting/qrgba64_p.h +++ b/src/gui/painting/qrgba64_p.h @@ -256,11 +256,12 @@ Q_ALWAYS_INLINE uint16x4_t addWithSaturation(uint16x4_t a, uint16x4_t b) inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha) { QRgba64 blend; -#ifdef __SSE2__ +#if defined(__SSE2__) __m128i vd = _mm_loadl_epi64((const __m128i *)&d); __m128i vs = _mm_loadl_epi64((const __m128i *)&s); __m128i va = _mm_cvtsi32_si128(rgbAlpha); va = _mm_unpacklo_epi8(va, va); + va = _mm_shufflelo_epi16(va, _MM_SHUFFLE(3, 0, 1, 2)); __m128i vb = _mm_xor_si128(_mm_set1_epi16(-1), va); vs = _mm_unpacklo_epi16(_mm_mullo_epi16(vs, va), _mm_mulhi_epu16(vs, va)); @@ -275,7 +276,7 @@ inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha) #elif defined(__ARM_NEON__) uint16x4_t vd = vreinterpret_u16_u64(vmov_n_u64(d)); uint16x4_t vs = vreinterpret_u16_u64(vmov_n_u64(s)); - uint8x8_t va8 = vreinterpret_u8_u32(vmov_n_u32(rgbAlpha)); + uint8x8_t va8 = vreinterpret_u8_u32(vmov_n_u32(ARGB2RGBA(rgbAlpha))); uint16x4_t va = vreinterpret_u16_u8(vzip_u8(va8, va8).val[0]); uint16x4_t vb = vdup_n_u16(0xffff); vb = vsub_u16(vb, va); |