7#include <qstylehints.h>
8#include <qguiapplication.h>
10#include <private/qcolortransform_p.h>
11#include <private/qcolortrclut_p.h>
12#include <private/qdrawhelper_p.h>
13#include <private/qdrawhelper_x86_p.h>
14#include <private/qdrawingprimitive_sse2_p.h>
15#include <private/qdrawhelper_loongarch64_p.h>
16#include <private/qdrawingprimitive_lsx_p.h>
17#include <private/qdrawhelper_neon_p.h>
18#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
19#include <private/qdrawhelper_mips_dsp_p.h>
21#include <private/qguiapplication_p.h>
22#include <private/qpaintengine_raster_p.h>
23#include <private/qpainter_p.h>
24#include <private/qpixellayout_p.h>
25#include <private/qrgba64_p.h>
27#include <qloggingcategory.h>
30#if QT_CONFIG(qtgui_threadpool)
31#include <private/qlatch_p.h>
32#include <qthreadpool.h>
33#include <private/qthreadpool_p.h>
38#if QT_CONFIG(raster_64bit) || QT_CONFIG(raster_fp)
39Q_STATIC_LOGGING_CATEGORY(lcQtGuiDrawHelper,
"qt.gui.drawhelper")
42#define MASK(src, a) src = BYTE_MUL(src, a)
45
46
54 Q_UNREACHABLE_RETURN(0);
58inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1LSB>(
const uchar *src,
int index)
60 return (src[index >> 3] >> (index & 7)) & 1;
64inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1MSB>(
const uchar *src,
int index)
66 return (src[index >> 3] >> (~index & 7)) & 1;
70inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP8>(
const uchar *src,
int index)
76inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16>(
const uchar *src,
int index)
78 return reinterpret_cast<
const quint16 *>(src)[index];
82inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP24>(
const uchar *src,
int index)
84 return reinterpret_cast<
const quint24 *>(src)[index];
88inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32>(
const uchar *src,
int index)
90 return reinterpret_cast<
const uint *>(src)[index];
94inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP64>(
const uchar *src,
int index)
97 QRgba64 c =
reinterpret_cast<
const QRgba64 *>(src)[index];
102inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16FPx4>(
const uchar *src,
int index)
105 QRgbaFloat16 c =
reinterpret_cast<
const QRgbaFloat16 *>(src)[index];
110inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32FPx4>(
const uchar *src,
int index)
113 QRgbaFloat32 c =
reinterpret_cast<
const QRgbaFloat32 *>(src)[index];
121 fetch1Pixel<QPixelLayout::BPP1MSB>,
122 fetch1Pixel<QPixelLayout::BPP1LSB>,
123 fetch1Pixel<QPixelLayout::BPP8>,
124 fetch1Pixel<QPixelLayout::BPP16>,
125 fetch1Pixel<QPixelLayout::BPP24>,
126 fetch1Pixel<QPixelLayout::BPP32>,
127 fetch1Pixel<QPixelLayout::BPP64>,
128 fetch1Pixel<QPixelLayout::BPP16FPx4>,
129 fetch1Pixel<QPixelLayout::BPP32FPx4>,
132#if QT_CONFIG(raster_64bit)
133static void QT_FASTCALL convertRGBA64ToRGBA64PM(QRgba64 *buffer,
int count)
135 for (
int i = 0; i < count; ++i)
136 buffer[i] = buffer[i].premultiplied();
139static void QT_FASTCALL convertRGBA64PMToRGBA64PM(QRgba64 *,
int)
143static void QT_FASTCALL convertRGBA16FToRGBA64PM(QRgba64 *buffer,
int count)
145 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
146 for (
int i = 0; i < count; ++i) {
147 QRgbaFloat16 c = in[i];
148 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
152static void QT_FASTCALL convertRGBA16FPMToRGBA64PM(QRgba64 *buffer,
int count)
154 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
155 for (
int i = 0; i < count; ++i) {
156 QRgbaFloat16 c = in[i];
157 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
161static void QT_FASTCALL convertRGBA32FToRGBA64PM(QRgba64 *buffer,
int count)
163 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
164 for (
int i = 0; i < count; ++i) {
165 QRgbaFloat32 c = in[i];
166 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
170static void QT_FASTCALL convertRGBA32FPMToRGBA64PM(QRgba64 *buffer,
int count)
172 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
173 for (
int i = 0; i < count; ++i) {
174 QRgbaFloat32 c = in[i];
175 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
179static Convert64Func convert64ToRGBA64PM[] = {
205 convertRGBA64PMToRGBA64PM,
206 convertRGBA64ToRGBA64PM,
207 convertRGBA64PMToRGBA64PM,
210 convertRGBA16FPMToRGBA64PM,
211 convertRGBA16FToRGBA64PM,
212 convertRGBA16FPMToRGBA64PM,
213 convertRGBA32FPMToRGBA64PM,
214 convertRGBA32FToRGBA64PM,
215 convertRGBA32FPMToRGBA64PM,
219static_assert(std::size(convert64ToRGBA64PM) == QImage::NImageFormats);
222#if QT_CONFIG(raster_fp)
223static void QT_FASTCALL convertRGBA64PMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
225 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
226 for (
int i = 0; i < count; ++i) {
228 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha()).premultiplied();
232static void QT_FASTCALL convertRGBA64ToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
234 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
235 for (
int i = 0; i < count; ++i) {
237 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
241static void QT_FASTCALL convertRGBA16FPMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
243 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
244 for (
int i = 0; i < count; ++i)
245 buffer[i] = buffer[i].premultiplied();
248static void QT_FASTCALL convertRGBA16FToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
250 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
253static Convert64ToFPFunc convert64ToRGBA32F[] = {
279 convertRGBA64ToRGBA32F,
280 convertRGBA64PMToRGBA32F,
281 convertRGBA64ToRGBA32F,
284 convertRGBA16FToRGBA32F,
285 convertRGBA16FPMToRGBA32F,
286 convertRGBA16FToRGBA32F,
293static_assert(std::size(convert64ToRGBA32F) == QImage::NImageFormats);
295static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer,
int count)
297 for (
int i = 0; i < count; ++i)
298 buffer[i] = buffer[i].premultiplied();
301static void convertRGBA32FToRGBA32F(QRgbaFloat32 *,
int)
308
309
310
312static uint * QT_FASTCALL destFetchMono(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
315 uint *start = buffer;
316 const uint *end = buffer + length;
317 while (buffer < end) {
318 *buffer = data[x>>3] & (0x80 >> (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
325static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
328 uint *start = buffer;
329 const uint *end = buffer + length;
330 while (buffer < end) {
331 *buffer = data[x>>3] & (0x1 << (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
338static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
340 return (uint *)rasterBuffer->scanLine(y) + x;
343static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
345 const ushort *
Q_DECL_RESTRICT data = (
const ushort *)rasterBuffer->scanLine(y) + x;
346 for (
int i = 0; i < length; ++i)
347 buffer[i] = qConvertRgb16To32(data[i]);
351static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
353 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
354 return const_cast<uint *>(layout->fetchToARGB32PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
357static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *,
int,
int,
int)
403static_assert(std::size(destFetchProc) == QImage::NImageFormats);
405#if QT_CONFIG(raster_64bit)
406static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
408 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
409 return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
412static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
414 return (QRgba64 *)rasterBuffer->scanLine(y) + x;
417static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *,
int,
int,
int)
422static DestFetchProc64 destFetchProc64[] =
463static_assert(std::size(destFetchProc64) == QImage::NImageFormats);
466#if QT_CONFIG(raster_fp)
467static QRgbaFloat32 *QT_FASTCALL destFetchFP(QRgbaFloat32 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
469 return const_cast<QRgbaFloat32 *>(qFetchToRGBA32F[rasterBuffer->format](buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
472static QRgbaFloat32 *QT_FASTCALL destFetchRGBFP(QRgbaFloat32 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
474 return reinterpret_cast<QRgbaFloat32 *>(rasterBuffer->scanLine(y)) + x;
477static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRasterBuffer *,
int,
int,
int)
481static DestFetchProcFP destFetchProcFP[] =
522static_assert(std::size(destFetchProcFP) == QImage::NImageFormats);
526
527
528
531 const QRgb color_0 = rbuf->destColor0;
532 const QRgb color_1 = rbuf->destColor1;
535 int g = qGreen(color);
536 int b = qBlue(color);
540 rx = r - qRed(color_0);
541 gx = g - qGreen(color_0);
542 bx = b - qBlue(color_0);
543 dist_0 = rx*rx + gx*gx + bx*bx;
545 rx = r - qRed(color_1);
546 gx = g - qGreen(color_1);
547 bx = b - qBlue(color_1);
548 dist_1 = rx*rx + gx*gx + bx*bx;
556
557
559static void QT_FASTCALL destStoreMono(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
562 if (rasterBuffer->monoDestinationWithClut) {
563 for (
int i = 0; i < length; ++i) {
564 if (buffer[i] == rasterBuffer->destColor0) {
565 data[x >> 3] &= ~(0x80 >> (x & 7));
566 }
else if (buffer[i] == rasterBuffer->destColor1) {
567 data[x >> 3] |= 0x80 >> (x & 7);
568 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
569 data[x >> 3] &= ~(0x80 >> (x & 7));
571 data[x >> 3] |= 0x80 >> (x & 7);
576 for (
int i = 0; i < length; ++i) {
577 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
578 data[x >> 3] |= 0x80 >> (x & 7);
580 data[x >> 3] &= ~(0x80 >> (x & 7));
586static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
589 if (rasterBuffer->monoDestinationWithClut) {
590 for (
int i = 0; i < length; ++i) {
591 if (buffer[i] == rasterBuffer->destColor0) {
592 data[x >> 3] &= ~(1 << (x & 7));
593 }
else if (buffer[i] == rasterBuffer->destColor1) {
594 data[x >> 3] |= 1 << (x & 7);
595 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
596 data[x >> 3] &= ~(1 << (x & 7));
598 data[x >> 3] |= 1 << (x & 7);
603 for (
int i = 0; i < length; ++i) {
604 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
605 data[x >> 3] |= 1 << (x & 7);
607 data[x >> 3] &= ~(1 << (x & 7));
613static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
615 quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x;
616 for (
int i = 0; i < length; ++i)
617 data[i] = qConvertRgb32To16(buffer[i]);
620static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
622 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
623 ConvertAndStorePixelsFunc store = layout->storeFromARGB32PM;
624 if (!layout->premultiplied && !layout->hasAlphaChannel)
625 store = layout->storeFromRGB32;
626 uchar *dest = rasterBuffer->scanLine(y);
627 store(dest, buffer, x, length,
nullptr,
nullptr);
630static void QT_FASTCALL destStoreGray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
632 uchar *data = rasterBuffer->scanLine(y) + x;
635 for (
int k = 0; k < length; ++k) {
636 if (!qIsGray(buffer[k])) {
640 data[k] = qRed(buffer[k]);
643 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
644 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
645 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
647 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
651static void QT_FASTCALL destStoreGray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
653 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
656 for (
int k = 0; k < length; ++k) {
657 if (!qIsGray(buffer[k])) {
661 data[k] = qRed(buffer[k]) * 257;
664 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
665 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
666 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
668 Q_DECL_UNINITIALIZED QRgba64 tmp_line[BufferSize];
669 for (
int k = 0; k < length; ++k)
670 tmp_line[k] = QRgba64::fromArgb32(buffer[k]);
671 tfd->apply(data, tmp_line, length, QColorTransformPrivate::InputPremultiplied);
716static_assert(std::size(destStoreProc) == QImage::NImageFormats);
718#if QT_CONFIG(raster_64bit)
719static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
721 auto store = qStoreFromRGBA64PM[rasterBuffer->format];
722 uchar *dest = rasterBuffer->scanLine(y);
723 store(dest, buffer, x, length,
nullptr,
nullptr);
726static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
728 QRgba64 *dest =
reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
729 for (
int i = 0; i < length; ++i) {
730 dest[i] = buffer[i].unpremultiplied();
734static void QT_FASTCALL destStore64Gray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
736 uchar *data = rasterBuffer->scanLine(y) + x;
739 for (
int k = 0; k < length; ++k) {
740 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
744 data[k] = buffer[k].red8();
747 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
748 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
749 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
751 Q_DECL_UNINITIALIZED quint16 gray_line[BufferSize];
752 tfd->apply(gray_line, buffer, length, QColorTransformPrivate::InputPremultiplied);
753 for (
int k = 0; k < length; ++k)
754 data[k] = qt_div_257(gray_line[k]);
758static void QT_FASTCALL destStore64Gray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
760 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
763 for (
int k = 0; k < length; ++k) {
764 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
768 data[k] = buffer[k].red();
771 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
772 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
773 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
774 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
778static DestStoreProc64 destStoreProc64[] =
819static_assert(std::size(destStoreProc64) == QImage::NImageFormats);
822#if QT_CONFIG(raster_fp)
823static void QT_FASTCALL destStoreFP(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgbaFloat32 *buffer,
int length)
825 auto store = qStoreFromRGBA32F[rasterBuffer->format];
826 uchar *dest = rasterBuffer->scanLine(y);
827 store(dest, buffer, x, length,
nullptr,
nullptr);
832
833
834
835
836
837
838
839
840
841
842
843
844
856static const uint *QT_FASTCALL fetchUntransformed(uint *buffer,
const Operator *,
857 const QSpanData *data,
int y,
int x,
int length)
859 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
860 return layout->fetchToARGB32PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
863static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *,
const Operator *,
864 const QSpanData *data,
int y,
int x,
int)
866 const uchar *scanLine = data->texture.scanLine(y);
867 return reinterpret_cast<
const uint *>(scanLine) + x;
870static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer,
const Operator *,
871 const QSpanData *data,
int y,
int x,
874 const quint16 *scanLine = (
const quint16 *)data->texture.scanLine(y) + x;
875 for (
int i = 0; i < length; ++i)
876 buffer[i] = qConvertRgb16To32(scanLine[i]);
880#if QT_CONFIG(raster_64bit)
881static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer,
const Operator *,
882 const QSpanData *data,
int y,
int x,
int length)
884 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
885 return layout->fetchToRGBA64PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
888static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *,
const Operator *,
889 const QSpanData *data,
int y,
int x,
int)
891 const uchar *scanLine = data->texture.scanLine(y);
892 return reinterpret_cast<
const QRgba64 *>(scanLine) + x;
896#if QT_CONFIG(raster_fp)
897static const QRgbaFloat32 *QT_FASTCALL fetchUntransformedFP(QRgbaFloat32 *buffer,
const Operator *,
898 const QSpanData *data,
int y,
int x,
int length)
900 const auto fetch = qFetchToRGBA32F[data->texture.format];
901 return fetch(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
910 if (v < 0 || v >= max) {
915 v = qBound(l1, v, l2);
921 if (Q_UNLIKELY(!data->fast_matrix))
924 qreal fx = (data->m21 * cy + data->m11 * cx + data->dx) *
fixed_scale;
925 qreal fy = (data->m22 * cy + data->m12 * cx + data->dy) *
fixed_scale;
926 qreal minc =
std::min(fx, fy);
927 qreal maxc =
std::max(fx, fy);
930 minc =
std::min(minc,
std::min(fx, fy));
931 maxc =
std::max(maxc,
std::max(fx, fy));
933 return minc >=
std::numeric_limits<
int>::min() && maxc <=
std::numeric_limits<
int>::max();
937static void QT_FASTCALL fetchTransformed_fetcher(T *buffer,
const QSpanData *data,
938 int y,
int x,
int length)
940 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
941 const QTextureData &image = data->texture;
943 const qreal cx = x + qreal(0.5);
944 const qreal cy = y + qreal(0.5);
946 constexpr bool useFetch = (bpp < QPixelLayout::BPP32) &&
sizeof(T) ==
sizeof(uint);
947 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
949 Q_ASSERT(layout->bpp == bpp || (layout->bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
951 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout->bpp] : Fetch1PixelFunc(fetch1Pixel<bpp>);
953 if (canUseFastMatrixPath(cx, cy, length, data)) {
955 int fdx = (
int)(data->m11 * fixed_scale);
956 int fdy = (
int)(data->m12 * fixed_scale);
958 int fx =
int((data->m21 * cy
959 + data->m11 * cx + data->dx) * fixed_scale);
960 int fy =
int((data->m22 * cy
961 + data->m12 * cx + data->dy) * fixed_scale);
965 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
966 const uchar *src = image.scanLine(py);
969 if (blendType == BlendTransformed) {
970 int fastLen = length;
972 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
974 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
976 for (; i < fastLen; ++i) {
979 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
982 if constexpr (useFetch)
983 buffer[i] = fetch1(src, x1);
985 buffer[i] =
reinterpret_cast<
const T*>(src)[x1];
989 for (; i < fastLen; ++i) {
991 if constexpr (useFetch)
992 buffer[i] = fetch1(src, px);
994 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
999 for (; i < length; ++i) {
1000 int px = (fx >> 16);
1001 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1002 if constexpr (useFetch)
1003 buffer[i] = fetch1(src, px);
1005 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1010 if (blendType == BlendTransformed) {
1011 int fastLen = length;
1013 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
1015 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
1017 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
1019 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
1021 for (; i < fastLen; ++i) {
1022 int x1 = (fx >> 16);
1023 int y1 = (fy >> 16);
1026 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
1027 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1);
1028 if (x1 == x2 && y1 == y2)
1030 if constexpr (useFetch)
1031 buffer[i] = fetch1(image.scanLine(y1), x1);
1033 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(y1))[x1];
1038 for (; i < fastLen; ++i) {
1039 int px = (fx >> 16);
1040 int py = (fy >> 16);
1041 if constexpr (useFetch)
1042 buffer[i] = fetch1(image.scanLine(py), px);
1044 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1050 for (; i < length; ++i) {
1051 int px = (fx >> 16);
1052 int py = (fy >> 16);
1053 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1054 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1055 if constexpr (useFetch)
1056 buffer[i] = fetch1(image.scanLine(py), px);
1058 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1064 const qreal fdx = data->m11;
1065 const qreal fdy = data->m12;
1066 const qreal fdw = data->m13;
1068 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
1069 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
1070 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
1072 T *
const end = buffer + length;
1075 const qreal iw = fw == 0 ? 1 : 1 / fw;
1076 const qreal tx = fx * iw;
1077 const qreal ty = fy * iw;
1078 int px = qFloor(tx);
1079 int py = qFloor(ty);
1081 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1082 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1083 if constexpr (useFetch)
1084 *b = fetch1(image.scanLine(py), px);
1086 *b =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1101static const uint *
QT_FASTCALL fetchTransformed(uint *buffer,
const Operator *,
const QSpanData *data,
1102 int y,
int x,
int length)
1104 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
1105 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1106 fetchTransformed_fetcher<blendType, bpp, uint>(buffer, data, y, x, length);
1107 layout->convertToARGB32PM(buffer, length, data->texture.colorTable);
1111#if QT_CONFIG(raster_64bit)
1112template<TextureBlendType blendType>
1113static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
1114 int y,
int x,
int length)
1116 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1117 if (layout->bpp < QPixelLayout::BPP64) {
1118 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1119 Q_ASSERT(length <= BufferSize);
1120 if (layout->bpp == QPixelLayout::BPP32)
1121 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1123 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1124 return layout->convertToRGBA64PM(buffer, buffer32, length, data->texture.colorTable,
nullptr);
1127 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(
reinterpret_cast<quint64*>(buffer), data, y, x, length);
1128 if (
auto convert = convert64ToRGBA64PM[data->texture.format])
1129 convert(buffer, length);
1134#if QT_CONFIG(raster_fp)
1135template<TextureBlendType blendType>
1136static const QRgbaFloat32 *QT_FASTCALL fetchTransformedFP(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
1137 int y,
int x,
int length)
1139 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1140 if (layout->bpp < QPixelLayout::BPP64) {
1141 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1142 Q_ASSERT(length <= BufferSize);
1143 if (layout->bpp == QPixelLayout::BPP32)
1144 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1146 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1147 qConvertToRGBA32F[data->texture.format](buffer, buffer32, length, data->texture.colorTable,
nullptr);
1148 }
else if (layout->bpp < QPixelLayout::BPP32FPx4) {
1149 Q_DECL_UNINITIALIZED quint64 buffer64[BufferSize];
1150 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(buffer64, data, y, x, length);
1151 convert64ToRGBA32F[data->texture.format](buffer, buffer64, length);
1153 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>(buffer, data, y, x, length);
1154 if (data->texture.format == QImage::Format_RGBA32FPx4)
1155 convertRGBA32FToRGBA32FPM(buffer, length);
1163
1164
1165
1168 uint distxy = distx * disty;
1171 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
1172 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
1173 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
1174 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy));
1175 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy));
1176 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy));
1177 uint brrb = ((br & 0x00ff00ff) * (distxy));
1178 uint brag = (((br & 0xff00ff00) >> 8) * (distxy));
1179 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
1182#if defined(__SSE2__
)
1183#define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \
1184{
1185 const __m128i dxdy = _mm_mullo_epi16 (distx, disty);
1186 const __m128i distx_ = _mm_slli_epi16(distx, 4
);
1187 const __m128i disty_ = _mm_slli_epi16(disty, 4
);
1188 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_)));
1189 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy);
1190 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy);
1192 __m128i tlAG = _mm_srli_epi16(tl, 8
);
1193 __m128i tlRB = _mm_and_si128(tl, colorMask);
1194 __m128i trAG = _mm_srli_epi16(tr, 8
);
1195 __m128i trRB = _mm_and_si128(tr, colorMask);
1196 __m128i blAG = _mm_srli_epi16(bl, 8
);
1197 __m128i blRB = _mm_and_si128(bl, colorMask);
1198 __m128i brAG = _mm_srli_epi16(br, 8
);
1199 __m128i brRB = _mm_and_si128(br, colorMask);
1201 tlAG = _mm_mullo_epi16(tlAG, idxidy);
1202 tlRB = _mm_mullo_epi16(tlRB, idxidy);
1203 trAG = _mm_mullo_epi16(trAG, dxidy);
1204 trRB = _mm_mullo_epi16(trRB, dxidy);
1205 blAG = _mm_mullo_epi16(blAG, idxdy);
1206 blRB = _mm_mullo_epi16(blRB, idxdy);
1207 brAG = _mm_mullo_epi16(brAG, dxdy);
1208 brRB = _mm_mullo_epi16(brRB, dxdy);
1211 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG));
1212 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB));
1213 rAG = _mm_andnot_si128(colorMask, rAG);
1214 rRB = _mm_srli_epi16(rRB, 8
);
1215 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \
1216}
1219#if defined(__ARM_NEON__)
1220#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \
1221{
1222 const int16x8_t dxdy = vmulq_s16(distx, disty);
1223 const int16x8_t distx_ = vshlq_n_s16(distx, 4
);
1224 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_)));
1225 const int16x8_t dxidy = vsubq_s16(distx_, dxdy);
1226 const int16x8_t idxdy = vsubq_s16(disty_, dxdy);
1228 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8
));
1229 int16x8_t tlRB = vandq_s16(tl, colorMask);
1230 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8
));
1231 int16x8_t trRB = vandq_s16(tr, colorMask);
1232 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8
));
1233 int16x8_t blRB = vandq_s16(bl, colorMask);
1234 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8
));
1235 int16x8_t brRB = vandq_s16(br, colorMask);
1237 int16x8_t rAG = vmulq_s16(tlAG, idxidy);
1238 int16x8_t rRB = vmulq_s16(tlRB, idxidy);
1239 rAG = vmlaq_s16(rAG, trAG, dxidy);
1240 rRB = vmlaq_s16(rRB, trRB, dxidy);
1241 rAG = vmlaq_s16(rAG, blAG, idxdy);
1242 rRB = vmlaq_s16(rRB, blRB, idxdy);
1243 rAG = vmlaq_s16(rAG, brAG, dxdy);
1244 rRB = vmlaq_s16(rRB, brRB, dxdy);
1246 rAG = vandq_s16(invColorMask, rAG);
1247 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8
));
1248 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \
1249}
1252#if defined(__loongarch_sx)
1253static inline void interpolate_4_pixels_16_lsx(__m128i tl, __m128i tr, __m128i bl, __m128i br,
1254 __m128i distx, __m128i disty, uint *b)
1256 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1257 const __m128i v_256 = __lsx_vreplgr2vr_h(256);
1258 const __m128i dxdy = __lsx_vmul_h(distx, disty);
1259 const __m128i distx_ = __lsx_vslli_h(distx, 4);
1260 const __m128i disty_ = __lsx_vslli_h(disty, 4);
1261 const __m128i idxidy = __lsx_vadd_h(dxdy, __lsx_vsub_h(v_256, __lsx_vadd_h(distx_, disty_)));
1262 const __m128i dxidy = __lsx_vsub_h(distx_, dxdy);
1263 const __m128i idxdy = __lsx_vsub_h(disty_,dxdy);
1265 __m128i tlAG = __lsx_vsrli_h(tl, 8);
1266 __m128i tlRB = __lsx_vand_v(tl, colorMask);
1267 __m128i trAG = __lsx_vsrli_h(tr, 8);
1268 __m128i trRB = __lsx_vand_v(tr, colorMask);
1269 __m128i blAG = __lsx_vsrli_h(bl, 8);
1270 __m128i blRB = __lsx_vand_v(bl, colorMask);
1271 __m128i brAG = __lsx_vsrli_h(br, 8);
1272 __m128i brRB = __lsx_vand_v(br, colorMask);
1274 tlAG = __lsx_vmul_h(tlAG, idxidy);
1275 tlRB = __lsx_vmul_h(tlRB, idxidy);
1276 trAG = __lsx_vmul_h(trAG, dxidy);
1277 trRB = __lsx_vmul_h(trRB, dxidy);
1278 blAG = __lsx_vmul_h(blAG, idxdy);
1279 blRB = __lsx_vmul_h(blRB, idxdy);
1280 brAG = __lsx_vmul_h(brAG, dxdy);
1281 brRB = __lsx_vmul_h(brRB, dxdy);
1283 __m128i rAG =__lsx_vadd_h(__lsx_vadd_h(tlAG, trAG), __lsx_vadd_h(blAG, brAG));
1284 __m128i rRB =__lsx_vadd_h(__lsx_vadd_h(tlRB, trRB), __lsx_vadd_h(blRB, brRB));
1285 rAG = __lsx_vandn_v(colorMask, rAG);
1286 rRB = __lsx_vsrli_h(rRB, 8);
1287 __lsx_vst(__lsx_vor_v(rAG, rRB), b, 0);
1303 Q_ASSERT(v1 >= 0 && v1 < max);
1304 Q_ASSERT(v2 >= 0 && v2 < max);
1316 Q_ASSERT(v1 >= l1 && v1 <= l2);
1317 Q_ASSERT(v2 >= l1 && v2 <= l2);
1331static void QT_FASTCALL intermediate_adder(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx)
1333#if defined(QT_COMPILER_SUPPORTS_AVX2)
1334 extern void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx);
1335 if (qCpuHasFeature(ArchHaswell))
1336 return intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
1340 fx -= offset * fixed_scale;
1343 const int x = (fx >> 16);
1345 const uint distx = (fx & 0x0000ffff) >> 8;
1346 const uint idistx = 256 - distx;
1347 const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
1348 const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
1349 *b = (rb >> 8) | ag;
1353 fx += offset * fixed_scale;
1359static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
1360 int &fx,
int &fy,
int fdx,
int )
1362 int y1 = (fy >> 16);
1364 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1365 const uint *s1 = (
const uint *)image.scanLine(y1);
1366 const uint *s2 = (
const uint *)image.scanLine(y2);
1368 const int disty = (fy & 0x0000ffff) >> 8;
1369 const int idisty = 256 - disty;
1370 const int length = end - b;
1373 const int adjust = (fdx < 0) ? fdx * length : 0;
1374 const int offset = (fx + adjust) >> 16;
1377 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
1379 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
1382 Q_ASSERT(count <= BufferSize + 2);
1385 if (blendType == BlendTransformedBilinearTiled) {
1387 if (x < 0) x += image.width;
1389 lim = qMin(count, image.x2 - x);
1391 Q_ASSERT(x < image.x2);
1392 uint t = s1[image.x1];
1393 uint b = s2[image.x1];
1394 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1395 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1397 intermediate.buffer_rb[f] = rb;
1398 intermediate.buffer_ag[f] = ag;
1401 }
while (x < image.x1 && f < lim);
1405 if (blendType != BlendTransformedBilinearTiled) {
1406#if defined(__SSE2__
)
1407 const __m128i disty_ = _mm_set1_epi16(disty);
1408 const __m128i idisty_ = _mm_set1_epi16(idisty);
1409 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1412 for (; f < lim; x += 4, f += 4) {
1414 __m128i top = _mm_loadu_si128((
const __m128i*)((
const uint *)(s1)+x));
1415 __m128i topAG = _mm_srli_epi16(top, 8);
1416 __m128i topRB = _mm_and_si128(top, colorMask);
1418 topAG = _mm_mullo_epi16 (topAG, idisty_);
1419 topRB = _mm_mullo_epi16 (topRB, idisty_);
1422 __m128i bottom = _mm_loadu_si128((
const __m128i*)((
const uint *)(s2)+x));
1423 __m128i bottomAG = _mm_srli_epi16(bottom, 8);
1424 __m128i bottomRB = _mm_and_si128(bottom, colorMask);
1425 bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
1426 bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
1429 __m128i rAG =_mm_add_epi16(topAG, bottomAG);
1430 rAG = _mm_srli_epi16(rAG, 8);
1431 _mm_storeu_si128((__m128i*)(&intermediate.buffer_ag[f]), rAG);
1432 __m128i rRB =_mm_add_epi16(topRB, bottomRB);
1433 rRB = _mm_srli_epi16(rRB, 8);
1434 _mm_storeu_si128((__m128i*)(&intermediate.buffer_rb[f]), rRB);
1436#elif defined(__ARM_NEON__)
1437 const int16x8_t disty_ = vdupq_n_s16(disty);
1438 const int16x8_t idisty_ = vdupq_n_s16(idisty);
1439 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1442 for (; f < lim; x += 4, f += 4) {
1444 int16x8_t top = vld1q_s16((int16_t*)((
const uint *)(s1)+x));
1445 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8));
1446 int16x8_t topRB = vandq_s16(top, colorMask);
1448 topAG = vmulq_s16(topAG, idisty_);
1449 topRB = vmulq_s16(topRB, idisty_);
1452 int16x8_t bottom = vld1q_s16((int16_t*)((
const uint *)(s2)+x));
1453 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8));
1454 int16x8_t bottomRB = vandq_s16(bottom, colorMask);
1455 bottomAG = vmulq_s16(bottomAG, disty_);
1456 bottomRB = vmulq_s16(bottomRB, disty_);
1459 int16x8_t rAG = vaddq_s16(topAG, bottomAG);
1460 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
1461 vst1q_s16((int16_t*)(&intermediate.buffer_ag[f]), rAG);
1462 int16x8_t rRB = vaddq_s16(topRB, bottomRB);
1463 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
1464 vst1q_s16((int16_t*)(&intermediate.buffer_rb[f]), rRB);
1466#elif defined(__loongarch_sx)
1467 const __m128i disty_ = __lsx_vreplgr2vr_h(disty);
1468 const __m128i idisty_ = __lsx_vreplgr2vr_h(idisty);
1469 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1472 for (; f < lim; x += 4, f += 4) {
1474 __m128i top = __lsx_vld((
const __m128i*)((
const uint *)(s1)+x), 0);
1475 __m128i topAG = __lsx_vsrli_h(top, 8);
1476 __m128i topRB = __lsx_vand_v(top, colorMask);
1478 topAG = __lsx_vmul_h(topAG, idisty_);
1479 topRB = __lsx_vmul_h(topRB, idisty_);
1482 __m128i bottom = __lsx_vld((
const __m128i*)((
const uint *)(s2)+x), 0);
1483 __m128i bottomAG = __lsx_vsrli_h(bottom, 8);
1484 __m128i bottomRB = __lsx_vand_v(bottom, colorMask);
1485 bottomAG = __lsx_vmul_h(bottomAG, disty_);
1486 bottomRB = __lsx_vmul_h(bottomRB, disty_);
1489 __m128i rAG = __lsx_vadd_h(topAG, bottomAG);
1490 rAG = __lsx_vsrli_h(rAG, 8);
1491 __lsx_vst(rAG, (__m128i*)(&intermediate.buffer_ag[f]), 0);
1492 __m128i rRB = __lsx_vadd_h(topRB, bottomRB);
1493 rRB = __lsx_vsrli_h(rRB, 8);
1494 __lsx_vst(rRB, (__m128i*)(&intermediate.buffer_rb[f]), 0);
1498 for (; f < count; f++) {
1499 if (blendType == BlendTransformedBilinearTiled) {
1500 if (x >= image.width) x -= image.width;
1502 x = qMin(x, image.x2 - 1);
1508 intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1509 intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1514 intermediate_adder(b, end, intermediate, offset, fx, fdx);
1518static void QT_FASTCALL fetchTransformedBilinearARGB32PM_upscale_helper(uint *b, uint *end,
const QTextureData &image,
1519 int &fx,
int &fy,
int fdx,
int )
1521 int y1 = (fy >> 16);
1523 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1524 const uint *s1 = (
const uint *)image.scanLine(y1);
1525 const uint *s2 = (
const uint *)image.scanLine(y2);
1526 const int disty = (fy & 0x0000ffff) >> 8;
1528 if (blendType != BlendTransformedBilinearTiled) {
1529 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1530 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1532 int x1 = (fx >> 16);
1534 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1539 *b = INTERPOLATE_PIXEL_256(top, 256 - disty, bot, disty);
1543 uint *boundedEnd = end;
1545 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1547 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1550 while (b < boundedEnd) {
1552 int distx = (fx & 0x0000ffff) >> 8;
1553 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
1560 int x1 = (fx >> 16);
1562 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1 , x1, x2);
1567 int distx = (fx & 0x0000ffff) >> 8;
1568 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1576static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *b, uint *end,
const QTextureData &image,
1577 int &fx,
int &fy,
int fdx,
int )
1579 int y1 = (fy >> 16);
1581 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1582 const uint *s1 = (
const uint *)image.scanLine(y1);
1583 const uint *s2 = (
const uint *)image.scanLine(y2);
1584 const int disty8 = (fy & 0x0000ffff) >> 8;
1585 const int disty4 = (disty8 + 0x08) >> 4;
1587 if (blendType != BlendTransformedBilinearTiled) {
1588 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1589 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1591 int x1 = (fx >> 16);
1593 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1598 *b = INTERPOLATE_PIXEL_256(top, 256 - disty8, bot, disty8);
1602 uint *boundedEnd = end;
1604 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1606 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1608#if defined(__SSE2__
)
1609 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1610 const __m128i v_256 = _mm_set1_epi16(256);
1611 const __m128i v_disty = _mm_set1_epi16(disty4);
1612 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1613 const __m128i v_fx_r = _mm_set1_epi32(0x8);
1614 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1616 while (b < boundedEnd - 3) {
1617 __m128i offset = _mm_srli_epi32(v_fx, 16);
1618 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1619 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1620 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1621 const int offset3 = _mm_cvtsi128_si32(offset);
1622 const __m128i tl = _mm_setr_epi32(s1[offset0], s1[offset1], s1[offset2], s1[offset3]);
1623 const __m128i tr = _mm_setr_epi32(s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]);
1624 const __m128i bl = _mm_setr_epi32(s2[offset0], s2[offset1], s2[offset2], s2[offset3]);
1625 const __m128i br = _mm_setr_epi32(s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]);
1627 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1628 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fx_r), 4);
1629 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1630 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1632 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1634 v_fx = _mm_add_epi32(v_fx, v_fdx);
1636 fx = _mm_cvtsi128_si32(v_fx);
1637#elif defined(__ARM_NEON__)
1638 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1639 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1640 const int16x8_t v_256 = vdupq_n_s16(256);
1641 const int16x8_t v_disty = vdupq_n_s16(disty4);
1642 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
1643 int32x4_t v_fdx = vdupq_n_s32(fdx*4);
1645 int32x4_t v_fx = vmovq_n_s32(fx);
1646 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1647 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1648 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1650 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1651 const int32x4_t v_fx_r = vdupq_n_s32(0x0800);
1654 uint32x4x2_t v_top = {};
1655 uint32x4x2_t v_bot = {};
1656 while (b < boundedEnd - 3) {
1657 int x1 = (fx >> 16);
1659 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1660 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1663 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1664 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1667 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1668 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1671 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1672 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1674 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_fx_r), 12);
1675 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1677 interpolate_4_pixels_16_neon(
1678 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1679 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1680 vreinterpretq_s16_s32(v_distx), v_disty, v_disty_,
1681 colorMask, invColorMask, v_256, b);
1683 v_fx = vaddq_s32(v_fx, v_fdx);
1685#elif defined (__loongarch_sx)
1686 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1687 const __m128i v_disty = __lsx_vreplgr2vr_h(disty4);
1688 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1689 const __m128i v_fx_r = __lsx_vreplgr2vr_w(0x8);
1690 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1692 while (b < boundedEnd - 3) {
1693 __m128i offset = __lsx_vsrli_w(v_fx, 16);
1694 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1695 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1696 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1697 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1698 const __m128i tl = (__m128i)(v4u32){s1[offset0], s1[offset1], s1[offset2], s1[offset3]};
1699 const __m128i tr = (__m128i)(v4u32){s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]};
1700 const __m128i bl = (__m128i)(v4u32){s2[offset0], s2[offset1], s2[offset2], s2[offset3]};
1701 const __m128i br = (__m128i)(v4u32){s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]};
1703 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1704 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fx_r), 4);
1705 v_distx = __lsx_vshuf_h(shuffleMask, v_distx, v_distx);
1707 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1709 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1711 fx = __lsx_vpickve2gr_w(v_fx, 0);
1713 while (b < boundedEnd) {
1715 if (hasFastInterpolate4()) {
1716 int distx8 = (fx & 0x0000ffff) >> 8;
1717 *b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
1719 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1720 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx4, disty4);
1728 int x1 = (fx >> 16);
1730 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1735 if (hasFastInterpolate4()) {
1736 int distx8 = (fx & 0x0000ffff) >> 8;
1737 *b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
1739 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1740 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
1748static void QT_FASTCALL fetchTransformedBilinearARGB32PM_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1749 int &fx,
int &fy,
int fdx,
int fdy)
1753 int x1 = (fx >> 16);
1755 int y1 = (fy >> 16);
1758 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1759 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1761 const uint *s1 = (
const uint *)image.scanLine(y1);
1762 const uint *s2 = (
const uint *)image.scanLine(y2);
1769 int distx = (fx & 0x0000ffff) >> 8;
1770 int disty = (fy & 0x0000ffff) >> 8;
1772 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1781static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1782 int &fx,
int &fy,
int fdx,
int fdy)
1785 if (blendType != BlendTransformedBilinearTiled) {
1786 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1787 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1788 const qint64 min_fy = qint64(image.y1) * fixed_scale;
1789 const qint64 max_fy = qint64(image.y2 - 1) * fixed_scale;
1792 int x1 = (fx >> 16);
1794 int y1 = (fy >> 16);
1796 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1797 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1798 if (x1 != x2 && y1 != y2)
1800 const uint *s1 = (
const uint *)image.scanLine(y1);
1801 const uint *s2 = (
const uint *)image.scanLine(y2);
1806 if (hasFastInterpolate4()) {
1807 int distx = (fx & 0x0000ffff) >> 8;
1808 int disty = (fy & 0x0000ffff) >> 8;
1809 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1811 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
1812 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
1813 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
1819 uint *boundedEnd = end;
1821 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1823 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1825 boundedEnd = qMin(boundedEnd, b + (max_fy - fy) / fdy);
1827 boundedEnd = qMin(boundedEnd, b + (min_fy - fy) / fdy);
1830#if defined(__SSE2__
)
1831 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1832 const __m128i v_256 = _mm_set1_epi16(256);
1833 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1834 const __m128i v_fdy = _mm_set1_epi32(fdy*4);
1835 const __m128i v_fxy_r = _mm_set1_epi32(0x8);
1836 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1837 __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
1839 const uchar *textureData = image.imageData;
1840 const qsizetype bytesPerLine = image.bytesPerLine;
1841 const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
1843 while (b < boundedEnd - 3) {
1844 const __m128i vy = _mm_packs_epi32(_mm_srli_epi32(v_fy, 16), _mm_setzero_si128());
1846 __m128i offset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epi16(vy, vbpl));
1847 offset = _mm_add_epi32(offset, _mm_srli_epi32(v_fx, 16));
1848 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1849 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1850 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1851 const int offset3 = _mm_cvtsi128_si32(offset);
1852 const uint *topData = (
const uint *)(textureData);
1853 const __m128i tl = _mm_setr_epi32(topData[offset0], topData[offset1], topData[offset2], topData[offset3]);
1854 const __m128i tr = _mm_setr_epi32(topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]);
1855 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1856 const __m128i bl = _mm_setr_epi32(bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]);
1857 const __m128i br = _mm_setr_epi32(bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]);
1859 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1860 __m128i v_disty = _mm_srli_epi16(v_fy, 8);
1861 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fxy_r), 4);
1862 v_disty = _mm_srli_epi16(_mm_add_epi32(v_disty, v_fxy_r), 4);
1863 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1864 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1865 v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1866 v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1868 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1870 v_fx = _mm_add_epi32(v_fx, v_fdx);
1871 v_fy = _mm_add_epi32(v_fy, v_fdy);
1873 fx = _mm_cvtsi128_si32(v_fx);
1874 fy = _mm_cvtsi128_si32(v_fy);
1875#elif defined(__ARM_NEON__)
1876 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1877 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1878 const int16x8_t v_256 = vdupq_n_s16(256);
1879 int32x4_t v_fdx = vdupq_n_s32(fdx * 4);
1880 int32x4_t v_fdy = vdupq_n_s32(fdy * 4);
1882 const uchar *textureData = image.imageData;
1883 const qsizetype bytesPerLine = image.bytesPerLine;
1885 int32x4_t v_fx = vmovq_n_s32(fx);
1886 int32x4_t v_fy = vmovq_n_s32(fy);
1887 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1888 v_fy = vsetq_lane_s32(fy + fdy, v_fy, 1);
1889 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1890 v_fy = vsetq_lane_s32(fy + fdy * 2, v_fy, 2);
1891 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1892 v_fy = vsetq_lane_s32(fy + fdy * 3, v_fy, 3);
1894 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1895 const int32x4_t v_round = vdupq_n_s32(0x0800);
1898 uint32x4x2_t v_top = {};
1899 uint32x4x2_t v_bot = {};
1900 while (b < boundedEnd - 3) {
1901 int x1 = (fx >> 16);
1902 int y1 = (fy >> 16);
1903 fx += fdx; fy += fdy;
1904 const uchar *sl = textureData + bytesPerLine * y1;
1905 const uint *s1 =
reinterpret_cast<
const uint *>(sl);
1906 const uint *s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1907 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1908 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1911 fx += fdx; fy += fdy;
1912 sl = textureData + bytesPerLine * y1;
1913 s1 =
reinterpret_cast<
const uint *>(sl);
1914 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1915 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1916 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1919 fx += fdx; fy += fdy;
1920 sl = textureData + bytesPerLine * y1;
1921 s1 =
reinterpret_cast<
const uint *>(sl);
1922 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1923 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1924 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1927 fx += fdx; fy += fdy;
1928 sl = textureData + bytesPerLine * y1;
1929 s1 =
reinterpret_cast<
const uint *>(sl);
1930 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1931 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1932 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1934 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_round), 12);
1935 int32x4_t v_disty = vshrq_n_s32(vaddq_s32(vandq_s32(v_fy, v_ffff_mask), v_round), 12);
1936 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1937 v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
1938 int16x8_t v_disty_ = vshlq_n_s16(vreinterpretq_s16_s32(v_disty), 4);
1940 interpolate_4_pixels_16_neon(
1941 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1942 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1943 vreinterpretq_s16_s32(v_distx), vreinterpretq_s16_s32(v_disty),
1944 v_disty_, colorMask, invColorMask, v_256, b);
1946 v_fx = vaddq_s32(v_fx, v_fdx);
1947 v_fy = vaddq_s32(v_fy, v_fdy);
1949#elif defined(__loongarch_sx)
1950 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1951 const __m128i v_fdy = __lsx_vreplgr2vr_w(fdy*4);
1952 const __m128i v_fxy_r = __lsx_vreplgr2vr_w(0x8);
1953 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1954 __m128i v_fy = (__m128i)(v4i32){fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy};
1956 const uchar *textureData = image.imageData;
1957 const qsizetype bytesPerLine = image.bytesPerLine;
1958 const __m128i zero = __lsx_vldi(0);
1959 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
1960 const __m128i shuffleMask1 = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1961 const __m128i vbpl = __lsx_vshuf_h(shuffleMask, zero, __lsx_vinsgr2vr_w(zero, bytesPerLine/4, 0));
1963 while (b < boundedEnd - 3) {
1964 const __m128i vy = __lsx_vpickev_h(zero, __lsx_vsat_w(__lsx_vsrli_w(v_fy, 16), 15));
1966 __m128i offset = __lsx_vilvl_h(__lsx_vmuh_h(vy, vbpl), __lsx_vmul_h(vy, vbpl));
1967 offset = __lsx_vadd_w(offset, __lsx_vsrli_w(v_fx, 16));
1968 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1969 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1970 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1971 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1972 const uint *topData = (
const uint *)(textureData);
1973 const __m128i tl = (__m128i)(v4u32){topData[offset0], topData[offset1], topData[offset2], topData[offset3]};
1974 const __m128i tr = (__m128i)(v4u32){topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]};
1975 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1976 const __m128i bl = (__m128i)(v4u32){bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]};
1977 const __m128i br = (__m128i)(v4u32){bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]};
1979 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1980 __m128i v_disty = __lsx_vsrli_h(v_fy, 8);
1981 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fxy_r), 4);
1982 v_disty = __lsx_vsrli_h(__lsx_vadd_w(v_disty, v_fxy_r), 4);
1983 v_distx = __lsx_vshuf_h(shuffleMask1, zero, v_distx);
1984 v_disty = __lsx_vshuf_h(shuffleMask1, zero, v_disty);
1986 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1988 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1989 v_fy = __lsx_vadd_w(v_fy, v_fdy);
1991 fx = __lsx_vpickve2gr_w(v_fx, 0);
1992 fy = __lsx_vpickve2gr_w(v_fy, 0);
1994 while (b < boundedEnd) {
1998 const uint *s1 = (
const uint *)image.scanLine(y);
1999 const uint *s2 = (
const uint *)image.scanLine(y + 1);
2001 if (hasFastInterpolate4()) {
2002 int distx = (fx & 0x0000ffff) >> 8;
2003 int disty = (fy & 0x0000ffff) >> 8;
2004 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
2006 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2007 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2008 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx, disty);
2018 int x1 = (fx >> 16);
2020 int y1 = (fy >> 16);
2023 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2024 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2026 const uint *s1 = (
const uint *)image.scanLine(y1);
2027 const uint *s2 = (
const uint *)image.scanLine(y2);
2034 if (hasFastInterpolate4()) {
2035 int distx = (fx & 0x0000ffff) >> 8;
2036 int disty = (fy & 0x0000ffff) >> 8;
2037 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2039 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2040 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2041 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2053 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinear>,
2054 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinear>,
2055 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinear>,
2056 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinear>,
2057 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinear>
2060 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinearTiled>,
2061 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinearTiled>,
2062 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinearTiled>,
2063 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinearTiled>,
2064 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinearTiled>
2069static const uint *
QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer,
const Operator *,
2070 const QSpanData *data,
int y,
int x,
2073 const qreal cx = x + qreal(0.5);
2074 const qreal cy = y + qreal(0.5);
2075 constexpr int tiled = (blendType == BlendTransformedBilinearTiled) ? 1 : 0;
2077 uint *end = buffer + length;
2079 if (canUseFastMatrixPath(cx, cy, length, data)) {
2081 int fdx = (
int)(data->m11 * fixed_scale);
2082 int fdy = (
int)(data->m12 * fixed_scale);
2084 int fx =
int((data->m21 * cy
2085 + data->m11 * cx + data->dx) * fixed_scale);
2086 int fy =
int((data->m22 * cy
2087 + data->m12 * cx + data->dy) * fixed_scale);
2093 if (qAbs(fdx) <= fixed_scale) {
2095 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2096 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2098 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2099 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2101 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2102 }
else if (qAbs(data->m22) < qreal(1./8.)) {
2104 bilinearFastTransformHelperARGB32PM[tiled][UpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2107 bilinearFastTransformHelperARGB32PM[tiled][DownscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2110 if (qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.) ) {
2112 bilinearFastTransformHelperARGB32PM[tiled][RotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2115 bilinearFastTransformHelperARGB32PM[tiled][FastRotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2119 const QTextureData &image = data->texture;
2121 const qreal fdx = data->m11;
2122 const qreal fdy = data->m12;
2123 const qreal fdw = data->m13;
2125 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2126 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2127 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2130 const qreal iw = fw == 0 ? 1 : 1 / fw;
2131 const qreal px = fx * iw - qreal(0.5);
2132 const qreal py = fy * iw - qreal(0.5);
2134 int x1 =
int(px) - (px < 0);
2136 int y1 =
int(py) - (py < 0);
2139 int distx =
int((px - x1) * 256);
2140 int disty =
int((py - y1) * 256);
2142 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2143 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2145 const uint *s1 = (
const uint *)data->texture.scanLine(y1);
2146 const uint *s2 = (
const uint *)data->texture.scanLine(y2);
2153 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2170static void QT_FASTCALL fetchTransformedBilinear_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
2171 int &fx,
int &fy,
int fdx,
int )
2173 const QPixelLayout *layout = &qPixelLayouts[image.format];
2174 const QList<QRgb> *clut = image.colorTable;
2175 const FetchAndConvertPixelsFunc fetch = layout->fetchToARGB32PM;
2177 int y1 = (fy >> 16);
2179 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2180 const uchar *s1 = image.scanLine(y1);
2181 const uchar *s2 = image.scanLine(y2);
2183 const int disty = (fy & 0x0000ffff) >> 8;
2184 const int idisty = 256 - disty;
2185 const int length = end - b;
2188 const int adjust = (fdx < 0) ? fdx * length : 0;
2189 const int offset = (fx + adjust) >> 16;
2192 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
2193 uint *buf1 = intermediate.buffer_rb;
2194 uint *buf2 = intermediate.buffer_ag;
2198 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
2199 Q_ASSERT(count <= BufferSize + 2);
2201 if (blendType == BlendTransformedBilinearTiled) {
2205 int len1 = qMin(count, image.width - x);
2206 int len2 = qMin(x, count - len1);
2208 ptr1 = fetch(buf1, s1, x, len1, clut,
nullptr);
2209 ptr2 = fetch(buf2, s2, x, len1, clut,
nullptr);
2210 for (
int i = 0; i < len1; ++i) {
2213 buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2214 buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2218 ptr1 = fetch(buf1 + len1, s1, 0, len2, clut,
nullptr);
2219 ptr2 = fetch(buf2 + len1, s2, 0, len2, clut,
nullptr);
2220 for (
int i = 0; i < len2; ++i) {
2223 buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2224 buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2228 for (
int i = image.width; i < count; ++i) {
2229 buf1[i] = buf1[i - image.width];
2230 buf2[i] = buf2[i - image.width];
2233 int start = qMax(x, image.x1);
2234 int end = qMin(x + count, image.x2);
2235 int len = qMax(1, end - start);
2236 int leading = start - x;
2238 ptr1 = fetch(buf1 + leading, s1, start, len, clut,
nullptr);
2239 ptr2 = fetch(buf2 + leading, s2, start, len, clut,
nullptr);
2241 for (
int i = 0; i < len; ++i) {
2244 buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2245 buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2248 for (
int i = 0; i < leading; ++i) {
2249 buf1[i] = buf1[leading];
2250 buf2[i] = buf2[leading];
2252 for (
int i = leading + len; i < count; ++i) {
2253 buf1[i] = buf1[i - 1];
2254 buf2[i] = buf2[i - 1];
2259 intermediate_adder(b, end, intermediate, offset, fx, fdx);
2264static void QT_FASTCALL fetchTransformedBilinear_fetcher(T *buf1, T *buf2,
const int len,
const QTextureData &image,
2265 int fx,
int fy,
const int fdx,
const int fdy)
2267 const QPixelLayout &layout = qPixelLayouts[image.format];
2268 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2270 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2272 Q_ASSERT(layout.bpp == bpp || (layout.bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
2273 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2275 int y1 = (fy >> 16);
2277 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2278 const uchar *s1 = image.scanLine(y1);
2279 const uchar *s2 = image.scanLine(y2);
2282 if (blendType == BlendTransformedBilinear) {
2283 for (; i < len; ++i) {
2284 int x1 = (fx >> 16);
2286 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2289 if constexpr (useFetch) {
2290 buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
2291 buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
2293 buf1[i * 2 + 0] = buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x1];
2294 buf2[i * 2 + 0] = buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x1];
2300 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2302 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2304 for (; i < fastLen; ++i) {
2306 if constexpr (useFetch) {
2307 buf1[i * 2 + 0] = fetch1(s1, x);
2308 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2309 buf2[i * 2 + 0] = fetch1(s2, x);
2310 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2312 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2313 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2314 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2315 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2321 for (; i < len; ++i) {
2322 int x1 = (fx >> 16);
2324 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2325 if constexpr (useFetch) {
2326 buf1[i * 2 + 0] = fetch1(s1, x1);
2327 buf1[i * 2 + 1] = fetch1(s1, x2);
2328 buf2[i * 2 + 0] = fetch1(s2, x1);
2329 buf2[i * 2 + 1] = fetch1(s2, x2);
2331 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2332 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2333 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2334 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2340 if (blendType == BlendTransformedBilinear) {
2341 for (; i < len; ++i) {
2342 int x1 = (fx >> 16);
2344 int y1 = (fy >> 16);
2346 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2347 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2348 if (x1 != x2 && y1 != y2)
2350 const uchar *s1 = image.scanLine(y1);
2351 const uchar *s2 = image.scanLine(y2);
2352 if constexpr (useFetch) {
2353 buf1[i * 2 + 0] = fetch1(s1, x1);
2354 buf1[i * 2 + 1] = fetch1(s1, x2);
2355 buf2[i * 2 + 0] = fetch1(s2, x1);
2356 buf2[i * 2 + 1] = fetch1(s2, x2);
2358 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2359 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2360 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2361 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2368 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2370 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2372 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
2374 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
2376 for (; i < fastLen; ++i) {
2379 const uchar *s1 = image.scanLine(y);
2380 const uchar *s2 = s1 + image.bytesPerLine;
2381 if constexpr (useFetch) {
2382 buf1[i * 2 + 0] = fetch1(s1, x);
2383 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2384 buf2[i * 2 + 0] = fetch1(s2, x);
2385 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2387 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2388 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2389 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2390 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2397 for (; i < len; ++i) {
2398 int x1 = (fx >> 16);
2400 int y1 = (fy >> 16);
2402 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2403 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2405 const uchar *s1 = image.scanLine(y1);
2406 const uchar *s2 = image.scanLine(y2);
2407 if constexpr (useFetch) {
2408 buf1[i * 2 + 0] = fetch1(s1, x1);
2409 buf1[i * 2 + 1] = fetch1(s1, x2);
2410 buf2[i * 2 + 0] = fetch1(s2, x1);
2411 buf2[i * 2 + 1] = fetch1(s2, x2);
2413 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2414 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2415 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2416 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2425static void QT_FASTCALL fetchTransformedBilinear_slow_fetcher(T *buf1, T *buf2, ushort *distxs, ushort *distys,
2426 const int len,
const QTextureData &image,
2427 qreal &fx, qreal &fy, qreal &fw,
2428 const qreal fdx,
const qreal fdy,
const qreal fdw)
2430 const QPixelLayout &layout = qPixelLayouts[image.format];
2431 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2433 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2435 Q_ASSERT(layout.bpp == bpp);
2437 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2439 for (
int i = 0; i < len; ++i) {
2440 const qreal iw = fw == 0 ? 16384 : 1 / fw;
2441 const qreal px = fx * iw - qreal(0.5);
2442 const qreal py = fy * iw - qreal(0.5);
2444 int x1 = qFloor(px);
2446 int y1 = qFloor(py);
2449 distxs[i] = ushort((px - x1) * (1<<16));
2450 distys[i] = ushort((py - y1) * (1<<16));
2452 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2453 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2455 const uchar *s1 = image.scanLine(y1);
2456 const uchar *s2 = image.scanLine(y2);
2457 if constexpr (useFetch) {
2458 buf1[i * 2 + 0] = fetch1(s1, x1);
2459 buf1[i * 2 + 1] = fetch1(s1, x2);
2460 buf2[i * 2 + 0] = fetch1(s2, x1);
2461 buf2[i * 2 + 1] = fetch1(s2, x2);
2463 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2464 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2465 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2466 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2478 const QSpanData *data,
int y,
int x,
int length)
2480 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2481 const QList<QRgb> *clut = data->texture.colorTable;
2482 Q_ASSERT(bpp == QPixelLayout::BPPNone || layout->bpp == bpp);
2484 const qreal cx = x + qreal(0.5);
2485 const qreal cy = y + qreal(0.5);
2487 if (canUseFastMatrixPath(cx, cy, length, data)) {
2489 int fdx = (
int)(data->m11 * fixed_scale);
2490 int fdy = (
int)(data->m12 * fixed_scale);
2492 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2493 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2499 if (qAbs(fdx) <= fixed_scale) {
2500 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
2501 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2502 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2503 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2505 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2507 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2509 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2510 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2513 int len = qMin(length, BufferSize / 2);
2514 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
2515 layout->convertToARGB32PM(buf1, len * 2, clut);
2516 layout->convertToARGB32PM(buf2, len * 2, clut);
2518 if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) {
2519 int disty = (fy & 0x0000ffff) >> 8;
2520 for (
int i = 0; i < len; ++i) {
2521 int distx = (fx & 0x0000ffff) >> 8;
2522 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2526 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2527 for (
int i = 0; i < len; ++i) {
2528 uint tl = buf1[i * 2 + 0];
2529 uint tr = buf1[i * 2 + 1];
2530 uint bl = buf2[i * 2 + 0];
2531 uint br = buf2[i * 2 + 1];
2532 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2533 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2542 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2544 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2545 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2548 int len = qMin(length, BufferSize / 2);
2549 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2550 layout->convertToARGB32PM(buf1, len * 2, clut);
2551 layout->convertToARGB32PM(buf2, len * 2, clut);
2553 if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
2555 for (
int i = 0; i < len; ++i) {
2556 int distx = (fx & 0x0000ffff) >> 8;
2557 int disty = (fy & 0x0000ffff) >> 8;
2559 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2565 for (
int i = 0; i < len; ++i) {
2566 uint tl = buf1[i * 2 + 0];
2567 uint tr = buf1[i * 2 + 1];
2568 uint bl = buf2[i * 2 + 0];
2569 uint br = buf2[i * 2 + 1];
2571 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2572 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2574 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2585 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType,bpp,uint>;
2587 const qreal fdx = data->m11;
2588 const qreal fdy = data->m12;
2589 const qreal fdw = data->m13;
2591 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2592 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2593 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2595 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2596 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2599 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2600 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2603 const int len = qMin(length, BufferSize / 2);
2604 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2606 layout->convertToARGB32PM(buf1, len * 2, clut);
2607 layout->convertToARGB32PM(buf2, len * 2, clut);
2609 for (
int i = 0; i < len; ++i) {
2610 const int distx = distxs[i] >> 8;
2611 const int disty = distys[i] >> 8;
2613 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2623#if QT_CONFIG(raster_64bit)
2624template<TextureBlendType blendType>
2625static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer,
const QSpanData *data,
2626 int y,
int x,
int length)
2628 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2629 const auto *clut = data->texture.colorTable;
2630 const auto convert = layout->convertToRGBA64PM;
2632 const qreal cx = x + qreal(0.5);
2633 const qreal cy = y + qreal(0.5);
2635 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
2636 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
2637 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2638 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2639 QRgba64 *b = buffer;
2641 if (canUseFastMatrixPath(cx, cy, length, data)) {
2643 const int fdx = (
int)(data->m11 * fixed_scale);
2644 const int fdy = (
int)(data->m12 * fixed_scale);
2646 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2647 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2652 const auto fetcher =
2653 (layout->bpp == QPixelLayout::BPP32)
2654 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
2655 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2659 const int len = qMin(length, BufferSize / 2);
2660 const int disty = (fy & 0x0000ffff);
2661#if defined(__SSE2__)
2662 const __m128i vdy = _mm_set1_epi16(disty);
2663 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2665 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2667 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2669 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2671 for (
int i = 0; i < len; ++i) {
2672 const int distx = (fx & 0x0000ffff);
2673#if defined(__SSE2__)
2674 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2676 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2677 vt = _mm_mulhi_epu16(vt, vidy);
2678 vb = _mm_mulhi_epu16(vb, vdy);
2679 vt = _mm_add_epi16(vt, vb);
2682 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2683 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2684 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2685 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2687 _mm_storel_epi64((__m128i*)(b+i), vt);
2689 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2698 const int len = qMin(length, BufferSize / 2);
2700 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2702 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2703 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2705 for (
int i = 0; i < len; ++i) {
2706 const int distx = (fx & 0x0000ffff);
2707 const int disty = (fy & 0x0000ffff);
2708 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2718 const auto fetcher =
2719 (layout->bpp == QPixelLayout::BPP32)
2720 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
2721 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2723 const qreal fdx = data->m11;
2724 const qreal fdy = data->m12;
2725 const qreal fdw = data->m13;
2727 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2728 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2729 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2731 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2732 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2735 const int len = qMin(length, BufferSize / 2);
2736 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2738 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2739 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2741 for (
int i = 0; i < len; ++i) {
2742 const int distx = distxs[i];
2743 const int disty = distys[i];
2744 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2754template<TextureBlendType blendType>
2755static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buffer,
const QSpanData *data,
2756 int y,
int x,
int length)
2758 const auto convert = convert64ToRGBA64PM[data->texture.format];
2760 const qreal cx = x + qreal(0.5);
2761 const qreal cy = y + qreal(0.5);
2763 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2764 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2765 QRgba64 *end = buffer + length;
2766 QRgba64 *b = buffer;
2768 if (canUseFastMatrixPath(cx, cy, length, data)) {
2770 const int fdx = (
int)(data->m11 * fixed_scale);
2771 const int fdy = (
int)(data->m12 * fixed_scale);
2773 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2774 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2778 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2782 int len = qMin(length, BufferSize / 2);
2783 int disty = (fy & 0x0000ffff);
2784#if defined(__SSE2__)
2785 const __m128i vdy = _mm_set1_epi16(disty);
2786 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2788 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2790 convert(buf1, len * 2);
2792 convert(buf2, len * 2);
2794 for (
int i = 0; i < len; ++i) {
2795 int distx = (fx & 0x0000ffff);
2796#if defined(__SSE2__)
2797 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2799 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2800 vt = _mm_mulhi_epu16(vt, vidy);
2801 vb = _mm_mulhi_epu16(vb, vdy);
2802 vt = _mm_add_epi16(vt, vb);
2805 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2806 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2807 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2808 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2810 _mm_storel_epi64((__m128i*)(b+i), vt);
2812 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2821 int len = qMin(length, BufferSize / 2);
2823 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2825 convert(buf1, len * 2);
2826 convert(buf2, len * 2);
2828 for (
int i = 0; i < len; ++i) {
2829 int distx = (fx & 0x0000ffff);
2830 int disty = (fy & 0x0000ffff);
2831 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2841 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2843 const qreal fdx = data->m11;
2844 const qreal fdy = data->m12;
2845 const qreal fdw = data->m13;
2847 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2848 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2849 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2851 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2852 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2855 const int len = qMin(length, BufferSize / 2);
2856 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2858 convert(buf1, len * 2);
2859 convert(buf2, len * 2);
2861 for (
int i = 0; i < len; ++i) {
2862 const int distx = distxs[i];
2863 const int disty = distys[i];
2864 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2874template<TextureBlendType blendType>
2875static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_f32x4(QRgba64 *buffer,
const QSpanData *data,
2876 int y,
int x,
int length)
2878 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2879 const auto *clut = data->texture.colorTable;
2880 const auto convert = layout->fetchToRGBA64PM;
2882 const qreal cx = x + qreal(0.5);
2883 const qreal cy = y + qreal(0.5);
2885 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf1[BufferSize];
2886 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf2[BufferSize];
2887 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2888 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2889 QRgba64 *b = buffer;
2891 if (canUseFastMatrixPath(cx, cy, length, data)) {
2893 const int fdx = (
int)(data->m11 * fixed_scale);
2894 const int fdy = (
int)(data->m12 * fixed_scale);
2896 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2897 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2902 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2904 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
2906 const int len = qMin(length, BufferSize / 2);
2908 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2910 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2912 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2914 for (
int i = 0; i < len; ++i) {
2915 const int distx = (fx & 0x0000ffff);
2916 const int disty = (fy & 0x0000ffff);
2917 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2926 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2928 const qreal fdx = data->m11;
2929 const qreal fdy = data->m12;
2930 const qreal fdw = data->m13;
2932 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2933 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2934 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2936 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2937 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2940 const int len = qMin(length, BufferSize / 2);
2941 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2943 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2944 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2946 for (
int i = 0; i < len; ++i) {
2947 const int distx = distxs[i];
2948 const int disty = distys[i];
2949 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2959template<TextureBlendType blendType>
2960static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer,
const Operator *,
2961 const QSpanData *data,
int y,
int x,
int length)
2963 switch (qPixelLayouts[data->texture.format].bpp) {
2964 case QPixelLayout::BPP64:
2965 case QPixelLayout::BPP16FPx4:
2966 return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
2967 case QPixelLayout::BPP32FPx4:
2968 return fetchTransformedBilinear64_f32x4<blendType>(buffer, data, y, x, length);
2970 return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
2975#if QT_CONFIG(raster_fp)
2976static void interpolate_simple_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2980 for (
int i = 0; i < len; ++i) {
2981 const int distx = (fx & 0x0000ffff);
2982 const int disty = (fy & 0x0000ffff);
2983 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, distx, disty);
2989static void interpolate_perspective_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2990 unsigned short *distxs,
2991 unsigned short *distys)
2993 for (
int i = 0; i < len; ++i) {
2994 const int dx = distxs[i];
2995 const int dy = distys[i];
2996 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, dx, dy);
3000template<TextureBlendType blendType>
3001static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint32(QRgbaFloat32 *buffer,
const QSpanData *data,
3002 int y,
int x,
int length)
3004 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
3005 const auto *clut = data->texture.colorTable;
3006 const auto convert = qConvertToRGBA32F[data->texture.format];
3008 const qreal cx = x + qreal(0.5);
3009 const qreal cy = y + qreal(0.5);
3011 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
3012 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
3013 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3014 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3015 QRgbaFloat32 *b = buffer;
3017 if (canUseFastMatrixPath(cx, cy, length, data)) {
3019 const int fdx = (
int)(data->m11 * fixed_scale);
3020 const int fdy = (
int)(data->m12 * fixed_scale);
3022 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3023 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3028 const auto fetcher =
3029 (layout->bpp == QPixelLayout::BPP32)
3030 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
3031 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3033 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3035 const int len = qMin(length, BufferSize / 2);
3036 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3038 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3040 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3042 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3048 const auto fetcher =
3049 (layout->bpp == QPixelLayout::BPP32)
3050 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
3051 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3053 const qreal fdx = data->m11;
3054 const qreal fdy = data->m12;
3055 const qreal fdw = data->m13;
3056 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3057 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3058 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3059 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3060 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3063 const int len = qMin(length, BufferSize / 2);
3064 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3066 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3067 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3069 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3078template<TextureBlendType blendType>
3079static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint64(QRgbaFloat32 *buffer,
const QSpanData *data,
3080 int y,
int x,
int length)
3082 const auto convert = convert64ToRGBA32F[data->texture.format];
3084 const qreal cx = x + qreal(0.5);
3085 const qreal cy = y + qreal(0.5);
3087 Q_DECL_UNINITIALIZED quint64 sbuf1[BufferSize] ;
3088 Q_DECL_UNINITIALIZED quint64 sbuf2[BufferSize];
3089 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3090 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3091 QRgbaFloat32 *b = buffer;
3093 if (canUseFastMatrixPath(cx, cy, length, data)) {
3095 const int fdx = (
int)(data->m11 * fixed_scale);
3096 const int fdy = (
int)(data->m12 * fixed_scale);
3098 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3099 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3103 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3105 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3107 const int len = qMin(length, BufferSize / 2);
3108 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3110 convert(buf1, sbuf1, len * 2);
3112 convert(buf2, sbuf2, len * 2);
3114 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3120 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3122 const qreal fdx = data->m11;
3123 const qreal fdy = data->m12;
3124 const qreal fdw = data->m13;
3126 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3127 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3128 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3130 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3131 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3134 const int len = qMin(length, BufferSize / 2);
3135 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3137 convert(buf1, sbuf1, len * 2);
3138 convert(buf2, sbuf2, len * 2);
3140 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3149template<TextureBlendType blendType>
3150static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const QSpanData *data,
3151 int y,
int x,
int length)
3153 const auto convert = data->rasterBuffer->format == QImage::Format_RGBA32FPx4 ? convertRGBA32FToRGBA32FPM
3154 : convertRGBA32FToRGBA32F;
3156 const qreal cx = x + qreal(0.5);
3157 const qreal cy = y + qreal(0.5);
3159 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3160 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3161 QRgbaFloat32 *b = buffer;
3163 if (canUseFastMatrixPath(cx, cy, length, data)) {
3165 const int fdx = (
int)(data->m11 * fixed_scale);
3166 const int fdy = (
int)(data->m12 * fixed_scale);
3168 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3169 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3173 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3175 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3177 const int len = qMin(length, BufferSize / 2);
3178 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
3180 convert(buf1, len * 2);
3182 convert(buf2, len * 2);
3184 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3190 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3192 const qreal fdx = data->m11;
3193 const qreal fdy = data->m12;
3194 const qreal fdw = data->m13;
3196 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3197 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3198 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3200 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3201 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3204 const int len = qMin(length, BufferSize / 2);
3205 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3207 convert(buf1, len * 2);
3208 convert(buf2, len * 2);
3210 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3219template<TextureBlendType blendType>
3220static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const Operator *,
3221 const QSpanData *data,
int y,
int x,
int length)
3223 switch (qPixelLayouts[data->texture.format].bpp) {
3224 case QPixelLayout::BPP64:
3225 case QPixelLayout::BPP16FPx4:
3226 return fetchTransformedBilinearFP_uint64<blendType>(buffer, data, y, x, length);
3227 case QPixelLayout::BPP32FPx4:
3228 return fetchTransformedBilinearFP<blendType>(buffer, data, y, x, length);
3230 return fetchTransformedBilinearFP_uint32<blendType>(buffer, data, y, x, length);
3241 fetchUntransformedARGB32PM,
3243 fetchUntransformedARGB32PM,
3244 fetchUntransformedRGB16,
3276static_assert(std::size(sourceFetchUntransformed) == QImage::NImageFormats);
3281 fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>,
3282 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPPNone>,
3283 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPPNone>,
3284 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone>
3287static_assert(std::size(sourceFetchGeneric) == NBlendTypes);
3290 fetchUntransformedARGB32PM,
3291 fetchUntransformedARGB32PM,
3292 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3293 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3294 fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>,
3295 fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>
3298static_assert(std::size(sourceFetchARGB32PM) == NBlendTypes);
3303 fetchTransformed<BlendTransformed, QPixelLayout::BPP16>,
3304 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP16>,
3305 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP16>,
3306 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16>
3309static_assert(std::size(sourceFetchAny16) == NBlendTypes);
3314 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3315 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3316 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP32>,
3317 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32>
3320static_assert(std::size(sourceFetchAny32) == NBlendTypes);
3324 if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
3325 return sourceFetchARGB32PM[blendType];
3327 return sourceFetchUntransformed[format];
3328 if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
3329 return sourceFetchAny16[blendType];
3330 if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
3331 return sourceFetchAny32[blendType];
3332 return sourceFetchGeneric[blendType];
3335#if QT_CONFIG(raster_64bit)
3336static const SourceFetchProc64 sourceFetchGeneric64[] = {
3337 fetchUntransformed64,
3338 fetchUntransformed64,
3339 fetchTransformed64<BlendTransformed>,
3340 fetchTransformed64<BlendTransformedTiled>,
3341 fetchTransformedBilinear64<BlendTransformedBilinear>,
3342 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3345static_assert(std::size(sourceFetchGeneric64) == NBlendTypes);
3347static const SourceFetchProc64 sourceFetchRGBA64PM[] = {
3348 fetchUntransformedRGBA64PM,
3349 fetchUntransformedRGBA64PM,
3350 fetchTransformed64<BlendTransformed>,
3351 fetchTransformed64<BlendTransformedTiled>,
3352 fetchTransformedBilinear64<BlendTransformedBilinear>,
3353 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3356static_assert(std::size(sourceFetchRGBA64PM) == NBlendTypes);
3358static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
3360 if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
3361 return sourceFetchRGBA64PM[blendType];
3362 return sourceFetchGeneric64[blendType];
3366#if QT_CONFIG(raster_fp)
3367static const SourceFetchProcFP sourceFetchGenericFP[] = {
3368 fetchUntransformedFP,
3369 fetchUntransformedFP,
3370 fetchTransformedFP<BlendTransformed>,
3371 fetchTransformedFP<BlendTransformedTiled>,
3372 fetchTransformedBilinearFP<BlendTransformedBilinear>,
3373 fetchTransformedBilinearFP<BlendTransformedBilinearTiled>
3376static_assert(std::size(sourceFetchGenericFP) == NBlendTypes);
3378static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format )
3380 return sourceFetchGenericFP[blendType];
3391 return data->colorTable32[qt_gradient_clamp(data, ipos)];
3394#if QT_CONFIG(raster_64bit)
3395static const QRgba64& qt_gradient_pixel64_fixed(
const QGradientData *data,
int fixed_pos)
3397 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3398 return data->colorTable64[qt_gradient_clamp(data, ipos)];
3402#if QT_CONFIG(raster_fp)
3403static inline QRgbaFloat32 qt_gradient_pixelFP(
const QGradientData *data, qreal pos)
3405 int ipos =
int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
3406 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3407 return QRgbaFloat32::fromRgba64(rgb64.red(),rgb64.green(), rgb64.blue(), rgb64.alpha());
3410static inline QRgbaFloat32 qt_gradient_pixelFP_fixed(
const QGradientData *data,
int fixed_pos)
3412 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3413 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3414 return QRgbaFloat32::fromRgba64(rgb64.red(), rgb64.green(), rgb64.blue(), rgb64.alpha());
3418static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v,
const QSpanData *data)
3420 v->dx = data->gradient.linear.end.x - data->gradient.linear.origin.x;
3421 v->dy = data->gradient.linear.end.y - data->gradient.linear.origin.y;
3422 v->l = v->dx * v->dx + v->dy * v->dy;
3427 v->off = -v->dx * data->gradient.linear.origin.x - v->dy * data->gradient.linear.origin.y;
3438 Q_ASSERT(
std::isfinite(v));
3439 return qt_gradient_pixel(&gradient, v);
3447 qt_memfill32(buffer, fill, length);
3451#if QT_CONFIG(raster_64bit)
3455 typedef QRgba64 Type;
3456 static Type null() {
return QRgba64::fromRgba64(0); }
3457 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3459 Q_ASSERT(std::isfinite(v));
3460 return qt_gradient_pixel64(&gradient, v);
3462 static Type fetchSingle(
const QGradientData& gradient,
int v)
3464 return qt_gradient_pixel64_fixed(&gradient, v);
3466 static void memfill(Type *buffer, Type fill,
int length)
3468 qt_memfill64((quint64*)buffer, fill, length);
3473#if QT_CONFIG(raster_fp)
3477 typedef QRgbaFloat32 Type;
3478 static Type null() {
return QRgbaFloat32::fromRgba64(0,0,0,0); }
3479 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3481 Q_ASSERT(std::isfinite(v));
3482 return qt_gradient_pixelFP(&gradient, v);
3484 static Type fetchSingle(
const QGradientData& gradient,
int v)
3486 return qt_gradient_pixelFP_fixed(&gradient, v);
3488 static void memfill(Type *buffer, Type fill,
int length)
3491 memcpy(&fillCopy, &fill,
sizeof(quint64));
3492 qt_memfill64((quint64*)buffer, fillCopy, length);
3499 BlendType *buffer,
const Operator *op,
const QSpanData *data,
3500 int y,
int x,
int length)
3502 const BlendType *b = buffer;
3507 if (op->linear.l == 0) {
3510 rx = data->m21 * (y + qreal(0.5)) + data->m11 * (x + qreal(0.5)) + data->dx;
3511 ry = data->m22 * (y + qreal(0.5)) + data->m12 * (x + qreal(0.5)) + data->dy;
3512 t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off;
3513 inc = op->linear.dx * data->m11 + op->linear.dy * data->m12;
3514 affine = !data->m13 && !data->m23;
3522 const BlendType *end = buffer + length;
3524 if (inc > qreal(-1e-5) && inc < qreal(1e-5)) {
3526 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient,
int(t *
FIXPT_SIZE)), length);
3528 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient, t /
GRADIENT_STOPTABLE_SIZE), length);
3534 while (buffer < end) {
3535 *buffer = GradientBase::fetchSingle(data->gradient, t_fixed);
3536 t_fixed += inc_fixed;
3541 while (buffer < end) {
3549 qreal rw = data->m23 * (y + qreal(0.5)) + data->m13 * (x + qreal(0.5)) + data->m33;
3550 while (buffer < end) {
3553 t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off;
3555 *buffer = GradientBase::fetchSingle(data->gradient, t);
3569static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer,
const Operator *op,
const QSpanData *data,
3570 int y,
int x,
int length)
3572 return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
3575#if QT_CONFIG(raster_64bit)
3576static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3577 int y,
int x,
int length)
3579 return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
3582#if QT_CONFIG(raster_fp)
3583static const QRgbaFloat32 * QT_FASTCALL qt_fetch_linear_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3584 int y,
int x,
int length)
3586 return qt_fetch_linear_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, op, data, y, x, length);
3590static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v,
const QSpanData *data)
3592 v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x;
3593 v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y;
3595 v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius;
3596 v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius;
3598 v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy;
3600 v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0;
3603template <
class GradientBase>
3610 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
3612 if (op->radial.extended) {
3613 while (buffer < end) {
3614 BlendType result = GradientBase::null();
3616 qreal w = qSqrt(det) - b;
3617 if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0)
3618 result = GradientBase::fetchSingle(data->gradient, w);
3624 delta_det += delta_delta_det;
3630 while (buffer < end) {
3631 BlendType result = GradientBase::null();
3633 qreal w = qSqrt(det) - b;
3634 result = GradientBase::fetchSingle(data->gradient, w);
3640 delta_det += delta_delta_det;
3647const uint *
QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer,
const Operator *op,
const QSpanData *data,
3648 int y,
int x,
int length)
3650 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase32>, uint>(buffer, op, data, y, x, length);
3655#if QT_CONFIG(raster_64bit)
3656const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3657 int y,
int x,
int length)
3659 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
3663#if QT_CONFIG(raster_fp)
3664static const QRgbaFloat32 * QT_FASTCALL qt_fetch_radial_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3665 int y,
int x,
int length)
3667 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBaseFP>, QRgbaFloat32>(buffer, op, data, y, x, length);
3673 BlendType *buffer,
const QSpanData *data,
3674 int y,
int x,
int length)
3676 const BlendType *b = buffer;
3677 qreal rx = data->m21 * (y + qreal(0.5))
3678 + data->dx + data->m11 * (x + qreal(0.5));
3679 qreal ry = data->m22 * (y + qreal(0.5))
3680 + data->dy + data->m12 * (x + qreal(0.5));
3681 bool affine = !data->m13 && !data->m23;
3683 const qreal inv2pi =
M_1_PI / 2.0;
3685 const BlendType *end = buffer + length;
3687 rx -= data->gradient.conical.center.x;
3688 ry -= data->gradient.conical.center.y;
3689 while (buffer < end) {
3690 qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
3692 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3699 qreal rw = data->m23 * (y + qreal(0.5))
3700 + data->m33 + data->m13 * (x + qreal(0.5));
3703 while (buffer < end) {
3704 qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
3705 rx/rw - data->gradient.conical.center.y)
3706 + data->gradient.conical.angle;
3708 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3722static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer,
const Operator *,
const QSpanData *data,
3723 int y,
int x,
int length)
3725 return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
3728#if QT_CONFIG(raster_64bit)
3729static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
3730 int y,
int x,
int length)
3732 return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
3736#if QT_CONFIG(raster_fp)
3737static const QRgbaFloat32 * QT_FASTCALL qt_fetch_conical_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
3738 int y,
int x,
int length)
3740 return qt_fetch_conical_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, data, y, x, length);
3749#if QT_CONFIG(raster_64bit)
3750static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
3752#if QT_CONFIG(raster_fp)
3753static const CompositionFunctionSolidFP *functionForModeSolidFP = qt_functionForModeSolidFP_C;
3761#if QT_CONFIG(raster_64bit)
3762static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
3764#if QT_CONFIG(raster_fp)
3765static const CompositionFunctionFP *functionForModeFP = qt_functionForModeFP_C;
3773 else if (data->txop <= QTransform::TxTranslate)
3794 bool solidSource =
false;
3795 switch(data->type) {
3797 solidSource = data->solidColor.alphaF() >= 1.0f;
3799 op.srcFetch =
nullptr;
3800 op.srcFetch64 =
nullptr;
3801 op.srcFetchFP =
nullptr;
3804 solidSource = !data->gradient.alphaColor;
3805 getLinearGradientValues(&op.linear, data);
3806 op.srcFetch = qt_fetch_linear_gradient;
3807#if QT_CONFIG(raster_64bit)
3808 op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
3810#if QT_CONFIG(raster_fp)
3811 op.srcFetchFP = qt_fetch_linear_gradient_rgbfp;
3815 solidSource = !data->gradient.alphaColor;
3816 getRadialGradientValues(&op.radial, data);
3817 op.srcFetch = qt_fetch_radial_gradient;
3818#if QT_CONFIG(raster_64bit)
3819 op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
3821#if QT_CONFIG(raster_fp)
3822 op.srcFetchFP = qt_fetch_radial_gradient_rgbfp;
3826 solidSource = !data->gradient.alphaColor;
3828 op.srcFetch = qt_fetch_conical_gradient;
3829#if QT_CONFIG(raster_64bit)
3830 op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
3832#if QT_CONFIG(raster_fp)
3833 op.srcFetchFP = qt_fetch_conical_gradient_rgbfp;
3837 solidSource = !data->texture.hasAlpha;
3839 op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
3840#if QT_CONFIG(raster_64bit)
3841 op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);
3843#if QT_CONFIG(raster_fp)
3844 op.srcFetchFP = getSourceFetchFP(getBlendType(data), data->texture.format);
3851#if !QT_CONFIG(raster_64bit)
3852 op.srcFetch64 =
nullptr;
3854#if !QT_CONFIG(raster_fp)
3855 op.srcFetchFP =
nullptr;
3859 if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
3860 op.mode = QPainter::CompositionMode_Source;
3863#if QT_CONFIG(raster_64bit)
3864 op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
3866 op.destFetch64 =
nullptr;
3868#if QT_CONFIG(raster_fp)
3869 op.destFetchFP = destFetchProcFP[data->rasterBuffer->format];
3871 op.destFetchFP =
nullptr;
3873 if (op.mode == QPainter::CompositionMode_Source &&
3874 (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
3875 const QT_FT_Span *lastSpan = spans + spanCount;
3876 bool alphaSpans =
false;
3877 while (spans < lastSpan) {
3878 if (spans->coverage != 255) {
3884 if (!alphaSpans && spanCount > 0) {
3887 if (op.destFetch != destFetchARGB32P)
3888 op.destFetch = destFetchUndefined;
3889#if QT_CONFIG(raster_64bit)
3890 if (op.destFetch64 != destFetchRGB64)
3891 op.destFetch64 = destFetch64Undefined;
3893#if QT_CONFIG(raster_fp)
3894 if (op.destFetchFP != destFetchRGBFP)
3895 op.destFetchFP = destFetchFPUndefined;
3901 op.funcSolid = functionForModeSolid[op.mode];
3902 op.func = functionForMode[op.mode];
3903#if QT_CONFIG(raster_64bit)
3904 op.destStore64 = destStoreProc64[data->rasterBuffer->format];
3905 op.funcSolid64 = functionForModeSolid64[op.mode];
3906 op.func64 = functionForMode64[op.mode];
3908 if (data->rasterBuffer->format == QImage::Format_RGBX64 && solidSource)
3909 op.destStore64 =
nullptr;
3911 op.destStore64 =
nullptr;
3912 op.funcSolid64 =
nullptr;
3913 op.func64 =
nullptr;
3915#if QT_CONFIG(raster_fp)
3916 op.destStoreFP = destStoreFP;
3917 op.funcSolidFP = functionForModeSolidFP[op.mode];
3918 op.funcFP = functionForModeFP[op.mode];
3920 op.destStoreFP =
nullptr;
3921 op.funcSolidFP =
nullptr;
3922 op.funcFP =
nullptr;
3931 case QPixelLayout::BPP32FPx4: {
3933 qt_memfill_template(dest + 1, dest[0], length - 1);
3936 case QPixelLayout::BPP16FPx4:
3937 case QPixelLayout::BPP64: {
3938 quint64 *dest =
reinterpret_cast<quint64 *>(rasterBuffer->scanLine(y)) + x;
3939 qt_memfill_template(dest + 1, dest[0], length - 1);
3942 case QPixelLayout::BPP32: {
3943 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(y)) + x;
3944 qt_memfill_template(dest + 1, dest[0], length - 1);
3947 case QPixelLayout::BPP24: {
3948 quint24 *dest =
reinterpret_cast<
quint24 *>(rasterBuffer->scanLine(y)) + x;
3949 qt_memfill_template(dest + 1, dest[0], length - 1);
3952 case QPixelLayout::BPP16: {
3953 quint16 *dest =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
3954 qt_memfill_template(dest + 1, dest[0], length - 1);
3957 case QPixelLayout::BPP8: {
3958 uchar *dest = rasterBuffer->scanLine(y) + x;
3959 memset(dest + 1, dest[0], length - 1);
3970#if QT_CONFIG(qtgui_threadpool)
3971#define QT_THREAD_PARALLEL_FILLS(function)
3972 const int segments = (count + 32
) / 64
;
3973 QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
3974 if (segments > 1
&& qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8
3975 && threadPool && !threadPool->contains(QThread::currentThread())) {
3976 QLatch latch(segments);
3978 for (int i = 0
; i < segments; ++i) {
3979 int cn = (count - c) / (segments - i);
3980 threadPool->start([&, c, cn]() {
3981 function(c, c + cn);
3990#define QT_THREAD_PARALLEL_FILLS(function) function(0
, count)
3996 const Operator op = getOperator(data,
nullptr, 0);
3997 const uint color = data->solidColor.rgba();
3998 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
3999 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4001 auto function = [=] (
int cStart,
int cEnd) {
4002 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4003 for (
int c = cStart; c < cEnd; ++c) {
4005 int length = spans[c].len;
4006 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore) {
4009 spanfill_from_first(data
->rasterBuffer, bpp, x, spans[c].y, length);
4015 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4016 op.funcSolid(dest, l, color, spans[c].coverage);
4018 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4031 const Operator op = getOperator(data,
nullptr, 0);
4032 const uint color = data->solidColor.rgba();
4034 if (op.mode == QPainter::CompositionMode_Source) {
4037 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans->y)) + spans->x;
4038 if (spans->coverage == 255) {
4039 qt_memfill(target, color, spans->len);
4041 }
else if (spans->len > 16) {
4042 op.funcSolid(target, spans->len, color, spans->coverage);
4045 uint c = BYTE_MUL(color, spans->coverage);
4046 int ialpha = 255 - spans->coverage;
4047 for (
int i = 0; i < spans->len; ++i)
4048 target[i] = c + BYTE_MUL(target[i], ialpha);
4054 const auto funcSolid = op.funcSolid;
4055 auto function = [=] (
int cStart,
int cEnd) {
4056 for (
int c = cStart; c < cEnd; ++c) {
4057 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + spans[c].x;
4058 funcSolid(target, spans[c].len, color, spans[c].coverage);
4066#if QT_CONFIG(raster_64bit)
4067 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4068 const Operator op = getOperator(data,
nullptr, 0);
4069 if (!op.funcSolid64) {
4070 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit");
4071 return blend_color_generic(count, spans, userData);
4074 const QRgba64 color = data->solidColor.rgba64();
4075 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4076 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4078 auto function = [=, &op] (
int cStart,
int cEnd)
4080 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4081 for (
int c = cStart; c < cEnd; ++c) {
4083 int length = spans[c].len;
4084 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore64) {
4086 op.destStore64(data->rasterBuffer, x, spans[c].y, &color, 1);
4087 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4092 int l = qMin(BufferSize, length);
4093 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4094 op.funcSolid64(dest, l, color, spans[c].coverage);
4096 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4102 QT_THREAD_PARALLEL_FILLS(function);
4104 blend_color_generic(count, spans, userData);
4110#if QT_CONFIG(raster_fp)
4111 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4112 const Operator op = getOperator(data,
nullptr, 0);
4113 if (!op.funcSolidFP || !op.destFetchFP) {
4114 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_fp: unsupported 4xF16 blend attempted, falling back to 32-bit");
4115 return blend_color_generic(count, spans, userData);
4119 data->solidColor.getRgbF(&r, &g, &b, &a);
4120 const QRgbaFloat32 color{r, g, b, a};
4121 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4122 QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4124 auto function = [=, &op] (
int cStart,
int cEnd)
4126 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4127 for (
int c = cStart; c < cEnd; ++c) {
4129 int length = spans[c].len;
4130 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStoreFP) {
4132 op.destStoreFP(data->rasterBuffer, x, spans[c].y, &color, 1);
4133 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4138 int l = qMin(BufferSize, length);
4139 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4140 op.funcSolidFP(dest, l, color, spans[c].coverage);
4142 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4148 QT_THREAD_PARALLEL_FILLS(function);
4150 blend_color_generic_rgb64(count, spans, userData);
4154template <
typename T>
4157 const int const_alpha = (data->type ==
QSpanData::Texture) ? data->texture.const_alpha : 256;
4158 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256;
4160 auto function = [=, &op] (
int cStart,
int cEnd)
4162 T Q_DECL_UNINITIALIZED handler(data, op);
4164 for (
int c = cStart; c < cEnd;) {
4165 if (!spans[c].len) {
4170 const int y = spans[c].y;
4171 int right = x + spans[c].len;
4172 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4175 for (
int i = c + 1; i < cEnd && spans[i].y == y && spans[i].x == right && fetchDest == (!solidSource || spans[i].coverage < 255); ++i)
4176 right += spans[i].len;
4177 int length = right - x;
4183 int process_length = l;
4186 const auto *src = handler.fetch(process_x, y, process_length, fetchDest);
4189 if (x == spans[c].x)
4190 coverage = (spans[c].coverage * const_alpha) >> 8;
4192 int right = spans[c].x + spans[c].len;
4193 int len = qMin(l, right - x);
4195 handler.process(x, y, len, coverage, src, offset);
4204 handler.store(process_x, y, process_length);
4228 const uint *
fetch(
int x,
int y,
int len,
bool fetchDest)
4230 if (fetchDest || op.destFetch == destFetchARGB32P)
4237 void process(
int,
int,
int len,
int coverage,
const uint *src,
int offset)
4239 op.func(
dest + offset, src + offset, len, coverage);
4249#if QT_CONFIG(raster_64bit)
4250class BlendSrcGenericRGB64 :
public QBlendBase
4253 QRgba64 *dest =
nullptr;
4254 alignas(16) QRgba64 buffer[BufferSize];
4255 alignas(16) QRgba64 src_buffer[BufferSize];
4256 BlendSrcGenericRGB64(
const QSpanData *d,
const Operator &o)
4261 bool isSupported()
const
4263 return op.func64 && op.destFetch64;
4266 const QRgba64 *fetch(
int x,
int y,
int len,
bool fetchDest)
4268 if (fetchDest || op.destFetch64 == destFetchRGB64)
4269 dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
4272 return op.srcFetch64(src_buffer, &op, data, y, x, len);
4275 void process(
int,
int,
int len,
int coverage,
const QRgba64 *src,
int offset)
4277 op.func64(dest + offset, src + offset, len, coverage);
4280 void store(
int x,
int y,
int len)
4283 op.destStore64(data->rasterBuffer, x, y, dest, len);
4288#if QT_CONFIG(raster_fp)
4289class BlendSrcGenericRGBFP :
public QBlendBase
4292 QRgbaFloat32 *dest =
nullptr;
4293 alignas(16) QRgbaFloat32 buffer[BufferSize];
4294 alignas(16) QRgbaFloat32 src_buffer[BufferSize];
4295 BlendSrcGenericRGBFP(
const QSpanData *d,
const Operator &o)
4300 bool isSupported()
const
4302 return op.funcFP && op.destFetchFP && op.srcFetchFP;
4305 const QRgbaFloat32 *fetch(
int x,
int y,
int len,
bool fetchDest)
4307 if (fetchDest || op.destFetchFP == destFetchRGBFP)
4308 dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
4311 return op.srcFetchFP(src_buffer, &op, data, y, x, len);
4314 void process(
int,
int,
int len,
int coverage,
const QRgbaFloat32 *src,
int offset)
4316 op.funcFP(dest + offset, src + offset, len, coverage);
4319 void store(
int x,
int y,
int len)
4322 op.destStoreFP(data->rasterBuffer, x, y, dest, len);
4330 const Operator op = getOperator(data,
nullptr, 0);
4334#if QT_CONFIG(raster_64bit)
4335static void blend_src_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4337 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4338 const Operator op = getOperator(data,
nullptr, 0);
4339 if (op.func64 && op.destFetch64) {
4340 handleSpans<BlendSrcGenericRGB64>(count, spans, data, op);
4342 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4343 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4348#if QT_CONFIG(raster_fp)
4349static void blend_src_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4351 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4352 const Operator op = getOperator(data, spans, count);
4353 if (op.funcFP && op.destFetchFP && op.srcFetchFP) {
4354 handleSpans<BlendSrcGenericRGBFP>(count, spans, data, op);
4356 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4357 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4366 const Operator op = getOperator(data, spans, count);
4368 const int image_width = data->texture.width;
4369 const int image_height = data->texture.height;
4370 const int const_alpha = data->texture.const_alpha;
4371 const int xoff = -qRound(-data->dx);
4372 const int yoff = -qRound(-data->dy);
4373 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch != destFetchARGB32P;
4375 auto function = [=, &op] (
int cStart,
int cEnd)
4377 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4378 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4379 for (
int c = cStart; c < cEnd; ++c) {
4383 int length = spans[c].len;
4385 int sy = yoff + spans[c].y;
4386 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4387 if (sy >= 0 && sy < image_height && sx < image_width) {
4393 if (sx + length > image_width)
4394 length = image_width - sx;
4396 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4399 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4400 uint *dest = fetchDest ? op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4401 op.func(dest, src, l, coverage);
4403 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4415#if QT_CONFIG(raster_64bit)
4416static void blend_untransformed_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4418 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4420 const Operator op = getOperator(data, spans, count);
4422 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4423 return blend_untransformed_generic(count, spans, userData);
4426 const int image_width = data->texture.width;
4427 const int image_height = data->texture.height;
4428 const int const_alpha = data->texture.const_alpha;
4429 const int xoff = -qRound(-data->dx);
4430 const int yoff = -qRound(-data->dy);
4431 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch64 != destFetchRGB64;
4433 auto function = [=, &op] (
int cStart,
int cEnd)
4435 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4436 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4437 for (
int c = cStart; c < cEnd; ++c) {
4441 int length = spans[c].len;
4443 int sy = yoff + spans[c].y;
4444 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4445 if (sy >= 0 && sy < image_height && sx < image_width) {
4451 if (sx + length > image_width)
4452 length = image_width - sx;
4454 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4456 int l = qMin(BufferSize, length);
4457 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4458 QRgba64 *dest = fetchDest ? op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4459 op.func64(dest, src, l, coverage);
4461 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4470 QT_THREAD_PARALLEL_FILLS(function);
4474#if QT_CONFIG(raster_fp)
4475static void blend_untransformed_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4477 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4479 const Operator op = getOperator(data, spans, count);
4481 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgbaf16: unsupported 4xFP16 blend attempted, falling back to 32-bit");
4482 return blend_untransformed_generic(count, spans, userData);
4485 const int image_width = data->texture.width;
4486 const int image_height = data->texture.height;
4487 const int xoff = -qRound(-data->dx);
4488 const int yoff = -qRound(-data->dy);
4489 const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetchFP != destFetchRGBFP;
4491 auto function = [=, &op] (
int cStart,
int cEnd)
4493 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4494 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4495 for (
int c = cStart; c < cEnd; ++c) {
4499 int length = spans[c].len;
4501 int sy = yoff + spans[c].y;
4502 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4503 if (sy >= 0 && sy < image_height && sx < image_width) {
4509 if (sx + length > image_width)
4510 length = image_width - sx;
4512 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4514 int l = qMin(BufferSize, length);
4515 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4516 QRgbaFloat32 *dest = fetchDest ? op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4517 op.funcFP(dest, src, l, coverage);
4519 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4528 QT_THREAD_PARALLEL_FILLS(function);
4535 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4536 && data->texture.format != QImage::Format_RGB32) {
4537 blend_untransformed_generic(count, spans, userData);
4541 const Operator op = getOperator(data, spans, count);
4543 const int image_width = data->texture.width;
4544 const int image_height = data->texture.height;
4545 const int const_alpha = data->texture.const_alpha;
4546 const int xoff = -qRound(-data->dx);
4547 const int yoff = -qRound(-data->dy);
4549 auto function = [=, &op] (
int cStart,
int cEnd)
4551 for (
int c = cStart; c < cEnd; ++c) {
4555 int length = spans[c].len;
4557 int sy = yoff + spans[c].y;
4558 if (sy >= 0 && sy < image_height && sx < image_width) {
4564 if (sx + length > image_width)
4565 length = image_width - sx;
4567 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4568 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4569 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4570 op.func(dest, src, length, coverage);
4579 quint16 y, quint8 b)
4581 quint16 t = ((((x & 0x07e0) * a) + ((y & 0x07e0) * b)) >> 5) & 0x07e0;
4582 t |= ((((x & 0xf81f) * a) + ((y & 0xf81f) * b)) >> 5) & 0xf81f;
4588 quint32 y, quint8 b)
4591 t = ((((x & 0xf81f07e0) >> 5) * a) + (((y & 0xf81f07e0) >> 5) * b)) & 0xf81f07e0;
4592 t |= ((((x & 0x07e0f81f) * a) + ((y & 0x07e0f81f) * b)) >> 5) & 0x07e0f81f;
4600 const quint8 ialpha)
4602 const int dstAlign = ((quintptr)dest) & 0x3;
4604 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4609 const int srcAlign = ((quintptr)src) & 0x3;
4610 int length32 = length >> 1;
4611 if (length32 && srcAlign == 0) {
4612 while (length32--) {
4613 const quint32 *src32 =
reinterpret_cast<
const quint32*>(src);
4614 quint32 *dest32 =
reinterpret_cast<quint32*>(dest);
4615 *dest32 = interpolate_pixel_rgb16x2_255(*src32, alpha,
4623 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4632 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4634 if (data->texture.format != QImage::Format_RGB16
4635 || (mode != QPainter::CompositionMode_SourceOver
4636 && mode != QPainter::CompositionMode_Source))
4638 blend_untransformed_generic(count, spans, userData);
4642 const int image_width = data->texture.width;
4643 const int image_height = data->texture.height;
4644 int xoff = -qRound(-data->dx);
4645 int yoff = -qRound(-data->dy);
4647 auto function = [=](
int cStart,
int cEnd)
4649 for (
int c = cStart; c < cEnd; ++c) {
4652 const quint8 coverage = (data->texture.const_alpha * spans[c].coverage) >> 8;
4657 int length = spans[c].len;
4659 int sy = yoff + spans[c].y;
4660 if (sy >= 0 && sy < image_height && sx < image_width) {
4666 if (sx + length > image_width)
4667 length = image_width - sx;
4669 quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans[c].y) + x;
4670 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
4671 if (coverage == 255) {
4672 memcpy(dest, src, length *
sizeof(quint16));
4674 const quint8 alpha = (coverage + 1) >> 3;
4675 const quint8 ialpha = 0x20 - alpha;
4677 blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha);
4690 const Operator op = getOperator(data, spans, count);
4692 const int image_width = data->texture.width;
4693 const int image_height = data->texture.height;
4694 const int const_alpha = data->texture.const_alpha;
4695 int xoff = -qRound(-data->dx) % image_width;
4696 int yoff = -qRound(-data->dy) % image_height;
4699 xoff += image_width;
4701 yoff += image_height;
4703 auto function = [=, &op](
int cStart,
int cEnd)
4705 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4706 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4707 for (
int c = cStart; c < cEnd; ++c) {
4709 int length = spans[c].len;
4710 int sx = (xoff + spans[c].x) % image_width;
4711 int sy = (spans[c].y + yoff) % image_height;
4717 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4719 int l = qMin(image_width - sx, length);
4722 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4723 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4724 op.func(dest, src, l, coverage);
4726 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4730 if (sx >= image_width)
4738#if QT_CONFIG(raster_64bit)
4739static void blend_tiled_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4741 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4743 const Operator op = getOperator(data, spans, count);
4745 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4746 return blend_tiled_generic(count, spans, userData);
4749 const int image_width = data->texture.width;
4750 const int image_height = data->texture.height;
4751 int xoff = -qRound(-data->dx) % image_width;
4752 int yoff = -qRound(-data->dy) % image_height;
4755 xoff += image_width;
4757 yoff += image_height;
4759 bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
4760 bool isBpp64 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP64;
4761 if (op.destFetch64 == destFetch64Undefined && image_width <= BufferSize && (isBpp32 || isBpp64)) {
4762 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4767 int length = spans->len;
4768 int sx = (xoff + spans->x) % image_width;
4769 int sy = (spans->y + yoff) % image_height;
4775 int sl = qMin(image_width, length);
4776 if (sx > 0 && sl > 0) {
4777 int l = qMin(image_width - sx, sl);
4778 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4779 op.destStore64(data->rasterBuffer, x, y, src, l);
4783 if (sx >= image_width)
4788 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, sl);
4789 op.destStore64(data->rasterBuffer, x, y, src, sl);
4793 if (sx >= image_width)
4797 uint *dest =
reinterpret_cast<uint *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4798 for (
int i = image_width; i < length; ++i)
4799 dest[i] = dest[i - image_width];
4801 quint64 *dest =
reinterpret_cast<quint64 *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4802 for (
int i = image_width; i < length; ++i)
4803 dest[i] = dest[i - image_width];
4810 auto function = [=, &op](
int cStart,
int cEnd)
4812 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4813 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4814 for (
int c = cStart; c < cEnd; ++c) {
4816 int length = spans[c].len;
4817 int sx = (xoff + spans[c].x) % image_width;
4818 int sy = (spans[c].y + yoff) % image_height;
4824 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4826 int l = qMin(image_width - sx, length);
4829 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4830 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4831 op.func64(dest, src, l, coverage);
4833 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4837 if (sx >= image_width)
4842 QT_THREAD_PARALLEL_FILLS(function);
4846#if QT_CONFIG(raster_fp)
4847static void blend_tiled_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4849 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4851 const Operator op = getOperator(data, spans, count);
4853 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4854 return blend_tiled_generic(count, spans, userData);
4857 const int image_width = data->texture.width;
4858 const int image_height = data->texture.height;
4859 int xoff = -qRound(-data->dx) % image_width;
4860 int yoff = -qRound(-data->dy) % image_height;
4863 xoff += image_width;
4865 yoff += image_height;
4869 auto function = [=, &op](
int cStart,
int cEnd)
4871 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4872 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4873 for (
int c = cStart; c < cEnd; ++c) {
4875 int length = spans[c].len;
4876 int sx = (xoff + spans[c].x) % image_width;
4877 int sy = (spans[c].y + yoff) % image_height;
4883 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4885 int l = qMin(image_width - sx, length);
4888 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4889 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4890 op.funcFP(dest, src, l, coverage);
4892 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4896 if (sx >= image_width)
4901 QT_THREAD_PARALLEL_FILLS(function);
4908 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4909 && data->texture.format != QImage::Format_RGB32) {
4910 blend_tiled_generic(count, spans, userData);
4914 const Operator op = getOperator(data, spans, count);
4916 const int image_width = data->texture.width;
4917 const int image_height = data->texture.height;
4918 int xoff = -qRound(-data->dx) % image_width;
4919 int yoff = -qRound(-data->dy) % image_height;
4922 xoff += image_width;
4924 yoff += image_height;
4925 const auto func = op.func;
4926 const int const_alpha = data->texture.const_alpha;
4928 auto function = [=] (
int cStart,
int cEnd) {
4929 for (
int c = cStart; c < cEnd; ++c) {
4931 int length = spans[c].len;
4932 int sx = (xoff + spans[c].x) % image_width;
4933 int sy = (spans[c].y + yoff) % image_height;
4939 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4941 int l = qMin(image_width - sx, length);
4944 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4945 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4946 func(dest, src, l, coverage);
4950 if (sx >= image_width)
4961 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4963 if (data->texture.format != QImage::Format_RGB16
4964 || (mode != QPainter::CompositionMode_SourceOver
4965 && mode != QPainter::CompositionMode_Source))
4967 blend_tiled_generic(count, spans, userData);
4971 const int image_width = data->texture.width;
4972 const int image_height = data->texture.height;
4973 int xoff = -qRound(-data->dx) % image_width;
4974 int yoff = -qRound(-data->dy) % image_height;
4977 xoff += image_width;
4979 yoff += image_height;
4981 const int const_alpha = data->texture.const_alpha;
4982 auto function = [=] (
int cStart,
int cEnd) {
4983 for (
int c = cStart; c < cEnd; ++c) {
4984 const quint8 coverage = (const_alpha * spans[c].coverage) >> 8;
4989 int length = spans[c].len;
4990 int sx = (xoff + spans[c].x) % image_width;
4991 int sy = (spans[c].y + yoff) % image_height;
4997 if (coverage == 255) {
4999 length = qMin(image_width,length);
5002 int l = qMin(image_width - sx, length);
5005 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + tx;
5006 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5007 memcpy(dest, src, l *
sizeof(quint16));
5011 if (sx >= image_width)
5021 int copy_image_width = qMin(image_width,
int(spans[c].len));
5022 length = spans[c].len - copy_image_width;
5023 quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5024 quint16 *dest = src + copy_image_width;
5025 while (copy_image_width < length) {
5026 memcpy(dest, src, copy_image_width *
sizeof(quint16));
5027 dest += copy_image_width;
5028 length -= copy_image_width;
5029 copy_image_width *= 2;
5032 memcpy(dest, src, length *
sizeof(quint16));
5034 const quint8 alpha = (coverage + 1) >> 3;
5035 const quint8 ialpha = 0x20 - alpha;
5038 int l = qMin(image_width - sx, length);
5041 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5042 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5043 blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
5047 if (sx >= image_width)
5059 blend_untransformed_argb,
5068 blend_untransformed_rgb565,
5077 blend_untransformed_generic,
5078 blend_tiled_generic,
5085#if QT_CONFIG(raster_64bit)
5086static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
5087 blend_untransformed_generic_rgb64,
5088 blend_tiled_generic_rgb64,
5089 blend_src_generic_rgb64,
5090 blend_src_generic_rgb64,
5091 blend_src_generic_rgb64,
5092 blend_src_generic_rgb64
5096#if QT_CONFIG(raster_fp)
5097static const ProcessSpans processTextureSpansGenericFP[NBlendTypes] = {
5098 blend_untransformed_generic_fp,
5099 blend_tiled_generic_fp,
5100 blend_src_generic_fp,
5101 blend_src_generic_fp,
5102 blend_src_generic_fp,
5103 blend_src_generic_fp
5112 case QImage::Format_Invalid:
5113 Q_UNREACHABLE_RETURN();
5114 case QImage::Format_ARGB32_Premultiplied:
5117 case QImage::Format_RGB16:
5120#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5121 case QImage::Format_ARGB32:
5122 case QImage::Format_RGBA8888:
5124 case QImage::Format_BGR30:
5125 case QImage::Format_A2BGR30_Premultiplied:
5126 case QImage::Format_RGB30:
5127 case QImage::Format_A2RGB30_Premultiplied:
5128 case QImage::Format_RGBX64:
5129 case QImage::Format_RGBA64:
5130 case QImage::Format_RGBA64_Premultiplied:
5131 case QImage::Format_Grayscale16:
5132#if !QT_CONFIG(raster_fp)
5133 case QImage::Format_RGBX16FPx4:
5134 case QImage::Format_RGBA16FPx4:
5135 case QImage::Format_RGBA16FPx4_Premultiplied:
5136 case QImage::Format_RGBX32FPx4:
5137 case QImage::Format_RGBA32FPx4:
5138 case QImage::Format_RGBA32FPx4_Premultiplied:
5140#if QT_CONFIG(raster_64bit)
5141 proc = processTextureSpansGeneric64[blendType];
5144#if QT_CONFIG(raster_fp)
5145 case QImage::Format_RGBX16FPx4:
5146 case QImage::Format_RGBA16FPx4:
5147 case QImage::Format_RGBA16FPx4_Premultiplied:
5148 case QImage::Format_RGBX32FPx4:
5149 case QImage::Format_RGBA32FPx4:
5150 case QImage::Format_RGBA32FPx4_Premultiplied:
5151 proc = processTextureSpansGenericFP[blendType];
5158 proc(count, spans, userData);
5164 int *pyinc,
int *poff)
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5180 qreal ryinc = linear.dy * data->m22 * gss *
FIXPT_SIZE;
5181 qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss *
FIXPT_SIZE;
5182 const int limit =
std::numeric_limits<
int>::max() -
FIXPT_SIZE;
5183 if (count && (
std::fabs(ryinc) < limit) && (
std::fabs(roff) < limit)
5184 && (
std::fabs(ryinc * spans->y + roff) < limit)
5185 && (
std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) {
5186 *pyinc =
int(ryinc);
5198 getLinearGradientValues(&linear, data);
5200 CompositionFunctionSolid funcSolid =
5203 int yinc(0), off(0);
5204 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5211 quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
5213 qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5215 funcSolid(dst, spans->len, color, spans->coverage);
5227 getLinearGradientValues(&linear, data);
5229 int yinc(0), off(0);
5230 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5236#if QT_CONFIG(raster_64bit)
5237 data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
5239 data->solidColor = qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5241 blend_color(1, spans, userData);
5250 bool isVerticalGradient =
5251 data->txop <= QTransform::TxScale &&
5252 data->type == QSpanData::LinearGradient &&
5253 data->gradient.linear.end.x == data->gradient.linear.origin.x;
5255 case QImage::Format_Invalid:
5257 case QImage::Format_RGB32:
5258 case QImage::Format_ARGB32_Premultiplied:
5259 if (isVerticalGradient && blend_vertical_gradient_argb(count, spans, userData))
5261 return blend_src_generic(count, spans, userData);
5262#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5263 case QImage::Format_ARGB32:
5264 case QImage::Format_RGBA8888:
5266 case QImage::Format_BGR30:
5267 case QImage::Format_A2BGR30_Premultiplied:
5268 case QImage::Format_RGB30:
5269 case QImage::Format_A2RGB30_Premultiplied:
5270 case QImage::Format_RGBX64:
5271 case QImage::Format_RGBA64:
5272 case QImage::Format_RGBA64_Premultiplied:
5273#if !QT_CONFIG(raster_fp)
5274 case QImage::Format_RGBX16FPx4:
5275 case QImage::Format_RGBA16FPx4:
5276 case QImage::Format_RGBA16FPx4_Premultiplied:
5277 case QImage::Format_RGBX32FPx4:
5278 case QImage::Format_RGBA32FPx4:
5279 case QImage::Format_RGBA32FPx4_Premultiplied:
5281#if QT_CONFIG(raster_64bit)
5282 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData))
5284 return blend_src_generic_rgb64(count, spans, userData);
5286#if QT_CONFIG(raster_fp)
5287 case QImage::Format_RGBX16FPx4:
5288 case QImage::Format_RGBA16FPx4:
5289 case QImage::Format_RGBA16FPx4_Premultiplied:
5290 case QImage::Format_RGBX32FPx4:
5291 case QImage::Format_RGBA32FPx4:
5292 case QImage::Format_RGBA32FPx4_Premultiplied:
5293 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_fp>(count, spans, userData))
5295 return blend_src_generic_fp(count, spans, userData);
5298 if (isVerticalGradient && blend_vertical_gradient<
blend_color_generic>(count, spans, userData))
5300 return blend_src_generic(count, spans, userData);
5305template <
class DST>
static
5307 int x,
int y, DST color,
5309 int mapWidth,
int mapHeight,
int mapStride)
5311 DST *dest =
reinterpret_cast<DST *>(rasterBuffer->scanLine(y)) + x;
5312 const int destStride = rasterBuffer->stride<DST>();
5315 while (--mapHeight >= 0) {
5318 for (
int x = 0; x < mapWidth; x += 8) {
5319 uchar s = map[x >> 3];
5320 for (
int i = 0; i < 8; ++i) {
5325 qt_memfill(dest + x0, color, n);
5340 qt_memfill(dest + x0, color, n);
5345 while (--mapHeight >= 0) {
5348 for (uchar s = *map; s; s <<= 1) {
5352 qt_memfill(dest + x0, color, n);
5360 qt_memfill(dest + x0, color, n);
5368 int x,
int y,
const QRgba64 &color,
5370 int mapWidth,
int mapHeight,
int mapStride)
5372 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color.toArgb32(),
5373 map, mapWidth, mapHeight, mapStride);
5377 int x,
int y,
const QRgba64 &color,
5379 int mapWidth,
int mapHeight,
int mapStride)
5381 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()),
5382 map, mapWidth, mapHeight, mapStride);
5385template<QtPixelOrder PixelOrder>
5387 int x,
int y,
const QRgba64 &color,
5389 int mapWidth,
int mapHeight,
int mapStride)
5391 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, qConvertRgb64ToRgb30<PixelOrder>(color),
5392 map, mapWidth, mapHeight, mapStride);
5396 int x,
int y,
const QRgba64 &color,
5398 int mapWidth,
int mapHeight,
int mapStride)
5400 qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color.toRgb16(),
5401 map, mapWidth, mapHeight, mapStride);
5404static inline void grayBlendPixel(quint32 *dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5407 const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5409 QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
5411 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5414static inline void alphamapblend_argb32(quint32 *dst,
int coverage, QRgba64 srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5416 if (coverage == 0) {
5418 }
else if (coverage == 255 || !colorProfile) {
5419 blend_pixel(*dst, src, coverage);
5420 }
else if (*dst < 0xff000000) {
5422 blend_pixel(*dst, src, coverage);
5423 }
else if (src >= 0xff000000) {
5424 grayBlendPixel(dst, coverage, srcLinear, colorProfile);
5428 blend_pixel(s, src);
5430 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5431 grayBlendPixel(dst, coverage, s64, colorProfile);
5435#if QT_CONFIG(raster_64bit)
5437static inline void grayBlendPixel(QRgba64 &dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5440 QRgba64 dstColor = dst;
5442 if (dstColor.isOpaque())
5443 dstColor = colorProfile->toLinear(dstColor);
5444 else if (!dstColor.isTransparent())
5445 dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
5448 blend_pixel(dstColor, srcLinear, coverage);
5451 if (dstColor.isOpaque())
5452 dstColor = colorProfile->fromLinear(dstColor);
5453 else if (!dstColor.isTransparent())
5454 dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
5459static inline void alphamapblend_generic(
int coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5461 if (coverage == 0) {
5463 }
else if (coverage == 255) {
5464 blend_pixel(dest[x], src);
5465 }
else if (src.isOpaque()) {
5466 grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5469 QRgba64 s = dest[x];
5470 blend_pixel(s, src);
5473 s = colorProfile->toLinear(s);
5474 grayBlendPixel(dest[x], coverage, s, colorProfile);
5478static void qt_alphamapblit_generic_oneline(
const uchar *map,
int len,
5479 const QRgba64 srcColor, QRgba64 *dest,
5480 const QRgba64 color,
5481 const QColorTrcLut *colorProfile)
5483 for (
int j = 0; j < len; ++j)
5484 alphamapblend_generic(map[j], dest, j, srcColor, color, colorProfile);
5487static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
5488 int x,
int y,
const QRgba64 &color,
5490 int mapWidth,
int mapHeight,
int mapStride,
5491 const QClipData *clip,
bool useGammaCorrection)
5493 if (color.isTransparent())
5496 const QColorTrcLut *colorProfile =
nullptr;
5498 if (useGammaCorrection)
5499 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5501 QRgba64 srcColor = color;
5502 if (colorProfile && color.isOpaque())
5503 srcColor = colorProfile->toLinear(srcColor);
5505 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5506 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5507 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5510 for (
int ly = 0; ly < mapHeight; ++ly) {
5512 int length = mapWidth;
5513 while (length > 0) {
5514 int l = qMin(BufferSize, length);
5516 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5517 qt_alphamapblit_generic_oneline(map + i - x, l,
5518 srcColor, dest, color,
5521 destStore64(rasterBuffer, i, y + ly, dest, l);
5528 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5530 int top = qMax(y, 0);
5531 map += (top - y) * mapStride;
5533 const_cast<QClipData *>(clip)->initialize();
5534 for (
int yp = top; yp<bottom; ++yp) {
5535 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5537 for (
int i=0; i<line.count; ++i) {
5538 const QT_FT_Span &clip = line.spans[i];
5540 int start = qMax<
int>(x, clip.x);
5541 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5544 Q_ASSERT(end - start <= BufferSize);
5545 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5546 qt_alphamapblit_generic_oneline(map + start - x, end - start,
5547 srcColor, dest, color,
5550 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5558 int x,
int y,
const QRgba64 &color,
5560 int mapWidth,
int mapHeight,
int mapStride,
5561 const QClipData *clip,
bool useGammaCorrection)
5563 if (color.isTransparent())
5566 const quint32 c = color.toArgb32();
5568 const QColorTrcLut *colorProfile =
nullptr;
5570 if (useGammaCorrection)
5571 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5573 QRgba64 srcColor = color;
5574 if (colorProfile && color.isOpaque())
5575 srcColor = colorProfile->toLinear(srcColor);
5578 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
5579 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
5582 for (
int ly = 0; ly < mapHeight; ++ly) {
5584 int length = mapWidth;
5585 while (length > 0) {
5587 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
5588 for (
int j=0; j < l; ++j) {
5589 const int coverage = map[j + (i - x)];
5590 alphamapblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
5593 destStore(rasterBuffer, i, y + ly, dest, l);
5600 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5602 int top = qMax(y, 0);
5603 map += (top - y) * mapStride;
5605 const_cast<
QClipData *>(clip)->initialize();
5606 for (
int yp = top; yp<bottom; ++yp) {
5607 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5609 for (
int i=0; i<line.count; ++i) {
5610 const QT_FT_Span &clip = line.spans[i];
5612 int start = qMax<
int>(x, clip.x);
5613 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5617 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
5619 for (
int xp=start; xp<end; ++xp) {
5620 const int coverage = map[xp - x];
5621 alphamapblend_argb32(dest + xp - x, coverage, srcColor, color, colorProfile);
5624 destStore(rasterBuffer, start, clip.y, dest, end - start);
5634 if (coverage == 0) {
5636 }
else if (coverage == 255) {
5639 dest[x] = BYTE_MUL_RGB16(srcColor, coverage)
5640 + BYTE_MUL_RGB16(dest[x], 255 - coverage);
5645 int x,
int y,
const QRgba64 &color,
5647 int mapWidth,
int mapHeight,
int mapStride,
5648 const QClipData *clip,
bool useGammaCorrection)
5650 if (useGammaCorrection || !color.isOpaque()) {
5651 qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
5655 const quint16 c = color.toRgb16();
5658 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
5659 const int destStride = rasterBuffer->stride<quint16>();
5660 while (--mapHeight >= 0) {
5661 for (
int i = 0; i < mapWidth; ++i)
5662 alphamapblend_quint16(map[i], dest, i, c);
5667 int top = qMax(y, 0);
5668 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5669 map += (top - y) * mapStride;
5671 const_cast<
QClipData *>(clip)->initialize();
5672 for (
int yp = top; yp<bottom; ++yp) {
5673 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5675 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(yp));
5677 for (
int i=0; i<line.count; ++i) {
5678 const QT_FT_Span &clip = line.spans[i];
5680 int start = qMax<
int>(x, clip.x);
5681 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5683 for (
int xp=start; xp<end; ++xp)
5684 alphamapblend_quint16(map[xp - x], dest, xp, c);
5692 int mapWidth,
const QRgba64 &srcColor,
5693 quint32 *dest,
const quint32 c,
5694 const QColorTrcLut *colorProfile)
5696 for (
int i = 0; i < mapWidth; ++i)
5697 alphamapblend_argb32(dest + i, map[i], srcColor, c, colorProfile);
5701 int x,
int y,
const QRgba64 &color,
5703 int mapWidth,
int mapHeight,
int mapStride,
5704 const QClipData *clip,
bool useGammaCorrection)
5706 const quint32 c = color.toArgb32();
5707 const int destStride = rasterBuffer->stride<quint32>();
5709 if (color.isTransparent())
5712 const QColorTrcLut *colorProfile =
nullptr;
5714 if (useGammaCorrection)
5715 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5717 QRgba64 srcColor = color;
5718 if (colorProfile && color.isOpaque())
5719 srcColor = colorProfile->toLinear(srcColor);
5722 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
5723 while (--mapHeight >= 0) {
5724 qt_alphamapblit_argb32_oneline(map, mapWidth, srcColor, dest, c, colorProfile);
5729 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5731 int top = qMax(y, 0);
5732 map += (top - y) * mapStride;
5734 const_cast<
QClipData *>(clip)->initialize();
5735 for (
int yp = top; yp<bottom; ++yp) {
5736 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5738 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
5740 for (
int i=0; i<line.count; ++i) {
5741 const QT_FT_Span &clip = line.spans[i];
5742 int start = qMax<
int>(x, clip.x);
5743 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5744 qt_alphamapblit_argb32_oneline(map + start - x, end - start, srcColor, dest + start, c, colorProfile);
5751#if QT_CONFIG(raster_64bit)
5752static void qt_alphamapblit_nonpremul_argb32(QRasterBuffer *rasterBuffer,
5753 int x,
int y,
const QRgba64 &color,
5755 int mapWidth,
int mapHeight,
int mapStride,
5756 const QClipData *clip,
bool useGammaCorrection)
5759 return qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight,
5760 mapStride, clip, useGammaCorrection);
5762 if (color.isTransparent())
5765 const QColorTrcLut *colorProfile =
nullptr;
5767 if (useGammaCorrection)
5768 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5770 const quint32 c = color.toArgb32();
5771 QRgba64 srcColor = color;
5772 if (colorProfile && color.isOpaque())
5773 srcColor = colorProfile->toLinear(srcColor);
5775 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5776 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5777 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5779 for (
int ly = 0; ly < mapHeight; ++ly) {
5780 bool dstFullyOpaque =
true;
5782 int length = mapWidth;
5783 while (length > 0) {
5784 int l = qMin(BufferSize, length);
5785 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y + ly)) + i;
5786 for (
int j = 0; j < l && dstFullyOpaque; ++j)
5787 dstFullyOpaque = (dest[j] & 0xff000000) == 0xff000000;
5788 if (dstFullyOpaque) {
5790 qt_alphamapblit_argb32_oneline(map + i - x, l, srcColor, dest, c, colorProfile);
5793 QRgba64 *dest64 = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5794 qt_alphamapblit_generic_oneline(map + i - x, l,
5795 srcColor, dest64, color,
5798 destStore64(rasterBuffer, i, y + ly, dest64, l);
5810 return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
5813static inline void rgbBlendPixel(quint32 *dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5816 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5818 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5820 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5825#if defined(__SSE2__
)
5826 __m128i vd = _mm_cvtsi32_si128(d);
5827 __m128i vs = _mm_cvtsi32_si128(s);
5828 __m128i va = _mm_cvtsi32_si128(rgbAlpha);
5829 const __m128i vz = _mm_setzero_si128();
5830 vd = _mm_unpacklo_epi8(vd, vz);
5831 vs = _mm_unpacklo_epi8(vs, vz);
5832 va = _mm_unpacklo_epi8(va, vz);
5833 __m128i vb = _mm_xor_si128(_mm_set1_epi16(255), va);
5834 vs = _mm_mullo_epi16(vs, va);
5835 vd = _mm_mullo_epi16(vd, vb);
5836 vd = _mm_add_epi16(vd, vs);
5837 vd = _mm_add_epi16(vd, _mm_srli_epi16(vd, 8));
5838 vd = _mm_add_epi16(vd, _mm_set1_epi16(0x80));
5839 vd = _mm_srli_epi16(vd, 8);
5840 vd = _mm_packus_epi16(vd, vd);
5841 return _mm_cvtsi128_si32(vd);
5843 const int dr = qRed(d);
5844 const int dg = qGreen(d);
5845 const int db = qBlue(d);
5847 const int sr = qRed(s);
5848 const int sg = qGreen(s);
5849 const int sb = qBlue(s);
5851 const int mr = qRed(rgbAlpha);
5852 const int mg = qGreen(rgbAlpha);
5853 const int mb = qBlue(rgbAlpha);
5855 const int nr = qt_div_255(sr * mr + dr * (255 - mr));
5856 const int ng = qt_div_255(sg * mg + dg * (255 - mg));
5857 const int nb = qt_div_255(sb * mb + db * (255 - mb));
5859 return 0xff000000 | (nr << 16) | (ng << 8) | nb;
5863static inline void alphargbblend_argb32(quint32 *dst, uint coverage,
const QRgba64 &srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5865 if (coverage == 0xff000000) {
5867 }
else if (coverage == 0xffffffff && qAlpha(src) == 255) {
5868 blend_pixel(*dst, src);
5869 }
else if (*dst < 0xff000000) {
5871 blend_pixel(*dst, src, qRgbAvg(coverage));
5872 }
else if (!colorProfile) {
5875 blend_pixel(s, src);
5877 *dst = rgbBlend(*dst, s, coverage);
5878 }
else if (srcLinear.isOpaque()) {
5879 rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
5883 blend_pixel(s, src);
5885 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5886 rgbBlendPixel(dst, coverage, s64, colorProfile);
5890#if QT_CONFIG(raster_64bit)
5891static inline void rgbBlendPixel(QRgba64 &dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5894 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
5896 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5898 dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
5901static inline void alphargbblend_generic(uint coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5903 if (coverage == 0xff000000) {
5905 }
else if (coverage == 0xffffffff) {
5906 blend_pixel(dest[x], src);
5907 }
else if (!dest[x].isOpaque()) {
5909 alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
5910 }
else if (src.isOpaque()) {
5911 rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5914 QRgba64 s = dest[x];
5915 blend_pixel(s, src);
5918 s = colorProfile->toLinear(s);
5919 rgbBlendPixel(dest[x], coverage, s, colorProfile);
5923static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
5924 int x,
int y,
const QRgba64 &color,
5925 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5926 const QClipData *clip,
bool useGammaCorrection)
5928 if (color.isTransparent())
5931 const QColorTrcLut *colorProfile =
nullptr;
5933 if (useGammaCorrection)
5934 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
5936 QRgba64 srcColor = color;
5937 if (colorProfile && color.isOpaque())
5938 srcColor = colorProfile->toLinear(srcColor);
5940 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5941 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5942 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5945 for (
int ly = 0; ly < mapHeight; ++ly) {
5947 int length = mapWidth;
5948 while (length > 0) {
5949 int l = qMin(BufferSize, length);
5950 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5951 for (
int j=0; j < l; ++j) {
5952 const uint coverage = src[j + (i - x)];
5953 alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile);
5956 destStore64(rasterBuffer, i, y + ly, dest, l);
5963 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5965 int top = qMax(y, 0);
5966 src += (top - y) * srcStride;
5968 const_cast<QClipData *>(clip)->initialize();
5969 for (
int yp = top; yp<bottom; ++yp) {
5970 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5972 for (
int i=0; i<line.count; ++i) {
5973 const QT_FT_Span &clip = line.spans[i];
5975 int start = qMax<
int>(x, clip.x);
5976 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5979 Q_ASSERT(end - start <= BufferSize);
5980 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5982 for (
int xp=start; xp<end; ++xp) {
5983 const uint coverage = src[xp - x];
5984 alphargbblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
5987 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5995 int x,
int y,
const QRgba64 &color,
5996 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5997 const QClipData *clip,
bool useGammaCorrection)
5999 if (color.isTransparent())
6002 const quint32 c = color.toArgb32();
6004 const QColorTrcLut *colorProfile =
nullptr;
6006 if (useGammaCorrection)
6007 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6009 QRgba64 srcColor = color;
6010 if (colorProfile && color.isOpaque())
6011 srcColor = colorProfile->toLinear(srcColor);
6013 Q_DECL_UNINITIALIZED quint32 buffer[BufferSize];
6014 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
6015 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
6018 for (
int ly = 0; ly < mapHeight; ++ly) {
6020 int length = mapWidth;
6021 while (length > 0) {
6023 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
6024 for (
int j=0; j < l; ++j) {
6025 const uint coverage = src[j + (i - x)];
6026 alphargbblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
6029 destStore(rasterBuffer, i, y + ly, dest, l);
6036 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6038 int top = qMax(y, 0);
6039 src += (top - y) * srcStride;
6041 const_cast<
QClipData *>(clip)->initialize();
6042 for (
int yp = top; yp<bottom; ++yp) {
6043 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6045 for (
int i=0; i<line.count; ++i) {
6046 const QT_FT_Span &clip = line.spans[i];
6048 int start = qMax<
int>(x, clip.x);
6049 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6053 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
6055 for (
int xp=start; xp<end; ++xp) {
6056 const uint coverage = src[xp - x];
6057 alphargbblend_argb32(dest + xp - start, coverage, srcColor, c, colorProfile);
6060 destStore(rasterBuffer, start, clip.y, dest, end - start);
6069 int x,
int y,
const QRgba64 &color,
6070 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
6071 const QClipData *clip,
bool useGammaCorrection)
6073 if (color.isTransparent())
6076 const quint32 c = color.toArgb32();
6078 const QColorTrcLut *colorProfile =
nullptr;
6080 if (useGammaCorrection)
6081 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6083 QRgba64 srcColor = color;
6084 if (colorProfile && color.isOpaque())
6085 srcColor = colorProfile->toLinear(srcColor);
6088 quint32 *dst =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
6089 const int destStride = rasterBuffer->stride<quint32>();
6090 while (--mapHeight >= 0) {
6091 for (
int i = 0; i < mapWidth; ++i) {
6092 const uint coverage = src[i];
6093 alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
6100 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6102 int top = qMax(y, 0);
6103 src += (top - y) * srcStride;
6105 const_cast<
QClipData *>(clip)->initialize();
6106 for (
int yp = top; yp<bottom; ++yp) {
6107 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6109 quint32 *dst =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
6111 for (
int i=0; i<line.count; ++i) {
6112 const QT_FT_Span &clip = line.spans[i];
6114 int start = qMax<
int>(x, clip.x);
6115 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6117 for (
int xp=start; xp<end; ++xp) {
6118 const uint coverage = src[xp - x];
6119 alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
6129 int x,
int y,
int width,
int height,
6130 const QRgba64 &color)
6132 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6133 color.toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6137 int x,
int y,
int width,
int height,
6138 const QRgba64 &color)
6140 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6141 quint32 c32 = color.toArgb32();
6143 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c16), &c32, 0, 1,
nullptr,
nullptr);
6144 qt_rectfill<quint16>(
reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
6145 c16, x, y, width, height, rasterBuffer->bytesPerLine());
6149 int x,
int y,
int width,
int height,
6150 const QRgba64 &color)
6152 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6153 quint32 c32 = color.toArgb32();
6155 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c24), &c32, 0, 1,
nullptr,
nullptr);
6156 qt_rectfill<
quint24>(
reinterpret_cast<
quint24 *>(rasterBuffer->buffer()),
6157 c24, x, y, width, height, rasterBuffer->bytesPerLine());
6161 int x,
int y,
int width,
int height,
6162 const QRgba64 &color)
6164 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6165 color.unpremultiplied().toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6169 int x,
int y,
int width,
int height,
6170 const QRgba64 &color)
6172 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6173 ARGB2RGBA(color.toArgb32() | 0xff000000), x, y, width, height, rasterBuffer->bytesPerLine());
6177 int x,
int y,
int width,
int height,
6178 const QRgba64 &color)
6180 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6181 ARGB2RGBA(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6185 int x,
int y,
int width,
int height,
6186 const QRgba64 &color)
6188 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6189 ARGB2RGBA(color.unpremultiplied().toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6192template<QtPixelOrder PixelOrder>
6194 int x,
int y,
int width,
int height,
6195 const QRgba64 &color)
6197 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6198 qConvertRgb64ToRgb30<PixelOrder>(color), x, y, width, height, rasterBuffer->bytesPerLine());
6202 int x,
int y,
int width,
int height,
6203 const QRgba64 &color)
6205 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6206 color.alpha() >> 8, x, y, width, height, rasterBuffer->bytesPerLine());
6210 int x,
int y,
int width,
int height,
6211 const QRgba64 &color)
6213 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6214 qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6218 int x,
int y,
int width,
int height,
6219 const QRgba64 &color)
6221 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6223 store(
reinterpret_cast<uchar *>(&c64), &color, 0, 1,
nullptr,
nullptr);
6224 qt_rectfill<quint64>(
reinterpret_cast<quint64 *>(rasterBuffer->buffer()),
6225 c64, x, y, width, height, rasterBuffer->bytesPerLine());
6229 int x,
int y,
int width,
int height,
6230 const QRgba64 &color)
6232 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6234 store(
reinterpret_cast<uchar *>(&c), &color, 0, 1,
nullptr,
nullptr);
6236 c, x, y, width, height, rasterBuffer->bytesPerLine());
6245 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr },
6248 blend_color_generic,
6249 nullptr,
nullptr,
nullptr,
nullptr
6253 blend_color_generic,
6254 nullptr,
nullptr,
nullptr,
nullptr
6258 blend_color_generic,
6259 nullptr,
nullptr,
nullptr,
nullptr
6264 qt_bitmapblit_argb32,
6265 qt_alphamapblit_argb32,
6266 qt_alphargbblit_argb32,
6271 blend_color_generic,
6272 qt_bitmapblit_argb32,
6273#if QT_CONFIG(raster_64bit)
6274 qt_alphamapblit_nonpremul_argb32,
6276 qt_alphamapblit_generic,
6278 qt_alphargbblit_generic,
6279 qt_rectfill_nonpremul_argb32
6284 qt_bitmapblit_argb32,
6285 qt_alphamapblit_argb32,
6286 qt_alphargbblit_argb32,
6291 blend_color_generic,
6292 qt_bitmapblit_quint16,
6293 qt_alphamapblit_quint16,
6294 qt_alphargbblit_generic,
6299 blend_color_generic,
6301 qt_alphamapblit_generic,
6302 qt_alphargbblit_generic,
6307 blend_color_generic,
6309 qt_alphamapblit_generic,
6310 qt_alphargbblit_generic,
6315 blend_color_generic,
6317 qt_alphamapblit_generic,
6318 qt_alphargbblit_generic,
6323 blend_color_generic,
6325 qt_alphamapblit_generic,
6326 qt_alphargbblit_generic,
6331 blend_color_generic,
6333 qt_alphamapblit_generic,
6334 qt_alphargbblit_generic,
6339 blend_color_generic,
6341 qt_alphamapblit_generic,
6342 qt_alphargbblit_generic,
6347 blend_color_generic,
6349 qt_alphamapblit_generic,
6350 qt_alphargbblit_generic,
6355 blend_color_generic,
6357 qt_alphamapblit_generic,
6358 qt_alphargbblit_generic,
6363 blend_color_generic,
6364 qt_bitmapblit_rgba8888,
6365 qt_alphamapblit_generic,
6366 qt_alphargbblit_generic,
6371 blend_color_generic,
6372 qt_bitmapblit_rgba8888,
6373 qt_alphamapblit_generic,
6374 qt_alphargbblit_generic,
6375 qt_rectfill_nonpremul_rgba
6379 blend_color_generic,
6380 qt_bitmapblit_rgba8888,
6381 qt_alphamapblit_generic,
6382 qt_alphargbblit_generic,
6387 blend_color_generic_rgb64,
6388 qt_bitmapblit_rgb30<PixelOrderBGR>,
6389 qt_alphamapblit_generic,
6390 qt_alphargbblit_generic,
6391 qt_rectfill_rgb30<PixelOrderBGR>
6395 blend_color_generic_rgb64,
6396 qt_bitmapblit_rgb30<PixelOrderBGR>,
6397 qt_alphamapblit_generic,
6398 qt_alphargbblit_generic,
6399 qt_rectfill_rgb30<PixelOrderBGR>
6403 blend_color_generic_rgb64,
6404 qt_bitmapblit_rgb30<PixelOrderRGB>,
6405 qt_alphamapblit_generic,
6406 qt_alphargbblit_generic,
6407 qt_rectfill_rgb30<PixelOrderRGB>
6411 blend_color_generic_rgb64,
6412 qt_bitmapblit_rgb30<PixelOrderRGB>,
6413 qt_alphamapblit_generic,
6414 qt_alphargbblit_generic,
6415 qt_rectfill_rgb30<PixelOrderRGB>
6419 blend_color_generic,
6421 qt_alphamapblit_generic,
6422 qt_alphargbblit_generic,
6427 blend_color_generic,
6429 qt_alphamapblit_generic,
6430 qt_alphargbblit_generic,
6435 blend_color_generic_rgb64,
6437 qt_alphamapblit_generic,
6438 qt_alphargbblit_generic,
6443 blend_color_generic_rgb64,
6445 qt_alphamapblit_generic,
6446 qt_alphargbblit_generic,
6451 blend_color_generic_rgb64,
6453 qt_alphamapblit_generic,
6454 qt_alphargbblit_generic,
6459 blend_color_generic_rgb64,
6461 qt_alphamapblit_generic,
6462 qt_alphargbblit_generic,
6467 blend_color_generic,
6469 qt_alphamapblit_generic,
6470 qt_alphargbblit_generic,
6475 blend_color_generic_fp,
6477 qt_alphamapblit_generic,
6478 qt_alphargbblit_generic,
6483 blend_color_generic_fp,
6485 qt_alphamapblit_generic,
6486 qt_alphargbblit_generic,
6491 blend_color_generic_fp,
6493 qt_alphamapblit_generic,
6494 qt_alphargbblit_generic,
6499 blend_color_generic_fp,
6501 qt_alphamapblit_generic,
6502 qt_alphargbblit_generic,
6507 blend_color_generic_fp,
6509 qt_alphamapblit_generic,
6510 qt_alphargbblit_generic,
6515 blend_color_generic_fp,
6517 qt_alphamapblit_generic,
6518 qt_alphargbblit_generic,
6523static_assert(std::size(qDrawHelper) == QImage::NImageFormats);
6525#if !defined(Q_PROCESSOR_X86) && !defined(QT_COMPILER_SUPPORTS_LSX)
6528 qt_memfill_template<quint64>(dest, color, count);
6532#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
6533__attribute__((optimize(
"no-tree-vectorize")))
6537# ifdef QT_COMPILER_SUPPORTS_SSSE3
6538 extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
6539 if (qCpuHasFeature(SSSE3))
6540 return qt_memfill24_ssse3(dest, color, count);
6541# elif defined QT_COMPILER_SUPPORTS_LSX
6542 extern void qt_memfill24_lsx(quint24 *, quint24, qsizetype);
6543 if (qCpuHasFeature(LSX))
6544 return qt_memfill24_lsx(dest, color, count);
6547 const quint32 v = color;
6551 while ((quintptr(dest) & 0x3) && dest < end) {
6557 const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
6558 const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
6559 const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
6561 for ( ; dest <= (end - 4); dest += 4) {
6562 quint32 *dst =
reinterpret_cast<quint32 *>(dest);
6569 switch (end - dest) {
6583 const int align = quintptr(dest) & 0x3;
6590 dest[count - 1] = value;
6592 const quint32 value32 = (value << 16) | value;
6593 qt_memfill32(
reinterpret_cast<quint32*>(dest), value32, count / 2);
6596#if defined(Q_PROCESSOR_X86) || defined(QT_COMPILER_SUPPORTS_LSX)
6597void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count) =
nullptr;
6598void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count) =
nullptr;
6599#elif !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
6602 qt_memfill_template<quint32>(dest, color, count);
6606#ifdef QT_COMPILER_SUPPORTS_SSE4_1
6607template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6608#elif defined(QT_COMPILER_SUPPORTS_LSX)
6609template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6619#if defined(Q_PROCESSOR_X86) && !defined(__SSE2__
)
6620 qt_memfill32 = qt_memfill_template<quint32>;
6621 qt_memfill64 = qt_memfill_template<quint64>;
6622#elif defined(__SSE2__
)
6624 qt_memfill32 = qt_memfill32_sse2;
6625 qt_memfill64 = qt_memfill64_sse2;
6627 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
6628 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
6629 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
6630 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
6631 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_sse2;
6632 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_sse2;
6633 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
6635 extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6636 const uchar *srcPixels,
int sbpl,
int srch,
6637 const QRectF &targetRect,
6638 const QRectF &sourceRect,
6641 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6642 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6643 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6644 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6646 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels,
int dbpl,
6647 const uchar *srcPixels,
int sbpl,
6650 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6651 const uchar *srcPixels,
int sbpl,
6655 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6656 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6657 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6658 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6659 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6660 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6661 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6662 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6664 extern const uint *
QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer,
const Operator *op,
const QSpanData *data,
6665 int y,
int x,
int length);
6667 qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
6669 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6670 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6671 extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6672 extern void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6673 extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6674 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
6675 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
6676 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
6677 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_sse2;
6678 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
6680#ifdef QT_COMPILER_SUPPORTS_SSSE3
6681 if (qCpuHasFeature(SSSE3)) {
6682 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels,
int dbpl,
6683 const uchar *srcPixels,
int sbpl,
6687 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer,
const Operator *,
const QSpanData *data,
6688 int y,
int x,
int length);
6689 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6690 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6691 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6692 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6693 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
6694 extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst,
const uchar *src,
int count);
6695 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
6696 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
6700#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
6701 if (qCpuHasFeature(SSE4_1)) {
6702 extern void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6703 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6704 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6705 const QList<QRgb> *, QDitherInfo *);
6706 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6707 const QList<QRgb> *, QDitherInfo *);
6708 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6709 const QList<QRgb> *, QDitherInfo *);
6710 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6711 const QList<QRgb> *, QDitherInfo *);
6712 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6713 const QList<QRgb> *, QDitherInfo *);
6714 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6715 const QList<QRgb> *, QDitherInfo *);
6716 extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6717 const QList<QRgb> *, QDitherInfo *);
6718 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6719 const QList<QRgb> *, QDitherInfo *);
6720 extern void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6721 const QList<QRgb> *, QDitherInfo *);
6722 extern void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6723 const QList<QRgb> *, QDitherInfo *);
6724 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6725 const QList<QRgb> *, QDitherInfo *);
6726 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6727 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6728 extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6729 extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6731 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
6732 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
6733 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
6734 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
6735 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4;
6736 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4;
6737 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6738 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6739 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6740 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6742 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
6743 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
6744 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
6745 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
6746 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
6747 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
6748 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
6749 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_sse4;
6750 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_sse4;
6751#if QT_CONFIG(raster_64bit)
6752 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
6753 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
6755#if QT_CONFIG(raster_fp)
6756 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_sse4(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6757 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6758 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6759 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_sse4;
6760 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_sse4;
6761 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_sse4;
6766#if defined(QT_COMPILER_SUPPORTS_AVX2)
6767 if (qCpuHasFeature(ArchHaswell)) {
6768 qt_memfill32 = qt_memfill32_avx2;
6769 qt_memfill64 = qt_memfill64_avx2;
6770 extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels,
int dbpl,
6771 const uchar *srcPixels,
int sbpl,
6772 int w,
int h,
int const_alpha);
6773 extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels,
int dbpl,
6774 const uchar *srcPixels,
int sbpl,
6775 int w,
int h,
int const_alpha);
6776 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6777 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6778 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6779 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6780 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6781 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6782 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6783 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6785 extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6786 extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6787 extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels,
int length, uint color, uint const_alpha);
6788 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
6789 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
6790 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
6791#if QT_CONFIG(raster_64bit)
6792 extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6793 extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6794 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
6795 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
6796 qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
6797 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
6799#if QT_CONFIG(raster_fp)
6800 extern void QT_FASTCALL comp_func_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6801 extern void QT_FASTCALL comp_func_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6802 extern void QT_FASTCALL comp_func_solid_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6803 extern void QT_FASTCALL comp_func_solid_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6804 qt_functionForModeFP_C[QPainter::CompositionMode_Source] = comp_func_Source_rgbafp_avx2;
6805 qt_functionForModeFP_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgbafp_avx2;
6806 qt_functionForModeSolidFP_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_rgbafp_avx2;
6807 qt_functionForModeSolidFP_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgbafp_avx2;
6810 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6811 int &fx,
int &fy,
int fdx,
int );
6812 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6813 int &fx,
int &fy,
int fdx,
int );
6814 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6815 int &fx,
int &fy,
int fdx,
int fdy);
6817 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
6818 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
6819 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
6821 extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6822 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6823 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6824 const QList<QRgb> *, QDitherInfo *);
6825 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6826 const QList<QRgb> *, QDitherInfo *);
6827 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2;
6828 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
6829 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
6830 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
6832 extern const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
6833 extern const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
6834 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6835 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6836 extern const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6837 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2;
6838 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
6839 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
6840 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
6841 qPixelLayouts[QImage::Format_RGBA64].fetchToRGBA64PM = fetchRGBA64ToRGBA64PM_avx2;
6843 extern const uint *QT_FASTCALL fetchRGB16FToRGB32_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6844 extern const uint *QT_FASTCALL fetchRGBA16FToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6845 extern const QRgba64 *QT_FASTCALL fetchRGBA16FPMToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6846 extern const QRgba64 *QT_FASTCALL fetchRGBA16FToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6847 extern void QT_FASTCALL storeRGB16FFromRGB32_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6848 extern void QT_FASTCALL storeRGBA16FFromARGB32PM_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6849 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6850 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6851 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6852 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6853 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToARGB32PM = fetchRGBA16FToARGB32PM_avx2;
6854 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToRGBA64PM = fetchRGBA16FToRGBA64PM_avx2;
6855 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromARGB32PM = storeRGBA16FFromARGB32PM_avx2;
6856 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6857 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6858 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6859 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6860 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6861#if QT_CONFIG(raster_fp)
6862 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA16FToRGBA32F_avx2(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6863 extern void QT_FASTCALL storeRGBX16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6864 extern void QT_FASTCALL storeRGBA16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6865 qFetchToRGBA32F[QImage::Format_RGBA16FPx4] = fetchRGBA16FToRGBA32F_avx2;
6866 qStoreFromRGBA32F[QImage::Format_RGBX16FPx4] = storeRGBX16FFromRGBA32F_avx2;
6867 qStoreFromRGBA32F[QImage::Format_RGBA16FPx4] = storeRGBA16FFromRGBA32F_avx2;
6875#if defined(QT_COMPILER_SUPPORTS_LSX)
6876 if (qCpuHasFeature(LSX)) {
6877 qt_memfill32 = qt_memfill32_lsx;
6878 qt_memfill64 = qt_memfill64_lsx;
6880 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_lsx;
6881 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_lsx;
6882 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_lsx;
6883 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_lsx;
6884 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_lsx;
6885 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_lsx;
6886 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_lsx;
6888 extern void qt_scale_image_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6889 const uchar *srcPixels,
int sbpl,
int srch,
6890 const QRectF &targetRect,
6891 const QRectF &sourceRect,
6895 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6896 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6897 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6898 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6900 extern void qt_blend_rgb32_on_rgb32_lsx(uchar *destPixels,
int dbpl,
6901 const uchar *srcPixels,
int sbpl,
6905 extern void qt_blend_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6906 const uchar *srcPixels,
int sbpl,
6910 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6911 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6912 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6913 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6914 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6915 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6916 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6917 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6919 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_lsx(uint *buffer,
const Operator *op,
const QSpanData *data,
6920 int y,
int x,
int length);
6922 qt_fetch_radial_gradient = qt_fetch_radial_gradient_lsx;
6924 extern void QT_FASTCALL comp_func_SourceOver_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6925 extern void QT_FASTCALL comp_func_solid_SourceOver_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6926 extern void QT_FASTCALL comp_func_Source_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6927 extern void QT_FASTCALL comp_func_solid_Source_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6928 extern void QT_FASTCALL comp_func_Plus_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6929 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lsx;
6930 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lsx;
6931 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lsx;
6932 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_lsx;
6933 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_lsx;
6935 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_lsx(uint *buffer,
const Operator *,
const QSpanData *data,
6936 int y,
int x,
int length);
6937 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_lsx;
6938 extern void QT_FASTCALL rbSwap_888_lsx(uchar *dst,
const uchar *src,
int count);
6939 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_lsx;
6940 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_lsx;
6942 extern void QT_FASTCALL convertARGB32ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6943 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6944 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6945 const QList<QRgb> *, QDitherInfo *);
6946 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6947 const QList<QRgb> *, QDitherInfo *);
6948 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6949 const QList<QRgb> *, QDitherInfo *);
6950 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6951 const QList<QRgb> *, QDitherInfo *);
6952 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6953 const QList<QRgb> *, QDitherInfo *);
6954 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6955 const QList<QRgb> *, QDitherInfo *);
6956 extern void QT_FASTCALL storeARGB32FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6957 const QList<QRgb> *, QDitherInfo *);
6958 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6959 const QList<QRgb> *, QDitherInfo *);
6960 extern void QT_FASTCALL storeRGBXFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6961 const QList<QRgb> *, QDitherInfo *);
6962 extern void QT_FASTCALL storeARGB32FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6963 const QList<QRgb> *, QDitherInfo *);
6964 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6965 const QList<QRgb> *, QDitherInfo *);
6966 extern void QT_FASTCALL destStore64ARGB32_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6967 extern void QT_FASTCALL destStore64RGBA8888_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6968 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6969 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6970 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lsx;
6971 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lsx;
6972 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lsx;
6973 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lsx;
6974 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lsx;
6975 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lsx;
6976 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6977 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6978 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6979 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6980 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_lsx;
6981 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_lsx;
6982 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_lsx;
6983 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderBGR>;
6984 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderRGB>;
6985 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_lsx;
6986 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_lsx;
6987 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_lsx;
6988 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_lsx;
6989#if QT_CONFIG(raster_64bit)
6990 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_lsx;
6991 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_lsx;
6993#if QT_CONFIG(raster_fp)
6994 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_lsx(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6995 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6996 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6997 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_lsx;
6998 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_lsx;
6999 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_lsx;
7003#if defined(QT_COMPILER_SUPPORTS_LASX)
7004 if (qCpuHasFeature(LASX)) {
7005 qt_memfill32 = qt_memfill32_lasx;
7006 qt_memfill64 = qt_memfill64_lasx;
7008 extern void qt_blend_rgb32_on_rgb32_lasx(uchar *destPixels,
int dbpl,
7009 const uchar *srcPixels,
int sbpl,
7010 int w,
int h,
int const_alpha);
7011 extern void qt_blend_argb32_on_argb32_lasx(uchar *destPixels,
int dbpl,
7012 const uchar *srcPixels,
int sbpl,
7013 int w,
int h,
int const_alpha);
7014 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7015 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7016 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7017 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7018 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7019 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7020 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7021 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7023 extern void QT_FASTCALL comp_func_Source_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7024 extern void QT_FASTCALL comp_func_SourceOver_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7025 extern void QT_FASTCALL comp_func_solid_SourceOver_lasx(uint *destPixels,
int length, uint color, uint const_alpha);
7026 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lasx;
7027 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lasx;
7028 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lasx;
7029#if QT_CONFIG(raster_64bit)
7030 extern void QT_FASTCALL comp_func_Source_rgb64_lasx(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
7031 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_lasx(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
7032 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_lasx;
7033 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_lasx;
7036 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7037 int &fx,
int &fy,
int fdx,
int );
7038 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7039 int &fx,
int &fy,
int fdx,
int );
7040 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7041 int &fx,
int &fy,
int fdx,
int fdy);
7043 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx;
7044 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_lasx;
7045 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx;
7047 extern void QT_FASTCALL convertARGB32ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7048 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7049 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7050 const QList<QRgb> *, QDitherInfo *);
7051 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7052 const QList<QRgb> *, QDitherInfo *);
7053 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lasx;
7054 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lasx;
7055 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lasx;
7056 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lasx;
7058 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
7059 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
7060 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7061 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7062 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lasx;
7063 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lasx;
7064 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lasx;
7065 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lasx;
7071#if defined(__ARM_NEON__)
7072 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7073 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7074 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7075 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7076#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7077 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7078 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7079 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7080 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7083 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
7084 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
7085 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
7087 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer,
const Operator *op,
const QSpanData *data,
7088 int y,
int x,
int length);
7090 qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
7092 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
7094#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7095 extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7096 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7097 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7098 const QList<QRgb> *, QDitherInfo *);
7099 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7100 const QList<QRgb> *, QDitherInfo *);
7101 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7102 const QList<QRgb> *, QDitherInfo *);
7103 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7104 const QList<QRgb> *, QDitherInfo *);
7105 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7106 const QList<QRgb> *, QDitherInfo *);
7107 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7108 const QList<QRgb> *, QDitherInfo *);
7109 extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7110 const QList<QRgb> *, QDitherInfo *);
7111 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7112 const QList<QRgb> *, QDitherInfo *);
7113 extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7114 const QList<QRgb> *, QDitherInfo *);
7115 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
7116 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
7117 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
7118 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon;
7119 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon;
7120 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
7121 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
7122 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
7123 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7124 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7125 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
7126 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7127 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7130#if defined(ENABLE_PIXMAN_DRAWHELPERS)
7132 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
7133 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
7134 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
7136 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
7137 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
7139 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
7140 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
7142 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
7144 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
7145 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
7147 qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon;
7148 qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon;
7152#if defined(__MIPS_DSP__)
7154 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
7155 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
7156 qt_functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
7157 qt_functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
7158 qt_functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
7159 qt_functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
7160 qt_functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
7161 qt_functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
7162 qt_functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
7163 qt_functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
7165 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
7166 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
7167 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
7168 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
7169 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
7170 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
7171 qt_functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
7172 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
7174 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7175 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7176 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7177 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7179 destFetchProc[QImage::Format_ARGB32] = qt_destFetchARGB32_mips_dsp;
7181 destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
7183 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
7184 sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
7185 sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
7187#if defined(__MIPS_DSPR2__)
7188 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
7189 sourceFetchUntransformed[QImage::Format_RGB16] = qt_fetchUntransformedRGB16_mips_dspr2;
7191 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
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