Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qdrawhelper.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4444#include <private/qpainter_p.h>
    4545#include <private/qdrawhelper_x86_p.h>
    46 #include <private/qdrawhelper_armv6_p.h>
     46#include <private/qdrawhelper_arm_simd_p.h>
    4747#include <private/qdrawhelper_neon_p.h>
    4848#include <private/qmath_p.h>
     
    7070*/
    7171
    72 static const int fixed_scale = 1 << 16;
    73 static const int half_point = 1 << 15;
     72enum {
     73    fixed_scale = 1 << 16,
     74    half_point = 1 << 15
     75};
    7476static const int buffer_size = 2048;
    7577
     
    175177# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg>
    176178
    177 static const DestFetchProc destFetchProc[QImage::NImageFormats] =
     179static DestFetchProc destFetchProc[QImage::NImageFormats] =
    178180{
    179181    0, // Format_Invalid
     
    323325# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST>
    324326
    325 static const DestStoreProc destStoreProc[QImage::NImageFormats] =
     327static DestStoreProc destStoreProc[QImage::NImageFormats] =
    326328{
    327329    0, // Format_Invalid
     
    654656}
    655657
     658/** \internal
     659  interpolate 4 argb pixels with the distx and disty factor.
     660  distx and disty bust be between 0 and 16
     661 */
     662static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty)
     663{
     664    uint distxy = distx * disty;
     665    //idistx * disty = (16-distx) * disty = 16*disty - distxy
     666    //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*dity + distxy
     667    uint tlrb = (tl & 0x00ff00ff)         * (16*16 - 16*distx - 16*disty + distxy);
     668    uint tlag = ((tl & 0xff00ff00) >> 8)  * (16*16 - 16*distx - 16*disty + distxy);
     669    uint trrb = ((tr & 0x00ff00ff)        * (distx*16 - distxy));
     670    uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy));
     671    uint blrb = ((bl & 0x00ff00ff)        * (disty*16 - distxy));
     672    uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy));
     673    uint brrb = ((br & 0x00ff00ff)        * (distxy));
     674    uint brag = (((br & 0xff00ff00) >> 8) * (distxy));
     675    return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
     676}
     677
     678#if defined(QT_ALWAYS_HAVE_SSE2)
     679#define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b)  \
     680{ \
     681    const __m128i dxdy = _mm_mullo_epi16 (distx, disty); \
     682    const __m128i distx_ = _mm_slli_epi16(distx, 4); \
     683    const __m128i disty_ = _mm_slli_epi16(disty, 4); \
     684    const __m128i idxidy =  _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_))); \
     685    const __m128i dxidy =  _mm_sub_epi16(distx_, dxdy); \
     686    const __m128i idxdy =  _mm_sub_epi16(disty_, dxdy); \
     687 \
     688    __m128i tlAG = _mm_srli_epi16(tl, 8); \
     689    __m128i tlRB = _mm_and_si128(tl, colorMask); \
     690    __m128i trAG = _mm_srli_epi16(tr, 8); \
     691    __m128i trRB = _mm_and_si128(tr, colorMask); \
     692    __m128i blAG = _mm_srli_epi16(bl, 8); \
     693    __m128i blRB = _mm_and_si128(bl, colorMask); \
     694    __m128i brAG = _mm_srli_epi16(br, 8); \
     695    __m128i brRB = _mm_and_si128(br, colorMask); \
     696 \
     697    tlAG = _mm_mullo_epi16(tlAG, idxidy); \
     698    tlRB = _mm_mullo_epi16(tlRB, idxidy); \
     699    trAG = _mm_mullo_epi16(trAG, dxidy); \
     700    trRB = _mm_mullo_epi16(trRB, dxidy); \
     701    blAG = _mm_mullo_epi16(blAG, idxdy); \
     702    blRB = _mm_mullo_epi16(blRB, idxdy); \
     703    brAG = _mm_mullo_epi16(brAG, dxdy); \
     704    brRB = _mm_mullo_epi16(brRB, dxdy); \
     705 \
     706    /* Add the values, and shift to only keep 8 significant bits per colors */ \
     707    __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG)); \
     708    __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB)); \
     709    rAG = _mm_andnot_si128(colorMask, rAG); \
     710    rRB = _mm_srli_epi16(rRB, 8); \
     711    _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \
     712}
     713#endif
     714
     715#if defined(QT_ALWAYS_HAVE_NEON)
     716#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b)  \
     717{ \
     718    const int16x8_t dxdy = vmulq_s16(distx, disty); \
     719    const int16x8_t distx_ = vshlq_n_s16(distx, 4); \
     720    const int16x8_t idxidy =  vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_))); \
     721    const int16x8_t dxidy =  vsubq_s16(distx_, dxdy); \
     722    const int16x8_t idxdy =  vsubq_s16(disty_, dxdy); \
     723 \
     724    int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8)); \
     725    int16x8_t tlRB = vandq_s16(tl, colorMask); \
     726    int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8)); \
     727    int16x8_t trRB = vandq_s16(tr, colorMask); \
     728    int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8)); \
     729    int16x8_t blRB = vandq_s16(bl, colorMask); \
     730    int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8)); \
     731    int16x8_t brRB = vandq_s16(br, colorMask); \
     732 \
     733    int16x8_t rAG = vmulq_s16(tlAG, idxidy); \
     734    int16x8_t rRB = vmulq_s16(tlRB, idxidy); \
     735    rAG = vmlaq_s16(rAG, trAG, dxidy); \
     736    rRB = vmlaq_s16(rRB, trRB, dxidy); \
     737    rAG = vmlaq_s16(rAG, blAG, idxdy); \
     738    rRB = vmlaq_s16(rRB, blRB, idxdy); \
     739    rAG = vmlaq_s16(rAG, brAG, dxdy); \
     740    rRB = vmlaq_s16(rRB, brRB, dxdy); \
     741 \
     742    rAG = vandq_s16(invColorMask, rAG); \
     743    rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); \
     744    vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \
     745}
     746#endif
     747
     748template<TextureBlendType blendType>
     749Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
     750{
     751    if (blendType == BlendTransformedBilinearTiled) {
     752        v1 %= max;
     753        if (v1 < 0) v1 += max;
     754        v2 = v1 + 1;
     755        v2 %= max;
     756    } else {
     757        if (v1 < l1) {
     758            v2 = v1 = l1;
     759        } else if (v1 >= l2) {
     760            v2 = v1 = l2;
     761        } else {
     762            v2 = v1 + 1;
     763        }
     764    }
     765
     766    Q_ASSERT(v1 >= 0 && v1 < max);
     767    Q_ASSERT(v2 >= 0 && v2 < max);
     768}
     769
    656770template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
    657771Q_STATIC_TEMPLATE_FUNCTION
     
    672786    int image_height = data->texture.height;
    673787
     788    int image_x1 = data->texture.x1;
     789    int image_y1 = data->texture.y1;
     790    int image_x2 = data->texture.x2 - 1;
     791    int image_y2 = data->texture.y2 - 1;
     792
    674793    const qreal cx = x + 0.5;
    675794    const qreal cy = y + 0.5;
    676795
    677     const uint *end = buffer + length;
     796    uint *end = buffer + length;
    678797    uint *b = buffer;
    679798    if (data->fast_matrix) {
     
    689808        fx -= half_point;
    690809        fy -= half_point;
    691         while (b < end) {
    692             int x1 = (fx >> 16);
    693             int x2 = x1 + 1;
     810
     811        if (fdy == 0) { //simple scale, no rotation
    694812            int y1 = (fy >> 16);
    695             int y2 = y1 + 1;
    696 
    697             int distx = ((fx - (x1 << 16)) >> 8);
    698             int disty = ((fy - (y1 << 16)) >> 8);
    699             int idistx = 256 - distx;
    700             int idisty = 256 - disty;
    701 
    702             if (blendType == BlendTransformedBilinearTiled) {
    703                 x1 %= image_width;
    704                 x2 %= image_width;
    705                 y1 %= image_height;
    706                 y2 %= image_height;
    707 
    708                 if (x1 < 0) x1 += image_width;
    709                 if (x2 < 0) x2 += image_width;
    710                 if (y1 < 0) y1 += image_height;
    711                 if (y2 < 0) y2 += image_height;
    712 
    713                 Q_ASSERT(x1 >= 0 && x1 < image_width);
    714                 Q_ASSERT(x2 >= 0 && x2 < image_width);
    715                 Q_ASSERT(y1 >= 0 && y1 < image_height);
    716                 Q_ASSERT(y2 >= 0 && y2 < image_height);
    717             } else {
    718                 x1 = qBound(0, x1, image_width - 1);
    719                 x2 = qBound(0, x2, image_width - 1);
    720                 y1 = qBound(0, y1, image_height - 1);
    721                 y2 = qBound(0, y2, image_height - 1);
    722             }
    723 
     813            int y2;
     814            fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
    724815            const uchar *s1 = data->texture.scanLine(y1);
    725816            const uchar *s2 = data->texture.scanLine(y2);
    726817
    727             uint tl = fetch(s1, x1, data->texture.colorTable);
    728             uint tr = fetch(s1, x2, data->texture.colorTable);
    729             uint bl = fetch(s2, x1, data->texture.colorTable);
    730             uint br = fetch(s2, x2, data->texture.colorTable);
    731 
    732             uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
    733             uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
    734             *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
    735 
    736             fx += fdx;
    737             fy += fdy;
    738             ++b;
     818            if (fdx <= fixed_scale && fdx > 0) { // scale up on X
     819                int disty = (fy & 0x0000ffff) >> 8;
     820                int idisty = 256 - disty;
     821                int x = fx >> 16;
     822
     823                // The idea is first to do the interpolation between the row s1 and the row s2
     824                // into an intermediate buffer, then we interpolate between two pixel of this buffer.
     825
     826                // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
     827                // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
     828                quint32 intermediate_buffer[2][buffer_size + 2];
     829                // count is the size used in the intermediate_buffer.
     830                int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
     831                Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
     832                int f = 0;
     833                int lim = count;
     834                if (blendType == BlendTransformedBilinearTiled) {
     835                    x %= image_width;
     836                    if (x < 0) x += image_width;
     837                } else {
     838                    lim = qMin(count, image_x2-x+1);
     839                    if (x < image_x1) {
     840                        Q_ASSERT(x <= image_x2);
     841                        uint t = fetch(s1, image_x1, data->texture.colorTable);
     842                        uint b = fetch(s2, image_x1, data->texture.colorTable);
     843                        quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
     844                        quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
     845                        do {
     846                            intermediate_buffer[0][f] = rb;
     847                            intermediate_buffer[1][f] = ag;
     848                            f++;
     849                            x++;
     850                        } while (x < image_x1 && f < lim);
     851                    }
     852                }
     853
     854                if (blendType != BlendTransformedBilinearTiled &&
     855                        (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
     856#if defined(QT_ALWAYS_HAVE_SSE2)
     857                    const __m128i disty_ = _mm_set1_epi16(disty);
     858                    const __m128i idisty_ = _mm_set1_epi16(idisty);
     859                    const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
     860
     861                    lim -= 3;
     862                    for (; f < lim; x += 4, f += 4) {
     863                        // Load 4 pixels from s1, and split the alpha-green and red-blue component
     864                        __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x));
     865                        __m128i topAG = _mm_srli_epi16(top, 8);
     866                        __m128i topRB = _mm_and_si128(top, colorMask);
     867                        // Multiplies each colour component by idisty
     868                        topAG = _mm_mullo_epi16 (topAG, idisty_);
     869                        topRB = _mm_mullo_epi16 (topRB, idisty_);
     870
     871                        // Same for the s2 vector
     872                        __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x));
     873                        __m128i bottomAG = _mm_srli_epi16(bottom, 8);
     874                        __m128i bottomRB = _mm_and_si128(bottom, colorMask);
     875                        bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
     876                        bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
     877
     878                        // Add the values, and shift to only keep 8 significant bits per colors
     879                        __m128i rAG =_mm_add_epi16(topAG, bottomAG);
     880                        rAG = _mm_srli_epi16(rAG, 8);
     881                        _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG);
     882                        __m128i rRB =_mm_add_epi16(topRB, bottomRB);
     883                        rRB = _mm_srli_epi16(rRB, 8);
     884                        _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB);
     885                    }
     886#elif defined(QT_ALWAYS_HAVE_NEON)
     887                    const int16x8_t disty_ = vdupq_n_s16(disty);
     888                    const int16x8_t idisty_ = vdupq_n_s16(idisty);
     889                    const int16x8_t colorMask = vdupq_n_s16(0x00ff);
     890
     891                    lim -= 3;
     892                    for (; f < lim; x += 4, f += 4) {
     893                        // Load 4 pixels from s1, and split the alpha-green and red-blue component
     894                        int16x8_t top = vld1q_s16((int16_t*)((const uint *)(s1)+x));
     895                        int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8));
     896                        int16x8_t topRB = vandq_s16(top, colorMask);
     897                        // Multiplies each colour component by idisty
     898                        topAG = vmulq_s16(topAG, idisty_);
     899                        topRB = vmulq_s16(topRB, idisty_);
     900
     901                        // Same for the s2 vector
     902                        int16x8_t bottom = vld1q_s16((int16_t*)((const uint *)(s2)+x));
     903                        int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8));
     904                        int16x8_t bottomRB = vandq_s16(bottom, colorMask);
     905                        bottomAG = vmulq_s16(bottomAG, disty_);
     906                        bottomRB = vmulq_s16(bottomRB, disty_);
     907
     908                        // Add the values, and shift to only keep 8 significant bits per colors
     909                        int16x8_t rAG = vaddq_s16(topAG, bottomAG);
     910                        rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
     911                        vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG);
     912                        int16x8_t rRB = vaddq_s16(topRB, bottomRB);
     913                        rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
     914                        vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB);
     915                    }
     916#endif
     917                }
     918                for (; f < count; f++) { // Same as above but without sse2
     919                    if (blendType == BlendTransformedBilinearTiled) {
     920                        if (x >= image_width) x -= image_width;
     921                    } else {
     922                        x = qMin(x, image_x2);
     923                    }
     924
     925                    uint t = fetch(s1, x, data->texture.colorTable);
     926                    uint b = fetch(s2, x, data->texture.colorTable);
     927
     928                    intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
     929                    intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
     930                    x++;
     931                }
     932                // Now interpolate the values from the intermediate_buffer to get the final result.
     933                fx &= fixed_scale - 1;
     934                Q_ASSERT((fx >> 16) == 0);
     935                while (b < end) {
     936                    register int x1 = (fx >> 16);
     937                    register int x2 = x1 + 1;
     938                    Q_ASSERT(x1 >= 0);
     939                    Q_ASSERT(x2 < count);
     940
     941                    register int distx = (fx & 0x0000ffff) >> 8;
     942                    register int idistx = 256 - distx;
     943                    int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff;
     944                    int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00;
     945                    *b = rb | ag;
     946                    b++;
     947                    fx += fdx;
     948                }
     949            } else if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
     950                int y1 = (fy >> 16);
     951                int y2;
     952                fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
     953                const uchar *s1 = data->texture.scanLine(y1);
     954                const uchar *s2 = data->texture.scanLine(y2);
     955                int disty = (fy & 0x0000ffff) >> 8;
     956                int idisty = 256 - disty;
     957                while (b < end) {
     958                    int x1 = (fx >> 16);
     959                    int x2;
     960                    fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
     961                    uint tl = fetch(s1, x1, data->texture.colorTable);
     962                    uint tr = fetch(s1, x2, data->texture.colorTable);
     963                    uint bl = fetch(s2, x1, data->texture.colorTable);
     964                    uint br = fetch(s2, x2, data->texture.colorTable);
     965
     966                    int distx = (fx & 0x0000ffff) >> 8;
     967                    int idistx = 256 - distx;
     968
     969                    uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
     970                    uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
     971                    *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
     972
     973                    fx += fdx;
     974                    ++b;
     975                }
     976            } else { //scale down
     977                int y1 = (fy >> 16);
     978                int y2;
     979                fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
     980                const uchar *s1 = data->texture.scanLine(y1);
     981                const uchar *s2 = data->texture.scanLine(y2);
     982                int disty = (fy & 0x0000ffff) >> 12;
     983
     984                if (blendType != BlendTransformedBilinearTiled &&
     985                    (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
     986
     987#define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \
     988                    while (b < end) { \
     989                        int x1 = (fx >> 16); \
     990                        int x2; \
     991                        fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \
     992                        if (x1 != x2) \
     993                            break; \
     994                        uint tl = fetch(s1, x1, data->texture.colorTable); \
     995                        uint tr = fetch(s1, x2, data->texture.colorTable); \
     996                        uint bl = fetch(s2, x1, data->texture.colorTable); \
     997                        uint br = fetch(s2, x2, data->texture.colorTable); \
     998                        int distx = (fx & 0x0000ffff) >> 12; \
     999                        *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \
     1000                        fx += fdx; \
     1001                        ++b; \
     1002                    } \
     1003                    uint *boundedEnd; \
     1004                    if (fdx > 0) \
     1005                        boundedEnd = qMin(end, buffer + uint((image_x2 - (fx >> 16)) / data->m11)); \
     1006                    else \
     1007                        boundedEnd = qMin(end, buffer + uint((image_x1 - (fx >> 16)) / data->m11)); \
     1008                    boundedEnd -= 3;
     1009
     1010#if defined(QT_ALWAYS_HAVE_SSE2)
     1011                    BILINEAR_DOWNSCALE_BOUNDS_PROLOG
     1012
     1013                    const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
     1014                    const __m128i v_256 = _mm_set1_epi16(256);
     1015                    const __m128i v_disty = _mm_set1_epi16(disty);
     1016                    __m128i v_fdx = _mm_set1_epi32(fdx*4);
     1017
     1018                    ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1);
     1019
     1020                    union Vect_buffer { __m128i vect; quint32 i[4]; };
     1021                    Vect_buffer v_fx;
     1022
     1023                    for (int i = 0; i < 4; i++) {
     1024                        v_fx.i[i] = fx;
     1025                        fx += fdx;
     1026                    }
     1027
     1028                    while (b < boundedEnd) {
     1029
     1030                        Vect_buffer tl, tr, bl, br;
     1031
     1032                        for (int i = 0; i < 4; i++) {
     1033                            int x1 = v_fx.i[i] >> 16;
     1034                            const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1;
     1035                            const uint *addr_tr = addr_tl + 1;
     1036                            tl.i[i] = *addr_tl;
     1037                            tr.i[i] = *addr_tr;
     1038                            bl.i[i] = *(addr_tl+secondLine);
     1039                            br.i[i] = *(addr_tr+secondLine);
     1040                        }
     1041                        __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12);
     1042                        v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
     1043                        v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
     1044
     1045                        interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b);
     1046                        b+=4;
     1047                        v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx);
     1048                    }
     1049                    fx = v_fx.i[0];
     1050#elif defined(QT_ALWAYS_HAVE_NEON)
     1051                    BILINEAR_DOWNSCALE_BOUNDS_PROLOG
     1052
     1053                    const int16x8_t colorMask = vdupq_n_s16(0x00ff);
     1054                    const int16x8_t invColorMask = vmvnq_s16(colorMask);
     1055                    const int16x8_t v_256 = vdupq_n_s16(256);
     1056                    const int16x8_t v_disty = vdupq_n_s16(disty);
     1057                    const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
     1058                    int32x4_t v_fdx = vdupq_n_s32(fdx*4);
     1059
     1060                    ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1);
     1061
     1062                    union Vect_buffer { int32x4_t vect; quint32 i[4]; };
     1063                    Vect_buffer v_fx;
     1064
     1065                    for (int i = 0; i < 4; i++) {
     1066                        v_fx.i[i] = fx;
     1067                        fx += fdx;
     1068                    }
     1069
     1070                    const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
     1071
     1072                    while (b < boundedEnd) {
     1073
     1074                        Vect_buffer tl, tr, bl, br;
     1075
     1076                        Vect_buffer v_fx_shifted;
     1077                        v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
     1078
     1079                        int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
     1080
     1081                        for (int i = 0; i < 4; i++) {
     1082                            int x1 = v_fx_shifted.i[i];
     1083                            const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1;
     1084                            const uint *addr_tr = addr_tl + 1;
     1085                            tl.i[i] = *addr_tl;
     1086                            tr.i[i] = *addr_tr;
     1087                            bl.i[i] = *(addr_tl+secondLine);
     1088                            br.i[i] = *(addr_tr+secondLine);
     1089                        }
     1090
     1091                        v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
     1092
     1093                        interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
     1094                        b+=4;
     1095                        v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
     1096                    }
     1097                    fx = v_fx.i[0];
     1098#endif
     1099                }
     1100
     1101                while (b < end) {
     1102                    int x1 = (fx >> 16);
     1103                    int x2;
     1104                    fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
     1105                    uint tl = fetch(s1, x1, data->texture.colorTable);
     1106                    uint tr = fetch(s1, x2, data->texture.colorTable);
     1107                    uint bl = fetch(s2, x1, data->texture.colorTable);
     1108                    uint br = fetch(s2, x2, data->texture.colorTable);
     1109                    int distx = (fx & 0x0000ffff) >> 12;
     1110                    *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
     1111                    fx += fdx;
     1112                    ++b;
     1113                }
     1114            }
     1115        } else { //rotation
     1116            if (fabs(data->m11) > 8 || fabs(data->m22) > 8) {
     1117                //if we are zooming more than 8 times, we use 8bit precision for the position.
     1118                while (b < end) {
     1119                    int x1 = (fx >> 16);
     1120                    int x2;
     1121                    int y1 = (fy >> 16);
     1122                    int y2;
     1123
     1124                    fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
     1125                    fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
     1126
     1127                    const uchar *s1 = data->texture.scanLine(y1);
     1128                    const uchar *s2 = data->texture.scanLine(y2);
     1129
     1130                    uint tl = fetch(s1, x1, data->texture.colorTable);
     1131                    uint tr = fetch(s1, x2, data->texture.colorTable);
     1132                    uint bl = fetch(s2, x1, data->texture.colorTable);
     1133                    uint br = fetch(s2, x2, data->texture.colorTable);
     1134
     1135                    int distx = (fx & 0x0000ffff) >> 8;
     1136                    int disty = (fy & 0x0000ffff) >> 8;
     1137                    int idistx = 256 - distx;
     1138                    int idisty = 256 - disty;
     1139
     1140                    uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
     1141                    uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
     1142                    *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
     1143
     1144                    fx += fdx;
     1145                    fy += fdy;
     1146                    ++b;
     1147                }
     1148            } else {
     1149                //we are zooming less than 8x, use 4bit precision
     1150                while (b < end) {
     1151                    int x1 = (fx >> 16);
     1152                    int x2;
     1153                    int y1 = (fy >> 16);
     1154                    int y2;
     1155
     1156                    fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
     1157                    fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
     1158
     1159                    const uchar *s1 = data->texture.scanLine(y1);
     1160                    const uchar *s2 = data->texture.scanLine(y2);
     1161
     1162                    uint tl = fetch(s1, x1, data->texture.colorTable);
     1163                    uint tr = fetch(s1, x2, data->texture.colorTable);
     1164                    uint bl = fetch(s2, x1, data->texture.colorTable);
     1165                    uint br = fetch(s2, x2, data->texture.colorTable);
     1166
     1167                    int distx = (fx & 0x0000ffff) >> 12;
     1168                    int disty = (fy & 0x0000ffff) >> 12;
     1169
     1170                    *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
     1171
     1172                    fx += fdx;
     1173                    fy += fdy;
     1174                    ++b;
     1175                }
     1176            }
    7391177        }
    7401178    } else {
     
    7531191
    7541192            int x1 = int(px) - (px < 0);
    755             int x2 = x1 + 1;
     1193            int x2;
    7561194            int y1 = int(py) - (py < 0);
    757             int y2 = y1 + 1;
     1195            int y2;
    7581196
    7591197            int distx = int((px - x1) * 256);
     
    7621200            int idisty = 256 - disty;
    7631201
    764             if (blendType == BlendTransformedBilinearTiled) {
    765                 x1 %= image_width;
    766                 x2 %= image_width;
    767                 y1 %= image_height;
    768                 y2 %= image_height;
    769 
    770                 if (x1 < 0) x1 += image_width;
    771                 if (x2 < 0) x2 += image_width;
    772                 if (y1 < 0) y1 += image_height;
    773                 if (y2 < 0) y2 += image_height;
    774 
    775                 Q_ASSERT(x1 >= 0 && x1 < image_width);
    776                 Q_ASSERT(x2 >= 0 && x2 < image_width);
    777                 Q_ASSERT(y1 >= 0 && y1 < image_height);
    778                 Q_ASSERT(y2 >= 0 && y2 < image_height);
    779             } else {
    780                 x1 = qBound(0, x1, image_width - 1);
    781                 x2 = qBound(0, x2, image_width - 1);
    782                 y1 = qBound(0, y1, image_height - 1);
    783                 y2 = qBound(0, y2, image_height - 1);
    784             }
     1202            fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
     1203            fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
    7851204
    7861205            const uchar *s1 = data->texture.scanLine(y1);
     
    12821701}
    12831702
    1284 static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
     1703void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
    12851704{
    12861705    comp_func_Clear_impl(dest, length, const_alpha);
    12871706}
    12881707
    1289 static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
     1708void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
    12901709{
    12911710    comp_func_Clear_impl(dest, length, const_alpha);
     
    12961715  dest = s * ca + d * cia
    12971716*/
    1298 static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
     1717void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
    12991718{
    13001719    if (const_alpha == 255) {
     
    13111730}
    13121731
    1313 static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
     1732void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)
    13141733{
    13151734    if (const_alpha == 255) {
     
    13251744}
    13261745
    1327 static void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
    1328 {
    1329 }
    1330 
    1331 static void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
     1746void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
     1747{
     1748}
     1749
     1750void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
    13321751{
    13331752}
     
    13391758       = s * ca + d * (1 - sa*ca)
    13401759*/
    1341 static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
     1760void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
    13421761{
    13431762    if ((const_alpha & qAlpha(color)) == 255) {
     
    13541773}
    13551774
    1356 static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
     1775void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)
    13571776{
    13581777    PRELOAD_INIT2(dest, src)
     
    13801799       = d + s * dia * ca
    13811800*/
    1382 static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
     1801void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
    13831802{
    13841803    if (const_alpha != 255)
     
    13921811}
    13931812
    1394 static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
     1813void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)
    13951814{
    13961815    PRELOAD_INIT2(dest, src)
     
    14151834  dest = s * da * ca + d * cia
    14161835*/
    1417 static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
     1836void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
    14181837{
    14191838    PRELOAD_INIT(dest)
     
    14341853}
    14351854
    1436 static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
     1855void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)
    14371856{
    14381857    PRELOAD_INIT2(dest, src)
     
    14581877       = d * (sa * ca + cia)
    14591878*/
    1460 static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
     1879void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
    14611880{
    14621881    uint a = qAlpha(color);
     
    14711890}
    14721891
    1473 static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
     1892void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)
    14741893{
    14751894    PRELOAD_INIT2(dest, src)
     
    14941913*/
    14951914
    1496 static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
     1915void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
    14971916{
    14981917    PRELOAD_INIT(dest)
     
    15131932}
    15141933
    1515 static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
     1934void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)
    15161935{
    15171936    PRELOAD_INIT2(dest, src)
     
    15371956       = d * (sia * ca + cia)
    15381957*/
    1539 static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
     1958void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
    15401959{
    15411960    uint a = qAlpha(~color);
     
    15491968}
    15501969
    1551 static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
     1970void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)
    15521971{
    15531972    PRELOAD_INIT2(dest, src)
     
    15731992       = s*ca * da + d * (1 - sa*ca)
    15741993*/
    1575 static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
     1994void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
    15761995{
    15771996    if (const_alpha != 255) {
     
    15862005}
    15872006
    1588 static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
     2007void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)
    15892008{
    15902009    PRELOAD_INIT2(dest, src)
     
    16112030       = s*ca * dia + d * (sa*ca + cia)
    16122031*/
    1613 static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
     2032void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
    16142033{
    16152034    uint a = qAlpha(color);
     
    16262045}
    16272046
    1628 static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
     2047void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)
    16292048{
    16302049    PRELOAD_INIT2(dest, src)
     
    16542073       = s*ca * dia + d * (1 - sa*ca)
    16552074*/
    1656 static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
     2075void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
    16572076{
    16582077    if (const_alpha != 255)
     
    16682087}
    16692088
    1670 static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
     2089void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)
    16712090{
    16722091    PRELOAD_INIT2(dest, src)
     
    16882107}
    16892108
    1690 static const uint AMASK = 0xff000000;
    1691 static const uint RMASK = 0x00ff0000;
    1692 static const uint GMASK = 0x0000ff00;
    1693 static const uint BMASK = 0x000000ff;
    1694 
    16952109struct QFullCoverage {
    16962110    inline void store(uint *dest, const uint src) const
     
    17352149        PRELOAD_COND(dest)
    17362150        uint d = dest[i];
    1737 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
    1738         d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
    1739 #undef MIX
     2151        d = comp_func_Plus_one_pixel(d, s);
    17402152        coverage.store(&dest[i], d);
    17412153    }
    17422154}
    17432155
    1744 static void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
     2156void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
    17452157{
    17462158    if (const_alpha == 255)
     
    17592171        uint s = src[i];
    17602172
    1761 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
    1762         d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
    1763 #undef MIX
     2173        d = comp_func_Plus_one_pixel(d, s);
    17642174
    17652175        coverage.store(&dest[i], d);
     
    17672177}
    17682178
    1769 static void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
     2179void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)
    17702180{
    17712181    if (const_alpha == 255)
     
    18082218}
    18092219
    1810 static void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
     2220void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
    18112221{
    18122222    if (const_alpha == 255)
     
    18392249}
    18402250
    1841 static void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
     2251void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)
    18422252{
    18432253    if (const_alpha == 255)
     
    18762286}
    18772287
    1878 static void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
     2288void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
    18792289{
    18802290    if (const_alpha == 255)
     
    19072317}
    19082318
    1909 static void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
     2319void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
    19102320{
    19112321    if (const_alpha == 255)
     
    19552365}
    19562366
    1957 static void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
     2367void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
    19582368{
    19592369    if (const_alpha == 255)
     
    19862396}
    19872397
    1988 static void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
     2398void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)
    19892399{
    19902400    if (const_alpha == 255)
     
    20282438}
    20292439
    2030 static void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
     2440void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
    20312441{
    20322442    if (const_alpha == 255)
     
    20592469}
    20602470
    2061 static void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
     2471void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)
    20622472{
    20632473    if (const_alpha == 255)
     
    21012511}
    21022512
    2103 static void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
     2513void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
    21042514{
    21052515    if (const_alpha == 255)
     
    21322542}
    21332543
    2134 static void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
     2544void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)
    21352545{
    21362546    if (const_alpha == 255)
     
    21842594}
    21852595
    2186 static void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
     2596void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
    21872597{
    21882598    if (const_alpha == 255)
     
    22152625}
    22162626
    2217 static void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
     2627void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)
    22182628{
    22192629    if (const_alpha == 255)
     
    22672677}
    22682678
    2269 static void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
     2679void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
    22702680{
    22712681    if (const_alpha == 255)
     
    22982708}
    22992709
    2300 static void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
     2710void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)
    23012711{
    23022712    if (const_alpha == 255)
     
    23472757}
    23482758
    2349 static void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
     2759void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
    23502760{
    23512761    if (const_alpha == 255)
     
    23782788}
    23792789
    2380 static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
     2790void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)
    23812791{
    23822792    if (const_alpha == 255)
     
    24382848}
    24392849
    2440 static void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
     2850void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
    24412851{
    24422852    if (const_alpha == 255)
     
    24692879}
    24702880
    2471 static void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
     2881void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)
    24722882{
    24732883    if (const_alpha == 255)
     
    25112921}
    25122922
    2513 static void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
     2923void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
    25142924{
    25152925    if (const_alpha == 255)
     
    25422952}
    25432953
    2544 static void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
     2954void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)
    25452955{
    25462956    if (const_alpha == 255)
     
    25782988}
    25792989
    2580 static void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
     2990void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
    25812991{
    25822992    if (const_alpha == 255)
     
    26093019}
    26103020
    2611 static void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
     3021void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)
    26123022{
    26133023    if (const_alpha == 255)
     
    26223032#endif
    26233033
    2624 static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
    2625                                                            int length,
    2626                                                            uint color,
    2627                                                            uint const_alpha)
     3034void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
     3035                                                    int length,
     3036                                                    uint color,
     3037                                                    uint const_alpha)
    26283038{
    26293039    Q_UNUSED(const_alpha);
     
    26323042}
    26333043
    2634 static void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
    2635                                                      const uint *src,
    2636                                                      int length,
    2637                                                      uint const_alpha)
     3044void QT_FASTCALL rasterop_SourceOrDestination(uint *dest,
     3045                                              const uint *src,
     3046                                              int length,
     3047                                              uint const_alpha)
    26383048{
    26393049    Q_UNUSED(const_alpha);
     
    26423052}
    26433053
    2644 static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
    2645                                                             int length,
    2646                                                             uint color,
    2647                                                             uint const_alpha)
     3054void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
     3055                                                     int length,
     3056                                                     uint color,
     3057                                                     uint const_alpha)
    26483058{
    26493059    Q_UNUSED(const_alpha);
     
    26533063}
    26543064
    2655 static void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
    2656                                                       const uint *src,
    2657                                                       int length,
    2658                                                       uint const_alpha)
     3065void QT_FASTCALL rasterop_SourceAndDestination(uint *dest,
     3066                                               const uint *src,
     3067                                               int length,
     3068                                               uint const_alpha)
    26593069{
    26603070    Q_UNUSED(const_alpha);
     
    26653075}
    26663076
    2667 static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
    2668                                                             int length,
    2669                                                             uint color,
    2670                                                             uint const_alpha)
     3077void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
     3078                                                     int length,
     3079                                                     uint color,
     3080                                                     uint const_alpha)
    26713081{
    26723082    Q_UNUSED(const_alpha);
     
    26763086}
    26773087
    2678 static void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
    2679                                                       const uint *src,
    2680                                                       int length,
    2681                                                       uint const_alpha)
     3088void QT_FASTCALL rasterop_SourceXorDestination(uint *dest,
     3089                                               const uint *src,
     3090                                               int length,
     3091                                               uint const_alpha)
    26823092{
    26833093    Q_UNUSED(const_alpha);
     
    26883098}
    26893099
    2690 static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
    2691                                                                   int length,
    2692                                                                   uint color,
    2693                                                                   uint const_alpha)
     3100void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
     3101                                                           int length,
     3102                                                           uint color,
     3103                                                           uint const_alpha)
    26943104{
    26953105    Q_UNUSED(const_alpha);
     
    27013111}
    27023112
    2703 static void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
    2704                                                             const uint *src,
    2705                                                             int length,
    2706                                                             uint const_alpha)
     3113void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,
     3114                                                     const uint *src,
     3115                                                     int length,
     3116                                                     uint const_alpha)
    27073117{
    27083118    Q_UNUSED(const_alpha);
     
    27133123}
    27143124
    2715 static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
    2716                                                                  int length,
    2717                                                                  uint color,
    2718                                                                  uint const_alpha)
     3125void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
     3126                                                          int length,
     3127                                                          uint color,
     3128                                                          uint const_alpha)
    27193129{
    27203130    Q_UNUSED(const_alpha);
     
    27263136}
    27273137
    2728 static void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
    2729                                                            const uint *src,
    2730                                                            int length,
    2731                                                            uint const_alpha)
     3138void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,
     3139                                                    const uint *src,
     3140                                                    int length,
     3141                                                    uint const_alpha)
    27323142{
    27333143    Q_UNUSED(const_alpha);
     
    27383148}
    27393149
    2740 static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
    2741                                                                int length,
    2742                                                                uint color,
    2743                                                                uint const_alpha)
     3150void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
     3151                                                        int length,
     3152                                                        uint color,
     3153                                                        uint const_alpha)
    27443154{
    27453155    Q_UNUSED(const_alpha);
     
    27513161}
    27523162
    2753 static void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
    2754                                                          const uint *src,
    2755                                                          int length,
    2756                                                          uint const_alpha)
     3163void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,
     3164                                                  const uint *src,
     3165                                                  int length,
     3166                                                  uint const_alpha)
    27573167{
    27583168    Q_UNUSED(const_alpha);
     
    27633173}
    27643174
    2765 static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
    2766                                                  uint color, uint const_alpha)
     3175void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
     3176                                          uint color, uint const_alpha)
    27673177{
    27683178    Q_UNUSED(const_alpha);
     
    27703180}
    27713181
    2772 static void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
    2773                                            int length, uint const_alpha)
     3182void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,
     3183                                    int length, uint const_alpha)
    27743184{
    27753185    Q_UNUSED(const_alpha);
     
    27783188}
    27793189
    2780 static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
    2781                                                                int length,
    2782                                                                uint color,
    2783                                                                uint const_alpha)
     3190void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
     3191                                                        int length,
     3192                                                        uint color,
     3193                                                        uint const_alpha)
    27843194{
    27853195    Q_UNUSED(const_alpha);
     
    27913201}
    27923202
    2793 static void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
    2794                                                          const uint *src,
    2795                                                          int length,
    2796                                                          uint const_alpha)
     3203void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,
     3204                                                  const uint *src,
     3205                                                  int length,
     3206                                                  uint const_alpha)
    27973207{
    27983208    Q_UNUSED(const_alpha);
     
    28033213}
    28043214
    2805 static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
    2806                                                                int length,
    2807                                                                uint color,
    2808                                                                uint const_alpha)
     3215void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
     3216                                                        int length,
     3217                                                        uint color,
     3218                                                        uint const_alpha)
    28093219{
    28103220    Q_UNUSED(const_alpha);
     
    28153225}
    28163226
    2817 static void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
    2818                                                          const uint *src,
    2819                                                          int length,
    2820                                                          uint const_alpha)
     3227void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,
     3228                                                  const uint *src,
     3229                                                  int length,
     3230                                                  uint const_alpha)
    28213231{
    28223232    Q_UNUSED(const_alpha);
     
    28273237}
    28283238
    2829 static const CompositionFunctionSolid functionForModeSolid_C[] = {
     3239static CompositionFunctionSolid functionForModeSolid_C[] = {
    28303240        comp_func_solid_SourceOver,
    28313241        comp_func_solid_DestinationOver,
     
    28653275static const CompositionFunctionSolid *functionForModeSolid = functionForModeSolid_C;
    28663276
    2867 static const CompositionFunction functionForMode_C[] = {
     3277static CompositionFunction functionForMode_C[] = {
    28683278        comp_func_SourceOver,
    28693279        comp_func_DestinationOver,
     
    37014111inline quint32 alpha_4(const qargb8555 *src)
    37024112{
    3703     Q_ASSERT((long(src) & 0x3) == 0);
     4113    Q_ASSERT((quintptr(src) & 0x3) == 0);
    37044114    const quint8 *src8 = reinterpret_cast<const quint8*>(src);
    37054115    return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9];
     
    38844294inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha)
    38854295{
    3886     Q_ASSERT((long(dest) & 0x3) == 0);
    3887     Q_ASSERT((long(src) & 0x3) == 0);
     4296    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4297    Q_ASSERT((quintptr(src) & 0x3) == 0);
    38884298
    38894299    const quint16 a = eff_alpha_2(alpha, dest);
     
    39584368                                const SRC *src, quint8 b)
    39594369{
    3960     Q_ASSERT((long(dest) & 0x3) == 0);
    3961     Q_ASSERT((long(src) & 0x3) == 0);
     4370    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4371    Q_ASSERT((quintptr(src) & 0x3) == 0);
    39624372
    39634373    Q_ASSERT(!SRC::hasAlpha());
     
    40074417inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha)
    40084418{
    4009     Q_ASSERT((long(dest) & 0x3) == 0);
    4010     Q_ASSERT((long(src) & 0x3) == 0);
     4419    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4420    Q_ASSERT((quintptr(src) & 0x3) == 0);
    40114421
    40124422    const quint32 a = eff_alpha_4(alpha, dest);
     
    40274437                                quint32 alpha)
    40284438{
    4029     Q_ASSERT((long(dest) & 0x3) == 0);
    4030     Q_ASSERT((long(src) & 0x3) == 0);
     4439    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4440    Q_ASSERT((quintptr(src) & 0x3) == 0);
    40314441
    40324442    const quint32 a = eff_alpha_4(alpha, dest);
     
    41234533                                quint32 alpha)
    41244534{
    4125     Q_ASSERT((long(dest) & 0x3) == 0);
    4126     Q_ASSERT((long(src) & 0x3) == 0);
     4535    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4536    Q_ASSERT((quintptr(src) & 0x3) == 0);
    41274537
    41284538
     
    42194629                                quint32 alpha)
    42204630{
    4221     Q_ASSERT((long(dest) & 0x3) == 0);
    4222     Q_ASSERT((long(src) & 0x3) == 0);
     4631    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4632    Q_ASSERT((quintptr(src) & 0x3) == 0);
    42234633
    42244634    const quint32 a = eff_alpha_4(alpha, dest);
     
    42924702                                const SRC *src, quint8 b)
    42934703{
    4294     Q_ASSERT((long(dest) & 0x3) == 0);
    4295     Q_ASSERT((long(src) & 0x3) == 0);
     4704    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4705    Q_ASSERT((quintptr(src) & 0x3) == 0);
    42964706
    42974707    dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b);
     
    43044714inline void blend_sourceOver_4(DST *dest, const SRC *src)
    43054715{
    4306     Q_ASSERT((long(dest) & 0x3) == 0);
    4307     Q_ASSERT((long(src) & 0x3) == 0);
     4716    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4717    Q_ASSERT((quintptr(src) & 0x3) == 0);
    43084718
    43094719    const quint32 a = alpha_4(src);
     
    43204730inline void blend_sourceOver_4(qargb8565 *dest, const qargb8565 *src)
    43214731{
    4322     Q_ASSERT((long(dest) & 0x3) == 0);
    4323     Q_ASSERT((long(src) & 0x3) == 0);
     4732    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4733    Q_ASSERT((quintptr(src) & 0x3) == 0);
    43244734
    43254735    const quint32 a = alpha_4(src);
     
    43344744inline void blend_sourceOver_4(qargb8555 *dest, const qargb8555 *src)
    43354745{
    4336     Q_ASSERT((long(dest) & 0x3) == 0);
    4337     Q_ASSERT((long(src) & 0x3) == 0);
     4746    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4747    Q_ASSERT((quintptr(src) & 0x3) == 0);
    43384748
    43394749    const quint32 a = alpha_4(src);
     
    43484758inline void blend_sourceOver_4(qargb6666 *dest, const qargb6666 *src)
    43494759{
    4350     Q_ASSERT((long(dest) & 0x3) == 0);
    4351     Q_ASSERT((long(src) & 0x3) == 0);
     4760    Q_ASSERT((quintptr(dest) & 0x3) == 0);
     4761    Q_ASSERT((quintptr(src) & 0x3) == 0);
    43524762
    43534763    const quint32 a = alpha_4(src);
     
    44114821    Q_ASSERT(sizeof(DST) == 2);
    44124822    Q_ASSERT(sizeof(SRC) == 2);
    4413     Q_ASSERT((long(dest) & 0x3) == (long(src) & 0x3));
     4823    Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3));
    44144824    Q_ASSERT(coverage > 0);
    44154825
     
    44794889
    44804890        while (length >= 2) {
    4481             Q_ASSERT((long(dest) & 3) == 0);
    4482             Q_ASSERT((long(src) & 3) == 0);
     4891            Q_ASSERT((quintptr(dest) & 3) == 0);
     4892            Q_ASSERT((quintptr(src) & 3) == 0);
    44834893
    44844894            const quint16 a = alpha_2(src);
     
    45114921                                           quint8 coverage, int length)
    45124922{
    4513     Q_ASSERT((long(dest) & 0x3) == (long(src) & 0x3));
     4923    Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3));
    45144924    Q_ASSERT(sizeof(DST) == 3);
    45154925    Q_ASSERT(coverage > 0);
     
    45364946        if (SRC::hasAlpha()) {
    45374947            while (length >= 4) {
    4538                 const quint32 alpha = BYTE_MUL(uint(alpha_4(src)), uint(coverage));
     4948                const quint32 alpha = QT_PREPEND_NAMESPACE(BYTE_MUL)(uint(alpha_4(src)), uint(coverage));
    45394949                if (alpha)
    45404950                    interpolate_pixel_4(dest, src, alpha);
     
    47345144                                       void *userData)
    47355145{
    4736 #if defined(QT_QWS_DEPTH_16)
     5146#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
    47375147    QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    47385148
     
    49875397                copy_image_width *= 2;
    49885398            }
    4989             qt_memconvert(dest, src, length);
     5399            if (length > 0)
     5400                qt_memconvert(dest, src, length);
    49905401        } else {
    49915402            while (length) {
     
    50725483static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
    50735484{
    5074 #if defined(QT_QWS_DEPTH_16)
     5485#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
    50755486    QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    50765487
     
    51385549#endif
    51395550        blend_tiled_generic<RegularSpans>(count, spans, userData);
    5140 }
    5141 
    5142 
    5143 template <SpanMethod spanMethod>
    5144 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)
    5145 {
    5146     QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    5147     if (data->texture.format != QImage::Format_ARGB32_Premultiplied
    5148         && data->texture.format != QImage::Format_RGB32) {
    5149         blend_src_generic<spanMethod>(count, spans, userData);
    5150         return;
    5151     }
    5152 
    5153     CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
    5154     uint buffer[buffer_size];
    5155 
    5156     int image_x1 = data->texture.x1;
    5157     int image_y1 = data->texture.y1;
    5158     int image_x2 = data->texture.x2;
    5159     int image_y2 = data->texture.y2;
    5160     const int scanline_offset = data->texture.bytesPerLine / 4;
    5161 
    5162     if (data->fast_matrix) {
    5163         // The increment pr x in the scanline
    5164         int fdx = (int)(data->m11 * fixed_scale);
    5165         int fdy = (int)(data->m12 * fixed_scale);
    5166 
    5167         while (count--) {
    5168             void *t = data->rasterBuffer->scanLine(spans->y);
    5169 
    5170             uint *target = ((uint *)t) + spans->x;
    5171             uint *image_bits = (uint *)data->texture.imageData;
    5172 
    5173             const qreal cx = spans->x + 0.5;
    5174             const qreal cy = spans->y + 0.5;
    5175 
    5176             int x = int((data->m21 * cy
    5177                          + data->m11 * cx + data->dx) * fixed_scale) - half_point;
    5178             int y = int((data->m22 * cy
    5179                          + data->m12 * cx + data->dy) * fixed_scale) - half_point;
    5180 
    5181             int length = spans->len;
    5182             const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
    5183             while (length) {
    5184                 int l = qMin(length, buffer_size);
    5185                 const uint *end = buffer + l;
    5186                 uint *b = buffer;
    5187                 while (b < end) {
    5188                     int x1 = (x >> 16);
    5189                     int x2 = x1 + 1;
    5190                     int y1 = (y >> 16);
    5191                     int y2 = y1 + 1;
    5192 
    5193                     int distx = ((x - (x1 << 16)) >> 8);
    5194                     int disty = ((y - (y1 << 16)) >> 8);
    5195                     int idistx = 256 - distx;
    5196                     int idisty = 256 - disty;
    5197 
    5198                     x1 = qBound(image_x1, x1, image_x2 - 1);
    5199                     x2 = qBound(image_x1, x2, image_x2 - 1);
    5200                     y1 = qBound(image_y1, y1, image_y2 - 1);
    5201                     y2 = qBound(image_y1, y2, image_y2 - 1);
    5202 
    5203                     int y1_offset = y1 * scanline_offset;
    5204                     int y2_offset = y2 * scanline_offset;
    5205 
    5206 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
    5207                     uint tl = gccBug(image_bits[y1_offset + x1]);
    5208                     uint tr = gccBug(image_bits[y1_offset + x2]);
    5209                     uint bl = gccBug(image_bits[y2_offset + x1]);
    5210                     uint br = gccBug(image_bits[y2_offset + x2]);
    5211 #else
    5212                     uint tl = image_bits[y1_offset + x1];
    5213                     uint tr = image_bits[y1_offset + x2];
    5214                     uint bl = image_bits[y2_offset + x1];
    5215                     uint br = image_bits[y2_offset + x2];
    5216 #endif
    5217 
    5218                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
    5219                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
    5220                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
    5221                     ++b;
    5222 
    5223                     x += fdx;
    5224                     y += fdy;
    5225                 }
    5226                 if (spanMethod == RegularSpans)
    5227                     func(target, buffer, l, coverage);
    5228                 else
    5229                     drawBufferSpan(data, buffer, buffer_size,
    5230                                    spans->x + spans->len - length,
    5231                                    spans->y, l, coverage);
    5232                 target += l;
    5233                 length -= l;
    5234             }
    5235             ++spans;
    5236         }
    5237     } else {
    5238         const qreal fdx = data->m11;
    5239         const qreal fdy = data->m12;
    5240         const qreal fdw = data->m13;
    5241 
    5242         while (count--) {
    5243             void *t = data->rasterBuffer->scanLine(spans->y);
    5244 
    5245             uint *target = ((uint *)t) + spans->x;
    5246             uint *image_bits = (uint *)data->texture.imageData;
    5247 
    5248             const qreal cx = spans->x + 0.5;
    5249             const qreal cy = spans->y + 0.5;
    5250 
    5251             qreal x = data->m21 * cy + data->m11 * cx + data->dx;
    5252             qreal y = data->m22 * cy + data->m12 * cx + data->dy;
    5253             qreal w = data->m23 * cy + data->m13 * cx + data->m33;
    5254 
    5255             int length = spans->len;
    5256             const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
    5257             while (length) {
    5258                 int l = qMin(length, buffer_size);
    5259                 const uint *end = buffer + l;
    5260                 uint *b = buffer;
    5261                 while (b < end) {
    5262                     const qreal iw = w == 0 ? 1 : 1 / w;
    5263                     const qreal px = x * iw - 0.5;
    5264                     const qreal py = y * iw - 0.5;
    5265 
    5266                     int x1 = int(px) - (px < 0);
    5267                     int x2 = x1 + 1;
    5268                     int y1 = int(py) - (py < 0);
    5269                     int y2 = y1 + 1;
    5270 
    5271                     int distx = int((px - x1) * 256);
    5272                     int disty = int((py - y1) * 256);
    5273                     int idistx = 256 - distx;
    5274                     int idisty = 256 - disty;
    5275 
    5276                     x1 = qBound(image_x1, x1, image_x2 - 1);
    5277                     x2 = qBound(image_x1, x2, image_x2 - 1);
    5278                     y1 = qBound(image_y1, y1, image_y2 - 1);
    5279                     y2 = qBound(image_y1, y2, image_y2 - 1);
    5280 
    5281                     int y1_offset = y1 * scanline_offset;
    5282                     int y2_offset = y2 * scanline_offset;
    5283 
    5284 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
    5285                     uint tl = gccBug(image_bits[y1_offset + x1]);
    5286                     uint tr = gccBug(image_bits[y1_offset + x2]);
    5287                     uint bl = gccBug(image_bits[y2_offset + x1]);
    5288                     uint br = gccBug(image_bits[y2_offset + x2]);
    5289 #else
    5290                     uint tl = image_bits[y1_offset + x1];
    5291                     uint tr = image_bits[y1_offset + x2];
    5292                     uint bl = image_bits[y2_offset + x1];
    5293                     uint br = image_bits[y2_offset + x2];
    5294 #endif
    5295 
    5296                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
    5297                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
    5298                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
    5299                     ++b;
    5300 
    5301                     x += fdx;
    5302                     y += fdy;
    5303                     w += fdw;
    5304                 }
    5305                 if (spanMethod == RegularSpans)
    5306                     func(target, buffer, l, coverage);
    5307                 else
    5308                     drawBufferSpan(data, buffer, buffer_size,
    5309                                    spans->x + spans->len - length,
    5310                                    spans->y, l, coverage);
    5311                 target += l;
    5312                 length -= l;
    5313             }
    5314             ++spans;
    5315         }
    5316     }
    53175551}
    53185552
     
    53665600                while (b < end) {
    53675601                    int x1 = (x >> 16);
    5368                     int x2 = x1 + 1;
     5602                    int x2;
    53695603                    int y1 = (y >> 16);
    5370                     int y2 = y1 + 1;
    5371 
    5372                     const int distx = ((x - (x1 << 16)) >> 8);
    5373                     const int disty = ((y - (y1 << 16)) >> 8);
    5374                     x1 = qBound(src_minx, x1, src_maxx);
    5375                     x2 = qBound(src_minx, x2, src_maxx);
    5376                     y1 = qBound(src_miny, y1, src_maxy);
    5377                     y2 = qBound(src_miny, y2, src_maxy);
    5378 
     5604                    int y2;
     5605
     5606                    const int distx = (x & 0x0000ffff) >> 8;
     5607                    const int disty = (y & 0x0000ffff) >> 8;
     5608
     5609                    if (x1 < src_minx) {
     5610                        x2 = x1 = src_minx;
     5611                    } else if (x1 >= src_maxx) {
     5612                        x2 = x1 = src_maxx;
     5613                    } else {
     5614                        x2 = x1 + 1;
     5615                    }
     5616                    if (y1 < src_miny) {
     5617                        y2 = y1 = src_miny;
     5618                    } else if (y1 >= src_maxy) {
     5619                        y2 = y1 = src_maxy;
     5620                    } else {
     5621                        y2 = y1 + 1;
     5622                    }
    53795623#if 0
    53805624                    if (x1 == x2) {
     
    54675711
    54685712                    int x1 = int(px) - (px < 0);
    5469                     int x2 = x1 + 1;
     5713                    int x2;
    54705714                    int y1 = int(py) - (py < 0);
    5471                     int y2 = y1 + 1;
     5715                    int y2;
    54725716
    54735717                    const int distx = int((px - x1) * 256);
    54745718                    const int disty = int((py - y1) * 256);
    54755719
    5476                     x1 = qBound(src_minx, x1, src_maxx);
    5477                     x2 = qBound(src_minx, x2, src_maxx);
    5478                     y1 = qBound(src_miny, y1, src_maxy);
    5479                     y2 = qBound(src_miny, y2, src_maxy);
     5720                    if (x1 < src_minx) {
     5721                        x2 = x1 = src_minx;
     5722                    } else if (x1 >= src_maxx) {
     5723                        x2 = x1 = src_maxx;
     5724                    } else {
     5725                        x2 = x1 + 1;
     5726                    }
     5727                    if (y1 < src_miny) {
     5728                        y2 = y1 = src_miny;
     5729                    } else if (y1 >= src_maxy) {
     5730                        y2 = y1 = src_maxy;
     5731                    } else {
     5732                        y2 = y1 + 1;
     5733                    }
    54805734
    54815735                    const SRC *src1 = (SRC*)data->texture.scanLine(y1);
     
    55775831                                              void *userData)
    55785832{
    5579 #if defined(QT_QWS_DEPTH_16)
     5833#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
    55805834    QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    55815835
     
    56435897#endif
    56445898        blend_src_generic<RegularSpans>(count, spans, userData);
    5645 }
    5646 
    5647 template <SpanMethod spanMethod>
    5648 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData)
    5649 {
    5650     QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    5651     if (data->texture.format != QImage::Format_ARGB32_Premultiplied
    5652         && data->texture.format != QImage::Format_RGB32) {
    5653         blend_src_generic<spanMethod>(count, spans, userData);
    5654         return;
    5655     }
    5656 
    5657     CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
    5658     uint buffer[buffer_size];
    5659 
    5660     int image_width = data->texture.width;
    5661     int image_height = data->texture.height;
    5662     const int scanline_offset = data->texture.bytesPerLine / 4;
    5663 
    5664     if (data->fast_matrix) {
    5665         // The increment pr x in the scanline
    5666         int fdx = (int)(data->m11 * fixed_scale);
    5667         int fdy = (int)(data->m12 * fixed_scale);
    5668 
    5669         while (count--) {
    5670             void *t = data->rasterBuffer->scanLine(spans->y);
    5671 
    5672             uint *target = ((uint *)t) + spans->x;
    5673             uint *image_bits = (uint *)data->texture.imageData;
    5674 
    5675             const qreal cx = spans->x + 0.5;
    5676             const qreal cy = spans->y + 0.5;
    5677 
    5678             int x = int((data->m21 * cy
    5679                          + data->m11 * cx + data->dx) * fixed_scale) - half_point;
    5680             int y = int((data->m22 * cy
    5681                          + data->m12 * cx + data->dy) * fixed_scale) - half_point;
    5682 
    5683             int length = spans->len;
    5684             const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
    5685             while (length) {
    5686                 int l = qMin(length, buffer_size);
    5687                 const uint *end = buffer + l;
    5688                 uint *b = buffer;
    5689                 while (b < end) {
    5690                     int x1 = (x >> 16);
    5691                     int x2 = (x1 + 1);
    5692                     int y1 = (y >> 16);
    5693                     int y2 = (y1 + 1);
    5694 
    5695                     int distx = ((x - (x1 << 16)) >> 8);
    5696                     int disty = ((y - (y1 << 16)) >> 8);
    5697                     int idistx = 256 - distx;
    5698                     int idisty = 256 - disty;
    5699 
    5700                     x1 %= image_width;
    5701                     x2 %= image_width;
    5702                     y1 %= image_height;
    5703                     y2 %= image_height;
    5704 
    5705                     if (x1 < 0) x1 += image_width;
    5706                     if (x2 < 0) x2 += image_width;
    5707                     if (y1 < 0) y1 += image_height;
    5708                     if (y2 < 0) y2 += image_height;
    5709 
    5710                     Q_ASSERT(x1 >= 0 && x1 < image_width);
    5711                     Q_ASSERT(x2 >= 0 && x2 < image_width);
    5712                     Q_ASSERT(y1 >= 0 && y1 < image_height);
    5713                     Q_ASSERT(y2 >= 0 && y2 < image_height);
    5714 
    5715                     int y1_offset = y1 * scanline_offset;
    5716                     int y2_offset = y2 * scanline_offset;
    5717 
    5718 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
    5719                     uint tl = gccBug(image_bits[y1_offset + x1]);
    5720                     uint tr = gccBug(image_bits[y1_offset + x2]);
    5721                     uint bl = gccBug(image_bits[y2_offset + x1]);
    5722                     uint br = gccBug(image_bits[y2_offset + x2]);
    5723 #else
    5724                     uint tl = image_bits[y1_offset + x1];
    5725                     uint tr = image_bits[y1_offset + x2];
    5726                     uint bl = image_bits[y2_offset + x1];
    5727                     uint br = image_bits[y2_offset + x2];
    5728 #endif
    5729 
    5730                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
    5731                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
    5732                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
    5733                     ++b;
    5734                     x += fdx;
    5735                     y += fdy;
    5736                 }
    5737                 if (spanMethod == RegularSpans)
    5738                     func(target, buffer, l, coverage);
    5739                 else
    5740                     drawBufferSpan(data, buffer, buffer_size,
    5741                                    spans->x + spans->len - length,
    5742                                    spans->y, l, coverage);
    5743                 target += l;
    5744                 length -= l;
    5745             }
    5746             ++spans;
    5747         }
    5748     } else {
    5749         const qreal fdx = data->m11;
    5750         const qreal fdy = data->m12;
    5751         const qreal fdw = data->m13;
    5752         while (count--) {
    5753             void *t = data->rasterBuffer->scanLine(spans->y);
    5754 
    5755             uint *target = ((uint *)t) + spans->x;
    5756             uint *image_bits = (uint *)data->texture.imageData;
    5757 
    5758             const qreal cx = spans->x + 0.5;
    5759             const qreal cy = spans->y + 0.5;
    5760 
    5761             qreal x = data->m21 * cy + data->m11 * cx + data->dx;
    5762             qreal y = data->m22 * cy + data->m12 * cx + data->dy;
    5763             qreal w = data->m23 * cy + data->m13 * cx + data->m33;
    5764 
    5765             int length = spans->len;
    5766             const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
    5767             while (length) {
    5768                 int l = qMin(length, buffer_size);
    5769                 const uint *end = buffer + l;
    5770                 uint *b = buffer;
    5771                 while (b < end) {
    5772                     const qreal iw = w == 0 ? 1 : 1 / w;
    5773                     const qreal px = x * iw - 0.5;
    5774                     const qreal py = y * iw - 0.5;
    5775 
    5776                     int x1 = int(px) - (px < 0);
    5777                     int x2 = x1 + 1;
    5778                     int y1 = int(py) - (py < 0);
    5779                     int y2 = y1 + 1;
    5780 
    5781                     int distx = int((px - x1) * 256);
    5782                     int disty = int((py - y1) * 256);
    5783                     int idistx = 256 - distx;
    5784                     int idisty = 256 - disty;
    5785 
    5786                     x1 %= image_width;
    5787                     x2 %= image_width;
    5788                     y1 %= image_height;
    5789                     y2 %= image_height;
    5790 
    5791                     if (x1 < 0) x1 += image_width;
    5792                     if (x2 < 0) x2 += image_width;
    5793                     if (y1 < 0) y1 += image_height;
    5794                     if (y2 < 0) y2 += image_height;
    5795 
    5796                     Q_ASSERT(x1 >= 0 && x1 < image_width);
    5797                     Q_ASSERT(x2 >= 0 && x2 < image_width);
    5798                     Q_ASSERT(y1 >= 0 && y1 < image_height);
    5799                     Q_ASSERT(y2 >= 0 && y2 < image_height);
    5800 
    5801                     int y1_offset = y1 * scanline_offset;
    5802                     int y2_offset = y2 * scanline_offset;
    5803 
    5804 #if defined(Q_IRIX_GCC3_3_WORKAROUND)
    5805                     uint tl = gccBug(image_bits[y1_offset + x1]);
    5806                     uint tr = gccBug(image_bits[y1_offset + x2]);
    5807                     uint bl = gccBug(image_bits[y2_offset + x1]);
    5808                     uint br = gccBug(image_bits[y2_offset + x2]);
    5809 #else
    5810                     uint tl = image_bits[y1_offset + x1];
    5811                     uint tr = image_bits[y1_offset + x2];
    5812                     uint bl = image_bits[y2_offset + x1];
    5813                     uint br = image_bits[y2_offset + x2];
    5814 #endif
    5815 
    5816                     uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
    5817                     uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
    5818                     *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
    5819                     ++b;
    5820                     x += fdx;
    5821                     y += fdy;
    5822                     w += fdw;
    5823                 }
    5824                 if (spanMethod == RegularSpans)
    5825                     func(target, buffer, l, coverage);
    5826                 else
    5827                     drawBufferSpan(data, buffer, buffer_size,
    5828                                    spans->x + spans->len - length,
    5829                                    spans->y, l, coverage);
    5830                 target += l;
    5831                 length -= l;
    5832             }
    5833             ++spans;
    5834         }
    5835     }
    58365899}
    58375900
     
    61646227                                       void *userData)
    61656228{
    6166 #if defined(QT_QWS_DEPTH_16)
     6229#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
    61676230    QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    61686231
     
    64806543                    int py = int(ty) - (ty < 0);
    64816544
     6545                    px %= image_width;
     6546                    py %= image_height;
    64826547                    if (px < 0)
    64836548                        px += image_width;
     
    65776642                                           void *userData)
    65786643{
    6579 #if defined(QT_QWS_DEPTH_16)
     6644#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
    65806645    QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    65816646
     
    67386803        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
    67396804        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
    6740         SPANFUNC_POINTER(blend_transformed_bilinear_argb, RegularSpans), // ARGB32_Premultiplied
     6805        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
    67416806        blend_transformed_bilinear_rgb565,
    67426807        blend_transformed_bilinear_argb8565,
     
    67576822        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
    67586823        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
    6759         SPANFUNC_POINTER(blend_transformed_bilinear_tiled_argb, RegularSpans), // ARGB32_Premultiplied
     6824        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
    67606825        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16
    67616826        SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied
     
    68566921        blend_src_generic<CallbackSpans>,   // RGB32
    68576922        blend_src_generic<CallbackSpans>,   // ARGB32
    6858         blend_transformed_bilinear_argb<CallbackSpans>, // ARGB32_Premultiplied
     6923        blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
    68596924        blend_src_generic<CallbackSpans>,   // RGB16
    68606925        blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
     
    68756940        blend_src_generic<CallbackSpans>,   // RGB32
    68766941        blend_src_generic<CallbackSpans>,   // ARGB32
    6877         blend_transformed_bilinear_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied
     6942        blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
    68786943        blend_src_generic<CallbackSpans>,   // RGB16
    68796944        blend_src_generic<CallbackSpans>,   // ARGB8565_Premultiplied
     
    71357200    if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
    71367201        smoothing = winSmooth / 1000.0;
     7202
     7203    // Safeguard ourselves against corrupt registry values...
     7204    if (smoothing > 5 || smoothing < 1)
     7205        smoothing = 1.4;
     7206
    71377207#endif
    71387208
     
    77217791qt_memfill16_func qt_memfill16 = qt_memfill16_setup;
    77227792
    7723 enum CPUFeatures {
    7724     None        = 0,
    7725     MMX         = 0x1,
    7726     MMXEXT      = 0x2,
    7727     MMX3DNOW    = 0x4,
    7728     MMX3DNOWEXT = 0x8,
    7729     SSE         = 0x10,
    7730     SSE2        = 0x20,
    7731     CMOV        = 0x40,
    7732     IWMMXT      = 0x80,
    7733     NEON        = 0x100
    7734 };
    7735 
    7736 static uint detectCPUFeatures()
    7737 {
    7738 #if defined (Q_OS_WINCE)
    7739 #if defined (ARM)
    7740     if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX))
    7741         return IWMMXT;
    7742 #elif defined(_X86_)
    7743     uint features = 0;
    7744 #if defined QT_HAVE_MMX
    7745     if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))
    7746         features |= MMX;
    7747 #endif
    7748 #if defined QT_HAVE_3DNOW
    7749     if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE))
    7750         features |= MMX3DNOW;
    7751 #endif
    7752     return features;
    7753 #endif
    7754     return 0;
    7755 #elif defined(QT_HAVE_IWMMXT)
    7756     // runtime detection only available when running as a previlegied process
    7757     static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
    7758     return doIWMMXT ? IWMMXT : 0;
    7759 #elif defined(QT_HAVE_NEON)
    7760     static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
    7761     return doNEON ? NEON : 0;
    7762 #else
    7763     uint features = 0;
    7764 #if defined(__x86_64__) || defined(Q_OS_WIN64)
    7765     features = MMX|SSE|SSE2|CMOV;
    7766 #elif defined(__ia64__)
    7767     features = MMX|SSE|SSE2;
    7768 #elif defined(__i386__) || defined(_M_IX86)
    7769     unsigned int extended_result = 0;
    7770     uint result = 0;
    7771     /* see p. 118 of amd64 instruction set manual Vol3 */
    7772 #if defined(Q_CC_GNU)
    7773     asm ("push %%ebx\n"
    7774          "pushf\n"
    7775          "pop %%eax\n"
    7776          "mov %%eax, %%ebx\n"
    7777          "xor $0x00200000, %%eax\n"
    7778          "push %%eax\n"
    7779          "popf\n"
    7780          "pushf\n"
    7781          "pop %%eax\n"
    7782          "xor %%edx, %%edx\n"
    7783          "xor %%ebx, %%eax\n"
    7784          "jz 1f\n"
    7785 
    7786          "mov $0x00000001, %%eax\n"
    7787          "cpuid\n"
    7788          "1:\n"
    7789          "pop %%ebx\n"
    7790          "mov %%edx, %0\n"
    7791         : "=r" (result)
    7792         :
    7793         : "%eax", "%ecx", "%edx"
    7794         );
    7795 
    7796     asm ("push %%ebx\n"
    7797          "pushf\n"
    7798          "pop %%eax\n"
    7799          "mov %%eax, %%ebx\n"
    7800          "xor $0x00200000, %%eax\n"
    7801          "push %%eax\n"
    7802          "popf\n"
    7803          "pushf\n"
    7804          "pop %%eax\n"
    7805          "xor %%edx, %%edx\n"
    7806          "xor %%ebx, %%eax\n"
    7807          "jz 2f\n"
    7808 
    7809          "mov $0x80000000, %%eax\n"
    7810          "cpuid\n"
    7811          "cmp $0x80000000, %%eax\n"
    7812          "jbe 2f\n"
    7813          "mov $0x80000001, %%eax\n"
    7814          "cpuid\n"
    7815          "2:\n"
    7816          "pop %%ebx\n"
    7817          "mov %%edx, %0\n"
    7818         : "=r" (extended_result)
    7819         :
    7820         : "%eax", "%ecx", "%edx"
    7821         );
    7822 #elif defined (Q_OS_WIN)
    7823     _asm {
    7824         push eax
    7825         push ebx
    7826         push ecx
    7827         push edx
    7828         pushfd
    7829         pop eax
    7830         mov ebx, eax
    7831         xor eax, 00200000h
    7832         push eax
    7833         popfd
    7834         pushfd
    7835         pop eax
    7836         mov edx, 0
    7837         xor eax, ebx
    7838         jz skip
    7839 
    7840         mov eax, 1
    7841         cpuid
    7842         mov result, edx
    7843     skip:
    7844         pop edx
    7845         pop ecx
    7846         pop ebx
    7847         pop eax
    7848     }
    7849 
    7850     _asm {
    7851         push eax
    7852         push ebx
    7853         push ecx
    7854         push edx
    7855         pushfd
    7856         pop eax
    7857         mov ebx, eax
    7858         xor eax, 00200000h
    7859         push eax
    7860         popfd
    7861         pushfd
    7862         pop eax
    7863         mov edx, 0
    7864         xor eax, ebx
    7865         jz skip2
    7866 
    7867         mov eax, 80000000h
    7868         cpuid
    7869         cmp eax, 80000000h
    7870         jbe skip2
    7871         mov eax, 80000001h
    7872         cpuid
    7873         mov extended_result, edx
    7874     skip2:
    7875         pop edx
    7876         pop ecx
    7877         pop ebx
    7878         pop eax
    7879     }
    7880 #endif
    7881 
    7882     // result now contains the standard feature bits
    7883     if (result & (1u << 15))
    7884         features |= CMOV;
    7885     if (result & (1u << 23))
    7886         features |= MMX;
    7887     if (extended_result & (1u << 22))
    7888         features |= MMXEXT;
    7889     if (extended_result & (1u << 31))
    7890         features |= MMX3DNOW;
    7891     if (extended_result & (1u << 30))
    7892         features |= MMX3DNOWEXT;
    7893     if (result & (1u << 25))
    7894         features |= SSE;
    7895     if (result & (1u << 26))
    7896         features |= SSE2;
    7897 #endif // i386
    7898 
    7899     if (qgetenv("QT_NO_MMX").toInt())
    7900         features ^= MMX;
    7901     if (qgetenv("QT_NO_MMXEXT").toInt())
    7902         features ^= MMXEXT;
    7903     if (qgetenv("QT_NO_3DNOW").toInt())
    7904         features ^= MMX3DNOW;
    7905     if (qgetenv("QT_NO_3DNOWEXT").toInt())
    7906         features ^= MMX3DNOWEXT;
    7907     if (qgetenv("QT_NO_SSE").toInt())
    7908         features ^= SSE;
    7909     if (qgetenv("QT_NO_SSE2").toInt())
    7910         features ^= SSE2;
    7911 
    7912     return features;
    7913 #endif
    7914 }
    7915 
    7916 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6)
    7917 // Move these to qdrawhelper_arm.c when all
    7918 // functions are implemented using arm assembly.
    7919 static CompositionFunctionSolid qt_functionForModeSolid_ARMv6[numCompositionFunctions] = {
    7920         comp_func_solid_SourceOver,
    7921         comp_func_solid_DestinationOver,
    7922         comp_func_solid_Clear,
    7923         comp_func_solid_Source,
    7924         comp_func_solid_Destination,
    7925         comp_func_solid_SourceIn,
    7926         comp_func_solid_DestinationIn,
    7927         comp_func_solid_SourceOut,
    7928         comp_func_solid_DestinationOut,
    7929         comp_func_solid_SourceAtop,
    7930         comp_func_solid_DestinationAtop,
    7931         comp_func_solid_XOR,
    7932         comp_func_solid_Plus,
    7933         comp_func_solid_Multiply,
    7934         comp_func_solid_Screen,
    7935         comp_func_solid_Overlay,
    7936         comp_func_solid_Darken,
    7937         comp_func_solid_Lighten,
    7938         comp_func_solid_ColorDodge,
    7939         comp_func_solid_ColorBurn,
    7940         comp_func_solid_HardLight,
    7941         comp_func_solid_SoftLight,
    7942         comp_func_solid_Difference,
    7943         comp_func_solid_Exclusion,
    7944         rasterop_solid_SourceOrDestination,
    7945         rasterop_solid_SourceAndDestination,
    7946         rasterop_solid_SourceXorDestination,
    7947         rasterop_solid_NotSourceAndNotDestination,
    7948         rasterop_solid_NotSourceOrNotDestination,
    7949         rasterop_solid_NotSourceXorDestination,
    7950         rasterop_solid_NotSource,
    7951         rasterop_solid_NotSourceAndDestination,
    7952         rasterop_solid_SourceAndNotDestination
    7953 };
    7954 
    7955 static CompositionFunction qt_functionForMode_ARMv6[numCompositionFunctions] = {
    7956         comp_func_SourceOver_armv6,
    7957         comp_func_DestinationOver,
    7958         comp_func_Clear,
    7959         comp_func_Source_armv6,
    7960         comp_func_Destination,
    7961         comp_func_SourceIn,
    7962         comp_func_DestinationIn,
    7963         comp_func_SourceOut,
    7964         comp_func_DestinationOut,
    7965         comp_func_SourceAtop,
    7966         comp_func_DestinationAtop,
    7967         comp_func_XOR,
    7968         comp_func_Plus,
    7969         comp_func_Multiply,
    7970         comp_func_Screen,
    7971         comp_func_Overlay,
    7972         comp_func_Darken,
    7973         comp_func_Lighten,
    7974         comp_func_ColorDodge,
    7975         comp_func_ColorBurn,
    7976         comp_func_HardLight,
    7977         comp_func_SoftLight,
    7978         comp_func_Difference,
    7979         comp_func_Exclusion,
    7980         rasterop_SourceOrDestination,
    7981         rasterop_SourceAndDestination,
    7982         rasterop_SourceXorDestination,
    7983         rasterop_NotSourceAndNotDestination,
    7984         rasterop_NotSourceOrNotDestination,
    7985         rasterop_NotSourceXorDestination,
    7986         rasterop_NotSource,
    7987         rasterop_NotSourceAndDestination,
    7988         rasterop_SourceAndNotDestination
    7989 };
    7990 
    7991 static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userData)
    7992 {
    7993     QSpanData *data = reinterpret_cast<QSpanData *>(userData);
    7994 
    7995     CompositionFunctionSolid func = qt_functionForModeSolid_ARMv6[data->rasterBuffer->compositionMode];
    7996     while (count--) {
    7997         uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
    7998         func(target, spans->len, data->solid.color, spans->coverage);
    7999         ++spans;
    8000     }
    8001 }
    8002 
    8003 #endif // Q_CC_RVCT && QT_HAVE_ARMV6
    8004 
    8005 
    80067793void qInitDrawhelperAsm()
    80077794{
    8008     static uint features = 0xffffffff;
    8009     if (features != 0xffffffff)
    8010         return;
    8011     features = detectCPUFeatures();
    80127795
    80137796    qt_memfill32 = qt_memfill_template<quint32, quint32>;
     
    80177800    CompositionFunctionSolid *functionForModeSolidAsm = 0;
    80187801
    8019 #ifdef QT_NO_DEBUG
     7802    const uint features = qDetectCPUFeatures();
    80207803    if (false) {
    80217804#ifdef QT_HAVE_SSE2
     
    80397822#endif
    80407823#endif // SSE
    8041 #if defined(QT_HAVE_MMXEXT) && defined(QT_HAVE_SSE)
    8042     } else if (features & MMXEXT) {
    8043         qt_memfill32 = qt_memfill32_sse;
    8044         qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse;
    8045 # ifdef QT_HAVE_3DNOW
    8046         if (features & MMX3DNOW) {
    8047             qt_memfill32 = qt_memfill32_sse3dnow;
    8048             qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse3dnow;
    8049         }
    8050 # endif // 3DNOW
    8051 #endif // MMXEXT
    80527824    }
    80537825#ifdef QT_HAVE_MMX
    80547826    if (features & MMX) {
    80557827        functionForModeAsm = qt_functionForMode_MMX;
     7828
    80567829        functionForModeSolidAsm = qt_functionForModeSolid_MMX;
    80577830        qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx;
     
    80807853    }
    80817854#endif // MMX
     7855
     7856#ifdef QT_HAVE_SSE
     7857    if (features & SSE) {
     7858        extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
     7859                                                const uchar *srcPixels, int sbpl,
     7860                                                int w, int h,
     7861                                                int const_alpha);
     7862        extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
     7863                                                  const uchar *srcPixels, int sbpl,
     7864                                                  int w, int h,
     7865                                                  int const_alpha);
     7866
     7867        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
     7868        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
     7869        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
     7870        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
     7871    }
     7872#endif // SSE
     7873
     7874#ifdef QT_HAVE_SSE2
     7875    if (features & SSE2) {
     7876        extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
     7877                                                 const uchar *srcPixels, int sbpl,
     7878                                                 int w, int h,
     7879                                                 int const_alpha);
     7880        extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
     7881                                                   const uchar *srcPixels, int sbpl,
     7882                                                   int w, int h,
     7883                                                   int const_alpha);
     7884
     7885        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
     7886        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
     7887        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
     7888        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
     7889    }
     7890
     7891#ifdef QT_HAVE_SSSE3
     7892    if (features & SSSE3) {
     7893        extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
     7894                                                    const uchar *srcPixels, int sbpl,
     7895                                                    int w, int h,
     7896                                                    int const_alpha);
     7897
     7898        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
     7899        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
     7900    }
     7901#endif // SSSE3
     7902
     7903#endif // SSE2
    80827904
    80837905#ifdef QT_HAVE_SSE
     
    80977919#ifdef QT_HAVE_SSE2
    80987920        if (features & SSE2) {
    8099             extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
    8100                                                      const uchar *srcPixels, int sbpl,
    8101                                                      int w, int h,
    8102                                                      int const_alpha);
    8103             extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
    8104                                                        const uchar *srcPixels, int sbpl,
    8105                                                        int w, int h,
    8106                                                        int const_alpha);
    8107 
    8108 
    8109             qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
    8110             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
    8111             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
    8112             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
    8113         } else
     7921            extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
     7922                                                              const uint *srcPixels,
     7923                                                              int length,
     7924                                                              uint const_alpha);
     7925            extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
     7926            extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha);
     7927            extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha);
     7928
     7929            functionForModeAsm[0] = comp_func_SourceOver_sse2;
     7930            functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
     7931            functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
     7932            functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2;
     7933        }
    81147934#endif
    8115         {
    8116             extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl,
    8117                                                     const uchar *srcPixels, int sbpl,
    8118                                                     int w, int h,
    8119                                                     int const_alpha);
    8120             extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl,
    8121                                                       const uchar *srcPixels, int sbpl,
    8122                                                       int w, int h,
    8123                                                       int const_alpha);
    8124 
    8125 
    8126             qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
    8127             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse;
    8128             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
    8129             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse;
    8130         }
    8131 }
    8132 #endif // SSE
     7935    }
     7936#elif defined(QT_HAVE_SSE2)
     7937    // this is the special case when SSE2 is usable but MMX/SSE is not usable (e.g.: Windows x64 + visual studio)
     7938    if (features & SSE2) {
     7939        functionForModeAsm = qt_functionForMode_onlySSE2;
     7940        functionForModeSolidAsm = qt_functionForModeSolid_onlySSE2;
     7941    }
     7942#endif
    81337943
    81347944#ifdef QT_HAVE_IWMMXT
     
    81407950#endif // IWMMXT
    81417951
    8142 #endif // QT_NO_DEBUG
    8143 
    8144 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6)
    8145         functionForModeAsm = qt_functionForMode_ARMv6;
    8146         functionForModeSolidAsm = qt_functionForModeSolid_ARMv6;
    8147 
    8148         qt_memfill32 = qt_memfill32_armv6;
    8149 
    8150         qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_armv6;
    8151 
    8152         qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6;
    8153         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6;
    8154         qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
    8155         qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
     7952#if defined(QT_HAVE_ARM_SIMD)
     7953    qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd;
     7954    qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd;
     7955    qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd;
     7956    qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd;
    81567957#elif defined(QT_HAVE_NEON)
    8157         if (features & NEON) {
    8158             qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
    8159             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
    8160             qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
    8161             qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
    8162         }
     7958    if (features & NEON) {
     7959        qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
     7960        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
     7961        qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
     7962        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
     7963        qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
     7964        qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
     7965        qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
     7966
     7967        qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
     7968        qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
     7969
     7970        qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
     7971        qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
     7972
     7973        qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
     7974
     7975        functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
     7976        functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
     7977        functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
     7978        destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
     7979        destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
     7980
     7981        qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
     7982        qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
     7983        qt_memfill32 = qt_memfill32_neon;
     7984    }
    81637985#endif
    81647986
     
    81747996        functionForModeSolid = functionForModeSolidAsm;
    81757997    }
    8176     if (functionForModeAsm) {
    8177         const int destinationMode = QPainter::CompositionMode_Destination;
    8178         functionForModeAsm[destinationMode] = functionForMode_C[destinationMode];
    8179 
    8180         // use the default qdrawhelper implementation for the
    8181         // extended composition modes
    8182         for (int mode = 12; mode < numCompositionFunctions; ++mode)
    8183             functionForModeAsm[mode] = functionForMode_C[mode];
    8184 
     7998    if (functionForModeAsm)
    81857999        functionForMode = functionForModeAsm;
    8186     }
    81878000
    81888001    qt_build_pow_tables();
Note: See TracChangeset for help on using the changeset viewer.