8#include <qstylehints.h>
9#include <qguiapplication.h>
11#include <private/qcolortransform_p.h>
12#include <private/qcolortrclut_p.h>
13#include <private/qdrawhelper_p.h>
14#include <private/qdrawhelper_x86_p.h>
15#include <private/qdrawingprimitive_sse2_p.h>
16#include <private/qdrawhelper_loongarch64_p.h>
17#include <private/qdrawingprimitive_lsx_p.h>
18#include <private/qdrawhelper_neon_p.h>
19#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
20#include <private/qdrawhelper_mips_dsp_p.h>
22#include <private/qguiapplication_p.h>
23#include <private/qpaintengine_raster_p.h>
24#include <private/qpainter_p.h>
25#include <private/qpixellayout_p.h>
26#include <private/qrgba64_p.h>
28#include <qloggingcategory.h>
31#if QT_CONFIG(qtgui_threadpool)
32#include <private/qlatch_p.h>
33#include <qthreadpool.h>
34#include <private/qthreadpool_p.h>
39#if QT_CONFIG(raster_64bit) || QT_CONFIG(raster_fp)
40Q_STATIC_LOGGING_CATEGORY(lcQtGuiDrawHelper,
"qt.gui.drawhelper")
43#define MASK(src, a) src = BYTE_MUL(src, a)
46
47
55 Q_UNREACHABLE_RETURN(0);
59inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1LSB>(
const uchar *src,
int index)
61 return (src[index >> 3] >> (index & 7)) & 1;
65inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1MSB>(
const uchar *src,
int index)
67 return (src[index >> 3] >> (~index & 7)) & 1;
71inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP8>(
const uchar *src,
int index)
77inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16>(
const uchar *src,
int index)
79 return reinterpret_cast<
const quint16 *>(src)[index];
83inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP24>(
const uchar *src,
int index)
85 return reinterpret_cast<
const quint24 *>(src)[index];
89inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32>(
const uchar *src,
int index)
91 return reinterpret_cast<
const uint *>(src)[index];
95inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP64>(
const uchar *src,
int index)
98 QRgba64 c =
reinterpret_cast<
const QRgba64 *>(src)[index];
103inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16FPx4>(
const uchar *src,
int index)
106 QRgbaFloat16 c =
reinterpret_cast<
const QRgbaFloat16 *>(src)[index];
111inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32FPx4>(
const uchar *src,
int index)
114 QRgbaFloat32 c =
reinterpret_cast<
const QRgbaFloat32 *>(src)[index];
122 fetch1Pixel<QPixelLayout::BPP1MSB>,
123 fetch1Pixel<QPixelLayout::BPP1LSB>,
124 fetch1Pixel<QPixelLayout::BPP8>,
125 fetch1Pixel<QPixelLayout::BPP16>,
126 fetch1Pixel<QPixelLayout::BPP24>,
127 fetch1Pixel<QPixelLayout::BPP32>,
128 fetch1Pixel<QPixelLayout::BPP64>,
129 fetch1Pixel<QPixelLayout::BPP16FPx4>,
130 fetch1Pixel<QPixelLayout::BPP32FPx4>,
133#if QT_CONFIG(raster_64bit)
134static void QT_FASTCALL convertRGBA64ToRGBA64PM(QRgba64 *buffer,
int count)
136 for (
int i = 0; i < count; ++i)
137 buffer[i] = buffer[i].premultiplied();
140static void QT_FASTCALL convertRGBA64PMToRGBA64PM(QRgba64 *,
int)
144static void QT_FASTCALL convertRGBA16FToRGBA64PM(QRgba64 *buffer,
int count)
146 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
147 for (
int i = 0; i < count; ++i) {
148 QRgbaFloat16 c = in[i];
149 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
153static void QT_FASTCALL convertRGBA16FPMToRGBA64PM(QRgba64 *buffer,
int count)
155 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
156 for (
int i = 0; i < count; ++i) {
157 QRgbaFloat16 c = in[i];
158 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
162static void QT_FASTCALL convertRGBA32FToRGBA64PM(QRgba64 *buffer,
int count)
164 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
165 for (
int i = 0; i < count; ++i) {
166 QRgbaFloat32 c = in[i];
167 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
171static void QT_FASTCALL convertRGBA32FPMToRGBA64PM(QRgba64 *buffer,
int count)
173 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
174 for (
int i = 0; i < count; ++i) {
175 QRgbaFloat32 c = in[i];
176 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
180static Convert64Func convert64ToRGBA64PM[] = {
206 convertRGBA64PMToRGBA64PM,
207 convertRGBA64ToRGBA64PM,
208 convertRGBA64PMToRGBA64PM,
211 convertRGBA16FPMToRGBA64PM,
212 convertRGBA16FToRGBA64PM,
213 convertRGBA16FPMToRGBA64PM,
214 convertRGBA32FPMToRGBA64PM,
215 convertRGBA32FToRGBA64PM,
216 convertRGBA32FPMToRGBA64PM,
220static_assert(std::size(convert64ToRGBA64PM) == QImage::NImageFormats);
223#if QT_CONFIG(raster_fp)
224static void QT_FASTCALL convertRGBA64PMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
226 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
227 for (
int i = 0; i < count; ++i) {
229 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha()).premultiplied();
233static void QT_FASTCALL convertRGBA64ToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
235 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
236 for (
int i = 0; i < count; ++i) {
238 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
242static void QT_FASTCALL convertRGBA16FPMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
244 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
245 for (
int i = 0; i < count; ++i)
246 buffer[i] = buffer[i].premultiplied();
249static void QT_FASTCALL convertRGBA16FToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
251 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
254static Convert64ToFPFunc convert64ToRGBA32F[] = {
280 convertRGBA64ToRGBA32F,
281 convertRGBA64PMToRGBA32F,
282 convertRGBA64ToRGBA32F,
285 convertRGBA16FToRGBA32F,
286 convertRGBA16FPMToRGBA32F,
287 convertRGBA16FToRGBA32F,
294static_assert(std::size(convert64ToRGBA32F) == QImage::NImageFormats);
296static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer,
int count)
298 for (
int i = 0; i < count; ++i)
299 buffer[i] = buffer[i].premultiplied();
302static void convertRGBA32FToRGBA32F(QRgbaFloat32 *,
int)
309
310
311
313static uint * QT_FASTCALL destFetchMono(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
316 uint *start = buffer;
317 const uint *end = buffer + length;
318 while (buffer < end) {
319 *buffer = data[x>>3] & (0x80 >> (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
326static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
329 uint *start = buffer;
330 const uint *end = buffer + length;
331 while (buffer < end) {
332 *buffer = data[x>>3] & (0x1 << (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
339static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
341 return (uint *)rasterBuffer->scanLine(y) + x;
344static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
346 const ushort *
Q_DECL_RESTRICT data = (
const ushort *)rasterBuffer->scanLine(y) + x;
347 for (
int i = 0; i < length; ++i)
348 buffer[i] = qConvertRgb16To32(data[i]);
352static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
354 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
355 return const_cast<uint *>(layout->fetchToARGB32PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
358static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *,
int,
int,
int)
404static_assert(std::size(destFetchProc) == QImage::NImageFormats);
406#if QT_CONFIG(raster_64bit)
407static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
409 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
410 return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
413static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
415 return (QRgba64 *)rasterBuffer->scanLine(y) + x;
418static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *,
int,
int,
int)
423static DestFetchProc64 destFetchProc64[] =
464static_assert(std::size(destFetchProc64) == QImage::NImageFormats);
467#if QT_CONFIG(raster_fp)
468static QRgbaFloat32 *QT_FASTCALL destFetchFP(QRgbaFloat32 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
470 return const_cast<QRgbaFloat32 *>(qFetchToRGBA32F[rasterBuffer->format](buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
473static QRgbaFloat32 *QT_FASTCALL destFetchRGBFP(QRgbaFloat32 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
475 return reinterpret_cast<QRgbaFloat32 *>(rasterBuffer->scanLine(y)) + x;
478static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRasterBuffer *,
int,
int,
int)
482static DestFetchProcFP destFetchProcFP[] =
523static_assert(std::size(destFetchProcFP) == QImage::NImageFormats);
527
528
529
532 const QRgb color_0 = rbuf->destColor0;
533 const QRgb color_1 = rbuf->destColor1;
536 int g = qGreen(color);
537 int b = qBlue(color);
541 rx = r - qRed(color_0);
542 gx = g - qGreen(color_0);
543 bx = b - qBlue(color_0);
544 dist_0 = rx*rx + gx*gx + bx*bx;
546 rx = r - qRed(color_1);
547 gx = g - qGreen(color_1);
548 bx = b - qBlue(color_1);
549 dist_1 = rx*rx + gx*gx + bx*bx;
557
558
560static void QT_FASTCALL destStoreMono(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
563 if (rasterBuffer->monoDestinationWithClut) {
564 for (
int i = 0; i < length; ++i) {
565 if (buffer[i] == rasterBuffer->destColor0) {
566 data[x >> 3] &= ~(0x80 >> (x & 7));
567 }
else if (buffer[i] == rasterBuffer->destColor1) {
568 data[x >> 3] |= 0x80 >> (x & 7);
569 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
570 data[x >> 3] &= ~(0x80 >> (x & 7));
572 data[x >> 3] |= 0x80 >> (x & 7);
577 for (
int i = 0; i < length; ++i) {
578 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
579 data[x >> 3] |= 0x80 >> (x & 7);
581 data[x >> 3] &= ~(0x80 >> (x & 7));
587static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
590 if (rasterBuffer->monoDestinationWithClut) {
591 for (
int i = 0; i < length; ++i) {
592 if (buffer[i] == rasterBuffer->destColor0) {
593 data[x >> 3] &= ~(1 << (x & 7));
594 }
else if (buffer[i] == rasterBuffer->destColor1) {
595 data[x >> 3] |= 1 << (x & 7);
596 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
597 data[x >> 3] &= ~(1 << (x & 7));
599 data[x >> 3] |= 1 << (x & 7);
604 for (
int i = 0; i < length; ++i) {
605 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
606 data[x >> 3] |= 1 << (x & 7);
608 data[x >> 3] &= ~(1 << (x & 7));
614static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
616 quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x;
617 for (
int i = 0; i < length; ++i)
618 data[i] = qConvertRgb32To16(buffer[i]);
621static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
623 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
624 ConvertAndStorePixelsFunc store = layout->storeFromARGB32PM;
625 if (!layout->premultiplied && !layout->hasAlphaChannel)
626 store = layout->storeFromRGB32;
627 uchar *dest = rasterBuffer->scanLine(y);
628 store(dest, buffer, x, length,
nullptr,
nullptr);
631static void QT_FASTCALL destStoreGray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
633 uchar *data = rasterBuffer->scanLine(y) + x;
636 for (
int k = 0; k < length; ++k) {
637 if (!qIsGray(buffer[k])) {
641 data[k] = qRed(buffer[k]);
644 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
645 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
646 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
648 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
652static void QT_FASTCALL destStoreGray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
654 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
657 for (
int k = 0; k < length; ++k) {
658 if (!qIsGray(buffer[k])) {
662 data[k] = qRed(buffer[k]) * 257;
665 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
666 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
667 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
669 Q_DECL_UNINITIALIZED QRgba64 tmp_line[BufferSize];
670 for (
int k = 0; k < length; ++k)
671 tmp_line[k] = QRgba64::fromArgb32(buffer[k]);
672 tfd->apply(data, tmp_line, length, QColorTransformPrivate::InputPremultiplied);
717static_assert(std::size(destStoreProc) == QImage::NImageFormats);
719#if QT_CONFIG(raster_64bit)
720static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
722 auto store = qStoreFromRGBA64PM[rasterBuffer->format];
723 uchar *dest = rasterBuffer->scanLine(y);
724 store(dest, buffer, x, length,
nullptr,
nullptr);
727static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
729 QRgba64 *dest =
reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
730 for (
int i = 0; i < length; ++i) {
731 dest[i] = buffer[i].unpremultiplied();
735static void QT_FASTCALL destStore64Gray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
737 uchar *data = rasterBuffer->scanLine(y) + x;
740 for (
int k = 0; k < length; ++k) {
741 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
745 data[k] = buffer[k].red8();
748 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
749 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
750 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
752 Q_DECL_UNINITIALIZED quint16 gray_line[BufferSize];
753 tfd->apply(gray_line, buffer, length, QColorTransformPrivate::InputPremultiplied);
754 for (
int k = 0; k < length; ++k)
755 data[k] = qt_div_257(gray_line[k]);
759static void QT_FASTCALL destStore64Gray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
761 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
764 for (
int k = 0; k < length; ++k) {
765 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
769 data[k] = buffer[k].red();
772 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
773 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
774 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
775 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
779static DestStoreProc64 destStoreProc64[] =
820static_assert(std::size(destStoreProc64) == QImage::NImageFormats);
823#if QT_CONFIG(raster_fp)
824static void QT_FASTCALL destStoreFP(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgbaFloat32 *buffer,
int length)
826 auto store = qStoreFromRGBA32F[rasterBuffer->format];
827 uchar *dest = rasterBuffer->scanLine(y);
828 store(dest, buffer, x, length,
nullptr,
nullptr);
833
834
835
836
837
838
839
840
841
842
843
844
845
857static const uint *QT_FASTCALL fetchUntransformed(uint *buffer,
const Operator *,
858 const QSpanData *data,
int y,
int x,
int length)
860 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
861 return layout->fetchToARGB32PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
864static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *,
const Operator *,
865 const QSpanData *data,
int y,
int x,
int)
867 const uchar *scanLine = data->texture.scanLine(y);
868 return reinterpret_cast<
const uint *>(scanLine) + x;
871static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer,
const Operator *,
872 const QSpanData *data,
int y,
int x,
875 const quint16 *scanLine = (
const quint16 *)data->texture.scanLine(y) + x;
876 for (
int i = 0; i < length; ++i)
877 buffer[i] = qConvertRgb16To32(scanLine[i]);
881#if QT_CONFIG(raster_64bit)
882static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer,
const Operator *,
883 const QSpanData *data,
int y,
int x,
int length)
885 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
886 return layout->fetchToRGBA64PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
889static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *,
const Operator *,
890 const QSpanData *data,
int y,
int x,
int)
892 const uchar *scanLine = data->texture.scanLine(y);
893 return reinterpret_cast<
const QRgba64 *>(scanLine) + x;
897#if QT_CONFIG(raster_fp)
898static const QRgbaFloat32 *QT_FASTCALL fetchUntransformedFP(QRgbaFloat32 *buffer,
const Operator *,
899 const QSpanData *data,
int y,
int x,
int length)
901 const auto fetch = qFetchToRGBA32F[data->texture.format];
902 return fetch(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
911 if (v < 0 || v >= max) {
916 v = qBound(l1, v, l2);
922 if (Q_UNLIKELY(!data->fast_matrix))
925 qreal fx = (data->m21 * cy + data->m11 * cx + data->dx) *
fixed_scale;
926 qreal fy = (data->m22 * cy + data->m12 * cx + data->dy) *
fixed_scale;
927 qreal minc =
std::min(fx, fy);
928 qreal maxc =
std::max(fx, fy);
931 minc =
std::min(minc,
std::min(fx, fy));
932 maxc =
std::max(maxc,
std::max(fx, fy));
934 return minc >=
std::numeric_limits<
int>::min() && maxc <= qreal(
std::numeric_limits<
int>::max());
938static void QT_FASTCALL fetchTransformed_fetcher(T *buffer,
const QSpanData *data,
939 int y,
int x,
int length)
941 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
942 const QTextureData &image = data->texture;
944 const qreal cx = x + qreal(0.5);
945 const qreal cy = y + qreal(0.5);
947 constexpr bool useFetch = (bpp < QPixelLayout::BPP32) &&
sizeof(T) ==
sizeof(uint);
948 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
950 Q_ASSERT(layout->bpp == bpp || (layout->bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
952 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout->bpp] : Fetch1PixelFunc(fetch1Pixel<bpp>);
954 if (canUseFastMatrixPath(cx, cy, length, data)) {
956 int fdx = (
int)(data->m11 * fixed_scale);
957 int fdy = (
int)(data->m12 * fixed_scale);
959 int fx =
int((data->m21 * cy
960 + data->m11 * cx + data->dx) * fixed_scale);
961 int fy =
int((data->m22 * cy
962 + data->m12 * cx + data->dy) * fixed_scale);
966 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
967 const uchar *src = image.scanLine(py);
970 if (blendType == BlendTransformed) {
971 int fastLen = length;
973 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
975 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
977 for (; i < fastLen; ++i) {
980 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
983 if constexpr (useFetch)
984 buffer[i] = fetch1(src, x1);
986 buffer[i] =
reinterpret_cast<
const T*>(src)[x1];
990 for (; i < fastLen; ++i) {
992 if constexpr (useFetch)
993 buffer[i] = fetch1(src, px);
995 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1000 for (; i < length; ++i) {
1001 int px = (fx >> 16);
1002 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1003 if constexpr (useFetch)
1004 buffer[i] = fetch1(src, px);
1006 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1011 if (blendType == BlendTransformed) {
1012 int fastLen = length;
1014 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
1016 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
1018 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
1020 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
1022 for (; i < fastLen; ++i) {
1023 int x1 = (fx >> 16);
1024 int y1 = (fy >> 16);
1027 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
1028 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1);
1029 if (x1 == x2 && y1 == y2)
1031 if constexpr (useFetch)
1032 buffer[i] = fetch1(image.scanLine(y1), x1);
1034 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(y1))[x1];
1039 for (; i < fastLen; ++i) {
1040 int px = (fx >> 16);
1041 int py = (fy >> 16);
1042 if constexpr (useFetch)
1043 buffer[i] = fetch1(image.scanLine(py), px);
1045 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1051 for (; i < length; ++i) {
1052 int px = (fx >> 16);
1053 int py = (fy >> 16);
1054 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1055 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1056 if constexpr (useFetch)
1057 buffer[i] = fetch1(image.scanLine(py), px);
1059 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1065 const qreal fdx = data->m11;
1066 const qreal fdy = data->m12;
1067 const qreal fdw = data->m13;
1069 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
1070 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
1071 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
1073 T *
const end = buffer + length;
1076 const qreal iw = fw == 0 ? 1 : 1 / fw;
1077 const qreal tx = fx * iw;
1078 const qreal ty = fy * iw;
1079 int px = qFloor(tx);
1080 int py = qFloor(ty);
1082 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1083 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1084 if constexpr (useFetch)
1085 *b = fetch1(image.scanLine(py), px);
1087 *b =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1102static const uint *
QT_FASTCALL fetchTransformed(uint *buffer,
const Operator *,
const QSpanData *data,
1103 int y,
int x,
int length)
1105 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
1106 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1107 fetchTransformed_fetcher<blendType, bpp, uint>(buffer, data, y, x, length);
1108 layout->convertToARGB32PM(buffer, length, data->texture.colorTable);
1112#if QT_CONFIG(raster_64bit)
1113template<TextureBlendType blendType>
1114static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
1115 int y,
int x,
int length)
1117 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1118 if (layout->bpp < QPixelLayout::BPP64) {
1119 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1120 Q_ASSERT(length <= BufferSize);
1121 if (layout->bpp == QPixelLayout::BPP32)
1122 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1124 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1125 return layout->convertToRGBA64PM(buffer, buffer32, length, data->texture.colorTable,
nullptr);
1128 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(
reinterpret_cast<quint64*>(buffer), data, y, x, length);
1129 if (
auto convert = convert64ToRGBA64PM[data->texture.format])
1130 convert(buffer, length);
1135#if QT_CONFIG(raster_fp)
1136template<TextureBlendType blendType>
1137static const QRgbaFloat32 *QT_FASTCALL fetchTransformedFP(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
1138 int y,
int x,
int length)
1140 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1141 if (layout->bpp < QPixelLayout::BPP64) {
1142 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1143 Q_ASSERT(length <= BufferSize);
1144 if (layout->bpp == QPixelLayout::BPP32)
1145 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1147 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1148 qConvertToRGBA32F[data->texture.format](buffer, buffer32, length, data->texture.colorTable,
nullptr);
1149 }
else if (layout->bpp < QPixelLayout::BPP32FPx4) {
1150 Q_DECL_UNINITIALIZED quint64 buffer64[BufferSize];
1151 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(buffer64, data, y, x, length);
1152 convert64ToRGBA32F[data->texture.format](buffer, buffer64, length);
1154 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>(buffer, data, y, x, length);
1155 if (data->texture.format == QImage::Format_RGBA32FPx4)
1156 convertRGBA32FToRGBA32FPM(buffer, length);
1164
1165
1166
1169 uint distxy = distx * disty;
1172 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
1173 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
1174 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
1175 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy));
1176 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy));
1177 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy));
1178 uint brrb = ((br & 0x00ff00ff) * (distxy));
1179 uint brag = (((br & 0xff00ff00) >> 8) * (distxy));
1180 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
1183#if defined(__SSE2__
)
1184#define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \
1185{
1186 const __m128i dxdy = _mm_mullo_epi16 (distx, disty);
1187 const __m128i distx_ = _mm_slli_epi16(distx, 4
);
1188 const __m128i disty_ = _mm_slli_epi16(disty, 4
);
1189 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_)));
1190 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy);
1191 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy);
1193 __m128i tlAG = _mm_srli_epi16(tl, 8
);
1194 __m128i tlRB = _mm_and_si128(tl, colorMask);
1195 __m128i trAG = _mm_srli_epi16(tr, 8
);
1196 __m128i trRB = _mm_and_si128(tr, colorMask);
1197 __m128i blAG = _mm_srli_epi16(bl, 8
);
1198 __m128i blRB = _mm_and_si128(bl, colorMask);
1199 __m128i brAG = _mm_srli_epi16(br, 8
);
1200 __m128i brRB = _mm_and_si128(br, colorMask);
1202 tlAG = _mm_mullo_epi16(tlAG, idxidy);
1203 tlRB = _mm_mullo_epi16(tlRB, idxidy);
1204 trAG = _mm_mullo_epi16(trAG, dxidy);
1205 trRB = _mm_mullo_epi16(trRB, dxidy);
1206 blAG = _mm_mullo_epi16(blAG, idxdy);
1207 blRB = _mm_mullo_epi16(blRB, idxdy);
1208 brAG = _mm_mullo_epi16(brAG, dxdy);
1209 brRB = _mm_mullo_epi16(brRB, dxdy);
1212 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG));
1213 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB));
1214 rAG = _mm_andnot_si128(colorMask, rAG);
1215 rRB = _mm_srli_epi16(rRB, 8
);
1216 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \
1217}
1220#if defined(__ARM_NEON__)
1221#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \
1222{
1223 const int16x8_t dxdy = vmulq_s16(distx, disty);
1224 const int16x8_t distx_ = vshlq_n_s16(distx, 4
);
1225 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_)));
1226 const int16x8_t dxidy = vsubq_s16(distx_, dxdy);
1227 const int16x8_t idxdy = vsubq_s16(disty_, dxdy);
1229 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8
));
1230 int16x8_t tlRB = vandq_s16(tl, colorMask);
1231 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8
));
1232 int16x8_t trRB = vandq_s16(tr, colorMask);
1233 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8
));
1234 int16x8_t blRB = vandq_s16(bl, colorMask);
1235 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8
));
1236 int16x8_t brRB = vandq_s16(br, colorMask);
1238 int16x8_t rAG = vmulq_s16(tlAG, idxidy);
1239 int16x8_t rRB = vmulq_s16(tlRB, idxidy);
1240 rAG = vmlaq_s16(rAG, trAG, dxidy);
1241 rRB = vmlaq_s16(rRB, trRB, dxidy);
1242 rAG = vmlaq_s16(rAG, blAG, idxdy);
1243 rRB = vmlaq_s16(rRB, blRB, idxdy);
1244 rAG = vmlaq_s16(rAG, brAG, dxdy);
1245 rRB = vmlaq_s16(rRB, brRB, dxdy);
1247 rAG = vandq_s16(invColorMask, rAG);
1248 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8
));
1249 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \
1250}
1253#if defined(__loongarch_sx)
1254static inline void interpolate_4_pixels_16_lsx(__m128i tl, __m128i tr, __m128i bl, __m128i br,
1255 __m128i distx, __m128i disty, uint *b)
1257 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1258 const __m128i v_256 = __lsx_vreplgr2vr_h(256);
1259 const __m128i dxdy = __lsx_vmul_h(distx, disty);
1260 const __m128i distx_ = __lsx_vslli_h(distx, 4);
1261 const __m128i disty_ = __lsx_vslli_h(disty, 4);
1262 const __m128i idxidy = __lsx_vadd_h(dxdy, __lsx_vsub_h(v_256, __lsx_vadd_h(distx_, disty_)));
1263 const __m128i dxidy = __lsx_vsub_h(distx_, dxdy);
1264 const __m128i idxdy = __lsx_vsub_h(disty_,dxdy);
1266 __m128i tlAG = __lsx_vsrli_h(tl, 8);
1267 __m128i tlRB = __lsx_vand_v(tl, colorMask);
1268 __m128i trAG = __lsx_vsrli_h(tr, 8);
1269 __m128i trRB = __lsx_vand_v(tr, colorMask);
1270 __m128i blAG = __lsx_vsrli_h(bl, 8);
1271 __m128i blRB = __lsx_vand_v(bl, colorMask);
1272 __m128i brAG = __lsx_vsrli_h(br, 8);
1273 __m128i brRB = __lsx_vand_v(br, colorMask);
1275 tlAG = __lsx_vmul_h(tlAG, idxidy);
1276 tlRB = __lsx_vmul_h(tlRB, idxidy);
1277 trAG = __lsx_vmul_h(trAG, dxidy);
1278 trRB = __lsx_vmul_h(trRB, dxidy);
1279 blAG = __lsx_vmul_h(blAG, idxdy);
1280 blRB = __lsx_vmul_h(blRB, idxdy);
1281 brAG = __lsx_vmul_h(brAG, dxdy);
1282 brRB = __lsx_vmul_h(brRB, dxdy);
1284 __m128i rAG =__lsx_vadd_h(__lsx_vadd_h(tlAG, trAG), __lsx_vadd_h(blAG, brAG));
1285 __m128i rRB =__lsx_vadd_h(__lsx_vadd_h(tlRB, trRB), __lsx_vadd_h(blRB, brRB));
1286 rAG = __lsx_vandn_v(colorMask, rAG);
1287 rRB = __lsx_vsrli_h(rRB, 8);
1288 __lsx_vst(__lsx_vor_v(rAG, rRB), b, 0);
1304 Q_ASSERT(v1 >= 0 && v1 < max);
1305 Q_ASSERT(v2 >= 0 && v2 < max);
1317 Q_ASSERT(v1 >= l1 && v1 <= l2);
1318 Q_ASSERT(v2 >= l1 && v2 <= l2);
1332static void QT_FASTCALL intermediate_adder(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx)
1334#if defined(QT_COMPILER_SUPPORTS_AVX2)
1335 extern void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx);
1336 if (qCpuHasFeature(ArchHaswell))
1337 return intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
1341 fx -= offset * fixed_scale;
1344 const int x = (fx >> 16);
1346 const uint distx = (fx & 0x0000ffff) >> 8;
1347 const uint idistx = 256 - distx;
1348 const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
1349 const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
1350 *b = (rb >> 8) | ag;
1354 fx += offset * fixed_scale;
1360static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
1361 int &fx,
int &fy,
int fdx,
int )
1363 int y1 = (fy >> 16);
1365 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1366 const uint *s1 = (
const uint *)image.scanLine(y1);
1367 const uint *s2 = (
const uint *)image.scanLine(y2);
1369 const int disty = (fy & 0x0000ffff) >> 8;
1370 const int idisty = 256 - disty;
1371 const int length = end - b;
1374 const int adjust = (fdx < 0) ? fdx * length : 0;
1375 const int offset = (fx + adjust) >> 16;
1378 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
1380 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
1383 Q_ASSERT(count <= BufferSize + 2);
1386 if (blendType == BlendTransformedBilinearTiled) {
1388 if (x < 0) x += image.width;
1390 lim = qMin(count, image.x2 - x);
1392 Q_ASSERT(x < image.x2);
1393 uint t = s1[image.x1];
1394 uint b = s2[image.x1];
1395 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1396 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1398 intermediate.buffer_rb[f] = rb;
1399 intermediate.buffer_ag[f] = ag;
1402 }
while (x < image.x1 && f < lim);
1406 if (blendType != BlendTransformedBilinearTiled) {
1407#if defined(__SSE2__
)
1408 const __m128i disty_ = _mm_set1_epi16(disty);
1409 const __m128i idisty_ = _mm_set1_epi16(idisty);
1410 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1413 for (; f < lim; x += 4, f += 4) {
1415 __m128i top = _mm_loadu_si128((
const __m128i*)((
const uint *)(s1)+x));
1416 __m128i topAG = _mm_srli_epi16(top, 8);
1417 __m128i topRB = _mm_and_si128(top, colorMask);
1419 topAG = _mm_mullo_epi16 (topAG, idisty_);
1420 topRB = _mm_mullo_epi16 (topRB, idisty_);
1423 __m128i bottom = _mm_loadu_si128((
const __m128i*)((
const uint *)(s2)+x));
1424 __m128i bottomAG = _mm_srli_epi16(bottom, 8);
1425 __m128i bottomRB = _mm_and_si128(bottom, colorMask);
1426 bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
1427 bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
1430 __m128i rAG =_mm_add_epi16(topAG, bottomAG);
1431 rAG = _mm_srli_epi16(rAG, 8);
1432 _mm_storeu_si128((__m128i*)(&intermediate.buffer_ag[f]), rAG);
1433 __m128i rRB =_mm_add_epi16(topRB, bottomRB);
1434 rRB = _mm_srli_epi16(rRB, 8);
1435 _mm_storeu_si128((__m128i*)(&intermediate.buffer_rb[f]), rRB);
1437#elif defined(__ARM_NEON__)
1438 const int16x8_t disty_ = vdupq_n_s16(disty);
1439 const int16x8_t idisty_ = vdupq_n_s16(idisty);
1440 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1443 for (; f < lim; x += 4, f += 4) {
1445 int16x8_t top = vld1q_s16((int16_t*)((
const uint *)(s1)+x));
1446 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8));
1447 int16x8_t topRB = vandq_s16(top, colorMask);
1449 topAG = vmulq_s16(topAG, idisty_);
1450 topRB = vmulq_s16(topRB, idisty_);
1453 int16x8_t bottom = vld1q_s16((int16_t*)((
const uint *)(s2)+x));
1454 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8));
1455 int16x8_t bottomRB = vandq_s16(bottom, colorMask);
1456 bottomAG = vmulq_s16(bottomAG, disty_);
1457 bottomRB = vmulq_s16(bottomRB, disty_);
1460 int16x8_t rAG = vaddq_s16(topAG, bottomAG);
1461 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
1462 vst1q_s16((int16_t*)(&intermediate.buffer_ag[f]), rAG);
1463 int16x8_t rRB = vaddq_s16(topRB, bottomRB);
1464 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
1465 vst1q_s16((int16_t*)(&intermediate.buffer_rb[f]), rRB);
1467#elif defined(__loongarch_sx)
1468 const __m128i disty_ = __lsx_vreplgr2vr_h(disty);
1469 const __m128i idisty_ = __lsx_vreplgr2vr_h(idisty);
1470 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1473 for (; f < lim; x += 4, f += 4) {
1475 __m128i top = __lsx_vld((
const __m128i*)((
const uint *)(s1)+x), 0);
1476 __m128i topAG = __lsx_vsrli_h(top, 8);
1477 __m128i topRB = __lsx_vand_v(top, colorMask);
1479 topAG = __lsx_vmul_h(topAG, idisty_);
1480 topRB = __lsx_vmul_h(topRB, idisty_);
1483 __m128i bottom = __lsx_vld((
const __m128i*)((
const uint *)(s2)+x), 0);
1484 __m128i bottomAG = __lsx_vsrli_h(bottom, 8);
1485 __m128i bottomRB = __lsx_vand_v(bottom, colorMask);
1486 bottomAG = __lsx_vmul_h(bottomAG, disty_);
1487 bottomRB = __lsx_vmul_h(bottomRB, disty_);
1490 __m128i rAG = __lsx_vadd_h(topAG, bottomAG);
1491 rAG = __lsx_vsrli_h(rAG, 8);
1492 __lsx_vst(rAG, (__m128i*)(&intermediate.buffer_ag[f]), 0);
1493 __m128i rRB = __lsx_vadd_h(topRB, bottomRB);
1494 rRB = __lsx_vsrli_h(rRB, 8);
1495 __lsx_vst(rRB, (__m128i*)(&intermediate.buffer_rb[f]), 0);
1499 for (; f < count; f++) {
1500 if (blendType == BlendTransformedBilinearTiled) {
1501 if (x >= image.width) x -= image.width;
1503 x = qMin(x, image.x2 - 1);
1509 intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1510 intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1515 intermediate_adder(b, end, intermediate, offset, fx, fdx);
1519static void QT_FASTCALL fetchTransformedBilinearARGB32PM_upscale_helper(uint *b, uint *end,
const QTextureData &image,
1520 int &fx,
int &fy,
int fdx,
int )
1522 int y1 = (fy >> 16);
1524 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1525 const uint *s1 = (
const uint *)image.scanLine(y1);
1526 const uint *s2 = (
const uint *)image.scanLine(y2);
1527 const int disty = (fy & 0x0000ffff) >> 8;
1529 if (blendType != BlendTransformedBilinearTiled) {
1530 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1531 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1533 int x1 = (fx >> 16);
1535 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1540 *b = INTERPOLATE_PIXEL_256(top, 256 - disty, bot, disty);
1544 uint *boundedEnd = end;
1546 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1548 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1551 while (b < boundedEnd) {
1553 int distx = (fx & 0x0000ffff) >> 8;
1554 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
1561 int x1 = (fx >> 16);
1563 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1 , x1, x2);
1568 int distx = (fx & 0x0000ffff) >> 8;
1569 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1577static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *b, uint *end,
const QTextureData &image,
1578 int &fx,
int &fy,
int fdx,
int )
1580 int y1 = (fy >> 16);
1582 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1583 const uint *s1 = (
const uint *)image.scanLine(y1);
1584 const uint *s2 = (
const uint *)image.scanLine(y2);
1585 const int disty8 = (fy & 0x0000ffff) >> 8;
1586 const int disty4 = (disty8 + 0x08) >> 4;
1588 if (blendType != BlendTransformedBilinearTiled) {
1589 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1590 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1592 int x1 = (fx >> 16);
1594 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1599 *b = INTERPOLATE_PIXEL_256(top, 256 - disty8, bot, disty8);
1603 uint *boundedEnd = end;
1605 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1607 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1609#if defined(__SSE2__
)
1610 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1611 const __m128i v_256 = _mm_set1_epi16(256);
1612 const __m128i v_disty = _mm_set1_epi16(disty4);
1613 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1614 const __m128i v_fx_r = _mm_set1_epi32(0x8);
1615 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1617 while (b < boundedEnd - 3) {
1618 __m128i offset = _mm_srli_epi32(v_fx, 16);
1619 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1620 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1621 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1622 const int offset3 = _mm_cvtsi128_si32(offset);
1623 const __m128i tl = _mm_setr_epi32(s1[offset0], s1[offset1], s1[offset2], s1[offset3]);
1624 const __m128i tr = _mm_setr_epi32(s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]);
1625 const __m128i bl = _mm_setr_epi32(s2[offset0], s2[offset1], s2[offset2], s2[offset3]);
1626 const __m128i br = _mm_setr_epi32(s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]);
1628 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1629 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fx_r), 4);
1630 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1631 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1633 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1635 v_fx = _mm_add_epi32(v_fx, v_fdx);
1637 fx = _mm_cvtsi128_si32(v_fx);
1638#elif defined(__ARM_NEON__)
1639 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1640 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1641 const int16x8_t v_256 = vdupq_n_s16(256);
1642 const int16x8_t v_disty = vdupq_n_s16(disty4);
1643 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
1644 int32x4_t v_fdx = vdupq_n_s32(fdx*4);
1646 int32x4_t v_fx = vmovq_n_s32(fx);
1647 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1648 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1649 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1651 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1652 const int32x4_t v_fx_r = vdupq_n_s32(0x0800);
1655 uint32x4x2_t v_top = {};
1656 uint32x4x2_t v_bot = {};
1657 while (b < boundedEnd - 3) {
1658 int x1 = (fx >> 16);
1660 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1661 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1664 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1665 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1668 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1669 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1672 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1673 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1675 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_fx_r), 12);
1676 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1678 interpolate_4_pixels_16_neon(
1679 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1680 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1681 vreinterpretq_s16_s32(v_distx), v_disty, v_disty_,
1682 colorMask, invColorMask, v_256, b);
1684 v_fx = vaddq_s32(v_fx, v_fdx);
1686#elif defined (__loongarch_sx)
1687 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1688 const __m128i v_disty = __lsx_vreplgr2vr_h(disty4);
1689 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1690 const __m128i v_fx_r = __lsx_vreplgr2vr_w(0x8);
1691 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1693 while (b < boundedEnd - 3) {
1694 __m128i offset = __lsx_vsrli_w(v_fx, 16);
1695 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1696 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1697 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1698 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1699 const __m128i tl = (__m128i)(v4u32){s1[offset0], s1[offset1], s1[offset2], s1[offset3]};
1700 const __m128i tr = (__m128i)(v4u32){s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]};
1701 const __m128i bl = (__m128i)(v4u32){s2[offset0], s2[offset1], s2[offset2], s2[offset3]};
1702 const __m128i br = (__m128i)(v4u32){s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]};
1704 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1705 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fx_r), 4);
1706 v_distx = __lsx_vshuf_h(shuffleMask, v_distx, v_distx);
1708 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1710 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1712 fx = __lsx_vpickve2gr_w(v_fx, 0);
1714 while (b < boundedEnd) {
1716 if (hasFastInterpolate4()) {
1717 int distx8 = (fx & 0x0000ffff) >> 8;
1718 *b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
1720 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1721 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx4, disty4);
1729 int x1 = (fx >> 16);
1731 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1736 if (hasFastInterpolate4()) {
1737 int distx8 = (fx & 0x0000ffff) >> 8;
1738 *b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
1740 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1741 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
1749static void QT_FASTCALL fetchTransformedBilinearARGB32PM_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1750 int &fx,
int &fy,
int fdx,
int fdy)
1754 int x1 = (fx >> 16);
1756 int y1 = (fy >> 16);
1759 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1760 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1762 const uint *s1 = (
const uint *)image.scanLine(y1);
1763 const uint *s2 = (
const uint *)image.scanLine(y2);
1770 int distx = (fx & 0x0000ffff) >> 8;
1771 int disty = (fy & 0x0000ffff) >> 8;
1773 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1782static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1783 int &fx,
int &fy,
int fdx,
int fdy)
1786 if (blendType != BlendTransformedBilinearTiled) {
1787 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1788 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1789 const qint64 min_fy = qint64(image.y1) * fixed_scale;
1790 const qint64 max_fy = qint64(image.y2 - 1) * fixed_scale;
1793 int x1 = (fx >> 16);
1795 int y1 = (fy >> 16);
1797 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1798 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1799 if (x1 != x2 && y1 != y2)
1801 const uint *s1 = (
const uint *)image.scanLine(y1);
1802 const uint *s2 = (
const uint *)image.scanLine(y2);
1807 if (hasFastInterpolate4()) {
1808 int distx = (fx & 0x0000ffff) >> 8;
1809 int disty = (fy & 0x0000ffff) >> 8;
1810 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1812 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
1813 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
1814 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
1820 uint *boundedEnd = end;
1822 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1824 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1826 boundedEnd = qMin(boundedEnd, b + (max_fy - fy) / fdy);
1828 boundedEnd = qMin(boundedEnd, b + (min_fy - fy) / fdy);
1831#if defined(__SSE2__
)
1832 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1833 const __m128i v_256 = _mm_set1_epi16(256);
1834 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1835 const __m128i v_fdy = _mm_set1_epi32(fdy*4);
1836 const __m128i v_fxy_r = _mm_set1_epi32(0x8);
1837 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1838 __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
1840 const uchar *textureData = image.imageData;
1841 const qsizetype bytesPerLine = image.bytesPerLine;
1842 const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
1844 while (b < boundedEnd - 3) {
1845 const __m128i vy = _mm_packs_epi32(_mm_srli_epi32(v_fy, 16), _mm_setzero_si128());
1847 __m128i offset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epi16(vy, vbpl));
1848 offset = _mm_add_epi32(offset, _mm_srli_epi32(v_fx, 16));
1849 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1850 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1851 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1852 const int offset3 = _mm_cvtsi128_si32(offset);
1853 const uint *topData = (
const uint *)(textureData);
1854 const __m128i tl = _mm_setr_epi32(topData[offset0], topData[offset1], topData[offset2], topData[offset3]);
1855 const __m128i tr = _mm_setr_epi32(topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]);
1856 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1857 const __m128i bl = _mm_setr_epi32(bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]);
1858 const __m128i br = _mm_setr_epi32(bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]);
1860 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1861 __m128i v_disty = _mm_srli_epi16(v_fy, 8);
1862 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fxy_r), 4);
1863 v_disty = _mm_srli_epi16(_mm_add_epi32(v_disty, v_fxy_r), 4);
1864 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1865 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1866 v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1867 v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1869 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1871 v_fx = _mm_add_epi32(v_fx, v_fdx);
1872 v_fy = _mm_add_epi32(v_fy, v_fdy);
1874 fx = _mm_cvtsi128_si32(v_fx);
1875 fy = _mm_cvtsi128_si32(v_fy);
1876#elif defined(__ARM_NEON__)
1877 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1878 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1879 const int16x8_t v_256 = vdupq_n_s16(256);
1880 int32x4_t v_fdx = vdupq_n_s32(fdx * 4);
1881 int32x4_t v_fdy = vdupq_n_s32(fdy * 4);
1883 const uchar *textureData = image.imageData;
1884 const qsizetype bytesPerLine = image.bytesPerLine;
1886 int32x4_t v_fx = vmovq_n_s32(fx);
1887 int32x4_t v_fy = vmovq_n_s32(fy);
1888 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1889 v_fy = vsetq_lane_s32(fy + fdy, v_fy, 1);
1890 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1891 v_fy = vsetq_lane_s32(fy + fdy * 2, v_fy, 2);
1892 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1893 v_fy = vsetq_lane_s32(fy + fdy * 3, v_fy, 3);
1895 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1896 const int32x4_t v_round = vdupq_n_s32(0x0800);
1899 uint32x4x2_t v_top = {};
1900 uint32x4x2_t v_bot = {};
1901 while (b < boundedEnd - 3) {
1902 int x1 = (fx >> 16);
1903 int y1 = (fy >> 16);
1904 fx += fdx; fy += fdy;
1905 const uchar *sl = textureData + bytesPerLine * y1;
1906 const uint *s1 =
reinterpret_cast<
const uint *>(sl);
1907 const uint *s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1908 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1909 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1912 fx += fdx; fy += fdy;
1913 sl = textureData + bytesPerLine * y1;
1914 s1 =
reinterpret_cast<
const uint *>(sl);
1915 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1916 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1917 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1920 fx += fdx; fy += fdy;
1921 sl = textureData + bytesPerLine * y1;
1922 s1 =
reinterpret_cast<
const uint *>(sl);
1923 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1924 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1925 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1928 fx += fdx; fy += fdy;
1929 sl = textureData + bytesPerLine * y1;
1930 s1 =
reinterpret_cast<
const uint *>(sl);
1931 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1932 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1933 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1935 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_round), 12);
1936 int32x4_t v_disty = vshrq_n_s32(vaddq_s32(vandq_s32(v_fy, v_ffff_mask), v_round), 12);
1937 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1938 v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
1939 int16x8_t v_disty_ = vshlq_n_s16(vreinterpretq_s16_s32(v_disty), 4);
1941 interpolate_4_pixels_16_neon(
1942 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1943 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1944 vreinterpretq_s16_s32(v_distx), vreinterpretq_s16_s32(v_disty),
1945 v_disty_, colorMask, invColorMask, v_256, b);
1947 v_fx = vaddq_s32(v_fx, v_fdx);
1948 v_fy = vaddq_s32(v_fy, v_fdy);
1950#elif defined(__loongarch_sx)
1951 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1952 const __m128i v_fdy = __lsx_vreplgr2vr_w(fdy*4);
1953 const __m128i v_fxy_r = __lsx_vreplgr2vr_w(0x8);
1954 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1955 __m128i v_fy = (__m128i)(v4i32){fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy};
1957 const uchar *textureData = image.imageData;
1958 const qsizetype bytesPerLine = image.bytesPerLine;
1959 const __m128i zero = __lsx_vldi(0);
1960 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
1961 const __m128i shuffleMask1 = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1962 const __m128i vbpl = __lsx_vshuf_h(shuffleMask, zero, __lsx_vinsgr2vr_w(zero, bytesPerLine/4, 0));
1964 while (b < boundedEnd - 3) {
1965 const __m128i vy = __lsx_vpickev_h(zero, __lsx_vsat_w(__lsx_vsrli_w(v_fy, 16), 15));
1967 __m128i offset = __lsx_vilvl_h(__lsx_vmuh_h(vy, vbpl), __lsx_vmul_h(vy, vbpl));
1968 offset = __lsx_vadd_w(offset, __lsx_vsrli_w(v_fx, 16));
1969 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1970 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1971 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1972 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1973 const uint *topData = (
const uint *)(textureData);
1974 const __m128i tl = (__m128i)(v4u32){topData[offset0], topData[offset1], topData[offset2], topData[offset3]};
1975 const __m128i tr = (__m128i)(v4u32){topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]};
1976 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1977 const __m128i bl = (__m128i)(v4u32){bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]};
1978 const __m128i br = (__m128i)(v4u32){bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]};
1980 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1981 __m128i v_disty = __lsx_vsrli_h(v_fy, 8);
1982 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fxy_r), 4);
1983 v_disty = __lsx_vsrli_h(__lsx_vadd_w(v_disty, v_fxy_r), 4);
1984 v_distx = __lsx_vshuf_h(shuffleMask1, zero, v_distx);
1985 v_disty = __lsx_vshuf_h(shuffleMask1, zero, v_disty);
1987 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1989 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1990 v_fy = __lsx_vadd_w(v_fy, v_fdy);
1992 fx = __lsx_vpickve2gr_w(v_fx, 0);
1993 fy = __lsx_vpickve2gr_w(v_fy, 0);
1995 while (b < boundedEnd) {
1999 const uint *s1 = (
const uint *)image.scanLine(y);
2000 const uint *s2 = (
const uint *)image.scanLine(y + 1);
2002 if (hasFastInterpolate4()) {
2003 int distx = (fx & 0x0000ffff) >> 8;
2004 int disty = (fy & 0x0000ffff) >> 8;
2005 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
2007 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2008 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2009 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx, disty);
2019 int x1 = (fx >> 16);
2021 int y1 = (fy >> 16);
2024 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2025 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2027 const uint *s1 = (
const uint *)image.scanLine(y1);
2028 const uint *s2 = (
const uint *)image.scanLine(y2);
2035 if (hasFastInterpolate4()) {
2036 int distx = (fx & 0x0000ffff) >> 8;
2037 int disty = (fy & 0x0000ffff) >> 8;
2038 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2040 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2041 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2042 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2054 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinear>,
2055 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinear>,
2056 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinear>,
2057 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinear>,
2058 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinear>
2061 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinearTiled>,
2062 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinearTiled>,
2063 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinearTiled>,
2064 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinearTiled>,
2065 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinearTiled>
2070static const uint *
QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer,
const Operator *,
2071 const QSpanData *data,
int y,
int x,
2074 const qreal cx = x + qreal(0.5);
2075 const qreal cy = y + qreal(0.5);
2076 constexpr int tiled = (blendType == BlendTransformedBilinearTiled) ? 1 : 0;
2078 uint *end = buffer + length;
2080 if (canUseFastMatrixPath(cx, cy, length, data)) {
2082 int fdx = (
int)(data->m11 * fixed_scale);
2083 int fdy = (
int)(data->m12 * fixed_scale);
2085 int fx =
int((data->m21 * cy
2086 + data->m11 * cx + data->dx) * fixed_scale);
2087 int fy =
int((data->m22 * cy
2088 + data->m12 * cx + data->dy) * fixed_scale);
2094 if (qAbs(fdx) <= fixed_scale) {
2096 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2097 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2099 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2100 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2102 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2103 }
else if (qAbs(data->m22) < qreal(1./8.)) {
2105 bilinearFastTransformHelperARGB32PM[tiled][UpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2108 bilinearFastTransformHelperARGB32PM[tiled][DownscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2111 if (qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.) ) {
2113 bilinearFastTransformHelperARGB32PM[tiled][RotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2116 bilinearFastTransformHelperARGB32PM[tiled][FastRotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2120 const QTextureData &image = data->texture;
2122 const qreal fdx = data->m11;
2123 const qreal fdy = data->m12;
2124 const qreal fdw = data->m13;
2126 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2127 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2128 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2131 const qreal iw = fw == 0 ? 1 : 1 / fw;
2132 const qreal px = fx * iw - qreal(0.5);
2133 const qreal py = fy * iw - qreal(0.5);
2135 int x1 =
int(px) - (px < 0);
2137 int y1 =
int(py) - (py < 0);
2140 int distx =
int((px - x1) * 256);
2141 int disty =
int((py - y1) * 256);
2143 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2144 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2146 const uint *s1 = (
const uint *)data->texture.scanLine(y1);
2147 const uint *s2 = (
const uint *)data->texture.scanLine(y2);
2154 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2171static void QT_FASTCALL fetchTransformedBilinear_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
2172 int &fx,
int &fy,
int fdx,
int )
2174 const QPixelLayout *layout = &qPixelLayouts[image.format];
2175 const QList<QRgb> *clut = image.colorTable;
2176 const FetchAndConvertPixelsFunc fetch = layout->fetchToARGB32PM;
2178 int y1 = (fy >> 16);
2180 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2181 const uchar *s1 = image.scanLine(y1);
2182 const uchar *s2 = image.scanLine(y2);
2184 const int disty = (fy & 0x0000ffff) >> 8;
2185 const int idisty = 256 - disty;
2186 const int length = end - b;
2189 const int adjust = (fdx < 0) ? fdx * length : 0;
2190 const int offset = (fx + adjust) >> 16;
2193 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
2194 uint *buf1 = intermediate.buffer_rb;
2195 uint *buf2 = intermediate.buffer_ag;
2199 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
2200 Q_ASSERT(count <= BufferSize + 2);
2202 if (blendType == BlendTransformedBilinearTiled) {
2206 int len1 = qMin(count, image.width - x);
2207 int len2 = qMin(x, count - len1);
2209 ptr1 = fetch(buf1, s1, x, len1, clut,
nullptr);
2210 ptr2 = fetch(buf2, s2, x, len1, clut,
nullptr);
2211 for (
int i = 0; i < len1; ++i) {
2214 buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2215 buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2219 ptr1 = fetch(buf1 + len1, s1, 0, len2, clut,
nullptr);
2220 ptr2 = fetch(buf2 + len1, s2, 0, len2, clut,
nullptr);
2221 for (
int i = 0; i < len2; ++i) {
2224 buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2225 buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2229 for (
int i = image.width; i < count; ++i) {
2230 buf1[i] = buf1[i - image.width];
2231 buf2[i] = buf2[i - image.width];
2234 int start = qMax(x, image.x1);
2235 int end = qMin(x + count, image.x2);
2236 int len = qMax(1, end - start);
2237 int leading = start - x;
2239 ptr1 = fetch(buf1 + leading, s1, start, len, clut,
nullptr);
2240 ptr2 = fetch(buf2 + leading, s2, start, len, clut,
nullptr);
2242 for (
int i = 0; i < len; ++i) {
2245 buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2246 buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2249 for (
int i = 0; i < leading; ++i) {
2250 buf1[i] = buf1[leading];
2251 buf2[i] = buf2[leading];
2253 for (
int i = leading + len; i < count; ++i) {
2254 buf1[i] = buf1[i - 1];
2255 buf2[i] = buf2[i - 1];
2260 intermediate_adder(b, end, intermediate, offset, fx, fdx);
2265static void QT_FASTCALL fetchTransformedBilinear_fetcher(T *buf1, T *buf2,
const int len,
const QTextureData &image,
2266 int fx,
int fy,
const int fdx,
const int fdy)
2268 const QPixelLayout &layout = qPixelLayouts[image.format];
2269 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2271 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2273 Q_ASSERT(layout.bpp == bpp || (layout.bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
2274 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2276 int y1 = (fy >> 16);
2278 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2279 const uchar *s1 = image.scanLine(y1);
2280 const uchar *s2 = image.scanLine(y2);
2283 if (blendType == BlendTransformedBilinear) {
2284 for (; i < len; ++i) {
2285 int x1 = (fx >> 16);
2287 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2290 if constexpr (useFetch) {
2291 buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
2292 buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
2294 buf1[i * 2 + 0] = buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x1];
2295 buf2[i * 2 + 0] = buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x1];
2301 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2303 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2305 for (; i < fastLen; ++i) {
2307 if constexpr (useFetch) {
2308 buf1[i * 2 + 0] = fetch1(s1, x);
2309 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2310 buf2[i * 2 + 0] = fetch1(s2, x);
2311 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2313 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2314 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2315 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2316 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2322 for (; i < len; ++i) {
2323 int x1 = (fx >> 16);
2325 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2326 if constexpr (useFetch) {
2327 buf1[i * 2 + 0] = fetch1(s1, x1);
2328 buf1[i * 2 + 1] = fetch1(s1, x2);
2329 buf2[i * 2 + 0] = fetch1(s2, x1);
2330 buf2[i * 2 + 1] = fetch1(s2, x2);
2332 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2333 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2334 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2335 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2341 if (blendType == BlendTransformedBilinear) {
2342 for (; i < len; ++i) {
2343 int x1 = (fx >> 16);
2345 int y1 = (fy >> 16);
2347 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2348 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2349 if (x1 != x2 && y1 != y2)
2351 const uchar *s1 = image.scanLine(y1);
2352 const uchar *s2 = image.scanLine(y2);
2353 if constexpr (useFetch) {
2354 buf1[i * 2 + 0] = fetch1(s1, x1);
2355 buf1[i * 2 + 1] = fetch1(s1, x2);
2356 buf2[i * 2 + 0] = fetch1(s2, x1);
2357 buf2[i * 2 + 1] = fetch1(s2, x2);
2359 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2360 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2361 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2362 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2369 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2371 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2373 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
2375 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
2377 for (; i < fastLen; ++i) {
2380 const uchar *s1 = image.scanLine(y);
2381 const uchar *s2 = s1 + image.bytesPerLine;
2382 if constexpr (useFetch) {
2383 buf1[i * 2 + 0] = fetch1(s1, x);
2384 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2385 buf2[i * 2 + 0] = fetch1(s2, x);
2386 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2388 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2389 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2390 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2391 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2398 for (; i < len; ++i) {
2399 int x1 = (fx >> 16);
2401 int y1 = (fy >> 16);
2403 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2404 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2406 const uchar *s1 = image.scanLine(y1);
2407 const uchar *s2 = image.scanLine(y2);
2408 if constexpr (useFetch) {
2409 buf1[i * 2 + 0] = fetch1(s1, x1);
2410 buf1[i * 2 + 1] = fetch1(s1, x2);
2411 buf2[i * 2 + 0] = fetch1(s2, x1);
2412 buf2[i * 2 + 1] = fetch1(s2, x2);
2414 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2415 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2416 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2417 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2426static void QT_FASTCALL fetchTransformedBilinear_slow_fetcher(T *buf1, T *buf2, ushort *distxs, ushort *distys,
2427 const int len,
const QTextureData &image,
2428 qreal &fx, qreal &fy, qreal &fw,
2429 const qreal fdx,
const qreal fdy,
const qreal fdw)
2431 const QPixelLayout &layout = qPixelLayouts[image.format];
2432 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2434 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2436 Q_ASSERT(layout.bpp == bpp);
2438 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2440 for (
int i = 0; i < len; ++i) {
2441 const qreal iw = fw == 0 ? 16384 : 1 / fw;
2442 const qreal px = fx * iw - qreal(0.5);
2443 const qreal py = fy * iw - qreal(0.5);
2445 int x1 = qFloor(px);
2447 int y1 = qFloor(py);
2450 distxs[i] = ushort((px - x1) * (1<<16));
2451 distys[i] = ushort((py - y1) * (1<<16));
2453 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2454 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2456 const uchar *s1 = image.scanLine(y1);
2457 const uchar *s2 = image.scanLine(y2);
2458 if constexpr (useFetch) {
2459 buf1[i * 2 + 0] = fetch1(s1, x1);
2460 buf1[i * 2 + 1] = fetch1(s1, x2);
2461 buf2[i * 2 + 0] = fetch1(s2, x1);
2462 buf2[i * 2 + 1] = fetch1(s2, x2);
2464 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2465 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2466 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2467 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2479 const QSpanData *data,
int y,
int x,
int length)
2481 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2482 const QList<QRgb> *clut = data->texture.colorTable;
2483 Q_ASSERT(bpp == QPixelLayout::BPPNone || layout->bpp == bpp);
2485 const qreal cx = x + qreal(0.5);
2486 const qreal cy = y + qreal(0.5);
2488 if (canUseFastMatrixPath(cx, cy, length, data)) {
2490 int fdx = (
int)(data->m11 * fixed_scale);
2491 int fdy = (
int)(data->m12 * fixed_scale);
2493 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2494 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2500 if (qAbs(fdx) <= fixed_scale) {
2501 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
2502 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2503 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2504 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2506 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2508 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2510 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2511 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2514 int len = qMin(length, BufferSize / 2);
2515 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
2516 layout->convertToARGB32PM(buf1, len * 2, clut);
2517 layout->convertToARGB32PM(buf2, len * 2, clut);
2519 if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) {
2520 int disty = (fy & 0x0000ffff) >> 8;
2521 for (
int i = 0; i < len; ++i) {
2522 int distx = (fx & 0x0000ffff) >> 8;
2523 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2527 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2528 for (
int i = 0; i < len; ++i) {
2529 uint tl = buf1[i * 2 + 0];
2530 uint tr = buf1[i * 2 + 1];
2531 uint bl = buf2[i * 2 + 0];
2532 uint br = buf2[i * 2 + 1];
2533 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2534 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2543 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2545 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2546 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2549 int len = qMin(length, BufferSize / 2);
2550 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2551 layout->convertToARGB32PM(buf1, len * 2, clut);
2552 layout->convertToARGB32PM(buf2, len * 2, clut);
2554 if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
2556 for (
int i = 0; i < len; ++i) {
2557 int distx = (fx & 0x0000ffff) >> 8;
2558 int disty = (fy & 0x0000ffff) >> 8;
2560 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2566 for (
int i = 0; i < len; ++i) {
2567 uint tl = buf1[i * 2 + 0];
2568 uint tr = buf1[i * 2 + 1];
2569 uint bl = buf2[i * 2 + 0];
2570 uint br = buf2[i * 2 + 1];
2572 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2573 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2575 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2586 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType,bpp,uint>;
2588 const qreal fdx = data->m11;
2589 const qreal fdy = data->m12;
2590 const qreal fdw = data->m13;
2592 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2593 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2594 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2596 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2597 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2600 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2601 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2604 const int len = qMin(length, BufferSize / 2);
2605 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2607 layout->convertToARGB32PM(buf1, len * 2, clut);
2608 layout->convertToARGB32PM(buf2, len * 2, clut);
2610 for (
int i = 0; i < len; ++i) {
2611 const int distx = distxs[i] >> 8;
2612 const int disty = distys[i] >> 8;
2614 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2624#if QT_CONFIG(raster_64bit)
2625template<TextureBlendType blendType>
2626static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer,
const QSpanData *data,
2627 int y,
int x,
int length)
2629 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2630 const auto *clut = data->texture.colorTable;
2631 const auto convert = layout->convertToRGBA64PM;
2633 const qreal cx = x + qreal(0.5);
2634 const qreal cy = y + qreal(0.5);
2636 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
2637 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
2638 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2639 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2640 QRgba64 *b = buffer;
2642 if (canUseFastMatrixPath(cx, cy, length, data)) {
2644 const int fdx = (
int)(data->m11 * fixed_scale);
2645 const int fdy = (
int)(data->m12 * fixed_scale);
2647 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2648 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2653 const auto fetcher =
2654 (layout->bpp == QPixelLayout::BPP32)
2655 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
2656 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2660 const int len = qMin(length, BufferSize / 2);
2661 const int disty = (fy & 0x0000ffff);
2662#if defined(__SSE2__)
2663 const __m128i vdy = _mm_set1_epi16(disty);
2664 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2666 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2668 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2670 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2672 for (
int i = 0; i < len; ++i) {
2673 const int distx = (fx & 0x0000ffff);
2674#if defined(__SSE2__)
2675 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2677 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2678 vt = _mm_mulhi_epu16(vt, vidy);
2679 vb = _mm_mulhi_epu16(vb, vdy);
2680 vt = _mm_add_epi16(vt, vb);
2683 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2684 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2685 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2686 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2688 _mm_storel_epi64((__m128i*)(b+i), vt);
2690 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2699 const int len = qMin(length, BufferSize / 2);
2701 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2703 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2704 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2706 for (
int i = 0; i < len; ++i) {
2707 const int distx = (fx & 0x0000ffff);
2708 const int disty = (fy & 0x0000ffff);
2709 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2719 const auto fetcher =
2720 (layout->bpp == QPixelLayout::BPP32)
2721 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
2722 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2724 const qreal fdx = data->m11;
2725 const qreal fdy = data->m12;
2726 const qreal fdw = data->m13;
2728 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2729 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2730 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2732 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2733 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2736 const int len = qMin(length, BufferSize / 2);
2737 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2739 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2740 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2742 for (
int i = 0; i < len; ++i) {
2743 const int distx = distxs[i];
2744 const int disty = distys[i];
2745 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2755template<TextureBlendType blendType>
2756static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buffer,
const QSpanData *data,
2757 int y,
int x,
int length)
2759 const auto convert = convert64ToRGBA64PM[data->texture.format];
2761 const qreal cx = x + qreal(0.5);
2762 const qreal cy = y + qreal(0.5);
2764 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2765 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2766 QRgba64 *end = buffer + length;
2767 QRgba64 *b = buffer;
2769 if (canUseFastMatrixPath(cx, cy, length, data)) {
2771 const int fdx = (
int)(data->m11 * fixed_scale);
2772 const int fdy = (
int)(data->m12 * fixed_scale);
2774 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2775 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2779 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2783 int len = qMin(length, BufferSize / 2);
2784 int disty = (fy & 0x0000ffff);
2785#if defined(__SSE2__)
2786 const __m128i vdy = _mm_set1_epi16(disty);
2787 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2789 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2791 convert(buf1, len * 2);
2793 convert(buf2, len * 2);
2795 for (
int i = 0; i < len; ++i) {
2796 int distx = (fx & 0x0000ffff);
2797#if defined(__SSE2__)
2798 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2800 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2801 vt = _mm_mulhi_epu16(vt, vidy);
2802 vb = _mm_mulhi_epu16(vb, vdy);
2803 vt = _mm_add_epi16(vt, vb);
2806 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2807 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2808 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2809 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2811 _mm_storel_epi64((__m128i*)(b+i), vt);
2813 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2822 int len = qMin(length, BufferSize / 2);
2824 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2826 convert(buf1, len * 2);
2827 convert(buf2, len * 2);
2829 for (
int i = 0; i < len; ++i) {
2830 int distx = (fx & 0x0000ffff);
2831 int disty = (fy & 0x0000ffff);
2832 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2842 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2844 const qreal fdx = data->m11;
2845 const qreal fdy = data->m12;
2846 const qreal fdw = data->m13;
2848 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2849 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2850 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2852 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2853 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2856 const int len = qMin(length, BufferSize / 2);
2857 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2859 convert(buf1, len * 2);
2860 convert(buf2, len * 2);
2862 for (
int i = 0; i < len; ++i) {
2863 const int distx = distxs[i];
2864 const int disty = distys[i];
2865 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2875template<TextureBlendType blendType>
2876static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_f32x4(QRgba64 *buffer,
const QSpanData *data,
2877 int y,
int x,
int length)
2879 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2880 const auto *clut = data->texture.colorTable;
2881 const auto convert = layout->fetchToRGBA64PM;
2883 const qreal cx = x + qreal(0.5);
2884 const qreal cy = y + qreal(0.5);
2886 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf1[BufferSize];
2887 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf2[BufferSize];
2888 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2889 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2890 QRgba64 *b = buffer;
2892 if (canUseFastMatrixPath(cx, cy, length, data)) {
2894 const int fdx = (
int)(data->m11 * fixed_scale);
2895 const int fdy = (
int)(data->m12 * fixed_scale);
2897 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2898 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2903 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2905 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
2907 const int len = qMin(length, BufferSize / 2);
2909 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2911 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2913 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2915 for (
int i = 0; i < len; ++i) {
2916 const int distx = (fx & 0x0000ffff);
2917 const int disty = (fy & 0x0000ffff);
2918 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2927 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2929 const qreal fdx = data->m11;
2930 const qreal fdy = data->m12;
2931 const qreal fdw = data->m13;
2933 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2934 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2935 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2937 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2938 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2941 const int len = qMin(length, BufferSize / 2);
2942 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2944 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2945 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2947 for (
int i = 0; i < len; ++i) {
2948 const int distx = distxs[i];
2949 const int disty = distys[i];
2950 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2960template<TextureBlendType blendType>
2961static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer,
const Operator *,
2962 const QSpanData *data,
int y,
int x,
int length)
2964 switch (qPixelLayouts[data->texture.format].bpp) {
2965 case QPixelLayout::BPP64:
2966 case QPixelLayout::BPP16FPx4:
2967 return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
2968 case QPixelLayout::BPP32FPx4:
2969 return fetchTransformedBilinear64_f32x4<blendType>(buffer, data, y, x, length);
2971 return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
2976#if QT_CONFIG(raster_fp)
2977static void interpolate_simple_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2981 for (
int i = 0; i < len; ++i) {
2982 const int distx = (fx & 0x0000ffff);
2983 const int disty = (fy & 0x0000ffff);
2984 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, distx, disty);
2990static void interpolate_perspective_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2991 unsigned short *distxs,
2992 unsigned short *distys)
2994 for (
int i = 0; i < len; ++i) {
2995 const int dx = distxs[i];
2996 const int dy = distys[i];
2997 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, dx, dy);
3001template<TextureBlendType blendType>
3002static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint32(QRgbaFloat32 *buffer,
const QSpanData *data,
3003 int y,
int x,
int length)
3005 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
3006 const auto *clut = data->texture.colorTable;
3007 const auto convert = qConvertToRGBA32F[data->texture.format];
3009 const qreal cx = x + qreal(0.5);
3010 const qreal cy = y + qreal(0.5);
3012 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
3013 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
3014 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3015 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3016 QRgbaFloat32 *b = buffer;
3018 if (canUseFastMatrixPath(cx, cy, length, data)) {
3020 const int fdx = (
int)(data->m11 * fixed_scale);
3021 const int fdy = (
int)(data->m12 * fixed_scale);
3023 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3024 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3029 const auto fetcher =
3030 (layout->bpp == QPixelLayout::BPP32)
3031 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
3032 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3034 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3036 const int len = qMin(length, BufferSize / 2);
3037 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3039 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3041 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3043 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3049 const auto fetcher =
3050 (layout->bpp == QPixelLayout::BPP32)
3051 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
3052 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3054 const qreal fdx = data->m11;
3055 const qreal fdy = data->m12;
3056 const qreal fdw = data->m13;
3057 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3058 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3059 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3060 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3061 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3064 const int len = qMin(length, BufferSize / 2);
3065 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3067 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3068 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3070 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3079template<TextureBlendType blendType>
3080static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint64(QRgbaFloat32 *buffer,
const QSpanData *data,
3081 int y,
int x,
int length)
3083 const auto convert = convert64ToRGBA32F[data->texture.format];
3085 const qreal cx = x + qreal(0.5);
3086 const qreal cy = y + qreal(0.5);
3088 Q_DECL_UNINITIALIZED quint64 sbuf1[BufferSize] ;
3089 Q_DECL_UNINITIALIZED quint64 sbuf2[BufferSize];
3090 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3091 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3092 QRgbaFloat32 *b = buffer;
3094 if (canUseFastMatrixPath(cx, cy, length, data)) {
3096 const int fdx = (
int)(data->m11 * fixed_scale);
3097 const int fdy = (
int)(data->m12 * fixed_scale);
3099 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3100 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3104 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3106 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3108 const int len = qMin(length, BufferSize / 2);
3109 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3111 convert(buf1, sbuf1, len * 2);
3113 convert(buf2, sbuf2, len * 2);
3115 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3121 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3123 const qreal fdx = data->m11;
3124 const qreal fdy = data->m12;
3125 const qreal fdw = data->m13;
3127 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3128 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3129 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3131 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3132 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3135 const int len = qMin(length, BufferSize / 2);
3136 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3138 convert(buf1, sbuf1, len * 2);
3139 convert(buf2, sbuf2, len * 2);
3141 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3150template<TextureBlendType blendType>
3151static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const QSpanData *data,
3152 int y,
int x,
int length)
3154 const auto convert = data->rasterBuffer->format == QImage::Format_RGBA32FPx4 ? convertRGBA32FToRGBA32FPM
3155 : convertRGBA32FToRGBA32F;
3157 const qreal cx = x + qreal(0.5);
3158 const qreal cy = y + qreal(0.5);
3160 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3161 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3162 QRgbaFloat32 *b = buffer;
3164 if (canUseFastMatrixPath(cx, cy, length, data)) {
3166 const int fdx = (
int)(data->m11 * fixed_scale);
3167 const int fdy = (
int)(data->m12 * fixed_scale);
3169 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3170 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3174 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3176 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3178 const int len = qMin(length, BufferSize / 2);
3179 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
3181 convert(buf1, len * 2);
3183 convert(buf2, len * 2);
3185 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3191 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3193 const qreal fdx = data->m11;
3194 const qreal fdy = data->m12;
3195 const qreal fdw = data->m13;
3197 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3198 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3199 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3201 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3202 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3205 const int len = qMin(length, BufferSize / 2);
3206 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3208 convert(buf1, len * 2);
3209 convert(buf2, len * 2);
3211 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3220template<TextureBlendType blendType>
3221static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const Operator *,
3222 const QSpanData *data,
int y,
int x,
int length)
3224 switch (qPixelLayouts[data->texture.format].bpp) {
3225 case QPixelLayout::BPP64:
3226 case QPixelLayout::BPP16FPx4:
3227 return fetchTransformedBilinearFP_uint64<blendType>(buffer, data, y, x, length);
3228 case QPixelLayout::BPP32FPx4:
3229 return fetchTransformedBilinearFP<blendType>(buffer, data, y, x, length);
3231 return fetchTransformedBilinearFP_uint32<blendType>(buffer, data, y, x, length);
3242 fetchUntransformedARGB32PM,
3244 fetchUntransformedARGB32PM,
3245 fetchUntransformedRGB16,
3277static_assert(std::size(sourceFetchUntransformed) == QImage::NImageFormats);
3282 fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>,
3283 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPPNone>,
3284 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPPNone>,
3285 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone>
3288static_assert(std::size(sourceFetchGeneric) == NBlendTypes);
3291 fetchUntransformedARGB32PM,
3292 fetchUntransformedARGB32PM,
3293 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3294 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3295 fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>,
3296 fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>
3299static_assert(std::size(sourceFetchARGB32PM) == NBlendTypes);
3304 fetchTransformed<BlendTransformed, QPixelLayout::BPP16>,
3305 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP16>,
3306 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP16>,
3307 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16>
3310static_assert(std::size(sourceFetchAny16) == NBlendTypes);
3315 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3316 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3317 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP32>,
3318 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32>
3321static_assert(std::size(sourceFetchAny32) == NBlendTypes);
3325 if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
3326 return sourceFetchARGB32PM[blendType];
3328 return sourceFetchUntransformed[format];
3329 if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
3330 return sourceFetchAny16[blendType];
3331 if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
3332 return sourceFetchAny32[blendType];
3333 return sourceFetchGeneric[blendType];
3336#if QT_CONFIG(raster_64bit)
3337static const SourceFetchProc64 sourceFetchGeneric64[] = {
3338 fetchUntransformed64,
3339 fetchUntransformed64,
3340 fetchTransformed64<BlendTransformed>,
3341 fetchTransformed64<BlendTransformedTiled>,
3342 fetchTransformedBilinear64<BlendTransformedBilinear>,
3343 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3346static_assert(std::size(sourceFetchGeneric64) == NBlendTypes);
3348static const SourceFetchProc64 sourceFetchRGBA64PM[] = {
3349 fetchUntransformedRGBA64PM,
3350 fetchUntransformedRGBA64PM,
3351 fetchTransformed64<BlendTransformed>,
3352 fetchTransformed64<BlendTransformedTiled>,
3353 fetchTransformedBilinear64<BlendTransformedBilinear>,
3354 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3357static_assert(std::size(sourceFetchRGBA64PM) == NBlendTypes);
3359static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
3361 if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
3362 return sourceFetchRGBA64PM[blendType];
3363 return sourceFetchGeneric64[blendType];
3367#if QT_CONFIG(raster_fp)
3368static const SourceFetchProcFP sourceFetchGenericFP[] = {
3369 fetchUntransformedFP,
3370 fetchUntransformedFP,
3371 fetchTransformedFP<BlendTransformed>,
3372 fetchTransformedFP<BlendTransformedTiled>,
3373 fetchTransformedBilinearFP<BlendTransformedBilinear>,
3374 fetchTransformedBilinearFP<BlendTransformedBilinearTiled>
3377static_assert(std::size(sourceFetchGenericFP) == NBlendTypes);
3379static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format )
3381 return sourceFetchGenericFP[blendType];
3392 return data->colorTable32[qt_gradient_clamp(data, ipos)];
3395#if QT_CONFIG(raster_64bit)
3396static const QRgba64& qt_gradient_pixel64_fixed(
const QGradientData *data,
int fixed_pos)
3398 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3399 return data->colorTable64[qt_gradient_clamp(data, ipos)];
3403#if QT_CONFIG(raster_fp)
3404static inline QRgbaFloat32 qt_gradient_pixelFP(
const QGradientData *data, qreal pos)
3406 int ipos =
int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
3407 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3408 return QRgbaFloat32::fromRgba64(rgb64.red(),rgb64.green(), rgb64.blue(), rgb64.alpha());
3411static inline QRgbaFloat32 qt_gradient_pixelFP_fixed(
const QGradientData *data,
int fixed_pos)
3413 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3414 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3415 return QRgbaFloat32::fromRgba64(rgb64.red(), rgb64.green(), rgb64.blue(), rgb64.alpha());
3419static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v,
const QSpanData *data)
3421 v->dx = data->gradient.linear.end.x - data->gradient.linear.origin.x;
3422 v->dy = data->gradient.linear.end.y - data->gradient.linear.origin.y;
3423 v->l = v->dx * v->dx + v->dy * v->dy;
3428 v->off = -v->dx * data->gradient.linear.origin.x - v->dy * data->gradient.linear.origin.y;
3439 Q_ASSERT(
std::isfinite(v));
3440 return qt_gradient_pixel(&gradient, v);
3448 qt_memfill32(buffer, fill, length);
3452#if QT_CONFIG(raster_64bit)
3456 typedef QRgba64 Type;
3457 static Type null() {
return QRgba64::fromRgba64(0); }
3458 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3460 Q_ASSERT(std::isfinite(v));
3461 return qt_gradient_pixel64(&gradient, v);
3463 static Type fetchSingle(
const QGradientData& gradient,
int v)
3465 return qt_gradient_pixel64_fixed(&gradient, v);
3467 static void memfill(Type *buffer, Type fill,
int length)
3469 qt_memfill64((quint64*)buffer, fill, length);
3474#if QT_CONFIG(raster_fp)
3478 typedef QRgbaFloat32 Type;
3479 static Type null() {
return QRgbaFloat32::fromRgba64(0,0,0,0); }
3480 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3482 Q_ASSERT(std::isfinite(v));
3483 return qt_gradient_pixelFP(&gradient, v);
3485 static Type fetchSingle(
const QGradientData& gradient,
int v)
3487 return qt_gradient_pixelFP_fixed(&gradient, v);
3489 static void memfill(Type *buffer, Type fill,
int length)
3492 memcpy(&fillCopy, &fill,
sizeof(quint64));
3493 qt_memfill64((quint64*)buffer, fillCopy, length);
3500 BlendType *buffer,
const Operator *op,
const QSpanData *data,
3501 int y,
int x,
int length)
3503 const BlendType *b = buffer;
3508 if (op->linear.l == 0) {
3511 rx = data->m21 * (y + qreal(0.5)) + data->m11 * (x + qreal(0.5)) + data->dx;
3512 ry = data->m22 * (y + qreal(0.5)) + data->m12 * (x + qreal(0.5)) + data->dy;
3513 t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off;
3514 inc = op->linear.dx * data->m11 + op->linear.dy * data->m12;
3515 affine = !data->m13 && !data->m23;
3523 const BlendType *end = buffer + length;
3525 if (inc > qreal(-1e-5) && inc < qreal(1e-5)) {
3527 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient,
int(t *
FIXPT_SIZE)), length);
3529 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient, t /
GRADIENT_STOPTABLE_SIZE), length);
3535 while (buffer < end) {
3536 *buffer = GradientBase::fetchSingle(data->gradient, t_fixed);
3537 t_fixed += inc_fixed;
3542 while (buffer < end) {
3550 qreal rw = data->m23 * (y + qreal(0.5)) + data->m13 * (x + qreal(0.5)) + data->m33;
3551 while (buffer < end) {
3554 t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off;
3556 *buffer = GradientBase::fetchSingle(data->gradient, t);
3570static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer,
const Operator *op,
const QSpanData *data,
3571 int y,
int x,
int length)
3573 return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
3576#if QT_CONFIG(raster_64bit)
3577static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3578 int y,
int x,
int length)
3580 return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
3583#if QT_CONFIG(raster_fp)
3584static const QRgbaFloat32 * QT_FASTCALL qt_fetch_linear_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3585 int y,
int x,
int length)
3587 return qt_fetch_linear_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, op, data, y, x, length);
3591static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v,
const QSpanData *data)
3593 v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x;
3594 v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y;
3596 v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius;
3597 v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius;
3599 v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy;
3601 v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0;
3604template <
class GradientBase>
3611 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
3613 if (op->radial.extended) {
3614 while (buffer < end) {
3615 BlendType result = GradientBase::null();
3617 qreal w = qSqrt(det) - b;
3618 if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0)
3619 result = GradientBase::fetchSingle(data->gradient, w);
3625 delta_det += delta_delta_det;
3631 while (buffer < end) {
3632 BlendType result = GradientBase::null();
3634 qreal w = qSqrt(det) - b;
3635 result = GradientBase::fetchSingle(data->gradient, w);
3641 delta_det += delta_delta_det;
3648const uint *
QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer,
const Operator *op,
const QSpanData *data,
3649 int y,
int x,
int length)
3651 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase32>, uint>(buffer, op, data, y, x, length);
3656#if QT_CONFIG(raster_64bit)
3657const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3658 int y,
int x,
int length)
3660 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
3664#if QT_CONFIG(raster_fp)
3665static const QRgbaFloat32 * QT_FASTCALL qt_fetch_radial_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3666 int y,
int x,
int length)
3668 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBaseFP>, QRgbaFloat32>(buffer, op, data, y, x, length);
3674 BlendType *buffer,
const QSpanData *data,
3675 int y,
int x,
int length)
3677 const BlendType *b = buffer;
3678 qreal rx = data->m21 * (y + qreal(0.5))
3679 + data->dx + data->m11 * (x + qreal(0.5));
3680 qreal ry = data->m22 * (y + qreal(0.5))
3681 + data->dy + data->m12 * (x + qreal(0.5));
3682 bool affine = !data->m13 && !data->m23;
3684 const qreal inv2pi =
M_1_PI / 2.0;
3686 const BlendType *end = buffer + length;
3688 rx -= data->gradient.conical.center.x;
3689 ry -= data->gradient.conical.center.y;
3690 while (buffer < end) {
3691 qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
3693 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3700 qreal rw = data->m23 * (y + qreal(0.5))
3701 + data->m33 + data->m13 * (x + qreal(0.5));
3704 while (buffer < end) {
3705 qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
3706 rx/rw - data->gradient.conical.center.y)
3707 + data->gradient.conical.angle;
3709 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3723static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer,
const Operator *,
const QSpanData *data,
3724 int y,
int x,
int length)
3726 return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
3729#if QT_CONFIG(raster_64bit)
3730static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
3731 int y,
int x,
int length)
3733 return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
3737#if QT_CONFIG(raster_fp)
3738static const QRgbaFloat32 * QT_FASTCALL qt_fetch_conical_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
3739 int y,
int x,
int length)
3741 return qt_fetch_conical_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, data, y, x, length);
3750#if QT_CONFIG(raster_64bit)
3751static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
3753#if QT_CONFIG(raster_fp)
3754static const CompositionFunctionSolidFP *functionForModeSolidFP = qt_functionForModeSolidFP_C;
3762#if QT_CONFIG(raster_64bit)
3763static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
3765#if QT_CONFIG(raster_fp)
3766static const CompositionFunctionFP *functionForModeFP = qt_functionForModeFP_C;
3774 else if (data->txop <= QTransform::TxTranslate)
3795 bool solidSource =
false;
3796 switch(data->type) {
3798 solidSource = data->solidColor.alphaF() >= 1.0f;
3800 op.srcFetch =
nullptr;
3801 op.srcFetch64 =
nullptr;
3802 op.srcFetchFP =
nullptr;
3805 solidSource = !data->gradient.alphaColor;
3806 getLinearGradientValues(&op.linear, data);
3807 op.srcFetch = qt_fetch_linear_gradient;
3808#if QT_CONFIG(raster_64bit)
3809 op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
3811#if QT_CONFIG(raster_fp)
3812 op.srcFetchFP = qt_fetch_linear_gradient_rgbfp;
3816 solidSource = !data->gradient.alphaColor;
3817 getRadialGradientValues(&op.radial, data);
3818 op.srcFetch = qt_fetch_radial_gradient;
3819#if QT_CONFIG(raster_64bit)
3820 op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
3822#if QT_CONFIG(raster_fp)
3823 op.srcFetchFP = qt_fetch_radial_gradient_rgbfp;
3827 solidSource = !data->gradient.alphaColor;
3829 op.srcFetch = qt_fetch_conical_gradient;
3830#if QT_CONFIG(raster_64bit)
3831 op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
3833#if QT_CONFIG(raster_fp)
3834 op.srcFetchFP = qt_fetch_conical_gradient_rgbfp;
3838 solidSource = !data->texture.hasAlpha;
3840 op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
3841#if QT_CONFIG(raster_64bit)
3842 op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);
3844#if QT_CONFIG(raster_fp)
3845 op.srcFetchFP = getSourceFetchFP(getBlendType(data), data->texture.format);
3852#if !QT_CONFIG(raster_64bit)
3853 op.srcFetch64 =
nullptr;
3855#if !QT_CONFIG(raster_fp)
3856 op.srcFetchFP =
nullptr;
3860 if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
3861 op.mode = QPainter::CompositionMode_Source;
3864#if QT_CONFIG(raster_64bit)
3865 op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
3867 op.destFetch64 =
nullptr;
3869#if QT_CONFIG(raster_fp)
3870 op.destFetchFP = destFetchProcFP[data->rasterBuffer->format];
3872 op.destFetchFP =
nullptr;
3874 if (op.mode == QPainter::CompositionMode_Source &&
3875 (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
3876 const QT_FT_Span *lastSpan = spans + spanCount;
3877 bool alphaSpans =
false;
3878 while (spans < lastSpan) {
3879 if (spans->coverage != 255) {
3885 if (!alphaSpans && spanCount > 0) {
3888 if (op.destFetch != destFetchARGB32P)
3889 op.destFetch = destFetchUndefined;
3890#if QT_CONFIG(raster_64bit)
3891 if (op.destFetch64 != destFetchRGB64)
3892 op.destFetch64 = destFetch64Undefined;
3894#if QT_CONFIG(raster_fp)
3895 if (op.destFetchFP != destFetchRGBFP)
3896 op.destFetchFP = destFetchFPUndefined;
3902 op.funcSolid = functionForModeSolid[op.mode];
3903 op.func = functionForMode[op.mode];
3904#if QT_CONFIG(raster_64bit)
3905 op.destStore64 = destStoreProc64[data->rasterBuffer->format];
3906 op.funcSolid64 = functionForModeSolid64[op.mode];
3907 op.func64 = functionForMode64[op.mode];
3909 if (data->rasterBuffer->format == QImage::Format_RGBX64 && solidSource)
3910 op.destStore64 =
nullptr;
3912 op.destStore64 =
nullptr;
3913 op.funcSolid64 =
nullptr;
3914 op.func64 =
nullptr;
3916#if QT_CONFIG(raster_fp)
3917 op.destStoreFP = destStoreFP;
3918 op.funcSolidFP = functionForModeSolidFP[op.mode];
3919 op.funcFP = functionForModeFP[op.mode];
3921 op.destStoreFP =
nullptr;
3922 op.funcSolidFP =
nullptr;
3923 op.funcFP =
nullptr;
3932 case QPixelLayout::BPP32FPx4: {
3934 qt_memfill_template(dest + 1, dest[0], length - 1);
3937 case QPixelLayout::BPP16FPx4:
3938 case QPixelLayout::BPP64: {
3939 quint64 *dest =
reinterpret_cast<quint64 *>(rasterBuffer->scanLine(y)) + x;
3940 qt_memfill_template(dest + 1, dest[0], length - 1);
3943 case QPixelLayout::BPP32: {
3944 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(y)) + x;
3945 qt_memfill_template(dest + 1, dest[0], length - 1);
3948 case QPixelLayout::BPP24: {
3949 quint24 *dest =
reinterpret_cast<
quint24 *>(rasterBuffer->scanLine(y)) + x;
3950 qt_memfill_template(dest + 1, dest[0], length - 1);
3953 case QPixelLayout::BPP16: {
3954 quint16 *dest =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
3955 qt_memfill_template(dest + 1, dest[0], length - 1);
3958 case QPixelLayout::BPP8: {
3959 uchar *dest = rasterBuffer->scanLine(y) + x;
3960 memset(dest + 1, dest[0], length - 1);
3971#if QT_CONFIG(qtgui_threadpool)
3972#define QT_THREAD_PARALLEL_FILLS(function)
3973 const int segments = (count + 32
) / 64
;
3974 QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
3975 if (segments > 1
&& qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8
3976 && threadPool && !threadPool->contains(QThread::currentThread())) {
3977 QLatch latch(segments);
3979 for (int i = 0
; i < segments; ++i) {
3980 int cn = (count - c) / (segments - i);
3981 threadPool->start([&, c, cn]() {
3982 function(c, c + cn);
3991#define QT_THREAD_PARALLEL_FILLS(function) function(0
, count)
3997 const Operator op = getOperator(data,
nullptr, 0);
3998 const uint color = data->solidColor.rgba();
3999 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4000 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4002 auto function = [=] (
int cStart,
int cEnd) {
4003 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4004 for (
int c = cStart; c < cEnd; ++c) {
4006 int length = spans[c].len;
4007 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore) {
4010 spanfill_from_first(data
->rasterBuffer, bpp, x, spans[c].y, length);
4016 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4017 op.funcSolid(dest, l, color, spans[c].coverage);
4032 const Operator op = getOperator(data,
nullptr, 0);
4033 const uint color = data->solidColor.rgba();
4035 if (op.mode == QPainter::CompositionMode_Source) {
4038 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans->y)) + spans->x;
4039 if (spans->coverage == 255) {
4040 qt_memfill(target, color, spans->len);
4042 }
else if (spans->len > 16) {
4043 op.funcSolid(target, spans->len, color, spans->coverage);
4046 uint c = BYTE_MUL(color, spans->coverage);
4047 int ialpha = 255 - spans->coverage;
4048 for (
int i = 0; i < spans->len; ++i)
4049 target[i] = c + BYTE_MUL(target[i], ialpha);
4055 const auto funcSolid = op.funcSolid;
4056 auto function = [=] (
int cStart,
int cEnd) {
4057 for (
int c = cStart; c < cEnd; ++c) {
4058 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + spans[c].x;
4059 funcSolid(target, spans[c].len, color, spans[c].coverage);
4067#if QT_CONFIG(raster_64bit)
4068 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4069 const Operator op = getOperator(data,
nullptr, 0);
4070 if (!op.funcSolid64) {
4071 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit");
4072 return blend_color_generic(count, spans, userData);
4075 const QRgba64 color = data->solidColor.rgba64();
4076 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4077 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4079 auto function = [=, &op] (
int cStart,
int cEnd)
4081 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4082 for (
int c = cStart; c < cEnd; ++c) {
4084 int length = spans[c].len;
4085 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore64) {
4087 op.destStore64(data->rasterBuffer, x, spans[c].y, &color, 1);
4088 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4093 int l = qMin(BufferSize, length);
4094 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4095 op.funcSolid64(dest, l, color, spans[c].coverage);
4097 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4103 QT_THREAD_PARALLEL_FILLS(function);
4105 blend_color_generic(count, spans, userData);
4111#if QT_CONFIG(raster_fp)
4112 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4113 const Operator op = getOperator(data,
nullptr, 0);
4114 if (!op.funcSolidFP || !op.destFetchFP) {
4115 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_fp: unsupported 4xF16 blend attempted, falling back to 32-bit");
4116 return blend_color_generic(count, spans, userData);
4120 data->solidColor.getRgbF(&r, &g, &b, &a);
4121 const QRgbaFloat32 color{r, g, b, a};
4122 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4123 QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4125 auto function = [=, &op] (
int cStart,
int cEnd)
4127 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4128 for (
int c = cStart; c < cEnd; ++c) {
4130 int length = spans[c].len;
4131 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStoreFP) {
4133 op.destStoreFP(data->rasterBuffer, x, spans[c].y, &color, 1);
4134 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4139 int l = qMin(BufferSize, length);
4140 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4141 op.funcSolidFP(dest, l, color, spans[c].coverage);
4143 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4149 QT_THREAD_PARALLEL_FILLS(function);
4151 blend_color_generic_rgb64(count, spans, userData);
4155template <
typename T>
4158 const int const_alpha = (data->type ==
QSpanData::Texture) ? data->texture.const_alpha : 256;
4159 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256;
4161 auto function = [=, &op] (
int cStart,
int cEnd)
4163 T Q_DECL_UNINITIALIZED handler(data, op);
4165 for (
int c = cStart; c < cEnd;) {
4166 if (!spans[c].len) {
4171 const int y = spans[c].y;
4172 int right = x + spans[c].len;
4173 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4176 for (
int i = c + 1; i < cEnd && spans[i].y == y && spans[i].x == right && fetchDest == (!solidSource || spans[i].coverage < 255); ++i)
4177 right += spans[i].len;
4178 int length = right - x;
4184 int process_length = l;
4187 const auto *src = handler.fetch(process_x, y, process_length, fetchDest);
4190 if (x == spans[c].x)
4191 coverage = (spans[c].coverage * const_alpha) >> 8;
4193 int right = spans[c].x + spans[c].len;
4194 int len = qMin(l, right - x);
4196 handler.process(x, y, len, coverage, src, offset);
4205 handler.store(process_x, y, process_length);
4229 const uint *
fetch(
int x,
int y,
int len,
bool fetchDest)
4231 if (fetchDest || op.destFetch == destFetchARGB32P)
4238 void process(
int,
int,
int len,
int coverage,
const uint *src,
int offset)
4240 op.func(
dest + offset, src + offset, len, coverage);
4250#if QT_CONFIG(raster_64bit)
4251class BlendSrcGenericRGB64 :
public QBlendBase
4254 QRgba64 *dest =
nullptr;
4255 alignas(16) QRgba64 buffer[BufferSize];
4256 alignas(16) QRgba64 src_buffer[BufferSize];
4257 BlendSrcGenericRGB64(
const QSpanData *d,
const Operator &o)
4262 bool isSupported()
const
4264 return op.func64 && op.destFetch64;
4267 const QRgba64 *fetch(
int x,
int y,
int len,
bool fetchDest)
4269 if (fetchDest || op.destFetch64 == destFetchRGB64)
4270 dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
4273 return op.srcFetch64(src_buffer, &op, data, y, x, len);
4276 void process(
int,
int,
int len,
int coverage,
const QRgba64 *src,
int offset)
4278 op.func64(dest + offset, src + offset, len, coverage);
4281 void store(
int x,
int y,
int len)
4284 op.destStore64(data->rasterBuffer, x, y, dest, len);
4289#if QT_CONFIG(raster_fp)
4290class BlendSrcGenericRGBFP :
public QBlendBase
4293 QRgbaFloat32 *dest =
nullptr;
4294 alignas(16) QRgbaFloat32 buffer[BufferSize];
4295 alignas(16) QRgbaFloat32 src_buffer[BufferSize];
4296 BlendSrcGenericRGBFP(
const QSpanData *d,
const Operator &o)
4301 bool isSupported()
const
4303 return op.funcFP && op.destFetchFP && op.srcFetchFP;
4306 const QRgbaFloat32 *fetch(
int x,
int y,
int len,
bool fetchDest)
4308 if (fetchDest || op.destFetchFP == destFetchRGBFP)
4309 dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
4312 return op.srcFetchFP(src_buffer, &op, data, y, x, len);
4315 void process(
int,
int,
int len,
int coverage,
const QRgbaFloat32 *src,
int offset)
4317 op.funcFP(dest + offset, src + offset, len, coverage);
4320 void store(
int x,
int y,
int len)
4323 op.destStoreFP(data->rasterBuffer, x, y, dest, len);
4331 const Operator op = getOperator(data,
nullptr, 0);
4335#if QT_CONFIG(raster_64bit)
4336static void blend_src_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4338 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4339 const Operator op = getOperator(data,
nullptr, 0);
4340 if (op.func64 && op.destFetch64) {
4341 handleSpans<BlendSrcGenericRGB64>(count, spans, data, op);
4343 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4344 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4349#if QT_CONFIG(raster_fp)
4350static void blend_src_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4352 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4353 const Operator op = getOperator(data, spans, count);
4354 if (op.funcFP && op.destFetchFP && op.srcFetchFP) {
4355 handleSpans<BlendSrcGenericRGBFP>(count, spans, data, op);
4357 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4358 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4367 const Operator op = getOperator(data, spans, count);
4369 const int image_width = data->texture.width;
4370 const int image_height = data->texture.height;
4371 const int const_alpha = data->texture.const_alpha;
4372 const int xoff = -qRound(-data->dx);
4373 const int yoff = -qRound(-data->dy);
4374 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch != destFetchARGB32P;
4376 auto function = [=, &op] (
int cStart,
int cEnd)
4378 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4379 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4380 for (
int c = cStart; c < cEnd; ++c) {
4384 int length = spans[c].len;
4386 int sy = yoff + spans[c].y;
4387 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4388 if (sy >= 0 && sy < image_height && sx < image_width) {
4394 if (sx + length > image_width)
4395 length = image_width - sx;
4397 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4400 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4401 uint *dest = fetchDest ? op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4402 op.func(dest, src, l, coverage);
4416#if QT_CONFIG(raster_64bit)
4417static void blend_untransformed_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4419 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4421 const Operator op = getOperator(data, spans, count);
4423 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4424 return blend_untransformed_generic(count, spans, userData);
4427 const int image_width = data->texture.width;
4428 const int image_height = data->texture.height;
4429 const int const_alpha = data->texture.const_alpha;
4430 const int xoff = -qRound(-data->dx);
4431 const int yoff = -qRound(-data->dy);
4432 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch64 != destFetchRGB64;
4434 auto function = [=, &op] (
int cStart,
int cEnd)
4436 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4437 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4438 for (
int c = cStart; c < cEnd; ++c) {
4442 int length = spans[c].len;
4444 int sy = yoff + spans[c].y;
4445 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4446 if (sy >= 0 && sy < image_height && sx < image_width) {
4452 if (sx + length > image_width)
4453 length = image_width - sx;
4455 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4457 int l = qMin(BufferSize, length);
4458 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4459 QRgba64 *dest = fetchDest ? op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4460 op.func64(dest, src, l, coverage);
4462 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4471 QT_THREAD_PARALLEL_FILLS(function);
4475#if QT_CONFIG(raster_fp)
4476static void blend_untransformed_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4478 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4480 const Operator op = getOperator(data, spans, count);
4482 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgbaf16: unsupported 4xFP16 blend attempted, falling back to 32-bit");
4483 return blend_untransformed_generic(count, spans, userData);
4486 const int image_width = data->texture.width;
4487 const int image_height = data->texture.height;
4488 const int xoff = -qRound(-data->dx);
4489 const int yoff = -qRound(-data->dy);
4490 const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetchFP != destFetchRGBFP;
4492 auto function = [=, &op] (
int cStart,
int cEnd)
4494 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4495 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4496 for (
int c = cStart; c < cEnd; ++c) {
4500 int length = spans[c].len;
4502 int sy = yoff + spans[c].y;
4503 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4504 if (sy >= 0 && sy < image_height && sx < image_width) {
4510 if (sx + length > image_width)
4511 length = image_width - sx;
4513 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4515 int l = qMin(BufferSize, length);
4516 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4517 QRgbaFloat32 *dest = fetchDest ? op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4518 op.funcFP(dest, src, l, coverage);
4520 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4529 QT_THREAD_PARALLEL_FILLS(function);
4536 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4537 && data->texture.format != QImage::Format_RGB32) {
4538 blend_untransformed_generic(count, spans, userData);
4542 const Operator op = getOperator(data, spans, count);
4544 const int image_width = data->texture.width;
4545 const int image_height = data->texture.height;
4546 const int const_alpha = data->texture.const_alpha;
4547 const int xoff = -qRound(-data->dx);
4548 const int yoff = -qRound(-data->dy);
4550 auto function = [=, &op] (
int cStart,
int cEnd)
4552 for (
int c = cStart; c < cEnd; ++c) {
4556 int length = spans[c].len;
4558 int sy = yoff + spans[c].y;
4559 if (sy >= 0 && sy < image_height && sx < image_width) {
4565 if (sx + length > image_width)
4566 length = image_width - sx;
4568 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4569 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4570 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4571 op.func(dest, src, length, coverage);
4580 quint16 y, quint8 b)
4582 quint16 t = ((((x & 0x07e0) * a) + ((y & 0x07e0) * b)) >> 5) & 0x07e0;
4583 t |= ((((x & 0xf81f) * a) + ((y & 0xf81f) * b)) >> 5) & 0xf81f;
4589 quint32 y, quint8 b)
4592 t = ((((x & 0xf81f07e0) >> 5) * a) + (((y & 0xf81f07e0) >> 5) * b)) & 0xf81f07e0;
4593 t |= ((((x & 0x07e0f81f) * a) + ((y & 0x07e0f81f) * b)) >> 5) & 0x07e0f81f;
4601 const quint8 ialpha)
4603 const int dstAlign = ((quintptr)dest) & 0x3;
4605 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4610 const int srcAlign = ((quintptr)src) & 0x3;
4611 int length32 = length >> 1;
4612 if (length32 && srcAlign == 0) {
4613 while (length32--) {
4614 const quint32 *src32 =
reinterpret_cast<
const quint32*>(src);
4615 quint32 *dest32 =
reinterpret_cast<quint32*>(dest);
4616 *dest32 = interpolate_pixel_rgb16x2_255(*src32, alpha,
4624 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4633 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4635 if (data->texture.format != QImage::Format_RGB16
4636 || (mode != QPainter::CompositionMode_SourceOver
4637 && mode != QPainter::CompositionMode_Source))
4639 blend_untransformed_generic(count, spans, userData);
4643 const int image_width = data->texture.width;
4644 const int image_height = data->texture.height;
4645 int xoff = -qRound(-data->dx);
4646 int yoff = -qRound(-data->dy);
4648 auto function = [=](
int cStart,
int cEnd)
4650 for (
int c = cStart; c < cEnd; ++c) {
4653 const quint8 coverage = (data->texture.const_alpha * spans[c].coverage) >> 8;
4658 int length = spans[c].len;
4660 int sy = yoff + spans[c].y;
4661 if (sy >= 0 && sy < image_height && sx < image_width) {
4667 if (sx + length > image_width)
4668 length = image_width - sx;
4670 quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans[c].y) + x;
4671 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
4672 if (coverage == 255) {
4673 memcpy(dest, src, length *
sizeof(quint16));
4675 const quint8 alpha = (coverage + 1) >> 3;
4676 const quint8 ialpha = 0x20 - alpha;
4678 blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha);
4691 const Operator op = getOperator(data, spans, count);
4693 const int image_width = data->texture.width;
4694 const int image_height = data->texture.height;
4695 const int const_alpha = data->texture.const_alpha;
4696 int xoff = -qRound(-data->dx) % image_width;
4697 int yoff = -qRound(-data->dy) % image_height;
4700 xoff += image_width;
4702 yoff += image_height;
4704 auto function = [=, &op](
int cStart,
int cEnd)
4706 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4707 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4708 for (
int c = cStart; c < cEnd; ++c) {
4710 int length = spans[c].len;
4711 int sx = (xoff + spans[c].x) % image_width;
4712 int sy = (spans[c].y + yoff) % image_height;
4718 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4720 int l = qMin(image_width - sx, length);
4723 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4724 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4725 op.func(dest, src, l, coverage);
4731 if (sx >= image_width)
4739#if QT_CONFIG(raster_64bit)
4740static void blend_tiled_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4742 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4744 const Operator op = getOperator(data, spans, count);
4746 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4747 return blend_tiled_generic(count, spans, userData);
4750 const int image_width = data->texture.width;
4751 const int image_height = data->texture.height;
4752 int xoff = -qRound(-data->dx) % image_width;
4753 int yoff = -qRound(-data->dy) % image_height;
4756 xoff += image_width;
4758 yoff += image_height;
4760 bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
4761 bool isBpp64 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP64;
4762 if (op.destFetch64 == destFetch64Undefined && image_width <= BufferSize && (isBpp32 || isBpp64)) {
4763 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4768 int length = spans->len;
4769 int sx = (xoff + spans->x) % image_width;
4770 int sy = (spans->y + yoff) % image_height;
4776 int sl = qMin(image_width, length);
4777 if (sx > 0 && sl > 0) {
4778 int l = qMin(image_width - sx, sl);
4779 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4780 op.destStore64(data->rasterBuffer, x, y, src, l);
4784 if (sx >= image_width)
4789 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, sl);
4790 op.destStore64(data->rasterBuffer, x, y, src, sl);
4794 if (sx >= image_width)
4798 uint *dest =
reinterpret_cast<uint *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4799 for (
int i = image_width; i < length; ++i)
4800 dest[i] = dest[i - image_width];
4802 quint64 *dest =
reinterpret_cast<quint64 *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4803 for (
int i = image_width; i < length; ++i)
4804 dest[i] = dest[i - image_width];
4811 auto function = [=, &op](
int cStart,
int cEnd)
4813 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4814 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4815 for (
int c = cStart; c < cEnd; ++c) {
4817 int length = spans[c].len;
4818 int sx = (xoff + spans[c].x) % image_width;
4819 int sy = (spans[c].y + yoff) % image_height;
4825 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4827 int l = qMin(image_width - sx, length);
4830 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4831 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4832 op.func64(dest, src, l, coverage);
4834 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4838 if (sx >= image_width)
4843 QT_THREAD_PARALLEL_FILLS(function);
4847#if QT_CONFIG(raster_fp)
4848static void blend_tiled_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4850 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4852 const Operator op = getOperator(data, spans, count);
4854 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4855 return blend_tiled_generic(count, spans, userData);
4858 const int image_width = data->texture.width;
4859 const int image_height = data->texture.height;
4860 int xoff = -qRound(-data->dx) % image_width;
4861 int yoff = -qRound(-data->dy) % image_height;
4864 xoff += image_width;
4866 yoff += image_height;
4870 auto function = [=, &op](
int cStart,
int cEnd)
4872 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4873 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4874 for (
int c = cStart; c < cEnd; ++c) {
4876 int length = spans[c].len;
4877 int sx = (xoff + spans[c].x) % image_width;
4878 int sy = (spans[c].y + yoff) % image_height;
4884 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4886 int l = qMin(image_width - sx, length);
4889 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4890 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4891 op.funcFP(dest, src, l, coverage);
4893 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4897 if (sx >= image_width)
4902 QT_THREAD_PARALLEL_FILLS(function);
4909 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4910 && data->texture.format != QImage::Format_RGB32) {
4911 blend_tiled_generic(count, spans, userData);
4915 const Operator op = getOperator(data, spans, count);
4917 const int image_width = data->texture.width;
4918 const int image_height = data->texture.height;
4919 int xoff = -qRound(-data->dx) % image_width;
4920 int yoff = -qRound(-data->dy) % image_height;
4923 xoff += image_width;
4925 yoff += image_height;
4926 const auto func = op.func;
4927 const int const_alpha = data->texture.const_alpha;
4929 auto function = [=] (
int cStart,
int cEnd) {
4930 for (
int c = cStart; c < cEnd; ++c) {
4932 int length = spans[c].len;
4933 int sx = (xoff + spans[c].x) % image_width;
4934 int sy = (spans[c].y + yoff) % image_height;
4940 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4942 int l = qMin(image_width - sx, length);
4945 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4946 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4947 func(dest, src, l, coverage);
4951 if (sx >= image_width)
4962 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4964 if (data->texture.format != QImage::Format_RGB16
4965 || (mode != QPainter::CompositionMode_SourceOver
4966 && mode != QPainter::CompositionMode_Source))
4968 blend_tiled_generic(count, spans, userData);
4972 const int image_width = data->texture.width;
4973 const int image_height = data->texture.height;
4974 int xoff = -qRound(-data->dx) % image_width;
4975 int yoff = -qRound(-data->dy) % image_height;
4978 xoff += image_width;
4980 yoff += image_height;
4982 const int const_alpha = data->texture.const_alpha;
4983 auto function = [=] (
int cStart,
int cEnd) {
4984 for (
int c = cStart; c < cEnd; ++c) {
4985 const quint8 coverage = (const_alpha * spans[c].coverage) >> 8;
4990 int length = spans[c].len;
4991 int sx = (xoff + spans[c].x) % image_width;
4992 int sy = (spans[c].y + yoff) % image_height;
4998 if (coverage == 255) {
5000 length = qMin(image_width,length);
5003 int l = qMin(image_width - sx, length);
5006 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + tx;
5007 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5008 memcpy(dest, src, l *
sizeof(quint16));
5012 if (sx >= image_width)
5022 int copy_image_width = qMin(image_width,
int(spans[c].len));
5023 length = spans[c].len - copy_image_width;
5024 quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5025 quint16 *dest = src + copy_image_width;
5026 while (copy_image_width < length) {
5027 memcpy(dest, src, copy_image_width *
sizeof(quint16));
5028 dest += copy_image_width;
5029 length -= copy_image_width;
5030 copy_image_width *= 2;
5033 memcpy(dest, src, length *
sizeof(quint16));
5035 const quint8 alpha = (coverage + 1) >> 3;
5036 const quint8 ialpha = 0x20 - alpha;
5039 int l = qMin(image_width - sx, length);
5042 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5043 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5044 blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
5048 if (sx >= image_width)
5060 blend_untransformed_argb,
5069 blend_untransformed_rgb565,
5078 blend_untransformed_generic,
5079 blend_tiled_generic,
5086#if QT_CONFIG(raster_64bit)
5087static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
5088 blend_untransformed_generic_rgb64,
5089 blend_tiled_generic_rgb64,
5090 blend_src_generic_rgb64,
5091 blend_src_generic_rgb64,
5092 blend_src_generic_rgb64,
5093 blend_src_generic_rgb64
5097#if QT_CONFIG(raster_fp)
5098static const ProcessSpans processTextureSpansGenericFP[NBlendTypes] = {
5099 blend_untransformed_generic_fp,
5100 blend_tiled_generic_fp,
5101 blend_src_generic_fp,
5102 blend_src_generic_fp,
5103 blend_src_generic_fp,
5104 blend_src_generic_fp
5113 case QImage::Format_Invalid:
5114 Q_UNREACHABLE_RETURN();
5115 case QImage::Format_ARGB32_Premultiplied:
5118 case QImage::Format_RGB16:
5121#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5122 case QImage::Format_ARGB32:
5123 case QImage::Format_RGBA8888:
5125 case QImage::Format_BGR30:
5126 case QImage::Format_A2BGR30_Premultiplied:
5127 case QImage::Format_RGB30:
5128 case QImage::Format_A2RGB30_Premultiplied:
5129 case QImage::Format_RGBX64:
5130 case QImage::Format_RGBA64:
5131 case QImage::Format_RGBA64_Premultiplied:
5132 case QImage::Format_Grayscale16:
5133#if !QT_CONFIG(raster_fp)
5134 case QImage::Format_RGBX16FPx4:
5135 case QImage::Format_RGBA16FPx4:
5136 case QImage::Format_RGBA16FPx4_Premultiplied:
5137 case QImage::Format_RGBX32FPx4:
5138 case QImage::Format_RGBA32FPx4:
5139 case QImage::Format_RGBA32FPx4_Premultiplied:
5141#if QT_CONFIG(raster_64bit)
5142 proc = processTextureSpansGeneric64[blendType];
5145#if QT_CONFIG(raster_fp)
5146 case QImage::Format_RGBX16FPx4:
5147 case QImage::Format_RGBA16FPx4:
5148 case QImage::Format_RGBA16FPx4_Premultiplied:
5149 case QImage::Format_RGBX32FPx4:
5150 case QImage::Format_RGBA32FPx4:
5151 case QImage::Format_RGBA32FPx4_Premultiplied:
5152 proc = processTextureSpansGenericFP[blendType];
5159 proc(count, spans, userData);
5165 int *pyinc,
int *poff)
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5181 qreal ryinc = linear.dy * data->m22 * gss *
FIXPT_SIZE;
5182 qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss *
FIXPT_SIZE;
5183 const qreal limit = qreal(
std::numeric_limits<
int>::max() -
FIXPT_SIZE);
5184 if (count && (
std::fabs(ryinc) < limit) && (
std::fabs(roff) < limit)
5185 && (
std::fabs(ryinc * spans->y + roff) < limit)
5186 && (
std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) {
5187 *pyinc =
int(ryinc);
5199 getLinearGradientValues(&linear, data);
5201 CompositionFunctionSolid funcSolid =
5204 int yinc(0), off(0);
5205 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5212 quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
5214 qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5216 funcSolid(dst, spans->len, color, spans->coverage);
5228 getLinearGradientValues(&linear, data);
5230 int yinc(0), off(0);
5231 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5237#if QT_CONFIG(raster_64bit)
5238 data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
5240 data->solidColor = qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5242 blend_color(1, spans, userData);
5251 bool isVerticalGradient =
5252 data->txop <= QTransform::TxScale &&
5253 data->type == QSpanData::LinearGradient &&
5254 data->gradient.linear.end.x == data->gradient.linear.origin.x;
5256 case QImage::Format_Invalid:
5258 case QImage::Format_RGB32:
5259 case QImage::Format_ARGB32_Premultiplied:
5260 if (isVerticalGradient && blend_vertical_gradient_argb(count, spans, userData))
5262 return blend_src_generic(count, spans, userData);
5263#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5264 case QImage::Format_ARGB32:
5265 case QImage::Format_RGBA8888:
5267 case QImage::Format_BGR30:
5268 case QImage::Format_A2BGR30_Premultiplied:
5269 case QImage::Format_RGB30:
5270 case QImage::Format_A2RGB30_Premultiplied:
5271 case QImage::Format_RGBX64:
5272 case QImage::Format_RGBA64:
5273 case QImage::Format_RGBA64_Premultiplied:
5274#if !QT_CONFIG(raster_fp)
5275 case QImage::Format_RGBX16FPx4:
5276 case QImage::Format_RGBA16FPx4:
5277 case QImage::Format_RGBA16FPx4_Premultiplied:
5278 case QImage::Format_RGBX32FPx4:
5279 case QImage::Format_RGBA32FPx4:
5280 case QImage::Format_RGBA32FPx4_Premultiplied:
5282#if QT_CONFIG(raster_64bit)
5283 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData))
5285 return blend_src_generic_rgb64(count, spans, userData);
5287#if QT_CONFIG(raster_fp)
5288 case QImage::Format_RGBX16FPx4:
5289 case QImage::Format_RGBA16FPx4:
5290 case QImage::Format_RGBA16FPx4_Premultiplied:
5291 case QImage::Format_RGBX32FPx4:
5292 case QImage::Format_RGBA32FPx4:
5293 case QImage::Format_RGBA32FPx4_Premultiplied:
5294 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_fp>(count, spans, userData))
5296 return blend_src_generic_fp(count, spans, userData);
5299 if (isVerticalGradient && blend_vertical_gradient<
blend_color_generic>(count, spans, userData))
5301 return blend_src_generic(count, spans, userData);
5306template <
class DST>
static
5308 int x,
int y, DST color,
5310 int mapWidth,
int mapHeight,
int mapStride)
5312 DST *dest =
reinterpret_cast<DST *>(rasterBuffer->scanLine(y)) + x;
5313 const int destStride = rasterBuffer->stride<DST>();
5316 while (--mapHeight >= 0) {
5319 for (
int x = 0; x < mapWidth; x += 8) {
5320 uchar s = map[x >> 3];
5321 for (
int i = 0; i < 8; ++i) {
5326 qt_memfill(dest + x0, color, n);
5341 qt_memfill(dest + x0, color, n);
5346 while (--mapHeight >= 0) {
5349 for (uchar s = *map; s; s <<= 1) {
5353 qt_memfill(dest + x0, color, n);
5361 qt_memfill(dest + x0, color, n);
5369 int x,
int y,
const QRgba64 &color,
5371 int mapWidth,
int mapHeight,
int mapStride)
5373 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color.toArgb32(),
5374 map, mapWidth, mapHeight, mapStride);
5378 int x,
int y,
const QRgba64 &color,
5380 int mapWidth,
int mapHeight,
int mapStride)
5382 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()),
5383 map, mapWidth, mapHeight, mapStride);
5386template<QtPixelOrder PixelOrder>
5388 int x,
int y,
const QRgba64 &color,
5390 int mapWidth,
int mapHeight,
int mapStride)
5392 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, qConvertRgb64ToRgb30<PixelOrder>(color),
5393 map, mapWidth, mapHeight, mapStride);
5397 int x,
int y,
const QRgba64 &color,
5399 int mapWidth,
int mapHeight,
int mapStride)
5401 qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color.toRgb16(),
5402 map, mapWidth, mapHeight, mapStride);
5405static inline void grayBlendPixel(quint32 *dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5408 const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5410 QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
5412 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5415static inline void alphamapblend_argb32(quint32 *dst,
int coverage, QRgba64 srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5417 if (coverage == 0) {
5419 }
else if (coverage == 255 || !colorProfile) {
5420 blend_pixel(*dst, src, coverage);
5421 }
else if (*dst < 0xff000000) {
5423 blend_pixel(*dst, src, coverage);
5424 }
else if (src >= 0xff000000) {
5425 grayBlendPixel(dst, coverage, srcLinear, colorProfile);
5429 blend_pixel(s, src);
5431 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5432 grayBlendPixel(dst, coverage, s64, colorProfile);
5436#if QT_CONFIG(raster_64bit)
5438static inline void grayBlendPixel(QRgba64 &dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5441 QRgba64 dstColor = dst;
5443 if (dstColor.isOpaque())
5444 dstColor = colorProfile->toLinear(dstColor);
5445 else if (!dstColor.isTransparent())
5446 dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
5449 blend_pixel(dstColor, srcLinear, coverage);
5452 if (dstColor.isOpaque())
5453 dstColor = colorProfile->fromLinear(dstColor);
5454 else if (!dstColor.isTransparent())
5455 dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
5460static inline void alphamapblend_generic(
int coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5462 if (coverage == 0) {
5464 }
else if (coverage == 255) {
5465 blend_pixel(dest[x], src);
5466 }
else if (src.isOpaque()) {
5467 grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5470 QRgba64 s = dest[x];
5471 blend_pixel(s, src);
5474 s = colorProfile->toLinear(s);
5475 grayBlendPixel(dest[x], coverage, s, colorProfile);
5479static void qt_alphamapblit_generic_oneline(
const uchar *map,
int len,
5480 const QRgba64 srcColor, QRgba64 *dest,
5481 const QRgba64 color,
5482 const QColorTrcLut *colorProfile)
5484 for (
int j = 0; j < len; ++j)
5485 alphamapblend_generic(map[j], dest, j, srcColor, color, colorProfile);
5488static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
5489 int x,
int y,
const QRgba64 &color,
5491 int mapWidth,
int mapHeight,
int mapStride,
5492 const QClipData *clip,
bool useGammaCorrection)
5494 if (color.isTransparent())
5497 const QColorTrcLut *colorProfile =
nullptr;
5499 if (useGammaCorrection)
5500 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5502 QRgba64 srcColor = color;
5503 if (colorProfile && color.isOpaque())
5504 srcColor = colorProfile->toLinear(srcColor);
5506 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5507 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5508 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5511 for (
int ly = 0; ly < mapHeight; ++ly) {
5513 int length = mapWidth;
5514 while (length > 0) {
5515 int l = qMin(BufferSize, length);
5517 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5518 qt_alphamapblit_generic_oneline(map + i - x, l,
5519 srcColor, dest, color,
5522 destStore64(rasterBuffer, i, y + ly, dest, l);
5529 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5531 int top = qMax(y, 0);
5532 map += (top - y) * mapStride;
5534 const_cast<QClipData *>(clip)->initialize();
5535 for (
int yp = top; yp<bottom; ++yp) {
5536 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5538 for (
int i=0; i<line.count; ++i) {
5539 const QT_FT_Span &clip = line.spans[i];
5541 int start = qMax<
int>(x, clip.x);
5542 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5545 Q_ASSERT(end - start <= BufferSize);
5546 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5547 qt_alphamapblit_generic_oneline(map + start - x, end - start,
5548 srcColor, dest, color,
5551 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5559 int x,
int y,
const QRgba64 &color,
5561 int mapWidth,
int mapHeight,
int mapStride,
5562 const QClipData *clip,
bool useGammaCorrection)
5564 if (color.isTransparent())
5567 const quint32 c = color.toArgb32();
5569 const QColorTrcLut *colorProfile =
nullptr;
5571 if (useGammaCorrection)
5572 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5574 QRgba64 srcColor = color;
5575 if (colorProfile && color.isOpaque())
5576 srcColor = colorProfile->toLinear(srcColor);
5579 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
5580 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
5583 for (
int ly = 0; ly < mapHeight; ++ly) {
5585 int length = mapWidth;
5586 while (length > 0) {
5588 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
5589 for (
int j=0; j < l; ++j) {
5590 const int coverage = map[j + (i - x)];
5591 alphamapblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
5594 destStore(rasterBuffer, i, y + ly, dest, l);
5601 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5603 int top = qMax(y, 0);
5604 map += (top - y) * mapStride;
5606 const_cast<
QClipData *>(clip)->initialize();
5607 for (
int yp = top; yp<bottom; ++yp) {
5608 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5610 for (
int i=0; i<line.count; ++i) {
5611 const QT_FT_Span &clip = line.spans[i];
5613 int start = qMax<
int>(x, clip.x);
5614 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5618 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
5620 for (
int xp=start; xp<end; ++xp) {
5621 const int coverage = map[xp - x];
5622 alphamapblend_argb32(dest + xp - x, coverage, srcColor, color, colorProfile);
5625 destStore(rasterBuffer, start, clip.y, dest, end - start);
5635 if (coverage == 0) {
5637 }
else if (coverage == 255) {
5640 dest[x] = BYTE_MUL_RGB16(srcColor, coverage)
5641 + BYTE_MUL_RGB16(dest[x], 255 - coverage);
5646 int x,
int y,
const QRgba64 &color,
5648 int mapWidth,
int mapHeight,
int mapStride,
5649 const QClipData *clip,
bool useGammaCorrection)
5651 if (useGammaCorrection || !color.isOpaque()) {
5652 qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
5656 const quint16 c = color.toRgb16();
5659 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
5660 const int destStride = rasterBuffer->stride<quint16>();
5661 while (--mapHeight >= 0) {
5662 for (
int i = 0; i < mapWidth; ++i)
5663 alphamapblend_quint16(map[i], dest, i, c);
5668 int top = qMax(y, 0);
5669 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5670 map += (top - y) * mapStride;
5672 const_cast<
QClipData *>(clip)->initialize();
5673 for (
int yp = top; yp<bottom; ++yp) {
5674 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5676 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(yp));
5678 for (
int i=0; i<line.count; ++i) {
5679 const QT_FT_Span &clip = line.spans[i];
5681 int start = qMax<
int>(x, clip.x);
5682 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5684 for (
int xp=start; xp<end; ++xp)
5685 alphamapblend_quint16(map[xp - x], dest, xp, c);
5693 int mapWidth,
const QRgba64 &srcColor,
5694 quint32 *dest,
const quint32 c,
5695 const QColorTrcLut *colorProfile)
5697 for (
int i = 0; i < mapWidth; ++i)
5698 alphamapblend_argb32(dest + i, map[i], srcColor, c, colorProfile);
5702 int x,
int y,
const QRgba64 &color,
5704 int mapWidth,
int mapHeight,
int mapStride,
5705 const QClipData *clip,
bool useGammaCorrection)
5707 const quint32 c = color.toArgb32();
5708 const int destStride = rasterBuffer->stride<quint32>();
5710 if (color.isTransparent())
5713 const QColorTrcLut *colorProfile =
nullptr;
5715 if (useGammaCorrection)
5716 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5718 QRgba64 srcColor = color;
5719 if (colorProfile && color.isOpaque())
5720 srcColor = colorProfile->toLinear(srcColor);
5723 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
5724 while (--mapHeight >= 0) {
5725 qt_alphamapblit_argb32_oneline(map, mapWidth, srcColor, dest, c, colorProfile);
5730 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5732 int top = qMax(y, 0);
5733 map += (top - y) * mapStride;
5735 const_cast<
QClipData *>(clip)->initialize();
5736 for (
int yp = top; yp<bottom; ++yp) {
5737 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5739 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
5741 for (
int i=0; i<line.count; ++i) {
5742 const QT_FT_Span &clip = line.spans[i];
5743 int start = qMax<
int>(x, clip.x);
5744 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5745 qt_alphamapblit_argb32_oneline(map + start - x, end - start, srcColor, dest + start, c, colorProfile);
5752#if QT_CONFIG(raster_64bit)
5753static void qt_alphamapblit_nonpremul_argb32(QRasterBuffer *rasterBuffer,
5754 int x,
int y,
const QRgba64 &color,
5756 int mapWidth,
int mapHeight,
int mapStride,
5757 const QClipData *clip,
bool useGammaCorrection)
5760 return qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight,
5761 mapStride, clip, useGammaCorrection);
5763 if (color.isTransparent())
5766 const QColorTrcLut *colorProfile =
nullptr;
5768 if (useGammaCorrection)
5769 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5771 const quint32 c = color.toArgb32();
5772 QRgba64 srcColor = color;
5773 if (colorProfile && color.isOpaque())
5774 srcColor = colorProfile->toLinear(srcColor);
5776 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5777 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5778 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5780 for (
int ly = 0; ly < mapHeight; ++ly) {
5781 bool dstFullyOpaque =
true;
5783 int length = mapWidth;
5784 while (length > 0) {
5785 int l = qMin(BufferSize, length);
5786 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y + ly)) + i;
5787 for (
int j = 0; j < l && dstFullyOpaque; ++j)
5788 dstFullyOpaque = (dest[j] & 0xff000000) == 0xff000000;
5789 if (dstFullyOpaque) {
5791 qt_alphamapblit_argb32_oneline(map + i - x, l, srcColor, dest, c, colorProfile);
5794 QRgba64 *dest64 = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5795 qt_alphamapblit_generic_oneline(map + i - x, l,
5796 srcColor, dest64, color,
5799 destStore64(rasterBuffer, i, y + ly, dest64, l);
5811 return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
5814static inline void rgbBlendPixel(quint32 *dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5817 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5819 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5821 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5826#if defined(__SSE2__
)
5827 __m128i vd = _mm_cvtsi32_si128(d);
5828 __m128i vs = _mm_cvtsi32_si128(s);
5829 __m128i va = _mm_cvtsi32_si128(rgbAlpha);
5830 const __m128i vz = _mm_setzero_si128();
5831 vd = _mm_unpacklo_epi8(vd, vz);
5832 vs = _mm_unpacklo_epi8(vs, vz);
5833 va = _mm_unpacklo_epi8(va, vz);
5834 __m128i vb = _mm_xor_si128(_mm_set1_epi16(255), va);
5835 vs = _mm_mullo_epi16(vs, va);
5836 vd = _mm_mullo_epi16(vd, vb);
5837 vd = _mm_add_epi16(vd, vs);
5838 vd = _mm_add_epi16(vd, _mm_srli_epi16(vd, 8));
5839 vd = _mm_add_epi16(vd, _mm_set1_epi16(0x80));
5840 vd = _mm_srli_epi16(vd, 8);
5841 vd = _mm_packus_epi16(vd, vd);
5842 return _mm_cvtsi128_si32(vd);
5844 const int dr = qRed(d);
5845 const int dg = qGreen(d);
5846 const int db = qBlue(d);
5848 const int sr = qRed(s);
5849 const int sg = qGreen(s);
5850 const int sb = qBlue(s);
5852 const int mr = qRed(rgbAlpha);
5853 const int mg = qGreen(rgbAlpha);
5854 const int mb = qBlue(rgbAlpha);
5856 const int nr = qt_div_255(sr * mr + dr * (255 - mr));
5857 const int ng = qt_div_255(sg * mg + dg * (255 - mg));
5858 const int nb = qt_div_255(sb * mb + db * (255 - mb));
5860 return 0xff000000 | (nr << 16) | (ng << 8) | nb;
5864static inline void alphargbblend_argb32(quint32 *dst, uint coverage,
const QRgba64 &srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5866 if (coverage == 0xff000000) {
5868 }
else if (coverage == 0xffffffff && qAlpha(src) == 255) {
5869 blend_pixel(*dst, src);
5870 }
else if (*dst < 0xff000000) {
5872 blend_pixel(*dst, src, qRgbAvg(coverage));
5873 }
else if (!colorProfile) {
5876 blend_pixel(s, src);
5878 *dst = rgbBlend(*dst, s, coverage);
5879 }
else if (srcLinear.isOpaque()) {
5880 rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
5884 blend_pixel(s, src);
5886 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5887 rgbBlendPixel(dst, coverage, s64, colorProfile);
5891#if QT_CONFIG(raster_64bit)
5892static inline void rgbBlendPixel(QRgba64 &dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5895 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
5897 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5899 dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
5902static inline void alphargbblend_generic(uint coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5904 if (coverage == 0xff000000) {
5906 }
else if (coverage == 0xffffffff) {
5907 blend_pixel(dest[x], src);
5908 }
else if (!dest[x].isOpaque()) {
5910 alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
5911 }
else if (src.isOpaque()) {
5912 rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5915 QRgba64 s = dest[x];
5916 blend_pixel(s, src);
5919 s = colorProfile->toLinear(s);
5920 rgbBlendPixel(dest[x], coverage, s, colorProfile);
5924static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
5925 int x,
int y,
const QRgba64 &color,
5926 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5927 const QClipData *clip,
bool useGammaCorrection)
5929 if (color.isTransparent())
5932 const QColorTrcLut *colorProfile =
nullptr;
5934 if (useGammaCorrection)
5935 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
5937 QRgba64 srcColor = color;
5938 if (colorProfile && color.isOpaque())
5939 srcColor = colorProfile->toLinear(srcColor);
5941 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5942 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5943 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5946 for (
int ly = 0; ly < mapHeight; ++ly) {
5948 int length = mapWidth;
5949 while (length > 0) {
5950 int l = qMin(BufferSize, length);
5951 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5952 for (
int j=0; j < l; ++j) {
5953 const uint coverage = src[j + (i - x)];
5954 alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile);
5957 destStore64(rasterBuffer, i, y + ly, dest, l);
5964 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5966 int top = qMax(y, 0);
5967 src += (top - y) * srcStride;
5969 const_cast<QClipData *>(clip)->initialize();
5970 for (
int yp = top; yp<bottom; ++yp) {
5971 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5973 for (
int i=0; i<line.count; ++i) {
5974 const QT_FT_Span &clip = line.spans[i];
5976 int start = qMax<
int>(x, clip.x);
5977 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5980 Q_ASSERT(end - start <= BufferSize);
5981 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5983 for (
int xp=start; xp<end; ++xp) {
5984 const uint coverage = src[xp - x];
5985 alphargbblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
5988 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5996 int x,
int y,
const QRgba64 &color,
5997 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5998 const QClipData *clip,
bool useGammaCorrection)
6000 if (color.isTransparent())
6003 const quint32 c = color.toArgb32();
6005 const QColorTrcLut *colorProfile =
nullptr;
6007 if (useGammaCorrection)
6008 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6010 QRgba64 srcColor = color;
6011 if (colorProfile && color.isOpaque())
6012 srcColor = colorProfile->toLinear(srcColor);
6014 Q_DECL_UNINITIALIZED quint32 buffer[BufferSize];
6015 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
6016 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
6019 for (
int ly = 0; ly < mapHeight; ++ly) {
6021 int length = mapWidth;
6022 while (length > 0) {
6024 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
6025 for (
int j=0; j < l; ++j) {
6026 const uint coverage = src[j + (i - x)];
6027 alphargbblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
6030 destStore(rasterBuffer, i, y + ly, dest, l);
6037 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6039 int top = qMax(y, 0);
6040 src += (top - y) * srcStride;
6042 const_cast<
QClipData *>(clip)->initialize();
6043 for (
int yp = top; yp<bottom; ++yp) {
6044 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6046 for (
int i=0; i<line.count; ++i) {
6047 const QT_FT_Span &clip = line.spans[i];
6049 int start = qMax<
int>(x, clip.x);
6050 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6054 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
6056 for (
int xp=start; xp<end; ++xp) {
6057 const uint coverage = src[xp - x];
6058 alphargbblend_argb32(dest + xp - start, coverage, srcColor, c, colorProfile);
6061 destStore(rasterBuffer, start, clip.y, dest, end - start);
6070 int x,
int y,
const QRgba64 &color,
6071 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
6072 const QClipData *clip,
bool useGammaCorrection)
6074 if (color.isTransparent())
6077 const quint32 c = color.toArgb32();
6079 const QColorTrcLut *colorProfile =
nullptr;
6081 if (useGammaCorrection)
6082 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6084 QRgba64 srcColor = color;
6085 if (colorProfile && color.isOpaque())
6086 srcColor = colorProfile->toLinear(srcColor);
6089 quint32 *dst =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
6090 const int destStride = rasterBuffer->stride<quint32>();
6091 while (--mapHeight >= 0) {
6092 for (
int i = 0; i < mapWidth; ++i) {
6093 const uint coverage = src[i];
6094 alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
6101 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6103 int top = qMax(y, 0);
6104 src += (top - y) * srcStride;
6106 const_cast<
QClipData *>(clip)->initialize();
6107 for (
int yp = top; yp<bottom; ++yp) {
6108 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6110 quint32 *dst =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
6112 for (
int i=0; i<line.count; ++i) {
6113 const QT_FT_Span &clip = line.spans[i];
6115 int start = qMax<
int>(x, clip.x);
6116 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6118 for (
int xp=start; xp<end; ++xp) {
6119 const uint coverage = src[xp - x];
6120 alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
6130 int x,
int y,
int width,
int height,
6131 const QRgba64 &color)
6133 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6134 color.toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6138 int x,
int y,
int width,
int height,
6139 const QRgba64 &color)
6141 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6142 quint32 c32 = color.toArgb32();
6144 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c16), &c32, 0, 1,
nullptr,
nullptr);
6145 qt_rectfill<quint16>(
reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
6146 c16, x, y, width, height, rasterBuffer->bytesPerLine());
6150 int x,
int y,
int width,
int height,
6151 const QRgba64 &color)
6153 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6154 quint32 c32 = color.toArgb32();
6156 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c24), &c32, 0, 1,
nullptr,
nullptr);
6157 qt_rectfill<
quint24>(
reinterpret_cast<
quint24 *>(rasterBuffer->buffer()),
6158 c24, x, y, width, height, rasterBuffer->bytesPerLine());
6162 int x,
int y,
int width,
int height,
6163 const QRgba64 &color)
6165 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6166 color.unpremultiplied().toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6170 int x,
int y,
int width,
int height,
6171 const QRgba64 &color)
6173 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6174 ARGB2RGBA(color.toArgb32() | 0xff000000), x, y, width, height, rasterBuffer->bytesPerLine());
6178 int x,
int y,
int width,
int height,
6179 const QRgba64 &color)
6181 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6182 ARGB2RGBA(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6186 int x,
int y,
int width,
int height,
6187 const QRgba64 &color)
6189 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6190 ARGB2RGBA(color.unpremultiplied().toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6193template<QtPixelOrder PixelOrder>
6195 int x,
int y,
int width,
int height,
6196 const QRgba64 &color)
6198 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6199 qConvertRgb64ToRgb30<PixelOrder>(color), x, y, width, height, rasterBuffer->bytesPerLine());
6203 int x,
int y,
int width,
int height,
6204 const QRgba64 &color)
6206 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6207 color.alpha() >> 8, x, y, width, height, rasterBuffer->bytesPerLine());
6211 int x,
int y,
int width,
int height,
6212 const QRgba64 &color)
6214 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6215 qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6219 int x,
int y,
int width,
int height,
6220 const QRgba64 &color)
6222 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6224 store(
reinterpret_cast<uchar *>(&c64), &color, 0, 1,
nullptr,
nullptr);
6225 qt_rectfill<quint64>(
reinterpret_cast<quint64 *>(rasterBuffer->buffer()),
6226 c64, x, y, width, height, rasterBuffer->bytesPerLine());
6230 int x,
int y,
int width,
int height,
6231 const QRgba64 &color)
6233 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6235 store(
reinterpret_cast<uchar *>(&c), &color, 0, 1,
nullptr,
nullptr);
6237 c, x, y, width, height, rasterBuffer->bytesPerLine());
6246 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr },
6249 blend_color_generic,
6250 nullptr,
nullptr,
nullptr,
nullptr
6254 blend_color_generic,
6255 nullptr,
nullptr,
nullptr,
nullptr
6259 blend_color_generic,
6260 nullptr,
nullptr,
nullptr,
nullptr
6265 qt_bitmapblit_argb32,
6266 qt_alphamapblit_argb32,
6267 qt_alphargbblit_argb32,
6272 blend_color_generic,
6273 qt_bitmapblit_argb32,
6274#if QT_CONFIG(raster_64bit)
6275 qt_alphamapblit_nonpremul_argb32,
6277 qt_alphamapblit_generic,
6279 qt_alphargbblit_generic,
6280 qt_rectfill_nonpremul_argb32
6285 qt_bitmapblit_argb32,
6286 qt_alphamapblit_argb32,
6287 qt_alphargbblit_argb32,
6292 blend_color_generic,
6293 qt_bitmapblit_quint16,
6294 qt_alphamapblit_quint16,
6295 qt_alphargbblit_generic,
6300 blend_color_generic,
6302 qt_alphamapblit_generic,
6303 qt_alphargbblit_generic,
6308 blend_color_generic,
6310 qt_alphamapblit_generic,
6311 qt_alphargbblit_generic,
6316 blend_color_generic,
6318 qt_alphamapblit_generic,
6319 qt_alphargbblit_generic,
6324 blend_color_generic,
6326 qt_alphamapblit_generic,
6327 qt_alphargbblit_generic,
6332 blend_color_generic,
6334 qt_alphamapblit_generic,
6335 qt_alphargbblit_generic,
6340 blend_color_generic,
6342 qt_alphamapblit_generic,
6343 qt_alphargbblit_generic,
6348 blend_color_generic,
6350 qt_alphamapblit_generic,
6351 qt_alphargbblit_generic,
6356 blend_color_generic,
6358 qt_alphamapblit_generic,
6359 qt_alphargbblit_generic,
6364 blend_color_generic,
6365 qt_bitmapblit_rgba8888,
6366 qt_alphamapblit_generic,
6367 qt_alphargbblit_generic,
6372 blend_color_generic,
6373 qt_bitmapblit_rgba8888,
6374 qt_alphamapblit_generic,
6375 qt_alphargbblit_generic,
6376 qt_rectfill_nonpremul_rgba
6380 blend_color_generic,
6381 qt_bitmapblit_rgba8888,
6382 qt_alphamapblit_generic,
6383 qt_alphargbblit_generic,
6388 blend_color_generic_rgb64,
6389 qt_bitmapblit_rgb30<PixelOrderBGR>,
6390 qt_alphamapblit_generic,
6391 qt_alphargbblit_generic,
6392 qt_rectfill_rgb30<PixelOrderBGR>
6396 blend_color_generic_rgb64,
6397 qt_bitmapblit_rgb30<PixelOrderBGR>,
6398 qt_alphamapblit_generic,
6399 qt_alphargbblit_generic,
6400 qt_rectfill_rgb30<PixelOrderBGR>
6404 blend_color_generic_rgb64,
6405 qt_bitmapblit_rgb30<PixelOrderRGB>,
6406 qt_alphamapblit_generic,
6407 qt_alphargbblit_generic,
6408 qt_rectfill_rgb30<PixelOrderRGB>
6412 blend_color_generic_rgb64,
6413 qt_bitmapblit_rgb30<PixelOrderRGB>,
6414 qt_alphamapblit_generic,
6415 qt_alphargbblit_generic,
6416 qt_rectfill_rgb30<PixelOrderRGB>
6420 blend_color_generic,
6422 qt_alphamapblit_generic,
6423 qt_alphargbblit_generic,
6428 blend_color_generic,
6430 qt_alphamapblit_generic,
6431 qt_alphargbblit_generic,
6436 blend_color_generic_rgb64,
6438 qt_alphamapblit_generic,
6439 qt_alphargbblit_generic,
6444 blend_color_generic_rgb64,
6446 qt_alphamapblit_generic,
6447 qt_alphargbblit_generic,
6452 blend_color_generic_rgb64,
6454 qt_alphamapblit_generic,
6455 qt_alphargbblit_generic,
6460 blend_color_generic_rgb64,
6462 qt_alphamapblit_generic,
6463 qt_alphargbblit_generic,
6468 blend_color_generic,
6470 qt_alphamapblit_generic,
6471 qt_alphargbblit_generic,
6476 blend_color_generic_fp,
6478 qt_alphamapblit_generic,
6479 qt_alphargbblit_generic,
6484 blend_color_generic_fp,
6486 qt_alphamapblit_generic,
6487 qt_alphargbblit_generic,
6492 blend_color_generic_fp,
6494 qt_alphamapblit_generic,
6495 qt_alphargbblit_generic,
6500 blend_color_generic_fp,
6502 qt_alphamapblit_generic,
6503 qt_alphargbblit_generic,
6508 blend_color_generic_fp,
6510 qt_alphamapblit_generic,
6511 qt_alphargbblit_generic,
6516 blend_color_generic_fp,
6518 qt_alphamapblit_generic,
6519 qt_alphargbblit_generic,
6524static_assert(std::size(qDrawHelper) == QImage::NImageFormats);
6526#if !defined(Q_PROCESSOR_X86) && !defined(QT_COMPILER_SUPPORTS_LSX)
6529 qt_memfill_template<quint64>(dest, color, count);
6533#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
6534__attribute__((optimize(
"no-tree-vectorize")))
6538# ifdef QT_COMPILER_SUPPORTS_SSSE3
6539 extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
6540 if (qCpuHasFeature(SSSE3))
6541 return qt_memfill24_ssse3(dest, color, count);
6542# elif defined QT_COMPILER_SUPPORTS_LSX
6543 extern void qt_memfill24_lsx(quint24 *, quint24, qsizetype);
6544 if (qCpuHasFeature(LSX))
6545 return qt_memfill24_lsx(dest, color, count);
6548 const quint32 v = color;
6552 while ((quintptr(dest) & 0x3) && dest < end) {
6558 const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
6559 const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
6560 const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
6562 for ( ; dest <= (end - 4); dest += 4) {
6563 quint32 *dst =
reinterpret_cast<quint32 *>(dest);
6570 switch (end - dest) {
6584 const int align = quintptr(dest) & 0x3;
6591 dest[count - 1] = value;
6593 const quint32 value32 = (value << 16) | value;
6594 qt_memfill32(
reinterpret_cast<quint32*>(dest), value32, count / 2);
6597#if defined(Q_PROCESSOR_X86) || defined(QT_COMPILER_SUPPORTS_LSX)
6598void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count) =
nullptr;
6599void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count) =
nullptr;
6600#elif !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
6603 qt_memfill_template<quint32>(dest, color, count);
6607#ifdef QT_COMPILER_SUPPORTS_SSE4_1
6608template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6609#elif defined(QT_COMPILER_SUPPORTS_LSX)
6610template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6620#if defined(Q_PROCESSOR_X86) && !defined(__SSE2__
)
6621 qt_memfill32 = qt_memfill_template<quint32>;
6622 qt_memfill64 = qt_memfill_template<quint64>;
6623#elif defined(__SSE2__
)
6625 qt_memfill32 = qt_memfill32_sse2;
6626 qt_memfill64 = qt_memfill64_sse2;
6628 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
6629 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
6630 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
6631 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
6632 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_sse2;
6633 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_sse2;
6634 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
6636 extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6637 const uchar *srcPixels,
int sbpl,
int srch,
6638 const QRectF &targetRect,
6639 const QRectF &sourceRect,
6642 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6643 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6644 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6645 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6647 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels,
int dbpl,
6648 const uchar *srcPixels,
int sbpl,
6651 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6652 const uchar *srcPixels,
int sbpl,
6656 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6657 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6658 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6659 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6660 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6661 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6662 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6663 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6665 extern const uint *
QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer,
const Operator *op,
const QSpanData *data,
6666 int y,
int x,
int length);
6668 qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
6670 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6671 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6672 extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6673 extern void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6674 extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6675 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
6676 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
6677 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
6678 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_sse2;
6679 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
6681#ifdef QT_COMPILER_SUPPORTS_SSSE3
6682 if (qCpuHasFeature(SSSE3)) {
6683 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels,
int dbpl,
6684 const uchar *srcPixels,
int sbpl,
6688 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer,
const Operator *,
const QSpanData *data,
6689 int y,
int x,
int length);
6690 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6691 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6692 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6693 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6694 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
6695 extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst,
const uchar *src,
int count);
6696 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
6697 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
6701#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
6702 if (qCpuHasFeature(SSE4_1)) {
6703 extern void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6704 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6705 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6706 const QList<QRgb> *, QDitherInfo *);
6707 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6708 const QList<QRgb> *, QDitherInfo *);
6709 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6710 const QList<QRgb> *, QDitherInfo *);
6711 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6712 const QList<QRgb> *, QDitherInfo *);
6713 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6714 const QList<QRgb> *, QDitherInfo *);
6715 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6716 const QList<QRgb> *, QDitherInfo *);
6717 extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6718 const QList<QRgb> *, QDitherInfo *);
6719 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6720 const QList<QRgb> *, QDitherInfo *);
6721 extern void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6722 const QList<QRgb> *, QDitherInfo *);
6723 extern void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6724 const QList<QRgb> *, QDitherInfo *);
6725 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6726 const QList<QRgb> *, QDitherInfo *);
6727 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6728 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6729 extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6730 extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6732 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
6733 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
6734 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
6735 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
6736 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4;
6737 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4;
6738 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6739 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6740 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6741 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6743 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
6744 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
6745 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
6746 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
6747 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
6748 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
6749 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
6750 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_sse4;
6751 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_sse4;
6752#if QT_CONFIG(raster_64bit)
6753 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
6754 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
6756#if QT_CONFIG(raster_fp)
6757 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_sse4(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6758 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6759 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6760 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_sse4;
6761 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_sse4;
6762 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_sse4;
6767#if defined(QT_COMPILER_SUPPORTS_AVX2)
6768 if (qCpuHasFeature(ArchHaswell)) {
6769 qt_memfill32 = qt_memfill32_avx2;
6770 qt_memfill64 = qt_memfill64_avx2;
6771 extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels,
int dbpl,
6772 const uchar *srcPixels,
int sbpl,
6773 int w,
int h,
int const_alpha);
6774 extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels,
int dbpl,
6775 const uchar *srcPixels,
int sbpl,
6776 int w,
int h,
int const_alpha);
6777 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6778 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6779 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6780 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6781 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6782 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6783 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6784 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6786 extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6787 extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6788 extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels,
int length, uint color, uint const_alpha);
6789 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
6790 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
6791 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
6792#if QT_CONFIG(raster_64bit)
6793 extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6794 extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6795 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
6796 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
6797 qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
6798 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
6800#if QT_CONFIG(raster_fp)
6801 extern void QT_FASTCALL comp_func_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6802 extern void QT_FASTCALL comp_func_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6803 extern void QT_FASTCALL comp_func_solid_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6804 extern void QT_FASTCALL comp_func_solid_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6805 qt_functionForModeFP_C[QPainter::CompositionMode_Source] = comp_func_Source_rgbafp_avx2;
6806 qt_functionForModeFP_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgbafp_avx2;
6807 qt_functionForModeSolidFP_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_rgbafp_avx2;
6808 qt_functionForModeSolidFP_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgbafp_avx2;
6811 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6812 int &fx,
int &fy,
int fdx,
int );
6813 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6814 int &fx,
int &fy,
int fdx,
int );
6815 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6816 int &fx,
int &fy,
int fdx,
int fdy);
6818 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
6819 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
6820 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
6822 extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6823 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6824 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6825 const QList<QRgb> *, QDitherInfo *);
6826 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6827 const QList<QRgb> *, QDitherInfo *);
6828 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2;
6829 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
6830 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
6831 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
6833 extern const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
6834 extern const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
6835 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6836 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6837 extern const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6838 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2;
6839 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
6840 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
6841 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
6842 qPixelLayouts[QImage::Format_RGBA64].fetchToRGBA64PM = fetchRGBA64ToRGBA64PM_avx2;
6844 extern const uint *QT_FASTCALL fetchRGB16FToRGB32_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6845 extern const uint *QT_FASTCALL fetchRGBA16FToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6846 extern const QRgba64 *QT_FASTCALL fetchRGBA16FPMToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6847 extern const QRgba64 *QT_FASTCALL fetchRGBA16FToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6848 extern void QT_FASTCALL storeRGB16FFromRGB32_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6849 extern void QT_FASTCALL storeRGBA16FFromARGB32PM_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6850 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6851 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6852 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6853 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6854 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToARGB32PM = fetchRGBA16FToARGB32PM_avx2;
6855 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToRGBA64PM = fetchRGBA16FToRGBA64PM_avx2;
6856 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromARGB32PM = storeRGBA16FFromARGB32PM_avx2;
6857 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6858 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6859 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6860 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6861 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6862#if QT_CONFIG(raster_fp)
6863 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA16FToRGBA32F_avx2(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6864 extern void QT_FASTCALL storeRGBX16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6865 extern void QT_FASTCALL storeRGBA16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6866 qFetchToRGBA32F[QImage::Format_RGBA16FPx4] = fetchRGBA16FToRGBA32F_avx2;
6867 qStoreFromRGBA32F[QImage::Format_RGBX16FPx4] = storeRGBX16FFromRGBA32F_avx2;
6868 qStoreFromRGBA32F[QImage::Format_RGBA16FPx4] = storeRGBA16FFromRGBA32F_avx2;
6876#if defined(QT_COMPILER_SUPPORTS_LSX)
6877 if (qCpuHasFeature(LSX)) {
6878 qt_memfill32 = qt_memfill32_lsx;
6879 qt_memfill64 = qt_memfill64_lsx;
6881 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_lsx;
6882 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_lsx;
6883 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_lsx;
6884 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_lsx;
6885 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_lsx;
6886 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_lsx;
6887 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_lsx;
6889 extern void qt_scale_image_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6890 const uchar *srcPixels,
int sbpl,
int srch,
6891 const QRectF &targetRect,
6892 const QRectF &sourceRect,
6896 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6897 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6898 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6899 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6901 extern void qt_blend_rgb32_on_rgb32_lsx(uchar *destPixels,
int dbpl,
6902 const uchar *srcPixels,
int sbpl,
6906 extern void qt_blend_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6907 const uchar *srcPixels,
int sbpl,
6911 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6912 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6913 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6914 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6915 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6916 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6917 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6918 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6920 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_lsx(uint *buffer,
const Operator *op,
const QSpanData *data,
6921 int y,
int x,
int length);
6923 qt_fetch_radial_gradient = qt_fetch_radial_gradient_lsx;
6925 extern void QT_FASTCALL comp_func_SourceOver_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6926 extern void QT_FASTCALL comp_func_solid_SourceOver_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6927 extern void QT_FASTCALL comp_func_Source_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6928 extern void QT_FASTCALL comp_func_solid_Source_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6929 extern void QT_FASTCALL comp_func_Plus_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6930 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lsx;
6931 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lsx;
6932 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lsx;
6933 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_lsx;
6934 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_lsx;
6936 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_lsx(uint *buffer,
const Operator *,
const QSpanData *data,
6937 int y,
int x,
int length);
6938 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_lsx;
6939 extern void QT_FASTCALL rbSwap_888_lsx(uchar *dst,
const uchar *src,
int count);
6940 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_lsx;
6941 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_lsx;
6943 extern void QT_FASTCALL convertARGB32ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6944 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6945 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6946 const QList<QRgb> *, QDitherInfo *);
6947 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6948 const QList<QRgb> *, QDitherInfo *);
6949 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6950 const QList<QRgb> *, QDitherInfo *);
6951 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6952 const QList<QRgb> *, QDitherInfo *);
6953 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6954 const QList<QRgb> *, QDitherInfo *);
6955 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6956 const QList<QRgb> *, QDitherInfo *);
6957 extern void QT_FASTCALL storeARGB32FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6958 const QList<QRgb> *, QDitherInfo *);
6959 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6960 const QList<QRgb> *, QDitherInfo *);
6961 extern void QT_FASTCALL storeRGBXFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6962 const QList<QRgb> *, QDitherInfo *);
6963 extern void QT_FASTCALL storeARGB32FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6964 const QList<QRgb> *, QDitherInfo *);
6965 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6966 const QList<QRgb> *, QDitherInfo *);
6967 extern void QT_FASTCALL destStore64ARGB32_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6968 extern void QT_FASTCALL destStore64RGBA8888_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6969 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6970 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6971 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lsx;
6972 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lsx;
6973 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lsx;
6974 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lsx;
6975 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lsx;
6976 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lsx;
6977 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6978 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6979 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6980 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6981 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_lsx;
6982 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_lsx;
6983 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_lsx;
6984 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderBGR>;
6985 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderRGB>;
6986 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_lsx;
6987 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_lsx;
6988 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_lsx;
6989 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_lsx;
6990#if QT_CONFIG(raster_64bit)
6991 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_lsx;
6992 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_lsx;
6994#if QT_CONFIG(raster_fp)
6995 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_lsx(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6996 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6997 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6998 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_lsx;
6999 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_lsx;
7000 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_lsx;
7004#if defined(QT_COMPILER_SUPPORTS_LASX)
7005 if (qCpuHasFeature(LASX)) {
7006 qt_memfill32 = qt_memfill32_lasx;
7007 qt_memfill64 = qt_memfill64_lasx;
7009 extern void qt_blend_rgb32_on_rgb32_lasx(uchar *destPixels,
int dbpl,
7010 const uchar *srcPixels,
int sbpl,
7011 int w,
int h,
int const_alpha);
7012 extern void qt_blend_argb32_on_argb32_lasx(uchar *destPixels,
int dbpl,
7013 const uchar *srcPixels,
int sbpl,
7014 int w,
int h,
int const_alpha);
7015 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7016 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7017 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7018 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7019 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7020 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7021 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7022 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7024 extern void QT_FASTCALL comp_func_Source_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7025 extern void QT_FASTCALL comp_func_SourceOver_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7026 extern void QT_FASTCALL comp_func_solid_SourceOver_lasx(uint *destPixels,
int length, uint color, uint const_alpha);
7027 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lasx;
7028 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lasx;
7029 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lasx;
7030#if QT_CONFIG(raster_64bit)
7031 extern void QT_FASTCALL comp_func_Source_rgb64_lasx(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
7032 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_lasx(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
7033 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_lasx;
7034 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_lasx;
7037 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7038 int &fx,
int &fy,
int fdx,
int );
7039 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7040 int &fx,
int &fy,
int fdx,
int );
7041 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7042 int &fx,
int &fy,
int fdx,
int fdy);
7044 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx;
7045 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_lasx;
7046 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx;
7048 extern void QT_FASTCALL convertARGB32ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7049 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7050 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7051 const QList<QRgb> *, QDitherInfo *);
7052 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7053 const QList<QRgb> *, QDitherInfo *);
7054 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lasx;
7055 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lasx;
7056 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lasx;
7057 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lasx;
7059 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
7060 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
7061 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7062 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7063 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lasx;
7064 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lasx;
7065 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lasx;
7066 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lasx;
7072#if defined(__ARM_NEON__)
7073 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7074 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7075 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7076 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7077#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7078 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7079 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7080 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7081 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7084 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
7085 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
7086 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
7088 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer,
const Operator *op,
const QSpanData *data,
7089 int y,
int x,
int length);
7091 qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
7093 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
7095#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7096 extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7097 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7098 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7099 const QList<QRgb> *, QDitherInfo *);
7100 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7101 const QList<QRgb> *, QDitherInfo *);
7102 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7103 const QList<QRgb> *, QDitherInfo *);
7104 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7105 const QList<QRgb> *, QDitherInfo *);
7106 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7107 const QList<QRgb> *, QDitherInfo *);
7108 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7109 const QList<QRgb> *, QDitherInfo *);
7110 extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7111 const QList<QRgb> *, QDitherInfo *);
7112 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7113 const QList<QRgb> *, QDitherInfo *);
7114 extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7115 const QList<QRgb> *, QDitherInfo *);
7116 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
7117 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
7118 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
7119 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon;
7120 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon;
7121 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
7122 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
7123 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
7124 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7125 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7126 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
7127 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7128 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7131#if defined(ENABLE_PIXMAN_DRAWHELPERS)
7133 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
7134 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
7135 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
7137 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
7138 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
7140 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
7141 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
7143 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
7145 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
7146 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
7148 qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon;
7149 qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon;
7153#if defined(__MIPS_DSP__)
7155 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
7156 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
7157 qt_functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
7158 qt_functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
7159 qt_functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
7160 qt_functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
7161 qt_functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
7162 qt_functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
7163 qt_functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
7164 qt_functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
7166 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
7167 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
7168 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
7169 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
7170 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
7171 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
7172 qt_functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
7173 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
7175 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7176 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7177 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7178 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7180 destFetchProc[QImage::Format_ARGB32] = qt_destFetchARGB32_mips_dsp;
7182 destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
7184 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
7185 sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
7186 sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
7188#if defined(__MIPS_DSPR2__)
7189 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
7190 sourceFetchUntransformed[QImage::Format_RGB16] = qt_fetchUntransformedRGB16_mips_dspr2;
7192 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dsp;
const uint * fetch(int x, int y, int len, bool fetchDest)
uint src_buffer[BufferSize]
void store(int x, int y, int len)
BlendSrcGeneric(const QSpanData *d, const Operator &o)
void process(int, int, int len, int coverage, const uint *src, int offset)
static Type fetchSingle(const QGradientData &gradient, qreal v)
static void memfill(Type *buffer, Type fill, int length)
static void fetch(BlendType *buffer, BlendType *end, const Operator *op, const QSpanData *data, qreal det, qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
GradientBase::Type BlendType
Combined button and popup list for selecting options.
void qInitBlendFunctions()
CompositionFunctionFP qt_functionForModeFP_C[]
CompositionFunction qt_functionForMode_C[]
CompositionFunctionSolidFP qt_functionForModeSolidFP_C[]
CompositionFunction64 qt_functionForMode64_C[]
CompositionFunctionSolid qt_functionForModeSolid_C[]
CompositionFunctionSolid64 qt_functionForModeSolid64_C[]
void(QT_FASTCALL * BilinearFastTransformHelper)(uint *b, uint *end, const QTextureData &image, int &fx, int &fy, int fdx, int fdy)
static int qRgbAvg(QRgb rgb)
static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
static void qt_alphamapblit_argb32_oneline(const uchar *map, int mapWidth, const QRgba64 &srcColor, quint32 *dest, const quint32 c, const QColorTrcLut *colorProfile)
static const CompositionFunctionSolid * functionForModeSolid
static DestFetchProc destFetchProc[]
constexpr Fetch1PixelFunc fetch1PixelTable[QPixelLayout::BPPCount]
static void alphamapblend_quint16(int coverage, quint16 *dest, int x, const quint16 srcColor)
static BilinearFastTransformHelper bilinearFastTransformHelperARGB32PM[2][NFastTransformTypes]
static void qt_rectfill_rgbx(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
static const CompositionFunction * functionForMode
static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void blend_color_generic(int count, const QT_FT_Span *spans, void *userData)
static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
uint QT_FASTCALL fetch1Pixel< QPixelLayout::BPP1LSB >(const uchar *src, int index)
static void qt_rectfill_quint64(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
@ BlendTransformedBilinearTiled
@ BlendTransformedBilinear
static SourceFetchProc sourceFetchAny32[]
static SourceFetchProc sourceFetchUntransformed[]
static bool calculate_fixed_gradient_factors(int count, const QT_FT_Span *spans, const QSpanData *data, const LinearGradientValues &linear, int *pyinc, int *poff)
static void blend_color_generic_fp(int count, const QT_FT_Span *spans, void *userData)
static TextureBlendType getBlendType(const QSpanData *data)
static void qt_bitmapblit_rgb30(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP bpp, int x, int y, int length)
Q_CONSTRUCTOR_FUNCTION(qInitDrawhelperFunctions)
static void qInitDrawhelperFunctions()
static void blend_untransformed_rgb565(int count, const QT_FT_Span *spans, void *userData)
static DestStoreProc destStoreProc[]
static QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
static void qt_bitmapblit_rgba8888(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static const SourceFetchProc sourceFetchGeneric[]
static void blend_untransformed_argb(int count, const QT_FT_Span *spans, void *userData)
static SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
static quint16 interpolate_pixel_rgb16_255(quint16 x, quint8 a, quint16 y, quint8 b)
static void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static bool canUseFastMatrixPath(const qreal cx, const qreal cy, const qsizetype length, const QSpanData *data)
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uint *src, int mapWidth, int mapHeight, int srcStride, const QClipData *clip, bool useGammaCorrection)
static void blend_color_generic_rgb64(int count, const QT_FT_Span *spans, void *userData)
void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v)
static void qt_rectfill_gray(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
constexpr int fixed_scale
static bool blend_vertical_gradient_argb(int count, const QT_FT_Span *spans, void *userData)
static Operator getOperator(const QSpanData *data, const QT_FT_Span *spans, int spanCount)
static SourceFetchProc qt_fetch_radial_gradient
static void qt_rectfill_argb32(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static const ProcessSpans processTextureSpansRGB16[NBlendTypes]
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)
static void blend_color_argb(int count, const QT_FT_Span *spans, void *userData)
static void qt_rectfill_alpha(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static SourceFetchProc sourceFetchAny16[]
static void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes]
static SourceFetchProc sourceFetchARGB32PM[]
static void blend_tiled_rgb565(int count, const QT_FT_Span *spans, void *userData)
static void qt_rectfill_quint24(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
#define QT_THREAD_PARALLEL_FILLS(function)
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)
static void blend_src_generic(int count, const QT_FT_Span *spans, void *userData)
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
void fetchTransformedBilinear_pixelBounds< BlendTransformedBilinearTiled >(int max, int, int, int &v1, int &v2)
static void blend_sourceOver_rgb16_rgb16(quint16 *Q_DECL_RESTRICT dest, const quint16 *Q_DECL_RESTRICT src, int length, const quint8 alpha, const quint8 ialpha)
static void blend_untransformed_generic(int count, const QT_FT_Span *spans, void *userData)
static void blend_tiled_argb(int count, const QT_FT_Span *spans, void *userData)
static void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile)
static bool blend_vertical_gradient(int count, const QT_FT_Span *spans, void *userData)
static void blend_tiled_generic(int count, const QT_FT_Span *spans, void *userData)
static const ProcessSpans processTextureSpansGeneric[NBlendTypes]
static QRgb findNearestColor(QRgb color, QRasterBuffer *rbuf)
static void qt_rectfill_fp32x4(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
void handleSpans(int count, const QT_FT_Span *spans, const QSpanData *data, const Operator &op)
static void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, DST color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static quint32 interpolate_pixel_rgb16x2_255(quint32 x, quint8 a, quint32 y, quint8 b)
static void qt_rectfill_rgb30(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
void qt_memfill24(quint24 *dest, quint24 value, qsizetype count)
void qt_memfill32(quint32 *dest, quint32 value, qsizetype count)
static constexpr int BufferSize
void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
QT_FT_SpanFunc ProcessSpans
QRgbaFloat< float > QRgbaFloat32
DrawHelper qDrawHelper[QImage::NImageFormats]
#define GRADIENT_STOPTABLE_SIZE
void qBlendGradient(int count, const QT_FT_Span *spans, void *userData)
void qBlendTexture(int count, const QT_FT_Span *spans, void *userData)
void qt_memfill64(quint64 *dest, quint64 value, qsizetype count)
QRasterBuffer * rasterBuffer