|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
|
|
@ -1126,6 +1127,7 @@ static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count)
|
|
|
|
|
static void convertRGBA64PMToRGBA64PM(QRgba64 *, int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
|
|
|
|
|
const QVector<QRgb> *, QDitherInfo *)
|
|
|
|
@ -1699,22 +1701,6 @@ static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *, int,
|
|
|
|
|
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] =
|
|
|
|
|
{
|
|
|
|
|
0, // Format_Invalid
|
|
|
|
@ -1748,6 +1734,23 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
|
|
|
|
|
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] =
|
|
|
|
|
{
|
|
|
|
|
0, // Format_Invalid
|
|
|
|
@ -1780,6 +1783,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
|
|
|
|
|
destFetchRGB64, // Format_RGBA64_Premultiplied
|
|
|
|
|
destFetch64, // Format_Grayscale16
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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] =
|
|
|
|
|
{
|
|
|
|
|
0, // Format_Invalid
|
|
|
|
@ -1935,6 +1924,22 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
|
|
|
|
|
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] =
|
|
|
|
|
{
|
|
|
|
|
0, // Format_Invalid
|
|
|
|
@ -1967,6 +1972,7 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
|
|
|
|
|
0, // Format_RGBA64_Premultiplied
|
|
|
|
|
destStore64, // Format_Grayscale16
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Source fetches
|
|
|
|
@ -2017,6 +2023,7 @@ static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Opera
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Operator *,
|
|
|
|
|
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);
|
|
|
|
|
return reinterpret_cast<const QRgba64 *>(scanLine) + x;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
template<TextureBlendType blendType>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
|
|
|
|
|
static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data,
|
|
|
|
|
int y, int x, int length)
|
|
|
|
@ -2240,6 +2249,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Oper
|
|
|
|
|
convertRGBA64ToRGBA64PM(buffer, length);
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/** \internal
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
template<TextureBlendType blendType>
|
|
|
|
|
static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer, const QSpanData *data,
|
|
|
|
|
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_uint32<blendType>(buffer, data, y, x, length);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// FetchUntransformed can have more specialized methods added depending on SIMD features.
|
|
|
|
|
static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
|
|
|
|
@ -3931,6 +3943,20 @@ static SourceFetchProc sourceFetchAny32[NBlendTypes] = {
|
|
|
|
|
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] = {
|
|
|
|
|
fetchUntransformed64, // Untransformed
|
|
|
|
|
fetchUntransformed64, // Tiled
|
|
|
|
@ -3949,25 +3975,13 @@ static const SourceFetchProc64 sourceFetchRGBA64PM[NBlendTypes] = {
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
|
|
|
|
|
return sourceFetchRGBA64PM[blendType];
|
|
|
|
|
return sourceFetchGeneric64[blendType];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const QRgba64& qt_gradient_pixel64_fixed(const QGradientData *data, int fixed_pos)
|
|
|
|
|
{
|
|
|
|
|
int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
|
|
|
|
|
return data->colorTable64[qt_gradient_clamp(data, ipos)];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data)
|
|
|
|
|
{
|
|
|
|
@ -4017,6 +4033,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
class GradientBase64
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
@ -4035,6 +4052,7 @@ public:
|
|
|
|
|
qt_memfill64((quint64*)buffer, fill, length);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
template<class GradientBase, typename BlendType>
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
|
|
|
|
|
int y, int x, int 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)
|
|
|
|
|
{
|
|
|
|
@ -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;
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer, const Operator *op, const QSpanData *data,
|
|
|
|
|
int y, int x, int length)
|
|
|
|
|
{
|
|
|
|
|
return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
template <class GradientBase, typename BlendType>
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer, const Operator *, const QSpanData *data,
|
|
|
|
|
int y, int x, int length)
|
|
|
|
|
{
|
|
|
|
|
return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern CompositionFunctionSolid qt_functionForModeSolid_C[];
|
|
|
|
|
extern CompositionFunctionSolid64 qt_functionForModeSolid64_C[];
|
|
|
|
|
|
|
|
|
|
static const CompositionFunctionSolid *functionForModeSolid = qt_functionForModeSolid_C;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern CompositionFunction qt_functionForMode_C[];
|
|
|
|
|
extern CompositionFunction64 qt_functionForMode64_C[];
|
|
|
|
|
|
|
|
|
|
static const CompositionFunction *functionForMode = qt_functionForMode_C;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static TextureBlendType getBlendType(const QSpanData *data)
|
|
|
|
|
{
|
|
|
|
@ -4289,41 +4317,58 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
|
|
|
|
|
case QSpanData::Solid:
|
|
|
|
|
solidSource = data->solidColor.isOpaque();
|
|
|
|
|
op.srcFetch = 0;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = 0;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case QSpanData::LinearGradient:
|
|
|
|
|
solidSource = !data->gradient.alphaColor;
|
|
|
|
|
getLinearGradientValues(&op.linear, data);
|
|
|
|
|
op.srcFetch = qt_fetch_linear_gradient;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case QSpanData::RadialGradient:
|
|
|
|
|
solidSource = !data->gradient.alphaColor;
|
|
|
|
|
getRadialGradientValues(&op.radial, data);
|
|
|
|
|
op.srcFetch = qt_fetch_radial_gradient;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case QSpanData::ConicalGradient:
|
|
|
|
|
solidSource = !data->gradient.alphaColor;
|
|
|
|
|
op.srcFetch = qt_fetch_conical_gradient;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case QSpanData::Texture:
|
|
|
|
|
solidSource = !data->texture.hasAlpha;
|
|
|
|
|
op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
Q_UNREACHABLE();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#if !QT_CONFIG(raster_64bit)
|
|
|
|
|
op.srcFetch64 = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
op.mode = data->rasterBuffer->compositionMode;
|
|
|
|
|
if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
|
|
|
|
|
op.mode = QPainter::CompositionMode_Source;
|
|
|
|
|
|
|
|
|
|
op.destFetch = destFetchProc[data->rasterBuffer->format];
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
|
|
|
|
|
#else
|
|
|
|
|
op.destFetch64 = 0;
|
|
|
|
|
#endif
|
|
|
|
|
if (op.mode == QPainter::CompositionMode_Source &&
|
|
|
|
|
(data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
|
|
|
|
|
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.
|
|
|
|
|
if (op.destFetch != destFetchARGB32P)
|
|
|
|
|
op.destFetch = destFetchUndefined;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
if (op.destFetch64 != destFetchRGB64)
|
|
|
|
|
op.destFetch64 = destFetch64Undefined;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
op.destStore = destStoreProc[data->rasterBuffer->format];
|
|
|
|
|
op.destStore64 = destStoreProc64[data->rasterBuffer->format];
|
|
|
|
|
|
|
|
|
|
op.funcSolid = functionForModeSolid[op.mode];
|
|
|
|
|
op.funcSolid64 = functionForModeSolid64[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];
|
|
|
|
|
#else
|
|
|
|
|
op.destStore64 = 0;
|
|
|
|
|
op.funcSolid64 = 0;
|
|
|
|
|
op.func64 = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
|
|
|
|
|
Operator op = getOperator(data, nullptr, 0);
|
|
|
|
|
if (!op.funcSolid64) {
|
|
|
|
@ -4492,6 +4545,9 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
|
|
|
|
|
}
|
|
|
|
|
++spans;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
blend_color_generic(count, spans, userData);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
@ -4695,6 +4752,7 @@ public:
|
|
|
|
|
op.destStore64(data->rasterBuffer, x, y, dest, len);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static void blend_src_generic_rgb64(int count, const QSpan *spans, void *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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
|
|
|
|
@ -4810,6 +4871,7 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
|
|
|
|
|
++spans;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
|
|
|
|
@ -5099,6 +5162,7 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD
|
|
|
|
|
++spans;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
|
|
|
|
|
blend_untransformed_generic_rgb64, // Untransformed
|
|
|
|
|
blend_tiled_generic_rgb64, // Tiled
|
|
|
|
@ -5283,6 +5348,7 @@ static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
|
|
|
|
|
blend_src_generic_rgb64, // TransformedBilinear
|
|
|
|
|
blend_src_generic_rgb64 // TransformedBilinearTiled
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
proc = processTextureSpansRGB16[blendType];
|
|
|
|
|
break;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
|
|
|
|
|
case QImage::Format_ARGB32:
|
|
|
|
|
case QImage::Format_RGBA8888:
|
|
|
|
@ -5310,6 +5377,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
|
|
|
|
|
case QImage::Format_Grayscale16:
|
|
|
|
|
proc = processTextureSpansGeneric64[blendType];
|
|
|
|
|
break;
|
|
|
|
|
#endif // QT_CONFIG(raster_64bit)
|
|
|
|
|
case QImage::Format_Invalid:
|
|
|
|
|
Q_UNREACHABLE();
|
|
|
|
|
return;
|
|
|
|
@ -5377,7 +5445,11 @@ static void blend_vertical_gradient(int count, const QSpan *spans, void *userDat
|
|
|
|
|
while (count--) {
|
|
|
|
|
int y = spans->y;
|
|
|
|
|
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
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);
|
|
|
|
|
++spans;
|
|
|
|
|
}
|
|
|
|
@ -5400,6 +5472,7 @@ void qBlendGradient(int count, const QSpan *spans, void *userData)
|
|
|
|
|
if (isVerticalGradient)
|
|
|
|
|
return blend_vertical_gradient_argb(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)
|
|
|
|
|
case QImage::Format_ARGB32:
|
|
|
|
|
case QImage::Format_RGBA8888:
|
|
|
|
@ -5414,6 +5487,7 @@ void qBlendGradient(int count, const QSpan *spans, void *userData)
|
|
|
|
|
if (isVerticalGradient)
|
|
|
|
|
return blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData);
|
|
|
|
|
return blend_src_generic_rgb64(count, spans, userData);
|
|
|
|
|
#endif // QT_CONFIG(raster_64bit)
|
|
|
|
|
case QImage::Format_Invalid:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
@ -5523,6 +5597,35 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (coverage == 0) {
|
|
|
|
@ -5624,6 +5727,85 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
|
|
|
|
|
} // 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)
|
|
|
|
|
{
|
|
|
|
@ -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,
|
|
|
|
|
int x, int y, const QRgba64 &color,
|
|
|
|
|
const uchar *map,
|
|
|
|
@ -5790,6 +5934,16 @@ static inline int qRgbAvg(QRgb rgb)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
#if defined(__SSE2__)
|
|
|
|
@ -5830,6 +5984,7 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
|
|
|
|
|
#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)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
@ -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,
|
|
|
|
|
int x, int y, const QRgba64 &color,
|
|
|
|
|
const uint *src, int mapWidth, int mapHeight, int srcStride,
|
|
|
|
@ -5943,6 +6100,84 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
|
|
|
|
|
} // 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,
|
|
|
|
|
int x, int y, const QRgba64 &color,
|
|
|
|
@ -6533,8 +6768,10 @@ static void qInitDrawhelperFunctions()
|
|
|
|
|
qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
|
|
|
|
|
qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
|
|
|
|
|
qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
|
|
|
|
|
#if QT_CONFIG(raster_64bit)
|
|
|
|
|
destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
|
|
|
|
|
destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -6558,18 +6795,19 @@ static void qInitDrawhelperFunctions()
|
|
|
|
|
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_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_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_rgb64_avx2(QRgba64 *destPixels, int length, QRgba64 color, uint const_alpha);
|
|
|
|
|
|
|
|
|
|
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_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_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;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end, const QTextureData &image,
|
|
|
|
|
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].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 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 *);
|
|
|
|
@ -6601,6 +6840,7 @@ static void qInitDrawhelperFunctions()
|
|
|
|
|
qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
|
|
|
|
|
qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
|
|
|
|
|
qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|