diff options
Diffstat (limited to 'src/gui/painting/qdrawhelper.cpp')
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 1387 |
1 files changed, 678 insertions, 709 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 1f0280e..ab192c5 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -38,15 +38,18 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include <private/qdrawhelper_p.h> #include <private/qpaintengine_raster_p.h> #include <private/qpainter_p.h> #include <private/qdrawhelper_x86_p.h> +#include <private/qdrawhelper_armv6_p.h> #include <private/qmath_p.h> #include <qmath.h> QT_BEGIN_NAMESPACE + #define MASK(src, a) src = BYTE_MUL(src, a) #if defined(Q_OS_IRIX) && defined(Q_CC_GNU) && __GNUC__ == 3 && __GNUC__ < 4 && QT_POINTER_SIZE == 8 @@ -157,46 +160,9 @@ static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuff return buffer; } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) -template <typename EnumType, int value> -class QEnumToType -{ -public: - inline EnumType operator()() const - { - return EnumType(value); - } -}; -template <QImage::Format format> -class QImageFormatToType -{ -public: - inline QImage::Format operator()() const - { - return format; - } -}; -// Would have used QEnumToType instead of creating a specialized version for QImageFormatToType, -// but that causes internal compiler error on VC6 -#define Q_TEMPLATE_IMAGEFORMAT_FIX(format) , const QImageFormatToType<format> &imageFormatType -#define Q_TEMPLATE_IMAGEFORMAT_CALL(format) , QImageFormatToType<format>() -#define Q_TEMPLATE_ENUM_FIX(Type, Value) , const QEnumToType<Type, Value> &enumTemplateType -#define Q_TEMPLATE_ENUM_CALL(Type, Value) , QEnumToType<Type, Value>() -#define Q_TEMPLATE_FIX(Type) , const QTypeInfo<Type> &templateType -#define Q_TEMPLATE_CALL(Type) , QTypeInfo<Type>() -#else -#define Q_TEMPLATE_IMAGEFORMAT_FIX(format) -#define Q_TEMPLATE_IMAGEFORMAT_CALL(format) -#define Q_TEMPLATE_ENUM_FIX(Type, Value) -#define Q_TEMPLATE_ENUM_CALL(Type, Value) -#define Q_TEMPLATE_FIX(Type) -#define Q_TEMPLATE_CALL(Type) -#endif - template <class DST> Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, - int x, int y, int length - Q_TEMPLATE_FIX(DST)) + int x, int y, int length) { const DST *src = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x; quint32 *dest = reinterpret_cast<quint32*>(buffer); @@ -205,28 +171,7 @@ Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuf return buffer; } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) -#define DEST_FETCH_DECL(DST) \ - static uint * QT_FASTCALL destFetch_##DST(uint *buffer, \ - QRasterBuffer *rasterBuffer, \ - int x, int y, int length) \ - { \ - return destFetch<DST>(buffer, rasterBuffer, x, y, length Q_TEMPLATE_CALL(DST)); \ - } - -DEST_FETCH_DECL(qargb8565) -DEST_FETCH_DECL(qrgb666) -DEST_FETCH_DECL(qargb6666) -DEST_FETCH_DECL(qrgb555) -DEST_FETCH_DECL(qrgb888) -DEST_FETCH_DECL(qargb8555) -DEST_FETCH_DECL(qrgb444) -DEST_FETCH_DECL(qargb4444) -#undef DEST_FETCH_DECL -# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch_##Arg -#else // !VC6 && !VC2002 # define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg> -#endif static const DestFetchProc destFetchProc[QImage::NImageFormats] = { @@ -366,8 +311,7 @@ static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y template <class DST> Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, - const uint *buffer, int length - Q_TEMPLATE_FIX(DST)) + const uint *buffer, int length) { DST *dest = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x; const quint32p *src = reinterpret_cast<const quint32p*>(buffer); @@ -375,28 +319,7 @@ Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffe *dest++ = DST(*src++); } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) -# define DEST_STORE_DECL(DST) \ - static void QT_FASTCALL destStore_##DST(QRasterBuffer *rasterBuffer, \ - int x, int y, \ - const uint *buffer, int length) \ - { \ - destStore<DST>(rasterBuffer, x, y, buffer, length Q_TEMPLATE_CALL(DST)); \ - } - -DEST_STORE_DECL(qargb8565) -DEST_STORE_DECL(qrgb555) -DEST_STORE_DECL(qrgb666) -DEST_STORE_DECL(qargb6666) -DEST_STORE_DECL(qargb8555) -DEST_STORE_DECL(qrgb888) -DEST_STORE_DECL(qrgb444) -DEST_STORE_DECL(qargb4444) -# undef DEST_FETCH_DECL -# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore_##DEST -#else // !VC6 && !VC2002 # define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST> -#endif static const DestStoreProc destStoreProc[QImage::NImageFormats] = { @@ -425,10 +348,8 @@ static const DestStoreProc destStoreProc[QImage::NImageFormats] = We need 5 fetch methods per surface type: untransformed - transformed - transformed tiled - transformed bilinear - transformed bilinear tiled + transformed (tiled and not tiled) + transformed bilinear (tiled and not tiled) We don't need bounds checks for untransformed, but we need them for the other ones. @@ -436,14 +357,12 @@ static const DestStoreProc destStoreProc[QImage::NImageFormats] = */ template <QImage::Format format> -Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector<QRgb> *rgb - Q_TEMPLATE_IMAGEFORMAT_FIX(format)); +Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector<QRgb> *rgb); template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_Mono>(const uchar *scanLine, - int x, const QVector<QRgb> *rgb - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_Mono)) + int x, const QVector<QRgb> *rgb) { bool pixel = scanLine[x>>3] & (0x80 >> (x & 7)); if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0)); @@ -453,8 +372,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_Mono>(const uchar *scanLine, template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_MonoLSB>(const uchar *scanLine, - int x, const QVector<QRgb> *rgb - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_MonoLSB)) + int x, const QVector<QRgb> *rgb) { bool pixel = scanLine[x>>3] & (0x1 << (x & 7)); if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0)); @@ -464,8 +382,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_MonoLSB>(const uchar *scanLine, template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_Indexed8>(const uchar *scanLine, - int x, const QVector<QRgb> *rgb - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_Indexed8)) + int x, const QVector<QRgb> *rgb) { return PREMUL(rgb->at(scanLine[x])); } @@ -473,8 +390,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_Indexed8>(const uchar *scanLine, template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32>(const uchar *scanLine, - int x, const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32)) + int x, const QVector<QRgb> *) { return PREMUL(((const uint *)scanLine)[x]); } @@ -482,8 +398,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32>(const uchar *scanLine, template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32_Premultiplied>(const uchar *scanLine, - int x, const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32_Premultiplied)) + int x, const QVector<QRgb> *) { return ((const uint *)scanLine)[x]; } @@ -491,8 +406,7 @@ uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32_Premultiplied>(const uchar template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB16>(const uchar *scanLine, - int x, const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB16)) + int x, const QVector<QRgb> *) { return qConvertRgb16To32(((const ushort *)scanLine)[x]); } @@ -501,8 +415,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8565_Premultiplied>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB8565_Premultiplied)) + const QVector<QRgb> *) { const qargb8565 color = reinterpret_cast<const qargb8565*>(scanLine)[x]; return qt_colorConvert<quint32, qargb8565>(color, 0); @@ -512,8 +425,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB666>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB666)) + const QVector<QRgb> *) { const qrgb666 color = reinterpret_cast<const qrgb666*>(scanLine)[x]; return qt_colorConvert<quint32, qrgb666>(color, 0); @@ -523,8 +435,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB6666_Premultiplied>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB6666_Premultiplied)) + const QVector<QRgb> *) { const qargb6666 color = reinterpret_cast<const qargb6666*>(scanLine)[x]; return qt_colorConvert<quint32, qargb6666>(color, 0); @@ -534,8 +445,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB555>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB555)) + const QVector<QRgb> *) { const qrgb555 color = reinterpret_cast<const qrgb555*>(scanLine)[x]; return qt_colorConvert<quint32, qrgb555>(color, 0); @@ -545,8 +455,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8555_Premultiplied>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB8555_Premultiplied)) + const QVector<QRgb> *) { const qargb8555 color = reinterpret_cast<const qargb8555*>(scanLine)[x]; return qt_colorConvert<quint32, qargb8555>(color, 0); @@ -556,8 +465,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB888>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB888)) + const QVector<QRgb> *) { const qrgb888 color = reinterpret_cast<const qrgb888*>(scanLine)[x]; return qt_colorConvert<quint32, qrgb888>(color, 0); @@ -567,8 +475,7 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB444>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_RGB444)) + const QVector<QRgb> *) { const qrgb444 color = reinterpret_cast<const qrgb444*>(scanLine)[x]; return qt_colorConvert<quint32, qrgb444>(color, 0); @@ -578,47 +485,24 @@ template<> Q_STATIC_TEMPLATE_SPECIALIZATION uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB4444_Premultiplied>(const uchar *scanLine, int x, - const QVector<QRgb> * - Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB4444_Premultiplied)) + const QVector<QRgb> *) { const qargb4444 color = reinterpret_cast<const qargb4444*>(scanLine)[x]; return qt_colorConvert<quint32, qargb4444>(color, 0); } -typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector<QRgb> *); - -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) - -// explicit template instantiations needed to compile with VC6 and VC2002 - -#define SPANFUNC_INSTANTIATION_FETCHPIXEL(Arg) \ - static inline uint fetchPixel_##Arg(const uchar * scanLine, int x, const QVector<QRgb> * rgb) \ -{ \ - return qt_fetchPixel<QImage::Arg>(scanLine, x, rgb Q_TEMPLATE_IMAGEFORMAT_CALL(QImage::Arg)); \ +template<> +Q_STATIC_TEMPLATE_SPECIALIZATION +uint QT_FASTCALL qt_fetchPixel<QImage::Format_Invalid>(const uchar *, + int , + const QVector<QRgb> *) +{ + return 0; } -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_Mono); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_MonoLSB); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_Indexed8); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB32_Premultiplied); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB32); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB16); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB8565_Premultiplied); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB666); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB6666_Premultiplied); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB555); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB8555_Premultiplied); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB888); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_RGB444); -SPANFUNC_INSTANTIATION_FETCHPIXEL(Format_ARGB4444_Premultiplied); - -#undef SPANFUNC_INSTANTIATION_FETCHPIXEL - -#define SPANFUNC_POINTER_FETCHPIXEL(Arg) fetchPixel_##Arg +typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector<QRgb> *); -#else // !VC6 && !VC2002 -# define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel<QImage::Arg> -#endif +#define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel<QImage::Arg> static const FetchPixelProc fetchPixelProc[QImage::NImageFormats] = @@ -653,11 +537,11 @@ enum TextureBlendType { template <QImage::Format format> Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetchUntransformed(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length Q_TEMPLATE_IMAGEFORMAT_FIX(format)) + int y, int x, int length) { const uchar *scanLine = data->texture.scanLine(y); for (int i = 0; i < length; ++i) - buffer[i] = qt_fetchPixel<format>(scanLine, x + i, data->texture.colorTable Q_TEMPLATE_IMAGEFORMAT_CALL(format)); + buffer[i] = qt_fetchPixel<format>(scanLine, x + i, data->texture.colorTable); return buffer; } @@ -665,13 +549,15 @@ template <> Q_STATIC_TEMPLATE_SPECIALIZATION const uint * QT_FASTCALL qt_fetchUntransformed<QImage::Format_ARGB32_Premultiplied>(uint *, const Operator *, const QSpanData *data, - int y, int x, int Q_TEMPLATE_IMAGEFORMAT_FIX(QImage::Format_ARGB32_Premultiplied)) + int y, int x, int) { const uchar *scanLine = data->texture.scanLine(y); return ((const uint *)scanLine) + x; } -static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, +template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { FetchPixelProc fetch = fetchPixelProc[data->texture.format]; @@ -698,84 +584,23 @@ static const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, int px = fx >> 16; int py = fy >> 16; - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); - - const uchar *scanLine = data->texture.scanLine(py); - *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable); - fx += fdx; - fy += fdy; - ++b; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; - qreal fx = data->m21 * cy + data->m11 * cx + data->dx; - qreal fy = data->m22 * cy + data->m12 * cx + data->dy; - qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - - while (b < end) { - const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal tx = fx * iw; - const qreal ty = fy * iw; - const int px = int(tx) - (tx < 0); - const int py = int(ty) - (ty < 0); - - bool out = (px < 0) || (px >= image_width) - || (py < 0) || (py >= image_height); - - const uchar *scanLine = data->texture.scanLine(py); - *b = out ? uint(0) : fetch(scanLine, px, data->texture.colorTable); - fx += fdx; - fy += fdy; - fw += fdw; - //force increment to avoid /0 - if (!fw) { - fw += fdw; + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } else { + if ((px < 0) || (px >= image_width) + || (py < 0) || (py >= image_height)) { + *b = uint(0); + } else { + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } } - ++b; - } - } - - return buffer; -} - -static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) -{ - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; - - int image_width = data->texture.width; - int image_height = data->texture.height; - - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; - - const uint *end = buffer + length; - uint *b = buffer; - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - int fx = int((data->m21 * cy - + data->m11 * cx + data->dx) * fixed_scale); - int fy = int((data->m22 * cy - + data->m12 * cx + data->dy) * fixed_scale); - - while (b < end) { - int px = fx >> 16; - int py = fy >> 16; - - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; - - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); fx += fdx; fy += fdy; ++b; @@ -796,13 +621,23 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat int px = int(tx) - (tx < 0); int py = int(ty) - (ty < 0); - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; + if (blendType == BlendTransformedTiled) { + px %= image_width; + py %= image_height; + if (px < 0) px += image_width; + if (py < 0) py += image_height; - const uchar *scanLine = data->texture.scanLine(py); - *b = fetch(scanLine, px, data->texture.colorTable); + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } else { + if ((px < 0) || (px >= image_width) + || (py < 0) || (py >= image_height)) { + *b = uint(0); + } else { + const uchar *scanLine = data->texture.scanLine(py); + *b = fetch(scanLine, px, data->texture.colorTable); + } + } fx += fdx; fy += fdy; fw += fdw; @@ -817,10 +652,20 @@ static const uint * QT_FASTCALL fetchTransformedTiled(uint *buffer, const Operat return buffer; } -static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ +Q_STATIC_TEMPLATE_FUNCTION +const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) { - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; +#ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2 + FetchPixelProc fetch; + if (format != QImage::Format_Invalid) + fetch = qt_fetchPixel<format>; + else + fetch = fetchPixelProc[data->texture.format]; +#else + FetchPixelProc fetch = (format != QImage::Format_Invalid) ? FetchPixelProc(qt_fetchPixel<format>) : fetchPixelProc[data->texture.format]; +#endif int image_width = data->texture.width; int image_height = data->texture.height; @@ -853,130 +698,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Ope int idistx = 256 - distx; int idisty = 256 - disty; - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); - - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); - - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - - fx += fdx; - fy += fdy; - ++b; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; - - qreal fx = data->m21 * cy + data->m11 * cx + data->dx; - qreal fy = data->m22 * cy + data->m12 * cx + data->dy; - qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - - while (b < end) { - const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal px = fx * iw - 0.5; - const qreal py = fy * iw - 0.5; - - int x1 = int(px) - (px < 0); - int x2 = x1 + 1; - int y1 = int(py) - (py < 0); - int y2 = y1 + 1; - - int distx = int((px - x1) * 256); - int disty = int((py - y1) * 256); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); - - const uchar *s1 = data->texture.scanLine(y1); - const uchar *s2 = data->texture.scanLine(y2); - - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - - fx += fdx; - fy += fdy; - fw += fdw; - //force increment to avoid /0 - if (!fw) { - fw += fdw; + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + x2 %= image_width; + y1 %= image_height; + y2 %= image_height; + + if (x1 < 0) x1 += image_width; + if (x2 < 0) x2 += image_width; + if (y1 < 0) y1 += image_height; + if (y2 < 0) y2 += image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + x1 = qBound(0, x1, image_width - 1); + x2 = qBound(0, x2, image_width - 1); + y1 = qBound(0, y1, image_height - 1); + y2 = qBound(0, y2, image_height - 1); } - ++b; - } - } - - return buffer; -} - -static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) -{ - FetchPixelProc fetch = fetchPixelProc[data->texture.format]; - - int image_width = data->texture.width; - int image_height = data->texture.height; - - const qreal cx = x + 0.5; - const qreal cy = y + 0.5; - - const uint *end = buffer + length; - uint *b = buffer; - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale); - int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale); - - fx -= half_point; - fy -= half_point; - while (b < end) { - int x1 = (fx >> 16); - int x2 = x1 + 1; - int y1 = (fy >> 16); - int y2 = y1 + 1; - - int distx = ((fx - (x1 << 16)) >> 8); - int disty = ((fy - (y1 << 16)) >> 8); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -1018,20 +760,27 @@ static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, cons int idistx = 256 - distx; int idisty = 256 - disty; - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + x2 %= image_width; + y1 %= image_height; + y2 %= image_height; + + if (x1 < 0) x1 += image_width; + if (x2 < 0) x2 += image_width; + if (y1 < 0) y1 += image_height; + if (y2 < 0) y2 += image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + x1 = qBound(0, x1, image_width - 1); + x2 = qBound(0, x2, image_width - 1); + y1 = qBound(0, y1, image_height - 1); + y2 = qBound(0, y2, image_height - 1); + } const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -1059,39 +808,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearTiled(uint *buffer, cons return buffer; } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) - -// explicit template instantiations needed to compile with VC6 and VC2002 - -#define SPANFUNC_POINTER_FETCHUNTRANSFORMED(Arg) \ - const uint *qt_fetchUntransformed_##Arg(uint *buffer, const Operator *op, const QSpanData *data, \ - int y, int x, int length) \ -{ \ - return qt_fetchUntransformed<QImage::Arg>(buffer, op, data, y, x, length Q_TEMPLATE_IMAGEFORMAT_CALL(QImage::Arg)); \ -} - -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_Mono); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_MonoLSB); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_Indexed8); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB32_Premultiplied); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB32); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB16); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB8565_Premultiplied); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB666); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB6666_Premultiplied); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB555); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB8555_Premultiplied); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB888); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_RGB444); -SPANFUNC_POINTER_FETCHUNTRANSFORMED(Format_ARGB4444_Premultiplied); - -#undef SPANFUNC_POINTER_FETCHUNTRANSFORMED - -#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed_##Arg - -#else // !VC6 && !VC2002 -# define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed<QImage::Arg> -#endif +#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed<QImage::Arg> static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { // Untransformed @@ -1135,75 +852,75 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { // Transformed { 0, // Invalid - fetchTransformed, // Mono - fetchTransformed, // MonoLsb - fetchTransformed, // Indexed8 - fetchTransformed, // RGB32 - fetchTransformed, // ARGB32 - fetchTransformed, // ARGB32_Premultiplied - fetchTransformed, // RGB16 - fetchTransformed, // ARGB8565_Premultiplied - fetchTransformed, // RGB666 - fetchTransformed, // ARGB6666_Premultiplied - fetchTransformed, // RGB555 - fetchTransformed, // ARGB8555_Premultiplied - fetchTransformed, // RGB888 - fetchTransformed, // RGB444 - fetchTransformed, // ARGB4444_Premultiplied + fetchTransformed<BlendTransformed>, // Mono + fetchTransformed<BlendTransformed>, // MonoLsb + fetchTransformed<BlendTransformed>, // Indexed8 + fetchTransformed<BlendTransformed>, // RGB32 + fetchTransformed<BlendTransformed>, // ARGB32 + fetchTransformed<BlendTransformed>, // ARGB32_Premultiplied + fetchTransformed<BlendTransformed>, // RGB16 + fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied + fetchTransformed<BlendTransformed>, // RGB666 + fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied + fetchTransformed<BlendTransformed>, // RGB555 + fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied + fetchTransformed<BlendTransformed>, // RGB888 + fetchTransformed<BlendTransformed>, // RGB444 + fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied }, { 0, // TransformedTiled - fetchTransformedTiled, // Mono - fetchTransformedTiled, // MonoLsb - fetchTransformedTiled, // Indexed8 - fetchTransformedTiled, // RGB32 - fetchTransformedTiled, // ARGB32 - fetchTransformedTiled, // ARGB32_Premultiplied - fetchTransformedTiled, // RGB16 - fetchTransformedTiled, // ARGB8565_Premultiplied - fetchTransformedTiled, // RGB666 - fetchTransformedTiled, // ARGB6666_Premultiplied - fetchTransformedTiled, // RGB555 - fetchTransformedTiled, // ARGB8555_Premultiplied - fetchTransformedTiled, // RGB888 - fetchTransformedTiled, // RGB444 - fetchTransformedTiled, // ARGB4444_Premultiplied + fetchTransformed<BlendTransformedTiled>, // Mono + fetchTransformed<BlendTransformedTiled>, // MonoLsb + fetchTransformed<BlendTransformedTiled>, // Indexed8 + fetchTransformed<BlendTransformedTiled>, // RGB32 + fetchTransformed<BlendTransformedTiled>, // ARGB32 + fetchTransformed<BlendTransformedTiled>, // ARGB32_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGB16 + fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGB666 + fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGB555 + fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGB888 + fetchTransformed<BlendTransformedTiled>, // RGB444 + fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied }, { 0, // Bilinear - fetchTransformedBilinear, // Mono - fetchTransformedBilinear, // MonoLsb - fetchTransformedBilinear, // Indexed8 - fetchTransformedBilinear, // RGB32 - fetchTransformedBilinear, // ARGB32 - fetchTransformedBilinear, // ARGB32_Premultiplied - fetchTransformedBilinear, // RGB16 - fetchTransformedBilinear, // ARGB8565_Premultiplied - fetchTransformedBilinear, // RGB666 - fetchTransformedBilinear, // ARGB6666_Premultiplied - fetchTransformedBilinear, // RGB555 - fetchTransformedBilinear, // ARGB8555_Premultiplied - fetchTransformedBilinear, // RGB888 - fetchTransformedBilinear, // RGB444 - fetchTransformedBilinear // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Mono + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // MonoLsb + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Indexed8 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // RGB32 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32>, // ARGB32 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB16 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8565_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB666 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB6666_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB555 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8555_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB888 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB444 + fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid> // ARGB4444_Premultiplied }, { 0, // BilinearTiled - fetchTransformedBilinearTiled, // Mono - fetchTransformedBilinearTiled, // MonoLsb - fetchTransformedBilinearTiled, // Indexed8 - fetchTransformedBilinearTiled, // RGB32 - fetchTransformedBilinearTiled, // ARGB32 - fetchTransformedBilinearTiled, // ARGB32_Premultiplied - fetchTransformedBilinearTiled, // RGB16 - fetchTransformedBilinearTiled, // ARGB8565_Premultiplied - fetchTransformedBilinearTiled, // RGB666 - fetchTransformedBilinearTiled, // ARGB6666_Premultiplied - fetchTransformedBilinearTiled, // RGB555 - fetchTransformedBilinearTiled, // ARGB8555_Premultiplied - fetchTransformedBilinearTiled, // RGB888 - fetchTransformedBilinearTiled, // RGB444 - fetchTransformedBilinearTiled // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Mono + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // MonoLsb + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Indexed8 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // RGB32 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32>, // ARGB32 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB16 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8565_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB666 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB6666_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB555 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8555_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB888 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB444 + fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid> // ARGB4444_Premultiplied }, }; @@ -1497,7 +1214,32 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato return b; } - +#if defined(Q_CC_RVCT) +// Force ARM code generation for comp_func_* -methods +# pragma push +# pragma arm +# if defined(QT_HAVE_ARMV6) +static __forceinline void preload(const uint *start) +{ + asm( "pld [start]" ); +} +static const uint L2CacheLineLength = 32; +static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint); +# define PRELOAD_INIT(x) preload(x); +# define PRELOAD_INIT2(x,y) PRELOAD_INIT(x) PRELOAD_INIT(y) +# define PRELOAD_COND(x) if (((uint)&x[i])%L2CacheLineLength == 0) preload(&x[i] + L2CacheLineLengthInInts); +// Two consecutive preloads stall, so space them out a bit by using different modulus. +# define PRELOAD_COND2(x,y) if (((uint)&x[i])%L2CacheLineLength == 0) preload(&x[i] + L2CacheLineLengthInInts); \ + if (((uint)&y[i])%L2CacheLineLength == 16) preload(&y[i] + L2CacheLineLengthInInts); +# endif // QT_HAVE_ARMV6 +#endif // Q_CC_RVCT + +#if !defined(Q_CC_RVCT) || !defined(QT_HAVE_ARMV6) +# define PRELOAD_INIT(x) +# define PRELOAD_INIT2(x,y) +# define PRELOAD_COND(x) +# define PRELOAD_COND2(x,y) +#endif /* The constant alpha factor describes an alpha factor that gets applied to the result of the composition operation combining it with the destination. @@ -1530,8 +1272,11 @@ static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint QT_MEMFILL_UINT(dest, length, 0); } else { int ialpha = 255 - const_alpha; - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(dest[i], ialpha); + } } } @@ -1541,8 +1286,11 @@ static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, ui QT_MEMFILL_UINT(dest, length, 0); } else { int ialpha = 255 - const_alpha; - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(dest[i], ialpha); + } } } @@ -1557,8 +1305,11 @@ static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint colo } else { int ialpha = 255 - const_alpha; color = BYTE_MUL(color, const_alpha); - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = color + BYTE_MUL(dest[i], ialpha); + } } } @@ -1568,8 +1319,11 @@ static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length ::memcpy(dest, src, length * sizeof(uint)); } else { int ialpha = 255 - const_alpha; - for (int i = 0; i < length; ++i) + PRELOAD_INIT2(dest, src) + for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha); + } } } @@ -1594,20 +1348,26 @@ static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint } else { if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color)); + } } } static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = src[i]; dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); } } else { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = BYTE_MUL(src[i], const_alpha); dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); } @@ -1623,7 +1383,9 @@ static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, { if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; dest[i] = d + BYTE_MUL(color, qAlpha(~d)); } @@ -1631,13 +1393,16 @@ static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; dest[i] = d + BYTE_MUL(src[i], qAlpha(~d)); } } else { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = BYTE_MUL(src[i], const_alpha); dest[i] = d + BYTE_MUL(s, qAlpha(~d)); @@ -1651,13 +1416,17 @@ static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, i */ static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha) { + PRELOAD_INIT(dest) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(color, qAlpha(dest[i])); + } } else { color = BYTE_MUL(color, const_alpha); uint cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia); } @@ -1666,12 +1435,16 @@ static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint co static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) dest[i] = BYTE_MUL(src[i], qAlpha(dest[i])); + } } else { uint cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = BYTE_MUL(src[i], const_alpha); dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, cia); @@ -1690,19 +1463,25 @@ static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, ui if (const_alpha != 255) { a = BYTE_MUL(a, const_alpha) + 255 - const_alpha; } + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(dest[i], a); } } static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) dest[i] = BYTE_MUL(dest[i], qAlpha(src[i])); + } } else { int cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint a = BYTE_MUL(qAlpha(src[i]), const_alpha) + cia; dest[i] = BYTE_MUL(dest[i], a); } @@ -1716,13 +1495,17 @@ static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha) { + PRELOAD_INIT(dest) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(color, qAlpha(~dest[i])); + } } else { color = BYTE_MUL(color, const_alpha); int cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia); } @@ -1731,12 +1514,16 @@ static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint c static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) dest[i] = BYTE_MUL(src[i], qAlpha(~dest[i])); + } } else { int cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = BYTE_MUL(src[i], const_alpha); uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, cia); @@ -1754,18 +1541,25 @@ static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, u uint a = qAlpha(~color); if (const_alpha != 255) a = BYTE_MUL(a, const_alpha) + 255 - const_alpha; - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = BYTE_MUL(dest[i], a); + } } static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { - for (int i = 0; i < length; ++i) + for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) dest[i] = BYTE_MUL(dest[i], qAlpha(~src[i])); + } } else { int cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint sia = BYTE_MUL(qAlpha(~src[i]), const_alpha) + cia; dest[i] = BYTE_MUL(dest[i], sia); } @@ -1784,20 +1578,26 @@ static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color = BYTE_MUL(color, const_alpha); } uint sia = qAlpha(~color); - for (int i = 0; i < length; ++i) + PRELOAD_INIT(dest) + for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia); + } } static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = src[i]; uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s)); } } else { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = BYTE_MUL(src[i], const_alpha); uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s)); @@ -1817,7 +1617,9 @@ static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, color = BYTE_MUL(color, const_alpha); a = qAlpha(color) + 255 - const_alpha; } + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d)); } @@ -1825,8 +1627,10 @@ static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = src[i]; uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(d, qAlpha(s), s, qAlpha(~d)); @@ -1834,6 +1638,7 @@ static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, i } else { int cia = 255 - const_alpha; for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint s = BYTE_MUL(src[i], const_alpha); uint d = dest[i]; uint a = qAlpha(s) + cia; @@ -1854,7 +1659,9 @@ static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, color = BYTE_MUL(color, const_alpha); uint sia = qAlpha(~color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia); } @@ -1862,14 +1669,17 @@ static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) { + PRELOAD_INIT2(dest, src) if (const_alpha == 255) { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s)); } } else { for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = BYTE_MUL(src[i], const_alpha); dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s)); @@ -1920,7 +1730,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int { uint s = color; + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); @@ -1940,7 +1752,9 @@ static void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -1976,7 +1790,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2002,7 +1818,9 @@ static void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint co template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2040,7 +1858,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, i int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2066,7 +1886,9 @@ static void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint colo template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2115,7 +1937,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2141,7 +1965,9 @@ static void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint col template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2184,7 +2010,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, i int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2210,7 +2038,9 @@ static void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint colo template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2253,7 +2083,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2279,7 +2111,9 @@ static void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint col template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2332,7 +2166,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *des int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2358,7 +2194,9 @@ static void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2411,7 +2249,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2437,7 +2277,9 @@ static void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint c template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2487,7 +2329,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2513,7 +2357,9 @@ static void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint c template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2572,7 +2418,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2598,7 +2446,9 @@ static void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint c template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2641,7 +2491,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *des int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2667,7 +2519,9 @@ static void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2704,7 +2558,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_imp int sg = qGreen(color); int sb = qBlue(color); + PRELOAD_INIT(dest) for (int i = 0; i < length; ++i) { + PRELOAD_COND(dest) uint d = dest[i]; int da = qAlpha(d); @@ -2730,7 +2586,9 @@ static void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint c template <typename T> Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *dest, const uint *src, int length, const T &coverage) { + PRELOAD_INIT2(dest, src) for (int i = 0; i < length; ++i) { + PRELOAD_COND2(dest, src) uint d = dest[i]; uint s = src[i]; @@ -2756,6 +2614,11 @@ static void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int len comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha)); } +#if defined(Q_CC_RVCT) +// Restore pragma state from previous #pragma arm +# pragma pop +#endif + static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, int length, uint color, @@ -3219,8 +3082,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) } template <class T> -Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData - Q_TEMPLATE_FIX(T)) +Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); Operator op = getOperator(data, spans, count); @@ -3266,28 +3128,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void * blend_color_generic(count, spans, userData); } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) -#define BLEND_COLOR_DECL(DST) \ - static void blendColor_##DST(int count, \ - const QSpan *spans, \ - void *userData) \ - { \ - blendColor<DST>(count, spans, userData Q_TEMPLATE_CALL(DST)); \ - } - -BLEND_COLOR_DECL(qargb8565) -BLEND_COLOR_DECL(qrgb666) -BLEND_COLOR_DECL(qargb6666) -BLEND_COLOR_DECL(qrgb555) -BLEND_COLOR_DECL(qargb8555) -BLEND_COLOR_DECL(qrgb888) -BLEND_COLOR_DECL(qrgb444) -BLEND_COLOR_DECL(qargb4444) -#undef DEST_FETCH_DECL -#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor_##DST -#else // !VC6 && !VC2002 -# define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor<DST> -#endif +#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor<DST> static void blend_color_rgb16(int count, const QSpan *spans, void *userData) { @@ -3365,45 +3206,117 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData) blend_color_generic(count, spans, userData); } -template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +template <typename T> +void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handler) { - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - uint buffer[buffer_size]; - uint src_buffer[buffer_size]; - Operator op = getOperator(data, spans, count); - uint const_alpha = 256; if (data->type == QSpanData::Texture) const_alpha = data->texture.const_alpha; - while (count--) { + int coverage = 0; + while (count) { int x = spans->x; - int length = spans->len; - const int coverage = (spans->coverage * const_alpha) >> 8; + const int y = spans->y; + int right = x + spans->len; + + // compute length of adjacent spans + for (int i = 1; i < count && spans[i].y == y && spans[i].x == right; ++i) + right += spans[i].len; + int length = right - x; + while (length) { int l = qMin(buffer_size, length); - const uint *src = op.src_fetch(src_buffer, &op, data, spans->y, x, l); - if (spanMethod == RegularSpans) { - uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer; - op.func(dest, src, l, coverage); - if (op.dest_store) - op.dest_store(data->rasterBuffer, x, spans->y, dest, l); - } else { - drawBufferSpan(data, src, l, x, spans->y, l, coverage); - } - x += l; length -= l; + + int process_length = l; + int process_x = x; + + const uint *src = handler.fetch(process_x, y, process_length); + int offset = 0; + while (l > 0) { + if (x == spans->x) // new span? + coverage = (spans->coverage * const_alpha) >> 8; + + int right = spans->x + spans->len; + int len = qMin(l, right - x); + + handler.process(x, y, len, coverage, src, offset); + + l -= len; + x += len; + offset += len; + + if (x == right) { // done with current span? + ++spans; + --count; + } + } + handler.store(process_x, y, process_length); } - ++spans; } } +struct QBlendBase +{ + QBlendBase(QSpanData *d, Operator o) + : data(d) + , op(o) + , dest(0) + { + } + + QSpanData *data; + Operator op; + + uint *dest; + + uint buffer[buffer_size]; + uint src_buffer[buffer_size]; +}; + +template <SpanMethod spanMethod> +class BlendSrcGeneric : public QBlendBase +{ +public: + BlendSrcGeneric(QSpanData *d, Operator o) + : QBlendBase(d, o) + { + } + + const uint *fetch(int x, int y, int len) + { + if (spanMethod == RegularSpans) + dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer; + + return op.src_fetch(src_buffer, &op, data, y, x, len); + } + + void process(int x, int y, int len, int coverage, const uint *src, int offset) + { + if (spanMethod == RegularSpans) + op.func(dest + offset, src + offset, len, coverage); + else + drawBufferSpan(data, src + offset, len, x, y, len, coverage); + } + + void store(int x, int y, int len) + { + if (spanMethod == RegularSpans && op.dest_store) { + op.dest_store(data->rasterBuffer, x, y, dest, len); + } + } +}; + +template <SpanMethod spanMethod> +Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData) +{ + QSpanData *data = reinterpret_cast<QSpanData *>(userData); + BlendSrcGeneric<spanMethod> blend(data, getOperator(data, spans, count)); + handleSpans(count, spans, data, blend); +} + template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -3454,13 +3367,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_untransformed_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_untransformed_generic<spanMethod>(count, spans, userData); return; } @@ -4706,8 +4618,7 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat if (mode != QPainter::CompositionMode_SourceOver && mode != QPainter::CompositionMode_Source) { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); return; } @@ -4769,8 +4680,7 @@ static void blend_untransformed_rgb888(int count, const QSpan *spans, blendUntransformed<qrgb888, qrgb888>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb6666(int count, const QSpan *spans, @@ -4785,8 +4695,7 @@ static void blend_untransformed_argb6666(int count, const QSpan *spans, blendUntransformed<qargb6666, qrgb666>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb666(int count, const QSpan *spans, @@ -4801,8 +4710,7 @@ static void blend_untransformed_rgb666(int count, const QSpan *spans, blendUntransformed<qrgb666, qrgb666>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb8565(int count, const QSpan *spans, @@ -4817,8 +4725,7 @@ static void blend_untransformed_argb8565(int count, const QSpan *spans, blendUntransformed<qargb8565, qrgb565>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb565(int count, const QSpan *spans, @@ -4833,8 +4740,7 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans, blendUntransformed<qrgb565, qrgb565>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb8555(int count, const QSpan *spans, @@ -4849,8 +4755,7 @@ static void blend_untransformed_argb8555(int count, const QSpan *spans, blendUntransformed<qargb8555, qrgb555>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb555(int count, const QSpan *spans, @@ -4865,8 +4770,7 @@ static void blend_untransformed_rgb555(int count, const QSpan *spans, blendUntransformed<qrgb555, qrgb555>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_argb4444(int count, const QSpan *spans, @@ -4881,8 +4785,7 @@ static void blend_untransformed_argb4444(int count, const QSpan *spans, blendUntransformed<qargb4444, qrgb444>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } static void blend_untransformed_rgb444(int count, const QSpan *spans, @@ -4897,13 +4800,11 @@ static void blend_untransformed_rgb444(int count, const QSpan *spans, blendUntransformed<qrgb444, qrgb444>(count, spans, userData); else #endif - blend_untransformed_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_untransformed_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -4957,13 +4858,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_tiled_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_tiled_generic<spanMethod>(count, spans, userData); return; } @@ -5019,8 +4919,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * if (mode != QPainter::CompositionMode_SourceOver && mode != QPainter::CompositionMode_Source) { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); return; } @@ -5052,30 +4951,60 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void * if (sy < 0) sy += image_height; - while (length) { - int l = qMin(image_width - sx, length); - if (buffer_size < l) - l = buffer_size; - - DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; - const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; - if (modeSource && coverage == 255) { + if (modeSource && coverage == 255) { + // Copy the first texture block + length = image_width; + while (length) { + int l = qMin(image_width - sx, length); + if (buffer_size < l) + l = buffer_size; + DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; + const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; qt_memconvert<DST, SRC>(dest, src, l); - } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest24(dest, src, coverage, l); - } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && - (quintptr(dest) & 3) == (quintptr(src) & 3)) - { - blendUntransformed_dest16(dest, src, coverage, l); - } else { - blendUntransformed_unaligned(dest, src, coverage, l); + length -= l; + sx = 0; } - x += l; - length -= l; - sx = 0; + // Now use the rasterBuffer as the source of the texture, + // We can now progressively copy larger blocks + // - Less cpu time in code figuring out what to copy + // We are dealing with one block of data + // - More likely to fit in the cache + // - can use memcpy + int copy_image_width = image_width; + length = spans->len - image_width; + DST *src = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; + DST *dest = src + copy_image_width; + while (copy_image_width < length) { + qt_memconvert(dest, src, copy_image_width); + dest += copy_image_width; + length -= copy_image_width; + copy_image_width *= 2; + } + qt_memconvert(dest, src, length); + } else { + while (length) { + int l = qMin(image_width - sx, length); + if (buffer_size < l) + l = buffer_size; + DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x; + const SRC *src = (SRC*)data->texture.scanLine(sy) + sx; + if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 && + (quintptr(dest) & 3) == (quintptr(src) & 3)) + { + blendUntransformed_dest24(dest, src, coverage, l); + } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 && + (quintptr(dest) & 3) == (quintptr(src) & 3)) + { + blendUntransformed_dest16(dest, src, coverage, l); + } else { + blendUntransformed_unaligned(dest, src, coverage, l); + } + + x += l; + length -= l; + sx = 0; + } } ++spans; } @@ -5090,8 +5019,7 @@ static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData) blendTiled<qrgb888, qrgb888>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData) @@ -5105,8 +5033,7 @@ static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData) blendTiled<qargb6666, qrgb666>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData) @@ -5120,8 +5047,7 @@ static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData) blendTiled<qrgb666, qrgb666>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData) @@ -5135,8 +5061,7 @@ static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData) blendTiled<qargb8565, qrgb565>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) @@ -5150,8 +5075,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) blendTiled<qrgb565, qrgb565>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData) @@ -5165,8 +5089,7 @@ static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData) blendTiled<qargb8555, qrgb555>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData) @@ -5180,8 +5103,7 @@ static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData) blendTiled<qrgb555, qrgb555>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData) @@ -5195,8 +5117,7 @@ static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData) blendTiled<qargb4444, qrgb444>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData) @@ -5210,19 +5131,17 @@ static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData) blendTiled<qrgb444, qrgb444>(count, spans, userData); else #endif - blend_tiled_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_tiled_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_src_generic<spanMethod>(count, spans, userData); return; } @@ -5401,8 +5320,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); return; } @@ -5605,8 +5523,7 @@ static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, voi blendTransformedBilinear<qrgb888, qrgb888>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData) @@ -5620,8 +5537,7 @@ static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, v blendTransformedBilinear<qargb6666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData) @@ -5635,8 +5551,7 @@ static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, voi blendTransformedBilinear<qrgb666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData) @@ -5650,8 +5565,7 @@ static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, v blendTransformedBilinear<qargb8565, qrgb565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, @@ -5666,8 +5580,7 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, blendTransformedBilinear<qrgb565, qargb8565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData) @@ -5681,8 +5594,7 @@ static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, v blendTransformedBilinear<qargb8555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData) @@ -5696,8 +5608,7 @@ static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, voi blendTransformedBilinear<qrgb555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData) @@ -5711,8 +5622,7 @@ static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, v blendTransformedBilinear<qargb4444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData) @@ -5726,18 +5636,16 @@ static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, voi blendTransformedBilinear<qrgb444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_src_generic<spanMethod>(count, spans, userData); return; } @@ -5923,13 +5831,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_src_generic<spanMethod>(count, spans, userData); return; } @@ -6051,8 +5958,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); return; } @@ -6201,8 +6107,7 @@ static void blend_transformed_rgb888(int count, const QSpan *spans, blendTransformed<qrgb888, qrgb888>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb6666(int count, const QSpan *spans, @@ -6217,8 +6122,7 @@ static void blend_transformed_argb6666(int count, const QSpan *spans, blendTransformed<qargb6666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb666(int count, const QSpan *spans, @@ -6233,8 +6137,7 @@ static void blend_transformed_rgb666(int count, const QSpan *spans, blendTransformed<qrgb666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb8565(int count, const QSpan *spans, @@ -6249,8 +6152,7 @@ static void blend_transformed_argb8565(int count, const QSpan *spans, blendTransformed<qargb8565, qrgb565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb565(int count, const QSpan *spans, @@ -6265,8 +6167,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans, blendTransformed<qrgb565, qrgb565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb8555(int count, const QSpan *spans, @@ -6281,8 +6182,7 @@ static void blend_transformed_argb8555(int count, const QSpan *spans, blendTransformed<qargb8555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb555(int count, const QSpan *spans, @@ -6297,8 +6197,7 @@ static void blend_transformed_rgb555(int count, const QSpan *spans, blendTransformed<qrgb555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_argb4444(int count, const QSpan *spans, @@ -6313,8 +6212,7 @@ static void blend_transformed_argb4444(int count, const QSpan *spans, blendTransformed<qargb4444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_rgb444(int count, const QSpan *spans, @@ -6329,18 +6227,16 @@ static void blend_transformed_rgb444(int count, const QSpan *spans, blendTransformed<qrgb444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData - Q_TEMPLATE_ENUM_FIX(SpanMethod, spanMethod)) +Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format != QImage::Format_ARGB32_Premultiplied && data->texture.format != QImage::Format_RGB32) { - blend_src_generic<spanMethod>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, spanMethod)); + blend_src_generic<spanMethod>(count, spans, userData); return; } @@ -6474,8 +6370,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; if (mode != QPainter::CompositionMode_SourceOver) { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); return; } @@ -6625,8 +6520,7 @@ static void blend_transformed_tiled_rgb888(int count, const QSpan *spans, blendTransformedTiled<qrgb888, qrgb888>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb6666(int count, const QSpan *spans, @@ -6641,8 +6535,7 @@ static void blend_transformed_tiled_argb6666(int count, const QSpan *spans, blendTransformedTiled<qargb6666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb666(int count, const QSpan *spans, @@ -6657,8 +6550,7 @@ static void blend_transformed_tiled_rgb666(int count, const QSpan *spans, blendTransformedTiled<qrgb666, qrgb666>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb8565(int count, const QSpan *spans, @@ -6673,8 +6565,7 @@ static void blend_transformed_tiled_argb8565(int count, const QSpan *spans, blendTransformedTiled<qargb8565, qrgb565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, @@ -6689,8 +6580,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, blendTransformedTiled<qrgb565, qrgb565>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb8555(int count, const QSpan *spans, @@ -6705,8 +6595,7 @@ static void blend_transformed_tiled_argb8555(int count, const QSpan *spans, blendTransformedTiled<qargb8555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb555(int count, const QSpan *spans, @@ -6721,8 +6610,7 @@ static void blend_transformed_tiled_rgb555(int count, const QSpan *spans, blendTransformedTiled<qrgb555, qrgb555>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_argb4444(int count, const QSpan *spans, @@ -6737,8 +6625,7 @@ static void blend_transformed_tiled_argb4444(int count, const QSpan *spans, blendTransformedTiled<qargb4444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } static void blend_transformed_tiled_rgb444(int count, const QSpan *spans, @@ -6753,36 +6640,10 @@ static void blend_transformed_tiled_rgb444(int count, const QSpan *spans, blendTransformedTiled<qrgb444, qrgb444>(count, spans, userData); else #endif - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } -#if defined(Q_CC_MSVC) && _MSC_VER <= 1300 && !defined(Q_CC_INTEL) - -// explicit template instantiations needed to compile with VC6 and VC2002 - -#define SPANFUNC_INSTANTIATION(Name, Arg) \ -static inline void Name##_##Arg(int count, const QSpan *spans, void *userData) \ -{ \ - Name<Arg>(count, spans, userData Q_TEMPLATE_ENUM_CALL(SpanMethod, Arg)); \ -} - -SPANFUNC_INSTANTIATION(blend_untransformed_generic, RegularSpans); -SPANFUNC_INSTANTIATION(blend_untransformed_argb, RegularSpans); -SPANFUNC_INSTANTIATION(blend_tiled_generic, RegularSpans); -SPANFUNC_INSTANTIATION(blend_tiled_argb, RegularSpans); -SPANFUNC_INSTANTIATION(blend_src_generic, RegularSpans); -SPANFUNC_INSTANTIATION(blend_transformed_argb, RegularSpans); -SPANFUNC_INSTANTIATION(blend_transformed_tiled_argb, RegularSpans); -SPANFUNC_INSTANTIATION(blend_transformed_bilinear_argb, RegularSpans); -SPANFUNC_INSTANTIATION(blend_transformed_bilinear_tiled_argb, RegularSpans); -#undef SPANFUNC_INSTANTIATION - -#define SPANFUNC_POINTER(Name, Arg) Name##_##Arg - -#else // !VC6 && !VC2002 # define SPANFUNC_POINTER(Name, Arg) Name<Arg> -#endif /* Image formats here are target formats */ @@ -7149,8 +7010,7 @@ static void qt_gradient_quint32(int count, const QSpan *spans, void *userData) } } else { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } } @@ -7198,8 +7058,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData) data->solid.color = oldColor; } else { - blend_src_generic<RegularSpans>(count, spans, userData - Q_TEMPLATE_ENUM_CALL(SpanMethod, RegularSpans)); + blend_src_generic<RegularSpans>(count, spans, userData); } } @@ -7258,7 +7117,13 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, } void qt_build_pow_tables() { - qreal smoothing = 1.7; + qreal smoothing = qreal(1.7); + +#ifdef Q_WS_MAC + // decided by testing a few things on an iMac, should probably get this from the + // system... + smoothing = 2.0; +#endif #ifdef Q_WS_WIN int winSmooth; @@ -7274,15 +7139,15 @@ void qt_build_pow_tables() { } #else for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / 255.0, smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / 255.0, 1 / smoothing) * 255)); + qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255)); } #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) const qreal gray_gamma = 2.31; for (int i=0; i<256; ++i) - qt_pow_gamma[i] = uint(qRound(pow(i / 255.0, gray_gamma) * 2047)); + qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047)); for (int i=0; i<2048; ++i) qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255)); #endif @@ -7404,7 +7269,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer, #endif { int ialpha = 255 - coverage; - dest[i] = BYTE_MUL(c, uint(coverage)) + BYTE_MUL(dest[i], ialpha); + dest[i] = INTERPOLATE_PIXEL_255(c, coverage, dest[i], ialpha); } } } @@ -7445,7 +7310,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer, #endif { int ialpha = 255 - coverage; - dest[xp] = BYTE_MUL(c, uint(coverage)) + BYTE_MUL(dest[xp], ialpha); + dest[xp] = INTERPOLATE_PIXEL_255(c, coverage, dest[xp], ialpha); } } @@ -7547,13 +7412,13 @@ inline void qt_rectfill_template(QRasterBuffer *rasterBuffer, QT_RECTFILL(quint32) QT_RECTFILL(quint16) QT_RECTFILL(qargb8565) -QT_RECTFILL(qrgb666); -QT_RECTFILL(qargb6666); +QT_RECTFILL(qrgb666) +QT_RECTFILL(qargb6666) QT_RECTFILL(qrgb555) QT_RECTFILL(qargb8555) QT_RECTFILL(qrgb888) -QT_RECTFILL(qrgb444); -QT_RECTFILL(qargb4444); +QT_RECTFILL(qrgb444) +QT_RECTFILL(qargb4444) #undef QT_RECTFILL @@ -8031,6 +7896,96 @@ static uint detectCPUFeatures() #endif } +#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) +// Move these to qdrawhelper_arm.c when all +// functions are implemented using arm assembly. +static CompositionFunctionSolid qt_functionForModeSolid_ARMv6[numCompositionFunctions] = { + comp_func_solid_SourceOver, + comp_func_solid_DestinationOver, + comp_func_solid_Clear, + comp_func_solid_Source, + comp_func_solid_Destination, + comp_func_solid_SourceIn, + comp_func_solid_DestinationIn, + comp_func_solid_SourceOut, + comp_func_solid_DestinationOut, + comp_func_solid_SourceAtop, + comp_func_solid_DestinationAtop, + comp_func_solid_XOR, + comp_func_solid_Plus, + comp_func_solid_Multiply, + comp_func_solid_Screen, + comp_func_solid_Overlay, + comp_func_solid_Darken, + comp_func_solid_Lighten, + comp_func_solid_ColorDodge, + comp_func_solid_ColorBurn, + comp_func_solid_HardLight, + comp_func_solid_SoftLight, + comp_func_solid_Difference, + comp_func_solid_Exclusion, + rasterop_solid_SourceOrDestination, + rasterop_solid_SourceAndDestination, + rasterop_solid_SourceXorDestination, + rasterop_solid_NotSourceAndNotDestination, + rasterop_solid_NotSourceOrNotDestination, + rasterop_solid_NotSourceXorDestination, + rasterop_solid_NotSource, + rasterop_solid_NotSourceAndDestination, + rasterop_solid_SourceAndNotDestination +}; + +static CompositionFunction qt_functionForMode_ARMv6[numCompositionFunctions] = { + comp_func_SourceOver_armv6, + comp_func_DestinationOver, + comp_func_Clear, + comp_func_Source_armv6, + comp_func_Destination, + comp_func_SourceIn, + comp_func_DestinationIn, + comp_func_SourceOut, + comp_func_DestinationOut, + comp_func_SourceAtop, + comp_func_DestinationAtop, + comp_func_XOR, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination +}; + +static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userData) +{ + QSpanData *data = reinterpret_cast<QSpanData *>(userData); + + CompositionFunctionSolid func = qt_functionForModeSolid_ARMv6[data->rasterBuffer->compositionMode]; + while (count--) { + uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; + func(target, spans->len, data->solid.color, spans->coverage); + ++spans; + } +} + +#endif // Q_CC_RVCT && QT_HAVE_ARMV6 + + void qInitDrawhelperAsm() { static uint features = 0xffffffff; @@ -8146,6 +8101,20 @@ void qInitDrawhelperAsm() #endif // QT_NO_DEBUG +#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) + functionForModeAsm = qt_functionForMode_ARMv6; + functionForModeSolidAsm = qt_functionForModeSolid_ARMv6; + + qt_memfill32 = qt_memfill32_armv6; + + qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_armv6; + + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; +#endif // Q_CC_RVCT && QT_HAVE_ARMV6 + if (functionForModeSolidAsm) { const int destinationMode = QPainter::CompositionMode_Destination; functionForModeSolidAsm[destinationMode] = functionForModeSolid_C[destinationMode]; |