8#include <qstylehints.h>
9#include <qguiapplication.h>
11#include <private/qcolortransform_p.h>
12#include <private/qcolortrclut_p.h>
13#include <private/qdrawhelper_p.h>
14#include <private/qdrawhelper_x86_p.h>
15#include <private/qdrawingprimitive_sse2_p.h>
16#include <private/qdrawhelper_loongarch64_p.h>
17#include <private/qdrawingprimitive_lsx_p.h>
18#include <private/qdrawhelper_neon_p.h>
19#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
20#include <private/qdrawhelper_mips_dsp_p.h>
22#include <private/qguiapplication_p.h>
23#include <private/qpaintengine_raster_p.h>
24#include <private/qpainter_p.h>
25#include <private/qpixellayout_p.h>
26#include <private/qrgba64_p.h>
28#include <qloggingcategory.h>
31#if QT_CONFIG(qtgui_threadpool)
32#include <private/qlatch_p.h>
33#include <qthreadpool.h>
34#include <private/qthreadpool_p.h>
39#if QT_CONFIG(raster_64bit) || QT_CONFIG(raster_fp)
40Q_STATIC_LOGGING_CATEGORY(lcQtGuiDrawHelper,
"qt.gui.drawhelper")
43#define MASK(src, a) src = BYTE_MUL(src, a)
46
47
55 Q_UNREACHABLE_RETURN(0);
59inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1LSB>(
const uchar *src,
int index)
61 return (src[index >> 3] >> (index & 7)) & 1;
65inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1MSB>(
const uchar *src,
int index)
67 return (src[index >> 3] >> (~index & 7)) & 1;
71inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP8>(
const uchar *src,
int index)
77inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16>(
const uchar *src,
int index)
79 return reinterpret_cast<
const quint16 *>(src)[index];
83inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP24>(
const uchar *src,
int index)
85 return reinterpret_cast<
const quint24 *>(src)[index];
89inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32>(
const uchar *src,
int index)
91 return reinterpret_cast<
const uint *>(src)[index];
95inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP64>(
const uchar *src,
int index)
98 QRgba64 c =
reinterpret_cast<
const QRgba64 *>(src)[index];
103inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16FPx4>(
const uchar *src,
int index)
106 QRgbaFloat16 c =
reinterpret_cast<
const QRgbaFloat16 *>(src)[index];
111inline uint QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32FPx4>(
const uchar *src,
int index)
114 QRgbaFloat32 c =
reinterpret_cast<
const QRgbaFloat32 *>(src)[index];
122 fetch1Pixel<QPixelLayout::BPP1MSB>,
123 fetch1Pixel<QPixelLayout::BPP1LSB>,
124 fetch1Pixel<QPixelLayout::BPP8>,
125 fetch1Pixel<QPixelLayout::BPP16>,
126 fetch1Pixel<QPixelLayout::BPP24>,
127 fetch1Pixel<QPixelLayout::BPP32>,
128 fetch1Pixel<QPixelLayout::BPP64>,
129 fetch1Pixel<QPixelLayout::BPP16FPx4>,
130 fetch1Pixel<QPixelLayout::BPP32FPx4>,
133#if QT_CONFIG(raster_64bit)
134static void QT_FASTCALL convertRGBA64ToRGBA64PM(QRgba64 *buffer,
int count)
136 for (
int i = 0; i < count; ++i)
137 buffer[i] = buffer[i].premultiplied();
140static void QT_FASTCALL convertRGBA64PMToRGBA64PM(QRgba64 *,
int)
144static void QT_FASTCALL convertRGBA16FToRGBA64PM(QRgba64 *buffer,
int count)
146 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
147 for (
int i = 0; i < count; ++i) {
148 QRgbaFloat16 c = in[i];
149 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
153static void QT_FASTCALL convertRGBA16FPMToRGBA64PM(QRgba64 *buffer,
int count)
155 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
156 for (
int i = 0; i < count; ++i) {
157 QRgbaFloat16 c = in[i];
158 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
162static void QT_FASTCALL convertRGBA32FToRGBA64PM(QRgba64 *buffer,
int count)
164 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
165 for (
int i = 0; i < count; ++i) {
166 QRgbaFloat32 c = in[i];
167 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
171static void QT_FASTCALL convertRGBA32FPMToRGBA64PM(QRgba64 *buffer,
int count)
173 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
174 for (
int i = 0; i < count; ++i) {
175 QRgbaFloat32 c = in[i];
176 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
180static Convert64Func convert64ToRGBA64PM[] = {
206 convertRGBA64PMToRGBA64PM,
207 convertRGBA64ToRGBA64PM,
208 convertRGBA64PMToRGBA64PM,
211 convertRGBA16FPMToRGBA64PM,
212 convertRGBA16FToRGBA64PM,
213 convertRGBA16FPMToRGBA64PM,
214 convertRGBA32FPMToRGBA64PM,
215 convertRGBA32FToRGBA64PM,
216 convertRGBA32FPMToRGBA64PM,
220static_assert(std::size(convert64ToRGBA64PM) == QImage::NImageFormats);
223#if QT_CONFIG(raster_fp)
224static void QT_FASTCALL convertRGBA64PMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
226 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
227 for (
int i = 0; i < count; ++i) {
229 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha()).premultiplied();
233static void QT_FASTCALL convertRGBA64ToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
235 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
236 for (
int i = 0; i < count; ++i) {
238 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
242static void QT_FASTCALL convertRGBA16FPMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
244 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
245 for (
int i = 0; i < count; ++i)
246 buffer[i] = buffer[i].premultiplied();
249static void QT_FASTCALL convertRGBA16FToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
251 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
254static Convert64ToFPFunc convert64ToRGBA32F[] = {
280 convertRGBA64ToRGBA32F,
281 convertRGBA64PMToRGBA32F,
282 convertRGBA64ToRGBA32F,
285 convertRGBA16FToRGBA32F,
286 convertRGBA16FPMToRGBA32F,
287 convertRGBA16FToRGBA32F,
294static_assert(std::size(convert64ToRGBA32F) == QImage::NImageFormats);
296static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer,
int count)
298 for (
int i = 0; i < count; ++i)
299 buffer[i] = buffer[i].premultiplied();
302static void convertRGBA32FToRGBA32F(QRgbaFloat32 *,
int)
309
310
311
313static uint * QT_FASTCALL destFetchMono(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
316 uint *start = buffer;
317 const uint *end = buffer + length;
318 while (buffer < end) {
319 *buffer = data[x>>3] & (0x80 >> (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
326static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
329 uint *start = buffer;
330 const uint *end = buffer + length;
331 while (buffer < end) {
332 *buffer = data[x>>3] & (0x1 << (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
339static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
341 return (uint *)rasterBuffer->scanLine(y) + x;
344static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
346 const ushort *
Q_DECL_RESTRICT data = (
const ushort *)rasterBuffer->scanLine(y) + x;
347 for (
int i = 0; i < length; ++i)
348 buffer[i] = qConvertRgb16To32(data[i]);
352static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
354 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
355 return const_cast<uint *>(layout->fetchToARGB32PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
358static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *,
int,
int,
int)
404static_assert(std::size(destFetchProc) == QImage::NImageFormats);
406#if QT_CONFIG(raster_64bit)
407static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
409 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
410 return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
413static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
415 return (QRgba64 *)rasterBuffer->scanLine(y) + x;
418static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *,
int,
int,
int)
423static DestFetchProc64 destFetchProc64[] =
464static_assert(std::size(destFetchProc64) == QImage::NImageFormats);
467#if QT_CONFIG(raster_fp)
468static QRgbaFloat32 *QT_FASTCALL destFetchFP(QRgbaFloat32 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
470 return const_cast<QRgbaFloat32 *>(qFetchToRGBA32F[rasterBuffer->format](buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
473static QRgbaFloat32 *QT_FASTCALL destFetchRGBFP(QRgbaFloat32 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
475 return reinterpret_cast<QRgbaFloat32 *>(rasterBuffer->scanLine(y)) + x;
478static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRasterBuffer *,
int,
int,
int)
482static DestFetchProcFP destFetchProcFP[] =
523static_assert(std::size(destFetchProcFP) == QImage::NImageFormats);
527
528
529
532 const QRgb color_0 = rbuf->destColor0;
533 const QRgb color_1 = rbuf->destColor1;
536 int g = qGreen(color);
537 int b = qBlue(color);
541 rx = r - qRed(color_0);
542 gx = g - qGreen(color_0);
543 bx = b - qBlue(color_0);
544 dist_0 = rx*rx + gx*gx + bx*bx;
546 rx = r - qRed(color_1);
547 gx = g - qGreen(color_1);
548 bx = b - qBlue(color_1);
549 dist_1 = rx*rx + gx*gx + bx*bx;
557
558
560static void QT_FASTCALL destStoreMono(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
563 if (rasterBuffer->monoDestinationWithClut) {
564 for (
int i = 0; i < length; ++i) {
565 if (buffer[i] == rasterBuffer->destColor0) {
566 data[x >> 3] &= ~(0x80 >> (x & 7));
567 }
else if (buffer[i] == rasterBuffer->destColor1) {
568 data[x >> 3] |= 0x80 >> (x & 7);
569 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
570 data[x >> 3] &= ~(0x80 >> (x & 7));
572 data[x >> 3] |= 0x80 >> (x & 7);
577 for (
int i = 0; i < length; ++i) {
578 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
579 data[x >> 3] |= 0x80 >> (x & 7);
581 data[x >> 3] &= ~(0x80 >> (x & 7));
587static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
590 if (rasterBuffer->monoDestinationWithClut) {
591 for (
int i = 0; i < length; ++i) {
592 if (buffer[i] == rasterBuffer->destColor0) {
593 data[x >> 3] &= ~(1 << (x & 7));
594 }
else if (buffer[i] == rasterBuffer->destColor1) {
595 data[x >> 3] |= 1 << (x & 7);
596 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
597 data[x >> 3] &= ~(1 << (x & 7));
599 data[x >> 3] |= 1 << (x & 7);
604 for (
int i = 0; i < length; ++i) {
605 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
606 data[x >> 3] |= 1 << (x & 7);
608 data[x >> 3] &= ~(1 << (x & 7));
614static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
616 quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x;
617 for (
int i = 0; i < length; ++i)
618 data[i] = qConvertRgb32To16(buffer[i]);
621static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
623 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
624 ConvertAndStorePixelsFunc store = layout->storeFromARGB32PM;
625 if (!layout->premultiplied && !layout->hasAlphaChannel)
626 store = layout->storeFromRGB32;
627 uchar *dest = rasterBuffer->scanLine(y);
628 store(dest, buffer, x, length,
nullptr,
nullptr);
631static void QT_FASTCALL destStoreGray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
633 uchar *data = rasterBuffer->scanLine(y) + x;
636 for (
int k = 0; k < length; ++k) {
637 if (!qIsGray(buffer[k])) {
641 data[k] = qRed(buffer[k]);
644 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
645 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
646 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
648 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
652static void QT_FASTCALL destStoreGray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
654 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
657 for (
int k = 0; k < length; ++k) {
658 if (!qIsGray(buffer[k])) {
662 data[k] = qRed(buffer[k]) * 257;
665 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
666 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
667 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
669 Q_DECL_UNINITIALIZED QRgba64 tmp_line[BufferSize];
670 for (
int k = 0; k < length; ++k)
671 tmp_line[k] = QRgba64::fromArgb32(buffer[k]);
672 tfd->apply(data, tmp_line, length, QColorTransformPrivate::InputPremultiplied);
717static_assert(std::size(destStoreProc) == QImage::NImageFormats);
719#if QT_CONFIG(raster_64bit)
720static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
722 auto store = qStoreFromRGBA64PM[rasterBuffer->format];
723 uchar *dest = rasterBuffer->scanLine(y);
724 store(dest, buffer, x, length,
nullptr,
nullptr);
727static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
729 QRgba64 *dest =
reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
730 for (
int i = 0; i < length; ++i) {
731 dest[i] = buffer[i].unpremultiplied();
735static void QT_FASTCALL destStore64Gray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
737 uchar *data = rasterBuffer->scanLine(y) + x;
740 for (
int k = 0; k < length; ++k) {
741 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
745 data[k] = buffer[k].red8();
748 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
749 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
750 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
752 Q_DECL_UNINITIALIZED quint16 gray_line[BufferSize];
753 tfd->apply(gray_line, buffer, length, QColorTransformPrivate::InputPremultiplied);
754 for (
int k = 0; k < length; ++k)
755 data[k] = qt_div_257(gray_line[k]);
759static void QT_FASTCALL destStore64Gray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
761 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
764 for (
int k = 0; k < length; ++k) {
765 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
769 data[k] = buffer[k].red();
772 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
773 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
774 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
775 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
779static DestStoreProc64 destStoreProc64[] =
820static_assert(std::size(destStoreProc64) == QImage::NImageFormats);
823#if QT_CONFIG(raster_fp)
824static void QT_FASTCALL destStoreFP(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgbaFloat32 *buffer,
int length)
826 auto store = qStoreFromRGBA32F[rasterBuffer->format];
827 uchar *dest = rasterBuffer->scanLine(y);
828 store(dest, buffer, x, length,
nullptr,
nullptr);
833
834
835
836
837
838
839
840
841
842
843
844
845
857static const uint *QT_FASTCALL fetchUntransformed(uint *buffer,
const Operator *,
858 const QSpanData *data,
int y,
int x,
int length)
860 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
861 return layout->fetchToARGB32PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
864static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *,
const Operator *,
865 const QSpanData *data,
int y,
int x,
int)
867 const uchar *scanLine = data->texture.scanLine(y);
868 return reinterpret_cast<
const uint *>(scanLine) + x;
871static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer,
const Operator *,
872 const QSpanData *data,
int y,
int x,
875 const quint16 *scanLine = (
const quint16 *)data->texture.scanLine(y) + x;
876 for (
int i = 0; i < length; ++i)
877 buffer[i] = qConvertRgb16To32(scanLine[i]);
881#if QT_CONFIG(raster_64bit)
882static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer,
const Operator *,
883 const QSpanData *data,
int y,
int x,
int length)
885 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
886 return layout->fetchToRGBA64PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
889static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *,
const Operator *,
890 const QSpanData *data,
int y,
int x,
int)
892 const uchar *scanLine = data->texture.scanLine(y);
893 return reinterpret_cast<
const QRgba64 *>(scanLine) + x;
897#if QT_CONFIG(raster_fp)
898static const QRgbaFloat32 *QT_FASTCALL fetchUntransformedFP(QRgbaFloat32 *buffer,
const Operator *,
899 const QSpanData *data,
int y,
int x,
int length)
901 const auto fetch = qFetchToRGBA32F[data->texture.format];
902 return fetch(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
911 if (v < 0 || v >= max) {
916 v = qBound(l1, v, l2);
922 if (Q_UNLIKELY(!data->fast_matrix))
925 qreal fx = (data->m21 * cy + data->m11 * cx + data->dx) *
fixed_scale;
926 qreal fy = (data->m22 * cy + data->m12 * cx + data->dy) *
fixed_scale;
927 qreal minc =
std::min(fx, fy);
928 qreal maxc =
std::max(fx, fy);
931 minc =
std::min(minc,
std::min(fx, fy));
932 maxc =
std::max(maxc,
std::max(fx, fy));
934 return minc >=
std::numeric_limits<
int>::min() && maxc <= qreal(
std::numeric_limits<
int>::max());
938static void QT_FASTCALL fetchTransformed_fetcher(T *buffer,
const QSpanData *data,
939 int y,
int x,
int length)
941 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
942 const QTextureData &image = data->texture;
944 const qreal cx = x + qreal(0.5);
945 const qreal cy = y + qreal(0.5);
947 constexpr bool useFetch = (bpp < QPixelLayout::BPP32) &&
sizeof(T) ==
sizeof(uint);
948 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
950 Q_ASSERT(layout->bpp == bpp || (layout->bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
952 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout->bpp] : Fetch1PixelFunc(fetch1Pixel<bpp>);
954 if (canUseFastMatrixPath(cx, cy, length, data)) {
956 int fdx = (
int)(data->m11 * fixed_scale);
957 int fdy = (
int)(data->m12 * fixed_scale);
959 int fx =
int((data->m21 * cy
960 + data->m11 * cx + data->dx) * fixed_scale);
961 int fy =
int((data->m22 * cy
962 + data->m12 * cx + data->dy) * fixed_scale);
966 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
967 const uchar *src = image.scanLine(py);
970 if (blendType == BlendTransformed) {
971 int fastLen = length;
973 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
975 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
977 for (; i < fastLen; ++i) {
980 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
983 if constexpr (useFetch)
984 buffer[i] = fetch1(src, x1);
986 buffer[i] =
reinterpret_cast<
const T*>(src)[x1];
990 for (; i < fastLen; ++i) {
992 if constexpr (useFetch)
993 buffer[i] = fetch1(src, px);
995 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1000 for (; i < length; ++i) {
1001 int px = (fx >> 16);
1002 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1003 if constexpr (useFetch)
1004 buffer[i] = fetch1(src, px);
1006 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1011 if (blendType == BlendTransformed) {
1012 int fastLen = length;
1014 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
1016 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
1018 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
1020 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
1022 for (; i < fastLen; ++i) {
1023 int x1 = (fx >> 16);
1024 int y1 = (fy >> 16);
1027 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
1028 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1);
1029 if (x1 == x2 && y1 == y2)
1031 if constexpr (useFetch)
1032 buffer[i] = fetch1(image.scanLine(y1), x1);
1034 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(y1))[x1];
1039 for (; i < fastLen; ++i) {
1040 int px = (fx >> 16);
1041 int py = (fy >> 16);
1042 if constexpr (useFetch)
1043 buffer[i] = fetch1(image.scanLine(py), px);
1045 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1051 for (; i < length; ++i) {
1052 int px = (fx >> 16);
1053 int py = (fy >> 16);
1054 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1055 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1056 if constexpr (useFetch)
1057 buffer[i] = fetch1(image.scanLine(py), px);
1059 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1065 const qreal fdx = data->m11;
1066 const qreal fdy = data->m12;
1067 const qreal fdw = data->m13;
1069 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
1070 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
1071 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
1073 T *
const end = buffer + length;
1076 const qreal iw = fw == 0 ? 1 : 1 / fw;
1077 const qreal tx = fx * iw;
1078 const qreal ty = fy * iw;
1079 int px = qFloor(tx);
1080 int py = qFloor(ty);
1082 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1083 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1084 if constexpr (useFetch)
1085 *b = fetch1(image.scanLine(py), px);
1087 *b =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1102static const uint *
QT_FASTCALL fetchTransformed(uint *buffer,
const Operator *,
const QSpanData *data,
1103 int y,
int x,
int length)
1105 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
1106 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1107 fetchTransformed_fetcher<blendType, bpp, uint>(buffer, data, y, x, length);
1108 layout->convertToARGB32PM(buffer, length, data->texture.colorTable);
1112#if QT_CONFIG(raster_64bit)
1113template<TextureBlendType blendType>
1114static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
1115 int y,
int x,
int length)
1117 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1118 if (layout->bpp < QPixelLayout::BPP64) {
1119 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1120 Q_ASSERT(length <= BufferSize);
1121 if (layout->bpp == QPixelLayout::BPP32)
1122 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1124 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1125 return layout->convertToRGBA64PM(buffer, buffer32, length, data->texture.colorTable,
nullptr);
1128 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(
reinterpret_cast<quint64*>(buffer), data, y, x, length);
1129 if (
auto convert = convert64ToRGBA64PM[data->texture.format])
1130 convert(buffer, length);
1135#if QT_CONFIG(raster_fp)
1136template<TextureBlendType blendType>
1137static const QRgbaFloat32 *QT_FASTCALL fetchTransformedFP(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
1138 int y,
int x,
int length)
1140 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1141 if (layout->bpp < QPixelLayout::BPP64) {
1142 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1143 Q_ASSERT(length <= BufferSize);
1144 if (layout->bpp == QPixelLayout::BPP32)
1145 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1147 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1148 qConvertToRGBA32F[data->texture.format](buffer, buffer32, length, data->texture.colorTable,
nullptr);
1149 }
else if (layout->bpp < QPixelLayout::BPP32FPx4) {
1150 Q_DECL_UNINITIALIZED quint64 buffer64[BufferSize];
1151 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(buffer64, data, y, x, length);
1152 convert64ToRGBA32F[data->texture.format](buffer, buffer64, length);
1154 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>(buffer, data, y, x, length);
1155 if (data->texture.format == QImage::Format_RGBA32FPx4)
1156 convertRGBA32FToRGBA32FPM(buffer, length);
1164
1165
1166
1169 uint distxy = distx * disty;
1172 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
1173 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
1174 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
1175 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy));
1176 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy));
1177 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy));
1178 uint brrb = ((br & 0x00ff00ff) * (distxy));
1179 uint brag = (((br & 0xff00ff00) >> 8) * (distxy));
1180 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
1183#if defined(__SSE2__
)
1184#define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \
1185{
1186 const __m128i dxdy = _mm_mullo_epi16 (distx, disty);
1187 const __m128i distx_ = _mm_slli_epi16(distx, 4
);
1188 const __m128i disty_ = _mm_slli_epi16(disty, 4
);
1189 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_)));
1190 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy);
1191 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy);
1193 __m128i tlAG = _mm_srli_epi16(tl, 8
);
1194 __m128i tlRB = _mm_and_si128(tl, colorMask);
1195 __m128i trAG = _mm_srli_epi16(tr, 8
);
1196 __m128i trRB = _mm_and_si128(tr, colorMask);
1197 __m128i blAG = _mm_srli_epi16(bl, 8
);
1198 __m128i blRB = _mm_and_si128(bl, colorMask);
1199 __m128i brAG = _mm_srli_epi16(br, 8
);
1200 __m128i brRB = _mm_and_si128(br, colorMask);
1202 tlAG = _mm_mullo_epi16(tlAG, idxidy);
1203 tlRB = _mm_mullo_epi16(tlRB, idxidy);
1204 trAG = _mm_mullo_epi16(trAG, dxidy);
1205 trRB = _mm_mullo_epi16(trRB, dxidy);
1206 blAG = _mm_mullo_epi16(blAG, idxdy);
1207 blRB = _mm_mullo_epi16(blRB, idxdy);
1208 brAG = _mm_mullo_epi16(brAG, dxdy);
1209 brRB = _mm_mullo_epi16(brRB, dxdy);
1212 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG));
1213 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB));
1214 rAG = _mm_andnot_si128(colorMask, rAG);
1215 rRB = _mm_srli_epi16(rRB, 8
);
1216 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \
1217}
1220#if defined(__ARM_NEON__)
1221#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \
1222{
1223 const int16x8_t dxdy = vmulq_s16(distx, disty);
1224 const int16x8_t distx_ = vshlq_n_s16(distx, 4
);
1225 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_)));
1226 const int16x8_t dxidy = vsubq_s16(distx_, dxdy);
1227 const int16x8_t idxdy = vsubq_s16(disty_, dxdy);
1229 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8
));
1230 int16x8_t tlRB = vandq_s16(tl, colorMask);
1231 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8
));
1232 int16x8_t trRB = vandq_s16(tr, colorMask);
1233 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8
));
1234 int16x8_t blRB = vandq_s16(bl, colorMask);
1235 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8
));
1236 int16x8_t brRB = vandq_s16(br, colorMask);
1238 int16x8_t rAG = vmulq_s16(tlAG, idxidy);
1239 int16x8_t rRB = vmulq_s16(tlRB, idxidy);
1240 rAG = vmlaq_s16(rAG, trAG, dxidy);
1241 rRB = vmlaq_s16(rRB, trRB, dxidy);
1242 rAG = vmlaq_s16(rAG, blAG, idxdy);
1243 rRB = vmlaq_s16(rRB, blRB, idxdy);
1244 rAG = vmlaq_s16(rAG, brAG, dxdy);
1245 rRB = vmlaq_s16(rRB, brRB, dxdy);
1247 rAG = vandq_s16(invColorMask, rAG);
1248 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8
));
1249 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \
1250}
1253#if defined(__loongarch_sx)
1254static inline void interpolate_4_pixels_16_lsx(__m128i tl, __m128i tr, __m128i bl, __m128i br,
1255 __m128i distx, __m128i disty, uint *b)
1257 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1258 const __m128i v_256 = __lsx_vreplgr2vr_h(256);
1259 const __m128i dxdy = __lsx_vmul_h(distx, disty);
1260 const __m128i distx_ = __lsx_vslli_h(distx, 4);
1261 const __m128i disty_ = __lsx_vslli_h(disty, 4);
1262 const __m128i idxidy = __lsx_vadd_h(dxdy, __lsx_vsub_h(v_256, __lsx_vadd_h(distx_, disty_)));
1263 const __m128i dxidy = __lsx_vsub_h(distx_, dxdy);
1264 const __m128i idxdy = __lsx_vsub_h(disty_,dxdy);
1266 __m128i tlAG = __lsx_vsrli_h(tl, 8);
1267 __m128i tlRB = __lsx_vand_v(tl, colorMask);
1268 __m128i trAG = __lsx_vsrli_h(tr, 8);
1269 __m128i trRB = __lsx_vand_v(tr, colorMask);
1270 __m128i blAG = __lsx_vsrli_h(bl, 8);
1271 __m128i blRB = __lsx_vand_v(bl, colorMask);
1272 __m128i brAG = __lsx_vsrli_h(br, 8);
1273 __m128i brRB = __lsx_vand_v(br, colorMask);
1275 tlAG = __lsx_vmul_h(tlAG, idxidy);
1276 tlRB = __lsx_vmul_h(tlRB, idxidy);
1277 trAG = __lsx_vmul_h(trAG, dxidy);
1278 trRB = __lsx_vmul_h(trRB, dxidy);
1279 blAG = __lsx_vmul_h(blAG, idxdy);
1280 blRB = __lsx_vmul_h(blRB, idxdy);
1281 brAG = __lsx_vmul_h(brAG, dxdy);
1282 brRB = __lsx_vmul_h(brRB, dxdy);
1284 __m128i rAG =__lsx_vadd_h(__lsx_vadd_h(tlAG, trAG), __lsx_vadd_h(blAG, brAG));
1285 __m128i rRB =__lsx_vadd_h(__lsx_vadd_h(tlRB, trRB), __lsx_vadd_h(blRB, brRB));
1286 rAG = __lsx_vandn_v(colorMask, rAG);
1287 rRB = __lsx_vsrli_h(rRB, 8);
1288 __lsx_vst(__lsx_vor_v(rAG, rRB), b, 0);
1304 Q_ASSERT(v1 >= 0 && v1 < max);
1305 Q_ASSERT(v2 >= 0 && v2 < max);
1317 Q_ASSERT(v1 >= l1 && v1 <= l2);
1318 Q_ASSERT(v2 >= l1 && v2 <= l2);
1332static void QT_FASTCALL intermediate_adder(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx)
1334#if defined(QT_COMPILER_SUPPORTS_AVX2)
1335 extern void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx);
1336 if (qCpuHasFeature(ArchHaswell))
1337 return intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
1341 fx -= offset * fixed_scale;
1344 const int x = (fx >> 16);
1346 const uint distx = (fx & 0x0000ffff) >> 8;
1347 const uint idistx = 256 - distx;
1348 const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
1349 const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
1350 *b = (rb >> 8) | ag;
1354 fx += offset * fixed_scale;
1360static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
1361 int &fx,
int &fy,
int fdx,
int )
1363 int y1 = (fy >> 16);
1365 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1366 const uint *s1 = (
const uint *)image.scanLine(y1);
1367 const uint *s2 = (
const uint *)image.scanLine(y2);
1369 const int disty = (fy & 0x0000ffff) >> 8;
1370 const int idisty = 256 - disty;
1371 const int length = end - b;
1374 const int adjust = (fdx < 0) ? fdx * length : 0;
1375 const int offset = (fx + adjust) >> 16;
1378 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
1380 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
1383 Q_ASSERT(count <= BufferSize + 2);
1386 if (blendType == BlendTransformedBilinearTiled) {
1388 if (x < 0) x += image.width;
1390 lim = qMin(count, image.x2 - x);
1392 Q_ASSERT(x < image.x2);
1393 uint t = s1[image.x1];
1394 uint b = s2[image.x1];
1395 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1396 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1398 intermediate.buffer_rb[f] = rb;
1399 intermediate.buffer_ag[f] = ag;
1402 }
while (x < image.x1 && f < lim);
1406 if (blendType != BlendTransformedBilinearTiled) {
1407#if defined(__SSE2__
)
1408 const __m128i disty_ = _mm_set1_epi16(disty);
1409 const __m128i idisty_ = _mm_set1_epi16(idisty);
1410 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1413 for (; f < lim; x += 4, f += 4) {
1415 __m128i top = _mm_loadu_si128((
const __m128i*)((
const uint *)(s1)+x));
1416 __m128i topAG = _mm_srli_epi16(top, 8);
1417 __m128i topRB = _mm_and_si128(top, colorMask);
1419 topAG = _mm_mullo_epi16 (topAG, idisty_);
1420 topRB = _mm_mullo_epi16 (topRB, idisty_);
1423 __m128i bottom = _mm_loadu_si128((
const __m128i*)((
const uint *)(s2)+x));
1424 __m128i bottomAG = _mm_srli_epi16(bottom, 8);
1425 __m128i bottomRB = _mm_and_si128(bottom, colorMask);
1426 bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
1427 bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
1430 __m128i rAG =_mm_add_epi16(topAG, bottomAG);
1431 rAG = _mm_srli_epi16(rAG, 8);
1432 _mm_storeu_si128((__m128i*)(&intermediate.buffer_ag[f]), rAG);
1433 __m128i rRB =_mm_add_epi16(topRB, bottomRB);
1434 rRB = _mm_srli_epi16(rRB, 8);
1435 _mm_storeu_si128((__m128i*)(&intermediate.buffer_rb[f]), rRB);
1437#elif defined(__ARM_NEON__)
1438 const int16x8_t disty_ = vdupq_n_s16(disty);
1439 const int16x8_t idisty_ = vdupq_n_s16(idisty);
1440 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1443 for (; f < lim; x += 4, f += 4) {
1445 int16x8_t top = vld1q_s16((int16_t*)((
const uint *)(s1)+x));
1446 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8));
1447 int16x8_t topRB = vandq_s16(top, colorMask);
1449 topAG = vmulq_s16(topAG, idisty_);
1450 topRB = vmulq_s16(topRB, idisty_);
1453 int16x8_t bottom = vld1q_s16((int16_t*)((
const uint *)(s2)+x));
1454 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8));
1455 int16x8_t bottomRB = vandq_s16(bottom, colorMask);
1456 bottomAG = vmulq_s16(bottomAG, disty_);
1457 bottomRB = vmulq_s16(bottomRB, disty_);
1460 int16x8_t rAG = vaddq_s16(topAG, bottomAG);
1461 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
1462 vst1q_s16((int16_t*)(&intermediate.buffer_ag[f]), rAG);
1463 int16x8_t rRB = vaddq_s16(topRB, bottomRB);
1464 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
1465 vst1q_s16((int16_t*)(&intermediate.buffer_rb[f]), rRB);
1467#elif defined(__loongarch_sx)
1468 const __m128i disty_ = __lsx_vreplgr2vr_h(disty);
1469 const __m128i idisty_ = __lsx_vreplgr2vr_h(idisty);
1470 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1473 for (; f < lim; x += 4, f += 4) {
1475 __m128i top = __lsx_vld((
const __m128i*)((
const uint *)(s1)+x), 0);
1476 __m128i topAG = __lsx_vsrli_h(top, 8);
1477 __m128i topRB = __lsx_vand_v(top, colorMask);
1479 topAG = __lsx_vmul_h(topAG, idisty_);
1480 topRB = __lsx_vmul_h(topRB, idisty_);
1483 __m128i bottom = __lsx_vld((
const __m128i*)((
const uint *)(s2)+x), 0);
1484 __m128i bottomAG = __lsx_vsrli_h(bottom, 8);
1485 __m128i bottomRB = __lsx_vand_v(bottom, colorMask);
1486 bottomAG = __lsx_vmul_h(bottomAG, disty_);
1487 bottomRB = __lsx_vmul_h(bottomRB, disty_);
1490 __m128i rAG = __lsx_vadd_h(topAG, bottomAG);
1491 rAG = __lsx_vsrli_h(rAG, 8);
1492 __lsx_vst(rAG, (__m128i*)(&intermediate.buffer_ag[f]), 0);
1493 __m128i rRB = __lsx_vadd_h(topRB, bottomRB);
1494 rRB = __lsx_vsrli_h(rRB, 8);
1495 __lsx_vst(rRB, (__m128i*)(&intermediate.buffer_rb[f]), 0);
1499 for (; f < count; f++) {
1500 if (blendType == BlendTransformedBilinearTiled) {
1501 if (x >= image.width) x -= image.width;
1503 x = qMin(x, image.x2 - 1);
1509 intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1510 intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1515 intermediate_adder(b, end, intermediate, offset, fx, fdx);
1519static void QT_FASTCALL fetchTransformedBilinearARGB32PM_upscale_helper(uint *b, uint *end,
const QTextureData &image,
1520 int &fx,
int &fy,
int fdx,
int )
1522 int y1 = (fy >> 16);
1524 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1525 const uint *s1 = (
const uint *)image.scanLine(y1);
1526 const uint *s2 = (
const uint *)image.scanLine(y2);
1527 const int disty = (fy & 0x0000ffff) >> 8;
1529 if (blendType != BlendTransformedBilinearTiled) {
1530 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1531 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1533 int x1 = (fx >> 16);
1535 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1540 *b = INTERPOLATE_PIXEL_256(top, 256 - disty, bot, disty);
1544 uint *boundedEnd = end;
1546 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1548 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1551 while (b < boundedEnd) {
1553 int distx = (fx & 0x0000ffff) >> 8;
1554 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
1561 int x1 = (fx >> 16);
1563 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1 , x1, x2);
1568 int distx = (fx & 0x0000ffff) >> 8;
1569 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1577static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *b, uint *end,
const QTextureData &image,
1578 int &fx,
int &fy,
int fdx,
int )
1580 int y1 = (fy >> 16);
1582 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1583 const uint *s1 = (
const uint *)image.scanLine(y1);
1584 const uint *s2 = (
const uint *)image.scanLine(y2);
1585 const int disty8 = (fy & 0x0000ffff) >> 8;
1586 const int disty4 = (disty8 + 0x08) >> 4;
1588 if (blendType != BlendTransformedBilinearTiled) {
1589 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1590 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1592 int x1 = (fx >> 16);
1594 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1599 *b = INTERPOLATE_PIXEL_256(top, 256 - disty8, bot, disty8);
1603 uint *boundedEnd = end;
1605 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1607 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1609#if defined(__SSE2__
)
1610 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1611 const __m128i v_256 = _mm_set1_epi16(256);
1612 const __m128i v_disty = _mm_set1_epi16(disty4);
1613 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1614 const __m128i v_fx_r = _mm_set1_epi32(0x8);
1615 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1617 while (b < boundedEnd - 3) {
1618 __m128i offset = _mm_srli_epi32(v_fx, 16);
1619 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1620 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1621 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1622 const int offset3 = _mm_cvtsi128_si32(offset);
1623 const __m128i tl = _mm_setr_epi32(s1[offset0], s1[offset1], s1[offset2], s1[offset3]);
1624 const __m128i tr = _mm_setr_epi32(s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]);
1625 const __m128i bl = _mm_setr_epi32(s2[offset0], s2[offset1], s2[offset2], s2[offset3]);
1626 const __m128i br = _mm_setr_epi32(s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]);
1628 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1629 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fx_r), 4);
1630 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1631 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1633 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1635 v_fx = _mm_add_epi32(v_fx, v_fdx);
1637 fx = _mm_cvtsi128_si32(v_fx);
1638#elif defined(__ARM_NEON__)
1639 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1640 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1641 const int16x8_t v_256 = vdupq_n_s16(256);
1642 const int16x8_t v_disty = vdupq_n_s16(disty4);
1643 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
1644 int32x4_t v_fdx = vdupq_n_s32(fdx*4);
1646 int32x4_t v_fx = vmovq_n_s32(fx);
1647 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1648 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1649 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1651 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1652 const int32x4_t v_fx_r = vdupq_n_s32(0x0800);
1655 uint32x4x2_t v_top = {};
1656 uint32x4x2_t v_bot = {};
1657 while (b < boundedEnd - 3) {
1658 int x1 = (fx >> 16);
1660 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1661 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1664 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1665 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1668 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1669 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1672 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1673 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1675 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_fx_r), 12);
1676 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1678 interpolate_4_pixels_16_neon(
1679 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1680 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1681 vreinterpretq_s16_s32(v_distx), v_disty, v_disty_,
1682 colorMask, invColorMask, v_256, b);
1684 v_fx = vaddq_s32(v_fx, v_fdx);
1686#elif defined (__loongarch_sx)
1687 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1688 const __m128i v_disty = __lsx_vreplgr2vr_h(disty4);
1689 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1690 const __m128i v_fx_r = __lsx_vreplgr2vr_w(0x8);
1691 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1693 while (b < boundedEnd - 3) {
1694 __m128i offset = __lsx_vsrli_w(v_fx, 16);
1695 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1696 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1697 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1698 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1699 const __m128i tl = (__m128i)(v4u32){s1[offset0], s1[offset1], s1[offset2], s1[offset3]};
1700 const __m128i tr = (__m128i)(v4u32){s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]};
1701 const __m128i bl = (__m128i)(v4u32){s2[offset0], s2[offset1], s2[offset2], s2[offset3]};
1702 const __m128i br = (__m128i)(v4u32){s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]};
1704 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1705 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fx_r), 4);
1706 v_distx = __lsx_vshuf_h(shuffleMask, v_distx, v_distx);
1708 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1710 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1712 fx = __lsx_vpickve2gr_w(v_fx, 0);
1714 while (b < boundedEnd) {
1716 if (hasFastInterpolate4()) {
1717 int distx8 = (fx & 0x0000ffff) >> 8;
1718 *b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
1720 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1721 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx4, disty4);
1729 int x1 = (fx >> 16);
1731 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1736 if (hasFastInterpolate4()) {
1737 int distx8 = (fx & 0x0000ffff) >> 8;
1738 *b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
1740 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1741 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
1749static void QT_FASTCALL fetchTransformedBilinearARGB32PM_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1750 int &fx,
int &fy,
int fdx,
int fdy)
1754 int x1 = (fx >> 16);
1756 int y1 = (fy >> 16);
1759 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1760 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1762 const uint *s1 = (
const uint *)image.scanLine(y1);
1763 const uint *s2 = (
const uint *)image.scanLine(y2);
1770 int distx = (fx & 0x0000ffff) >> 8;
1771 int disty = (fy & 0x0000ffff) >> 8;
1773 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1782static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1783 int &fx,
int &fy,
int fdx,
int fdy)
1786 if (blendType != BlendTransformedBilinearTiled) {
1787 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1788 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1789 const qint64 min_fy = qint64(image.y1) * fixed_scale;
1790 const qint64 max_fy = qint64(image.y2 - 1) * fixed_scale;
1793 int x1 = (fx >> 16);
1795 int y1 = (fy >> 16);
1797 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1798 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1799 if (x1 != x2 && y1 != y2)
1801 const uint *s1 = (
const uint *)image.scanLine(y1);
1802 const uint *s2 = (
const uint *)image.scanLine(y2);
1807 if (hasFastInterpolate4()) {
1808 int distx = (fx & 0x0000ffff) >> 8;
1809 int disty = (fy & 0x0000ffff) >> 8;
1810 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1812 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
1813 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
1814 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
1820 uint *boundedEnd = end;
1822 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1824 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1826 boundedEnd = qMin(boundedEnd, b + (max_fy - fy) / fdy);
1828 boundedEnd = qMin(boundedEnd, b + (min_fy - fy) / fdy);
1831#if defined(__SSE2__
)
1832 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1833 const __m128i v_256 = _mm_set1_epi16(256);
1834 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1835 const __m128i v_fdy = _mm_set1_epi32(fdy*4);
1836 const __m128i v_fxy_r = _mm_set1_epi32(0x8);
1837 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1838 __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
1840 const uchar *textureData = image.imageData;
1841 const qsizetype bytesPerLine = image.bytesPerLine;
1842 const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
1844 while (b < boundedEnd - 3) {
1845 const __m128i vy = _mm_packs_epi32(_mm_srli_epi32(v_fy, 16), _mm_setzero_si128());
1847 __m128i offset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epi16(vy, vbpl));
1848 offset = _mm_add_epi32(offset, _mm_srli_epi32(v_fx, 16));
1849 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1850 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1851 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1852 const int offset3 = _mm_cvtsi128_si32(offset);
1853 const uint *topData = (
const uint *)(textureData);
1854 const __m128i tl = _mm_setr_epi32(topData[offset0], topData[offset1], topData[offset2], topData[offset3]);
1855 const __m128i tr = _mm_setr_epi32(topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]);
1856 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1857 const __m128i bl = _mm_setr_epi32(bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]);
1858 const __m128i br = _mm_setr_epi32(bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]);
1860 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1861 __m128i v_disty = _mm_srli_epi16(v_fy, 8);
1862 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fxy_r), 4);
1863 v_disty = _mm_srli_epi16(_mm_add_epi32(v_disty, v_fxy_r), 4);
1864 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1865 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1866 v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1867 v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1869 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1871 v_fx = _mm_add_epi32(v_fx, v_fdx);
1872 v_fy = _mm_add_epi32(v_fy, v_fdy);
1874 fx = _mm_cvtsi128_si32(v_fx);
1875 fy = _mm_cvtsi128_si32(v_fy);
1876#elif defined(__ARM_NEON__)
1877 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1878 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1879 const int16x8_t v_256 = vdupq_n_s16(256);
1880 int32x4_t v_fdx = vdupq_n_s32(fdx * 4);
1881 int32x4_t v_fdy = vdupq_n_s32(fdy * 4);
1883 const uchar *textureData = image.imageData;
1884 const qsizetype bytesPerLine = image.bytesPerLine;
1886 int32x4_t v_fx = vmovq_n_s32(fx);
1887 int32x4_t v_fy = vmovq_n_s32(fy);
1888 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1889 v_fy = vsetq_lane_s32(fy + fdy, v_fy, 1);
1890 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1891 v_fy = vsetq_lane_s32(fy + fdy * 2, v_fy, 2);
1892 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1893 v_fy = vsetq_lane_s32(fy + fdy * 3, v_fy, 3);
1895 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1896 const int32x4_t v_round = vdupq_n_s32(0x0800);
1899 uint32x4x2_t v_top = {};
1900 uint32x4x2_t v_bot = {};
1901 while (b < boundedEnd - 3) {
1902 int x1 = (fx >> 16);
1903 int y1 = (fy >> 16);
1904 fx += fdx; fy += fdy;
1905 const uchar *sl = textureData + bytesPerLine * y1;
1906 const uint *s1 =
reinterpret_cast<
const uint *>(sl);
1907 const uint *s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1908 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1909 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1912 fx += fdx; fy += fdy;
1913 sl = textureData + bytesPerLine * y1;
1914 s1 =
reinterpret_cast<
const uint *>(sl);
1915 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1916 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1917 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1920 fx += fdx; fy += fdy;
1921 sl = textureData + bytesPerLine * y1;
1922 s1 =
reinterpret_cast<
const uint *>(sl);
1923 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1924 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1925 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1928 fx += fdx; fy += fdy;
1929 sl = textureData + bytesPerLine * y1;
1930 s1 =
reinterpret_cast<
const uint *>(sl);
1931 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1932 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1933 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1935 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_round), 12);
1936 int32x4_t v_disty = vshrq_n_s32(vaddq_s32(vandq_s32(v_fy, v_ffff_mask), v_round), 12);
1937 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1938 v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
1939 int16x8_t v_disty_ = vshlq_n_s16(vreinterpretq_s16_s32(v_disty), 4);
1941 interpolate_4_pixels_16_neon(
1942 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1943 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1944 vreinterpretq_s16_s32(v_distx), vreinterpretq_s16_s32(v_disty),
1945 v_disty_, colorMask, invColorMask, v_256, b);
1947 v_fx = vaddq_s32(v_fx, v_fdx);
1948 v_fy = vaddq_s32(v_fy, v_fdy);
1950#elif defined(__loongarch_sx)
1951 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1952 const __m128i v_fdy = __lsx_vreplgr2vr_w(fdy*4);
1953 const __m128i v_fxy_r = __lsx_vreplgr2vr_w(0x8);
1954 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1955 __m128i v_fy = (__m128i)(v4i32){fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy};
1957 const uchar *textureData = image.imageData;
1958 const qsizetype bytesPerLine = image.bytesPerLine;
1959 const __m128i zero = __lsx_vldi(0);
1960 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
1961 const __m128i shuffleMask1 = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1962 const __m128i vbpl = __lsx_vshuf_h(shuffleMask, zero, __lsx_vinsgr2vr_w(zero, bytesPerLine/4, 0));
1964 while (b < boundedEnd - 3) {
1965 const __m128i vy = __lsx_vpickev_h(zero, __lsx_vsat_w(__lsx_vsrli_w(v_fy, 16), 15));
1967 __m128i offset = __lsx_vilvl_h(__lsx_vmuh_h(vy, vbpl), __lsx_vmul_h(vy, vbpl));
1968 offset = __lsx_vadd_w(offset, __lsx_vsrli_w(v_fx, 16));
1969 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1970 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1971 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1972 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1973 const uint *topData = (
const uint *)(textureData);
1974 const __m128i tl = (__m128i)(v4u32){topData[offset0], topData[offset1], topData[offset2], topData[offset3]};
1975 const __m128i tr = (__m128i)(v4u32){topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]};
1976 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1977 const __m128i bl = (__m128i)(v4u32){bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]};
1978 const __m128i br = (__m128i)(v4u32){bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]};
1980 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1981 __m128i v_disty = __lsx_vsrli_h(v_fy, 8);
1982 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fxy_r), 4);
1983 v_disty = __lsx_vsrli_h(__lsx_vadd_w(v_disty, v_fxy_r), 4);
1984 v_distx = __lsx_vshuf_h(shuffleMask1, zero, v_distx);
1985 v_disty = __lsx_vshuf_h(shuffleMask1, zero, v_disty);
1987 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1989 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1990 v_fy = __lsx_vadd_w(v_fy, v_fdy);
1992 fx = __lsx_vpickve2gr_w(v_fx, 0);
1993 fy = __lsx_vpickve2gr_w(v_fy, 0);
1995 while (b < boundedEnd) {
1999 const uint *s1 = (
const uint *)image.scanLine(y);
2000 const uint *s2 = (
const uint *)image.scanLine(y + 1);
2002 if (hasFastInterpolate4()) {
2003 int distx = (fx & 0x0000ffff) >> 8;
2004 int disty = (fy & 0x0000ffff) >> 8;
2005 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
2007 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2008 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2009 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx, disty);
2019 int x1 = (fx >> 16);
2021 int y1 = (fy >> 16);
2024 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2025 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2027 const uint *s1 = (
const uint *)image.scanLine(y1);
2028 const uint *s2 = (
const uint *)image.scanLine(y2);
2035 if (hasFastInterpolate4()) {
2036 int distx = (fx & 0x0000ffff) >> 8;
2037 int disty = (fy & 0x0000ffff) >> 8;
2038 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2040 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2041 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2042 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2054 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinear>,
2055 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinear>,
2056 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinear>,
2057 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinear>,
2058 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinear>
2061 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinearTiled>,
2062 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinearTiled>,
2063 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinearTiled>,
2064 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinearTiled>,
2065 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinearTiled>
2070static const uint *
QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer,
const Operator *,
2071 const QSpanData *data,
int y,
int x,
2074 const qreal cx = x + qreal(0.5);
2075 const qreal cy = y + qreal(0.5);
2076 constexpr int tiled = (blendType == BlendTransformedBilinearTiled) ? 1 : 0;
2078 uint *end = buffer + length;
2080 if (canUseFastMatrixPath(cx, cy, length, data)) {
2082 int fdx = (
int)(data->m11 * fixed_scale);
2083 int fdy = (
int)(data->m12 * fixed_scale);
2085 int fx =
int((data->m21 * cy
2086 + data->m11 * cx + data->dx) * fixed_scale);
2087 int fy =
int((data->m22 * cy
2088 + data->m12 * cx + data->dy) * fixed_scale);
2094 if (qAbs(fdx) <= fixed_scale) {
2096 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2097 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2099 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2100 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2102 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2103 }
else if (qAbs(data->m22) < qreal(1./8.)) {
2105 bilinearFastTransformHelperARGB32PM[tiled][UpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2108 bilinearFastTransformHelperARGB32PM[tiled][DownscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2111 if (qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.) ) {
2113 bilinearFastTransformHelperARGB32PM[tiled][RotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2116 bilinearFastTransformHelperARGB32PM[tiled][FastRotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2120 const QTextureData &image = data->texture;
2122 const qreal fdx = data->m11;
2123 const qreal fdy = data->m12;
2124 const qreal fdw = data->m13;
2126 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2127 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2128 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2131 const qreal iw = fw == 0 ? 1 : 1 / fw;
2132 const qreal px = fx * iw - qreal(0.5);
2133 const qreal py = fy * iw - qreal(0.5);
2135 int x1 =
int(px) - (px < 0);
2137 int y1 =
int(py) - (py < 0);
2140 int distx =
int((px - x1) * 256);
2141 int disty =
int((py - y1) * 256);
2143 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2144 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2146 const uint *s1 = (
const uint *)data->texture.scanLine(y1);
2147 const uint *s2 = (
const uint *)data->texture.scanLine(y2);
2154 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2171static void QT_FASTCALL fetchTransformedBilinear_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
2172 int &fx,
int &fy,
int fdx,
int )
2174 const QPixelLayout *layout = &qPixelLayouts[image.format];
2175 const QList<QRgb> *clut = image.colorTable;
2176 const FetchAndConvertPixelsFunc fetch = layout->fetchToARGB32PM;
2178 int y1 = (fy >> 16);
2180 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2181 const uchar *s1 = image.scanLine(y1);
2182 const uchar *s2 = image.scanLine(y2);
2184 const int disty = (fy & 0x0000ffff) >> 8;
2185 const int idisty = 256 - disty;
2186 const int length = end - b;
2189 const int adjust = (fdx < 0) ? fdx * length : 0;
2190 const int offset = (fx + adjust) >> 16;
2193 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
2194 uint *buf1 = intermediate.buffer_rb;
2195 uint *buf2 = intermediate.buffer_ag;
2199 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
2200 Q_ASSERT(count <= BufferSize + 2);
2202 if (blendType == BlendTransformedBilinearTiled) {
2206 int len1 = qMin(count, image.width - x);
2207 int len2 = qMin(x, count - len1);
2209 ptr1 = fetch(buf1, s1, x, len1, clut,
nullptr);
2210 ptr2 = fetch(buf2, s2, x, len1, clut,
nullptr);
2211 for (
int i = 0; i < len1; ++i) {
2214 buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2215 buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2219 ptr1 = fetch(buf1 + len1, s1, 0, len2, clut,
nullptr);
2220 ptr2 = fetch(buf2 + len1, s2, 0, len2, clut,
nullptr);
2221 for (
int i = 0; i < len2; ++i) {
2224 buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2225 buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2229 for (
int i = image.width; i < count; ++i) {
2230 buf1[i] = buf1[i - image.width];
2231 buf2[i] = buf2[i - image.width];
2234 int start = qMax(x, image.x1);
2235 int end = qMin(x + count, image.x2);
2236 int len = qMax(1, end - start);
2237 int leading = start - x;
2239 ptr1 = fetch(buf1 + leading, s1, start, len, clut,
nullptr);
2240 ptr2 = fetch(buf2 + leading, s2, start, len, clut,
nullptr);
2242 for (
int i = 0; i < len; ++i) {
2245 buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2246 buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2249 for (
int i = 0; i < leading; ++i) {
2250 buf1[i] = buf1[leading];
2251 buf2[i] = buf2[leading];
2253 for (
int i = leading + len; i < count; ++i) {
2254 buf1[i] = buf1[i - 1];
2255 buf2[i] = buf2[i - 1];
2260 intermediate_adder(b, end, intermediate, offset, fx, fdx);
2265static void QT_FASTCALL fetchTransformedBilinear_fetcher(T *buf1, T *buf2,
const int len,
const QTextureData &image,
2266 int fx,
int fy,
const int fdx,
const int fdy)
2268 const QPixelLayout &layout = qPixelLayouts[image.format];
2269 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2271 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2273 Q_ASSERT(layout.bpp == bpp || (layout.bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
2274 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2276 int y1 = (fy >> 16);
2278 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2279 const uchar *s1 = image.scanLine(y1);
2280 const uchar *s2 = image.scanLine(y2);
2283 if (blendType == BlendTransformedBilinear) {
2284 for (; i < len; ++i) {
2285 int x1 = (fx >> 16);
2287 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2290 if constexpr (useFetch) {
2291 buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
2292 buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
2294 buf1[i * 2 + 0] = buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x1];
2295 buf2[i * 2 + 0] = buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x1];
2301 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2303 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2305 for (; i < fastLen; ++i) {
2307 if constexpr (useFetch) {
2308 buf1[i * 2 + 0] = fetch1(s1, x);
2309 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2310 buf2[i * 2 + 0] = fetch1(s2, x);
2311 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2313 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2314 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2315 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2316 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2322 for (; i < len; ++i) {
2323 int x1 = (fx >> 16);
2325 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2326 if constexpr (useFetch) {
2327 buf1[i * 2 + 0] = fetch1(s1, x1);
2328 buf1[i * 2 + 1] = fetch1(s1, x2);
2329 buf2[i * 2 + 0] = fetch1(s2, x1);
2330 buf2[i * 2 + 1] = fetch1(s2, x2);
2332 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2333 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2334 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2335 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2341 if (blendType == BlendTransformedBilinear) {
2342 for (; i < len; ++i) {
2343 int x1 = (fx >> 16);
2345 int y1 = (fy >> 16);
2347 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2348 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2349 if (x1 != x2 && y1 != y2)
2351 const uchar *s1 = image.scanLine(y1);
2352 const uchar *s2 = image.scanLine(y2);
2353 if constexpr (useFetch) {
2354 buf1[i * 2 + 0] = fetch1(s1, x1);
2355 buf1[i * 2 + 1] = fetch1(s1, x2);
2356 buf2[i * 2 + 0] = fetch1(s2, x1);
2357 buf2[i * 2 + 1] = fetch1(s2, x2);
2359 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2360 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2361 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2362 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2369 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2371 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2373 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
2375 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
2377 for (; i < fastLen; ++i) {
2380 const uchar *s1 = image.scanLine(y);
2381 const uchar *s2 = s1 + image.bytesPerLine;
2382 if constexpr (useFetch) {
2383 buf1[i * 2 + 0] = fetch1(s1, x);
2384 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2385 buf2[i * 2 + 0] = fetch1(s2, x);
2386 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2388 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2389 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2390 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2391 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2398 for (; i < len; ++i) {
2399 int x1 = (fx >> 16);
2401 int y1 = (fy >> 16);
2403 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2404 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2406 const uchar *s1 = image.scanLine(y1);
2407 const uchar *s2 = image.scanLine(y2);
2408 if constexpr (useFetch) {
2409 buf1[i * 2 + 0] = fetch1(s1, x1);
2410 buf1[i * 2 + 1] = fetch1(s1, x2);
2411 buf2[i * 2 + 0] = fetch1(s2, x1);
2412 buf2[i * 2 + 1] = fetch1(s2, x2);
2414 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2415 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2416 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2417 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2426static void QT_FASTCALL fetchTransformedBilinear_slow_fetcher(T *buf1, T *buf2, ushort *distxs, ushort *distys,
2427 const int len,
const QTextureData &image,
2428 qreal &fx, qreal &fy, qreal &fw,
2429 const qreal fdx,
const qreal fdy,
const qreal fdw)
2431 const QPixelLayout &layout = qPixelLayouts[image.format];
2432 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2434 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2436 Q_ASSERT(layout.bpp == bpp);
2438 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2440 for (
int i = 0; i < len; ++i) {
2441 const qreal iw = fw == 0 ? 16384 : 1 / fw;
2442 const qreal px = fx * iw - qreal(0.5);
2443 const qreal py = fy * iw - qreal(0.5);
2445 int x1 = qFloor(px);
2447 int y1 = qFloor(py);
2450 distxs[i] = ushort((px - x1) * (1<<16));
2451 distys[i] = ushort((py - y1) * (1<<16));
2453 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2454 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2456 const uchar *s1 = image.scanLine(y1);
2457 const uchar *s2 = image.scanLine(y2);
2458 if constexpr (useFetch) {
2459 buf1[i * 2 + 0] = fetch1(s1, x1);
2460 buf1[i * 2 + 1] = fetch1(s1, x2);
2461 buf2[i * 2 + 0] = fetch1(s2, x1);
2462 buf2[i * 2 + 1] = fetch1(s2, x2);
2464 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2465 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2466 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2467 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2479 const QSpanData *data,
int y,
int x,
int length)
2481 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2482 const QList<QRgb> *clut = data->texture.colorTable;
2483 Q_ASSERT(bpp == QPixelLayout::BPPNone || layout->bpp == bpp);
2485 const qreal cx = x + qreal(0.5);
2486 const qreal cy = y + qreal(0.5);
2488 if (canUseFastMatrixPath(cx, cy, length, data)) {
2490 int fdx = (
int)(data->m11 * fixed_scale);
2491 int fdy = (
int)(data->m12 * fixed_scale);
2493 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2494 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2500 if (qAbs(fdx) <= fixed_scale) {
2501 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
2502 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2503 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2504 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2506 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2508 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2510 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2511 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2514 int len = qMin(length, BufferSize / 2);
2515 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
2516 layout->convertToARGB32PM(buf1, len * 2, clut);
2517 layout->convertToARGB32PM(buf2, len * 2, clut);
2519 if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) {
2520 int disty = (fy & 0x0000ffff) >> 8;
2521 for (
int i = 0; i < len; ++i) {
2522 int distx = (fx & 0x0000ffff) >> 8;
2523 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2527 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2528 for (
int i = 0; i < len; ++i) {
2529 uint tl = buf1[i * 2 + 0];
2530 uint tr = buf1[i * 2 + 1];
2531 uint bl = buf2[i * 2 + 0];
2532 uint br = buf2[i * 2 + 1];
2533 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2534 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2543 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2545 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2546 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2549 int len = qMin(length, BufferSize / 2);
2550 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2551 layout->convertToARGB32PM(buf1, len * 2, clut);
2552 layout->convertToARGB32PM(buf2, len * 2, clut);
2554 if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
2556 for (
int i = 0; i < len; ++i) {
2557 int distx = (fx & 0x0000ffff) >> 8;
2558 int disty = (fy & 0x0000ffff) >> 8;
2560 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2566 for (
int i = 0; i < len; ++i) {
2567 uint tl = buf1[i * 2 + 0];
2568 uint tr = buf1[i * 2 + 1];
2569 uint bl = buf2[i * 2 + 0];
2570 uint br = buf2[i * 2 + 1];
2572 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2573 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2575 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2586 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType,bpp,uint>;
2588 const qreal fdx = data->m11;
2589 const qreal fdy = data->m12;
2590 const qreal fdw = data->m13;
2592 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2593 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2594 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2596 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2597 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2600 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2601 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2604 const int len = qMin(length, BufferSize / 2);
2605 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2607 layout->convertToARGB32PM(buf1, len * 2, clut);
2608 layout->convertToARGB32PM(buf2, len * 2, clut);
2610 for (
int i = 0; i < len; ++i) {
2611 const int distx = distxs[i] >> 8;
2612 const int disty = distys[i] >> 8;
2614 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2624#if QT_CONFIG(raster_64bit)
2625template<TextureBlendType blendType>
2626static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer,
const QSpanData *data,
2627 int y,
int x,
int length)
2629 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2630 const auto *clut = data->texture.colorTable;
2631 const auto convert = layout->convertToRGBA64PM;
2633 const qreal cx = x + qreal(0.5);
2634 const qreal cy = y + qreal(0.5);
2636 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
2637 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
2638 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2639 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2640 QRgba64 *b = buffer;
2642 if (canUseFastMatrixPath(cx, cy, length, data)) {
2644 const int fdx = (
int)(data->m11 * fixed_scale);
2645 const int fdy = (
int)(data->m12 * fixed_scale);
2647 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2648 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2653 const auto fetcher =
2654 (layout->bpp == QPixelLayout::BPP32)
2655 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
2656 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2660 const int len = qMin(length, BufferSize / 2);
2661 const int disty = (fy & 0x0000ffff);
2662#if defined(__SSE2__)
2663 const __m128i vdy = _mm_set1_epi16(disty);
2664 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2666 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2668 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2670 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2672 for (
int i = 0; i < len; ++i) {
2673 const int distx = (fx & 0x0000ffff);
2674#if defined(__SSE2__)
2675 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2677 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2678 vt = _mm_mulhi_epu16(vt, vidy);
2679 vb = _mm_mulhi_epu16(vb, vdy);
2680 vt = _mm_add_epi16(vt, vb);
2683 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2684 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2685 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2686 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2688 _mm_storel_epi64((__m128i*)(b+i), vt);
2690 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2699 const int len = qMin(length, BufferSize / 2);
2701 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2703 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2704 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2706 for (
int i = 0; i < len; ++i) {
2707 const int distx = (fx & 0x0000ffff);
2708 const int disty = (fy & 0x0000ffff);
2709 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2719 const auto fetcher =
2720 (layout->bpp == QPixelLayout::BPP32)
2721 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
2722 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2724 const qreal fdx = data->m11;
2725 const qreal fdy = data->m12;
2726 const qreal fdw = data->m13;
2728 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2729 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2730 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2732 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2733 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2736 const int len = qMin(length, BufferSize / 2);
2737 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2739 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2740 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2742 for (
int i = 0; i < len; ++i) {
2743 const int distx = distxs[i];
2744 const int disty = distys[i];
2745 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2755template<TextureBlendType blendType>
2756static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buffer,
const QSpanData *data,
2757 int y,
int x,
int length)
2759 const auto convert = convert64ToRGBA64PM[data->texture.format];
2761 const qreal cx = x + qreal(0.5);
2762 const qreal cy = y + qreal(0.5);
2764 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2765 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2766 QRgba64 *end = buffer + length;
2767 QRgba64 *b = buffer;
2769 if (canUseFastMatrixPath(cx, cy, length, data)) {
2771 const int fdx = (
int)(data->m11 * fixed_scale);
2772 const int fdy = (
int)(data->m12 * fixed_scale);
2774 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2775 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2779 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2783 int len = qMin(length, BufferSize / 2);
2784 int disty = (fy & 0x0000ffff);
2785#if defined(__SSE2__)
2786 const __m128i vdy = _mm_set1_epi16(disty);
2787 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2789 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2791 convert(buf1, len * 2);
2793 convert(buf2, len * 2);
2795 for (
int i = 0; i < len; ++i) {
2796 int distx = (fx & 0x0000ffff);
2797#if defined(__SSE2__)
2798 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2800 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2801 vt = _mm_mulhi_epu16(vt, vidy);
2802 vb = _mm_mulhi_epu16(vb, vdy);
2803 vt = _mm_add_epi16(vt, vb);
2806 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2807 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2808 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2809 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2811 _mm_storel_epi64((__m128i*)(b+i), vt);
2813 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2822 int len = qMin(length, BufferSize / 2);
2824 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2826 convert(buf1, len * 2);
2827 convert(buf2, len * 2);
2829 for (
int i = 0; i < len; ++i) {
2830 int distx = (fx & 0x0000ffff);
2831 int disty = (fy & 0x0000ffff);
2832 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2842 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2844 const qreal fdx = data->m11;
2845 const qreal fdy = data->m12;
2846 const qreal fdw = data->m13;
2848 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2849 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2850 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2852 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2853 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2856 const int len = qMin(length, BufferSize / 2);
2857 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2859 convert(buf1, len * 2);
2860 convert(buf2, len * 2);
2862 for (
int i = 0; i < len; ++i) {
2863 const int distx = distxs[i];
2864 const int disty = distys[i];
2865 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2875template<TextureBlendType blendType>
2876static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_f32x4(QRgba64 *buffer,
const QSpanData *data,
2877 int y,
int x,
int length)
2879 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2880 const auto *clut = data->texture.colorTable;
2881 const auto convert = layout->fetchToRGBA64PM;
2883 const qreal cx = x + qreal(0.5);
2884 const qreal cy = y + qreal(0.5);
2886 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf1[BufferSize];
2887 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf2[BufferSize];
2888 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2889 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2890 QRgba64 *b = buffer;
2892 if (canUseFastMatrixPath(cx, cy, length, data)) {
2894 const int fdx = (
int)(data->m11 * fixed_scale);
2895 const int fdy = (
int)(data->m12 * fixed_scale);
2897 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2898 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2903 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2905 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
2907 const int len = qMin(length, BufferSize / 2);
2909 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2911 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2913 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2915 for (
int i = 0; i < len; ++i) {
2916 const int distx = (fx & 0x0000ffff);
2917 const int disty = (fy & 0x0000ffff);
2918 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2927 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2929 const qreal fdx = data->m11;
2930 const qreal fdy = data->m12;
2931 const qreal fdw = data->m13;
2933 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2934 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2935 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2937 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2938 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2941 const int len = qMin(length, BufferSize / 2);
2942 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2944 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2945 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2947 for (
int i = 0; i < len; ++i) {
2948 const int distx = distxs[i];
2949 const int disty = distys[i];
2950 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2960template<TextureBlendType blendType>
2961static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer,
const Operator *,
2962 const QSpanData *data,
int y,
int x,
int length)
2964 switch (qPixelLayouts[data->texture.format].bpp) {
2965 case QPixelLayout::BPP64:
2966 case QPixelLayout::BPP16FPx4:
2967 return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
2968 case QPixelLayout::BPP32FPx4:
2969 return fetchTransformedBilinear64_f32x4<blendType>(buffer, data, y, x, length);
2971 return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
2976#if QT_CONFIG(raster_fp)
2977static void interpolate_simple_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2981 for (
int i = 0; i < len; ++i) {
2982 const int distx = (fx & 0x0000ffff);
2983 const int disty = (fy & 0x0000ffff);
2984 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, distx, disty);
2990static void interpolate_perspective_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2991 unsigned short *distxs,
2992 unsigned short *distys)
2994 for (
int i = 0; i < len; ++i) {
2995 const int dx = distxs[i];
2996 const int dy = distys[i];
2997 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, dx, dy);
3001template<TextureBlendType blendType>
3002static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint32(QRgbaFloat32 *buffer,
const QSpanData *data,
3003 int y,
int x,
int length)
3005 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
3006 const auto *clut = data->texture.colorTable;
3007 const auto convert = qConvertToRGBA32F[data->texture.format];
3009 const qreal cx = x + qreal(0.5);
3010 const qreal cy = y + qreal(0.5);
3012 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
3013 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
3014 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3015 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3016 QRgbaFloat32 *b = buffer;
3018 if (canUseFastMatrixPath(cx, cy, length, data)) {
3020 const int fdx = (
int)(data->m11 * fixed_scale);
3021 const int fdy = (
int)(data->m12 * fixed_scale);
3023 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3024 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3029 const auto fetcher =
3030 (layout->bpp == QPixelLayout::BPP32)
3031 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
3032 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3034 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3036 const int len = qMin(length, BufferSize / 2);
3037 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3039 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3041 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3043 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3049 const auto fetcher =
3050 (layout->bpp == QPixelLayout::BPP32)
3051 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
3052 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3054 const qreal fdx = data->m11;
3055 const qreal fdy = data->m12;
3056 const qreal fdw = data->m13;
3057 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3058 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3059 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3060 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3061 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3064 const int len = qMin(length, BufferSize / 2);
3065 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3067 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3068 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3070 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3079template<TextureBlendType blendType>
3080static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint64(QRgbaFloat32 *buffer,
const QSpanData *data,
3081 int y,
int x,
int length)
3083 const auto convert = convert64ToRGBA32F[data->texture.format];
3085 const qreal cx = x + qreal(0.5);
3086 const qreal cy = y + qreal(0.5);
3088 Q_DECL_UNINITIALIZED quint64 sbuf1[BufferSize] ;
3089 Q_DECL_UNINITIALIZED quint64 sbuf2[BufferSize];
3090 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3091 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3092 QRgbaFloat32 *b = buffer;
3094 if (canUseFastMatrixPath(cx, cy, length, data)) {
3096 const int fdx = (
int)(data->m11 * fixed_scale);
3097 const int fdy = (
int)(data->m12 * fixed_scale);
3099 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3100 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3104 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3106 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3108 const int len = qMin(length, BufferSize / 2);
3109 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3111 convert(buf1, sbuf1, len * 2);
3113 convert(buf2, sbuf2, len * 2);
3115 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3121 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3123 const qreal fdx = data->m11;
3124 const qreal fdy = data->m12;
3125 const qreal fdw = data->m13;
3127 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3128 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3129 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3131 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3132 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3135 const int len = qMin(length, BufferSize / 2);
3136 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3138 convert(buf1, sbuf1, len * 2);
3139 convert(buf2, sbuf2, len * 2);
3141 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3150template<TextureBlendType blendType>
3151static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const QSpanData *data,
3152 int y,
int x,
int length)
3154 const auto convert = data->rasterBuffer->format == QImage::Format_RGBA32FPx4 ? convertRGBA32FToRGBA32FPM
3155 : convertRGBA32FToRGBA32F;
3157 const qreal cx = x + qreal(0.5);
3158 const qreal cy = y + qreal(0.5);
3160 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3161 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3162 QRgbaFloat32 *b = buffer;
3164 if (canUseFastMatrixPath(cx, cy, length, data)) {
3166 const int fdx = (
int)(data->m11 * fixed_scale);
3167 const int fdy = (
int)(data->m12 * fixed_scale);
3169 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3170 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3174 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3176 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3178 const int len = qMin(length, BufferSize / 2);
3179 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
3181 convert(buf1, len * 2);
3183 convert(buf2, len * 2);
3185 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3191 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3193 const qreal fdx = data->m11;
3194 const qreal fdy = data->m12;
3195 const qreal fdw = data->m13;
3197 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3198 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3199 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3201 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3202 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3205 const int len = qMin(length, BufferSize / 2);
3206 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3208 convert(buf1, len * 2);
3209 convert(buf2, len * 2);
3211 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3220template<TextureBlendType blendType>
3221static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const Operator *,
3222 const QSpanData *data,
int y,
int x,
int length)
3224 switch (qPixelLayouts[data->texture.format].bpp) {
3225 case QPixelLayout::BPP64:
3226 case QPixelLayout::BPP16FPx4:
3227 return fetchTransformedBilinearFP_uint64<blendType>(buffer, data, y, x, length);
3228 case QPixelLayout::BPP32FPx4:
3229 return fetchTransformedBilinearFP<blendType>(buffer, data, y, x, length);
3231 return fetchTransformedBilinearFP_uint32<blendType>(buffer, data, y, x, length);
3242 fetchUntransformedARGB32PM,
3244 fetchUntransformedARGB32PM,
3245 fetchUntransformedRGB16,
3277static_assert(std::size(sourceFetchUntransformed) == QImage::NImageFormats);
3282 fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>,
3283 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPPNone>,
3284 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPPNone>,
3285 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone>
3288static_assert(std::size(sourceFetchGeneric) == NBlendTypes);
3291 fetchUntransformedARGB32PM,
3292 fetchUntransformedARGB32PM,
3293 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3294 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3295 fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>,
3296 fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>
3299static_assert(std::size(sourceFetchARGB32PM) == NBlendTypes);
3304 fetchTransformed<BlendTransformed, QPixelLayout::BPP16>,
3305 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP16>,
3306 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP16>,
3307 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16>
3310static_assert(std::size(sourceFetchAny16) == NBlendTypes);
3315 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3316 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3317 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP32>,
3318 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32>
3321static_assert(std::size(sourceFetchAny32) == NBlendTypes);
3325 if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
3326 return sourceFetchARGB32PM[blendType];
3328 return sourceFetchUntransformed[format];
3329 if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
3330 return sourceFetchAny16[blendType];
3331 if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
3332 return sourceFetchAny32[blendType];
3333 return sourceFetchGeneric[blendType];
3336#if QT_CONFIG(raster_64bit)
3337static const SourceFetchProc64 sourceFetchGeneric64[] = {
3338 fetchUntransformed64,
3339 fetchUntransformed64,
3340 fetchTransformed64<BlendTransformed>,
3341 fetchTransformed64<BlendTransformedTiled>,
3342 fetchTransformedBilinear64<BlendTransformedBilinear>,
3343 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3346static_assert(std::size(sourceFetchGeneric64) == NBlendTypes);
3348static const SourceFetchProc64 sourceFetchRGBA64PM[] = {
3349 fetchUntransformedRGBA64PM,
3350 fetchUntransformedRGBA64PM,
3351 fetchTransformed64<BlendTransformed>,
3352 fetchTransformed64<BlendTransformedTiled>,
3353 fetchTransformedBilinear64<BlendTransformedBilinear>,
3354 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3357static_assert(std::size(sourceFetchRGBA64PM) == NBlendTypes);
3359static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
3361 if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
3362 return sourceFetchRGBA64PM[blendType];
3363 return sourceFetchGeneric64[blendType];
3367#if QT_CONFIG(raster_fp)
3368static const SourceFetchProcFP sourceFetchGenericFP[] = {
3369 fetchUntransformedFP,
3370 fetchUntransformedFP,
3371 fetchTransformedFP<BlendTransformed>,
3372 fetchTransformedFP<BlendTransformedTiled>,
3373 fetchTransformedBilinearFP<BlendTransformedBilinear>,
3374 fetchTransformedBilinearFP<BlendTransformedBilinearTiled>
3377static_assert(std::size(sourceFetchGenericFP) == NBlendTypes);
3379static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format )
3381 return sourceFetchGenericFP[blendType];
3392 return data->colorTable32[qt_gradient_clamp(data, ipos)];
3395#if QT_CONFIG(raster_64bit)
3396static const QRgba64& qt_gradient_pixel64_fixed(
const QGradientData *data,
int fixed_pos)
3398 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3399 return data->colorTable64[qt_gradient_clamp(data, ipos)];
3403#if QT_CONFIG(raster_fp)
3404static inline QRgbaFloat32 qt_gradient_pixelFP(
const QGradientData *data, qreal pos)
3406 int ipos =
int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
3407 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3408 return QRgbaFloat32::fromRgba64(rgb64.red(),rgb64.green(), rgb64.blue(), rgb64.alpha());
3411static inline QRgbaFloat32 qt_gradient_pixelFP_fixed(
const QGradientData *data,
int fixed_pos)
3413 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3414 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3415 return QRgbaFloat32::fromRgba64(rgb64.red(), rgb64.green(), rgb64.blue(), rgb64.alpha());
3419static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v,
const QSpanData *data)
3421 v->dx = data->gradient.linear.end.x - data->gradient.linear.origin.x;
3422 v->dy = data->gradient.linear.end.y - data->gradient.linear.origin.y;
3423 v->l = v->dx * v->dx + v->dy * v->dy;
3428 v->off = -v->dx * data->gradient.linear.origin.x - v->dy * data->gradient.linear.origin.y;
3439 Q_ASSERT(
std::isfinite(v));
3440 return qt_gradient_pixel(&gradient, v);
3444 return qt_gradient_pixel_fixed(&gradient, v);
3448 qt_memfill32(buffer, fill, length);
3452#if QT_CONFIG(raster_64bit)
3456 typedef QRgba64 Type;
3457 static Type null() {
return QRgba64::fromRgba64(0); }
3458 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3460 Q_ASSERT(std::isfinite(v));
3461 return qt_gradient_pixel64(&gradient, v);
3463 static Type fetchSingle(
const QGradientData& gradient,
int v)
3465 return qt_gradient_pixel64_fixed(&gradient, v);
3467 static void memfill(Type *buffer, Type fill,
int length)
3469 qt_memfill64((quint64*)buffer, fill, length);
3474#if QT_CONFIG(raster_fp)
3478 typedef QRgbaFloat32 Type;
3479 static Type null() {
return QRgbaFloat32::fromRgba64(0,0,0,0); }
3480 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3482 Q_ASSERT(std::isfinite(v));
3483 return qt_gradient_pixelFP(&gradient, v);
3485 static Type fetchSingle(
const QGradientData& gradient,
int v)
3487 return qt_gradient_pixelFP_fixed(&gradient, v);
3489 static void memfill(Type *buffer, Type fill,
int length)
3492 memcpy(&fillCopy, &fill,
sizeof(quint64));
3493 qt_memfill64((quint64*)buffer, fillCopy, length);
3500 BlendType *buffer,
const Operator *op,
const QSpanData *data,
3501 int y,
int x,
int length)
3503 const BlendType *b = buffer;
3508 if (op->linear.l == 0) {
3511 rx = data->m21 * (y + qreal(0.5)) + data->m11 * (x + qreal(0.5)) + data->dx;
3512 ry = data->m22 * (y + qreal(0.5)) + data->m12 * (x + qreal(0.5)) + data->dy;
3513 t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off;
3514 inc = op->linear.dx * data->m11 + op->linear.dy * data->m12;
3515 affine = !data->m13 && !data->m23;
3523 const BlendType *end = buffer + length;
3525 if (inc > qreal(-1e-5) && inc < qreal(1e-5)) {
3527 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient,
int(t *
FIXPT_SIZE)), length);
3529 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient, t /
GRADIENT_STOPTABLE_SIZE), length);
3535 while (buffer < end) {
3536 *buffer = GradientBase::fetchSingle(data->gradient, t_fixed);
3537 t_fixed += inc_fixed;
3542 while (buffer < end) {
3550 qreal rw = data->m23 * (y + qreal(0.5)) + data->m13 * (x + qreal(0.5)) + data->m33;
3551 while (buffer < end) {
3554 t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off;
3556 *buffer = GradientBase::fetchSingle(data->gradient, t);
3570static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer,
const Operator *op,
const QSpanData *data,
3571 int y,
int x,
int length)
3573 return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
3576#if QT_CONFIG(raster_64bit)
3577static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3578 int y,
int x,
int length)
3580 return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
3583#if QT_CONFIG(raster_fp)
3584static const QRgbaFloat32 * QT_FASTCALL qt_fetch_linear_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3585 int y,
int x,
int length)
3587 return qt_fetch_linear_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, op, data, y, x, length);
3591static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v,
const QSpanData *data)
3593 v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x;
3594 v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y;
3596 v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius;
3597 v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius;
3599 v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy;
3601 v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0;
3604template <
class GradientBase>
3611 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
3613 if (op->radial.extended) {
3614 while (buffer < end) {
3615 BlendType result = GradientBase::null();
3617 qreal w = qSqrt(det) - b;
3618 if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0)
3619 result = GradientBase::fetchSingle(data->gradient, w);
3625 delta_det += delta_delta_det;
3631 while (buffer < end) {
3632 BlendType result = GradientBase::null();
3634 qreal w = qSqrt(det) - b;
3635 result = GradientBase::fetchSingle(data->gradient, w);
3641 delta_det += delta_delta_det;
3648const uint *
QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer,
const Operator *op,
const QSpanData *data,
3649 int y,
int x,
int length)
3651 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase32>, uint>(buffer, op, data, y, x, length);
3656#if QT_CONFIG(raster_64bit)
3657const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3658 int y,
int x,
int length)
3660 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
3664#if QT_CONFIG(raster_fp)
3665static const QRgbaFloat32 * QT_FASTCALL qt_fetch_radial_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3666 int y,
int x,
int length)
3668 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBaseFP>, QRgbaFloat32>(buffer, op, data, y, x, length);
3674 BlendType *buffer,
const QSpanData *data,
3675 int y,
int x,
int length)
3677 const BlendType *b = buffer;
3678 qreal rx = data->m21 * (y + qreal(0.5))
3679 + data->dx + data->m11 * (x + qreal(0.5));
3680 qreal ry = data->m22 * (y + qreal(0.5))
3681 + data->dy + data->m12 * (x + qreal(0.5));
3682 bool affine = !data->m13 && !data->m23;
3684 const qreal inv2pi =
M_1_PI / 2.0;
3686 const BlendType *end = buffer + length;
3688 rx -= data->gradient.conical.center.x;
3689 ry -= data->gradient.conical.center.y;
3690 while (buffer < end) {
3691 qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
3693 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3700 qreal rw = data->m23 * (y + qreal(0.5))
3701 + data->m33 + data->m13 * (x + qreal(0.5));
3704 while (buffer < end) {
3705 qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
3706 rx/rw - data->gradient.conical.center.y)
3707 + data->gradient.conical.angle;
3709 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3723static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer,
const Operator *,
const QSpanData *data,
3724 int y,
int x,
int length)
3726 return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
3729#if QT_CONFIG(raster_64bit)
3730static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
3731 int y,
int x,
int length)
3733 return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
3737#if QT_CONFIG(raster_fp)
3738static const QRgbaFloat32 * QT_FASTCALL qt_fetch_conical_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
3739 int y,
int x,
int length)
3741 return qt_fetch_conical_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, data, y, x, length);
3750#if QT_CONFIG(raster_64bit)
3751static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
3753#if QT_CONFIG(raster_fp)
3754static const CompositionFunctionSolidFP *functionForModeSolidFP = qt_functionForModeSolidFP_C;
3762#if QT_CONFIG(raster_64bit)
3763static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
3765#if QT_CONFIG(raster_fp)
3766static const CompositionFunctionFP *functionForModeFP = qt_functionForModeFP_C;
3774 else if (data->txop <= QTransform::TxTranslate)
3795 bool solidSource =
false;
3796 switch(data->type) {
3798 solidSource = data->solidColor.alphaF() >= 1.0f;
3800 op.srcFetch =
nullptr;
3801 op.srcFetch64 =
nullptr;
3802 op.srcFetchFP =
nullptr;
3805 solidSource = !data->gradient.alphaColor;
3806 getLinearGradientValues(&op.linear, data);
3807 op.srcFetch = qt_fetch_linear_gradient;
3808#if QT_CONFIG(raster_64bit)
3809 op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
3811#if QT_CONFIG(raster_fp)
3812 op.srcFetchFP = qt_fetch_linear_gradient_rgbfp;
3816 solidSource = !data->gradient.alphaColor;
3817 getRadialGradientValues(&op.radial, data);
3818 op.srcFetch = qt_fetch_radial_gradient;
3819#if QT_CONFIG(raster_64bit)
3820 op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
3822#if QT_CONFIG(raster_fp)
3823 op.srcFetchFP = qt_fetch_radial_gradient_rgbfp;
3827 solidSource = !data->gradient.alphaColor;
3829 op.srcFetch = qt_fetch_conical_gradient;
3830#if QT_CONFIG(raster_64bit)
3831 op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
3833#if QT_CONFIG(raster_fp)
3834 op.srcFetchFP = qt_fetch_conical_gradient_rgbfp;
3838 solidSource = !data->texture.hasAlpha;
3840 op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
3841#if QT_CONFIG(raster_64bit)
3842 op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);
3844#if QT_CONFIG(raster_fp)
3845 op.srcFetchFP = getSourceFetchFP(getBlendType(data), data->texture.format);
3852#if !QT_CONFIG(raster_64bit)
3853 op.srcFetch64 =
nullptr;
3855#if !QT_CONFIG(raster_fp)
3856 op.srcFetchFP =
nullptr;
3860 if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
3861 op.mode = QPainter::CompositionMode_Source;
3864#if QT_CONFIG(raster_64bit)
3865 op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
3867 op.destFetch64 =
nullptr;
3869#if QT_CONFIG(raster_fp)
3870 op.destFetchFP = destFetchProcFP[data->rasterBuffer->format];
3872 op.destFetchFP =
nullptr;
3874 if (op.mode == QPainter::CompositionMode_Source &&
3875 (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
3876 const QT_FT_Span *lastSpan = spans + spanCount;
3877 bool alphaSpans =
false;
3878 while (spans < lastSpan) {
3879 if (spans->coverage != 255) {
3885 if (!alphaSpans && spanCount > 0) {
3888 if (op.destFetch != destFetchARGB32P)
3889 op.destFetch = destFetchUndefined;
3890#if QT_CONFIG(raster_64bit)
3891 if (op.destFetch64 != destFetchRGB64)
3892 op.destFetch64 = destFetch64Undefined;
3894#if QT_CONFIG(raster_fp)
3895 if (op.destFetchFP != destFetchRGBFP)
3896 op.destFetchFP = destFetchFPUndefined;
3902 op.funcSolid = functionForModeSolid[op.mode];
3903 op.func = functionForMode[op.mode];
3904#if QT_CONFIG(raster_64bit)
3905 op.destStore64 = destStoreProc64[data->rasterBuffer->format];
3906 op.funcSolid64 = functionForModeSolid64[op.mode];
3907 op.func64 = functionForMode64[op.mode];
3909 if (data->rasterBuffer->format == QImage::Format_RGBX64 && solidSource)
3910 op.destStore64 =
nullptr;
3912 op.destStore64 =
nullptr;
3913 op.funcSolid64 =
nullptr;
3914 op.func64 =
nullptr;
3916#if QT_CONFIG(raster_fp)
3917 op.destStoreFP = destStoreFP;
3918 op.funcSolidFP = functionForModeSolidFP[op.mode];
3919 op.funcFP = functionForModeFP[op.mode];
3921 op.destStoreFP =
nullptr;
3922 op.funcSolidFP =
nullptr;
3923 op.funcFP =
nullptr;
3932 case QPixelLayout::BPP32FPx4: {
3934 qt_memfill_template(dest + 1, dest[0], length - 1);
3937 case QPixelLayout::BPP16FPx4:
3938 case QPixelLayout::BPP64: {
3939 quint64 *dest =
reinterpret_cast<quint64 *>(rasterBuffer->scanLine(y)) + x;
3940 qt_memfill_template(dest + 1, dest[0], length - 1);
3943 case QPixelLayout::BPP32: {
3944 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(y)) + x;
3945 qt_memfill_template(dest + 1, dest[0], length - 1);
3948 case QPixelLayout::BPP24: {
3949 quint24 *dest =
reinterpret_cast<
quint24 *>(rasterBuffer->scanLine(y)) + x;
3950 qt_memfill_template(dest + 1, dest[0], length - 1);
3953 case QPixelLayout::BPP16: {
3954 quint16 *dest =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
3955 qt_memfill_template(dest + 1, dest[0], length - 1);
3958 case QPixelLayout::BPP8: {
3959 uchar *dest = rasterBuffer->scanLine(y) + x;
3960 memset(dest + 1, dest[0], length - 1);
3971#if QT_CONFIG(qtgui_threadpool)
3974static constexpr int MinParallelSolidPixels = 1 << 17;
3975static constexpr int MinParallelBlendPixels = 1 << 15;
3978static inline bool qt_pixelCountAtLeast(
int count,
const QT_FT_Span *spans,
int limit)
3980 constexpr int MaxProbeSpans = 32;
3981 const int numProbeSpans = qMin(count, MaxProbeSpans);
3982 qint64 numPixels = 0;
3983 for (
int i = 0; i < numProbeSpans; ++i)
3984 numPixels += spans[i].len;
3985 return numPixels * count >= qint64(limit) * numProbeSpans;
3989#define QT_THREAD_PARALLEL_FILLS(function, minPixels)
3990 const int segments = (count + 32
) / 64
;
3991 QThreadPool *threadPool = (segments > 1
3992 && qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8
3993 && qt_pixelCountAtLeast(count, spans, minPixels))
3994 ? QGuiApplicationPrivate::qtGuiThreadPool() : nullptr;
3995 if (threadPool && !threadPool->contains(QThread::currentThread())) {
3996 QLatch latch(segments);
3998 for (int i = 0
; i < segments; ++i) {
3999 int cn = (count - c) / (segments - i);
4000 threadPool->start([&, c, cn]() {
4001 function(c, c + cn);
4010#define QT_THREAD_PARALLEL_FILLS(function, minPixels) function(0
, count)
4016 const Operator op = getOperator(data,
nullptr, 0);
4017 const uint color = data->solidColor.rgba();
4018 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4019 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4021 auto function = [=] (
int cStart,
int cEnd) {
4022 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4023 for (
int c = cStart; c < cEnd; ++c) {
4025 int length = spans[c].len;
4026 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore) {
4029 spanfill_from_first(data
->rasterBuffer, bpp, x, spans[c].y, length);
4035 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4036 op.funcSolid(dest, l, color, spans[c].coverage);
4051 const Operator op = getOperator(data,
nullptr, 0);
4052 const uint color = data->solidColor.rgba();
4054 if (op.mode == QPainter::CompositionMode_Source) {
4058 if (spans->coverage == 255) {
4059 qt_memfill(target, color, spans->len);
4061 }
else if (spans->len > 16) {
4062 op.funcSolid(target, spans->len, color, spans->coverage);
4065 uint c = BYTE_MUL(color, spans->coverage);
4066 int ialpha = 255 - spans->coverage;
4067 for (
int i = 0; i < spans->len; ++i)
4068 target[i] = c + BYTE_MUL(target[i], ialpha);
4074 const auto funcSolid = op.funcSolid;
4075 auto function = [=] (
int cStart,
int cEnd) {
4076 for (
int c = cStart; c < cEnd; ++c) {
4078 funcSolid(target, spans[c].len, color, spans[c].coverage);
4086#if QT_CONFIG(raster_64bit)
4087 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4088 const Operator op = getOperator(data,
nullptr, 0);
4089 if (!op.funcSolid64) {
4090 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit");
4091 return blend_color_generic(count, spans, userData);
4094 const QRgba64 color = data->solidColor.rgba64();
4095 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4096 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4098 auto function = [=, &op] (
int cStart,
int cEnd)
4100 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4101 for (
int c = cStart; c < cEnd; ++c) {
4103 int length = spans[c].len;
4104 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore64) {
4106 op.destStore64(data->rasterBuffer, x, spans[c].y, &color, 1);
4107 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4112 int l = qMin(BufferSize, length);
4113 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4114 op.funcSolid64(dest, l, color, spans[c].coverage);
4116 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4122 QT_THREAD_PARALLEL_FILLS(function, MinParallelSolidPixels);
4124 blend_color_generic(count, spans, userData);
4130#if QT_CONFIG(raster_fp)
4131 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4132 const Operator op = getOperator(data,
nullptr, 0);
4133 if (!op.funcSolidFP || !op.destFetchFP) {
4134 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_fp: unsupported 4xF16 blend attempted, falling back to 32-bit");
4135 return blend_color_generic(count, spans, userData);
4139 data->solidColor.getRgbF(&r, &g, &b, &a);
4140 const QRgbaFloat32 color{r, g, b, a};
4141 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4142 QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4144 auto function = [=, &op] (
int cStart,
int cEnd)
4146 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4147 for (
int c = cStart; c < cEnd; ++c) {
4149 int length = spans[c].len;
4150 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStoreFP) {
4152 op.destStoreFP(data->rasterBuffer, x, spans[c].y, &color, 1);
4153 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4158 int l = qMin(BufferSize, length);
4159 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4160 op.funcSolidFP(dest, l, color, spans[c].coverage);
4162 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4168 QT_THREAD_PARALLEL_FILLS(function, MinParallelSolidPixels);
4170 blend_color_generic_rgb64(count, spans, userData);
4174template <
typename T>
4177 const int const_alpha = (data->type ==
QSpanData::Texture) ? data->texture.const_alpha : 256;
4178 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256;
4180 auto function = [=, &op] (
int cStart,
int cEnd)
4182 T Q_DECL_UNINITIALIZED handler(data, op);
4184 for (
int c = cStart; c < cEnd;) {
4185 if (!spans[c].len) {
4190 const int y = spans[c].y;
4191 int right = x + spans[c].len;
4192 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4195 for (
int i = c + 1; i < cEnd && spans[i].y == y && spans[i].x == right && fetchDest == (!solidSource || spans[i].coverage < 255); ++i)
4196 right += spans[i].len;
4197 int length = right - x;
4203 int process_length = l;
4206 const auto *src = handler.fetch(process_x, y, process_length, fetchDest);
4209 if (x == spans[c].x)
4210 coverage = (spans[c].coverage * const_alpha) >> 8;
4212 int right = spans[c].x + spans[c].len;
4213 int len = qMin(l, right - x);
4215 handler.process(x, y, len, coverage, src, offset);
4224 handler.store(process_x, y, process_length);
4250 if (fetchDest || op.destFetch == destFetchARGB32P)
4251 dest = op.destFetch(buffer, data->rasterBuffer, x, y, len);
4254 return op.srcFetch(src_buffer, &op, data, y, x, len);
4257 void process(
int,
int,
int len,
int coverage,
const uint *src,
int offset)
4259 op.func(dest + offset, src + offset, len, coverage);
4265 op.destStore(data->rasterBuffer, x, y, dest, len);
4269#if QT_CONFIG(raster_64bit)
4270class BlendSrcGenericRGB64 :
public QBlendBase
4273 QRgba64 *dest =
nullptr;
4274 alignas(16) QRgba64 buffer[BufferSize];
4275 alignas(16) QRgba64 src_buffer[BufferSize];
4276 BlendSrcGenericRGB64(
const QSpanData *d,
const Operator &o)
4281 bool isSupported()
const
4283 return op.func64 && op.destFetch64;
4286 const QRgba64 *fetch(
int x,
int y,
int len,
bool fetchDest)
4288 if (fetchDest || op.destFetch64 == destFetchRGB64)
4289 dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
4292 return op.srcFetch64(src_buffer, &op, data, y, x, len);
4295 void process(
int,
int,
int len,
int coverage,
const QRgba64 *src,
int offset)
4297 op.func64(dest + offset, src + offset, len, coverage);
4300 void store(
int x,
int y,
int len)
4303 op.destStore64(data->rasterBuffer, x, y, dest, len);
4308#if QT_CONFIG(raster_fp)
4309class BlendSrcGenericRGBFP :
public QBlendBase
4312 QRgbaFloat32 *dest =
nullptr;
4313 alignas(16) QRgbaFloat32 buffer[BufferSize];
4314 alignas(16) QRgbaFloat32 src_buffer[BufferSize];
4315 BlendSrcGenericRGBFP(
const QSpanData *d,
const Operator &o)
4320 bool isSupported()
const
4322 return op.funcFP && op.destFetchFP && op.srcFetchFP;
4325 const QRgbaFloat32 *fetch(
int x,
int y,
int len,
bool fetchDest)
4327 if (fetchDest || op.destFetchFP == destFetchRGBFP)
4328 dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
4331 return op.srcFetchFP(src_buffer, &op, data, y, x, len);
4334 void process(
int,
int,
int len,
int coverage,
const QRgbaFloat32 *src,
int offset)
4336 op.funcFP(dest + offset, src + offset, len, coverage);
4339 void store(
int x,
int y,
int len)
4342 op.destStoreFP(data->rasterBuffer, x, y, dest, len);
4350 const Operator op = getOperator(data,
nullptr, 0);
4354#if QT_CONFIG(raster_64bit)
4355static void blend_src_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4357 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4358 const Operator op = getOperator(data,
nullptr, 0);
4359 if (op.func64 && op.destFetch64) {
4360 handleSpans<BlendSrcGenericRGB64>(count, spans, data, op);
4362 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4363 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4368#if QT_CONFIG(raster_fp)
4369static void blend_src_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4371 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4372 const Operator op = getOperator(data, spans, count);
4373 if (op.funcFP && op.destFetchFP && op.srcFetchFP) {
4374 handleSpans<BlendSrcGenericRGBFP>(count, spans, data, op);
4376 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4377 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4386 const Operator op = getOperator(data, spans, count);
4388 const int image_width = data->texture.width;
4389 const int image_height = data->texture.height;
4390 const int const_alpha = data->texture.const_alpha;
4391 const int xoff = -qRound(-data->dx);
4392 const int yoff = -qRound(-data->dy);
4393 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch != destFetchARGB32P;
4395 auto function = [=, &op] (
int cStart,
int cEnd)
4397 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4398 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4399 for (
int c = cStart; c < cEnd; ++c) {
4403 int length = spans[c].len;
4405 int sy = yoff + spans[c].y;
4406 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4407 if (sy >= 0 && sy < image_height && sx < image_width) {
4413 if (sx + length > image_width)
4414 length = image_width - sx;
4416 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4419 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4420 uint *dest = fetchDest ? op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4421 op.func(dest, src, l, coverage);
4435#if QT_CONFIG(raster_64bit)
4436static void blend_untransformed_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4438 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4440 const Operator op = getOperator(data, spans, count);
4442 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4443 return blend_untransformed_generic(count, spans, userData);
4446 const int image_width = data->texture.width;
4447 const int image_height = data->texture.height;
4448 const int const_alpha = data->texture.const_alpha;
4449 const int xoff = -qRound(-data->dx);
4450 const int yoff = -qRound(-data->dy);
4451 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch64 != destFetchRGB64;
4453 auto function = [=, &op] (
int cStart,
int cEnd)
4455 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4456 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4457 for (
int c = cStart; c < cEnd; ++c) {
4461 int length = spans[c].len;
4463 int sy = yoff + spans[c].y;
4464 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4465 if (sy >= 0 && sy < image_height && sx < image_width) {
4471 if (sx + length > image_width)
4472 length = image_width - sx;
4474 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4476 int l = qMin(BufferSize, length);
4477 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4478 QRgba64 *dest = fetchDest ? op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4479 op.func64(dest, src, l, coverage);
4481 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4490 QT_THREAD_PARALLEL_FILLS(function, MinParallelBlendPixels);
4494#if QT_CONFIG(raster_fp)
4495static void blend_untransformed_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4497 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4499 const Operator op = getOperator(data, spans, count);
4501 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgbaf16: unsupported 4xFP16 blend attempted, falling back to 32-bit");
4502 return blend_untransformed_generic(count, spans, userData);
4505 const int image_width = data->texture.width;
4506 const int image_height = data->texture.height;
4507 const int xoff = -qRound(-data->dx);
4508 const int yoff = -qRound(-data->dy);
4509 const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetchFP != destFetchRGBFP;
4511 auto function = [=, &op] (
int cStart,
int cEnd)
4513 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4514 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4515 for (
int c = cStart; c < cEnd; ++c) {
4519 int length = spans[c].len;
4521 int sy = yoff + spans[c].y;
4522 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4523 if (sy >= 0 && sy < image_height && sx < image_width) {
4529 if (sx + length > image_width)
4530 length = image_width - sx;
4532 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4534 int l = qMin(BufferSize, length);
4535 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4536 QRgbaFloat32 *dest = fetchDest ? op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4537 op.funcFP(dest, src, l, coverage);
4539 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4548 QT_THREAD_PARALLEL_FILLS(function, MinParallelBlendPixels);
4555 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4556 && data->texture.format != QImage::Format_RGB32) {
4557 blend_untransformed_generic(count, spans, userData);
4561 const Operator op = getOperator(data, spans, count);
4563 const int image_width = data->texture.width;
4564 const int image_height = data->texture.height;
4565 const int const_alpha = data->texture.const_alpha;
4566 const int xoff = -qRound(-data->dx);
4567 const int yoff = -qRound(-data->dy);
4569 auto function = [=, &op] (
int cStart,
int cEnd)
4571 for (
int c = cStart; c < cEnd; ++c) {
4575 int length = spans[c].len;
4577 int sy = yoff + spans[c].y;
4578 if (sy >= 0 && sy < image_height && sx < image_width) {
4584 if (sx + length > image_width)
4585 length = image_width - sx;
4587 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4588 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4590 op.func(dest, src, length, coverage);
4599 quint16 y, quint8 b)
4601 quint16 t = ((((x & 0x07e0) * a) + ((y & 0x07e0) * b)) >> 5) & 0x07e0;
4602 t |= ((((x & 0xf81f) * a) + ((y & 0xf81f) * b)) >> 5) & 0xf81f;
4608 quint32 y, quint8 b)
4611 t = ((((x & 0xf81f07e0) >> 5) * a) + (((y & 0xf81f07e0) >> 5) * b)) & 0xf81f07e0;
4612 t |= ((((x & 0x07e0f81f) * a) + ((y & 0x07e0f81f) * b)) >> 5) & 0x07e0f81f;
4620 const quint8 ialpha)
4622 const int dstAlign = ((quintptr)dest) & 0x3;
4624 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4629 const int srcAlign = ((quintptr)src) & 0x3;
4630 int length32 = length >> 1;
4631 if (length32 && srcAlign == 0) {
4632 while (length32--) {
4633 const quint32 *src32 =
reinterpret_cast<
const quint32*>(src);
4634 quint32 *dest32 =
reinterpret_cast<quint32*>(dest);
4635 *dest32 = interpolate_pixel_rgb16x2_255(*src32, alpha,
4643 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4652 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4654 if (data->texture.format != QImage::Format_RGB16
4655 || (mode != QPainter::CompositionMode_SourceOver
4656 && mode != QPainter::CompositionMode_Source))
4658 blend_untransformed_generic(count, spans, userData);
4662 const int image_width = data->texture.width;
4663 const int image_height = data->texture.height;
4664 int xoff = -qRound(-data->dx);
4665 int yoff = -qRound(-data->dy);
4667 auto function = [=](
int cStart,
int cEnd)
4669 for (
int c = cStart; c < cEnd; ++c) {
4672 const quint8 coverage = (data->texture.const_alpha * spans[c].coverage) >> 8;
4677 int length = spans[c].len;
4679 int sy = yoff + spans[c].y;
4680 if (sy >= 0 && sy < image_height && sx < image_width) {
4686 if (sx + length > image_width)
4687 length = image_width - sx;
4689 quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans[c].y) + x;
4690 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
4691 if (coverage == 255) {
4692 memcpy(dest, src, length *
sizeof(quint16));
4694 const quint8 alpha = (coverage + 1) >> 3;
4695 const quint8 ialpha = 0x20 - alpha;
4697 blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha);
4710 const Operator op = getOperator(data, spans, count);
4712 const int image_width = data->texture.width;
4713 const int image_height = data->texture.height;
4714 const int const_alpha = data->texture.const_alpha;
4715 int xoff = -qRound(-data->dx) % image_width;
4716 int yoff = -qRound(-data->dy) % image_height;
4719 xoff += image_width;
4721 yoff += image_height;
4723 auto function = [=, &op](
int cStart,
int cEnd)
4725 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4726 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4727 for (
int c = cStart; c < cEnd; ++c) {
4729 int length = spans[c].len;
4730 int sx = (xoff + spans[c].x) % image_width;
4731 int sy = (spans[c].y + yoff) % image_height;
4737 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4739 int l = qMin(image_width - sx, length);
4742 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4743 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4744 op.func(dest, src, l, coverage);
4750 if (sx >= image_width)
4758#if QT_CONFIG(raster_64bit)
4759static void blend_tiled_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4761 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4763 const Operator op = getOperator(data, spans, count);
4765 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4766 return blend_tiled_generic(count, spans, userData);
4769 const int image_width = data->texture.width;
4770 const int image_height = data->texture.height;
4771 int xoff = -qRound(-data->dx) % image_width;
4772 int yoff = -qRound(-data->dy) % image_height;
4775 xoff += image_width;
4777 yoff += image_height;
4779 bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
4780 bool isBpp64 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP64;
4781 if (op.destFetch64 == destFetch64Undefined && image_width <= BufferSize && (isBpp32 || isBpp64)) {
4782 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4787 int length = spans->len;
4788 int sx = (xoff + spans->x) % image_width;
4789 int sy = (spans->y + yoff) % image_height;
4795 int sl = qMin(image_width, length);
4796 if (sx > 0 && sl > 0) {
4797 int l = qMin(image_width - sx, sl);
4798 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4799 op.destStore64(data->rasterBuffer, x, y, src, l);
4803 if (sx >= image_width)
4808 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, sl);
4809 op.destStore64(data->rasterBuffer, x, y, src, sl);
4813 if (sx >= image_width)
4817 uint *dest =
reinterpret_cast<uint *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4818 for (
int i = image_width; i < length; ++i)
4819 dest[i] = dest[i - image_width];
4821 quint64 *dest =
reinterpret_cast<quint64 *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4822 for (
int i = image_width; i < length; ++i)
4823 dest[i] = dest[i - image_width];
4830 auto function = [=, &op](
int cStart,
int cEnd)
4832 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4833 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4834 for (
int c = cStart; c < cEnd; ++c) {
4836 int length = spans[c].len;
4837 int sx = (xoff + spans[c].x) % image_width;
4838 int sy = (spans[c].y + yoff) % image_height;
4844 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4846 int l = qMin(image_width - sx, length);
4849 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4850 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4851 op.func64(dest, src, l, coverage);
4853 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4857 if (sx >= image_width)
4862 QT_THREAD_PARALLEL_FILLS(function, MinParallelBlendPixels);
4866#if QT_CONFIG(raster_fp)
4867static void blend_tiled_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4869 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4871 const Operator op = getOperator(data, spans, count);
4873 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4874 return blend_tiled_generic(count, spans, userData);
4877 const int image_width = data->texture.width;
4878 const int image_height = data->texture.height;
4879 int xoff = -qRound(-data->dx) % image_width;
4880 int yoff = -qRound(-data->dy) % image_height;
4883 xoff += image_width;
4885 yoff += image_height;
4889 auto function = [=, &op](
int cStart,
int cEnd)
4891 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4892 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4893 for (
int c = cStart; c < cEnd; ++c) {
4895 int length = spans[c].len;
4896 int sx = (xoff + spans[c].x) % image_width;
4897 int sy = (spans[c].y + yoff) % image_height;
4903 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4905 int l = qMin(image_width - sx, length);
4908 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4909 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4910 op.funcFP(dest, src, l, coverage);
4912 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4916 if (sx >= image_width)
4921 QT_THREAD_PARALLEL_FILLS(function, MinParallelBlendPixels);
4928 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4929 && data->texture.format != QImage::Format_RGB32) {
4930 blend_tiled_generic(count, spans, userData);
4934 const Operator op = getOperator(data, spans, count);
4936 const int image_width = data->texture.width;
4937 const int image_height = data->texture.height;
4938 int xoff = -qRound(-data->dx) % image_width;
4939 int yoff = -qRound(-data->dy) % image_height;
4942 xoff += image_width;
4944 yoff += image_height;
4945 const auto func = op.func;
4946 const int const_alpha = data->texture.const_alpha;
4948 auto function = [=] (
int cStart,
int cEnd) {
4949 for (
int c = cStart; c < cEnd; ++c) {
4951 int length = spans[c].len;
4952 int sx = (xoff + spans[c].x) % image_width;
4953 int sy = (spans[c].y + yoff) % image_height;
4959 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4961 int l = qMin(image_width - sx, length);
4964 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4966 func(dest, src, l, coverage);
4970 if (sx >= image_width)
4981 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4983 if (data->texture.format != QImage::Format_RGB16
4984 || (mode != QPainter::CompositionMode_SourceOver
4985 && mode != QPainter::CompositionMode_Source))
4987 blend_tiled_generic(count, spans, userData);
4991 const int image_width = data->texture.width;
4992 const int image_height = data->texture.height;
4993 int xoff = -qRound(-data->dx) % image_width;
4994 int yoff = -qRound(-data->dy) % image_height;
4997 xoff += image_width;
4999 yoff += image_height;
5001 const int const_alpha = data->texture.const_alpha;
5002 auto function = [=] (
int cStart,
int cEnd) {
5003 for (
int c = cStart; c < cEnd; ++c) {
5004 const quint8 coverage = (const_alpha * spans[c].coverage) >> 8;
5009 int length = spans[c].len;
5010 int sx = (xoff + spans[c].x) % image_width;
5011 int sy = (spans[c].y + yoff) % image_height;
5017 if (coverage == 255) {
5019 length = qMin(image_width,length);
5022 int l = qMin(image_width - sx, length);
5025 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + tx;
5026 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5027 memcpy(dest, src, l *
sizeof(quint16));
5031 if (sx >= image_width)
5041 int copy_image_width = qMin(image_width,
int(spans[c].len));
5042 length = spans[c].len - copy_image_width;
5043 quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5044 quint16 *dest = src + copy_image_width;
5045 while (copy_image_width < length) {
5046 memcpy(dest, src, copy_image_width *
sizeof(quint16));
5047 dest += copy_image_width;
5048 length -= copy_image_width;
5049 copy_image_width *= 2;
5052 memcpy(dest, src, length *
sizeof(quint16));
5054 const quint8 alpha = (coverage + 1) >> 3;
5055 const quint8 ialpha = 0x20 - alpha;
5058 int l = qMin(image_width - sx, length);
5061 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5062 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5063 blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
5067 if (sx >= image_width)
5079 blend_untransformed_argb,
5088 blend_untransformed_rgb565,
5097 blend_untransformed_generic,
5098 blend_tiled_generic,
5105#if QT_CONFIG(raster_64bit)
5106static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
5107 blend_untransformed_generic_rgb64,
5108 blend_tiled_generic_rgb64,
5109 blend_src_generic_rgb64,
5110 blend_src_generic_rgb64,
5111 blend_src_generic_rgb64,
5112 blend_src_generic_rgb64
5116#if QT_CONFIG(raster_fp)
5117static const ProcessSpans processTextureSpansGenericFP[NBlendTypes] = {
5118 blend_untransformed_generic_fp,
5119 blend_tiled_generic_fp,
5120 blend_src_generic_fp,
5121 blend_src_generic_fp,
5122 blend_src_generic_fp,
5123 blend_src_generic_fp
5132 case QImage::Format_Invalid:
5133 Q_UNREACHABLE_RETURN();
5134 case QImage::Format_ARGB32_Premultiplied:
5137 case QImage::Format_RGB16:
5140#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5141 case QImage::Format_ARGB32:
5142 case QImage::Format_RGBA8888:
5144 case QImage::Format_BGR30:
5145 case QImage::Format_A2BGR30_Premultiplied:
5146 case QImage::Format_RGB30:
5147 case QImage::Format_A2RGB30_Premultiplied:
5148 case QImage::Format_RGBX64:
5149 case QImage::Format_RGBA64:
5150 case QImage::Format_RGBA64_Premultiplied:
5151 case QImage::Format_Grayscale16:
5152#if !QT_CONFIG(raster_fp)
5153 case QImage::Format_RGBX16FPx4:
5154 case QImage::Format_RGBA16FPx4:
5155 case QImage::Format_RGBA16FPx4_Premultiplied:
5156 case QImage::Format_RGBX32FPx4:
5157 case QImage::Format_RGBA32FPx4:
5158 case QImage::Format_RGBA32FPx4_Premultiplied:
5160#if QT_CONFIG(raster_64bit)
5161 proc = processTextureSpansGeneric64[blendType];
5164#if QT_CONFIG(raster_fp)
5165 case QImage::Format_RGBX16FPx4:
5166 case QImage::Format_RGBA16FPx4:
5167 case QImage::Format_RGBA16FPx4_Premultiplied:
5168 case QImage::Format_RGBX32FPx4:
5169 case QImage::Format_RGBA32FPx4:
5170 case QImage::Format_RGBA32FPx4_Premultiplied:
5171 proc = processTextureSpansGenericFP[blendType];
5178 proc(count, spans, userData);
5184 int *pyinc,
int *poff)
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5200 qreal ryinc = linear.dy * data->m22 * gss *
FIXPT_SIZE;
5201 qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss *
FIXPT_SIZE;
5202 const qreal limit = qreal(
std::numeric_limits<
int>::max() -
FIXPT_SIZE);
5203 if (count && (
std::fabs(ryinc) < limit) && (
std::fabs(roff) < limit)
5204 && (
std::fabs(ryinc * spans->y + roff) < limit)
5205 && (
std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) {
5206 *pyinc =
int(ryinc);
5218 getLinearGradientValues(&linear, data);
5220 CompositionFunctionSolid funcSolid =
5223 int yinc(0), off(0);
5224 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5231 quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
5233 qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5235 funcSolid(dst, spans->len, color, spans->coverage);
5247 getLinearGradientValues(&linear, data);
5249 int yinc(0), off(0);
5250 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5256#if QT_CONFIG(raster_64bit)
5257 data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
5259 data->solidColor = qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5261 blend_color(1, spans, userData);
5270 bool isVerticalGradient =
5271 data->txop <= QTransform::TxScale &&
5272 data->type == QSpanData::LinearGradient &&
5273 data->gradient.linear.end.x == data->gradient.linear.origin.x;
5275 case QImage::Format_Invalid:
5277 case QImage::Format_RGB32:
5278 case QImage::Format_ARGB32_Premultiplied:
5279 if (isVerticalGradient && blend_vertical_gradient_argb(count, spans, userData))
5281 return blend_src_generic(count, spans, userData);
5282#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5283 case QImage::Format_ARGB32:
5284 case QImage::Format_RGBA8888:
5286 case QImage::Format_BGR30:
5287 case QImage::Format_A2BGR30_Premultiplied:
5288 case QImage::Format_RGB30:
5289 case QImage::Format_A2RGB30_Premultiplied:
5290 case QImage::Format_RGBX64:
5291 case QImage::Format_RGBA64:
5292 case QImage::Format_RGBA64_Premultiplied:
5293#if !QT_CONFIG(raster_fp)
5294 case QImage::Format_RGBX16FPx4:
5295 case QImage::Format_RGBA16FPx4:
5296 case QImage::Format_RGBA16FPx4_Premultiplied:
5297 case QImage::Format_RGBX32FPx4:
5298 case QImage::Format_RGBA32FPx4:
5299 case QImage::Format_RGBA32FPx4_Premultiplied:
5301#if QT_CONFIG(raster_64bit)
5302 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData))
5304 return blend_src_generic_rgb64(count, spans, userData);
5306#if QT_CONFIG(raster_fp)
5307 case QImage::Format_RGBX16FPx4:
5308 case QImage::Format_RGBA16FPx4:
5309 case QImage::Format_RGBA16FPx4_Premultiplied:
5310 case QImage::Format_RGBX32FPx4:
5311 case QImage::Format_RGBA32FPx4:
5312 case QImage::Format_RGBA32FPx4_Premultiplied:
5313 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_fp>(count, spans, userData))
5315 return blend_src_generic_fp(count, spans, userData);
5318 if (isVerticalGradient && blend_vertical_gradient<
blend_color_generic>(count, spans, userData))
5320 return blend_src_generic(count, spans, userData);
5325template <
class DST>
static
5327 int x,
int y, DST color,
5329 int mapWidth,
int mapHeight,
int mapStride)
5331 DST *dest =
reinterpret_cast<DST *>(rasterBuffer->scanLine(y)) + x;
5332 const int destStride = rasterBuffer->stride<DST>();
5335 while (--mapHeight >= 0) {
5338 for (
int x = 0; x < mapWidth; x += 8) {
5339 uchar s = map[x >> 3];
5340 for (
int i = 0; i < 8; ++i) {
5345 qt_memfill(dest + x0, color, n);
5360 qt_memfill(dest + x0, color, n);
5365 while (--mapHeight >= 0) {
5368 for (uchar s = *map; s; s <<= 1) {
5372 qt_memfill(dest + x0, color, n);
5380 qt_memfill(dest + x0, color, n);
5388 int x,
int y,
const QRgba64 &color,
5390 int mapWidth,
int mapHeight,
int mapStride)
5392 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color.toArgb32(),
5393 map, mapWidth, mapHeight, mapStride);
5397 int x,
int y,
const QRgba64 &color,
5399 int mapWidth,
int mapHeight,
int mapStride)
5401 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()),
5402 map, mapWidth, mapHeight, mapStride);
5405template<QtPixelOrder PixelOrder>
5407 int x,
int y,
const QRgba64 &color,
5409 int mapWidth,
int mapHeight,
int mapStride)
5411 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, qConvertRgb64ToRgb30<PixelOrder>(color),
5412 map, mapWidth, mapHeight, mapStride);
5416 int x,
int y,
const QRgba64 &color,
5418 int mapWidth,
int mapHeight,
int mapStride)
5420 qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color.toRgb16(),
5421 map, mapWidth, mapHeight, mapStride);
5424static inline void grayBlendPixel(quint32 *dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5427 const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5429 QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
5431 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5434static inline void alphamapblend_argb32(quint32 *dst,
int coverage, QRgba64 srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5436 if (coverage == 0) {
5438 }
else if (coverage == 255 || !colorProfile) {
5439 blend_pixel(*dst, src, coverage);
5440 }
else if (*dst < 0xff000000) {
5442 blend_pixel(*dst, src, coverage);
5443 }
else if (src >= 0xff000000) {
5444 grayBlendPixel(dst, coverage, srcLinear, colorProfile);
5448 blend_pixel(s, src);
5450 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5451 grayBlendPixel(dst, coverage, s64, colorProfile);
5455#if QT_CONFIG(raster_64bit)
5457static inline void grayBlendPixel(QRgba64 &dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5460 QRgba64 dstColor = dst;
5462 if (dstColor.isOpaque())
5463 dstColor = colorProfile->toLinear(dstColor);
5464 else if (!dstColor.isTransparent())
5465 dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
5468 blend_pixel(dstColor, srcLinear, coverage);
5471 if (dstColor.isOpaque())
5472 dstColor = colorProfile->fromLinear(dstColor);
5473 else if (!dstColor.isTransparent())
5474 dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
5479static inline void alphamapblend_generic(
int coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5481 if (coverage == 0) {
5483 }
else if (coverage == 255) {
5484 blend_pixel(dest[x], src);
5485 }
else if (src.isOpaque()) {
5486 grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5489 QRgba64 s = dest[x];
5490 blend_pixel(s, src);
5493 s = colorProfile->toLinear(s);
5494 grayBlendPixel(dest[x], coverage, s, colorProfile);
5498static void qt_alphamapblit_generic_oneline(
const uchar *map,
int len,
5499 const QRgba64 srcColor, QRgba64 *dest,
5500 const QRgba64 color,
5501 const QColorTrcLut *colorProfile)
5503 for (
int j = 0; j < len; ++j)
5504 alphamapblend_generic(map[j], dest, j, srcColor, color, colorProfile);
5507static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
5508 int x,
int y,
const QRgba64 &color,
5510 int mapWidth,
int mapHeight,
int mapStride,
5511 const QClipData *clip,
bool useGammaCorrection)
5513 if (color.isTransparent())
5516 const QColorTrcLut *colorProfile =
nullptr;
5518 if (useGammaCorrection)
5519 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5521 QRgba64 srcColor = color;
5522 if (colorProfile && color.isOpaque())
5523 srcColor = colorProfile->toLinear(srcColor);
5525 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5526 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5527 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5530 for (
int ly = 0; ly < mapHeight; ++ly) {
5532 int length = mapWidth;
5533 while (length > 0) {
5534 int l = qMin(BufferSize, length);
5536 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5537 qt_alphamapblit_generic_oneline(map + i - x, l,
5538 srcColor, dest, color,
5541 destStore64(rasterBuffer, i, y + ly, dest, l);
5548 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5550 int top = qMax(y, 0);
5551 map += (top - y) * mapStride;
5553 const_cast<QClipData *>(clip)->initialize();
5554 for (
int yp = top; yp<bottom; ++yp) {
5555 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5557 for (
int i=0; i<line.count; ++i) {
5558 const QT_FT_Span &clip = line.spans[i];
5560 int start = qMax<
int>(x, clip.x);
5561 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5564 Q_ASSERT(end - start <= BufferSize);
5565 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5566 qt_alphamapblit_generic_oneline(map + start - x, end - start,
5567 srcColor, dest, color,
5570 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5578 int x,
int y,
const QRgba64 &color,
5580 int mapWidth,
int mapHeight,
int mapStride,
5581 const QClipData *clip,
bool useGammaCorrection)
5583 if (color.isTransparent())
5586 const quint32 c = color.toArgb32();
5588 const QColorTrcLut *colorProfile =
nullptr;
5590 if (useGammaCorrection)
5591 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5593 QRgba64 srcColor = color;
5594 if (colorProfile && color.isOpaque())
5595 srcColor = colorProfile->toLinear(srcColor);
5598 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
5599 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
5602 for (
int ly = 0; ly < mapHeight; ++ly) {
5604 int length = mapWidth;
5605 while (length > 0) {
5607 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
5608 for (
int j=0; j < l; ++j) {
5609 const int coverage = map[j + (i - x)];
5610 alphamapblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
5613 destStore(rasterBuffer, i, y + ly, dest, l);
5620 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5622 int top = qMax(y, 0);
5623 map += (top - y) * mapStride;
5625 const_cast<
QClipData *>(clip)->initialize();
5626 for (
int yp = top; yp<bottom; ++yp) {
5627 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5629 for (
int i=0; i<line.count; ++i) {
5630 const QT_FT_Span &clip = line.spans[i];
5632 int start = qMax<
int>(x, clip.x);
5633 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5637 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
5639 for (
int xp=start; xp<end; ++xp) {
5640 const int coverage = map[xp - x];
5641 alphamapblend_argb32(dest + xp - x, coverage, srcColor, color, colorProfile);
5644 destStore(rasterBuffer, start, clip.y, dest, end - start);
5654 if (coverage == 0) {
5656 }
else if (coverage == 255) {
5659 dest[x] = BYTE_MUL_RGB16(srcColor, coverage)
5660 + BYTE_MUL_RGB16(dest[x], 255 - coverage);
5665 int x,
int y,
const QRgba64 &color,
5667 int mapWidth,
int mapHeight,
int mapStride,
5668 const QClipData *clip,
bool useGammaCorrection)
5670 if (useGammaCorrection || !color.isOpaque()) {
5671 qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
5675 const quint16 c = color.toRgb16();
5678 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
5679 const int destStride = rasterBuffer->stride<quint16>();
5680 while (--mapHeight >= 0) {
5681 for (
int i = 0; i < mapWidth; ++i)
5682 alphamapblend_quint16(map[i], dest, i, c);
5687 int top = qMax(y, 0);
5688 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5689 map += (top - y) * mapStride;
5691 const_cast<
QClipData *>(clip)->initialize();
5692 for (
int yp = top; yp<bottom; ++yp) {
5693 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5695 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(yp));
5697 for (
int i=0; i<line.count; ++i) {
5698 const QT_FT_Span &clip = line.spans[i];
5700 int start = qMax<
int>(x, clip.x);
5701 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5703 for (
int xp=start; xp<end; ++xp)
5704 alphamapblend_quint16(map[xp - x], dest, xp, c);
5712 int mapWidth,
const QRgba64 &srcColor,
5713 quint32 *dest,
const quint32 c,
5714 const QColorTrcLut *colorProfile)
5716 for (
int i = 0; i < mapWidth; ++i)
5717 alphamapblend_argb32(dest + i, map[i], srcColor, c, colorProfile);
5721 int x,
int y,
const QRgba64 &color,
5723 int mapWidth,
int mapHeight,
int mapStride,
5724 const QClipData *clip,
bool useGammaCorrection)
5726 const quint32 c = color.toArgb32();
5727 const int destStride = rasterBuffer->stride<quint32>();
5729 if (color.isTransparent())
5732 const QColorTrcLut *colorProfile =
nullptr;
5734 if (useGammaCorrection)
5735 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5737 QRgba64 srcColor = color;
5738 if (colorProfile && color.isOpaque())
5739 srcColor = colorProfile->toLinear(srcColor);
5742 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
5743 while (--mapHeight >= 0) {
5744 qt_alphamapblit_argb32_oneline(map, mapWidth, srcColor, dest, c, colorProfile);
5749 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5751 int top = qMax(y, 0);
5752 map += (top - y) * mapStride;
5754 const_cast<
QClipData *>(clip)->initialize();
5755 for (
int yp = top; yp<bottom; ++yp) {
5756 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5758 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
5760 for (
int i=0; i<line.count; ++i) {
5761 const QT_FT_Span &clip = line.spans[i];
5762 int start = qMax<
int>(x, clip.x);
5763 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5764 qt_alphamapblit_argb32_oneline(map + start - x, end - start, srcColor, dest + start, c, colorProfile);
5771#if QT_CONFIG(raster_64bit)
5772static void qt_alphamapblit_nonpremul_argb32(QRasterBuffer *rasterBuffer,
5773 int x,
int y,
const QRgba64 &color,
5775 int mapWidth,
int mapHeight,
int mapStride,
5776 const QClipData *clip,
bool useGammaCorrection)
5779 return qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight,
5780 mapStride, clip, useGammaCorrection);
5782 if (color.isTransparent())
5785 const QColorTrcLut *colorProfile =
nullptr;
5787 if (useGammaCorrection)
5788 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5790 const quint32 c = color.toArgb32();
5791 QRgba64 srcColor = color;
5792 if (colorProfile && color.isOpaque())
5793 srcColor = colorProfile->toLinear(srcColor);
5795 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5796 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5797 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5799 for (
int ly = 0; ly < mapHeight; ++ly) {
5800 bool dstFullyOpaque =
true;
5802 int length = mapWidth;
5803 while (length > 0) {
5804 int l = qMin(BufferSize, length);
5805 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y + ly)) + i;
5806 for (
int j = 0; j < l && dstFullyOpaque; ++j)
5807 dstFullyOpaque = (dest[j] & 0xff000000) == 0xff000000;
5808 if (dstFullyOpaque) {
5810 qt_alphamapblit_argb32_oneline(map + i - x, l, srcColor, dest, c, colorProfile);
5813 QRgba64 *dest64 = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5814 qt_alphamapblit_generic_oneline(map + i - x, l,
5815 srcColor, dest64, color,
5818 destStore64(rasterBuffer, i, y + ly, dest64, l);
5830 return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
5833static inline void rgbBlendPixel(quint32 *dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5836 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5838 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5840 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5845#if defined(__SSE2__
)
5846 __m128i vd = _mm_cvtsi32_si128(d);
5847 __m128i vs = _mm_cvtsi32_si128(s);
5848 __m128i va = _mm_cvtsi32_si128(rgbAlpha);
5849 const __m128i vz = _mm_setzero_si128();
5850 vd = _mm_unpacklo_epi8(vd, vz);
5851 vs = _mm_unpacklo_epi8(vs, vz);
5852 va = _mm_unpacklo_epi8(va, vz);
5853 __m128i vb = _mm_xor_si128(_mm_set1_epi16(255), va);
5854 vs = _mm_mullo_epi16(vs, va);
5855 vd = _mm_mullo_epi16(vd, vb);
5856 vd = _mm_add_epi16(vd, vs);
5857 vd = _mm_add_epi16(vd, _mm_srli_epi16(vd, 8));
5858 vd = _mm_add_epi16(vd, _mm_set1_epi16(0x80));
5859 vd = _mm_srli_epi16(vd, 8);
5860 vd = _mm_packus_epi16(vd, vd);
5861 return _mm_cvtsi128_si32(vd);
5863 const int dr = qRed(d);
5864 const int dg = qGreen(d);
5865 const int db = qBlue(d);
5867 const int sr = qRed(s);
5868 const int sg = qGreen(s);
5869 const int sb = qBlue(s);
5871 const int mr = qRed(rgbAlpha);
5872 const int mg = qGreen(rgbAlpha);
5873 const int mb = qBlue(rgbAlpha);
5875 const int nr = qt_div_255(sr * mr + dr * (255 - mr));
5876 const int ng = qt_div_255(sg * mg + dg * (255 - mg));
5877 const int nb = qt_div_255(sb * mb + db * (255 - mb));
5879 return 0xff000000 | (nr << 16) | (ng << 8) | nb;
5883static inline void alphargbblend_argb32(quint32 *dst,
uint coverage,
const QRgba64 &srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5885 if (coverage == 0xff000000) {
5887 }
else if (coverage == 0xffffffff && qAlpha(src) == 255) {
5888 blend_pixel(*dst, src);
5889 }
else if (*dst < 0xff000000) {
5891 blend_pixel(*dst, src, qRgbAvg(coverage));
5892 }
else if (!colorProfile) {
5895 blend_pixel(s, src);
5897 *dst = rgbBlend(*dst, s, coverage);
5898 }
else if (srcLinear.isOpaque()) {
5899 rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
5903 blend_pixel(s, src);
5905 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5906 rgbBlendPixel(dst, coverage, s64, colorProfile);
5910#if QT_CONFIG(raster_64bit)
5911static inline void rgbBlendPixel(QRgba64 &dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5914 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
5916 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5918 dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
5921static inline void alphargbblend_generic(uint coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5923 if (coverage == 0xff000000) {
5925 }
else if (coverage == 0xffffffff) {
5926 blend_pixel(dest[x], src);
5927 }
else if (!dest[x].isOpaque()) {
5929 alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
5930 }
else if (src.isOpaque()) {
5931 rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5934 QRgba64 s = dest[x];
5935 blend_pixel(s, src);
5938 s = colorProfile->toLinear(s);
5939 rgbBlendPixel(dest[x], coverage, s, colorProfile);
5943static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
5944 int x,
int y,
const QRgba64 &color,
5945 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5946 const QClipData *clip,
bool useGammaCorrection)
5948 if (color.isTransparent())
5951 const QColorTrcLut *colorProfile =
nullptr;
5953 if (useGammaCorrection)
5954 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
5956 QRgba64 srcColor = color;
5957 if (colorProfile && color.isOpaque())
5958 srcColor = colorProfile->toLinear(srcColor);
5960 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5961 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5962 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5965 for (
int ly = 0; ly < mapHeight; ++ly) {
5967 int length = mapWidth;
5968 while (length > 0) {
5969 int l = qMin(BufferSize, length);
5970 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5971 for (
int j=0; j < l; ++j) {
5972 const uint coverage = src[j + (i - x)];
5973 alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile);
5976 destStore64(rasterBuffer, i, y + ly, dest, l);
5983 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5985 int top = qMax(y, 0);
5986 src += (top - y) * srcStride;
5988 const_cast<QClipData *>(clip)->initialize();
5989 for (
int yp = top; yp<bottom; ++yp) {
5990 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5992 for (
int i=0; i<line.count; ++i) {
5993 const QT_FT_Span &clip = line.spans[i];
5995 int start = qMax<
int>(x, clip.x);
5996 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5999 Q_ASSERT(end - start <= BufferSize);
6000 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
6002 for (
int xp=start; xp<end; ++xp) {
6003 const uint coverage = src[xp - x];
6004 alphargbblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
6007 destStore64(rasterBuffer, start, clip.y, dest, end - start);
6015 int x,
int y,
const QRgba64 &color,
6016 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
6017 const QClipData *clip,
bool useGammaCorrection)
6019 if (color.isTransparent())
6022 const quint32 c = color.toArgb32();
6024 const QColorTrcLut *colorProfile =
nullptr;
6026 if (useGammaCorrection)
6027 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6029 QRgba64 srcColor = color;
6030 if (colorProfile && color.isOpaque())
6031 srcColor = colorProfile->toLinear(srcColor);
6033 Q_DECL_UNINITIALIZED quint32 buffer[BufferSize];
6034 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
6035 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
6038 for (
int ly = 0; ly < mapHeight; ++ly) {
6040 int length = mapWidth;
6041 while (length > 0) {
6043 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
6044 for (
int j=0; j < l; ++j) {
6045 const uint coverage = src[j + (i - x)];
6046 alphargbblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
6049 destStore(rasterBuffer, i, y + ly, dest, l);
6056 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6058 int top = qMax(y, 0);
6059 src += (top - y) * srcStride;
6061 const_cast<
QClipData *>(clip)->initialize();
6062 for (
int yp = top; yp<bottom; ++yp) {
6063 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6065 for (
int i=0; i<line.count; ++i) {
6066 const QT_FT_Span &clip = line.spans[i];
6068 int start = qMax<
int>(x, clip.x);
6069 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6073 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
6075 for (
int xp=start; xp<end; ++xp) {
6076 const uint coverage = src[xp - x];
6077 alphargbblend_argb32(dest + xp - start, coverage, srcColor, c, colorProfile);
6080 destStore(rasterBuffer, start, clip.y, dest, end - start);
6089 int x,
int y,
const QRgba64 &color,
6090 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
6091 const QClipData *clip,
bool useGammaCorrection)
6093 if (color.isTransparent())
6096 const quint32 c = color.toArgb32();
6098 const QColorTrcLut *colorProfile =
nullptr;
6100 if (useGammaCorrection)
6101 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6103 QRgba64 srcColor = color;
6104 if (colorProfile && color.isOpaque())
6105 srcColor = colorProfile->toLinear(srcColor);
6108 quint32 *dst =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
6109 const int destStride = rasterBuffer->stride<quint32>();
6110 while (--mapHeight >= 0) {
6111 for (
int i = 0; i < mapWidth; ++i) {
6112 const uint coverage = src[i];
6113 alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
6120 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6122 int top = qMax(y, 0);
6123 src += (top - y) * srcStride;
6125 const_cast<
QClipData *>(clip)->initialize();
6126 for (
int yp = top; yp<bottom; ++yp) {
6127 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6129 quint32 *dst =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
6131 for (
int i=0; i<line.count; ++i) {
6132 const QT_FT_Span &clip = line.spans[i];
6134 int start = qMax<
int>(x, clip.x);
6135 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6137 for (
int xp=start; xp<end; ++xp) {
6138 const uint coverage = src[xp - x];
6139 alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
6149 int x,
int y,
int width,
int height,
6150 const QRgba64 &color)
6152 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6153 color.toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6157 int x,
int y,
int width,
int height,
6158 const QRgba64 &color)
6160 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6161 quint32 c32 = color.toArgb32();
6163 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c16), &c32, 0, 1,
nullptr,
nullptr);
6164 qt_rectfill<quint16>(
reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
6165 c16, x, y, width, height, rasterBuffer->bytesPerLine());
6169 int x,
int y,
int width,
int height,
6170 const QRgba64 &color)
6172 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6173 quint32 c32 = color.toArgb32();
6175 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c24), &c32, 0, 1,
nullptr,
nullptr);
6176 qt_rectfill<
quint24>(
reinterpret_cast<
quint24 *>(rasterBuffer->buffer()),
6177 c24, x, y, width, height, rasterBuffer->bytesPerLine());
6181 int x,
int y,
int width,
int height,
6182 const QRgba64 &color)
6184 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6185 color.unpremultiplied().toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6189 int x,
int y,
int width,
int height,
6190 const QRgba64 &color)
6192 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6193 ARGB2RGBA(color.toArgb32() | 0xff000000), x, y, width, height, rasterBuffer->bytesPerLine());
6197 int x,
int y,
int width,
int height,
6198 const QRgba64 &color)
6200 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6201 ARGB2RGBA(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6205 int x,
int y,
int width,
int height,
6206 const QRgba64 &color)
6208 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6209 ARGB2RGBA(color.unpremultiplied().toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6212template<QtPixelOrder PixelOrder>
6214 int x,
int y,
int width,
int height,
6215 const QRgba64 &color)
6217 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6218 qConvertRgb64ToRgb30<PixelOrder>(color), x, y, width, height, rasterBuffer->bytesPerLine());
6222 int x,
int y,
int width,
int height,
6223 const QRgba64 &color)
6225 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6226 color.alpha() >> 8, x, y, width, height, rasterBuffer->bytesPerLine());
6230 int x,
int y,
int width,
int height,
6231 const QRgba64 &color)
6233 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6234 qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6238 int x,
int y,
int width,
int height,
6239 const QRgba64 &color)
6241 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6243 store(
reinterpret_cast<uchar *>(&c64), &color, 0, 1,
nullptr,
nullptr);
6244 qt_rectfill<quint64>(
reinterpret_cast<quint64 *>(rasterBuffer->buffer()),
6245 c64, x, y, width, height, rasterBuffer->bytesPerLine());
6249 int x,
int y,
int width,
int height,
6250 const QRgba64 &color)
6252 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6254 store(
reinterpret_cast<uchar *>(&c), &color, 0, 1,
nullptr,
nullptr);
6256 c, x, y, width, height, rasterBuffer->bytesPerLine());
6265 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr },
6268 blend_color_generic,
6269 nullptr,
nullptr,
nullptr,
nullptr
6273 blend_color_generic,
6274 nullptr,
nullptr,
nullptr,
nullptr
6278 blend_color_generic,
6279 nullptr,
nullptr,
nullptr,
nullptr
6284 qt_bitmapblit_argb32,
6285 qt_alphamapblit_argb32,
6286 qt_alphargbblit_argb32,
6291 blend_color_generic,
6292 qt_bitmapblit_argb32,
6293#if QT_CONFIG(raster_64bit)
6294 qt_alphamapblit_nonpremul_argb32,
6296 qt_alphamapblit_generic,
6298 qt_alphargbblit_generic,
6299 qt_rectfill_nonpremul_argb32
6304 qt_bitmapblit_argb32,
6305 qt_alphamapblit_argb32,
6306 qt_alphargbblit_argb32,
6311 blend_color_generic,
6312 qt_bitmapblit_quint16,
6313 qt_alphamapblit_quint16,
6314 qt_alphargbblit_generic,
6319 blend_color_generic,
6321 qt_alphamapblit_generic,
6322 qt_alphargbblit_generic,
6327 blend_color_generic,
6329 qt_alphamapblit_generic,
6330 qt_alphargbblit_generic,
6335 blend_color_generic,
6337 qt_alphamapblit_generic,
6338 qt_alphargbblit_generic,
6343 blend_color_generic,
6345 qt_alphamapblit_generic,
6346 qt_alphargbblit_generic,
6351 blend_color_generic,
6353 qt_alphamapblit_generic,
6354 qt_alphargbblit_generic,
6359 blend_color_generic,
6361 qt_alphamapblit_generic,
6362 qt_alphargbblit_generic,
6367 blend_color_generic,
6369 qt_alphamapblit_generic,
6370 qt_alphargbblit_generic,
6375 blend_color_generic,
6377 qt_alphamapblit_generic,
6378 qt_alphargbblit_generic,
6383 blend_color_generic,
6384 qt_bitmapblit_rgba8888,
6385 qt_alphamapblit_generic,
6386 qt_alphargbblit_generic,
6391 blend_color_generic,
6392 qt_bitmapblit_rgba8888,
6393 qt_alphamapblit_generic,
6394 qt_alphargbblit_generic,
6395 qt_rectfill_nonpremul_rgba
6399 blend_color_generic,
6400 qt_bitmapblit_rgba8888,
6401 qt_alphamapblit_generic,
6402 qt_alphargbblit_generic,
6407 blend_color_generic_rgb64,
6408 qt_bitmapblit_rgb30<PixelOrderBGR>,
6409 qt_alphamapblit_generic,
6410 qt_alphargbblit_generic,
6411 qt_rectfill_rgb30<PixelOrderBGR>
6415 blend_color_generic_rgb64,
6416 qt_bitmapblit_rgb30<PixelOrderBGR>,
6417 qt_alphamapblit_generic,
6418 qt_alphargbblit_generic,
6419 qt_rectfill_rgb30<PixelOrderBGR>
6423 blend_color_generic_rgb64,
6424 qt_bitmapblit_rgb30<PixelOrderRGB>,
6425 qt_alphamapblit_generic,
6426 qt_alphargbblit_generic,
6427 qt_rectfill_rgb30<PixelOrderRGB>
6431 blend_color_generic_rgb64,
6432 qt_bitmapblit_rgb30<PixelOrderRGB>,
6433 qt_alphamapblit_generic,
6434 qt_alphargbblit_generic,
6435 qt_rectfill_rgb30<PixelOrderRGB>
6439 blend_color_generic,
6441 qt_alphamapblit_generic,
6442 qt_alphargbblit_generic,
6447 blend_color_generic,
6449 qt_alphamapblit_generic,
6450 qt_alphargbblit_generic,
6455 blend_color_generic_rgb64,
6457 qt_alphamapblit_generic,
6458 qt_alphargbblit_generic,
6463 blend_color_generic_rgb64,
6465 qt_alphamapblit_generic,
6466 qt_alphargbblit_generic,
6471 blend_color_generic_rgb64,
6473 qt_alphamapblit_generic,
6474 qt_alphargbblit_generic,
6479 blend_color_generic_rgb64,
6481 qt_alphamapblit_generic,
6482 qt_alphargbblit_generic,
6487 blend_color_generic,
6489 qt_alphamapblit_generic,
6490 qt_alphargbblit_generic,
6495 blend_color_generic_fp,
6497 qt_alphamapblit_generic,
6498 qt_alphargbblit_generic,
6503 blend_color_generic_fp,
6505 qt_alphamapblit_generic,
6506 qt_alphargbblit_generic,
6511 blend_color_generic_fp,
6513 qt_alphamapblit_generic,
6514 qt_alphargbblit_generic,
6519 blend_color_generic_fp,
6521 qt_alphamapblit_generic,
6522 qt_alphargbblit_generic,
6527 blend_color_generic_fp,
6529 qt_alphamapblit_generic,
6530 qt_alphargbblit_generic,
6535 blend_color_generic_fp,
6537 qt_alphamapblit_generic,
6538 qt_alphargbblit_generic,
6543static_assert(std::size(qDrawHelper) == QImage::NImageFormats);
6545#if !defined(Q_PROCESSOR_X86) && !defined(QT_COMPILER_SUPPORTS_LSX)
6548 qt_memfill_template<quint64>(dest, color, count);
6552#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
6553__attribute__((optimize(
"no-tree-vectorize")))
6557# ifdef QT_COMPILER_SUPPORTS_SSSE3
6558 extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
6559 if (qCpuHasFeature(SSSE3))
6560 return qt_memfill24_ssse3(dest, color, count);
6561# elif defined QT_COMPILER_SUPPORTS_LSX
6562 extern void qt_memfill24_lsx(quint24 *, quint24, qsizetype);
6563 if (qCpuHasFeature(LSX))
6564 return qt_memfill24_lsx(dest, color, count);
6567 const quint32 v = color;
6571 while ((quintptr(dest) & 0x3) && dest < end) {
6577 const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
6578 const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
6579 const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
6581 for ( ; dest <= (end - 4); dest += 4) {
6582 quint32 *dst =
reinterpret_cast<quint32 *>(dest);
6589 switch (end - dest) {
6603 const int align = quintptr(dest) & 0x3;
6610 dest[count - 1] = value;
6612 const quint32 value32 = (value << 16) | value;
6613 qt_memfill32(
reinterpret_cast<quint32*>(dest), value32, count / 2);
6616#if defined(Q_PROCESSOR_X86) || defined(QT_COMPILER_SUPPORTS_LSX)
6617void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count) =
nullptr;
6618void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count) =
nullptr;
6619#elif !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
6622 qt_memfill_template<quint32>(dest, color, count);
6626#ifdef QT_COMPILER_SUPPORTS_SSE4_1
6627template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6628#elif defined(QT_COMPILER_SUPPORTS_LSX)
6629template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6639#if defined(Q_PROCESSOR_X86) && !defined(__SSE2__
)
6640 qt_memfill32 = qt_memfill_template<quint32>;
6641 qt_memfill64 = qt_memfill_template<quint64>;
6642#elif defined(__SSE2__
)
6644 qt_memfill32 = qt_memfill32_sse2;
6645 qt_memfill64 = qt_memfill64_sse2;
6647 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
6648 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
6649 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
6650 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
6651 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_sse2;
6652 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_sse2;
6653 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
6655 extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6656 const uchar *srcPixels,
int sbpl,
int srch,
6657 const QRectF &targetRect,
6658 const QRectF &sourceRect,
6661 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6662 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6663 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6664 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6666 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels,
int dbpl,
6667 const uchar *srcPixels,
int sbpl,
6670 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6671 const uchar *srcPixels,
int sbpl,
6675 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6676 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6677 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6678 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6679 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6680 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6681 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6682 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6684 extern const uint *
QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer,
const Operator *op,
const QSpanData *data,
6685 int y,
int x,
int length);
6687 qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
6689 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6690 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6691 extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6692 extern void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6693 extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6694 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
6695 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
6696 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
6697 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_sse2;
6698 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
6700#ifdef QT_COMPILER_SUPPORTS_SSSE3
6701 if (qCpuHasFeature(SSSE3)) {
6702 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels,
int dbpl,
6703 const uchar *srcPixels,
int sbpl,
6707 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer,
const Operator *,
const QSpanData *data,
6708 int y,
int x,
int length);
6709 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6710 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6711 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6712 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6713 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
6714 extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst,
const uchar *src,
int count);
6715 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
6716 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
6720#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
6721 if (qCpuHasFeature(SSE4_1)) {
6722 extern void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6723 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6724 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6725 const QList<QRgb> *, QDitherInfo *);
6726 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6727 const QList<QRgb> *, QDitherInfo *);
6728 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6729 const QList<QRgb> *, QDitherInfo *);
6730 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6731 const QList<QRgb> *, QDitherInfo *);
6732 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6733 const QList<QRgb> *, QDitherInfo *);
6734 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6735 const QList<QRgb> *, QDitherInfo *);
6736 extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6737 const QList<QRgb> *, QDitherInfo *);
6738 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6739 const QList<QRgb> *, QDitherInfo *);
6740 extern void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6741 const QList<QRgb> *, QDitherInfo *);
6742 extern void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6743 const QList<QRgb> *, QDitherInfo *);
6744 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6745 const QList<QRgb> *, QDitherInfo *);
6746 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6747 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6748 extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6749 extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6751 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
6752 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
6753 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
6754 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
6755 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4;
6756 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4;
6757 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6758 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6759 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6760 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6762 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
6763 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
6764 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
6765 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
6766 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
6767 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
6768 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
6769 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_sse4;
6770 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_sse4;
6771#if QT_CONFIG(raster_64bit)
6772 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
6773 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
6775#if QT_CONFIG(raster_fp)
6776 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_sse4(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6777 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6778 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6779 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_sse4;
6780 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_sse4;
6781 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_sse4;
6786#if defined(QT_COMPILER_SUPPORTS_AVX2)
6787 if (qCpuHasFeature(ArchHaswell)) {
6788 qt_memfill32 = qt_memfill32_avx2;
6789 qt_memfill64 = qt_memfill64_avx2;
6790 extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels,
int dbpl,
6791 const uchar *srcPixels,
int sbpl,
6792 int w,
int h,
int const_alpha);
6793 extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels,
int dbpl,
6794 const uchar *srcPixels,
int sbpl,
6795 int w,
int h,
int const_alpha);
6796 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6797 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6798 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6799 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6800 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6801 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6802 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6803 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6805 extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6806 extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6807 extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels,
int length, uint color, uint const_alpha);
6808 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
6809 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
6810 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
6811#if QT_CONFIG(raster_64bit)
6812 extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6813 extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6814 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
6815 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
6816 qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
6817 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
6819#if QT_CONFIG(raster_fp)
6820 extern void QT_FASTCALL comp_func_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6821 extern void QT_FASTCALL comp_func_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6822 extern void QT_FASTCALL comp_func_solid_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6823 extern void QT_FASTCALL comp_func_solid_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6824 qt_functionForModeFP_C[QPainter::CompositionMode_Source] = comp_func_Source_rgbafp_avx2;
6825 qt_functionForModeFP_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgbafp_avx2;
6826 qt_functionForModeSolidFP_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_rgbafp_avx2;
6827 qt_functionForModeSolidFP_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgbafp_avx2;
6830 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6831 int &fx,
int &fy,
int fdx,
int );
6832 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6833 int &fx,
int &fy,
int fdx,
int );
6834 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6835 int &fx,
int &fy,
int fdx,
int fdy);
6837 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
6838 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
6839 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
6841 extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6842 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6843 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6844 const QList<QRgb> *, QDitherInfo *);
6845 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6846 const QList<QRgb> *, QDitherInfo *);
6847 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2;
6848 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
6849 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
6850 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
6852 extern const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
6853 extern const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
6854 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6855 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6856 extern const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6857 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2;
6858 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
6859 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
6860 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
6861 qPixelLayouts[QImage::Format_RGBA64].fetchToRGBA64PM = fetchRGBA64ToRGBA64PM_avx2;
6863 extern const uint *QT_FASTCALL fetchRGB16FToRGB32_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6864 extern const uint *QT_FASTCALL fetchRGBA16FToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6865 extern const QRgba64 *QT_FASTCALL fetchRGBA16FPMToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6866 extern const QRgba64 *QT_FASTCALL fetchRGBA16FToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6867 extern void QT_FASTCALL storeRGB16FFromRGB32_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6868 extern void QT_FASTCALL storeRGBA16FFromARGB32PM_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6869 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6870 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6871 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6872 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6873 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToARGB32PM = fetchRGBA16FToARGB32PM_avx2;
6874 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToRGBA64PM = fetchRGBA16FToRGBA64PM_avx2;
6875 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromARGB32PM = storeRGBA16FFromARGB32PM_avx2;
6876 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6877 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6878 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6879 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6880 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6881#if QT_CONFIG(raster_fp)
6882 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA16FToRGBA32F_avx2(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6883 extern void QT_FASTCALL storeRGBX16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6884 extern void QT_FASTCALL storeRGBA16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6885 qFetchToRGBA32F[QImage::Format_RGBA16FPx4] = fetchRGBA16FToRGBA32F_avx2;
6886 qStoreFromRGBA32F[QImage::Format_RGBX16FPx4] = storeRGBX16FFromRGBA32F_avx2;
6887 qStoreFromRGBA32F[QImage::Format_RGBA16FPx4] = storeRGBA16FFromRGBA32F_avx2;
6895#if defined(QT_COMPILER_SUPPORTS_LSX)
6896 if (qCpuHasFeature(LSX)) {
6897 qt_memfill32 = qt_memfill32_lsx;
6898 qt_memfill64 = qt_memfill64_lsx;
6900 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_lsx;
6901 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_lsx;
6902 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_lsx;
6903 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_lsx;
6904 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_lsx;
6905 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_lsx;
6906 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_lsx;
6908 extern void qt_scale_image_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6909 const uchar *srcPixels,
int sbpl,
int srch,
6910 const QRectF &targetRect,
6911 const QRectF &sourceRect,
6915 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6916 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6917 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6918 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6920 extern void qt_blend_rgb32_on_rgb32_lsx(uchar *destPixels,
int dbpl,
6921 const uchar *srcPixels,
int sbpl,
6925 extern void qt_blend_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6926 const uchar *srcPixels,
int sbpl,
6930 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6931 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6932 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6933 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6934 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6935 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6936 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6937 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6939 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_lsx(uint *buffer,
const Operator *op,
const QSpanData *data,
6940 int y,
int x,
int length);
6942 qt_fetch_radial_gradient = qt_fetch_radial_gradient_lsx;
6944 extern void QT_FASTCALL comp_func_SourceOver_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6945 extern void QT_FASTCALL comp_func_solid_SourceOver_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6946 extern void QT_FASTCALL comp_func_Source_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6947 extern void QT_FASTCALL comp_func_solid_Source_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6948 extern void QT_FASTCALL comp_func_Plus_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6949 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lsx;
6950 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lsx;
6951 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lsx;
6952 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_lsx;
6953 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_lsx;
6955 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_lsx(uint *buffer,
const Operator *,
const QSpanData *data,
6956 int y,
int x,
int length);
6957 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_lsx;
6958 extern void QT_FASTCALL rbSwap_888_lsx(uchar *dst,
const uchar *src,
int count);
6959 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_lsx;
6960 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_lsx;
6962 extern void QT_FASTCALL convertARGB32ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6963 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6964 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6965 const QList<QRgb> *, QDitherInfo *);
6966 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6967 const QList<QRgb> *, QDitherInfo *);
6968 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6969 const QList<QRgb> *, QDitherInfo *);
6970 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6971 const QList<QRgb> *, QDitherInfo *);
6972 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6973 const QList<QRgb> *, QDitherInfo *);
6974 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6975 const QList<QRgb> *, QDitherInfo *);
6976 extern void QT_FASTCALL storeARGB32FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6977 const QList<QRgb> *, QDitherInfo *);
6978 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6979 const QList<QRgb> *, QDitherInfo *);
6980 extern void QT_FASTCALL storeRGBXFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6981 const QList<QRgb> *, QDitherInfo *);
6982 extern void QT_FASTCALL storeARGB32FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6983 const QList<QRgb> *, QDitherInfo *);
6984 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6985 const QList<QRgb> *, QDitherInfo *);
6986 extern void QT_FASTCALL destStore64ARGB32_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6987 extern void QT_FASTCALL destStore64RGBA8888_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6988 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6989 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6990 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lsx;
6991 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lsx;
6992 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lsx;
6993 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lsx;
6994 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lsx;
6995 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lsx;
6996 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6997 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6998 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6999 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
7000 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_lsx;
7001 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_lsx;
7002 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_lsx;
7003 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderBGR>;
7004 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderRGB>;
7005 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_lsx;
7006 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_lsx;
7007 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_lsx;
7008 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_lsx;
7009#if QT_CONFIG(raster_64bit)
7010 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_lsx;
7011 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_lsx;
7013#if QT_CONFIG(raster_fp)
7014 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_lsx(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
7015 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
7016 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
7017 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_lsx;
7018 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_lsx;
7019 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_lsx;
7023#if defined(QT_COMPILER_SUPPORTS_LASX)
7024 if (qCpuHasFeature(LASX)) {
7025 qt_memfill32 = qt_memfill32_lasx;
7026 qt_memfill64 = qt_memfill64_lasx;
7028 extern void qt_blend_rgb32_on_rgb32_lasx(uchar *destPixels,
int dbpl,
7029 const uchar *srcPixels,
int sbpl,
7030 int w,
int h,
int const_alpha);
7031 extern void qt_blend_argb32_on_argb32_lasx(uchar *destPixels,
int dbpl,
7032 const uchar *srcPixels,
int sbpl,
7033 int w,
int h,
int const_alpha);
7034 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7035 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7036 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7037 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7038 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7039 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7040 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7041 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7043 extern void QT_FASTCALL comp_func_Source_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7044 extern void QT_FASTCALL comp_func_SourceOver_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7045 extern void QT_FASTCALL comp_func_solid_SourceOver_lasx(uint *destPixels,
int length, uint color, uint const_alpha);
7046 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lasx;
7047 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lasx;
7048 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lasx;
7049#if QT_CONFIG(raster_64bit)
7050 extern void QT_FASTCALL comp_func_Source_rgb64_lasx(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
7051 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_lasx(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
7052 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_lasx;
7053 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_lasx;
7056 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7057 int &fx,
int &fy,
int fdx,
int );
7058 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7059 int &fx,
int &fy,
int fdx,
int );
7060 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7061 int &fx,
int &fy,
int fdx,
int fdy);
7063 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx;
7064 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_lasx;
7065 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx;
7067 extern void QT_FASTCALL convertARGB32ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7068 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7069 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7070 const QList<QRgb> *, QDitherInfo *);
7071 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7072 const QList<QRgb> *, QDitherInfo *);
7073 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lasx;
7074 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lasx;
7075 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lasx;
7076 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lasx;
7078 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
7079 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
7080 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7081 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7082 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lasx;
7083 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lasx;
7084 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lasx;
7085 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lasx;
7091#if defined(__ARM_NEON__)
7092 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7093 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7094 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7095 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7096#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7097 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7098 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7099 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7100 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7103 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_neon;
7104 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
7105 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
7107 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer,
const Operator *op,
const QSpanData *data,
7108 int y,
int x,
int length);
7110 qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
7112 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
7114#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7115 extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7116 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7117 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7118 const QList<QRgb> *, QDitherInfo *);
7119 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7120 const QList<QRgb> *, QDitherInfo *);
7121 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7122 const QList<QRgb> *, QDitherInfo *);
7123 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7124 const QList<QRgb> *, QDitherInfo *);
7125 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7126 const QList<QRgb> *, QDitherInfo *);
7127 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7128 const QList<QRgb> *, QDitherInfo *);
7129 extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7130 const QList<QRgb> *, QDitherInfo *);
7131 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7132 const QList<QRgb> *, QDitherInfo *);
7133 extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7134 const QList<QRgb> *, QDitherInfo *);
7135 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
7136 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
7137 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
7138 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon;
7139 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon;
7140 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
7141 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
7142 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
7143 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7144 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7145 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
7146 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7147 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7150#if defined(ENABLE_PIXMAN_DRAWHELPERS)
7152 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
7153 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
7154 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
7156 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
7157 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
7159 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
7160 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
7162 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
7164 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
7165 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
7167 qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon;
7168 qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon;
7172#if defined(__MIPS_DSP__)
7174 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
7175 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
7176 qt_functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
7177 qt_functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
7178 qt_functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
7179 qt_functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
7180 qt_functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
7181 qt_functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
7182 qt_functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
7183 qt_functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
7185 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
7186 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
7187 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
7188 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
7189 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
7190 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
7191 qt_functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
7192 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
7194 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7195 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7196 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7197 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7199 destFetchProc[QImage::Format_ARGB32] = qt_destFetchARGB32_mips_dsp;
7201 destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
7203 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
7204 sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
7205 sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
7207#if defined(__MIPS_DSPR2__)
7208 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
7209 sourceFetchUntransformed[QImage::Format_RGB16] = qt_fetchUntransformedRGB16_mips_dspr2;
7211 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dsp;
const uint * fetch(int x, int y, int len, bool fetchDest)
uint src_buffer[BufferSize]
void store(int x, int y, int len)
BlendSrcGeneric(const QSpanData *d, const Operator &o)
void process(int, int, int len, int coverage, const uint *src, int offset)
static Type fetchSingle(const QGradientData &gradient, qreal v)
static void memfill(Type *buffer, Type fill, int length)
static void fetch(BlendType *buffer, BlendType *end, const Operator *op, const QSpanData *data, qreal det, qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
GradientBase::Type BlendType
Combined button and popup list for selecting options.
void qInitBlendFunctions()
CompositionFunctionFP qt_functionForModeFP_C[]
CompositionFunction qt_functionForMode_C[]
CompositionFunctionSolidFP qt_functionForModeSolidFP_C[]
CompositionFunction64 qt_functionForMode64_C[]
CompositionFunctionSolid qt_functionForModeSolid_C[]
CompositionFunctionSolid64 qt_functionForModeSolid64_C[]
void(QT_FASTCALL * BilinearFastTransformHelper)(uint *b, uint *end, const QTextureData &image, int &fx, int &fy, int fdx, int fdy)
static int qRgbAvg(QRgb rgb)
static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
static void qt_alphamapblit_argb32_oneline(const uchar *map, int mapWidth, const QRgba64 &srcColor, quint32 *dest, const quint32 c, const QColorTrcLut *colorProfile)
static const CompositionFunctionSolid * functionForModeSolid
static DestFetchProc destFetchProc[]
constexpr Fetch1PixelFunc fetch1PixelTable[QPixelLayout::BPPCount]
static void alphamapblend_quint16(int coverage, quint16 *dest, int x, const quint16 srcColor)
static BilinearFastTransformHelper bilinearFastTransformHelperARGB32PM[2][NFastTransformTypes]
static void qt_rectfill_rgbx(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
#define QT_THREAD_PARALLEL_FILLS(function, minPixels)
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)
uint(QT_FASTCALL * Fetch1PixelFunc)(const uchar *src, int index)
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