Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qdrawhelper_ssse3.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||||||||
2 | - | |||||||||||||||||||
3 | - | |||||||||||||||||||
4 | - | |||||||||||||||||||
5 | - | |||||||||||||||||||
6 | - | |||||||||||||||||||
7 | inline static void blend_pixel(quint32 &dst, const quint32 src) | - | ||||||||||||||||||
8 | { | - | ||||||||||||||||||
9 | if (src >= 0xff000000) | - | ||||||||||||||||||
10 | dst = src; | - | ||||||||||||||||||
11 | else if (src != 0) | - | ||||||||||||||||||
12 | dst = src + BYTE_MUL(dst, qAlpha(~src)); | - | ||||||||||||||||||
13 | } | - | ||||||||||||||||||
14 | void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, | - | ||||||||||||||||||
15 | const uchar *srcPixels, int sbpl, | - | ||||||||||||||||||
16 | int w, int h, | - | ||||||||||||||||||
17 | int const_alpha) | - | ||||||||||||||||||
18 | { | - | ||||||||||||||||||
19 | const quint32 *src = (const quint32 *) srcPixels; | - | ||||||||||||||||||
20 | quint32 *dst = (quint32 *) destPixels; | - | ||||||||||||||||||
21 | if (const_alpha == 256) { | - | ||||||||||||||||||
22 | const __m128i alphaMask = _mm_set1_epi32(0xff000000); | - | ||||||||||||||||||
23 | const __m128i nullVector = _mm_setzero_si128(); | - | ||||||||||||||||||
24 | const __m128i half = _mm_set1_epi16(0x80); | - | ||||||||||||||||||
25 | const __m128i one = _mm_set1_epi16(0xff); | - | ||||||||||||||||||
26 | const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); | - | ||||||||||||||||||
27 | - | |||||||||||||||||||
28 | for (int y = 0; y < h; ++y) { | - | ||||||||||||||||||
29 | { int x = 0; for (; x < static_cast<int>(qMin(static_cast<quintptr>(w), ((4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3))); ++x) { blend_pixel(dst[x], src[x]); } const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast<quintptr>(&(src[x])) >> 2) & 0x3; if (!minusOffsetToAlignSrcOn16Bytes) { const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); for (; x < w-3; x += 4) { const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { _mm_store_si128((__m128i *)&dst[x], srcVector); } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); alphaChannel = _mm_sub_epi16(one, alphaChannel); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i destMultipliedByOneMinusAlpha; { __m128i pixelVectorAG = _mm_srli_epi16(dstVector, 8); __m128i pixelVectorRB = _mm_and_si128(dstVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); destMultipliedByOneMinusAlpha = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); _mm_store_si128((__m128i *)&dst[x], result); } } } else if ((w - x) >= 8) { __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]); const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2; const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); switch (palignrOffset) { case 4: for (; x-minusOffsetToAlignSrcOn16Bytes < w-7; x += 4) { const __m128i srcVectorLastLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]); const __m128i srcVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(srcVectorLastLoaded), (__v2di)(__m128i)(srcVectorPrevLoaded), (int)(4) * 8)); const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { _mm_store_si128((__m128i *)&dst[x], srcVector); } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); alphaChannel = _mm_sub_epi16(one, alphaChannel); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i destMultipliedByOneMinusAlpha; { __m128i pixelVectorAG = _mm_srli_epi16(dstVector, 8); __m128i pixelVectorRB = _mm_and_si128(dstVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); destMultipliedByOneMinusAlpha = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); _mm_store_si128((__m128i *)&dst[x], result); } srcVectorPrevLoaded = srcVectorLastLoaded; } break; case 8: for (; x-minusOffsetToAlignSrcOn16Bytes < w-7; x += 4) { const __m128i srcVectorLastLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]); const __m128i srcVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(srcVectorLastLoaded), (__v2di)(__m128i)(srcVectorPrevLoaded), (int)(8) * 8)); const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { _mm_store_si128((__m128i *)&dst[x], srcVector); } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); alphaChannel = _mm_sub_epi16(one, alphaChannel); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i destMultipliedByOneMinusAlpha; { __m128i pixelVectorAG = _mm_srli_epi16(dstVector, 8); __m128i pixelVectorRB = _mm_and_si128(dstVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); destMultipliedByOneMinusAlpha = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); _mm_store_si128((__m128i *)&dst[x], result); } srcVectorPrevLoaded = srcVectorLastLoaded; } break; case 12: for (; x-minusOffsetToAlignSrcOn16Bytes < w-7; x += 4) { const __m128i srcVectorLastLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]); const __m128i srcVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(srcVectorLastLoaded), (__v2di)(__m128i)(srcVectorPrevLoaded), (int)(12) * 8)); const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { _mm_store_si128((__m128i *)&dst[x], srcVector); } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); alphaChannel = _mm_sub_epi16(one, alphaChannel); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i destMultipliedByOneMinusAlpha; { __m128i pixelVectorAG = _mm_srli_epi16(dstVector, 8); __m128i pixelVectorRB = _mm_and_si128(dstVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); destMultipliedByOneMinusAlpha = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); _mm_store_si128((__m128i *)&dst[x], result); } srcVectorPrevLoaded = srcVectorLastLoaded; } break; } } for (; x < w; ++x) blend_pixel(dst[x], src[x]); }; | - | ||||||||||||||||||
30 | dst = (quint32 *)(((uchar *) dst) + dbpl); | - | ||||||||||||||||||
31 | src = (const quint32 *)(((const uchar *) src) + sbpl); | - | ||||||||||||||||||
32 | } | - | ||||||||||||||||||
33 | } else if (const_alpha != 0) { | - | ||||||||||||||||||
34 | - | |||||||||||||||||||
35 | - | |||||||||||||||||||
36 | - | |||||||||||||||||||
37 | const_alpha = (const_alpha * 255) >> 8; | - | ||||||||||||||||||
38 | const __m128i nullVector = _mm_setzero_si128(); | - | ||||||||||||||||||
39 | const __m128i half = _mm_set1_epi16(0x80); | - | ||||||||||||||||||
40 | const __m128i one = _mm_set1_epi16(0xff); | - | ||||||||||||||||||
41 | const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); | - | ||||||||||||||||||
42 | const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); | - | ||||||||||||||||||
43 | for (int y = 0; y < h; ++y) { | - | ||||||||||||||||||
44 | { int x = 0; for (; x < static_cast<int>(qMin(static_cast<quintptr>(w), ((4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3))); ++x) { quint32 s = src[x]; if (s != 0) { s = BYTE_MUL(s, const_alpha); dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); } } for (; x < w-3; x += 4) { __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[x]); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { { __m128i pixelVectorAG = _mm_srli_epi16(srcVector, 8); __m128i pixelVectorRB = _mm_and_si128(srcVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, constAlphaVector); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, constAlphaVector); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); srcVector = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); alphaChannel = _mm_sub_epi16(one, alphaChannel); const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i destMultipliedByOneMinusAlpha; { __m128i pixelVectorAG = _mm_srli_epi16(dstVector, 8); __m128i pixelVectorRB = _mm_and_si128(dstVector, colorMask); pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); destMultipliedByOneMinusAlpha = _mm_or_si128(pixelVectorAG, pixelVectorRB); }; const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); _mm_store_si128((__m128i *)&dst[x], result); } } for (; x < w; ++x) { quint32 s = src[x]; if (s != 0) { s = BYTE_MUL(s, const_alpha); dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); } } } | - | ||||||||||||||||||
45 | dst = (quint32 *)(((uchar *) dst) + dbpl); | - | ||||||||||||||||||
46 | src = (const quint32 *)(((const uchar *) src) + sbpl); | - | ||||||||||||||||||
47 | } | - | ||||||||||||||||||
48 | } | - | ||||||||||||||||||
49 | } | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | static inline void store_uint24_ssse3(uchar *dst, const uint *src, int len) | - | ||||||||||||||||||
52 | { | - | ||||||||||||||||||
53 | int i = 0; | - | ||||||||||||||||||
54 | - | |||||||||||||||||||
55 | quint24 *dst24 = reinterpret_cast<quint24*>(dst); | - | ||||||||||||||||||
56 | - | |||||||||||||||||||
57 | for (; i < len
| 0 | ||||||||||||||||||
58 | * never executed: dst24++ = quint24(*src++);*dst24++ = quint24(*src++); never executed: *dst24++ = quint24(*src++); | 0 | ||||||||||||||||||
59 | - | |||||||||||||||||||
60 | - | |||||||||||||||||||
61 | const __m128i shuffleMask1 = _mm_setr_epi8(char(0x80), char(0x80), char(0x80), char(0x80), 2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12); | - | ||||||||||||||||||
62 | const __m128i shuffleMask2 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, char(0x80), char(0x80), char(0x80), char(0x80)); | - | ||||||||||||||||||
63 | - | |||||||||||||||||||
64 | const __m128i *inVectorPtr = (const __m128i *)src; | - | ||||||||||||||||||
65 | __m128i *dstVectorPtr = (__m128i *)dst24; | - | ||||||||||||||||||
66 | - | |||||||||||||||||||
67 | for (; i < (len - 15)
| 0 | ||||||||||||||||||
68 | - | |||||||||||||||||||
69 | - | |||||||||||||||||||
70 | __m128i srcVector1 = _mm_loadu_si128(inVectorPtr); | - | ||||||||||||||||||
71 | ++inVectorPtr; | - | ||||||||||||||||||
72 | __m128i srcVector2 = _mm_loadu_si128(inVectorPtr); | - | ||||||||||||||||||
73 | ++inVectorPtr; | - | ||||||||||||||||||
74 | __m128i outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1); | - | ||||||||||||||||||
75 | __m128i outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2); | - | ||||||||||||||||||
76 | __m128i outputVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(outputVector2), (__v2di)(__m128i)(outputVector1), (int)(4) * 8)); | - | ||||||||||||||||||
77 | _mm_store_si128(dstVectorPtr, outputVector); | - | ||||||||||||||||||
78 | ++dstVectorPtr; | - | ||||||||||||||||||
79 | - | |||||||||||||||||||
80 | srcVector1 = _mm_loadu_si128(inVectorPtr); | - | ||||||||||||||||||
81 | ++inVectorPtr; | - | ||||||||||||||||||
82 | outputVector1 = _mm_shuffle_epi8(srcVector2, shuffleMask1); | - | ||||||||||||||||||
83 | outputVector2 = _mm_shuffle_epi8(srcVector1, shuffleMask2); | - | ||||||||||||||||||
84 | outputVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(outputVector2), (__v2di)(__m128i)(outputVector1), (int)(8) * 8)); | - | ||||||||||||||||||
85 | _mm_store_si128(dstVectorPtr, outputVector); | - | ||||||||||||||||||
86 | ++dstVectorPtr; | - | ||||||||||||||||||
87 | - | |||||||||||||||||||
88 | srcVector2 = _mm_loadu_si128(inVectorPtr); | - | ||||||||||||||||||
89 | ++inVectorPtr; | - | ||||||||||||||||||
90 | outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1); | - | ||||||||||||||||||
91 | outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2); | - | ||||||||||||||||||
92 | outputVector = ((__m128i) __builtin_ia32_palignr128 ((__v2di)(__m128i)(outputVector2), (__v2di)(__m128i)(outputVector1), (int)(12) * 8)); | - | ||||||||||||||||||
93 | _mm_store_si128(dstVectorPtr, outputVector); | - | ||||||||||||||||||
94 | ++dstVectorPtr; | - | ||||||||||||||||||
95 | } never executed: end of block | 0 | ||||||||||||||||||
96 | dst24 = reinterpret_cast<quint24*>(dstVectorPtr); | - | ||||||||||||||||||
97 | src = reinterpret_cast<const uint*>(inVectorPtr); | - | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | for (; i < len
| 0 | ||||||||||||||||||
100 | * never executed: dst24++ = quint24(*src++);*dst24++ = quint24(*src++); never executed: *dst24++ = quint24(*src++); | 0 | ||||||||||||||||||
101 | } never executed: end of block | 0 | ||||||||||||||||||
102 | - | |||||||||||||||||||
103 | void storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count) | - | ||||||||||||||||||
104 | { | - | ||||||||||||||||||
105 | store_uint24_ssse3(dest + index * 3, src, count); | - | ||||||||||||||||||
106 | } never executed: end of block | 0 | ||||||||||||||||||
107 | - | |||||||||||||||||||
108 | extern void qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); | - | ||||||||||||||||||
109 | - | |||||||||||||||||||
110 | const uint * qt_fetchUntransformed_888_ssse3(uint *buffer, const Operator *, const QSpanData *data, | - | ||||||||||||||||||
111 | int y, int x, int length) | - | ||||||||||||||||||
112 | { | - | ||||||||||||||||||
113 | const uchar *line = data->texture.scanLine(y) + x * 3; | - | ||||||||||||||||||
114 | qt_convert_rgb888_to_rgb32_ssse3(buffer, line, length); | - | ||||||||||||||||||
115 | return never executed: buffer;return buffer; never executed: return buffer; | 0 | ||||||||||||||||||
116 | } | - | ||||||||||||||||||
117 | - | |||||||||||||||||||
118 | - | |||||||||||||||||||
Switch to Source code | Preprocessed file |