Make the 64 bit raster backend an optional feature

Can be used to make smaller binaries, and possibly speed up ARGB32
rendering on some platforms.

Change-Id: I7647b197ba7a6582187cc9736b7e0d752bd5bee5
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2019-04-01 13:17:24 +02:00
parent 84ce5022ce
commit 0bee05f4c1
11 changed files with 782 additions and 415 deletions

View File

@ -1775,6 +1775,12 @@
"purpose": "Supports displaying \"What's this\" help.", "purpose": "Supports displaying \"What's this\" help.",
"section": "Widget Support", "section": "Widget Support",
"output": [ "publicFeature", "feature" ] "output": [ "publicFeature", "feature" ]
},
"raster-64bit": {
"label": "QPainter - 64 bit raster",
"purpose": "Internal painting support for 64 bit (16 bpc) rasterization.",
"section": "Painting",
"output": [ "privateFeature" ]
} }
}, },

View File

@ -4690,12 +4690,14 @@ QImage QImage::smoothScaled(int w, int h) const {
case QImage::Format_RGBX8888: case QImage::Format_RGBX8888:
#endif #endif
case QImage::Format_RGBA8888_Premultiplied: case QImage::Format_RGBA8888_Premultiplied:
#if QT_CONFIG(raster_64bit)
case QImage::Format_RGBX64: case QImage::Format_RGBX64:
case QImage::Format_RGBA64_Premultiplied: case QImage::Format_RGBA64_Premultiplied:
break; break;
case QImage::Format_RGBA64: case QImage::Format_RGBA64:
src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied); src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);
break; break;
#endif
default: default:
if (src.hasAlphaChannel()) if (src.hasAlphaChannel())
src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied); src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);

File diff suppressed because it is too large Load Diff

View File

@ -1117,6 +1117,7 @@ static const QRgba64 *QT_FASTCALL fetchARGB32PMToRGBA64PM(QRgba64 *buffer, const
return convertARGB32PMToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr); return convertARGB32PMToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
} }
#if QT_CONFIG(raster_64bit)
static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count) static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count)
{ {
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
@ -1126,6 +1127,7 @@ static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count)
static void convertRGBA64PMToRGBA64PM(QRgba64 *, int) static void convertRGBA64PMToRGBA64PM(QRgba64 *, int)
{ {
} }
#endif
static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count, static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *) const QVector<QRgb> *, QDitherInfo *)
@ -1699,22 +1701,6 @@ static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *, int,
return buffer; return buffer;
} }
static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
{
const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length, nullptr, nullptr));
}
static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer, int x, int y, int)
{
return (QRgba64 *)rasterBuffer->scanLine(y) + x;
}
static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *, int, int, int)
{
return buffer;
}
static DestFetchProc destFetchProc[QImage::NImageFormats] = static DestFetchProc destFetchProc[QImage::NImageFormats] =
{ {
0, // Format_Invalid 0, // Format_Invalid
@ -1748,6 +1734,23 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_Grayscale16 destFetch, // Format_Grayscale16
}; };
#if QT_CONFIG(raster_64bit)
static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
{
const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length, nullptr, nullptr));
}
static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer, int x, int y, int)
{
return (QRgba64 *)rasterBuffer->scanLine(y) + x;
}
static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *, int, int, int)
{
return buffer;
}
static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
{ {
0, // Format_Invalid 0, // Format_Invalid
@ -1780,6 +1783,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
destFetchRGB64, // Format_RGBA64_Premultiplied destFetchRGB64, // Format_RGBA64_Premultiplied
destFetch64, // Format_Grayscale16 destFetch64, // Format_Grayscale16
}; };
#endif
/* /*
Returns the color in the mono destination color table Returns the color in the mono destination color table
@ -1887,21 +1891,6 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con
store(dest, buffer, x, length, nullptr, nullptr); store(dest, buffer, x, length, nullptr, nullptr);
} }
static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
auto store = qStoreFromRGBA64PM[rasterBuffer->format];
uchar *dest = rasterBuffer->scanLine(y);
store(dest, buffer, x, length, nullptr, nullptr);
}
static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
QRgba64 *dest = reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
for (int i = 0; i < length; ++i) {
dest[i] = buffer[i].unpremultiplied();
}
}
static DestStoreProc destStoreProc[QImage::NImageFormats] = static DestStoreProc destStoreProc[QImage::NImageFormats] =
{ {
0, // Format_Invalid 0, // Format_Invalid
@ -1935,6 +1924,22 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_Grayscale16 destStore, // Format_Grayscale16
}; };
#if QT_CONFIG(raster_64bit)
static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
auto store = qStoreFromRGBA64PM[rasterBuffer->format];
uchar *dest = rasterBuffer->scanLine(y);
store(dest, buffer, x, length, nullptr, nullptr);
}
static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
QRgba64 *dest = reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
for (int i = 0; i < length; ++i) {
dest[i] = buffer[i].unpremultiplied();
}
}
static DestStoreProc64 destStoreProc64[QImage::NImageFormats] = static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
{ {
0, // Format_Invalid 0, // Format_Invalid
@ -1967,6 +1972,7 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
0, // Format_RGBA64_Premultiplied 0, // Format_RGBA64_Premultiplied
destStore64, // Format_Grayscale16 destStore64, // Format_Grayscale16
}; };
#endif
/* /*
Source fetches Source fetches
@ -2017,6 +2023,7 @@ static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Opera
return buffer; return buffer;
} }
#if QT_CONFIG(raster_64bit)
static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Operator *, static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Operator *,
const QSpanData *data, int y, int x, int length) const QSpanData *data, int y, int x, int length)
{ {
@ -2030,6 +2037,7 @@ static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *, const Op
const uchar *scanLine = data->texture.scanLine(y); const uchar *scanLine = data->texture.scanLine(y);
return reinterpret_cast<const QRgba64 *>(scanLine) + x; return reinterpret_cast<const QRgba64 *>(scanLine) + x;
} }
#endif
template<TextureBlendType blendType> template<TextureBlendType blendType>
inline void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v) inline void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v)
@ -2220,6 +2228,7 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
return buffer; return buffer;
} }
#if QT_CONFIG(raster_64bit)
template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */ template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data, static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data,
int y, int x, int length) int y, int x, int length)
@ -2240,6 +2249,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Oper
convertRGBA64ToRGBA64PM(buffer, length); convertRGBA64ToRGBA64PM(buffer, length);
return buffer; return buffer;
} }
#endif
/** \internal /** \internal
interpolate 4 argb pixels with the distx and disty factor. interpolate 4 argb pixels with the distx and disty factor.
@ -3541,6 +3551,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
return buffer; return buffer;
} }
#if QT_CONFIG(raster_64bit)
template<TextureBlendType blendType> template<TextureBlendType blendType>
static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer, const QSpanData *data, static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer, const QSpanData *data,
int y, int x, int length) int y, int x, int length)
@ -3861,6 +3872,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length); return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length); return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
} }
#endif
// FetchUntransformed can have more specialized methods added depending on SIMD features. // FetchUntransformed can have more specialized methods added depending on SIMD features.
static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = { static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
@ -3931,6 +3943,20 @@ static SourceFetchProc sourceFetchAny32[NBlendTypes] = {
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32> // TransformedBilinearTiled fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32> // TransformedBilinearTiled
}; };
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
{
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
return sourceFetchARGB32PM[blendType];
if (blendType == BlendUntransformed || blendType == BlendTiled)
return sourceFetchUntransformed[format];
if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
return sourceFetchAny16[blendType];
if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
return sourceFetchAny32[blendType];
return sourceFetchGeneric[blendType];
}
#if QT_CONFIG(raster_64bit)
static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = { static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
fetchUntransformed64, // Untransformed fetchUntransformed64, // Untransformed
fetchUntransformed64, // Tiled fetchUntransformed64, // Tiled
@ -3949,25 +3975,13 @@ static const SourceFetchProc64 sourceFetchRGBA64PM[NBlendTypes] = {
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
}; };
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
{
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
return sourceFetchARGB32PM[blendType];
if (blendType == BlendUntransformed || blendType == BlendTiled)
return sourceFetchUntransformed[format];
if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
return sourceFetchAny16[blendType];
if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
return sourceFetchAny32[blendType];
return sourceFetchGeneric[blendType];
}
static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format) static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
{ {
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied) if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
return sourceFetchRGBA64PM[blendType]; return sourceFetchRGBA64PM[blendType];
return sourceFetchGeneric64[blendType]; return sourceFetchGeneric64[blendType];
} }
#endif
#define FIXPT_BITS 8 #define FIXPT_BITS 8
@ -3979,11 +3993,13 @@ static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
return data->colorTable32[qt_gradient_clamp(data, ipos)]; return data->colorTable32[qt_gradient_clamp(data, ipos)];
} }
#if QT_CONFIG(raster_64bit)
static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos) static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos)
{ {
int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
return data->colorTable64[qt_gradient_clamp(data, ipos)]; return data->colorTable64[qt_gradient_clamp(data, ipos)];
} }
#endif
static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data) static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data)
{ {
@ -4017,6 +4033,7 @@ public:
} }
}; };
#if QT_CONFIG(raster_64bit)
class GradientBase64 class GradientBase64
{ {
public: public:
@ -4035,6 +4052,7 @@ public:
qt_memfill64((quint64*)buffer, fill, length); qt_memfill64((quint64*)buffer, fill, length);
} }
}; };
#endif
template<class GradientBase, typename BlendType> template<class GradientBase, typename BlendType>
static inline const BlendType * QT_FASTCALL qt_fetch_linear_gradient_template( static inline const BlendType * QT_FASTCALL qt_fetch_linear_gradient_template(
@ -4112,11 +4130,13 @@ static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Ope
return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length); return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
} }
#if QT_CONFIG(raster_64bit)
static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data, static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length) int y, int x, int length)
{ {
return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length); return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
} }
#endif
static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data) static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data)
{ {
@ -4178,11 +4198,13 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Oper
static SourceFetchProc qt_fetch_radial_gradient = qt_fetch_radial_gradient_plain; static SourceFetchProc qt_fetch_radial_gradient = qt_fetch_radial_gradient_plain;
#if QT_CONFIG(raster_64bit)
const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data, const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length) int y, int x, int length)
{ {
return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length); return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
} }
#endif
template <class GradientBase, typename BlendType> template <class GradientBase, typename BlendType>
static inline const BlendType * QT_FASTCALL qt_fetch_conical_gradient_template( static inline const BlendType * QT_FASTCALL qt_fetch_conical_gradient_template(
@ -4241,23 +4263,29 @@ static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Op
return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length); return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
} }
#if QT_CONFIG(raster_64bit)
static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer, const Operator *, const QSpanData *data, static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer, const Operator *, const QSpanData *data,
int y, int x, int length) int y, int x, int length)
{ {
return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length); return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
} }
#endif
extern CompositionFunctionSolid qt_functionForModeSolid_C[]; extern CompositionFunctionSolid qt_functionForModeSolid_C[];
extern CompositionFunctionSolid64 qt_functionForModeSolid64_C[]; extern CompositionFunctionSolid64 qt_functionForModeSolid64_C[];
static const CompositionFunctionSolid *functionForModeSolid = qt_functionForModeSolid_C; static const CompositionFunctionSolid *functionForModeSolid = qt_functionForModeSolid_C;
#if QT_CONFIG(raster_64bit)
static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C; static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
#endif
extern CompositionFunction qt_functionForMode_C[]; extern CompositionFunction qt_functionForMode_C[];
extern CompositionFunction64 qt_functionForMode64_C[]; extern CompositionFunction64 qt_functionForMode64_C[];
static const CompositionFunction *functionForMode = qt_functionForMode_C; static const CompositionFunction *functionForMode = qt_functionForMode_C;
#if QT_CONFIG(raster_64bit)
static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C; static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
#endif
static TextureBlendType getBlendType(const QSpanData *data) static TextureBlendType getBlendType(const QSpanData *data)
{ {
@ -4289,41 +4317,58 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
case QSpanData::Solid: case QSpanData::Solid:
solidSource = data->solidColor.isOpaque(); solidSource = data->solidColor.isOpaque();
op.srcFetch = 0; op.srcFetch = 0;
#if QT_CONFIG(raster_64bit)
op.srcFetch64 = 0; op.srcFetch64 = 0;
#endif
break; break;
case QSpanData::LinearGradient: case QSpanData::LinearGradient:
solidSource = !data->gradient.alphaColor; solidSource = !data->gradient.alphaColor;
getLinearGradientValues(&op.linear, data); getLinearGradientValues(&op.linear, data);
op.srcFetch = qt_fetch_linear_gradient; op.srcFetch = qt_fetch_linear_gradient;
#if QT_CONFIG(raster_64bit)
op.srcFetch64 = qt_fetch_linear_gradient_rgb64; op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
#endif
break; break;
case QSpanData::RadialGradient: case QSpanData::RadialGradient:
solidSource = !data->gradient.alphaColor; solidSource = !data->gradient.alphaColor;
getRadialGradientValues(&op.radial, data); getRadialGradientValues(&op.radial, data);
op.srcFetch = qt_fetch_radial_gradient; op.srcFetch = qt_fetch_radial_gradient;
#if QT_CONFIG(raster_64bit)
op.srcFetch64 = qt_fetch_radial_gradient_rgb64; op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
#endif
break; break;
case QSpanData::ConicalGradient: case QSpanData::ConicalGradient:
solidSource = !data->gradient.alphaColor; solidSource = !data->gradient.alphaColor;
op.srcFetch = qt_fetch_conical_gradient; op.srcFetch = qt_fetch_conical_gradient;
#if QT_CONFIG(raster_64bit)
op.srcFetch64 = qt_fetch_conical_gradient_rgb64; op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
#endif
break; break;
case QSpanData::Texture: case QSpanData::Texture:
solidSource = !data->texture.hasAlpha; solidSource = !data->texture.hasAlpha;
op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format); op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
#if QT_CONFIG(raster_64bit)
op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);; op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);;
#endif
break; break;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
break; break;
} }
#if !QT_CONFIG(raster_64bit)
op.srcFetch64 = 0;
#endif
op.mode = data->rasterBuffer->compositionMode; op.mode = data->rasterBuffer->compositionMode;
if (op.mode == QPainter::CompositionMode_SourceOver && solidSource) if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
op.mode = QPainter::CompositionMode_Source; op.mode = QPainter::CompositionMode_Source;
op.destFetch = destFetchProc[data->rasterBuffer->format]; op.destFetch = destFetchProc[data->rasterBuffer->format];
#if QT_CONFIG(raster_64bit)
op.destFetch64 = destFetchProc64[data->rasterBuffer->format]; op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
#else
op.destFetch64 = 0;
#endif
if (op.mode == QPainter::CompositionMode_Source && if (op.mode == QPainter::CompositionMode_Source &&
(data->type != QSpanData::Texture || data->texture.const_alpha == 256)) { (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
const QSpan *lastSpan = spans + spanCount; const QSpan *lastSpan = spans + spanCount;
@ -4340,18 +4385,25 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
// But don't clear passthrough destFetch as they are just as fast and save destStore. // But don't clear passthrough destFetch as they are just as fast and save destStore.
if (op.destFetch != destFetchARGB32P) if (op.destFetch != destFetchARGB32P)
op.destFetch = destFetchUndefined; op.destFetch = destFetchUndefined;
#if QT_CONFIG(raster_64bit)
if (op.destFetch64 != destFetchRGB64) if (op.destFetch64 != destFetchRGB64)
op.destFetch64 = destFetch64Undefined; op.destFetch64 = destFetch64Undefined;
#endif
} }
} }
op.destStore = destStoreProc[data->rasterBuffer->format]; op.destStore = destStoreProc[data->rasterBuffer->format];
op.destStore64 = destStoreProc64[data->rasterBuffer->format];
op.funcSolid = functionForModeSolid[op.mode]; op.funcSolid = functionForModeSolid[op.mode];
op.funcSolid64 = functionForModeSolid64[op.mode];
op.func = functionForMode[op.mode]; op.func = functionForMode[op.mode];
#if QT_CONFIG(raster_64bit)
op.destStore64 = destStoreProc64[data->rasterBuffer->format];
op.funcSolid64 = functionForModeSolid64[op.mode];
op.func64 = functionForMode64[op.mode]; op.func64 = functionForMode64[op.mode];
#else
op.destStore64 = 0;
op.funcSolid64 = 0;
op.func64 = 0;
#endif
return op; return op;
} }
@ -4458,6 +4510,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
{ {
#if QT_CONFIG(raster_64bit)
QSpanData *data = reinterpret_cast<QSpanData *>(userData); QSpanData *data = reinterpret_cast<QSpanData *>(userData);
Operator op = getOperator(data, nullptr, 0); Operator op = getOperator(data, nullptr, 0);
if (!op.funcSolid64) { if (!op.funcSolid64) {
@ -4492,6 +4545,9 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
} }
++spans; ++spans;
} }
#else
blend_color_generic(count, spans, userData);
#endif
} }
static void blend_color_rgb16(int count, const QSpan *spans, void *userData) static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
@ -4665,6 +4721,7 @@ public:
} }
}; };
#if QT_CONFIG(raster_64bit)
class BlendSrcGenericRGB64 : public QBlendBase<QRgba64> class BlendSrcGenericRGB64 : public QBlendBase<QRgba64>
{ {
public: public:
@ -4695,6 +4752,7 @@ public:
op.destStore64(data->rasterBuffer, x, y, dest, len); op.destStore64(data->rasterBuffer, x, y, dest, len);
} }
}; };
#endif
static void blend_src_generic(int count, const QSpan *spans, void *userData) static void blend_src_generic(int count, const QSpan *spans, void *userData)
{ {
@ -4703,6 +4761,7 @@ static void blend_src_generic(int count, const QSpan *spans, void *userData)
handleSpans(count, spans, data, blend); handleSpans(count, spans, data, blend);
} }
#if QT_CONFIG(raster_64bit)
static void blend_src_generic_rgb64(int count, const QSpan *spans, void *userData) static void blend_src_generic_rgb64(int count, const QSpan *spans, void *userData)
{ {
QSpanData *data = reinterpret_cast<QSpanData *>(userData); QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@ -4716,6 +4775,7 @@ static void blend_src_generic_rgb64(int count, const QSpan *spans, void *userDat
handleSpans(count, spans, data, blend32); handleSpans(count, spans, data, blend32);
} }
} }
#endif
static void blend_untransformed_generic(int count, const QSpan *spans, void *userData) static void blend_untransformed_generic(int count, const QSpan *spans, void *userData)
{ {
@ -4762,6 +4822,7 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
} }
} }
#if QT_CONFIG(raster_64bit)
static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, void *userData) static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, void *userData)
{ {
QSpanData *data = reinterpret_cast<QSpanData *>(userData); QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@ -4810,6 +4871,7 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
++spans; ++spans;
} }
} }
#endif
static void blend_untransformed_argb(int count, const QSpan *spans, void *userData) static void blend_untransformed_argb(int count, const QSpan *spans, void *userData)
{ {
@ -5004,6 +5066,7 @@ static void blend_tiled_generic(int count, const QSpan *spans, void *userData)
} }
} }
#if QT_CONFIG(raster_64bit)
static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userData) static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userData)
{ {
QSpanData *data = reinterpret_cast<QSpanData *>(userData); QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@ -5099,6 +5162,7 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD
++spans; ++spans;
} }
} }
#endif
static void blend_tiled_argb(int count, const QSpan *spans, void *userData) static void blend_tiled_argb(int count, const QSpan *spans, void *userData)
{ {
@ -5275,6 +5339,7 @@ static const ProcessSpans processTextureSpansGeneric[NBlendTypes] = {
blend_src_generic // TransformedBilinearTiled blend_src_generic // TransformedBilinearTiled
}; };
#if QT_CONFIG(raster_64bit)
static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = { static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
blend_untransformed_generic_rgb64, // Untransformed blend_untransformed_generic_rgb64, // Untransformed
blend_tiled_generic_rgb64, // Tiled blend_tiled_generic_rgb64, // Tiled
@ -5283,6 +5348,7 @@ static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
blend_src_generic_rgb64, // TransformedBilinear blend_src_generic_rgb64, // TransformedBilinear
blend_src_generic_rgb64 // TransformedBilinearTiled blend_src_generic_rgb64 // TransformedBilinearTiled
}; };
#endif
void qBlendTexture(int count, const QSpan *spans, void *userData) void qBlendTexture(int count, const QSpan *spans, void *userData)
{ {
@ -5296,6 +5362,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
case QImage::Format_RGB16: case QImage::Format_RGB16:
proc = processTextureSpansRGB16[blendType]; proc = processTextureSpansRGB16[blendType];
break; break;
#if QT_CONFIG(raster_64bit)
#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8) #if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
case QImage::Format_ARGB32: case QImage::Format_ARGB32:
case QImage::Format_RGBA8888: case QImage::Format_RGBA8888:
@ -5310,6 +5377,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
case QImage::Format_Grayscale16: case QImage::Format_Grayscale16:
proc = processTextureSpansGeneric64[blendType]; proc = processTextureSpansGeneric64[blendType];
break; break;
#endif // QT_CONFIG(raster_64bit)
case QImage::Format_Invalid: case QImage::Format_Invalid:
Q_UNREACHABLE(); Q_UNREACHABLE();
return; return;
@ -5377,7 +5445,11 @@ static void blend_vertical_gradient(int count, const QSpan *spans, void *userDat
while (count--) { while (count--) {
int y = spans->y; int y = spans->y;
#if QT_CONFIG(raster_64bit)
data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off); data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
#else
data->solidColor = QRgba64::fromArgb32(qt_gradient_pixel_fixed(&data->gradient, yinc * y + off));
#endif
blend_color(1, spans, userData); blend_color(1, spans, userData);
++spans; ++spans;
} }
@ -5400,6 +5472,7 @@ void qBlendGradient(int count, const QSpan *spans, void *userData)
if (isVerticalGradient) if (isVerticalGradient)
return blend_vertical_gradient_argb(count, spans, userData); return blend_vertical_gradient_argb(count, spans, userData);
return blend_src_generic(count, spans, userData); return blend_src_generic(count, spans, userData);
#if QT_CONFIG(raster_64bit)
#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8) #if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
case QImage::Format_ARGB32: case QImage::Format_ARGB32:
case QImage::Format_RGBA8888: case QImage::Format_RGBA8888:
@ -5414,6 +5487,7 @@ void qBlendGradient(int count, const QSpan *spans, void *userData)
if (isVerticalGradient) if (isVerticalGradient)
return blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData); return blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData);
return blend_src_generic_rgb64(count, spans, userData); return blend_src_generic_rgb64(count, spans, userData);
#endif // QT_CONFIG(raster_64bit)
case QImage::Format_Invalid: case QImage::Format_Invalid:
break; break;
default: default:
@ -5523,6 +5597,35 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
map, mapWidth, mapHeight, mapStride); map, mapWidth, mapHeight, mapStride);
} }
static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected gray alphablend...
const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
} else if (coverage == 255) {
*dst = src;
} else if (!colorProfile) {
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
} else {
if (*dst >= 0xff000000) {
grayBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
}
}
}
#if QT_CONFIG(raster_64bit)
static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{ {
if (coverage == 0) { if (coverage == 0) {
@ -5624,6 +5727,85 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
} // for (yp -> bottom) } // for (yp -> bottom)
} }
} }
#else
static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip, bool useGammaCorrection)
{
if (color.isTransparent())
return;
const quint32 c = color.toArgb32();
const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
if (colorProfile) {
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
if (!clip) {
for (int ly = 0; ly < mapHeight; ++ly) {
int i = x;
int length = mapWidth;
while (length > 0) {
int l = qMin(BufferSize, length);
quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
for (int j=0; j < l; ++j) {
const int coverage = map[j + (i - x)];
alphamapblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
}
if (destStore)
destStore(rasterBuffer, i, y + ly, dest, l);
length -= l;
i += l;
}
map += mapStride;
}
} else {
int bottom = qMin(y + mapHeight, rasterBuffer->height());
int top = qMax(y, 0);
map += (top - y) * mapStride;
const_cast<QClipData *>(clip)->initialize();
for (int yp = top; yp<bottom; ++yp) {
const QClipData::ClipLine &line = clip->m_clipLines[yp];
for (int i=0; i<line.count; ++i) {
const QSpan &clip = line.spans[i];
int start = qMax<int>(x, clip.x);
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
if (end <= start)
continue;
Q_ASSERT(end - start <= BufferSize);
quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
for (int xp=start; xp<end; ++xp) {
const int coverage = map[xp - x];
alphamapblend_argb32(dest + xp - x, coverage, srcColor, color, colorProfile);
}
if (destStore)
destStore(rasterBuffer, start, clip.y, dest, end - start);
} // for (i -> line.count)
map += mapStride;
} // for (yp -> bottom)
}
}
#endif
static inline void alphamapblend_quint16(int coverage, quint16 *dest, int x, const quint16 srcColor) static inline void alphamapblend_quint16(int coverage, quint16 *dest, int x, const quint16 srcColor)
{ {
@ -5684,44 +5866,6 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
} }
} }
static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected RGB alphablend...
const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected gray alphablend...
const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
} else if (coverage == 255) {
*dst = src;
} else if (!colorProfile) {
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
} else {
if (*dst >= 0xff000000) {
grayBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
*dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
}
}
}
static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color, int x, int y, const QRgba64 &color,
const uchar *map, const uchar *map,
@ -5790,6 +5934,16 @@ static inline int qRgbAvg(QRgb rgb)
return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16; return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
} }
static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected RGB alphablend...
const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha) static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
{ {
#if defined(__SSE2__) #if defined(__SSE2__)
@ -5830,6 +5984,7 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
#endif #endif
} }
#if QT_CONFIG(raster_64bit)
static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{ {
if (coverage == 0xff000000) { if (coverage == 0xff000000) {
@ -5851,6 +6006,7 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co
} }
} }
} }
#endif
static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile) static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{ {
@ -5869,6 +6025,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
} }
} }
#if QT_CONFIG(raster_64bit)
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color, int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride, const uint *src, int mapWidth, int mapHeight, int srcStride,
@ -5943,6 +6100,84 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
} // for (yp -> bottom) } // for (yp -> bottom)
} }
} }
#else
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride,
const QClipData *clip, bool useGammaCorrection)
{
if (color.isTransparent())
return;
const quint32 c = color.toArgb32();
const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
if (colorProfile) {
if (color.isOpaque())
srcColor = colorProfile->toLinear(srcColor);
else
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
if (!clip) {
for (int ly = 0; ly < mapHeight; ++ly) {
int i = x;
int length = mapWidth;
while (length > 0) {
int l = qMin(BufferSize, length);
quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
for (int j=0; j < l; ++j) {
const uint coverage = src[j + (i - x)];
alphargbblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
}
if (destStore)
destStore(rasterBuffer, i, y + ly, dest, l);
length -= l;
i += l;
}
src += srcStride;
}
} else {
int bottom = qMin(y + mapHeight, rasterBuffer->height());
int top = qMax(y, 0);
src += (top - y) * srcStride;
const_cast<QClipData *>(clip)->initialize();
for (int yp = top; yp<bottom; ++yp) {
const QClipData::ClipLine &line = clip->m_clipLines[yp];
for (int i=0; i<line.count; ++i) {
const QSpan &clip = line.spans[i];
int start = qMax<int>(x, clip.x);
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
if (end <= start)
continue;
Q_ASSERT(end - start <= BufferSize);
quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
for (int xp=start; xp<end; ++xp) {
const uint coverage = src[xp - x];
alphargbblend_argb32(dest + xp - start, coverage, srcColor, c, colorProfile);
}
if (destStore)
destStore(rasterBuffer, start, clip.y, dest, end - start);
} // for (i -> line.count)
src += srcStride;
} // for (yp -> bottom)
}
}
#endif
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color, int x, int y, const QRgba64 &color,
@ -6533,8 +6768,10 @@ static void qInitDrawhelperFunctions()
qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>; qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4; qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4; qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
#if QT_CONFIG(raster_64bit)
destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4; destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4; destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
#endif
} }
#endif #endif
@ -6558,18 +6795,19 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2; qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha); extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha); extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha);
qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2; qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2; qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2; qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
#if QT_CONFIG(raster_64bit)
extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels, const QRgba64 *srcPixels, int length, uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha);
qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2; qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
#endif
extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end, const QTextureData &image, extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end, const QTextureData &image,
int &fx, int &fy, int fdx, int /*fdy*/); int &fx, int &fy, int fdx, int /*fdy*/);
@ -6593,6 +6831,7 @@ static void qInitDrawhelperFunctions()
qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2; qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
#if QT_CONFIG(raster_64bit)
extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *, const uint *, int, const QVector<QRgb> *, QDitherInfo *); extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *, const uint *, int, const QVector<QRgb> *, QDitherInfo *);
extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uint *, int count, const QVector<QRgb> *, QDitherInfo *); extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uint *, int count, const QVector<QRgb> *, QDitherInfo *);
extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *); extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *);
@ -6601,6 +6840,7 @@ static void qInitDrawhelperFunctions()
qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2; qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2; qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2; qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
#endif
} }
#endif #endif

View File

@ -396,6 +396,7 @@ void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixe
BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, length, const_alpha); BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(dst, src, length, const_alpha);
} }
#if QT_CONFIG(raster_64bit)
void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, int length, uint const_alpha) void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, int length, uint const_alpha)
{ {
Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255] Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255]
@ -453,6 +454,7 @@ void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *dst, const QRgba64 *sr
blend_pixel(dst[x], src[x], const_alpha); blend_pixel(dst[x], src[x], const_alpha);
} }
} }
#endif
void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, uint const_alpha) void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, uint const_alpha)
{ {
@ -485,6 +487,7 @@ void QT_FASTCALL comp_func_Source_avx2(uint *dst, const uint *src, int length, u
} }
} }
#if QT_CONFIG(raster_64bit)
void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, int length, uint const_alpha) void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, int length, uint const_alpha)
{ {
Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255] Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255]
@ -517,6 +520,7 @@ void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, i
dst[x] = interpolate65535(src[x], ca, dst[x], cia); dst[x] = interpolate65535(src[x], ca, dst[x], cia);
} }
} }
#endif
void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha) void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, uint color, uint const_alpha)
{ {
@ -549,6 +553,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels, int length, u
} }
} }
#if QT_CONFIG(raster_64bit)
void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha) void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha)
{ {
Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255] Q_ASSERT(const_alpha < 256); // const_alpha is in [0-255]
@ -579,6 +584,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int
destPixels[x] = color + multiplyAlpha65535(destPixels[x], minusAlphaOfColor); destPixels[x] = color + multiplyAlpha65535(destPixels[x], minusAlphaOfColor);
} }
} }
#endif
#define interpolate_4_pixels_16_avx2(tlr1, tlr2, blr1, blr2, distx, disty, colorMask, v_256, b) \ #define interpolate_4_pixels_16_avx2(tlr1, tlr2, blr1, blr2, distx, disty, colorMask, v_256, b) \
{ \ { \

View File

@ -296,7 +296,9 @@ struct QGradientData
#define GRADIENT_STOPTABLE_SIZE 1024 #define GRADIENT_STOPTABLE_SIZE 1024
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10 #define GRADIENT_STOPTABLE_SIZE_SHIFT 10
#if QT_CONFIG(raster_64bit)
const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE]; const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE];
#endif
const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE]; const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE];
uint alphaColor : 1; uint alphaColor : 1;
@ -402,11 +404,13 @@ static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos)
return data->colorTable32[qt_gradient_clamp(data, ipos)]; return data->colorTable32[qt_gradient_clamp(data, ipos)];
} }
#if QT_CONFIG(raster_64bit)
static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos) static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos)
{ {
int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
return data->colorTable64[qt_gradient_clamp(data, ipos)]; return data->colorTable64[qt_gradient_clamp(data, ipos)];
} }
#endif
static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c)
{ {

View File

@ -399,6 +399,7 @@ void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, i
d[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]); d[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]);
} }
#if QT_CONFIG(raster_64bit)
void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length) void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{ {
uint *dest = (uint*)rasterBuffer->scanLine(y) + x; uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
@ -410,6 +411,7 @@ void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer, int x, in
uint *dest = (uint*)rasterBuffer->scanLine(y) + x; uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
convertARGBFromRGBA64PM_sse4<true>(dest, buffer, length); convertARGBFromRGBA64PM_sse4<true>(dest, buffer, length);
} }
#endif
void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count, void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *) const QVector<QRgb> *, QDitherInfo *)

View File

@ -528,6 +528,7 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des
} }
} }
#if QT_CONFIG(raster_64bit)
static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest, static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
int dw, int dh, int dow, int sow); int dw, int dh, int dow, int sow);
@ -728,6 +729,7 @@ static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
} }
} }
} }
#endif
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow); int dw, int dh, int dow, int sow);
@ -945,10 +947,13 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
return QImage(); return QImage();
} }
#if QT_CONFIG(raster_64bit)
if (src.depth() > 32) if (src.depth() > 32)
qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0), qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),
dw, dh, dw, src.bytesPerLine() / 8); dw, dh, dw, src.bytesPerLine() / 8);
else if (src.hasAlphaChannel()) else
#endif
if (src.hasAlphaChannel())
qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
dw, dh, dw, src.bytesPerLine() / 4); dw, dh, dw, src.bytesPerLine() / 4);
else else

View File

@ -4531,7 +4531,9 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable32 = cacheInfo->buffer32;
#if QT_CONFIG(raster_64bit)
gradient.colorTable64 = cacheInfo->buffer64; gradient.colorTable64 = cacheInfo->buffer64;
#endif
cachedGradient = std::move(cacheInfo); cachedGradient = std::move(cacheInfo);
gradient.spread = g->spread(); gradient.spread = g->spread();
@ -4553,7 +4555,9 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable32 = cacheInfo->buffer32;
#if QT_CONFIG(raster_64bit)
gradient.colorTable64 = cacheInfo->buffer64; gradient.colorTable64 = cacheInfo->buffer64;
#endif
cachedGradient = std::move(cacheInfo); cachedGradient = std::move(cacheInfo);
gradient.spread = g->spread(); gradient.spread = g->spread();
@ -4579,7 +4583,9 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha);
gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable32 = cacheInfo->buffer32;
#if QT_CONFIG(raster_64bit)
gradient.colorTable64 = cacheInfo->buffer64; gradient.colorTable64 = cacheInfo->buffer64;
#endif
cachedGradient = std::move(cacheInfo); cachedGradient = std::move(cacheInfo);
gradient.spread = QGradient::RepeatSpread; gradient.spread = QGradient::RepeatSpread;

View File

@ -1852,7 +1852,9 @@ void tst_QImage::smoothScale4_data()
QTest::addColumn<QImage::Format>("format"); QTest::addColumn<QImage::Format>("format");
QTest::newRow("RGB32") << QImage::Format_RGB32; QTest::newRow("RGB32") << QImage::Format_RGB32;
#if QT_CONFIG(raster_64bit)
QTest::newRow("RGBx64") << QImage::Format_RGBX64; QTest::newRow("RGBx64") << QImage::Format_RGBX64;
#endif
} }
void tst_QImage::smoothScale4() void tst_QImage::smoothScale4()
@ -3412,6 +3414,7 @@ void tst_QImage::ditherGradient_data()
QTest::newRow("argb32pm -> argb6666pm (no dither)") << rgb32 << QImage::Format_ARGB6666_Premultiplied << 0 << 64; QTest::newRow("argb32pm -> argb6666pm (no dither)") << rgb32 << QImage::Format_ARGB6666_Premultiplied << 0 << 64;
QTest::newRow("argb32pm -> argb6666pm (dithering)") << rgb32 << QImage::Format_ARGB6666_Premultiplied << int(Qt::PreferDither | Qt::OrderedDither) << 129; QTest::newRow("argb32pm -> argb6666pm (dithering)") << rgb32 << QImage::Format_ARGB6666_Premultiplied << int(Qt::PreferDither | Qt::OrderedDither) << 129;
#if QT_CONFIG(raster_64bit)
QImage rgb30(1024, 16, QImage::Format_RGB30); QImage rgb30(1024, 16, QImage::Format_RGB30);
QLinearGradient gradient30(QRectF(rgb30.rect()).topLeft(), QRectF(rgb30.rect()).topRight()); QLinearGradient gradient30(QRectF(rgb30.rect()).topLeft(), QRectF(rgb30.rect()).topRight());
gradient30.setColorAt(0.0, QColor(0, 0, 0)); gradient30.setColorAt(0.0, QColor(0, 0, 0));
@ -3424,6 +3427,7 @@ void tst_QImage::ditherGradient_data()
QTest::newRow("rgb30 -> rgb32 (dithering)") << rgb30 << QImage::Format_RGB32 << int(Qt::PreferDither | Qt::OrderedDither) << 513; QTest::newRow("rgb30 -> rgb32 (dithering)") << rgb30 << QImage::Format_RGB32 << int(Qt::PreferDither | Qt::OrderedDither) << 513;
QTest::newRow("rgb30 -> rgb888 (no dither)") << rgb30 << QImage::Format_RGB888 << 0 << 256; QTest::newRow("rgb30 -> rgb888 (no dither)") << rgb30 << QImage::Format_RGB888 << 0 << 256;
QTest::newRow("rgb30 -> rgb888 (dithering)") << rgb30 << QImage::Format_RGB888 << int(Qt::PreferDither | Qt::OrderedDither) << 513; QTest::newRow("rgb30 -> rgb888 (dithering)") << rgb30 << QImage::Format_RGB888 << int(Qt::PreferDither | Qt::OrderedDither) << 513;
#endif
} }
void tst_QImage::ditherGradient() void tst_QImage::ditherGradient()

View File

@ -185,10 +185,12 @@ private slots:
void gradientPixelFormat_data(); void gradientPixelFormat_data();
void gradientPixelFormat(); void gradientPixelFormat();
#if QT_CONFIG(raster_64bit)
void linearGradientRgb30_data(); void linearGradientRgb30_data();
void linearGradientRgb30(); void linearGradientRgb30();
void radialGradientRgb30_data(); void radialGradientRgb30_data();
void radialGradientRgb30(); void radialGradientRgb30();
#endif
void fpe_pixmapTransform(); void fpe_pixmapTransform();
void fpe_zeroLengthLines(); void fpe_zeroLengthLines();
@ -3946,6 +3948,7 @@ void tst_QPainter::gradientInterpolation()
} }
} }
#if QT_CONFIG(raster_64bit)
void tst_QPainter::linearGradientRgb30_data() void tst_QPainter::linearGradientRgb30_data()
{ {
QTest::addColumn<QColor>("stop0"); QTest::addColumn<QColor>("stop0");
@ -4004,6 +4007,7 @@ void tst_QPainter::radialGradientRgb30()
QVERIFY(qGray(p1.rgb()) >= qGray(p2.rgb())); QVERIFY(qGray(p1.rgb()) >= qGray(p2.rgb()));
} }
} }
#endif
void tst_QPainter::drawPolygon() void tst_QPainter::drawPolygon()
{ {
@ -4884,14 +4888,18 @@ void tst_QPainter::blendARGBonRGB_data()
<< QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 85) << 85; << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 85) << 85;
QTest::newRow("ARGB_PM over RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied QTest::newRow("ARGB_PM over RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85; << QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85;
#if QT_CONFIG(raster_64bit)
QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
<< QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85; << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85;
QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
<< QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85; << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85;
#endif
QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85; << QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85;
#if QT_CONFIG(raster_64bit)
QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170; << QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170;
#endif
QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32 QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
<< QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85; << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85;
QTest::newRow("ARGB_PM source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied QTest::newRow("ARGB_PM source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied