src/gui/painting/qdrawhelper.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    44 #include <private/qpainter_p.h>
    44 #include <private/qpainter_p.h>
    45 #include <private/qdrawhelper_x86_p.h>
    45 #include <private/qdrawhelper_x86_p.h>
    46 #include <private/qdrawhelper_armv6_p.h>
    46 #include <private/qdrawhelper_armv6_p.h>
    47 #include <private/qdrawhelper_neon_p.h>
    47 #include <private/qdrawhelper_neon_p.h>
    48 #include <private/qmath_p.h>
    48 #include <private/qmath_p.h>
    49 #include <private/qsimd_p.h>
       
    50 #include <qmath.h>
    49 #include <qmath.h>
    51 
    50 
    52 QT_BEGIN_NAMESPACE
    51 QT_BEGIN_NAMESPACE
    53 
    52 
    54 
    53 
   654     }
   653     }
   655 
   654 
   656     return buffer;
   655     return buffer;
   657 }
   656 }
   658 
   657 
       
   658 /** \internal
       
   659   interpolate 4 argb pixels with the distx and disty factor.
       
   660   distx and disty bust be between 0 and 16
       
   661  */
       
   662 static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty, int idistx, int idisty)
       
   663 {
       
   664     uint tlrb = ((tl & 0x00ff00ff) * idistx * idisty);
       
   665     uint tlag = (((tl & 0xff00ff00) >> 8) * idistx * idisty);
       
   666     uint trrb = ((tr & 0x00ff00ff) * distx * idisty);
       
   667     uint trag = (((tr & 0xff00ff00) >> 8) * distx * idisty);
       
   668     uint blrb = ((bl & 0x00ff00ff) * idistx * disty);
       
   669     uint blag = (((bl & 0xff00ff00) >> 8) * idistx * disty);
       
   670     uint brrb = ((br & 0x00ff00ff) * distx * disty);
       
   671     uint brag = (((br & 0xff00ff00) >> 8) * distx * disty);
       
   672     return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
       
   673 }
       
   674 
       
   675 
       
   676 template<TextureBlendType blendType>
       
   677 Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
       
   678 {
       
   679     if (blendType == BlendTransformedBilinearTiled) {
       
   680         v1 %= max;
       
   681         if (v1 < 0) v1 += max;
       
   682         v2 = v1 + 1;
       
   683         v2 %= max;
       
   684     } else {
       
   685         if (v1 < l1) {
       
   686             v2 = v1 = l1;
       
   687         } else if (v1 >= l2) {
       
   688             v2 = v1 = l2;
       
   689         } else {
       
   690             v2 = v1 + 1;
       
   691         }
       
   692     }
       
   693 
       
   694     Q_ASSERT(v1 >= 0 && v1 < max);
       
   695     Q_ASSERT(v2 >= 0 && v2 < max);
       
   696 }
       
   697 
   659 template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
   698 template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
   660 Q_STATIC_TEMPLATE_FUNCTION
   699 Q_STATIC_TEMPLATE_FUNCTION
   661 const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
   700 const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
   662                                                   int y, int x, int length)
   701                                                   int y, int x, int length)
   663 {
   702 {
   674     int image_width = data->texture.width;
   713     int image_width = data->texture.width;
   675     int image_height = data->texture.height;
   714     int image_height = data->texture.height;
   676 
   715 
   677     int image_x1 = data->texture.x1;
   716     int image_x1 = data->texture.x1;
   678     int image_y1 = data->texture.y1;
   717     int image_y1 = data->texture.y1;
   679     int image_x2 = data->texture.x2;
   718     int image_x2 = data->texture.x2 - 1;
   680     int image_y2 = data->texture.y2;
   719     int image_y2 = data->texture.y2 - 1;
   681 
   720 
   682     const qreal cx = x + 0.5;
   721     const qreal cx = x + 0.5;
   683     const qreal cy = y + 0.5;
   722     const qreal cy = y + 0.5;
   684 
   723 
   685     const uint *end = buffer + length;
   724     const uint *end = buffer + length;
   694         int fy = int((data->m22 * cy
   733         int fy = int((data->m22 * cy
   695                       + data->m12 * cx + data->dy) * fixed_scale);
   734                       + data->m12 * cx + data->dy) * fixed_scale);
   696 
   735 
   697         fx -= half_point;
   736         fx -= half_point;
   698         fy -= half_point;
   737         fy -= half_point;
   699         while (b < end) {
   738 
   700             int x1 = (fx >> 16);
   739         if (fdy == 0) { //simple scale, no rotation
   701             int x2;
       
   702             int y1 = (fy >> 16);
   740             int y1 = (fy >> 16);
   703             int y2;
   741             int y2;
   704 
   742             fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
   705             if (blendType == BlendTransformedBilinearTiled) {
   743             const uchar *s1 = data->texture.scanLine(y1);
   706                 x1 %= image_width;
   744             const uchar *s2 = data->texture.scanLine(y2);
   707                 if (x1 < 0) x1 += image_width;
   745 
   708                 x2 = x1 + 1;
   746             if (fdx <= fixed_scale && fdx > 0) { // scale up on X
   709                 x2 %= image_width;
   747                 int disty = (fy & 0x0000ffff) >> 8;
   710 
   748                 int idisty = 256 - disty;
   711                 y1 %= image_height;
   749                 int x = fx >> 16;
   712                 if (y1 < 0) y1 += image_height;
   750 
   713                 y2 = y1 + 1;
   751                 // The idea is first to do the interpolation between the row s1 and the row s2
   714                 y2 %= image_height;
   752                 // into an intermediate buffer, then we interpolate between two pixel of this buffer.
   715             } else {
   753 
   716                 if (x1 < image_x1) {
   754                 // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
   717                     x2 = x1 = image_x1;
   755                 // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
   718                 } else if (x1 >= image_x2 - 1) {
   756                 quint32 intermediate_buffer[2][buffer_size + 2];
   719                     x2 = x1 = image_x2 - 1;
   757                 // count is the size used in the intermediate_buffer.
       
   758                 int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
       
   759                 Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
       
   760                 int f = 0;
       
   761                 int lim = count;
       
   762                 if (blendType == BlendTransformedBilinearTiled) {
       
   763                     x %= image_width;
       
   764                     if (x < 0) x += image_width;
   720                 } else {
   765                 } else {
   721                     x2 = x1 + 1;
   766                     lim = qMin(count, image_x2-x+1);
       
   767                     if (x < image_x1) {
       
   768                         Q_ASSERT(x <= image_x2);
       
   769                         uint t = fetch(s1, image_x1, data->texture.colorTable);
       
   770                         uint b = fetch(s2, image_x1, data->texture.colorTable);
       
   771                         quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
       
   772                         quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
       
   773                         do {
       
   774                             intermediate_buffer[0][f] = rb;
       
   775                             intermediate_buffer[1][f] = ag;
       
   776                             f++;
       
   777                             x++;
       
   778                         } while (x < image_x1 && f < lim);
       
   779                     }
   722                 }
   780                 }
   723                 if (y1 < image_y1) {
   781 
   724                     y2 = y1 = image_y1;
   782 #if defined(QT_ALWAYS_HAVE_SSE2)
   725                 } else if (y1 >= image_y2 - 1) {
   783                 if (blendType != BlendTransformedBilinearTiled &&
   726                     y2 = y1 = image_y2 - 1;
   784                         (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
   727                 } else {
   785 
   728                     y2 = y1 + 1;
   786                     const __m128i disty_ = _mm_set1_epi16(disty);
       
   787                     const __m128i idisty_ = _mm_set1_epi16(idisty);
       
   788                     const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
       
   789 
       
   790                     lim -= 3;
       
   791                     for (; f < lim; x += 4, f += 4) {
       
   792                         // Load 4 pixels from s1, and split the alpha-green and red-blue component
       
   793                         __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x));
       
   794                         __m128i topAG = _mm_srli_epi16(top, 8);
       
   795                         __m128i topRB = _mm_and_si128(top, colorMask);
       
   796                         // Multiplies each colour component by idisty
       
   797                         topAG = _mm_mullo_epi16 (topAG, idisty_);
       
   798                         topRB = _mm_mullo_epi16 (topRB, idisty_);
       
   799 
       
   800                         // Same for the s2 vector
       
   801                         __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x));
       
   802                         __m128i bottomAG = _mm_srli_epi16(bottom, 8);
       
   803                         __m128i bottomRB = _mm_and_si128(bottom, colorMask);
       
   804                         bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
       
   805                         bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
       
   806 
       
   807                         // Add the values, and shift to only keep 8 significant bits per colors
       
   808                         __m128i rAG =_mm_add_epi16(topAG, bottomAG);
       
   809                         rAG = _mm_srli_epi16(rAG, 8);
       
   810                         _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG);
       
   811                         __m128i rRB =_mm_add_epi16(topRB, bottomRB);
       
   812                         rRB = _mm_srli_epi16(rRB, 8);
       
   813                         _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB);
       
   814                     }
       
   815                 }
       
   816 #endif
       
   817                 for (; f < count; f++) { // Same as above but without sse2
       
   818                     if (blendType == BlendTransformedBilinearTiled) {
       
   819                         if (x >= image_width) x -= image_width;
       
   820                     } else {
       
   821                         x = qMin(x, image_x2);
       
   822                     }
       
   823 
       
   824                     uint t = fetch(s1, x, data->texture.colorTable);
       
   825                     uint b = fetch(s2, x, data->texture.colorTable);
       
   826 
       
   827                     intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
       
   828                     intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
       
   829                     x++;
       
   830                 }
       
   831                 // Now interpolate the values from the intermediate_buffer to get the final result.
       
   832                 fx &= fixed_scale - 1;
       
   833                 Q_ASSERT((fx >> 16) == 0);
       
   834                 while (b < end) {
       
   835                     register int x1 = (fx >> 16);
       
   836                     register int x2 = x1 + 1;
       
   837                     Q_ASSERT(x1 >= 0);
       
   838                     Q_ASSERT(x2 < count);
       
   839 
       
   840                     register int distx = (fx & 0x0000ffff) >> 8;
       
   841                     register int idistx = 256 - distx;
       
   842                     int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff;
       
   843                     int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00;
       
   844                     *b = rb | ag;
       
   845                     b++;
       
   846                     fx += fdx;
       
   847                 }
       
   848             } else if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
       
   849                 int y1 = (fy >> 16);
       
   850                 int y2;
       
   851                 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
       
   852                 const uchar *s1 = data->texture.scanLine(y1);
       
   853                 const uchar *s2 = data->texture.scanLine(y2);
       
   854                 int disty = (fy & 0x0000ffff) >> 8;
       
   855                 int idisty = 256 - disty;
       
   856                 while (b < end) {
       
   857                     int x1 = (fx >> 16);
       
   858                     int x2;
       
   859                     fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
       
   860                     uint tl = fetch(s1, x1, data->texture.colorTable);
       
   861                     uint tr = fetch(s1, x2, data->texture.colorTable);
       
   862                     uint bl = fetch(s2, x1, data->texture.colorTable);
       
   863                     uint br = fetch(s2, x2, data->texture.colorTable);
       
   864 
       
   865                     int distx = (fx & 0x0000ffff) >> 8;
       
   866                     int idistx = 256 - distx;
       
   867 
       
   868                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
       
   869                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
       
   870                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
       
   871 
       
   872                     fx += fdx;
       
   873                     ++b;
       
   874                 }
       
   875             } else { //scale down
       
   876                 int y1 = (fy >> 16);
       
   877                 int y2;
       
   878                 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
       
   879                 const uchar *s1 = data->texture.scanLine(y1);
       
   880                 const uchar *s2 = data->texture.scanLine(y2);
       
   881                 int disty = (fy & 0x0000ffff) >> 12;
       
   882                 int idisty = 16 - disty;
       
   883                 while (b < end) {
       
   884                     int x1 = (fx >> 16);
       
   885                     int x2;
       
   886                     fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
       
   887                     uint tl = fetch(s1, x1, data->texture.colorTable);
       
   888                     uint tr = fetch(s1, x2, data->texture.colorTable);
       
   889                     uint bl = fetch(s2, x1, data->texture.colorTable);
       
   890                     uint br = fetch(s2, x2, data->texture.colorTable);
       
   891                     int distx = (fx & 0x0000ffff) >> 12;
       
   892                     int idistx = 16 - distx;
       
   893                     *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty, idistx, idisty);
       
   894                     fx += fdx;
       
   895                     ++b;
   729                 }
   896                 }
   730             }
   897             }
   731 
   898         } else { //rotation
   732             Q_ASSERT(x1 >= 0 && x1 < image_width);
   899             if (fabs(data->m11) > 8 || fabs(data->m22) > 8) {
   733             Q_ASSERT(x2 >= 0 && x2 < image_width);
   900                 //if we are zooming more than 8 times, we use 8bit precision for the position.
   734             Q_ASSERT(y1 >= 0 && y1 < image_height);
   901                 while (b < end) {
   735             Q_ASSERT(y2 >= 0 && y2 < image_height);
   902                     int x1 = (fx >> 16);
   736 
   903                     int x2;
   737             const uchar *s1 = data->texture.scanLine(y1);
   904                     int y1 = (fy >> 16);
   738             const uchar *s2 = data->texture.scanLine(y2);
   905                     int y2;
   739 
   906 
   740             uint tl = fetch(s1, x1, data->texture.colorTable);
   907                     fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
   741             uint tr = fetch(s1, x2, data->texture.colorTable);
   908                     fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
   742             uint bl = fetch(s2, x1, data->texture.colorTable);
   909 
   743             uint br = fetch(s2, x2, data->texture.colorTable);
   910                     const uchar *s1 = data->texture.scanLine(y1);
   744 
   911                     const uchar *s2 = data->texture.scanLine(y2);
   745             int distx = (fx & 0x0000ffff) >> 8;
   912 
   746             int disty = (fy & 0x0000ffff) >> 8;
   913                     uint tl = fetch(s1, x1, data->texture.colorTable);
   747             int idistx = 256 - distx;
   914                     uint tr = fetch(s1, x2, data->texture.colorTable);
   748             int idisty = 256 - disty;
   915                     uint bl = fetch(s2, x1, data->texture.colorTable);
   749 
   916                     uint br = fetch(s2, x2, data->texture.colorTable);
   750             uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
   917 
   751             uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
   918                     int distx = (fx & 0x0000ffff) >> 8;
   752             *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
   919                     int disty = (fy & 0x0000ffff) >> 8;
   753 
   920                     int idistx = 256 - distx;
   754             fx += fdx;
   921                     int idisty = 256 - disty;
   755             fy += fdy;
   922 
   756             ++b;
   923                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
       
   924                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
       
   925                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
       
   926 
       
   927                     fx += fdx;
       
   928                     fy += fdy;
       
   929                     ++b;
       
   930                 }
       
   931             } else {
       
   932                 //we are zooming less than 8x, use 4bit precision
       
   933                 while (b < end) {
       
   934                     int x1 = (fx >> 16);
       
   935                     int x2;
       
   936                     int y1 = (fy >> 16);
       
   937                     int y2;
       
   938 
       
   939                     fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
       
   940                     fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
       
   941 
       
   942                     const uchar *s1 = data->texture.scanLine(y1);
       
   943                     const uchar *s2 = data->texture.scanLine(y2);
       
   944 
       
   945                     uint tl = fetch(s1, x1, data->texture.colorTable);
       
   946                     uint tr = fetch(s1, x2, data->texture.colorTable);
       
   947                     uint bl = fetch(s2, x1, data->texture.colorTable);
       
   948                     uint br = fetch(s2, x2, data->texture.colorTable);
       
   949 
       
   950                     int distx = (fx & 0x0000ffff) >> 12;
       
   951                     int disty = (fy & 0x0000ffff) >> 12;
       
   952                     int idistx = 16 - distx;
       
   953                     int idisty = 16 - disty;
       
   954 
       
   955                     *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty, idistx, idisty);
       
   956 
       
   957                     fx += fdx;
       
   958                     fy += fdy;
       
   959                     ++b;
       
   960                 }
       
   961             }
   757         }
   962         }
   758     } else {
   963     } else {
   759         const qreal fdx = data->m11;
   964         const qreal fdx = data->m11;
   760         const qreal fdy = data->m12;
   965         const qreal fdy = data->m12;
   761         const qreal fdw = data->m13;
   966         const qreal fdw = data->m13;
   777             int distx = int((px - x1) * 256);
   982             int distx = int((px - x1) * 256);
   778             int disty = int((py - y1) * 256);
   983             int disty = int((py - y1) * 256);
   779             int idistx = 256 - distx;
   984             int idistx = 256 - distx;
   780             int idisty = 256 - disty;
   985             int idisty = 256 - disty;
   781 
   986 
   782             if (blendType == BlendTransformedBilinearTiled) {
   987             fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
   783                 x1 %= image_width;
   988             fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
   784                 if (x1 < 0) x1 += image_width;
       
   785                 x2 = x1 + 1;
       
   786                 x2 %= image_width;
       
   787 
       
   788                 y1 %= image_height;
       
   789                 if (y1 < 0) y1 += image_height;
       
   790                 y2 = y1 + 1;
       
   791                 y2 %= image_height;
       
   792             } else {
       
   793                 if (x1 < 0) {
       
   794                     x2 = x1 = 0;
       
   795                 } else if (x1 >= image_width - 1) {
       
   796                     x2 = x1 = image_width - 1;
       
   797                 } else {
       
   798                     x2 = x1 + 1;
       
   799                 }
       
   800                 if (y1 < 0) {
       
   801                     y2 = y1 = 0;
       
   802                 } else if (y1 >= image_height - 1) {
       
   803                     y2 = y1 = image_height - 1;
       
   804                 } else {
       
   805                     y2 = y1 + 1;
       
   806                 }
       
   807             }
       
   808 
       
   809             Q_ASSERT(x1 >= 0 && x1 < image_width);
       
   810             Q_ASSERT(x2 >= 0 && x2 < image_width);
       
   811             Q_ASSERT(y1 >= 0 && y1 < image_height);
       
   812             Q_ASSERT(y2 >= 0 && y2 < image_height);
       
   813 
   989 
   814             const uchar *s1 = data->texture.scanLine(y1);
   990             const uchar *s1 = data->texture.scanLine(y1);
   815             const uchar *s2 = data->texture.scanLine(y2);
   991             const uchar *s2 = data->texture.scanLine(y2);
   816 
   992 
   817             uint tl = fetch(s1, x1, data->texture.colorTable);
   993             uint tl = fetch(s1, x1, data->texture.colorTable);
  1307             dest[i] = BYTE_MUL(dest[i], ialpha);\
  1483             dest[i] = BYTE_MUL(dest[i], ialpha);\
  1308         }\
  1484         }\
  1309     }\
  1485     }\
  1310 }
  1486 }
  1311 
  1487 
  1312 static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
  1488 void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
  1313 {
  1489 {
  1314     comp_func_Clear_impl(dest, length, const_alpha);
  1490     comp_func_Clear_impl(dest, length, const_alpha);
  1315 }
  1491 }
  1316 
  1492 
  1317 static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
  1493 void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
  1318 {
  1494 {
  1319     comp_func_Clear_impl(dest, length, const_alpha);
  1495     comp_func_Clear_impl(dest, length, const_alpha);
  1320 }
  1496 }
  1321 
  1497 
  1322 /*
  1498 /*
  1323   result = s
  1499   result = s
  1324   dest = s * ca + d * cia
  1500   dest = s * ca + d * cia
  1325 */
  1501 */
  1326 static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
  1502 void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
  1327 {
  1503 {
  1328     if (const_alpha == 255) {
  1504     if (const_alpha == 255) {
  1329         QT_MEMFILL_UINT(dest, length, color);
  1505         QT_MEMFILL_UINT(dest, length, color);
  1330     } else {
  1506     } else {
  1331         int ialpha = 255 - const_alpha;
  1507         int ialpha = 255 - const_alpha;
  1336             dest[i] = color + BYTE_MUL(dest[i], ialpha);
  1512             dest[i] = color + BYTE_MUL(dest[i], ialpha);
  1337         }
  1513         }
  1338     }
  1514     }
  1339 }
  1515 }
  1340 
  1516 
  1341 static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
  1517 void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
  1342 {
  1518 {
  1343     if (const_alpha == 255) {
  1519     if (const_alpha == 255) {
  1344         ::memcpy(dest, src, length * sizeof(uint));
  1520         ::memcpy(dest, src, length * sizeof(uint));
  1345     } else {
  1521     } else {
  1346         int ialpha = 255 - const_alpha;
  1522         int ialpha = 255 - const_alpha;
  1350             dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha);
  1526             dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha);
  1351         }
  1527         }
  1352     }
  1528     }
  1353 }
  1529 }
  1354 
  1530 
  1355 static void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
  1531 void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
  1356 {
  1532 {
  1357 }
  1533 }
  1358 
  1534 
  1359 static void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
  1535 void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
  1360 {
  1536 {
  1361 }
  1537 }
  1362 
  1538 
  1363 /*
  1539 /*
  1364   result = s + d * sia
  1540   result = s + d * sia
  1365   dest = (s + d * sia) * ca + d * cia
  1541   dest = (s + d * sia) * ca + d * cia
  1366        = s * ca + d * (sia * ca + cia)
  1542        = s * ca + d * (sia * ca + cia)
  1367        = s * ca + d * (1 - sa*ca)
  1543        = s * ca + d * (1 - sa*ca)
  1368 */
  1544 */
  1369 static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
  1545 void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
  1370 {
  1546 {
  1371     if ((const_alpha & qAlpha(color)) == 255) {
  1547     if ((const_alpha & qAlpha(color)) == 255) {
  1372         QT_MEMFILL_UINT(dest, length, color);
  1548         QT_MEMFILL_UINT(dest, length, color);
  1373     } else {
  1549     } else {
  1374         if (const_alpha != 255)
  1550         if (const_alpha != 255)
  1379             dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color));
  1555             dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color));
  1380         }
  1556         }
  1381     }
  1557     }
  1382 }
  1558 }
  1383 
  1559 
  1384 static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
  1560 void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
  1385 {
  1561 {
  1386     PRELOAD_INIT2(dest, src)
  1562     PRELOAD_INIT2(dest, src)
  1387     if (const_alpha == 255) {
  1563     if (const_alpha == 255) {
  1388         for (int i = 0; i < length; ++i) {
  1564         for (int i = 0; i < length; ++i) {
  1389             PRELOAD_COND2(dest, src)
  1565             PRELOAD_COND2(dest, src)
  1405 /*
  1581 /*
  1406   result = d + s * dia
  1582   result = d + s * dia
  1407   dest = (d + s * dia) * ca + d * cia
  1583   dest = (d + s * dia) * ca + d * cia
  1408        = d + s * dia * ca
  1584        = d + s * dia * ca
  1409 */
  1585 */
  1410 static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
  1586 void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
  1411 {
  1587 {
  1412     if (const_alpha != 255)
  1588     if (const_alpha != 255)
  1413         color = BYTE_MUL(color, const_alpha);
  1589         color = BYTE_MUL(color, const_alpha);
  1414     PRELOAD_INIT(dest)
  1590     PRELOAD_INIT(dest)
  1415     for (int i = 0; i < length; ++i) {
  1591     for (int i = 0; i < length; ++i) {
  1417         uint d = dest[i];
  1593         uint d = dest[i];
  1418         dest[i] = d + BYTE_MUL(color, qAlpha(~d));
  1594         dest[i] = d + BYTE_MUL(color, qAlpha(~d));
  1419     }
  1595     }
  1420 }
  1596 }
  1421 
  1597 
  1422 static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
  1598 void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
  1423 {
  1599 {
  1424     PRELOAD_INIT2(dest, src)
  1600     PRELOAD_INIT2(dest, src)
  1425     if (const_alpha == 255) {
  1601     if (const_alpha == 255) {
  1426         for (int i = 0; i < length; ++i) {
  1602         for (int i = 0; i < length; ++i) {
  1427             PRELOAD_COND2(dest, src)
  1603             PRELOAD_COND2(dest, src)
  1440 
  1616 
  1441 /*
  1617 /*
  1442   result = s * da
  1618   result = s * da
  1443   dest = s * da * ca + d * cia
  1619   dest = s * da * ca + d * cia
  1444 */
  1620 */
  1445 static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
  1621 void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
  1446 {
  1622 {
  1447     PRELOAD_INIT(dest)
  1623     PRELOAD_INIT(dest)
  1448     if (const_alpha == 255) {
  1624     if (const_alpha == 255) {
  1449         for (int i = 0; i < length; ++i) {
  1625         for (int i = 0; i < length; ++i) {
  1450             PRELOAD_COND(dest)
  1626             PRELOAD_COND(dest)
  1459             dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia);
  1635             dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia);
  1460         }
  1636         }
  1461     }
  1637     }
  1462 }
  1638 }
  1463 
  1639 
  1464 static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
  1640 void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
  1465 {
  1641 {
  1466     PRELOAD_INIT2(dest, src)
  1642     PRELOAD_INIT2(dest, src)
  1467     if (const_alpha == 255) {
  1643     if (const_alpha == 255) {
  1468         for (int i = 0; i < length; ++i) {
  1644         for (int i = 0; i < length; ++i) {
  1469             PRELOAD_COND2(dest, src)
  1645             PRELOAD_COND2(dest, src)
  1483 /*
  1659 /*
  1484   result = d * sa
  1660   result = d * sa
  1485   dest = d * sa * ca + d * cia
  1661   dest = d * sa * ca + d * cia
  1486        = d * (sa * ca + cia)
  1662        = d * (sa * ca + cia)
  1487 */
  1663 */
  1488 static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
  1664 void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
  1489 {
  1665 {
  1490     uint a = qAlpha(color);
  1666     uint a = qAlpha(color);
  1491     if (const_alpha != 255) {
  1667     if (const_alpha != 255) {
  1492         a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
  1668         a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
  1493     }
  1669     }
  1496         PRELOAD_COND(dest)
  1672         PRELOAD_COND(dest)
  1497         dest[i] = BYTE_MUL(dest[i], a);
  1673         dest[i] = BYTE_MUL(dest[i], a);
  1498     }
  1674     }
  1499 }
  1675 }
  1500 
  1676 
  1501 static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
  1677 void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
  1502 {
  1678 {
  1503     PRELOAD_INIT2(dest, src)
  1679     PRELOAD_INIT2(dest, src)
  1504     if (const_alpha == 255) {
  1680     if (const_alpha == 255) {
  1505         for (int i = 0; i < length; ++i) {
  1681         for (int i = 0; i < length; ++i) {
  1506             PRELOAD_COND2(dest, src)
  1682             PRELOAD_COND2(dest, src)
  1519 /*
  1695 /*
  1520   result = s * dia
  1696   result = s * dia
  1521   dest = s * dia * ca + d * cia
  1697   dest = s * dia * ca + d * cia
  1522 */
  1698 */
  1523 
  1699 
  1524 static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
  1700 void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
  1525 {
  1701 {
  1526     PRELOAD_INIT(dest)
  1702     PRELOAD_INIT(dest)
  1527     if (const_alpha == 255) {
  1703     if (const_alpha == 255) {
  1528         for (int i = 0; i < length; ++i) {
  1704         for (int i = 0; i < length; ++i) {
  1529             PRELOAD_COND(dest)
  1705             PRELOAD_COND(dest)
  1538             dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia);
  1714             dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia);
  1539         }
  1715         }
  1540     }
  1716     }
  1541 }
  1717 }
  1542 
  1718 
  1543 static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
  1719 void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
  1544 {
  1720 {
  1545     PRELOAD_INIT2(dest, src)
  1721     PRELOAD_INIT2(dest, src)
  1546     if (const_alpha == 255) {
  1722     if (const_alpha == 255) {
  1547         for (int i = 0; i < length; ++i) {
  1723         for (int i = 0; i < length; ++i) {
  1548             PRELOAD_COND2(dest, src)
  1724             PRELOAD_COND2(dest, src)
  1562 /*
  1738 /*
  1563   result = d * sia
  1739   result = d * sia
  1564   dest = d * sia * ca + d * cia
  1740   dest = d * sia * ca + d * cia
  1565        = d * (sia * ca + cia)
  1741        = d * (sia * ca + cia)
  1566 */
  1742 */
  1567 static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
  1743 void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
  1568 {
  1744 {
  1569     uint a = qAlpha(~color);
  1745     uint a = qAlpha(~color);
  1570     if (const_alpha != 255)
  1746     if (const_alpha != 255)
  1571         a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
  1747         a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
  1572     PRELOAD_INIT(dest)
  1748     PRELOAD_INIT(dest)
  1574         PRELOAD_COND(dest)
  1750         PRELOAD_COND(dest)
  1575         dest[i] = BYTE_MUL(dest[i], a);
  1751         dest[i] = BYTE_MUL(dest[i], a);
  1576     }
  1752     }
  1577 }
  1753 }
  1578 
  1754 
  1579 static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
  1755 void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
  1580 {
  1756 {
  1581     PRELOAD_INIT2(dest, src)
  1757     PRELOAD_INIT2(dest, src)
  1582     if (const_alpha == 255) {
  1758     if (const_alpha == 255) {
  1583         for (int i = 0; i < length; ++i) {
  1759         for (int i = 0; i < length; ++i) {
  1584             PRELOAD_COND2(dest, src)
  1760             PRELOAD_COND2(dest, src)
  1598   result = s*da + d*sia
  1774   result = s*da + d*sia
  1599   dest = s*da*ca + d*sia*ca + d *cia
  1775   dest = s*da*ca + d*sia*ca + d *cia
  1600        = s*ca * da + d * (sia*ca + cia)
  1776        = s*ca * da + d * (sia*ca + cia)
  1601        = s*ca * da + d * (1 - sa*ca)
  1777        = s*ca * da + d * (1 - sa*ca)
  1602 */
  1778 */
  1603 static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
  1779 void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
  1604 {
  1780 {
  1605     if (const_alpha != 255) {
  1781     if (const_alpha != 255) {
  1606         color = BYTE_MUL(color, const_alpha);
  1782         color = BYTE_MUL(color, const_alpha);
  1607     }
  1783     }
  1608     uint sia = qAlpha(~color);
  1784     uint sia = qAlpha(~color);
  1611         PRELOAD_COND(dest)
  1787         PRELOAD_COND(dest)
  1612         dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia);
  1788         dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia);
  1613     }
  1789     }
  1614 }
  1790 }
  1615 
  1791 
  1616 static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
  1792 void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
  1617 {
  1793 {
  1618     PRELOAD_INIT2(dest, src)
  1794     PRELOAD_INIT2(dest, src)
  1619     if (const_alpha == 255) {
  1795     if (const_alpha == 255) {
  1620         for (int i = 0; i < length; ++i) {
  1796         for (int i = 0; i < length; ++i) {
  1621             PRELOAD_COND2(dest, src)
  1797             PRELOAD_COND2(dest, src)
  1636 /*
  1812 /*
  1637   result = d*sa + s*dia
  1813   result = d*sa + s*dia
  1638   dest = d*sa*ca + s*dia*ca + d *cia
  1814   dest = d*sa*ca + s*dia*ca + d *cia
  1639        = s*ca * dia + d * (sa*ca + cia)
  1815        = s*ca * dia + d * (sa*ca + cia)
  1640 */
  1816 */
  1641 static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
  1817 void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
  1642 {
  1818 {
  1643     uint a = qAlpha(color);
  1819     uint a = qAlpha(color);
  1644     if (const_alpha != 255) {
  1820     if (const_alpha != 255) {
  1645         color = BYTE_MUL(color, const_alpha);
  1821         color = BYTE_MUL(color, const_alpha);
  1646         a = qAlpha(color) + 255 - const_alpha;
  1822         a = qAlpha(color) + 255 - const_alpha;
  1651         uint d = dest[i];
  1827         uint d = dest[i];
  1652         dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d));
  1828         dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d));
  1653     }
  1829     }
  1654 }
  1830 }
  1655 
  1831 
  1656 static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
  1832 void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
  1657 {
  1833 {
  1658     PRELOAD_INIT2(dest, src)
  1834     PRELOAD_INIT2(dest, src)
  1659     if (const_alpha == 255) {
  1835     if (const_alpha == 255) {
  1660         for (int i = 0; i < length; ++i) {
  1836         for (int i = 0; i < length; ++i) {
  1661             PRELOAD_COND2(dest, src)
  1837             PRELOAD_COND2(dest, src)
  1679   result = d*sia + s*dia
  1855   result = d*sia + s*dia
  1680   dest = d*sia*ca + s*dia*ca + d *cia
  1856   dest = d*sia*ca + s*dia*ca + d *cia
  1681        = s*ca * dia + d * (sia*ca + cia)
  1857        = s*ca * dia + d * (sia*ca + cia)
  1682        = s*ca * dia + d * (1 - sa*ca)
  1858        = s*ca * dia + d * (1 - sa*ca)
  1683 */
  1859 */
  1684 static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
  1860 void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
  1685 {
  1861 {
  1686     if (const_alpha != 255)
  1862     if (const_alpha != 255)
  1687         color = BYTE_MUL(color, const_alpha);
  1863         color = BYTE_MUL(color, const_alpha);
  1688     uint sia = qAlpha(~color);
  1864     uint sia = qAlpha(~color);
  1689 
  1865 
  1693         uint d = dest[i];
  1869         uint d = dest[i];
  1694         dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia);
  1870         dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia);
  1695     }
  1871     }
  1696 }
  1872 }
  1697 
  1873 
  1698 static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
  1874 void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
  1699 {
  1875 {
  1700     PRELOAD_INIT2(dest, src)
  1876     PRELOAD_INIT2(dest, src)
  1701     if (const_alpha == 255) {
  1877     if (const_alpha == 255) {
  1702         for (int i = 0; i < length; ++i) {
  1878         for (int i = 0; i < length; ++i) {
  1703             PRELOAD_COND2(dest, src)
  1879             PRELOAD_COND2(dest, src)
  1713             dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
  1889             dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
  1714         }
  1890         }
  1715     }
  1891     }
  1716 }
  1892 }
  1717 
  1893 
  1718 static const uint AMASK = 0xff000000;
       
  1719 static const uint RMASK = 0x00ff0000;
       
  1720 static const uint GMASK = 0x0000ff00;
       
  1721 static const uint BMASK = 0x000000ff;
       
  1722 
       
  1723 struct QFullCoverage {
  1894 struct QFullCoverage {
  1724     inline void store(uint *dest, const uint src) const
  1895     inline void store(uint *dest, const uint src) const
  1725     {
  1896     {
  1726         *dest = src;
  1897         *dest = src;
  1727     }
  1898     }
  1760 
  1931 
  1761     PRELOAD_INIT(dest)
  1932     PRELOAD_INIT(dest)
  1762     for (int i = 0; i < length; ++i) {
  1933     for (int i = 0; i < length; ++i) {
  1763         PRELOAD_COND(dest)
  1934         PRELOAD_COND(dest)
  1764         uint d = dest[i];
  1935         uint d = dest[i];
  1765 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
  1936         d = comp_func_Plus_one_pixel(d, s);
  1766         d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
       
  1767 #undef MIX
       
  1768         coverage.store(&dest[i], d);
  1937         coverage.store(&dest[i], d);
  1769     }
  1938     }
  1770 }
  1939 }
  1771 
  1940 
  1772 static void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
  1941 void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
  1773 {
  1942 {
  1774     if (const_alpha == 255)
  1943     if (const_alpha == 255)
  1775         comp_func_solid_Plus_impl(dest, length, color, QFullCoverage());
  1944         comp_func_solid_Plus_impl(dest, length, color, QFullCoverage());
  1776     else
  1945     else
  1777         comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
  1946         comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
  1784     for (int i = 0; i < length; ++i) {
  1953     for (int i = 0; i < length; ++i) {
  1785         PRELOAD_COND2(dest, src)
  1954         PRELOAD_COND2(dest, src)
  1786         uint d = dest[i];
  1955         uint d = dest[i];
  1787         uint s = src[i];
  1956         uint s = src[i];
  1788 
  1957 
  1789 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
  1958         d = comp_func_Plus_one_pixel(d, s);
  1790         d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
       
  1791 #undef MIX
       
  1792 
  1959 
  1793         coverage.store(&dest[i], d);
  1960         coverage.store(&dest[i], d);
  1794     }
  1961     }
  1795 }
  1962 }
  1796 
  1963 
  1797 static void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
  1964 void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
  1798 {
  1965 {
  1799     if (const_alpha == 255)
  1966     if (const_alpha == 255)
  1800         comp_func_Plus_impl(dest, src, length, QFullCoverage());
  1967         comp_func_Plus_impl(dest, src, length, QFullCoverage());
  1801     else
  1968     else
  1802         comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
  1969         comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
  1833 
  2000 
  1834         coverage.store(&dest[i], qRgba(r, g, b, a));
  2001         coverage.store(&dest[i], qRgba(r, g, b, a));
  1835     }
  2002     }
  1836 }
  2003 }
  1837 
  2004 
  1838 static void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
  2005 void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
  1839 {
  2006 {
  1840     if (const_alpha == 255)
  2007     if (const_alpha == 255)
  1841         comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
  2008         comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
  1842     else
  2009     else
  1843         comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
  2010         comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
  1864 
  2031 
  1865         coverage.store(&dest[i], qRgba(r, g, b, a));
  2032         coverage.store(&dest[i], qRgba(r, g, b, a));
  1866     }
  2033     }
  1867 }
  2034 }
  1868 
  2035 
  1869 static void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
  2036 void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
  1870 {
  2037 {
  1871     if (const_alpha == 255)
  2038     if (const_alpha == 255)
  1872         comp_func_Multiply_impl(dest, src, length, QFullCoverage());
  2039         comp_func_Multiply_impl(dest, src, length, QFullCoverage());
  1873     else
  2040     else
  1874         comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
  2041         comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
  1901 
  2068 
  1902         coverage.store(&dest[i], qRgba(r, g, b, a));
  2069         coverage.store(&dest[i], qRgba(r, g, b, a));
  1903     }
  2070     }
  1904 }
  2071 }
  1905 
  2072 
  1906 static void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
  2073 void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
  1907 {
  2074 {
  1908     if (const_alpha == 255)
  2075     if (const_alpha == 255)
  1909         comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
  2076         comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
  1910     else
  2077     else
  1911         comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
  2078         comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
  1932 
  2099 
  1933         coverage.store(&dest[i], qRgba(r, g, b, a));
  2100         coverage.store(&dest[i], qRgba(r, g, b, a));
  1934     }
  2101     }
  1935 }
  2102 }
  1936 
  2103 
  1937 static void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
  2104 void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
  1938 {
  2105 {
  1939     if (const_alpha == 255)
  2106     if (const_alpha == 255)
  1940         comp_func_Screen_impl(dest, src, length, QFullCoverage());
  2107         comp_func_Screen_impl(dest, src, length, QFullCoverage());
  1941     else
  2108     else
  1942         comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
  2109         comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
  1980 
  2147 
  1981         coverage.store(&dest[i], qRgba(r, g, b, a));
  2148         coverage.store(&dest[i], qRgba(r, g, b, a));
  1982     }
  2149     }
  1983 }
  2150 }
  1984 
  2151 
  1985 static void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
  2152 void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
  1986 {
  2153 {
  1987     if (const_alpha == 255)
  2154     if (const_alpha == 255)
  1988         comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
  2155         comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
  1989     else
  2156     else
  1990         comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
  2157         comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
  2011 
  2178 
  2012         coverage.store(&dest[i], qRgba(r, g, b, a));
  2179         coverage.store(&dest[i], qRgba(r, g, b, a));
  2013     }
  2180     }
  2014 }
  2181 }
  2015 
  2182 
  2016 static void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
  2183 void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
  2017 {
  2184 {
  2018     if (const_alpha == 255)
  2185     if (const_alpha == 255)
  2019         comp_func_Overlay_impl(dest, src, length, QFullCoverage());
  2186         comp_func_Overlay_impl(dest, src, length, QFullCoverage());
  2020     else
  2187     else
  2021         comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
  2188         comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
  2053 
  2220 
  2054         coverage.store(&dest[i], qRgba(r, g, b, a));
  2221         coverage.store(&dest[i], qRgba(r, g, b, a));
  2055     }
  2222     }
  2056 }
  2223 }
  2057 
  2224 
  2058 static void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
  2225 void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
  2059 {
  2226 {
  2060     if (const_alpha == 255)
  2227     if (const_alpha == 255)
  2061         comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
  2228         comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
  2062     else
  2229     else
  2063         comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
  2230         comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
  2084 
  2251 
  2085         coverage.store(&dest[i], qRgba(r, g, b, a));
  2252         coverage.store(&dest[i], qRgba(r, g, b, a));
  2086     }
  2253     }
  2087 }
  2254 }
  2088 
  2255 
  2089 static void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
  2256 void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
  2090 {
  2257 {
  2091     if (const_alpha == 255)
  2258     if (const_alpha == 255)
  2092         comp_func_Darken_impl(dest, src, length, QFullCoverage());
  2259         comp_func_Darken_impl(dest, src, length, QFullCoverage());
  2093     else
  2260     else
  2094         comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
  2261         comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
  2126 
  2293 
  2127         coverage.store(&dest[i], qRgba(r, g, b, a));
  2294         coverage.store(&dest[i], qRgba(r, g, b, a));
  2128     }
  2295     }
  2129 }
  2296 }
  2130 
  2297 
  2131 static void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
  2298 void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
  2132 {
  2299 {
  2133     if (const_alpha == 255)
  2300     if (const_alpha == 255)
  2134         comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
  2301         comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
  2135     else
  2302     else
  2136         comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
  2303         comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
  2157 
  2324 
  2158         coverage.store(&dest[i], qRgba(r, g, b, a));
  2325         coverage.store(&dest[i], qRgba(r, g, b, a));
  2159     }
  2326     }
  2160 }
  2327 }
  2161 
  2328 
  2162 static void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
  2329 void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
  2163 {
  2330 {
  2164     if (const_alpha == 255)
  2331     if (const_alpha == 255)
  2165         comp_func_Lighten_impl(dest, src, length, QFullCoverage());
  2332         comp_func_Lighten_impl(dest, src, length, QFullCoverage());
  2166     else
  2333     else
  2167         comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
  2334         comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
  2209 
  2376 
  2210         coverage.store(&dest[i], qRgba(r, g, b, a));
  2377         coverage.store(&dest[i], qRgba(r, g, b, a));
  2211     }
  2378     }
  2212 }
  2379 }
  2213 
  2380 
  2214 static void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
  2381 void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
  2215 {
  2382 {
  2216     if (const_alpha == 255)
  2383     if (const_alpha == 255)
  2217         comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
  2384         comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
  2218     else
  2385     else
  2219         comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
  2386         comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
  2240 
  2407 
  2241         coverage.store(&dest[i], qRgba(r, g, b, a));
  2408         coverage.store(&dest[i], qRgba(r, g, b, a));
  2242     }
  2409     }
  2243 }
  2410 }
  2244 
  2411 
  2245 static void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
  2412 void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
  2246 {
  2413 {
  2247     if (const_alpha == 255)
  2414     if (const_alpha == 255)
  2248         comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
  2415         comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
  2249     else
  2416     else
  2250         comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
  2417         comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
  2292 
  2459 
  2293         coverage.store(&dest[i], qRgba(r, g, b, a));
  2460         coverage.store(&dest[i], qRgba(r, g, b, a));
  2294     }
  2461     }
  2295 }
  2462 }
  2296 
  2463 
  2297 static void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
  2464 void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
  2298 {
  2465 {
  2299     if (const_alpha == 255)
  2466     if (const_alpha == 255)
  2300         comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
  2467         comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
  2301     else
  2468     else
  2302         comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
  2469         comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
  2323 
  2490 
  2324         coverage.store(&dest[i], qRgba(r, g, b, a));
  2491         coverage.store(&dest[i], qRgba(r, g, b, a));
  2325     }
  2492     }
  2326 }
  2493 }
  2327 
  2494 
  2328 static void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
  2495 void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
  2329 {
  2496 {
  2330     if (const_alpha == 255)
  2497     if (const_alpha == 255)
  2331         comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
  2498         comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
  2332     else
  2499     else
  2333         comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
  2500         comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
  2372 
  2539 
  2373         coverage.store(&dest[i], qRgba(r, g, b, a));
  2540         coverage.store(&dest[i], qRgba(r, g, b, a));
  2374     }
  2541     }
  2375 }
  2542 }
  2376 
  2543 
  2377 static void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
  2544 void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
  2378 {
  2545 {
  2379     if (const_alpha == 255)
  2546     if (const_alpha == 255)
  2380         comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
  2547         comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
  2381     else
  2548     else
  2382         comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
  2549         comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
  2403 
  2570 
  2404         coverage.store(&dest[i], qRgba(r, g, b, a));
  2571         coverage.store(&dest[i], qRgba(r, g, b, a));
  2405     }
  2572     }
  2406 }
  2573 }
  2407 
  2574 
  2408 static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
  2575 void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
  2409 {
  2576 {
  2410     if (const_alpha == 255)
  2577     if (const_alpha == 255)
  2411         comp_func_HardLight_impl(dest, src, length, QFullCoverage());
  2578         comp_func_HardLight_impl(dest, src, length, QFullCoverage());
  2412     else
  2579     else
  2413         comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
  2580         comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
  2463 
  2630 
  2464         coverage.store(&dest[i], qRgba(r, g, b, a));
  2631         coverage.store(&dest[i], qRgba(r, g, b, a));
  2465     }
  2632     }
  2466 }
  2633 }
  2467 
  2634 
  2468 static void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
  2635 void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
  2469 {
  2636 {
  2470     if (const_alpha == 255)
  2637     if (const_alpha == 255)
  2471         comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
  2638         comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
  2472     else
  2639     else
  2473         comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
  2640         comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
  2494 
  2661 
  2495         coverage.store(&dest[i], qRgba(r, g, b, a));
  2662         coverage.store(&dest[i], qRgba(r, g, b, a));
  2496     }
  2663     }
  2497 }
  2664 }
  2498 
  2665 
  2499 static void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
  2666 void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
  2500 {
  2667 {
  2501     if (const_alpha == 255)
  2668     if (const_alpha == 255)
  2502         comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
  2669         comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
  2503     else
  2670     else
  2504         comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
  2671         comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
  2536 
  2703 
  2537         coverage.store(&dest[i], qRgba(r, g, b, a));
  2704         coverage.store(&dest[i], qRgba(r, g, b, a));
  2538     }
  2705     }
  2539 }
  2706 }
  2540 
  2707 
  2541 static void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
  2708 void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
  2542 {
  2709 {
  2543     if (const_alpha == 255)
  2710     if (const_alpha == 255)
  2544         comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
  2711         comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
  2545     else
  2712     else
  2546         comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
  2713         comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
  2567 
  2734 
  2568         coverage.store(&dest[i], qRgba(r, g, b, a));
  2735         coverage.store(&dest[i], qRgba(r, g, b, a));
  2569     }
  2736     }
  2570 }
  2737 }
  2571 
  2738 
  2572 static void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
  2739 void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
  2573 {
  2740 {
  2574     if (const_alpha == 255)
  2741     if (const_alpha == 255)
  2575         comp_func_Difference_impl(dest, src, length, QFullCoverage());
  2742         comp_func_Difference_impl(dest, src, length, QFullCoverage());
  2576     else
  2743     else
  2577         comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
  2744         comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
  2603 
  2770 
  2604         coverage.store(&dest[i], qRgba(r, g, b, a));
  2771         coverage.store(&dest[i], qRgba(r, g, b, a));
  2605     }
  2772     }
  2606 }
  2773 }
  2607 
  2774 
  2608 static void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
  2775 void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
  2609 {
  2776 {
  2610     if (const_alpha == 255)
  2777     if (const_alpha == 255)
  2611         comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
  2778         comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
  2612     else
  2779     else
  2613         comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
  2780         comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
  2634 
  2801 
  2635         coverage.store(&dest[i], qRgba(r, g, b, a));
  2802         coverage.store(&dest[i], qRgba(r, g, b, a));
  2636     }
  2803     }
  2637 }
  2804 }
  2638 
  2805 
  2639 static void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
  2806 void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
  2640 {
  2807 {
  2641     if (const_alpha == 255)
  2808     if (const_alpha == 255)
  2642         comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
  2809         comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
  2643     else
  2810     else
  2644         comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
  2811         comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
  2647 #if defined(Q_CC_RVCT)
  2814 #if defined(Q_CC_RVCT)
  2648 // Restore pragma state from previous #pragma arm
  2815 // Restore pragma state from previous #pragma arm
  2649 #  pragma pop
  2816 #  pragma pop
  2650 #endif
  2817 #endif
  2651 
  2818 
  2652 static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
  2819 void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
  2653                                                            int length,
  2820                                                     int length,
  2654                                                            uint color,
  2821                                                     uint color,
  2655                                                            uint const_alpha)
  2822                                                     uint const_alpha)
  2656 {
  2823 {
  2657     Q_UNUSED(const_alpha);
  2824     Q_UNUSED(const_alpha);
  2658     while (length--)
  2825     while (length--)
  2659         *dest++ |= color;
  2826         *dest++ |= color;
  2660 }
  2827 }
  2661 
  2828 
  2662 static void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
  2829 void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
  2663                                                      const uint *src,
  2830                                               const uint *src,
  2664                                                      int length,
  2831                                               int length,
  2665                                                      uint const_alpha)
  2832                                               uint const_alpha)
  2666 {
  2833 {
  2667     Q_UNUSED(const_alpha);
  2834     Q_UNUSED(const_alpha);
  2668     while (length--)
  2835     while (length--)
  2669         *dest++ |= *src++;
  2836         *dest++ |= *src++;
  2670 }
  2837 }
  2671 
  2838 
  2672 static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
  2839 void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
  2673                                                             int length,
  2840                                                      int length,
  2674                                                             uint color,
  2841                                                      uint color,
  2675                                                             uint const_alpha)
  2842                                                      uint const_alpha)
  2676 {
  2843 {
  2677     Q_UNUSED(const_alpha);
  2844     Q_UNUSED(const_alpha);
  2678     color |= 0xff000000;
  2845     color |= 0xff000000;
  2679     while (length--)
  2846     while (length--)
  2680         *dest++ &= color;
  2847         *dest++ &= color;
  2681 }
  2848 }
  2682 
  2849 
  2683 static void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
  2850 void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
  2684                                                       const uint *src,
  2851                                                const uint *src,
  2685                                                       int length,
  2852                                                int length,
  2686                                                       uint const_alpha)
  2853                                                uint const_alpha)
  2687 {
  2854 {
  2688     Q_UNUSED(const_alpha);
  2855     Q_UNUSED(const_alpha);
  2689     while (length--) {
  2856     while (length--) {
  2690         *dest = (*src & *dest) | 0xff000000;
  2857         *dest = (*src & *dest) | 0xff000000;
  2691         ++dest; ++src;
  2858         ++dest; ++src;
  2692     }
  2859     }
  2693 }
  2860 }
  2694 
  2861 
  2695 static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
  2862 void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
  2696                                                             int length,
  2863                                                      int length,
  2697                                                             uint color,
  2864                                                      uint color,
  2698                                                             uint const_alpha)
  2865                                                      uint const_alpha)
  2699 {
  2866 {
  2700     Q_UNUSED(const_alpha);
  2867     Q_UNUSED(const_alpha);
  2701     color &= 0x00ffffff;
  2868     color &= 0x00ffffff;
  2702     while (length--)
  2869     while (length--)
  2703         *dest++ ^= color;
  2870         *dest++ ^= color;
  2704 }
  2871 }
  2705 
  2872 
  2706 static void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
  2873 void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
  2707                                                       const uint *src,
  2874                                                const uint *src,
  2708                                                       int length,
  2875                                                int length,
  2709                                                       uint const_alpha)
  2876                                                uint const_alpha)
  2710 {
  2877 {
  2711     Q_UNUSED(const_alpha);
  2878     Q_UNUSED(const_alpha);
  2712     while (length--) {
  2879     while (length--) {
  2713         *dest = (*src ^ *dest) | 0xff000000;
  2880         *dest = (*src ^ *dest) | 0xff000000;
  2714         ++dest; ++src;
  2881         ++dest; ++src;
  2715     }
  2882     }
  2716 }
  2883 }
  2717 
  2884 
  2718 static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
  2885 void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
  2719                                                                   int length,
  2886                                                            int length,
  2720                                                                   uint color,
  2887                                                            uint color,
  2721                                                                   uint const_alpha)
  2888                                                            uint const_alpha)
  2722 {
  2889 {
  2723     Q_UNUSED(const_alpha);
  2890     Q_UNUSED(const_alpha);
  2724     color = ~color;
  2891     color = ~color;
  2725     while (length--) {
  2892     while (length--) {
  2726         *dest = (color & ~(*dest)) | 0xff000000;
  2893         *dest = (color & ~(*dest)) | 0xff000000;
  2727         ++dest;
  2894         ++dest;
  2728     }
  2895     }
  2729 }
  2896 }
  2730 
  2897 
  2731 static void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
  2898 void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
  2732                                                             const uint *src,
  2899                                                      const uint *src,
  2733                                                             int length,
  2900                                                      int length,
  2734                                                             uint const_alpha)
  2901                                                      uint const_alpha)
  2735 {
  2902 {
  2736     Q_UNUSED(const_alpha);
  2903     Q_UNUSED(const_alpha);
  2737     while (length--) {
  2904     while (length--) {
  2738         *dest = (~(*src) & ~(*dest)) | 0xff000000;
  2905         *dest = (~(*src) & ~(*dest)) | 0xff000000;
  2739         ++dest; ++src;
  2906         ++dest; ++src;
  2740     }
  2907     }
  2741 }
  2908 }
  2742 
  2909 
  2743 static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
  2910 void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
  2744                                                                  int length,
  2911                                                           int length,
  2745                                                                  uint color,
  2912                                                           uint color,
  2746                                                                  uint const_alpha)
  2913                                                           uint const_alpha)
  2747 {
  2914 {
  2748     Q_UNUSED(const_alpha);
  2915     Q_UNUSED(const_alpha);
  2749     color = ~color | 0xff000000;
  2916     color = ~color | 0xff000000;
  2750     while (length--) {
  2917     while (length--) {
  2751         *dest = color | ~(*dest);
  2918         *dest = color | ~(*dest);
  2752         ++dest;
  2919         ++dest;
  2753     }
  2920     }
  2754 }
  2921 }
  2755 
  2922 
  2756 static void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
  2923 void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
  2757                                                            const uint *src,
  2924                                                     const uint *src,
  2758                                                            int length,
  2925                                                     int length,
  2759                                                            uint const_alpha)
  2926                                                     uint const_alpha)
  2760 {
  2927 {
  2761     Q_UNUSED(const_alpha);
  2928     Q_UNUSED(const_alpha);
  2762     while (length--) {
  2929     while (length--) {
  2763         *dest = ~(*src) | ~(*dest) | 0xff000000;
  2930         *dest = ~(*src) | ~(*dest) | 0xff000000;
  2764         ++dest; ++src;
  2931         ++dest; ++src;
  2765     }
  2932     }
  2766 }
  2933 }
  2767 
  2934 
  2768 static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
  2935 void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
  2769                                                                int length,
  2936                                                         int length,
  2770                                                                uint color,
  2937                                                         uint color,
  2771                                                                uint const_alpha)
  2938                                                         uint const_alpha)
  2772 {
  2939 {
  2773     Q_UNUSED(const_alpha);
  2940     Q_UNUSED(const_alpha);
  2774     color = ~color & 0x00ffffff;
  2941     color = ~color & 0x00ffffff;
  2775     while (length--) {
  2942     while (length--) {
  2776         *dest = color ^ (*dest);
  2943         *dest = color ^ (*dest);
  2777         ++dest;
  2944         ++dest;
  2778     }
  2945     }
  2779 }
  2946 }
  2780 
  2947 
  2781 static void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
  2948 void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
  2782                                                          const uint *src,
  2949                                                   const uint *src,
  2783                                                          int length,
  2950                                                   int length,
  2784                                                          uint const_alpha)
  2951                                                   uint const_alpha)
  2785 {
  2952 {
  2786     Q_UNUSED(const_alpha);
  2953     Q_UNUSED(const_alpha);
  2787     while (length--) {
  2954     while (length--) {
  2788         *dest = ((~(*src)) ^ (*dest)) | 0xff000000;
  2955         *dest = ((~(*src)) ^ (*dest)) | 0xff000000;
  2789         ++dest; ++src;
  2956         ++dest; ++src;
  2790     }
  2957     }
  2791 }
  2958 }
  2792 
  2959 
  2793 static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
  2960 void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
  2794                                                  uint color, uint const_alpha)
  2961                                           uint color, uint const_alpha)
  2795 {
  2962 {
  2796     Q_UNUSED(const_alpha);
  2963     Q_UNUSED(const_alpha);
  2797     qt_memfill(dest, ~color | 0xff000000, length);
  2964     qt_memfill(dest, ~color | 0xff000000, length);
  2798 }
  2965 }
  2799 
  2966 
  2800 static void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
  2967 void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
  2801                                            int length, uint const_alpha)
  2968                                     int length, uint const_alpha)
  2802 {
  2969 {
  2803     Q_UNUSED(const_alpha);
  2970     Q_UNUSED(const_alpha);
  2804     while (length--)
  2971     while (length--)
  2805         *dest++ = ~(*src++) | 0xff000000;
  2972         *dest++ = ~(*src++) | 0xff000000;
  2806 }
  2973 }
  2807 
  2974 
  2808 static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
  2975 void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
  2809                                                                int length,
  2976                                                         int length,
  2810                                                                uint color,
  2977                                                         uint color,
  2811                                                                uint const_alpha)
  2978                                                         uint const_alpha)
  2812 {
  2979 {
  2813     Q_UNUSED(const_alpha);
  2980     Q_UNUSED(const_alpha);
  2814     color = ~color | 0xff000000;
  2981     color = ~color | 0xff000000;
  2815     while (length--) {
  2982     while (length--) {
  2816         *dest = color & *dest;
  2983         *dest = color & *dest;
  2817         ++dest;
  2984         ++dest;
  2818     }
  2985     }
  2819 }
  2986 }
  2820 
  2987 
  2821 static void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
  2988 void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
  2822                                                          const uint *src,
  2989                                                   const uint *src,
  2823                                                          int length,
  2990                                                   int length,
  2824                                                          uint const_alpha)
  2991                                                   uint const_alpha)
  2825 {
  2992 {
  2826     Q_UNUSED(const_alpha);
  2993     Q_UNUSED(const_alpha);
  2827     while (length--) {
  2994     while (length--) {
  2828         *dest = (~(*src) & *dest) | 0xff000000;
  2995         *dest = (~(*src) & *dest) | 0xff000000;
  2829         ++dest; ++src;
  2996         ++dest; ++src;
  2830     }
  2997     }
  2831 }
  2998 }
  2832 
  2999 
  2833 static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
  3000 void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
  2834                                                                int length,
  3001                                                         int length,
  2835                                                                uint color,
  3002                                                         uint color,
  2836                                                                uint const_alpha)
  3003                                                         uint const_alpha)
  2837 {
  3004 {
  2838     Q_UNUSED(const_alpha);
  3005     Q_UNUSED(const_alpha);
  2839     while (length--) {
  3006     while (length--) {
  2840         *dest = (color & ~(*dest)) | 0xff000000;
  3007         *dest = (color & ~(*dest)) | 0xff000000;
  2841         ++dest;
  3008         ++dest;
  2842     }
  3009     }
  2843 }
  3010 }
  2844 
  3011 
  2845 static void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
  3012 void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
  2846                                                          const uint *src,
  3013                                                   const uint *src,
  2847                                                          int length,
  3014                                                   int length,
  2848                                                          uint const_alpha)
  3015                                                   uint const_alpha)
  2849 {
  3016 {
  2850     Q_UNUSED(const_alpha);
  3017     Q_UNUSED(const_alpha);
  2851     while (length--) {
  3018     while (length--) {
  2852         *dest = (*src & ~(*dest)) | 0xff000000;
  3019         *dest = (*src & ~(*dest)) | 0xff000000;
  2853         ++dest; ++src;
  3020         ++dest; ++src;
  5164     else if (data->texture.format == QImage::Format_RGB444)
  5331     else if (data->texture.format == QImage::Format_RGB444)
  5165         blendTiled<qrgb444, qrgb444>(count, spans, userData);
  5332         blendTiled<qrgb444, qrgb444>(count, spans, userData);
  5166     else
  5333     else
  5167 #endif
  5334 #endif
  5168         blend_tiled_generic<RegularSpans>(count, spans, userData);
  5335         blend_tiled_generic<RegularSpans>(count, spans, userData);
  5169 }
       
  5170 
       
  5171 
       
  5172 template <SpanMethod spanMethod, TextureBlendType blendType>  /* blendType must be either BlendTransformedBilinear or BlendTransformedBilinearTiled */
       
  5173 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)
       
  5174 {
       
  5175     QSpanData *data = reinterpret_cast<QSpanData *>(userData);
       
  5176     if (data->texture.format != QImage::Format_ARGB32_Premultiplied
       
  5177         && data->texture.format != QImage::Format_RGB32) {
       
  5178         blend_src_generic<spanMethod>(count, spans, userData);
       
  5179         return;
       
  5180     }
       
  5181 
       
  5182     CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
       
  5183     uint buffer[buffer_size];
       
  5184 
       
  5185     const int image_x1 = data->texture.x1;
       
  5186     const int image_y1 = data->texture.y1;
       
  5187     const int image_x2 = data->texture.x2;
       
  5188     const int image_y2 = data->texture.y2;
       
  5189     const int image_width = data->texture.width;
       
  5190     const int image_height = data->texture.height;
       
  5191     const int scanline_offset = data->texture.bytesPerLine / 4;
       
  5192 
       
  5193     if (data->fast_matrix) {
       
  5194         // The increment pr x in the scanline
       
  5195         int fdx = (int)(data->m11 * fixed_scale);
       
  5196         int fdy = (int)(data->m12 * fixed_scale);
       
  5197 
       
  5198         while (count--) {
       
  5199             void *t = data->rasterBuffer->scanLine(spans->y);
       
  5200 
       
  5201             uint *target = ((uint *)t) + spans->x;
       
  5202             uint *image_bits = (uint *)data->texture.imageData;
       
  5203 
       
  5204             const qreal cx = spans->x + 0.5;
       
  5205             const qreal cy = spans->y + 0.5;
       
  5206 
       
  5207             int x = int((data->m21 * cy
       
  5208                          + data->m11 * cx + data->dx) * fixed_scale) - half_point;
       
  5209             int y = int((data->m22 * cy
       
  5210                          + data->m12 * cx + data->dy) * fixed_scale) - half_point;
       
  5211 
       
  5212             int length = spans->len;
       
  5213             const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
       
  5214             while (length) {
       
  5215                 int l = qMin(length, buffer_size);
       
  5216                 const uint *end = buffer + l;
       
  5217                 uint *b = buffer;
       
  5218                 while (b < end) {
       
  5219                     int x1 = (x >> 16);
       
  5220                     int x2;
       
  5221                     int y1 = (y >> 16);
       
  5222                     int y2;
       
  5223 
       
  5224                     if (blendType == BlendTransformedBilinearTiled) {
       
  5225                         x1 %= image_width;
       
  5226                         if (x1 < 0) x1 += image_width;
       
  5227                         x2 = x1 + 1;
       
  5228                         x2 %= image_width;
       
  5229 
       
  5230                         y1 %= image_height;
       
  5231                         if (y1 < 0) y1 += image_height;
       
  5232                         y2 = y1 + 1;
       
  5233                         y2 %= image_height;
       
  5234 
       
  5235                         Q_ASSERT(x1 >= 0 && x1 < image_width);
       
  5236                         Q_ASSERT(x2 >= 0 && x2 < image_width);
       
  5237                         Q_ASSERT(y1 >= 0 && y1 < image_height);
       
  5238                         Q_ASSERT(y2 >= 0 && y2 < image_height);
       
  5239                     } else {
       
  5240                         if (x1 < image_x1) {
       
  5241                             x2 = x1 = image_x1;
       
  5242                         } else if (x1 >= image_x2 - 1) {
       
  5243                             x2 = x1 = image_x2 - 1;
       
  5244                         } else {
       
  5245                             x2 = x1 + 1;
       
  5246                         }
       
  5247                         if (y1 < image_y1) {
       
  5248                             y2 = y1 = image_y1;
       
  5249                         } else if (y1 >= image_y2 - 1) {
       
  5250                             y2 = y1 = image_y2 - 1;
       
  5251                         } else {
       
  5252                             y2 = y1 + 1;
       
  5253                         }
       
  5254                     }
       
  5255 
       
  5256                     int y1_offset = y1 * scanline_offset;
       
  5257                     int y2_offset = y2 * scanline_offset;
       
  5258 
       
  5259 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
       
  5260                     uint tl = gccBug(image_bits[y1_offset + x1]);
       
  5261                     uint tr = gccBug(image_bits[y1_offset + x2]);
       
  5262                     uint bl = gccBug(image_bits[y2_offset + x1]);
       
  5263                     uint br = gccBug(image_bits[y2_offset + x2]);
       
  5264 #else
       
  5265                     uint tl = image_bits[y1_offset + x1];
       
  5266                     uint tr = image_bits[y1_offset + x2];
       
  5267                     uint bl = image_bits[y2_offset + x1];
       
  5268                     uint br = image_bits[y2_offset + x2];
       
  5269 #endif
       
  5270 
       
  5271                     int distx = (x & 0x0000ffff) >> 8;
       
  5272                     int disty = (y & 0x0000ffff) >> 8;
       
  5273                     int idistx = 256 - distx;
       
  5274                     int idisty = 256 - disty;
       
  5275 
       
  5276                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
       
  5277                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
       
  5278                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
       
  5279                     ++b;
       
  5280 
       
  5281                     x += fdx;
       
  5282                     y += fdy;
       
  5283                 }
       
  5284                 if (spanMethod == RegularSpans)
       
  5285                     func(target, buffer, l, coverage);
       
  5286                 else
       
  5287                     drawBufferSpan(data, buffer, buffer_size,
       
  5288                                    spans->x + spans->len - length,
       
  5289                                    spans->y, l, coverage);
       
  5290                 target += l;
       
  5291                 length -= l;
       
  5292             }
       
  5293             ++spans;
       
  5294         }
       
  5295     } else {
       
  5296         const qreal fdx = data->m11;
       
  5297         const qreal fdy = data->m12;
       
  5298         const qreal fdw = data->m13;
       
  5299 
       
  5300         while (count--) {
       
  5301             void *t = data->rasterBuffer->scanLine(spans->y);
       
  5302 
       
  5303             uint *target = ((uint *)t) + spans->x;
       
  5304             uint *image_bits = (uint *)data->texture.imageData;
       
  5305 
       
  5306             const qreal cx = spans->x + 0.5;
       
  5307             const qreal cy = spans->y + 0.5;
       
  5308 
       
  5309             qreal x = data->m21 * cy + data->m11 * cx + data->dx;
       
  5310             qreal y = data->m22 * cy + data->m12 * cx + data->dy;
       
  5311             qreal w = data->m23 * cy + data->m13 * cx + data->m33;
       
  5312 
       
  5313             int length = spans->len;
       
  5314             const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
       
  5315             while (length) {
       
  5316                 int l = qMin(length, buffer_size);
       
  5317                 const uint *end = buffer + l;
       
  5318                 uint *b = buffer;
       
  5319                 while (b < end) {
       
  5320                     const qreal iw = w == 0 ? 1 : 1 / w;
       
  5321                     const qreal px = x * iw - 0.5;
       
  5322                     const qreal py = y * iw - 0.5;
       
  5323 
       
  5324                     int x1 = int(px) - (px < 0);
       
  5325                     int x2;
       
  5326                     int y1 = int(py) - (py < 0);
       
  5327                     int y2;
       
  5328 
       
  5329                     int distx = int((px - x1) * 256);
       
  5330                     int disty = int((py - y1) * 256);
       
  5331                     int idistx = 256 - distx;
       
  5332                     int idisty = 256 - disty;
       
  5333 
       
  5334                     if (blendType == BlendTransformedBilinearTiled) {
       
  5335                         x1 %= image_width;
       
  5336                         if (x1 < 0) x1 += image_width;
       
  5337                         x2 = x1 + 1;
       
  5338                         x2 %= image_width;
       
  5339 
       
  5340                         y1 %= image_height;
       
  5341                         if (y1 < 0) y1 += image_height;
       
  5342                         y2 = y1 + 1;
       
  5343                         y2 %= image_height;
       
  5344 
       
  5345                         Q_ASSERT(x1 >= 0 && x1 < image_width);
       
  5346                         Q_ASSERT(x2 >= 0 && x2 < image_width);
       
  5347                         Q_ASSERT(y1 >= 0 && y1 < image_height);
       
  5348                         Q_ASSERT(y2 >= 0 && y2 < image_height);
       
  5349                     } else {
       
  5350                         if (x1 < image_x1) {
       
  5351                             x2 = x1 = image_x1;
       
  5352                         } else if (x1 >= image_x2 - 1) {
       
  5353                             x2 = x1 = image_x2 - 1;
       
  5354                         } else {
       
  5355                             x2 = x1 + 1;
       
  5356                         }
       
  5357                         if (y1 < image_y1) {
       
  5358                             y2 = y1 = image_y1;
       
  5359                         } else if (y1 >= image_y2 - 1) {
       
  5360                             y2 = y1 = image_y2 - 1;
       
  5361                         } else {
       
  5362                             y2 = y1 + 1;
       
  5363                         }
       
  5364                     }
       
  5365 
       
  5366                     int y1_offset = y1 * scanline_offset;
       
  5367                     int y2_offset = y2 * scanline_offset;
       
  5368 
       
  5369 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
       
  5370                     uint tl = gccBug(image_bits[y1_offset + x1]);
       
  5371                     uint tr = gccBug(image_bits[y1_offset + x2]);
       
  5372                     uint bl = gccBug(image_bits[y2_offset + x1]);
       
  5373                     uint br = gccBug(image_bits[y2_offset + x2]);
       
  5374 #else
       
  5375                     uint tl = image_bits[y1_offset + x1];
       
  5376                     uint tr = image_bits[y1_offset + x2];
       
  5377                     uint bl = image_bits[y2_offset + x1];
       
  5378                     uint br = image_bits[y2_offset + x2];
       
  5379 #endif
       
  5380 
       
  5381                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
       
  5382                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
       
  5383                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
       
  5384                     ++b;
       
  5385 
       
  5386                     x += fdx;
       
  5387                     y += fdy;
       
  5388                     w += fdw;
       
  5389                 }
       
  5390                 if (spanMethod == RegularSpans)
       
  5391                     func(target, buffer, l, coverage);
       
  5392                 else
       
  5393                     drawBufferSpan(data, buffer, buffer_size,
       
  5394                                    spans->x + spans->len - length,
       
  5395                                    spans->y, l, coverage);
       
  5396                 target += l;
       
  5397                 length -= l;
       
  5398             }
       
  5399             ++spans;
       
  5400         }
       
  5401     }
       
  5402 }
  5336 }
  5403 
  5337 
  5404 template <class DST, class SRC>
  5338 template <class DST, class SRC>
  5405 Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan *spans,
  5339 Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan *spans,
  5406                                      void *userData)
  5340                                      void *userData)
  6649         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
  6583         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
  6650         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
  6584         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
  6651         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
  6585         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
  6652         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
  6586         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
  6653         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
  6587         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
  6654         blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied
  6588         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
  6655         blend_transformed_bilinear_rgb565,
  6589         blend_transformed_bilinear_rgb565,
  6656         blend_transformed_bilinear_argb8565,
  6590         blend_transformed_bilinear_argb8565,
  6657         blend_transformed_bilinear_rgb666,
  6591         blend_transformed_bilinear_rgb666,
  6658         blend_transformed_bilinear_argb6666,
  6592         blend_transformed_bilinear_argb6666,
  6659         blend_transformed_bilinear_rgb555,
  6593         blend_transformed_bilinear_rgb555,
  6668         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
  6602         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
  6669         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
  6603         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
  6670         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
  6604         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
  6671         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
  6605         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
  6672         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
  6606         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
  6673         blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
  6607         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
  6674         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16
  6608         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16
  6675         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied
  6609         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied
  6676         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666
  6610         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666
  6677         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB6666_Premultiplied
  6611         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB6666_Premultiplied
  6678         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB555
  6612         SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB555
  6767         blend_src_generic<CallbackSpans>,   // Mono
  6701         blend_src_generic<CallbackSpans>,   // Mono
  6768         blend_src_generic<CallbackSpans>,   // MonoLsb
  6702         blend_src_generic<CallbackSpans>,   // MonoLsb
  6769         blend_src_generic<CallbackSpans>,   // Indexed8
  6703         blend_src_generic<CallbackSpans>,   // Indexed8
  6770         blend_src_generic<CallbackSpans>,   // RGB32
  6704         blend_src_generic<CallbackSpans>,   // RGB32
  6771         blend_src_generic<CallbackSpans>,   // ARGB32
  6705         blend_src_generic<CallbackSpans>,   // ARGB32
  6772         blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied
  6706         blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
  6773         blend_src_generic<CallbackSpans>,   // RGB16
  6707         blend_src_generic<CallbackSpans>,   // RGB16
  6774         blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
  6708         blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
  6775         blend_src_generic<CallbackSpans>,   // RGB666
  6709         blend_src_generic<CallbackSpans>,   // RGB666
  6776         blend_src_generic<CallbackSpans>,   // ARGB6666_Premultiplied
  6710         blend_src_generic<CallbackSpans>,   // ARGB6666_Premultiplied
  6777         blend_src_generic<CallbackSpans>,   // RGB555
  6711         blend_src_generic<CallbackSpans>,   // RGB555
  6786         blend_src_generic<CallbackSpans>,   // Mono
  6720         blend_src_generic<CallbackSpans>,   // Mono
  6787         blend_src_generic<CallbackSpans>,   // MonoLsb
  6721         blend_src_generic<CallbackSpans>,   // MonoLsb
  6788         blend_src_generic<CallbackSpans>,   // Indexed8
  6722         blend_src_generic<CallbackSpans>,   // Indexed8
  6789         blend_src_generic<CallbackSpans>,   // RGB32
  6723         blend_src_generic<CallbackSpans>,   // RGB32
  6790         blend_src_generic<CallbackSpans>,   // ARGB32
  6724         blend_src_generic<CallbackSpans>,   // ARGB32
  6791         blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
  6725         blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
  6792         blend_src_generic<CallbackSpans>,   // RGB16
  6726         blend_src_generic<CallbackSpans>,   // RGB16
  6793         blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
  6727         blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
  6794         blend_src_generic<CallbackSpans>,   // RGB666
  6728         blend_src_generic<CallbackSpans>,   // RGB666
  6795         blend_src_generic<CallbackSpans>,   // ARGB6666_Premultiplied
  6729         blend_src_generic<CallbackSpans>,   // ARGB6666_Premultiplied
  6796         blend_src_generic<CallbackSpans>,   // RGB555
  6730         blend_src_generic<CallbackSpans>,   // RGB555
  7773 #endif // MMXEXT
  7707 #endif // MMXEXT
  7774     }
  7708     }
  7775 #ifdef QT_HAVE_MMX
  7709 #ifdef QT_HAVE_MMX
  7776     if (features & MMX) {
  7710     if (features & MMX) {
  7777         functionForModeAsm = qt_functionForMode_MMX;
  7711         functionForModeAsm = qt_functionForMode_MMX;
       
  7712 
  7778         functionForModeSolidAsm = qt_functionForModeSolid_MMX;
  7713         functionForModeSolidAsm = qt_functionForModeSolid_MMX;
  7779         qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx;
  7714         qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx;
  7780 #ifdef QT_HAVE_3DNOW
  7715 #ifdef QT_HAVE_3DNOW
  7781         if (features & MMX3DNOW) {
  7716         if (features & MMX3DNOW) {
  7782             functionForModeAsm = qt_functionForMode_MMX3DNOW;
  7717             functionForModeAsm = qt_functionForMode_MMX3DNOW;
  7799         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx;
  7734         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx;
  7800         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx;
  7735         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mmx;
  7801 
  7736 
  7802     }
  7737     }
  7803 #endif // MMX
  7738 #endif // MMX
       
  7739 
       
  7740 #ifdef QT_HAVE_SSE
       
  7741     if (features & SSE) {
       
  7742         extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
       
  7743                                                 const uchar *srcPixels, int sbpl,
       
  7744                                                 int w, int h,
       
  7745                                                 int const_alpha);
       
  7746         extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
       
  7747                                                   const uchar *srcPixels, int sbpl,
       
  7748                                                   int w, int h,
       
  7749                                                   int const_alpha);
       
  7750 
       
  7751         qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
       
  7752         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
       
  7753         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
       
  7754         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
       
  7755     }
       
  7756 #endif // SSE
       
  7757 
       
  7758 #ifdef QT_HAVE_SSE2
       
  7759     if (features & SSE2) {
       
  7760         extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
       
  7761                                                  const uchar *srcPixels, int sbpl,
       
  7762                                                  int w, int h,
       
  7763                                                  int const_alpha);
       
  7764         extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
       
  7765                                                    const uchar *srcPixels, int sbpl,
       
  7766                                                    int w, int h,
       
  7767                                                    int const_alpha);
       
  7768 
       
  7769         qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
       
  7770         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
       
  7771         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
       
  7772         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
       
  7773     }
       
  7774 
       
  7775 #ifdef QT_HAVE_SSSE3
       
  7776     if (features & SSSE3) {
       
  7777         extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
       
  7778                                                     const uchar *srcPixels, int sbpl,
       
  7779                                                     int w, int h,
       
  7780                                                     int const_alpha);
       
  7781 
       
  7782         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
       
  7783         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
       
  7784     }
       
  7785 #endif // SSSE3
       
  7786 
       
  7787 #endif // SSE2
  7804 
  7788 
  7805 #ifdef QT_HAVE_SSE
  7789 #ifdef QT_HAVE_SSE
  7806     if (features & SSE) {
  7790     if (features & SSE) {
  7807         functionForModeAsm = qt_functionForMode_SSE;
  7791         functionForModeAsm = qt_functionForMode_SSE;
  7808         functionForModeSolidAsm = qt_functionForModeSolid_SSE;
  7792         functionForModeSolidAsm = qt_functionForModeSolid_SSE;
  7817 
  7801 
  7818 
  7802 
  7819 #ifdef QT_HAVE_SSE2
  7803 #ifdef QT_HAVE_SSE2
  7820         if (features & SSE2) {
  7804         if (features & SSE2) {
  7821             extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
  7805             extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
  7822                                                   const uint *srcPixels,
  7806                                                               const uint *srcPixels,
  7823                                                   int length,
  7807                                                               int length,
  7824                                                   uint const_alpha);
  7808                                                               uint const_alpha);
  7825             extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
  7809             extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
       
  7810             extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha);
       
  7811             extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha);
  7826 
  7812 
  7827             functionForModeAsm[0] = comp_func_SourceOver_sse2;
  7813             functionForModeAsm[0] = comp_func_SourceOver_sse2;
       
  7814             functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
       
  7815             functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
  7828             functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2;
  7816             functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2;
  7829 
  7817         }
  7830             extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
       
  7831                                                      const uchar *srcPixels, int sbpl,
       
  7832                                                      int w, int h,
       
  7833                                                      int const_alpha);
       
  7834             extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
       
  7835                                                        const uchar *srcPixels, int sbpl,
       
  7836                                                        int w, int h,
       
  7837                                                        int const_alpha);
       
  7838 
       
  7839             qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
       
  7840             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
       
  7841             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
       
  7842             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
       
  7843         } else
       
  7844 #endif
  7818 #endif
  7845         {
  7819     }
  7846             extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
  7820 #elif defined(QT_HAVE_SSE2)
  7847                                                     const uchar *srcPixels, int sbpl,
  7821     // this is the special case when SSE2 is usable but MMX/SSE is not usable (e.g.: Windows x64 + visual studio)
  7848                                                     int w, int h,
  7822     if (features & SSE2) {
  7849                                                     int const_alpha);
  7823         functionForModeAsm = qt_functionForMode_onlySSE2;
  7850             extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
  7824         functionForModeSolidAsm = qt_functionForModeSolid_onlySSE2;
  7851                                                       const uchar *srcPixels, int sbpl,
  7825     }
  7852                                                       int w, int h,
  7826 #endif
  7853                                                       int const_alpha);
       
  7854 
       
  7855 
       
  7856             qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
       
  7857             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
       
  7858             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
       
  7859             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
       
  7860         }
       
  7861 }
       
  7862 #endif // SSE
       
  7863 
  7827 
  7864 #ifdef QT_HAVE_IWMMXT
  7828 #ifdef QT_HAVE_IWMMXT
  7865     if (features & IWMMXT) {
  7829     if (features & IWMMXT) {
  7866         functionForModeAsm = qt_functionForMode_IWMMXT;
  7830         functionForModeAsm = qt_functionForMode_IWMMXT;
  7867         functionForModeSolidAsm = qt_functionForModeSolid_IWMMXT;
  7831         functionForModeSolidAsm = qt_functionForModeSolid_IWMMXT;
  7887             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
  7851             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
  7888             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
  7852             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
  7889             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
  7853             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
  7890             qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
  7854             qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
  7891             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
  7855             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
       
  7856             qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
  7892 
  7857 
  7893             qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
  7858             qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
  7894             qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
  7859             qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
  7895 
  7860 
  7896             qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
  7861             qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
  7898 
  7863 
  7899             qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
  7864             qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
  7900 
  7865 
  7901             functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
  7866             functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
  7902             functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
  7867             functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
       
  7868             functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
  7903             destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
  7869             destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
  7904             destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
  7870             destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
  7905 
  7871 
  7906             qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
  7872             qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
  7907             qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
  7873             qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
       
  7874             qt_memfill32 = qt_memfill32_neon;
  7908         }
  7875         }
  7909 #endif
  7876 #endif
  7910 
  7877 
  7911     if (functionForModeSolidAsm) {
  7878     if (functionForModeSolidAsm) {
  7912         const int destinationMode = QPainter::CompositionMode_Destination;
  7879         const int destinationMode = QPainter::CompositionMode_Destination;
  7917         for (int mode = 12; mode < 24; ++mode)
  7884         for (int mode = 12; mode < 24; ++mode)
  7918             functionForModeSolidAsm[mode] = functionForModeSolid_C[mode];
  7885             functionForModeSolidAsm[mode] = functionForModeSolid_C[mode];
  7919 
  7886 
  7920         functionForModeSolid = functionForModeSolidAsm;
  7887         functionForModeSolid = functionForModeSolidAsm;
  7921     }
  7888     }
  7922     if (functionForModeAsm) {
  7889     if (functionForModeAsm)
  7923         const int destinationMode = QPainter::CompositionMode_Destination;
       
  7924         functionForModeAsm[destinationMode] = functionForMode_C[destinationMode];
       
  7925 
       
  7926         // use the default qdrawhelper implementation for the
       
  7927         // extended composition modes
       
  7928         for (int mode = 12; mode < numCompositionFunctions; ++mode)
       
  7929             functionForModeAsm[mode] = functionForMode_C[mode];
       
  7930 
       
  7931         functionForMode = functionForModeAsm;
  7890         functionForMode = functionForModeAsm;
  7932     }
       
  7933 
  7891 
  7934     qt_build_pow_tables();
  7892     qt_build_pow_tables();
  7935 }
  7893 }
  7936 
  7894 
  7937 static void qt_memfill32_setup(quint32 *dest, quint32 value, int count)
  7895 static void qt_memfill32_setup(quint32 *dest, quint32 value, int count)