1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QDRAWHELPER_MMX_P_H
43 #define QDRAWHELPER_MMX_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
56 #include <private/qdrawhelper_p.h>
57 #include <private/qdrawhelper_x86_p.h>
58 #include <private/qpaintengine_raster_p.h>
64 #define C_FF const m64 mmx_0x00ff = _mm_set1_pi16(0xff)
65 #define C_80 const m64 mmx_0x0080 = _mm_set1_pi16(0x80)
66 #define C_00 const m64 mmx_0x0000 = _mm_setzero_si64()
69 # pragma warning(disable: 4799) // No EMMS at end of function
76 struct QMMXCommonIntrinsics
78 static inline m64 alpha(m64 x) {
79 x = _mm_unpackhi_pi16(x, x);
80 x = _mm_unpackhi_pi16(x, x);
84 static inline m64 _negate(const m64 &x, const m64 &mmx_0x00ff) {
85 return _mm_xor_si64(x, mmx_0x00ff);
88 static inline m64 add(const m64 &a, const m64 &b) {
89 return _mm_adds_pu16 (a, b);
92 static inline m64 _byte_mul(const m64 &a, const m64 &b,
93 const m64 &mmx_0x0080)
95 m64 res = _mm_mullo_pi16(a, b);
96 res = _mm_adds_pu16(res, mmx_0x0080);
97 res = _mm_adds_pu16(res, _mm_srli_pi16 (res, 8));
98 return _mm_srli_pi16(res, 8);
101 static inline m64 interpolate_pixel_256(const m64 &x, const m64 &a,
102 const m64 &y, const m64 &b)
104 m64 res = _mm_adds_pu16(_mm_mullo_pi16(x, a), _mm_mullo_pi16(y, b));
105 return _mm_srli_pi16(res, 8);
108 static inline m64 _interpolate_pixel_255(const m64 &x, const m64 &a,
109 const m64 &y, const m64 &b,
110 const m64 &mmx_0x0080)
112 m64 res = _mm_adds_pu16(_mm_mullo_pi16(x, a), _mm_mullo_pi16(y, b));
113 res = _mm_adds_pu16(res, mmx_0x0080);
114 res = _mm_adds_pu16(res, _mm_srli_pi16 (res, 8));
115 return _mm_srli_pi16(res, 8);
118 static inline m64 _premul(m64 x, const m64 &mmx_0x0080) {
120 return _byte_mul(x, a, mmx_0x0080);
123 static inline m64 _load(uint x, const m64 &mmx_0x0000) {
124 return _mm_unpacklo_pi8(_mm_cvtsi32_si64(x), mmx_0x0000);
127 static inline m64 _load_alpha(uint x, const m64 &) {
129 return _mm_set1_pi32(x);
132 static inline uint _store(const m64 &x, const m64 &mmx_0x0000) {
133 return _mm_cvtsi64_si32(_mm_packs_pu16(x, mmx_0x0000));
137 #define negate(x) _negate(x, mmx_0x00ff)
138 #define byte_mul(a, b) _byte_mul(a, b, mmx_0x0080)
139 #define interpolate_pixel_255(x, a, y, b) _interpolate_pixel_255(x, a, y, b, mmx_0x0080)
140 #define premul(x) _premul(x, mmx_0x0080)
141 #define load(x) _load(x, mmx_0x0000)
142 #define load_alpha(x) _load_alpha(x, mmx_0x0000)
143 #define store(x) _store(x, mmx_0x0000)
149 #define comp_func_Clear_impl(dest, length, const_alpha)\
151 if (const_alpha == 255) {\
152 qt_memfill(static_cast<quint32*>(dest), quint32(0), length);\
155 m64 ia = MM::negate(MM::load_alpha(const_alpha));\
156 for (int i = 0; i < length; ++i) {\
157 dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\
164 static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
166 comp_func_Clear_impl(dest, length, const_alpha);
170 static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
172 comp_func_Clear_impl(dest, length, const_alpha);
177 dest = s * ca + d * cia
180 static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint src, uint const_alpha)
182 if (const_alpha == 255) {
183 qt_memfill(static_cast<quint32*>(dest), quint32(src), length);
186 const m64 a = MM::load_alpha(const_alpha);
187 const m64 ia = MM::negate(a);
188 const m64 s = MM::byte_mul(MM::load(src), a);
189 for (int i = 0; i < length; ++i) {
190 dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia)));
197 static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
199 if (const_alpha == 255) {
200 ::memcpy(dest, src, length * sizeof(uint));
203 const m64 a = MM::load_alpha(const_alpha);
204 const m64 ia = MM::negate(a);
205 for (int i = 0; i < length; ++i)
206 dest[i] = MM::store(MM::interpolate_pixel_255(MM::load(src[i]), a,
207 MM::load(dest[i]), ia));
214 dest = (s + d * sia) * ca + d * cia
215 = s * ca + d * (sia * ca + cia)
216 = s * ca + d * (1 - sa*ca)
219 static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint src, uint const_alpha)
221 if ((const_alpha & qAlpha(src)) == 255) {
222 qt_memfill(static_cast<quint32*>(dest), quint32(src), length);
225 m64 s = MM::load(src);
226 if (const_alpha != 255) {
227 m64 ca = MM::load_alpha(const_alpha);
228 s = MM::byte_mul(s, ca);
230 m64 a = MM::negate(MM::alpha(s));
231 for (int i = 0; i < length; ++i)
232 dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), a)));
238 static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
241 if (const_alpha == 255) {
242 for (int i = 0; i < length; ++i) {
243 const uint alphaMaskedSource = 0xff000000 & src[i];
244 if (alphaMaskedSource == 0)
246 if (alphaMaskedSource == 0xff000000) {
249 m64 s = MM::load(src[i]);
250 m64 ia = MM::negate(MM::alpha(s));
251 dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia)));
255 m64 ca = MM::load_alpha(const_alpha);
256 for (int i = 0; i < length; ++i) {
257 if ((0xff000000 & src[i]) == 0)
259 m64 s = MM::byte_mul(MM::load(src[i]), ca);
260 m64 ia = MM::negate(MM::alpha(s));
261 dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia)));
269 dest = (d + s * dia) * ca + d * cia
273 static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint src, uint const_alpha)
276 m64 s = MM::load(src);
277 if (const_alpha != 255)
278 s = MM::byte_mul(s, MM::load_alpha(const_alpha));
280 for (int i = 0; i < length; ++i) {
281 m64 d = MM::load(dest[i]);
282 m64 dia = MM::negate(MM::alpha(d));
283 dest[i] = MM::store(MM::add(d, MM::byte_mul(s, dia)));
289 static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
292 if (const_alpha == 255) {
293 for (int i = 0; i < length; ++i) {
294 m64 d = MM::load(dest[i]);
295 m64 ia = MM::negate(MM::alpha(d));
296 dest[i] = MM::store(MM::add(d, MM::byte_mul(MM::load(src[i]), ia)));
299 m64 ca = MM::load_alpha(const_alpha);
300 for (int i = 0; i < length; ++i) {
301 m64 d = MM::load(dest[i]);
302 m64 dia = MM::negate(MM::alpha(d));
303 dia = MM::byte_mul(dia, ca);
304 dest[i] = MM::store(MM::add(d, MM::byte_mul(MM::load(src[i]), dia)));
312 dest = s * da * ca + d * cia
315 static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint src, uint const_alpha)
318 if (const_alpha == 255) {
319 m64 s = MM::load(src);
320 for (int i = 0; i < length; ++i) {
321 m64 da = MM::alpha(MM::load(dest[i]));
322 dest[i] = MM::store(MM::byte_mul(s, da));
326 m64 s = MM::load(src);
327 m64 ca = MM::load_alpha(const_alpha);
328 s = MM::byte_mul(s, ca);
329 m64 cia = MM::negate(ca);
330 for (int i = 0; i < length; ++i) {
331 m64 d = MM::load(dest[i]);
332 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, cia));
339 static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
342 if (const_alpha == 255) {
343 for (int i = 0; i < length; ++i) {
344 m64 a = MM::alpha(MM::load(dest[i]));
345 dest[i] = MM::store(MM::byte_mul(MM::load(src[i]), a));
348 m64 ca = MM::load_alpha(const_alpha);
349 m64 cia = MM::negate(ca);
350 for (int i = 0; i < length; ++i) {
351 m64 d = MM::load(dest[i]);
352 m64 da = MM::byte_mul(MM::alpha(d), ca);
353 dest[i] = MM::store(MM::interpolate_pixel_255(
354 MM::load(src[i]), da, d, cia));
362 dest = d * sa * ca + d * cia
363 = d * (sa * ca + cia)
366 static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint src, uint const_alpha)
369 m64 a = MM::alpha(MM::load(src));
370 if (const_alpha != 255) {
372 m64 ca = MM::load_alpha(const_alpha);
373 m64 cia = MM::negate(ca);
374 a = MM::byte_mul(a, ca);
377 for (int i = 0; i < length; ++i)
378 dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a));
383 static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
386 if (const_alpha == 255) {
387 for (int i = 0; i < length; ++i) {
388 m64 a = MM::alpha(MM::load(src[i]));
389 dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a));
392 m64 ca = MM::load_alpha(const_alpha);
393 m64 cia = MM::negate(ca);
394 for (int i = 0; i < length; ++i) {
395 m64 d = MM::load(dest[i]);
396 m64 a = MM::alpha(MM::load(src[i]));
397 a = MM::byte_mul(a, ca);
399 dest[i] = MM::store(MM::byte_mul(d, a));
407 dest = s * dia * ca + d * cia
410 static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint src, uint const_alpha)
413 m64 s = MM::load(src);
414 if (const_alpha == 255) {
415 for (int i = 0; i < length; ++i) {
416 m64 dia = MM::negate(MM::alpha(MM::load(dest[i])));
417 dest[i] = MM::store(MM::byte_mul(s, dia));
420 m64 ca = MM::load_alpha(const_alpha);
421 m64 cia = MM::negate(ca);
422 s = MM::byte_mul(s, ca);
423 for (int i = 0; i < length; ++i) {
424 m64 d = MM::load(dest[i]);
425 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), d, cia));
432 static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
435 if (const_alpha == 255) {
436 for (int i = 0; i < length; ++i) {
437 m64 ia = MM::negate(MM::alpha(MM::load(dest[i])));
438 dest[i] = MM::store(MM::byte_mul(MM::load(src[i]), ia));
441 m64 ca = MM::load_alpha(const_alpha);
442 m64 cia = MM::negate(ca);
443 for (int i = 0; i < length; ++i) {
444 m64 d = MM::load(dest[i]);
445 m64 dia = MM::byte_mul(MM::negate(MM::alpha(d)), ca);
446 dest[i] = MM::store(MM::interpolate_pixel_255(MM::load(src[i]), dia, d, cia));
454 dest = d * sia * ca + d * cia
455 = d * (sia * ca + cia)
458 static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint src, uint const_alpha)
461 m64 a = MM::negate(MM::alpha(MM::load(src)));
462 if (const_alpha != 255) {
463 m64 ca = MM::load_alpha(const_alpha);
464 a = MM::byte_mul(a, ca);
465 a = MM::add(a, MM::negate(ca));
467 for (int i = 0; i < length; ++i)
468 dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a));
473 static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
476 if (const_alpha == 255) {
477 for (int i = 0; i < length; ++i) {
478 m64 a = MM::negate(MM::alpha(MM::load(src[i])));
479 dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), a));
482 m64 ca = MM::load_alpha(const_alpha);
483 m64 cia = MM::negate(ca);
484 for (int i = 0; i < length; ++i) {
485 m64 d = MM::load(dest[i]);
486 m64 a = MM::negate(MM::alpha(MM::load(src[i])));
487 a = MM::byte_mul(a, ca);
489 dest[i] = MM::store(MM::byte_mul(d, a));
496 result = s*da + d*sia
497 dest = s*da*ca + d*sia*ca + d *cia
498 = s*ca * da + d * (sia*ca + cia)
499 = s*ca * da + d * (1 - sa*ca)
502 static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint src, uint const_alpha)
505 m64 s = MM::load(src);
506 if (const_alpha != 255) {
507 m64 ca = MM::load_alpha(const_alpha);
508 s = MM::byte_mul(s, ca);
510 m64 a = MM::negate(MM::alpha(s));
511 for (int i = 0; i < length; ++i) {
512 m64 d = MM::load(dest[i]);
513 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d, a));
519 static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
522 if (const_alpha == 255) {
523 for (int i = 0; i < length; ++i) {
524 m64 s = MM::load(src[i]);
525 m64 d = MM::load(dest[i]);
526 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d,
527 MM::negate(MM::alpha(s))));
530 m64 ca = MM::load_alpha(const_alpha);
531 for (int i = 0; i < length; ++i) {
532 m64 s = MM::load(src[i]);
533 s = MM::byte_mul(s, ca);
534 m64 d = MM::load(dest[i]);
535 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::alpha(d), d,
536 MM::negate(MM::alpha(s))));
543 result = d*sa + s*dia
544 dest = d*sa*ca + s*dia*ca + d *cia
545 = s*ca * dia + d * (sa*ca + cia)
548 static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint src, uint const_alpha)
551 m64 s = MM::load(src);
552 m64 a = MM::alpha(s);
553 if (const_alpha != 255) {
554 m64 ca = MM::load_alpha(const_alpha);
555 s = MM::byte_mul(s, ca);
557 a = MM::add(a, MM::negate(ca));
559 for (int i = 0; i < length; ++i) {
560 m64 d = MM::load(dest[i]);
561 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)), d, a));
567 static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
570 if (const_alpha == 255) {
571 for (int i = 0; i < length; ++i) {
572 m64 s = MM::load(src[i]);
573 m64 d = MM::load(dest[i]);
574 dest[i] = MM::store(MM::interpolate_pixel_255(d, MM::alpha(s), s,
575 MM::negate(MM::alpha(d))));
578 m64 ca = MM::load_alpha(const_alpha);
579 for (int i = 0; i < length; ++i) {
580 m64 s = MM::load(src[i]);
581 s = MM::byte_mul(s, ca);
582 m64 d = MM::load(dest[i]);
583 m64 a = MM::alpha(s);
584 a = MM::add(a, MM::negate(ca));
585 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)),
593 result = d*sia + s*dia
594 dest = d*sia*ca + s*dia*ca + d *cia
595 = s*ca * dia + d * (sia*ca + cia)
596 = s*ca * dia + d * (1 - sa*ca)
599 static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint src, uint const_alpha)
602 m64 s = MM::load(src);
603 if (const_alpha != 255) {
604 m64 ca = MM::load_alpha(const_alpha);
605 s = MM::byte_mul(s, ca);
607 m64 a = MM::negate(MM::alpha(s));
608 for (int i = 0; i < length; ++i) {
609 m64 d = MM::load(dest[i]);
610 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)),
617 static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
620 if (const_alpha == 255) {
621 for (int i = 0; i < length; ++i) {
622 m64 s = MM::load(src[i]);
623 m64 d = MM::load(dest[i]);
624 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)),
625 d, MM::negate(MM::alpha(s))));
628 m64 ca = MM::load_alpha(const_alpha);
629 for (int i = 0; i < length; ++i) {
630 m64 s = MM::load(src[i]);
631 s = MM::byte_mul(s, ca);
632 m64 d = MM::load(dest[i]);
633 dest[i] = MM::store(MM::interpolate_pixel_255(s, MM::negate(MM::alpha(d)),
634 d, MM::negate(MM::alpha(s))));
641 static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
646 Q_UNUSED(const_alpha);
648 if ((quintptr)(dest) & 0x7) {
653 const int length64 = length / 2;
655 __m64 *dst64 = reinterpret_cast<__m64*>(dest);
656 const __m64 color64 = _mm_set_pi32(color, color);
658 int n = (length64 + 3) / 4;
659 switch (length64 & 0x3) {
660 case 0: do { *dst64 = _mm_or_si64(*dst64, color64); ++dst64;
661 case 3: *dst64 = _mm_or_si64(*dst64, color64); ++dst64;
662 case 2: *dst64 = _mm_or_si64(*dst64, color64); ++dst64;
663 case 1: *dst64 = _mm_or_si64(*dst64, color64); ++dst64;
669 dest[length - 1] |= color;
676 static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
681 Q_UNUSED(const_alpha);
685 if ((quintptr)(dest) & 0x7) { // align
690 const int length64 = length / 2;
692 __m64 *dst64 = reinterpret_cast<__m64*>(dest);
693 const __m64 color64 = _mm_set_pi32(color, color);
695 int n = (length64 + 3) / 4;
696 switch (length64 & 0x3) {
697 case 0: do { *dst64 = _mm_and_si64(*dst64, color64); ++dst64;
698 case 3: *dst64 = _mm_and_si64(*dst64, color64); ++dst64;
699 case 2: *dst64 = _mm_and_si64(*dst64, color64); ++dst64;
700 case 1: *dst64 = _mm_and_si64(*dst64, color64); ++dst64;
706 dest[length - 1] &= color;
713 static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
718 Q_UNUSED(const_alpha);
722 if ((quintptr)(dest) & 0x7) {
727 const int length64 = length / 2;
729 __m64 *dst64 = reinterpret_cast<__m64*>(dest);
730 const __m64 color64 = _mm_set_pi32(color, color);
732 int n = (length64 + 3) / 4;
733 switch (length64 & 0x3) {
734 case 0: do { *dst64 = _mm_xor_si64(*dst64, color64); ++dst64;
735 case 3: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64;
736 case 2: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64;
737 case 1: *dst64 = _mm_xor_si64(*dst64, color64); ++dst64;
743 dest[length - 1] ^= color;
750 static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
756 Q_UNUSED(const_alpha);
758 if ((quintptr)(dest) & 0x7) {
759 *dest = (color & ~(*dest)) | 0xff000000;
764 const int length64 = length / 2;
766 __m64 *dst64 = reinterpret_cast<__m64*>(dest);
767 const __m64 color64 = _mm_set_pi32(color, color);
768 const m64 mmx_0xff000000 = _mm_set1_pi32(0xff000000);
769 __m64 tmp1, tmp2, tmp3, tmp4;
771 int n = (length64 + 3) / 4;
772 switch (length64 & 0x3) {
773 case 0: do { tmp1 = _mm_andnot_si64(*dst64, color64);
774 *dst64++ = _mm_or_si64(tmp1, mmx_0xff000000);
775 case 3: tmp2 = _mm_andnot_si64(*dst64, color64);
776 *dst64++ = _mm_or_si64(tmp2, mmx_0xff000000);
777 case 2: tmp3 = _mm_andnot_si64(*dst64, color64);
778 *dst64++ = _mm_or_si64(tmp3, mmx_0xff000000);
779 case 1: tmp4 = _mm_andnot_si64(*dst64, color64);
780 *dst64++ = _mm_or_si64(tmp4, mmx_0xff000000);
786 dest[length - 1] = (color & ~(dest[length - 1])) | 0xff000000;
793 static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
798 rasterop_solid_SourceAndNotDestination<MM>(dest, length,
799 ~color, const_alpha);
803 static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
808 Q_UNUSED(const_alpha);
809 color = ~color | 0xff000000;
811 *dest = color | ~(*dest);
817 static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
822 rasterop_solid_SourceXorDestination<MM>(dest, length, ~color, const_alpha);
826 static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
827 uint color, uint const_alpha)
829 Q_UNUSED(const_alpha);
830 qt_memfill((quint32*)dest, ~color | 0xff000000, length);
834 static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
839 rasterop_solid_SourceAndDestination<MM>(dest, length,
840 ~color, const_alpha);
844 static inline void qt_blend_color_argb_x86(int count, const QSpan *spans,
846 CompositionFunctionSolid *solidFunc)
848 QSpanData *data = reinterpret_cast<QSpanData *>(userData);
849 if (data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source
850 || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
851 && qAlpha(data->solid.color) == 255)) {
852 // inline for performance
855 uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
856 if (spans->coverage == 255) {
857 qt_memfill(static_cast<quint32*>(target), quint32(data->solid.color), spans->len);
859 // dest = s * ca + d * (1 - sa*ca) --> dest = s * ca + d * (1-ca)
860 m64 ca = MM::load_alpha(spans->coverage);
861 m64 s = MM::byte_mul(MM::load(data->solid.color), ca);
862 m64 ica = MM::negate(ca);
863 for (int i = 0; i < spans->len; ++i)
864 target[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(target[i]), ica)));
871 CompositionFunctionSolid func = solidFunc[data->rasterBuffer->compositionMode];
873 uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
874 func(target, spans->len, data->solid.color, spans->coverage);
880 struct QMMXIntrinsics : public QMMXCommonIntrinsics
882 static inline void end() {
883 #if !defined(Q_OS_WINCE) || defined(_X86_)
888 #endif // QT_HAVE_MMX
892 #endif // QDRAWHELPER_MMX_P_H