7#include <qstylehints.h>
8#include <qguiapplication.h>
10#include <private/qcolortransform_p.h>
11#include <private/qcolortrclut_p.h>
12#include <private/qdrawhelper_p.h>
13#include <private/qdrawhelper_x86_p.h>
14#include <private/qdrawingprimitive_sse2_p.h>
15#include <private/qdrawhelper_loongarch64_p.h>
16#include <private/qdrawingprimitive_lsx_p.h>
17#include <private/qdrawhelper_neon_p.h>
18#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
19#include <private/qdrawhelper_mips_dsp_p.h>
21#include <private/qguiapplication_p.h>
22#include <private/qpaintengine_raster_p.h>
23#include <private/qpainter_p.h>
24#include <private/qpixellayout_p.h>
25#include <private/qrgba64_p.h>
27#include <qloggingcategory.h>
30#if QT_CONFIG(qtgui_threadpool)
31#include <qsemaphore.h>
32#include <qthreadpool.h>
33#include <private/qthreadpool_p.h>
40#define MASK(src, a) src = BYTE_MUL(src, a)
43
44
52 Q_UNREACHABLE_RETURN(0);
56inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1LSB>(
const uchar *src,
int index)
58 return (src[index >> 3] >> (index & 7)) & 1;
62inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP1MSB>(
const uchar *src,
int index)
64 return (src[index >> 3] >> (~index & 7)) & 1;
68inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP8>(
const uchar *src,
int index)
74inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16>(
const uchar *src,
int index)
76 return reinterpret_cast<
const quint16 *>(src)[index];
80inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP24>(
const uchar *src,
int index)
82 return reinterpret_cast<
const quint24 *>(src)[index];
86inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32>(
const uchar *src,
int index)
88 return reinterpret_cast<
const uint *>(src)[index];
92inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP64>(
const uchar *src,
int index)
95 QRgba64 c =
reinterpret_cast<
const QRgba64 *>(src)[index];
100inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP16FPx4>(
const uchar *src,
int index)
103 QRgbaFloat16 c =
reinterpret_cast<
const QRgbaFloat16 *>(src)[index];
108inline uint
QT_FASTCALL fetch1Pixel<QPixelLayout::BPP32FPx4>(
const uchar *src,
int index)
111 QRgbaFloat32 c =
reinterpret_cast<
const QRgbaFloat32 *>(src)[index];
119 fetch1Pixel<QPixelLayout::BPP1MSB>,
120 fetch1Pixel<QPixelLayout::BPP1LSB>,
121 fetch1Pixel<QPixelLayout::BPP8>,
122 fetch1Pixel<QPixelLayout::BPP16>,
123 fetch1Pixel<QPixelLayout::BPP24>,
124 fetch1Pixel<QPixelLayout::BPP32>,
125 fetch1Pixel<QPixelLayout::BPP64>,
126 fetch1Pixel<QPixelLayout::BPP16FPx4>,
127 fetch1Pixel<QPixelLayout::BPP32FPx4>,
130#if QT_CONFIG(raster_64bit)
131static void QT_FASTCALL convertRGBA64ToRGBA64PM(QRgba64 *buffer,
int count)
133 for (
int i = 0; i < count; ++i)
134 buffer[i] = buffer[i].premultiplied();
137static void QT_FASTCALL convertRGBA64PMToRGBA64PM(QRgba64 *,
int)
141static void QT_FASTCALL convertRGBA16FToRGBA64PM(QRgba64 *buffer,
int count)
143 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
144 for (
int i = 0; i < count; ++i) {
145 QRgbaFloat16 c = in[i];
146 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
150static void QT_FASTCALL convertRGBA16FPMToRGBA64PM(QRgba64 *buffer,
int count)
152 const QRgbaFloat16 *in =
reinterpret_cast<
const QRgbaFloat16 *>(buffer);
153 for (
int i = 0; i < count; ++i) {
154 QRgbaFloat16 c = in[i];
155 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
159static void QT_FASTCALL convertRGBA32FToRGBA64PM(QRgba64 *buffer,
int count)
161 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
162 for (
int i = 0; i < count; ++i) {
163 QRgbaFloat32 c = in[i];
164 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16()).premultiplied();
168static void QT_FASTCALL convertRGBA32FPMToRGBA64PM(QRgba64 *buffer,
int count)
170 const QRgbaFloat32 *in =
reinterpret_cast<
const QRgbaFloat32 *>(buffer);
171 for (
int i = 0; i < count; ++i) {
172 QRgbaFloat32 c = in[i];
173 buffer[i] = QRgba64::fromRgba64(c.red16(), c.green16(), c.blue16(), c.alpha16());
177static Convert64Func convert64ToRGBA64PM[] = {
203 convertRGBA64PMToRGBA64PM,
204 convertRGBA64ToRGBA64PM,
205 convertRGBA64PMToRGBA64PM,
208 convertRGBA16FPMToRGBA64PM,
209 convertRGBA16FToRGBA64PM,
210 convertRGBA16FPMToRGBA64PM,
211 convertRGBA32FPMToRGBA64PM,
212 convertRGBA32FToRGBA64PM,
213 convertRGBA32FPMToRGBA64PM,
217static_assert(std::size(convert64ToRGBA64PM) == QImage::NImageFormats);
220#if QT_CONFIG(raster_fp)
221static void QT_FASTCALL convertRGBA64PMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
223 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
224 for (
int i = 0; i < count; ++i) {
226 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha()).premultiplied();
230static void QT_FASTCALL convertRGBA64ToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
232 const auto *in =
reinterpret_cast<
const QRgba64 *>(src);
233 for (
int i = 0; i < count; ++i) {
235 buffer[i] = QRgbaFloat32::fromRgba64(c.red(), c.green(), c.blue(), c.alpha());
239static void QT_FASTCALL convertRGBA16FPMToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
241 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
242 for (
int i = 0; i < count; ++i)
243 buffer[i] = buffer[i].premultiplied();
246static void QT_FASTCALL convertRGBA16FToRGBA32F(QRgbaFloat32 *buffer,
const quint64 *src,
int count)
248 qFloatFromFloat16((
float *)buffer, (
const qfloat16 *)src, count * 4);
251static Convert64ToFPFunc convert64ToRGBA32F[] = {
277 convertRGBA64ToRGBA32F,
278 convertRGBA64PMToRGBA32F,
279 convertRGBA64ToRGBA32F,
282 convertRGBA16FToRGBA32F,
283 convertRGBA16FPMToRGBA32F,
284 convertRGBA16FToRGBA32F,
291static_assert(std::size(convert64ToRGBA32F) == QImage::NImageFormats);
293static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer,
int count)
295 for (
int i = 0; i < count; ++i)
296 buffer[i] = buffer[i].premultiplied();
299static void convertRGBA32FToRGBA32F(QRgbaFloat32 *,
int)
306
307
308
310static uint * QT_FASTCALL destFetchMono(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
313 uint *start = buffer;
314 const uint *end = buffer + length;
315 while (buffer < end) {
316 *buffer = data[x>>3] & (0x80 >> (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
323static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
326 uint *start = buffer;
327 const uint *end = buffer + length;
328 while (buffer < end) {
329 *buffer = data[x>>3] & (0x1 << (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
336static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
338 return (uint *)rasterBuffer->scanLine(y) + x;
341static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
343 const ushort *
Q_DECL_RESTRICT data = (
const ushort *)rasterBuffer->scanLine(y) + x;
344 for (
int i = 0; i < length; ++i)
345 buffer[i] = qConvertRgb16To32(data[i]);
349static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
351 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
352 return const_cast<uint *>(layout->fetchToARGB32PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
355static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *,
int,
int,
int)
401static_assert(std::size(destFetchProc) == QImage::NImageFormats);
403#if QT_CONFIG(raster_64bit)
404static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
406 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
407 return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
410static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
412 return (QRgba64 *)rasterBuffer->scanLine(y) + x;
415static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *,
int,
int,
int)
420static DestFetchProc64 destFetchProc64[] =
461static_assert(std::size(destFetchProc64) == QImage::NImageFormats);
464#if QT_CONFIG(raster_fp)
465static QRgbaFloat32 *QT_FASTCALL destFetchFP(QRgbaFloat32 *buffer, QRasterBuffer *rasterBuffer,
int x,
int y,
int length)
467 return const_cast<QRgbaFloat32 *>(qFetchToRGBA32F[rasterBuffer->format](buffer, rasterBuffer->scanLine(y), x, length,
nullptr,
nullptr));
470static QRgbaFloat32 *QT_FASTCALL destFetchRGBFP(QRgbaFloat32 *, QRasterBuffer *rasterBuffer,
int x,
int y,
int)
472 return reinterpret_cast<QRgbaFloat32 *>(rasterBuffer->scanLine(y)) + x;
475static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRasterBuffer *,
int,
int,
int)
479static DestFetchProcFP destFetchProcFP[] =
520static_assert(std::size(destFetchProcFP) == QImage::NImageFormats);
524
525
526
529 const QRgb color_0 = rbuf->destColor0;
530 const QRgb color_1 = rbuf->destColor1;
533 int g = qGreen(color);
534 int b = qBlue(color);
538 rx = r - qRed(color_0);
539 gx = g - qGreen(color_0);
540 bx = b - qBlue(color_0);
541 dist_0 = rx*rx + gx*gx + bx*bx;
543 rx = r - qRed(color_1);
544 gx = g - qGreen(color_1);
545 bx = b - qBlue(color_1);
546 dist_1 = rx*rx + gx*gx + bx*bx;
554
555
557static void QT_FASTCALL destStoreMono(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
560 if (rasterBuffer->monoDestinationWithClut) {
561 for (
int i = 0; i < length; ++i) {
562 if (buffer[i] == rasterBuffer->destColor0) {
563 data[x >> 3] &= ~(0x80 >> (x & 7));
564 }
else if (buffer[i] == rasterBuffer->destColor1) {
565 data[x >> 3] |= 0x80 >> (x & 7);
566 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
567 data[x >> 3] &= ~(0x80 >> (x & 7));
569 data[x >> 3] |= 0x80 >> (x & 7);
574 for (
int i = 0; i < length; ++i) {
575 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
576 data[x >> 3] |= 0x80 >> (x & 7);
578 data[x >> 3] &= ~(0x80 >> (x & 7));
584static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
587 if (rasterBuffer->monoDestinationWithClut) {
588 for (
int i = 0; i < length; ++i) {
589 if (buffer[i] == rasterBuffer->destColor0) {
590 data[x >> 3] &= ~(1 << (x & 7));
591 }
else if (buffer[i] == rasterBuffer->destColor1) {
592 data[x >> 3] |= 1 << (x & 7);
593 }
else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) {
594 data[x >> 3] &= ~(1 << (x & 7));
596 data[x >> 3] |= 1 << (x & 7);
601 for (
int i = 0; i < length; ++i) {
602 if (qGray(buffer[i]) <
int(qt_bayer_matrix[y & 15][x & 15]))
603 data[x >> 3] |= 1 << (x & 7);
605 data[x >> 3] &= ~(1 << (x & 7));
611static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
613 quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x;
614 for (
int i = 0; i < length; ++i)
615 data[i] = qConvertRgb32To16(buffer[i]);
618static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
620 const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
621 ConvertAndStorePixelsFunc store = layout->storeFromARGB32PM;
622 if (!layout->premultiplied && !layout->hasAlphaChannel)
623 store = layout->storeFromRGB32;
624 uchar *dest = rasterBuffer->scanLine(y);
625 store(dest, buffer, x, length,
nullptr,
nullptr);
628static void QT_FASTCALL destStoreGray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
630 uchar *data = rasterBuffer->scanLine(y) + x;
633 for (
int k = 0; k < length; ++k) {
634 if (!qIsGray(buffer[k])) {
638 data[k] = qRed(buffer[k]);
641 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
642 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
643 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
645 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
649static void QT_FASTCALL destStoreGray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const uint *buffer,
int length)
651 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
654 for (
int k = 0; k < length; ++k) {
655 if (!qIsGray(buffer[k])) {
659 data[k] = qRed(buffer[k]) * 257;
662 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
663 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
664 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
666 Q_DECL_UNINITIALIZED QRgba64 tmp_line[BufferSize];
667 for (
int k = 0; k < length; ++k)
668 tmp_line[k] = QRgba64::fromArgb32(buffer[k]);
669 tfd->apply(data, tmp_line, length, QColorTransformPrivate::InputPremultiplied);
714static_assert(std::size(destStoreProc) == QImage::NImageFormats);
716#if QT_CONFIG(raster_64bit)
717static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
719 auto store = qStoreFromRGBA64PM[rasterBuffer->format];
720 uchar *dest = rasterBuffer->scanLine(y);
721 store(dest, buffer, x, length,
nullptr,
nullptr);
724static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
726 QRgba64 *dest =
reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
727 for (
int i = 0; i < length; ++i) {
728 dest[i] = buffer[i].unpremultiplied();
732static void QT_FASTCALL destStore64Gray8(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
734 uchar *data = rasterBuffer->scanLine(y) + x;
737 for (
int k = 0; k < length; ++k) {
738 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
742 data[k] = buffer[k].red8();
745 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
746 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
747 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
749 Q_DECL_UNINITIALIZED quint16 gray_line[BufferSize];
750 tfd->apply(gray_line, buffer, length, QColorTransformPrivate::InputPremultiplied);
751 for (
int k = 0; k < length; ++k)
752 data[k] = qt_div_257(gray_line[k]);
756static void QT_FASTCALL destStore64Gray16(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length)
758 quint16 *data =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
761 for (
int k = 0; k < length; ++k) {
762 if (buffer[k].red() != buffer[k].green() || buffer[k].red() != buffer[k].blue()) {
766 data[k] = buffer[k].red();
769 QColorSpace fromCS = rasterBuffer->colorSpace.isValid() ? rasterBuffer->colorSpace : QColorSpace::SRgb;
770 QColorTransform tf = QColorSpacePrivate::get(fromCS)->transformationToXYZ();
771 QColorTransformPrivate *tfd = QColorTransformPrivate::get(tf);
772 tfd->apply(data, buffer, length, QColorTransformPrivate::InputPremultiplied);
776static DestStoreProc64 destStoreProc64[] =
817static_assert(std::size(destStoreProc64) == QImage::NImageFormats);
820#if QT_CONFIG(raster_fp)
821static void QT_FASTCALL destStoreFP(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgbaFloat32 *buffer,
int length)
823 auto store = qStoreFromRGBA32F[rasterBuffer->format];
824 uchar *dest = rasterBuffer->scanLine(y);
825 store(dest, buffer, x, length,
nullptr,
nullptr);
830
831
832
833
834
835
836
837
838
839
840
841
842
854static const uint *QT_FASTCALL fetchUntransformed(uint *buffer,
const Operator *,
855 const QSpanData *data,
int y,
int x,
int length)
857 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
858 return layout->fetchToARGB32PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
861static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *,
const Operator *,
862 const QSpanData *data,
int y,
int x,
int)
864 const uchar *scanLine = data->texture.scanLine(y);
865 return reinterpret_cast<
const uint *>(scanLine) + x;
868static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer,
const Operator *,
869 const QSpanData *data,
int y,
int x,
872 const quint16 *scanLine = (
const quint16 *)data->texture.scanLine(y) + x;
873 for (
int i = 0; i < length; ++i)
874 buffer[i] = qConvertRgb16To32(scanLine[i]);
878#if QT_CONFIG(raster_64bit)
879static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer,
const Operator *,
880 const QSpanData *data,
int y,
int x,
int length)
882 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
883 return layout->fetchToRGBA64PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
886static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *,
const Operator *,
887 const QSpanData *data,
int y,
int x,
int)
889 const uchar *scanLine = data->texture.scanLine(y);
890 return reinterpret_cast<
const QRgba64 *>(scanLine) + x;
894#if QT_CONFIG(raster_fp)
895static const QRgbaFloat32 *QT_FASTCALL fetchUntransformedFP(QRgbaFloat32 *buffer,
const Operator *,
896 const QSpanData *data,
int y,
int x,
int length)
898 const auto fetch = qFetchToRGBA32F[data->texture.format];
899 return fetch(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable,
nullptr);
908 if (v < 0 || v >= max) {
913 v = qBound(l1, v, l2);
919 if (Q_UNLIKELY(!data->fast_matrix))
922 qreal fx = (data->m21 * cy + data->m11 * cx + data->dx) *
fixed_scale;
923 qreal fy = (data->m22 * cy + data->m12 * cx + data->dy) *
fixed_scale;
924 qreal minc =
std::min(fx, fy);
925 qreal maxc =
std::max(fx, fy);
928 minc =
std::min(minc,
std::min(fx, fy));
929 maxc =
std::max(maxc,
std::max(fx, fy));
931 return minc >=
std::numeric_limits<
int>::min() && maxc <=
std::numeric_limits<
int>::max();
935static void QT_FASTCALL fetchTransformed_fetcher(T *buffer,
const QSpanData *data,
936 int y,
int x,
int length)
938 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
939 const QTextureData &image = data->texture;
941 const qreal cx = x + qreal(0.5);
942 const qreal cy = y + qreal(0.5);
944 constexpr bool useFetch = (bpp < QPixelLayout::BPP32) &&
sizeof(T) ==
sizeof(uint);
945 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
947 Q_ASSERT(layout->bpp == bpp || (layout->bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
949 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout->bpp] : Fetch1PixelFunc(fetch1Pixel<bpp>);
951 if (canUseFastMatrixPath(cx, cy, length, data)) {
953 int fdx = (
int)(data->m11 * fixed_scale);
954 int fdy = (
int)(data->m12 * fixed_scale);
956 int fx =
int((data->m21 * cy
957 + data->m11 * cx + data->dx) * fixed_scale);
958 int fy =
int((data->m22 * cy
959 + data->m12 * cx + data->dy) * fixed_scale);
963 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
964 const uchar *src = image.scanLine(py);
967 if (blendType == BlendTransformed) {
968 int fastLen = length;
970 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
972 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
974 for (; i < fastLen; ++i) {
977 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
980 if constexpr (useFetch)
981 buffer[i] = fetch1(src, x1);
983 buffer[i] =
reinterpret_cast<
const T*>(src)[x1];
987 for (; i < fastLen; ++i) {
989 if constexpr (useFetch)
990 buffer[i] = fetch1(src, px);
992 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
997 for (; i < length; ++i) {
999 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1000 if constexpr (useFetch)
1001 buffer[i] = fetch1(src, px);
1003 buffer[i] =
reinterpret_cast<
const T*>(src)[px];
1008 if (blendType == BlendTransformed) {
1009 int fastLen = length;
1011 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
1013 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
1015 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
1017 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
1019 for (; i < fastLen; ++i) {
1020 int x1 = (fx >> 16);
1021 int y1 = (fy >> 16);
1024 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
1025 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1);
1026 if (x1 == x2 && y1 == y2)
1028 if constexpr (useFetch)
1029 buffer[i] = fetch1(image.scanLine(y1), x1);
1031 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(y1))[x1];
1036 for (; i < fastLen; ++i) {
1037 int px = (fx >> 16);
1038 int py = (fy >> 16);
1039 if constexpr (useFetch)
1040 buffer[i] = fetch1(image.scanLine(py), px);
1042 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1048 for (; i < length; ++i) {
1049 int px = (fx >> 16);
1050 int py = (fy >> 16);
1051 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1052 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1053 if constexpr (useFetch)
1054 buffer[i] = fetch1(image.scanLine(py), px);
1056 buffer[i] =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1062 const qreal fdx = data->m11;
1063 const qreal fdy = data->m12;
1064 const qreal fdw = data->m13;
1066 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
1067 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
1068 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
1070 T *
const end = buffer + length;
1073 const qreal iw = fw == 0 ? 1 : 1 / fw;
1074 const qreal tx = fx * iw;
1075 const qreal ty = fy * iw;
1076 int px = qFloor(tx);
1077 int py = qFloor(ty);
1079 fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
1080 fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
1081 if constexpr (useFetch)
1082 *b = fetch1(image.scanLine(py), px);
1084 *b =
reinterpret_cast<
const T*>(image.scanLine(py))[px];
1099static const uint *
QT_FASTCALL fetchTransformed(uint *buffer,
const Operator *,
const QSpanData *data,
1100 int y,
int x,
int length)
1102 static_assert(blendType == BlendTransformed || blendType == BlendTransformedTiled);
1103 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1104 fetchTransformed_fetcher<blendType, bpp, uint>(buffer, data, y, x, length);
1105 layout->convertToARGB32PM(buffer, length, data->texture.colorTable);
1109#if QT_CONFIG(raster_64bit)
1110template<TextureBlendType blendType>
1111static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
1112 int y,
int x,
int length)
1114 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1115 if (layout->bpp < QPixelLayout::BPP64) {
1116 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1117 Q_ASSERT(length <= BufferSize);
1118 if (layout->bpp == QPixelLayout::BPP32)
1119 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1121 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1122 return layout->convertToRGBA64PM(buffer, buffer32, length, data->texture.colorTable,
nullptr);
1125 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(
reinterpret_cast<quint64*>(buffer), data, y, x, length);
1126 if (
auto convert = convert64ToRGBA64PM[data->texture.format])
1127 convert(buffer, length);
1132#if QT_CONFIG(raster_fp)
1133template<TextureBlendType blendType>
1134static const QRgbaFloat32 *QT_FASTCALL fetchTransformedFP(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
1135 int y,
int x,
int length)
1137 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
1138 if (layout->bpp < QPixelLayout::BPP64) {
1139 Q_DECL_UNINITIALIZED uint buffer32[BufferSize];
1140 Q_ASSERT(length <= BufferSize);
1141 if (layout->bpp == QPixelLayout::BPP32)
1142 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
1144 fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
1145 qConvertToRGBA32F[data->texture.format](buffer, buffer32, length, data->texture.colorTable,
nullptr);
1146 }
else if (layout->bpp < QPixelLayout::BPP32FPx4) {
1147 Q_DECL_UNINITIALIZED quint64 buffer64[BufferSize];
1148 fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, quint64>(buffer64, data, y, x, length);
1149 convert64ToRGBA32F[data->texture.format](buffer, buffer64, length);
1151 fetchTransformed_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>(buffer, data, y, x, length);
1152 if (data->texture.format == QImage::Format_RGBA32FPx4)
1153 convertRGBA32FToRGBA32FPM(buffer, length);
1161
1162
1163
1166 uint distxy = distx * disty;
1169 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
1170 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
1171 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
1172 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy));
1173 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy));
1174 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy));
1175 uint brrb = ((br & 0x00ff00ff) * (distxy));
1176 uint brag = (((br & 0xff00ff00) >> 8) * (distxy));
1177 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
1180#if defined(__SSE2__
)
1181#define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \
1182{
1183 const __m128i dxdy = _mm_mullo_epi16 (distx, disty);
1184 const __m128i distx_ = _mm_slli_epi16(distx, 4
);
1185 const __m128i disty_ = _mm_slli_epi16(disty, 4
);
1186 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_)));
1187 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy);
1188 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy);
1190 __m128i tlAG = _mm_srli_epi16(tl, 8
);
1191 __m128i tlRB = _mm_and_si128(tl, colorMask);
1192 __m128i trAG = _mm_srli_epi16(tr, 8
);
1193 __m128i trRB = _mm_and_si128(tr, colorMask);
1194 __m128i blAG = _mm_srli_epi16(bl, 8
);
1195 __m128i blRB = _mm_and_si128(bl, colorMask);
1196 __m128i brAG = _mm_srli_epi16(br, 8
);
1197 __m128i brRB = _mm_and_si128(br, colorMask);
1199 tlAG = _mm_mullo_epi16(tlAG, idxidy);
1200 tlRB = _mm_mullo_epi16(tlRB, idxidy);
1201 trAG = _mm_mullo_epi16(trAG, dxidy);
1202 trRB = _mm_mullo_epi16(trRB, dxidy);
1203 blAG = _mm_mullo_epi16(blAG, idxdy);
1204 blRB = _mm_mullo_epi16(blRB, idxdy);
1205 brAG = _mm_mullo_epi16(brAG, dxdy);
1206 brRB = _mm_mullo_epi16(brRB, dxdy);
1209 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG));
1210 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB));
1211 rAG = _mm_andnot_si128(colorMask, rAG);
1212 rRB = _mm_srli_epi16(rRB, 8
);
1213 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \
1214}
1217#if defined(__ARM_NEON__)
1218#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \
1219{
1220 const int16x8_t dxdy = vmulq_s16(distx, disty);
1221 const int16x8_t distx_ = vshlq_n_s16(distx, 4
);
1222 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_)));
1223 const int16x8_t dxidy = vsubq_s16(distx_, dxdy);
1224 const int16x8_t idxdy = vsubq_s16(disty_, dxdy);
1226 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8
));
1227 int16x8_t tlRB = vandq_s16(tl, colorMask);
1228 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8
));
1229 int16x8_t trRB = vandq_s16(tr, colorMask);
1230 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8
));
1231 int16x8_t blRB = vandq_s16(bl, colorMask);
1232 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8
));
1233 int16x8_t brRB = vandq_s16(br, colorMask);
1235 int16x8_t rAG = vmulq_s16(tlAG, idxidy);
1236 int16x8_t rRB = vmulq_s16(tlRB, idxidy);
1237 rAG = vmlaq_s16(rAG, trAG, dxidy);
1238 rRB = vmlaq_s16(rRB, trRB, dxidy);
1239 rAG = vmlaq_s16(rAG, blAG, idxdy);
1240 rRB = vmlaq_s16(rRB, blRB, idxdy);
1241 rAG = vmlaq_s16(rAG, brAG, dxdy);
1242 rRB = vmlaq_s16(rRB, brRB, dxdy);
1244 rAG = vandq_s16(invColorMask, rAG);
1245 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8
));
1246 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \
1247}
1250#if defined(__loongarch_sx)
1251static inline void interpolate_4_pixels_16_lsx(__m128i tl, __m128i tr, __m128i bl, __m128i br,
1252 __m128i distx, __m128i disty, uint *b)
1254 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1255 const __m128i v_256 = __lsx_vreplgr2vr_h(256);
1256 const __m128i dxdy = __lsx_vmul_h(distx, disty);
1257 const __m128i distx_ = __lsx_vslli_h(distx, 4);
1258 const __m128i disty_ = __lsx_vslli_h(disty, 4);
1259 const __m128i idxidy = __lsx_vadd_h(dxdy, __lsx_vsub_h(v_256, __lsx_vadd_h(distx_, disty_)));
1260 const __m128i dxidy = __lsx_vsub_h(distx_, dxdy);
1261 const __m128i idxdy = __lsx_vsub_h(disty_,dxdy);
1263 __m128i tlAG = __lsx_vsrli_h(tl, 8);
1264 __m128i tlRB = __lsx_vand_v(tl, colorMask);
1265 __m128i trAG = __lsx_vsrli_h(tr, 8);
1266 __m128i trRB = __lsx_vand_v(tr, colorMask);
1267 __m128i blAG = __lsx_vsrli_h(bl, 8);
1268 __m128i blRB = __lsx_vand_v(bl, colorMask);
1269 __m128i brAG = __lsx_vsrli_h(br, 8);
1270 __m128i brRB = __lsx_vand_v(br, colorMask);
1272 tlAG = __lsx_vmul_h(tlAG, idxidy);
1273 tlRB = __lsx_vmul_h(tlRB, idxidy);
1274 trAG = __lsx_vmul_h(trAG, dxidy);
1275 trRB = __lsx_vmul_h(trRB, dxidy);
1276 blAG = __lsx_vmul_h(blAG, idxdy);
1277 blRB = __lsx_vmul_h(blRB, idxdy);
1278 brAG = __lsx_vmul_h(brAG, dxdy);
1279 brRB = __lsx_vmul_h(brRB, dxdy);
1281 __m128i rAG =__lsx_vadd_h(__lsx_vadd_h(tlAG, trAG), __lsx_vadd_h(blAG, brAG));
1282 __m128i rRB =__lsx_vadd_h(__lsx_vadd_h(tlRB, trRB), __lsx_vadd_h(blRB, brRB));
1283 rAG = __lsx_vandn_v(colorMask, rAG);
1284 rRB = __lsx_vsrli_h(rRB, 8);
1285 __lsx_vst(__lsx_vor_v(rAG, rRB), b, 0);
1301 Q_ASSERT(v1 >= 0 && v1 < max);
1302 Q_ASSERT(v2 >= 0 && v2 < max);
1314 Q_ASSERT(v1 >= l1 && v1 <= l2);
1315 Q_ASSERT(v2 >= l1 && v2 <= l2);
1329static void QT_FASTCALL intermediate_adder(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx)
1331#if defined(QT_COMPILER_SUPPORTS_AVX2)
1332 extern void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end,
const IntermediateBuffer &intermediate,
int offset,
int &fx,
int fdx);
1333 if (qCpuHasFeature(ArchHaswell))
1334 return intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
1338 fx -= offset * fixed_scale;
1341 const int x = (fx >> 16);
1343 const uint distx = (fx & 0x0000ffff) >> 8;
1344 const uint idistx = 256 - distx;
1345 const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
1346 const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
1347 *b = (rb >> 8) | ag;
1351 fx += offset * fixed_scale;
1357static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
1358 int &fx,
int &fy,
int fdx,
int )
1360 int y1 = (fy >> 16);
1362 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1363 const uint *s1 = (
const uint *)image.scanLine(y1);
1364 const uint *s2 = (
const uint *)image.scanLine(y2);
1366 const int disty = (fy & 0x0000ffff) >> 8;
1367 const int idisty = 256 - disty;
1368 const int length = end - b;
1371 const int adjust = (fdx < 0) ? fdx * length : 0;
1372 const int offset = (fx + adjust) >> 16;
1375 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
1377 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
1380 Q_ASSERT(count <= BufferSize + 2);
1383 if (blendType == BlendTransformedBilinearTiled) {
1385 if (x < 0) x += image.width;
1387 lim = qMin(count, image.x2 - x);
1389 Q_ASSERT(x < image.x2);
1390 uint t = s1[image.x1];
1391 uint b = s2[image.x1];
1392 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1393 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1395 intermediate.buffer_rb[f] = rb;
1396 intermediate.buffer_ag[f] = ag;
1399 }
while (x < image.x1 && f < lim);
1403 if (blendType != BlendTransformedBilinearTiled) {
1404#if defined(__SSE2__
)
1405 const __m128i disty_ = _mm_set1_epi16(disty);
1406 const __m128i idisty_ = _mm_set1_epi16(idisty);
1407 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1410 for (; f < lim; x += 4, f += 4) {
1412 __m128i top = _mm_loadu_si128((
const __m128i*)((
const uint *)(s1)+x));
1413 __m128i topAG = _mm_srli_epi16(top, 8);
1414 __m128i topRB = _mm_and_si128(top, colorMask);
1416 topAG = _mm_mullo_epi16 (topAG, idisty_);
1417 topRB = _mm_mullo_epi16 (topRB, idisty_);
1420 __m128i bottom = _mm_loadu_si128((
const __m128i*)((
const uint *)(s2)+x));
1421 __m128i bottomAG = _mm_srli_epi16(bottom, 8);
1422 __m128i bottomRB = _mm_and_si128(bottom, colorMask);
1423 bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
1424 bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
1427 __m128i rAG =_mm_add_epi16(topAG, bottomAG);
1428 rAG = _mm_srli_epi16(rAG, 8);
1429 _mm_storeu_si128((__m128i*)(&intermediate.buffer_ag[f]), rAG);
1430 __m128i rRB =_mm_add_epi16(topRB, bottomRB);
1431 rRB = _mm_srli_epi16(rRB, 8);
1432 _mm_storeu_si128((__m128i*)(&intermediate.buffer_rb[f]), rRB);
1434#elif defined(__ARM_NEON__)
1435 const int16x8_t disty_ = vdupq_n_s16(disty);
1436 const int16x8_t idisty_ = vdupq_n_s16(idisty);
1437 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1440 for (; f < lim; x += 4, f += 4) {
1442 int16x8_t top = vld1q_s16((int16_t*)((
const uint *)(s1)+x));
1443 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8));
1444 int16x8_t topRB = vandq_s16(top, colorMask);
1446 topAG = vmulq_s16(topAG, idisty_);
1447 topRB = vmulq_s16(topRB, idisty_);
1450 int16x8_t bottom = vld1q_s16((int16_t*)((
const uint *)(s2)+x));
1451 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8));
1452 int16x8_t bottomRB = vandq_s16(bottom, colorMask);
1453 bottomAG = vmulq_s16(bottomAG, disty_);
1454 bottomRB = vmulq_s16(bottomRB, disty_);
1457 int16x8_t rAG = vaddq_s16(topAG, bottomAG);
1458 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
1459 vst1q_s16((int16_t*)(&intermediate.buffer_ag[f]), rAG);
1460 int16x8_t rRB = vaddq_s16(topRB, bottomRB);
1461 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
1462 vst1q_s16((int16_t*)(&intermediate.buffer_rb[f]), rRB);
1464#elif defined(__loongarch_sx)
1465 const __m128i disty_ = __lsx_vreplgr2vr_h(disty);
1466 const __m128i idisty_ = __lsx_vreplgr2vr_h(idisty);
1467 const __m128i colorMask = __lsx_vreplgr2vr_w(0x00ff00ff);
1470 for (; f < lim; x += 4, f += 4) {
1472 __m128i top = __lsx_vld((
const __m128i*)((
const uint *)(s1)+x), 0);
1473 __m128i topAG = __lsx_vsrli_h(top, 8);
1474 __m128i topRB = __lsx_vand_v(top, colorMask);
1476 topAG = __lsx_vmul_h(topAG, idisty_);
1477 topRB = __lsx_vmul_h(topRB, idisty_);
1480 __m128i bottom = __lsx_vld((
const __m128i*)((
const uint *)(s2)+x), 0);
1481 __m128i bottomAG = __lsx_vsrli_h(bottom, 8);
1482 __m128i bottomRB = __lsx_vand_v(bottom, colorMask);
1483 bottomAG = __lsx_vmul_h(bottomAG, disty_);
1484 bottomRB = __lsx_vmul_h(bottomRB, disty_);
1487 __m128i rAG = __lsx_vadd_h(topAG, bottomAG);
1488 rAG = __lsx_vsrli_h(rAG, 8);
1489 __lsx_vst(rAG, (__m128i*)(&intermediate.buffer_ag[f]), 0);
1490 __m128i rRB = __lsx_vadd_h(topRB, bottomRB);
1491 rRB = __lsx_vsrli_h(rRB, 8);
1492 __lsx_vst(rRB, (__m128i*)(&intermediate.buffer_rb[f]), 0);
1496 for (; f < count; f++) {
1497 if (blendType == BlendTransformedBilinearTiled) {
1498 if (x >= image.width) x -= image.width;
1500 x = qMin(x, image.x2 - 1);
1506 intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
1507 intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
1512 intermediate_adder(b, end, intermediate, offset, fx, fdx);
1516static void QT_FASTCALL fetchTransformedBilinearARGB32PM_upscale_helper(uint *b, uint *end,
const QTextureData &image,
1517 int &fx,
int &fy,
int fdx,
int )
1519 int y1 = (fy >> 16);
1521 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1522 const uint *s1 = (
const uint *)image.scanLine(y1);
1523 const uint *s2 = (
const uint *)image.scanLine(y2);
1524 const int disty = (fy & 0x0000ffff) >> 8;
1526 if (blendType != BlendTransformedBilinearTiled) {
1527 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1528 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1530 int x1 = (fx >> 16);
1532 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1537 *b = INTERPOLATE_PIXEL_256(top, 256 - disty, bot, disty);
1541 uint *boundedEnd = end;
1543 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1545 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1548 while (b < boundedEnd) {
1550 int distx = (fx & 0x0000ffff) >> 8;
1551 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
1558 int x1 = (fx >> 16);
1560 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1 , x1, x2);
1565 int distx = (fx & 0x0000ffff) >> 8;
1566 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1574static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *b, uint *end,
const QTextureData &image,
1575 int &fx,
int &fy,
int fdx,
int )
1577 int y1 = (fy >> 16);
1579 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1580 const uint *s1 = (
const uint *)image.scanLine(y1);
1581 const uint *s2 = (
const uint *)image.scanLine(y2);
1582 const int disty8 = (fy & 0x0000ffff) >> 8;
1583 const int disty4 = (disty8 + 0x08) >> 4;
1585 if (blendType != BlendTransformedBilinearTiled) {
1586 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1587 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1589 int x1 = (fx >> 16);
1591 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1596 *b = INTERPOLATE_PIXEL_256(top, 256 - disty8, bot, disty8);
1600 uint *boundedEnd = end;
1602 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1604 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1606#if defined(__SSE2__
)
1607 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1608 const __m128i v_256 = _mm_set1_epi16(256);
1609 const __m128i v_disty = _mm_set1_epi16(disty4);
1610 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1611 const __m128i v_fx_r = _mm_set1_epi32(0x8);
1612 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1614 while (b < boundedEnd - 3) {
1615 __m128i offset = _mm_srli_epi32(v_fx, 16);
1616 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1617 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1618 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1619 const int offset3 = _mm_cvtsi128_si32(offset);
1620 const __m128i tl = _mm_setr_epi32(s1[offset0], s1[offset1], s1[offset2], s1[offset3]);
1621 const __m128i tr = _mm_setr_epi32(s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]);
1622 const __m128i bl = _mm_setr_epi32(s2[offset0], s2[offset1], s2[offset2], s2[offset3]);
1623 const __m128i br = _mm_setr_epi32(s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]);
1625 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1626 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fx_r), 4);
1627 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1628 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1630 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1632 v_fx = _mm_add_epi32(v_fx, v_fdx);
1634 fx = _mm_cvtsi128_si32(v_fx);
1635#elif defined(__ARM_NEON__)
1636 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1637 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1638 const int16x8_t v_256 = vdupq_n_s16(256);
1639 const int16x8_t v_disty = vdupq_n_s16(disty4);
1640 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
1641 int32x4_t v_fdx = vdupq_n_s32(fdx*4);
1643 int32x4_t v_fx = vmovq_n_s32(fx);
1644 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1645 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1646 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1648 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1649 const int32x4_t v_fx_r = vdupq_n_s32(0x0800);
1652 uint32x4x2_t v_top = {};
1653 uint32x4x2_t v_bot = {};
1654 while (b < boundedEnd - 3) {
1655 int x1 = (fx >> 16);
1657 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1658 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1661 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1662 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1665 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1666 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1669 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1670 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1672 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_fx_r), 12);
1673 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1675 interpolate_4_pixels_16_neon(
1676 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1677 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1678 vreinterpretq_s16_s32(v_distx), v_disty, v_disty_,
1679 colorMask, invColorMask, v_256, b);
1681 v_fx = vaddq_s32(v_fx, v_fdx);
1683#elif defined (__loongarch_sx)
1684 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1685 const __m128i v_disty = __lsx_vreplgr2vr_h(disty4);
1686 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1687 const __m128i v_fx_r = __lsx_vreplgr2vr_w(0x8);
1688 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1690 while (b < boundedEnd - 3) {
1691 __m128i offset = __lsx_vsrli_w(v_fx, 16);
1692 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1693 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1694 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1695 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1696 const __m128i tl = (__m128i)(v4u32){s1[offset0], s1[offset1], s1[offset2], s1[offset3]};
1697 const __m128i tr = (__m128i)(v4u32){s1[offset0 + 1], s1[offset1 + 1], s1[offset2 + 1], s1[offset3 + 1]};
1698 const __m128i bl = (__m128i)(v4u32){s2[offset0], s2[offset1], s2[offset2], s2[offset3]};
1699 const __m128i br = (__m128i)(v4u32){s2[offset0 + 1], s2[offset1 + 1], s2[offset2 + 1], s2[offset3 + 1]};
1701 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1702 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fx_r), 4);
1703 v_distx = __lsx_vshuf_h(shuffleMask, v_distx, v_distx);
1705 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1707 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1709 fx = __lsx_vpickve2gr_w(v_fx, 0);
1711 while (b < boundedEnd) {
1713 if (hasFastInterpolate4()) {
1714 int distx8 = (fx & 0x0000ffff) >> 8;
1715 *b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
1717 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1718 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx4, disty4);
1726 int x1 = (fx >> 16);
1728 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1733 if (hasFastInterpolate4()) {
1734 int distx8 = (fx & 0x0000ffff) >> 8;
1735 *b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
1737 int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
1738 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
1746static void QT_FASTCALL fetchTransformedBilinearARGB32PM_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1747 int &fx,
int &fy,
int fdx,
int fdy)
1751 int x1 = (fx >> 16);
1753 int y1 = (fy >> 16);
1756 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1757 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1759 const uint *s1 = (
const uint *)image.scanLine(y1);
1760 const uint *s2 = (
const uint *)image.scanLine(y2);
1767 int distx = (fx & 0x0000ffff) >> 8;
1768 int disty = (fy & 0x0000ffff) >> 8;
1770 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1779static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint *b, uint *end,
const QTextureData &image,
1780 int &fx,
int &fy,
int fdx,
int fdy)
1783 if (blendType != BlendTransformedBilinearTiled) {
1784 const qint64 min_fx = qint64(image.x1) * fixed_scale;
1785 const qint64 max_fx = qint64(image.x2 - 1) * fixed_scale;
1786 const qint64 min_fy = qint64(image.y1) * fixed_scale;
1787 const qint64 max_fy = qint64(image.y2 - 1) * fixed_scale;
1790 int x1 = (fx >> 16);
1792 int y1 = (fy >> 16);
1794 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
1795 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
1796 if (x1 != x2 && y1 != y2)
1798 const uint *s1 = (
const uint *)image.scanLine(y1);
1799 const uint *s2 = (
const uint *)image.scanLine(y2);
1804 if (hasFastInterpolate4()) {
1805 int distx = (fx & 0x0000ffff) >> 8;
1806 int disty = (fy & 0x0000ffff) >> 8;
1807 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
1809 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
1810 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
1811 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
1817 uint *boundedEnd = end;
1819 boundedEnd = qMin(boundedEnd, b + (max_fx - fx) / fdx);
1821 boundedEnd = qMin(boundedEnd, b + (min_fx - fx) / fdx);
1823 boundedEnd = qMin(boundedEnd, b + (max_fy - fy) / fdy);
1825 boundedEnd = qMin(boundedEnd, b + (min_fy - fy) / fdy);
1828#if defined(__SSE2__
)
1829 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
1830 const __m128i v_256 = _mm_set1_epi16(256);
1831 const __m128i v_fdx = _mm_set1_epi32(fdx*4);
1832 const __m128i v_fdy = _mm_set1_epi32(fdy*4);
1833 const __m128i v_fxy_r = _mm_set1_epi32(0x8);
1834 __m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
1835 __m128i v_fy = _mm_setr_epi32(fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy);
1837 const uchar *textureData = image.imageData;
1838 const qsizetype bytesPerLine = image.bytesPerLine;
1839 const __m128i vbpl = _mm_shufflelo_epi16(_mm_cvtsi32_si128(bytesPerLine/4), _MM_SHUFFLE(0, 0, 0, 0));
1841 while (b < boundedEnd - 3) {
1842 const __m128i vy = _mm_packs_epi32(_mm_srli_epi32(v_fy, 16), _mm_setzero_si128());
1844 __m128i offset = _mm_unpacklo_epi16(_mm_mullo_epi16(vy, vbpl), _mm_mulhi_epi16(vy, vbpl));
1845 offset = _mm_add_epi32(offset, _mm_srli_epi32(v_fx, 16));
1846 const int offset0 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1847 const int offset1 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1848 const int offset2 = _mm_cvtsi128_si32(offset); offset = _mm_srli_si128(offset, 4);
1849 const int offset3 = _mm_cvtsi128_si32(offset);
1850 const uint *topData = (
const uint *)(textureData);
1851 const __m128i tl = _mm_setr_epi32(topData[offset0], topData[offset1], topData[offset2], topData[offset3]);
1852 const __m128i tr = _mm_setr_epi32(topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]);
1853 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1854 const __m128i bl = _mm_setr_epi32(bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]);
1855 const __m128i br = _mm_setr_epi32(bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]);
1857 __m128i v_distx = _mm_srli_epi16(v_fx, 8);
1858 __m128i v_disty = _mm_srli_epi16(v_fy, 8);
1859 v_distx = _mm_srli_epi16(_mm_add_epi32(v_distx, v_fxy_r), 4);
1860 v_disty = _mm_srli_epi16(_mm_add_epi32(v_disty, v_fxy_r), 4);
1861 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1862 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
1863 v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1864 v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
1866 interpolate_4_pixels_16_sse2(tl, tr, bl, br, v_distx, v_disty, colorMask, v_256, b);
1868 v_fx = _mm_add_epi32(v_fx, v_fdx);
1869 v_fy = _mm_add_epi32(v_fy, v_fdy);
1871 fx = _mm_cvtsi128_si32(v_fx);
1872 fy = _mm_cvtsi128_si32(v_fy);
1873#elif defined(__ARM_NEON__)
1874 const int16x8_t colorMask = vdupq_n_s16(0x00ff);
1875 const int16x8_t invColorMask = vmvnq_s16(colorMask);
1876 const int16x8_t v_256 = vdupq_n_s16(256);
1877 int32x4_t v_fdx = vdupq_n_s32(fdx * 4);
1878 int32x4_t v_fdy = vdupq_n_s32(fdy * 4);
1880 const uchar *textureData = image.imageData;
1881 const qsizetype bytesPerLine = image.bytesPerLine;
1883 int32x4_t v_fx = vmovq_n_s32(fx);
1884 int32x4_t v_fy = vmovq_n_s32(fy);
1885 v_fx = vsetq_lane_s32(fx + fdx, v_fx, 1);
1886 v_fy = vsetq_lane_s32(fy + fdy, v_fy, 1);
1887 v_fx = vsetq_lane_s32(fx + fdx * 2, v_fx, 2);
1888 v_fy = vsetq_lane_s32(fy + fdy * 2, v_fy, 2);
1889 v_fx = vsetq_lane_s32(fx + fdx * 3, v_fx, 3);
1890 v_fy = vsetq_lane_s32(fy + fdy * 3, v_fy, 3);
1892 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
1893 const int32x4_t v_round = vdupq_n_s32(0x0800);
1896 uint32x4x2_t v_top = {};
1897 uint32x4x2_t v_bot = {};
1898 while (b < boundedEnd - 3) {
1899 int x1 = (fx >> 16);
1900 int y1 = (fy >> 16);
1901 fx += fdx; fy += fdy;
1902 const uchar *sl = textureData + bytesPerLine * y1;
1903 const uint *s1 =
reinterpret_cast<
const uint *>(sl);
1904 const uint *s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1905 v_top = vld2q_lane_u32(s1 + x1, v_top, 0);
1906 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 0);
1909 fx += fdx; fy += fdy;
1910 sl = textureData + bytesPerLine * y1;
1911 s1 =
reinterpret_cast<
const uint *>(sl);
1912 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1913 v_top = vld2q_lane_u32(s1 + x1, v_top, 1);
1914 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 1);
1917 fx += fdx; fy += fdy;
1918 sl = textureData + bytesPerLine * y1;
1919 s1 =
reinterpret_cast<
const uint *>(sl);
1920 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1921 v_top = vld2q_lane_u32(s1 + x1, v_top, 2);
1922 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 2);
1925 fx += fdx; fy += fdy;
1926 sl = textureData + bytesPerLine * y1;
1927 s1 =
reinterpret_cast<
const uint *>(sl);
1928 s2 =
reinterpret_cast<
const uint *>(sl + bytesPerLine);
1929 v_top = vld2q_lane_u32(s1 + x1, v_top, 3);
1930 v_bot = vld2q_lane_u32(s2 + x1, v_bot, 3);
1932 int32x4_t v_distx = vshrq_n_s32(vaddq_s32(vandq_s32(v_fx, v_ffff_mask), v_round), 12);
1933 int32x4_t v_disty = vshrq_n_s32(vaddq_s32(vandq_s32(v_fy, v_ffff_mask), v_round), 12);
1934 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
1935 v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
1936 int16x8_t v_disty_ = vshlq_n_s16(vreinterpretq_s16_s32(v_disty), 4);
1938 interpolate_4_pixels_16_neon(
1939 vreinterpretq_s16_u32(v_top.val[0]), vreinterpretq_s16_u32(v_top.val[1]),
1940 vreinterpretq_s16_u32(v_bot.val[0]), vreinterpretq_s16_u32(v_bot.val[1]),
1941 vreinterpretq_s16_s32(v_distx), vreinterpretq_s16_s32(v_disty),
1942 v_disty_, colorMask, invColorMask, v_256, b);
1944 v_fx = vaddq_s32(v_fx, v_fdx);
1945 v_fy = vaddq_s32(v_fy, v_fdy);
1947#elif defined(__loongarch_sx)
1948 const __m128i v_fdx = __lsx_vreplgr2vr_w(fdx*4);
1949 const __m128i v_fdy = __lsx_vreplgr2vr_w(fdy*4);
1950 const __m128i v_fxy_r = __lsx_vreplgr2vr_w(0x8);
1951 __m128i v_fx = (__m128i)(v4i32){fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx};
1952 __m128i v_fy = (__m128i)(v4i32){fy, fy + fdy, fy + fdy + fdy, fy + fdy + fdy + fdy};
1954 const uchar *textureData = image.imageData;
1955 const qsizetype bytesPerLine = image.bytesPerLine;
1956 const __m128i zero = __lsx_vldi(0);
1957 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
1958 const __m128i shuffleMask1 = (__m128i)(v8i16){0, 0, 2, 2, 4, 4, 6, 6};
1959 const __m128i vbpl = __lsx_vshuf_h(shuffleMask, zero, __lsx_vinsgr2vr_w(zero, bytesPerLine/4, 0));
1961 while (b < boundedEnd - 3) {
1962 const __m128i vy = __lsx_vpickev_h(zero, __lsx_vsat_w(__lsx_vsrli_w(v_fy, 16), 15));
1964 __m128i offset = __lsx_vilvl_h(__lsx_vmuh_h(vy, vbpl), __lsx_vmul_h(vy, vbpl));
1965 offset = __lsx_vadd_w(offset, __lsx_vsrli_w(v_fx, 16));
1966 const int offset0 = __lsx_vpickve2gr_w(offset, 0);
1967 const int offset1 = __lsx_vpickve2gr_w(offset, 1);
1968 const int offset2 = __lsx_vpickve2gr_w(offset, 2);
1969 const int offset3 = __lsx_vpickve2gr_w(offset, 3);
1970 const uint *topData = (
const uint *)(textureData);
1971 const __m128i tl = (__m128i)(v4u32){topData[offset0], topData[offset1], topData[offset2], topData[offset3]};
1972 const __m128i tr = (__m128i)(v4u32){topData[offset0 + 1], topData[offset1 + 1], topData[offset2 + 1], topData[offset3 + 1]};
1973 const uint *bottomData = (
const uint *)(textureData + bytesPerLine);
1974 const __m128i bl = (__m128i)(v4u32){bottomData[offset0], bottomData[offset1], bottomData[offset2], bottomData[offset3]};
1975 const __m128i br = (__m128i)(v4u32){bottomData[offset0 + 1], bottomData[offset1 + 1], bottomData[offset2 + 1], bottomData[offset3 + 1]};
1977 __m128i v_distx = __lsx_vsrli_h(v_fx, 8);
1978 __m128i v_disty = __lsx_vsrli_h(v_fy, 8);
1979 v_distx = __lsx_vsrli_h(__lsx_vadd_w(v_distx, v_fxy_r), 4);
1980 v_disty = __lsx_vsrli_h(__lsx_vadd_w(v_disty, v_fxy_r), 4);
1981 v_distx = __lsx_vshuf_h(shuffleMask1, zero, v_distx);
1982 v_disty = __lsx_vshuf_h(shuffleMask1, zero, v_disty);
1984 interpolate_4_pixels_16_lsx(tl, tr, bl, br, v_distx, v_disty, b);
1986 v_fx = __lsx_vadd_w(v_fx, v_fdx);
1987 v_fy = __lsx_vadd_w(v_fy, v_fdy);
1989 fx = __lsx_vpickve2gr_w(v_fx, 0);
1990 fy = __lsx_vpickve2gr_w(v_fy, 0);
1992 while (b < boundedEnd) {
1996 const uint *s1 = (
const uint *)image.scanLine(y);
1997 const uint *s2 = (
const uint *)image.scanLine(y + 1);
1999 if (hasFastInterpolate4()) {
2000 int distx = (fx & 0x0000ffff) >> 8;
2001 int disty = (fy & 0x0000ffff) >> 8;
2002 *b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
2004 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2005 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2006 *b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx, disty);
2016 int x1 = (fx >> 16);
2018 int y1 = (fy >> 16);
2021 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2022 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2024 const uint *s1 = (
const uint *)image.scanLine(y1);
2025 const uint *s2 = (
const uint *)image.scanLine(y2);
2032 if (hasFastInterpolate4()) {
2033 int distx = (fx & 0x0000ffff) >> 8;
2034 int disty = (fy & 0x0000ffff) >> 8;
2035 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2037 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2038 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2039 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2051 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinear>,
2052 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinear>,
2053 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinear>,
2054 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinear>,
2055 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinear>
2058 fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinearTiled>,
2059 fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinearTiled>,
2060 fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinearTiled>,
2061 fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinearTiled>,
2062 fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinearTiled>
2067static const uint *
QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer,
const Operator *,
2068 const QSpanData *data,
int y,
int x,
2071 const qreal cx = x + qreal(0.5);
2072 const qreal cy = y + qreal(0.5);
2073 constexpr int tiled = (blendType == BlendTransformedBilinearTiled) ? 1 : 0;
2075 uint *end = buffer + length;
2077 if (canUseFastMatrixPath(cx, cy, length, data)) {
2079 int fdx = (
int)(data->m11 * fixed_scale);
2080 int fdy = (
int)(data->m12 * fixed_scale);
2082 int fx =
int((data->m21 * cy
2083 + data->m11 * cx + data->dx) * fixed_scale);
2084 int fy =
int((data->m22 * cy
2085 + data->m12 * cx + data->dy) * fixed_scale);
2091 if (qAbs(fdx) <= fixed_scale) {
2093 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2094 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2096 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2097 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2099 bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2100 }
else if (qAbs(data->m22) < qreal(1./8.)) {
2102 bilinearFastTransformHelperARGB32PM[tiled][UpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2105 bilinearFastTransformHelperARGB32PM[tiled][DownscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
2108 if (qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.) ) {
2110 bilinearFastTransformHelperARGB32PM[tiled][RotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2113 bilinearFastTransformHelperARGB32PM[tiled][FastRotateTransform](b, end, data->texture, fx, fy, fdx, fdy);
2117 const QTextureData &image = data->texture;
2119 const qreal fdx = data->m11;
2120 const qreal fdy = data->m12;
2121 const qreal fdw = data->m13;
2123 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2124 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2125 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2128 const qreal iw = fw == 0 ? 1 : 1 / fw;
2129 const qreal px = fx * iw - qreal(0.5);
2130 const qreal py = fy * iw - qreal(0.5);
2132 int x1 =
int(px) - (px < 0);
2134 int y1 =
int(py) - (py < 0);
2137 int distx =
int((px - x1) * 256);
2138 int disty =
int((py - y1) * 256);
2140 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2141 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2143 const uint *s1 = (
const uint *)data->texture.scanLine(y1);
2144 const uint *s2 = (
const uint *)data->texture.scanLine(y2);
2151 *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
2168static void QT_FASTCALL fetchTransformedBilinear_simple_scale_helper(uint *b, uint *end,
const QTextureData &image,
2169 int &fx,
int &fy,
int fdx,
int )
2171 const QPixelLayout *layout = &qPixelLayouts[image.format];
2172 const QList<QRgb> *clut = image.colorTable;
2173 const FetchAndConvertPixelsFunc fetch = layout->fetchToARGB32PM;
2175 int y1 = (fy >> 16);
2177 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2178 const uchar *s1 = image.scanLine(y1);
2179 const uchar *s2 = image.scanLine(y2);
2181 const int disty = (fy & 0x0000ffff) >> 8;
2182 const int idisty = 256 - disty;
2183 const int length = end - b;
2186 const int adjust = (fdx < 0) ? fdx * length : 0;
2187 const int offset = (fx + adjust) >> 16;
2190 Q_DECL_UNINITIALIZED IntermediateBuffer intermediate;
2191 uint *buf1 = intermediate.buffer_rb;
2192 uint *buf2 = intermediate.buffer_ag;
2196 int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
2197 Q_ASSERT(count <= BufferSize + 2);
2199 if (blendType == BlendTransformedBilinearTiled) {
2203 int len1 = qMin(count, image.width - x);
2204 int len2 = qMin(x, count - len1);
2206 ptr1 = fetch(buf1, s1, x, len1, clut,
nullptr);
2207 ptr2 = fetch(buf2, s2, x, len1, clut,
nullptr);
2208 for (
int i = 0; i < len1; ++i) {
2211 buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2212 buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2216 ptr1 = fetch(buf1 + len1, s1, 0, len2, clut,
nullptr);
2217 ptr2 = fetch(buf2 + len1, s2, 0, len2, clut,
nullptr);
2218 for (
int i = 0; i < len2; ++i) {
2221 buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2222 buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2226 for (
int i = image.width; i < count; ++i) {
2227 buf1[i] = buf1[i - image.width];
2228 buf2[i] = buf2[i - image.width];
2231 int start = qMax(x, image.x1);
2232 int end = qMin(x + count, image.x2);
2233 int len = qMax(1, end - start);
2234 int leading = start - x;
2236 ptr1 = fetch(buf1 + leading, s1, start, len, clut,
nullptr);
2237 ptr2 = fetch(buf2 + leading, s2, start, len, clut,
nullptr);
2239 for (
int i = 0; i < len; ++i) {
2242 buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
2243 buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
2246 for (
int i = 0; i < leading; ++i) {
2247 buf1[i] = buf1[leading];
2248 buf2[i] = buf2[leading];
2250 for (
int i = leading + len; i < count; ++i) {
2251 buf1[i] = buf1[i - 1];
2252 buf2[i] = buf2[i - 1];
2257 intermediate_adder(b, end, intermediate, offset, fx, fdx);
2262static void QT_FASTCALL fetchTransformedBilinear_fetcher(T *buf1, T *buf2,
const int len,
const QTextureData &image,
2263 int fx,
int fy,
const int fdx,
const int fdy)
2265 const QPixelLayout &layout = qPixelLayouts[image.format];
2266 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2268 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2270 Q_ASSERT(layout.bpp == bpp || (layout.bpp == QPixelLayout::BPP16FPx4 && bpp == QPixelLayout::BPP64));
2271 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2273 int y1 = (fy >> 16);
2275 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2276 const uchar *s1 = image.scanLine(y1);
2277 const uchar *s2 = image.scanLine(y2);
2280 if (blendType == BlendTransformedBilinear) {
2281 for (; i < len; ++i) {
2282 int x1 = (fx >> 16);
2284 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2287 if constexpr (useFetch) {
2288 buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
2289 buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
2291 buf1[i * 2 + 0] = buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x1];
2292 buf2[i * 2 + 0] = buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x1];
2298 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2300 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2302 for (; i < fastLen; ++i) {
2304 if constexpr (useFetch) {
2305 buf1[i * 2 + 0] = fetch1(s1, x);
2306 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2307 buf2[i * 2 + 0] = fetch1(s2, x);
2308 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2310 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2311 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2312 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2313 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2319 for (; i < len; ++i) {
2320 int x1 = (fx >> 16);
2322 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2323 if constexpr (useFetch) {
2324 buf1[i * 2 + 0] = fetch1(s1, x1);
2325 buf1[i * 2 + 1] = fetch1(s1, x2);
2326 buf2[i * 2 + 0] = fetch1(s2, x1);
2327 buf2[i * 2 + 1] = fetch1(s2, x2);
2329 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2330 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2331 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2332 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2338 if (blendType == BlendTransformedBilinear) {
2339 for (; i < len; ++i) {
2340 int x1 = (fx >> 16);
2342 int y1 = (fy >> 16);
2344 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2345 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2346 if (x1 != x2 && y1 != y2)
2348 const uchar *s1 = image.scanLine(y1);
2349 const uchar *s2 = image.scanLine(y2);
2350 if constexpr (useFetch) {
2351 buf1[i * 2 + 0] = fetch1(s1, x1);
2352 buf1[i * 2 + 1] = fetch1(s1, x2);
2353 buf2[i * 2 + 0] = fetch1(s2, x1);
2354 buf2[i * 2 + 1] = fetch1(s2, x2);
2356 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2357 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2358 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2359 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2366 fastLen = qMin(fastLen,
int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
2368 fastLen = qMin(fastLen,
int((qint64(image.x1) * fixed_scale - fx) / fdx));
2370 fastLen = qMin(fastLen,
int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
2372 fastLen = qMin(fastLen,
int((qint64(image.y1) * fixed_scale - fy) / fdy));
2374 for (; i < fastLen; ++i) {
2377 const uchar *s1 = image.scanLine(y);
2378 const uchar *s2 = s1 + image.bytesPerLine;
2379 if constexpr (useFetch) {
2380 buf1[i * 2 + 0] = fetch1(s1, x);
2381 buf1[i * 2 + 1] = fetch1(s1, x + 1);
2382 buf2[i * 2 + 0] = fetch1(s2, x);
2383 buf2[i * 2 + 1] = fetch1(s2, x + 1);
2385 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x];
2386 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x + 1];
2387 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x];
2388 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x + 1];
2395 for (; i < len; ++i) {
2396 int x1 = (fx >> 16);
2398 int y1 = (fy >> 16);
2400 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2401 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2403 const uchar *s1 = image.scanLine(y1);
2404 const uchar *s2 = image.scanLine(y2);
2405 if constexpr (useFetch) {
2406 buf1[i * 2 + 0] = fetch1(s1, x1);
2407 buf1[i * 2 + 1] = fetch1(s1, x2);
2408 buf2[i * 2 + 0] = fetch1(s2, x1);
2409 buf2[i * 2 + 1] = fetch1(s2, x2);
2411 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2412 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2413 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2414 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2423static void QT_FASTCALL fetchTransformedBilinear_slow_fetcher(T *buf1, T *buf2, ushort *distxs, ushort *distys,
2424 const int len,
const QTextureData &image,
2425 qreal &fx, qreal &fy, qreal &fw,
2426 const qreal fdx,
const qreal fdy,
const qreal fdw)
2428 const QPixelLayout &layout = qPixelLayouts[image.format];
2429 constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
2431 Q_ASSERT(
sizeof(T) ==
sizeof(uint));
2433 Q_ASSERT(layout.bpp == bpp);
2435 const Fetch1PixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? fetch1PixelTable[layout.bpp] : fetch1Pixel<bpp>;
2437 for (
int i = 0; i < len; ++i) {
2438 const qreal iw = fw == 0 ? 16384 : 1 / fw;
2439 const qreal px = fx * iw - qreal(0.5);
2440 const qreal py = fy * iw - qreal(0.5);
2442 int x1 = qFloor(px);
2444 int y1 = qFloor(py);
2447 distxs[i] = ushort((px - x1) * (1<<16));
2448 distys[i] = ushort((py - y1) * (1<<16));
2450 fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
2451 fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
2453 const uchar *s1 = image.scanLine(y1);
2454 const uchar *s2 = image.scanLine(y2);
2455 if constexpr (useFetch) {
2456 buf1[i * 2 + 0] = fetch1(s1, x1);
2457 buf1[i * 2 + 1] = fetch1(s1, x2);
2458 buf2[i * 2 + 0] = fetch1(s2, x1);
2459 buf2[i * 2 + 1] = fetch1(s2, x2);
2461 buf1[i * 2 + 0] =
reinterpret_cast<
const T *>(s1)[x1];
2462 buf1[i * 2 + 1] =
reinterpret_cast<
const T *>(s1)[x2];
2463 buf2[i * 2 + 0] =
reinterpret_cast<
const T *>(s2)[x1];
2464 buf2[i * 2 + 1] =
reinterpret_cast<
const T *>(s2)[x2];
2476 const QSpanData *data,
int y,
int x,
int length)
2478 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2479 const QList<QRgb> *clut = data->texture.colorTable;
2480 Q_ASSERT(bpp == QPixelLayout::BPPNone || layout->bpp == bpp);
2482 const qreal cx = x + qreal(0.5);
2483 const qreal cy = y + qreal(0.5);
2485 if (canUseFastMatrixPath(cx, cy, length, data)) {
2487 int fdx = (
int)(data->m11 * fixed_scale);
2488 int fdy = (
int)(data->m12 * fixed_scale);
2490 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2491 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2497 if (qAbs(fdx) <= fixed_scale) {
2498 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
2499 }
else if (qAbs(fdx) <= 2 * fixed_scale) {
2500 const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
2501 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
2503 fetchTransformedBilinear_simple_scale_helper<blendType>(buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
2505 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2507 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2508 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2511 int len = qMin(length, BufferSize / 2);
2512 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
2513 layout->convertToARGB32PM(buf1, len * 2, clut);
2514 layout->convertToARGB32PM(buf2, len * 2, clut);
2516 if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) {
2517 int disty = (fy & 0x0000ffff) >> 8;
2518 for (
int i = 0; i < len; ++i) {
2519 int distx = (fx & 0x0000ffff) >> 8;
2520 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2524 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2525 for (
int i = 0; i < len; ++i) {
2526 uint tl = buf1[i * 2 + 0];
2527 uint tr = buf1[i * 2 + 1];
2528 uint bl = buf2[i * 2 + 0];
2529 uint br = buf2[i * 2 + 1];
2530 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2531 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2540 const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
2542 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2543 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2546 int len = qMin(length, BufferSize / 2);
2547 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2548 layout->convertToARGB32PM(buf1, len * 2, clut);
2549 layout->convertToARGB32PM(buf2, len * 2, clut);
2551 if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
2553 for (
int i = 0; i < len; ++i) {
2554 int distx = (fx & 0x0000ffff) >> 8;
2555 int disty = (fy & 0x0000ffff) >> 8;
2557 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2563 for (
int i = 0; i < len; ++i) {
2564 uint tl = buf1[i * 2 + 0];
2565 uint tr = buf1[i * 2 + 1];
2566 uint bl = buf2[i * 2 + 0];
2567 uint br = buf2[i * 2 + 1];
2569 int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
2570 int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
2572 b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
2583 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType,bpp,uint>;
2585 const qreal fdx = data->m11;
2586 const qreal fdy = data->m12;
2587 const qreal fdw = data->m13;
2589 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2590 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2591 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2593 Q_DECL_UNINITIALIZED uint buf1[BufferSize];
2594 Q_DECL_UNINITIALIZED uint buf2[BufferSize];
2597 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2598 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2601 const int len = qMin(length, BufferSize / 2);
2602 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2604 layout->convertToARGB32PM(buf1, len * 2, clut);
2605 layout->convertToARGB32PM(buf2, len * 2, clut);
2607 for (
int i = 0; i < len; ++i) {
2608 const int distx = distxs[i] >> 8;
2609 const int disty = distys[i] >> 8;
2611 b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
2621#if QT_CONFIG(raster_64bit)
2622template<TextureBlendType blendType>
2623static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer,
const QSpanData *data,
2624 int y,
int x,
int length)
2626 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2627 const auto *clut = data->texture.colorTable;
2628 const auto convert = layout->convertToRGBA64PM;
2630 const qreal cx = x + qreal(0.5);
2631 const qreal cy = y + qreal(0.5);
2633 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
2634 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
2635 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2636 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2637 QRgba64 *b = buffer;
2639 if (canUseFastMatrixPath(cx, cy, length, data)) {
2641 const int fdx = (
int)(data->m11 * fixed_scale);
2642 const int fdy = (
int)(data->m12 * fixed_scale);
2644 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2645 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2650 const auto fetcher =
2651 (layout->bpp == QPixelLayout::BPP32)
2652 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
2653 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2657 const int len = qMin(length, BufferSize / 2);
2658 const int disty = (fy & 0x0000ffff);
2659#if defined(__SSE2__)
2660 const __m128i vdy = _mm_set1_epi16(disty);
2661 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2663 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2665 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2667 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2669 for (
int i = 0; i < len; ++i) {
2670 const int distx = (fx & 0x0000ffff);
2671#if defined(__SSE2__)
2672 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2674 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2675 vt = _mm_mulhi_epu16(vt, vidy);
2676 vb = _mm_mulhi_epu16(vb, vdy);
2677 vt = _mm_add_epi16(vt, vb);
2680 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2681 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2682 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2683 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2685 _mm_storel_epi64((__m128i*)(b+i), vt);
2687 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2696 const int len = qMin(length, BufferSize / 2);
2698 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2700 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2701 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2703 for (
int i = 0; i < len; ++i) {
2704 const int distx = (fx & 0x0000ffff);
2705 const int disty = (fy & 0x0000ffff);
2706 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2716 const auto fetcher =
2717 (layout->bpp == QPixelLayout::BPP32)
2718 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
2719 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
2721 const qreal fdx = data->m11;
2722 const qreal fdy = data->m12;
2723 const qreal fdw = data->m13;
2725 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2726 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2727 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2729 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2730 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2733 const int len = qMin(length, BufferSize / 2);
2734 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2736 convert(buf1, sbuf1, len * 2, clut,
nullptr);
2737 convert(buf2, sbuf2, len * 2, clut,
nullptr);
2739 for (
int i = 0; i < len; ++i) {
2740 const int distx = distxs[i];
2741 const int disty = distys[i];
2742 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2752template<TextureBlendType blendType>
2753static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buffer,
const QSpanData *data,
2754 int y,
int x,
int length)
2756 const auto convert = convert64ToRGBA64PM[data->texture.format];
2758 const qreal cx = x + qreal(0.5);
2759 const qreal cy = y + qreal(0.5);
2761 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2762 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2763 QRgba64 *end = buffer + length;
2764 QRgba64 *b = buffer;
2766 if (canUseFastMatrixPath(cx, cy, length, data)) {
2768 const int fdx = (
int)(data->m11 * fixed_scale);
2769 const int fdy = (
int)(data->m12 * fixed_scale);
2771 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2772 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2776 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2780 int len = qMin(length, BufferSize / 2);
2781 int disty = (fy & 0x0000ffff);
2782#if defined(__SSE2__)
2783 const __m128i vdy = _mm_set1_epi16(disty);
2784 const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
2786 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2788 convert(buf1, len * 2);
2790 convert(buf2, len * 2);
2792 for (
int i = 0; i < len; ++i) {
2793 int distx = (fx & 0x0000ffff);
2794#if defined(__SSE2__)
2795 __m128i vt = _mm_loadu_si128((
const __m128i*)(buf1 + i*2));
2797 __m128i vb = _mm_loadu_si128((
const __m128i*)(buf2 + i*2));
2798 vt = _mm_mulhi_epu16(vt, vidy);
2799 vb = _mm_mulhi_epu16(vb, vdy);
2800 vt = _mm_add_epi16(vt, vb);
2803 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
2804 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
2805 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
2806 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
2808 _mm_storel_epi64((__m128i*)(b+i), vt);
2810 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2819 int len = qMin(length, BufferSize / 2);
2821 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
2823 convert(buf1, len * 2);
2824 convert(buf2, len * 2);
2826 for (
int i = 0; i < len; ++i) {
2827 int distx = (fx & 0x0000ffff);
2828 int disty = (fy & 0x0000ffff);
2829 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2839 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
2841 const qreal fdx = data->m11;
2842 const qreal fdy = data->m12;
2843 const qreal fdw = data->m13;
2845 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2846 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2847 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2849 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2850 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2853 const int len = qMin(length, BufferSize / 2);
2854 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2856 convert(buf1, len * 2);
2857 convert(buf2, len * 2);
2859 for (
int i = 0; i < len; ++i) {
2860 const int distx = distxs[i];
2861 const int disty = distys[i];
2862 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2872template<TextureBlendType blendType>
2873static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_f32x4(QRgba64 *buffer,
const QSpanData *data,
2874 int y,
int x,
int length)
2876 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
2877 const auto *clut = data->texture.colorTable;
2878 const auto convert = layout->fetchToRGBA64PM;
2880 const qreal cx = x + qreal(0.5);
2881 const qreal cy = y + qreal(0.5);
2883 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf1[BufferSize];
2884 Q_DECL_UNINITIALIZED QRgbaFloat32 sbuf2[BufferSize];
2885 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf1[BufferSize];
2886 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buf2[BufferSize];
2887 QRgba64 *b = buffer;
2889 if (canUseFastMatrixPath(cx, cy, length, data)) {
2891 const int fdx = (
int)(data->m11 * fixed_scale);
2892 const int fdy = (
int)(data->m12 * fixed_scale);
2894 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
2895 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
2900 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2902 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
2904 const int len = qMin(length, BufferSize / 2);
2906 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
2908 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2910 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2912 for (
int i = 0; i < len; ++i) {
2913 const int distx = (fx & 0x0000ffff);
2914 const int disty = (fy & 0x0000ffff);
2915 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2924 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
2926 const qreal fdx = data->m11;
2927 const qreal fdy = data->m12;
2928 const qreal fdw = data->m13;
2930 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
2931 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
2932 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
2934 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
2935 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
2938 const int len = qMin(length, BufferSize / 2);
2939 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
2941 convert(buf1, (
const uchar *)sbuf1, 0, len * 2, clut,
nullptr);
2942 convert(buf2, (
const uchar *)sbuf2, 0, len * 2, clut,
nullptr);
2944 for (
int i = 0; i < len; ++i) {
2945 const int distx = distxs[i];
2946 const int disty = distys[i];
2947 b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
2957template<TextureBlendType blendType>
2958static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer,
const Operator *,
2959 const QSpanData *data,
int y,
int x,
int length)
2961 switch (qPixelLayouts[data->texture.format].bpp) {
2962 case QPixelLayout::BPP64:
2963 case QPixelLayout::BPP16FPx4:
2964 return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
2965 case QPixelLayout::BPP32FPx4:
2966 return fetchTransformedBilinear64_f32x4<blendType>(buffer, data, y, x, length);
2968 return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
2973#if QT_CONFIG(raster_fp)
2974static void interpolate_simple_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2978 for (
int i = 0; i < len; ++i) {
2979 const int distx = (fx & 0x0000ffff);
2980 const int disty = (fy & 0x0000ffff);
2981 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, distx, disty);
2987static void interpolate_perspective_rgba32f(QRgbaFloat32 *b,
const QRgbaFloat32 *buf1,
const QRgbaFloat32 *buf2,
int len,
2988 unsigned short *distxs,
2989 unsigned short *distys)
2991 for (
int i = 0; i < len; ++i) {
2992 const int dx = distxs[i];
2993 const int dy = distys[i];
2994 b[i] = interpolate_4_pixels_rgba32f(buf1 + i*2, buf2 + i*2, dx, dy);
2998template<TextureBlendType blendType>
2999static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint32(QRgbaFloat32 *buffer,
const QSpanData *data,
3000 int y,
int x,
int length)
3002 const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
3003 const auto *clut = data->texture.colorTable;
3004 const auto convert = qConvertToRGBA32F[data->texture.format];
3006 const qreal cx = x + qreal(0.5);
3007 const qreal cy = y + qreal(0.5);
3009 Q_DECL_UNINITIALIZED uint sbuf1[BufferSize];
3010 Q_DECL_UNINITIALIZED uint sbuf2[BufferSize];
3011 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3012 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3013 QRgbaFloat32 *b = buffer;
3015 if (canUseFastMatrixPath(cx, cy, length, data)) {
3017 const int fdx = (
int)(data->m11 * fixed_scale);
3018 const int fdy = (
int)(data->m12 * fixed_scale);
3020 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3021 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3026 const auto fetcher =
3027 (layout->bpp == QPixelLayout::BPP32)
3028 ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
3029 : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3031 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3033 const int len = qMin(length, BufferSize / 2);
3034 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3036 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3038 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3040 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3046 const auto fetcher =
3047 (layout->bpp == QPixelLayout::BPP32)
3048 ? fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32, uint>
3049 : fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPPNone, uint>;
3051 const qreal fdx = data->m11;
3052 const qreal fdy = data->m12;
3053 const qreal fdw = data->m13;
3054 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3055 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3056 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3057 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3058 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3061 const int len = qMin(length, BufferSize / 2);
3062 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3064 convert(buf1, sbuf1, len * 2, clut,
nullptr);
3065 convert(buf2, sbuf2, len * 2, clut,
nullptr);
3067 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3076template<TextureBlendType blendType>
3077static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP_uint64(QRgbaFloat32 *buffer,
const QSpanData *data,
3078 int y,
int x,
int length)
3080 const auto convert = convert64ToRGBA32F[data->texture.format];
3082 const qreal cx = x + qreal(0.5);
3083 const qreal cy = y + qreal(0.5);
3085 Q_DECL_UNINITIALIZED quint64 sbuf1[BufferSize] ;
3086 Q_DECL_UNINITIALIZED quint64 sbuf2[BufferSize];
3087 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3088 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3089 QRgbaFloat32 *b = buffer;
3091 if (canUseFastMatrixPath(cx, cy, length, data)) {
3093 const int fdx = (
int)(data->m11 * fixed_scale);
3094 const int fdy = (
int)(data->m12 * fixed_scale);
3096 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3097 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3101 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3103 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3105 const int len = qMin(length, BufferSize / 2);
3106 fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
3108 convert(buf1, sbuf1, len * 2);
3110 convert(buf2, sbuf2, len * 2);
3112 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3118 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP64, quint64>;
3120 const qreal fdx = data->m11;
3121 const qreal fdy = data->m12;
3122 const qreal fdw = data->m13;
3124 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3125 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3126 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3128 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3129 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3132 const int len = qMin(length, BufferSize / 2);
3133 fetcher(sbuf1, sbuf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3135 convert(buf1, sbuf1, len * 2);
3136 convert(buf2, sbuf2, len * 2);
3138 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3147template<TextureBlendType blendType>
3148static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const QSpanData *data,
3149 int y,
int x,
int length)
3151 const auto convert = data->rasterBuffer->format == QImage::Format_RGBA32FPx4 ? convertRGBA32FToRGBA32FPM
3152 : convertRGBA32FToRGBA32F;
3154 const qreal cx = x + qreal(0.5);
3155 const qreal cy = y + qreal(0.5);
3157 Q_DECL_UNINITIALIZED QRgbaFloat32 buf1[BufferSize];
3158 Q_DECL_UNINITIALIZED QRgbaFloat32 buf2[BufferSize];
3159 QRgbaFloat32 *b = buffer;
3161 if (canUseFastMatrixPath(cx, cy, length, data)) {
3163 const int fdx = (
int)(data->m11 * fixed_scale);
3164 const int fdy = (
int)(data->m12 * fixed_scale);
3166 int fx =
int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
3167 int fy =
int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
3171 const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3173 const bool skipsecond = (fdy == 0) && ((fy & 0x0000ffff) == 0);
3175 const int len = qMin(length, BufferSize / 2);
3176 fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
3178 convert(buf1, len * 2);
3180 convert(buf2, len * 2);
3182 interpolate_simple_rgba32f(b, buf1, buf2, len, fx, fdx, fy, fdy);
3188 const auto fetcher = fetchTransformedBilinear_slow_fetcher<blendType, QPixelLayout::BPP32FPx4, QRgbaFloat32>;
3190 const qreal fdx = data->m11;
3191 const qreal fdy = data->m12;
3192 const qreal fdw = data->m13;
3194 qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
3195 qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
3196 qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
3198 Q_DECL_UNINITIALIZED ushort distxs[BufferSize / 2];
3199 Q_DECL_UNINITIALIZED ushort distys[BufferSize / 2];
3202 const int len = qMin(length, BufferSize / 2);
3203 fetcher(buf1, buf2, distxs, distys, len, data->texture, fx, fy, fw, fdx, fdy, fdw);
3205 convert(buf1, len * 2);
3206 convert(buf2, len * 2);
3208 interpolate_perspective_rgba32f(b, buf1, buf2, len, distxs, distys);
3217template<TextureBlendType blendType>
3218static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *buffer,
const Operator *,
3219 const QSpanData *data,
int y,
int x,
int length)
3221 switch (qPixelLayouts[data->texture.format].bpp) {
3222 case QPixelLayout::BPP64:
3223 case QPixelLayout::BPP16FPx4:
3224 return fetchTransformedBilinearFP_uint64<blendType>(buffer, data, y, x, length);
3225 case QPixelLayout::BPP32FPx4:
3226 return fetchTransformedBilinearFP<blendType>(buffer, data, y, x, length);
3228 return fetchTransformedBilinearFP_uint32<blendType>(buffer, data, y, x, length);
3239 fetchUntransformedARGB32PM,
3241 fetchUntransformedARGB32PM,
3242 fetchUntransformedRGB16,
3274static_assert(std::size(sourceFetchUntransformed) == QImage::NImageFormats);
3279 fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>,
3280 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPPNone>,
3281 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPPNone>,
3282 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone>
3285static_assert(std::size(sourceFetchGeneric) == NBlendTypes);
3288 fetchUntransformedARGB32PM,
3289 fetchUntransformedARGB32PM,
3290 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3291 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3292 fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>,
3293 fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>
3296static_assert(std::size(sourceFetchARGB32PM) == NBlendTypes);
3301 fetchTransformed<BlendTransformed, QPixelLayout::BPP16>,
3302 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP16>,
3303 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP16>,
3304 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16>
3307static_assert(std::size(sourceFetchAny16) == NBlendTypes);
3312 fetchTransformed<BlendTransformed, QPixelLayout::BPP32>,
3313 fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP32>,
3314 fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP32>,
3315 fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32>
3318static_assert(std::size(sourceFetchAny32) == NBlendTypes);
3322 if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
3323 return sourceFetchARGB32PM[blendType];
3325 return sourceFetchUntransformed[format];
3326 if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
3327 return sourceFetchAny16[blendType];
3328 if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
3329 return sourceFetchAny32[blendType];
3330 return sourceFetchGeneric[blendType];
3333#if QT_CONFIG(raster_64bit)
3334static const SourceFetchProc64 sourceFetchGeneric64[] = {
3335 fetchUntransformed64,
3336 fetchUntransformed64,
3337 fetchTransformed64<BlendTransformed>,
3338 fetchTransformed64<BlendTransformedTiled>,
3339 fetchTransformedBilinear64<BlendTransformedBilinear>,
3340 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3343static_assert(std::size(sourceFetchGeneric64) == NBlendTypes);
3345static const SourceFetchProc64 sourceFetchRGBA64PM[] = {
3346 fetchUntransformedRGBA64PM,
3347 fetchUntransformedRGBA64PM,
3348 fetchTransformed64<BlendTransformed>,
3349 fetchTransformed64<BlendTransformedTiled>,
3350 fetchTransformedBilinear64<BlendTransformedBilinear>,
3351 fetchTransformedBilinear64<BlendTransformedBilinearTiled>
3354static_assert(std::size(sourceFetchRGBA64PM) == NBlendTypes);
3356static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
3358 if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
3359 return sourceFetchRGBA64PM[blendType];
3360 return sourceFetchGeneric64[blendType];
3364#if QT_CONFIG(raster_fp)
3365static const SourceFetchProcFP sourceFetchGenericFP[] = {
3366 fetchUntransformedFP,
3367 fetchUntransformedFP,
3368 fetchTransformedFP<BlendTransformed>,
3369 fetchTransformedFP<BlendTransformedTiled>,
3370 fetchTransformedBilinearFP<BlendTransformedBilinear>,
3371 fetchTransformedBilinearFP<BlendTransformedBilinearTiled>
3374static_assert(std::size(sourceFetchGenericFP) == NBlendTypes);
3376static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format )
3378 return sourceFetchGenericFP[blendType];
3389 return data->colorTable32[qt_gradient_clamp(data, ipos)];
3392#if QT_CONFIG(raster_64bit)
3393static const QRgba64& qt_gradient_pixel64_fixed(
const QGradientData *data,
int fixed_pos)
3395 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3396 return data->colorTable64[qt_gradient_clamp(data, ipos)];
3400#if QT_CONFIG(raster_fp)
3401static inline QRgbaFloat32 qt_gradient_pixelFP(
const QGradientData *data, qreal pos)
3403 int ipos =
int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
3404 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3405 return QRgbaFloat32::fromRgba64(rgb64.red(),rgb64.green(), rgb64.blue(), rgb64.alpha());
3408static inline QRgbaFloat32 qt_gradient_pixelFP_fixed(
const QGradientData *data,
int fixed_pos)
3410 int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
3411 QRgba64 rgb64 = data->colorTable64[qt_gradient_clamp(data, ipos)];
3412 return QRgbaFloat32::fromRgba64(rgb64.red(), rgb64.green(), rgb64.blue(), rgb64.alpha());
3416static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v,
const QSpanData *data)
3418 v->dx = data->gradient.linear.end.x - data->gradient.linear.origin.x;
3419 v->dy = data->gradient.linear.end.y - data->gradient.linear.origin.y;
3420 v->l = v->dx * v->dx + v->dy * v->dy;
3425 v->off = -v->dx * data->gradient.linear.origin.x - v->dy * data->gradient.linear.origin.y;
3436 Q_ASSERT(
std::isfinite(v));
3437 return qt_gradient_pixel(&gradient, v);
3445 qt_memfill32(buffer, fill, length);
3449#if QT_CONFIG(raster_64bit)
3453 typedef QRgba64 Type;
3454 static Type null() {
return QRgba64::fromRgba64(0); }
3455 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3457 Q_ASSERT(std::isfinite(v));
3458 return qt_gradient_pixel64(&gradient, v);
3460 static Type fetchSingle(
const QGradientData& gradient,
int v)
3462 return qt_gradient_pixel64_fixed(&gradient, v);
3464 static void memfill(Type *buffer, Type fill,
int length)
3466 qt_memfill64((quint64*)buffer, fill, length);
3471#if QT_CONFIG(raster_fp)
3475 typedef QRgbaFloat32 Type;
3476 static Type null() {
return QRgbaFloat32::fromRgba64(0,0,0,0); }
3477 static Type fetchSingle(
const QGradientData& gradient, qreal v)
3479 Q_ASSERT(std::isfinite(v));
3480 return qt_gradient_pixelFP(&gradient, v);
3482 static Type fetchSingle(
const QGradientData& gradient,
int v)
3484 return qt_gradient_pixelFP_fixed(&gradient, v);
3486 static void memfill(Type *buffer, Type fill,
int length)
3489 memcpy(&fillCopy, &fill,
sizeof(quint64));
3490 qt_memfill64((quint64*)buffer, fillCopy, length);
3497 BlendType *buffer,
const Operator *op,
const QSpanData *data,
3498 int y,
int x,
int length)
3500 const BlendType *b = buffer;
3505 if (op->linear.l == 0) {
3508 rx = data->m21 * (y + qreal(0.5)) + data->m11 * (x + qreal(0.5)) + data->dx;
3509 ry = data->m22 * (y + qreal(0.5)) + data->m12 * (x + qreal(0.5)) + data->dy;
3510 t = op->linear.dx*rx + op->linear.dy*ry + op->linear.off;
3511 inc = op->linear.dx * data->m11 + op->linear.dy * data->m12;
3512 affine = !data->m13 && !data->m23;
3520 const BlendType *end = buffer + length;
3522 if (inc > qreal(-1e-5) && inc < qreal(1e-5)) {
3524 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient,
int(t *
FIXPT_SIZE)), length);
3526 GradientBase::memfill(buffer, GradientBase::fetchSingle(data->gradient, t /
GRADIENT_STOPTABLE_SIZE), length);
3532 while (buffer < end) {
3533 *buffer = GradientBase::fetchSingle(data->gradient, t_fixed);
3534 t_fixed += inc_fixed;
3539 while (buffer < end) {
3547 qreal rw = data->m23 * (y + qreal(0.5)) + data->m13 * (x + qreal(0.5)) + data->m33;
3548 while (buffer < end) {
3551 t = (op->linear.dx*x + op->linear.dy *y) + op->linear.off;
3553 *buffer = GradientBase::fetchSingle(data->gradient, t);
3567static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer,
const Operator *op,
const QSpanData *data,
3568 int y,
int x,
int length)
3570 return qt_fetch_linear_gradient_template<GradientBase32, uint>(buffer, op, data, y, x, length);
3573#if QT_CONFIG(raster_64bit)
3574static const QRgba64 * QT_FASTCALL qt_fetch_linear_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3575 int y,
int x,
int length)
3577 return qt_fetch_linear_gradient_template<GradientBase64, QRgba64>(buffer, op, data, y, x, length);
3580#if QT_CONFIG(raster_fp)
3581static const QRgbaFloat32 * QT_FASTCALL qt_fetch_linear_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3582 int y,
int x,
int length)
3584 return qt_fetch_linear_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, op, data, y, x, length);
3588static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v,
const QSpanData *data)
3590 v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x;
3591 v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y;
3593 v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius;
3594 v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius;
3596 v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy;
3598 v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0;
3601template <
class GradientBase>
3608 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
3610 if (op->radial.extended) {
3611 while (buffer < end) {
3612 BlendType result = GradientBase::null();
3614 qreal w = qSqrt(det) - b;
3615 if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0)
3616 result = GradientBase::fetchSingle(data->gradient, w);
3622 delta_det += delta_delta_det;
3628 while (buffer < end) {
3629 BlendType result = GradientBase::null();
3631 qreal w = qSqrt(det) - b;
3632 result = GradientBase::fetchSingle(data->gradient, w);
3638 delta_det += delta_delta_det;
3645const uint *
QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer,
const Operator *op,
const QSpanData *data,
3646 int y,
int x,
int length)
3648 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase32>, uint>(buffer, op, data, y, x, length);
3653#if QT_CONFIG(raster_64bit)
3654const QRgba64 * QT_FASTCALL qt_fetch_radial_gradient_rgb64(QRgba64 *buffer,
const Operator *op,
const QSpanData *data,
3655 int y,
int x,
int length)
3657 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBase64>, QRgba64>(buffer, op, data, y, x, length);
3661#if QT_CONFIG(raster_fp)
3662static const QRgbaFloat32 * QT_FASTCALL qt_fetch_radial_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *op,
const QSpanData *data,
3663 int y,
int x,
int length)
3665 return qt_fetch_radial_gradient_template<RadialFetchPlain<GradientBaseFP>, QRgbaFloat32>(buffer, op, data, y, x, length);
3671 BlendType *buffer,
const QSpanData *data,
3672 int y,
int x,
int length)
3674 const BlendType *b = buffer;
3675 qreal rx = data->m21 * (y + qreal(0.5))
3676 + data->dx + data->m11 * (x + qreal(0.5));
3677 qreal ry = data->m22 * (y + qreal(0.5))
3678 + data->dy + data->m12 * (x + qreal(0.5));
3679 bool affine = !data->m13 && !data->m23;
3681 const qreal inv2pi =
M_1_PI / 2.0;
3683 const BlendType *end = buffer + length;
3685 rx -= data->gradient.conical.center.x;
3686 ry -= data->gradient.conical.center.y;
3687 while (buffer < end) {
3688 qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
3690 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3697 qreal rw = data->m23 * (y + qreal(0.5))
3698 + data->m33 + data->m13 * (x + qreal(0.5));
3701 while (buffer < end) {
3702 qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
3703 rx/rw - data->gradient.conical.center.y)
3704 + data->gradient.conical.angle;
3706 *buffer = GradientBase::fetchSingle(data->gradient, 1 - angle * inv2pi);
3720static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer,
const Operator *,
const QSpanData *data,
3721 int y,
int x,
int length)
3723 return qt_fetch_conical_gradient_template<GradientBase32, uint>(buffer, data, y, x, length);
3726#if QT_CONFIG(raster_64bit)
3727static const QRgba64 * QT_FASTCALL qt_fetch_conical_gradient_rgb64(QRgba64 *buffer,
const Operator *,
const QSpanData *data,
3728 int y,
int x,
int length)
3730 return qt_fetch_conical_gradient_template<GradientBase64, QRgba64>(buffer, data, y, x, length);
3734#if QT_CONFIG(raster_fp)
3735static const QRgbaFloat32 * QT_FASTCALL qt_fetch_conical_gradient_rgbfp(QRgbaFloat32 *buffer,
const Operator *,
const QSpanData *data,
3736 int y,
int x,
int length)
3738 return qt_fetch_conical_gradient_template<GradientBaseFP, QRgbaFloat32>(buffer, data, y, x, length);
3747#if QT_CONFIG(raster_64bit)
3748static const CompositionFunctionSolid64 *functionForModeSolid64 = qt_functionForModeSolid64_C;
3750#if QT_CONFIG(raster_fp)
3751static const CompositionFunctionSolidFP *functionForModeSolidFP = qt_functionForModeSolidFP_C;
3759#if QT_CONFIG(raster_64bit)
3760static const CompositionFunction64 *functionForMode64 = qt_functionForMode64_C;
3762#if QT_CONFIG(raster_fp)
3763static const CompositionFunctionFP *functionForModeFP = qt_functionForModeFP_C;
3771 else if (data->txop <= QTransform::TxTranslate)
3792 bool solidSource =
false;
3793 switch(data->type) {
3795 solidSource = data->solidColor.alphaF() >= 1.0f;
3796 op.srcFetch =
nullptr;
3797 op.srcFetch64 =
nullptr;
3798 op.srcFetchFP =
nullptr;
3801 solidSource = !data->gradient.alphaColor;
3802 getLinearGradientValues(&op.linear, data);
3803 op.srcFetch = qt_fetch_linear_gradient;
3804#if QT_CONFIG(raster_64bit)
3805 op.srcFetch64 = qt_fetch_linear_gradient_rgb64;
3807#if QT_CONFIG(raster_fp)
3808 op.srcFetchFP = qt_fetch_linear_gradient_rgbfp;
3812 solidSource = !data->gradient.alphaColor;
3813 getRadialGradientValues(&op.radial, data);
3814 op.srcFetch = qt_fetch_radial_gradient;
3815#if QT_CONFIG(raster_64bit)
3816 op.srcFetch64 = qt_fetch_radial_gradient_rgb64;
3818#if QT_CONFIG(raster_fp)
3819 op.srcFetchFP = qt_fetch_radial_gradient_rgbfp;
3823 solidSource = !data->gradient.alphaColor;
3824 op.srcFetch = qt_fetch_conical_gradient;
3825#if QT_CONFIG(raster_64bit)
3826 op.srcFetch64 = qt_fetch_conical_gradient_rgb64;
3828#if QT_CONFIG(raster_fp)
3829 op.srcFetchFP = qt_fetch_conical_gradient_rgbfp;
3833 solidSource = !data->texture.hasAlpha;
3834 op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
3835#if QT_CONFIG(raster_64bit)
3836 op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);
3838#if QT_CONFIG(raster_fp)
3839 op.srcFetchFP = getSourceFetchFP(getBlendType(data), data->texture.format);
3846#if !QT_CONFIG(raster_64bit)
3847 op.srcFetch64 =
nullptr;
3849#if !QT_CONFIG(raster_fp)
3850 op.srcFetchFP =
nullptr;
3854 if (op.mode == QPainter::CompositionMode_SourceOver && solidSource)
3855 op.mode = QPainter::CompositionMode_Source;
3858#if QT_CONFIG(raster_64bit)
3859 op.destFetch64 = destFetchProc64[data->rasterBuffer->format];
3861 op.destFetch64 =
nullptr;
3863#if QT_CONFIG(raster_fp)
3864 op.destFetchFP = destFetchProcFP[data->rasterBuffer->format];
3866 op.destFetchFP =
nullptr;
3868 if (op.mode == QPainter::CompositionMode_Source &&
3869 (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) {
3870 const QT_FT_Span *lastSpan = spans + spanCount;
3871 bool alphaSpans =
false;
3872 while (spans < lastSpan) {
3873 if (spans->coverage != 255) {
3879 if (!alphaSpans && spanCount > 0) {
3882 if (op.destFetch != destFetchARGB32P)
3883 op.destFetch = destFetchUndefined;
3884#if QT_CONFIG(raster_64bit)
3885 if (op.destFetch64 != destFetchRGB64)
3886 op.destFetch64 = destFetch64Undefined;
3888#if QT_CONFIG(raster_fp)
3889 if (op.destFetchFP != destFetchRGBFP)
3890 op.destFetchFP = destFetchFPUndefined;
3896 op.funcSolid = functionForModeSolid[op.mode];
3897 op.func = functionForMode[op.mode];
3898#if QT_CONFIG(raster_64bit)
3899 op.destStore64 = destStoreProc64[data->rasterBuffer->format];
3900 op.funcSolid64 = functionForModeSolid64[op.mode];
3901 op.func64 = functionForMode64[op.mode];
3903 op.destStore64 =
nullptr;
3904 op.funcSolid64 =
nullptr;
3905 op.func64 =
nullptr;
3907#if QT_CONFIG(raster_fp)
3908 op.destStoreFP = destStoreFP;
3909 op.funcSolidFP = functionForModeSolidFP[op.mode];
3910 op.funcFP = functionForModeFP[op.mode];
3912 op.destStoreFP =
nullptr;
3913 op.funcSolidFP =
nullptr;
3914 op.funcFP =
nullptr;
3923 case QPixelLayout::BPP32FPx4: {
3925 qt_memfill_template(dest + 1, dest[0], length - 1);
3928 case QPixelLayout::BPP16FPx4:
3929 case QPixelLayout::BPP64: {
3930 quint64 *dest =
reinterpret_cast<quint64 *>(rasterBuffer->scanLine(y)) + x;
3931 qt_memfill_template(dest + 1, dest[0], length - 1);
3934 case QPixelLayout::BPP32: {
3935 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(y)) + x;
3936 qt_memfill_template(dest + 1, dest[0], length - 1);
3939 case QPixelLayout::BPP24: {
3940 quint24 *dest =
reinterpret_cast<
quint24 *>(rasterBuffer->scanLine(y)) + x;
3941 qt_memfill_template(dest + 1, dest[0], length - 1);
3944 case QPixelLayout::BPP16: {
3945 quint16 *dest =
reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
3946 qt_memfill_template(dest + 1, dest[0], length - 1);
3949 case QPixelLayout::BPP8: {
3950 uchar *dest = rasterBuffer->scanLine(y) + x;
3951 memset(dest + 1, dest[0], length - 1);
3962#if QT_CONFIG(qtgui_threadpool)
3963#define QT_THREAD_PARALLEL_FILLS(function)
3964 const int segments = (count + 32
) / 64
;
3965 QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool();
3966 if (segments > 1
&& qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8
3967 && threadPool && !threadPool->contains(QThread::currentThread())) {
3968 QSemaphore semaphore;
3970 for (int i = 0
; i < segments; ++i) {
3971 int cn = (count - c) / (segments - i);
3972 threadPool->start([&, c, cn]() {
3973 function(c, c + cn);
3974 semaphore.release(1
);
3978 semaphore.acquire(segments);
3982#define QT_THREAD_PARALLEL_FILLS(function) function(0
, count)
3988 const Operator op = getOperator(data,
nullptr, 0);
3989 const uint color = data->solidColor.rgba();
3990 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
3991 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
3993 auto function = [=] (
int cStart,
int cEnd) {
3994 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
3995 for (
int c = cStart; c < cEnd; ++c) {
3997 int length = spans[c].len;
3998 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore) {
4001 spanfill_from_first(data
->rasterBuffer, bpp, x, spans[c].y, length);
4007 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4008 op.funcSolid(dest, l, color, spans[c].coverage);
4010 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4023 const Operator op = getOperator(data,
nullptr, 0);
4024 const uint color = data->solidColor.rgba();
4026 if (op.mode == QPainter::CompositionMode_Source) {
4029 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans->y)) + spans->x;
4030 if (spans->coverage == 255) {
4031 qt_memfill(target, color, spans->len);
4033 }
else if (spans->len > 16) {
4034 op.funcSolid(target, spans->len, color, spans->coverage);
4037 uint c = BYTE_MUL(color, spans->coverage);
4038 int ialpha = 255 - spans->coverage;
4039 for (
int i = 0; i < spans->len; ++i)
4040 target[i] = c + BYTE_MUL(target[i], ialpha);
4046 const auto funcSolid = op.funcSolid;
4047 auto function = [=] (
int cStart,
int cEnd) {
4048 for (
int c = cStart; c < cEnd; ++c) {
4049 uint *target = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + spans[c].x;
4050 funcSolid(target, spans[c].len, color, spans[c].coverage);
4058#if QT_CONFIG(raster_64bit)
4059 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4060 const Operator op = getOperator(data,
nullptr, 0);
4061 if (!op.funcSolid64) {
4062 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit");
4063 return blend_color_generic(count, spans, userData);
4066 const QRgba64 color = data->solidColor.rgba64();
4067 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4068 const QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4070 auto function = [=, &op] (
int cStart,
int cEnd)
4072 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4073 for (
int c = cStart; c < cEnd; ++c) {
4075 int length = spans[c].len;
4076 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStore64) {
4078 op.destStore64(data->rasterBuffer, x, spans[c].y, &color, 1);
4079 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4084 int l = qMin(BufferSize, length);
4085 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4086 op.funcSolid64(dest, l, color, spans[c].coverage);
4088 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4094 QT_THREAD_PARALLEL_FILLS(function);
4096 blend_color_generic(count, spans, userData);
4102#if QT_CONFIG(raster_fp)
4103 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4104 const Operator op = getOperator(data,
nullptr, 0);
4105 if (!op.funcSolidFP || !op.destFetchFP) {
4106 qCDebug(lcQtGuiDrawHelper,
"blend_color_generic_fp: unsupported 4xF16 blend attempted, falling back to 32-bit");
4107 return blend_color_generic(count, spans, userData);
4111 data->solidColor.getRgbF(&r, &g, &b, &a);
4112 const QRgbaFloat32 color{r, g, b, a};
4113 const bool solidFill = op.mode == QPainter::CompositionMode_Source;
4114 QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
4116 auto function = [=, &op] (
int cStart,
int cEnd)
4118 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4119 for (
int c = cStart; c < cEnd; ++c) {
4121 int length = spans[c].len;
4122 if (solidFill && bpp >= QPixelLayout::BPP8 && spans[c].coverage == 255 && length && op.destStoreFP) {
4124 op.destStoreFP(data->rasterBuffer, x, spans[c].y, &color, 1);
4125 spanfill_from_first(data->rasterBuffer, bpp, x, spans[c].y, length);
4130 int l = qMin(BufferSize, length);
4131 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4132 op.funcSolidFP(dest, l, color, spans[c].coverage);
4134 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4140 QT_THREAD_PARALLEL_FILLS(function);
4142 blend_color_generic(count, spans, userData);
4146template <
typename T>
4149 const int const_alpha = (data->type ==
QSpanData::Texture) ? data->texture.const_alpha : 256;
4150 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256;
4152 auto function = [=, &op] (
int cStart,
int cEnd)
4154 T Q_DECL_UNINITIALIZED handler(data, op);
4156 for (
int c = cStart; c < cEnd;) {
4157 if (!spans[c].len) {
4162 const int y = spans[c].y;
4163 int right = x + spans[c].len;
4164 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4167 for (
int i = c + 1; i < cEnd && spans[i].y == y && spans[i].x == right && fetchDest == (!solidSource || spans[i].coverage < 255); ++i)
4168 right += spans[i].len;
4169 int length = right - x;
4175 int process_length = l;
4178 const auto *src = handler.fetch(process_x, y, process_length, fetchDest);
4181 if (x == spans[c].x)
4182 coverage = (spans[c].coverage * const_alpha) >> 8;
4184 int right = spans[c].x + spans[c].len;
4185 int len = qMin(l, right - x);
4187 handler.process(x, y, len, coverage, src, offset);
4196 handler.store(process_x, y, process_length);
4220 const uint *
fetch(
int x,
int y,
int len,
bool fetchDest)
4222 if (fetchDest || op.destFetch == destFetchARGB32P)
4229 void process(
int,
int,
int len,
int coverage,
const uint *src,
int offset)
4231 op.func(
dest + offset, src + offset, len, coverage);
4241#if QT_CONFIG(raster_64bit)
4242class BlendSrcGenericRGB64 :
public QBlendBase
4245 QRgba64 *dest =
nullptr;
4246 alignas(16) QRgba64 buffer[BufferSize];
4247 alignas(16) QRgba64 src_buffer[BufferSize];
4248 BlendSrcGenericRGB64(
const QSpanData *d,
const Operator &o)
4253 bool isSupported()
const
4255 return op.func64 && op.destFetch64;
4258 const QRgba64 *fetch(
int x,
int y,
int len,
bool fetchDest)
4260 if (fetchDest || op.destFetch64 == destFetchRGB64)
4261 dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len);
4264 return op.srcFetch64(src_buffer, &op, data, y, x, len);
4267 void process(
int,
int,
int len,
int coverage,
const QRgba64 *src,
int offset)
4269 op.func64(dest + offset, src + offset, len, coverage);
4272 void store(
int x,
int y,
int len)
4275 op.destStore64(data->rasterBuffer, x, y, dest, len);
4280#if QT_CONFIG(raster_fp)
4281class BlendSrcGenericRGBFP :
public QBlendBase
4284 QRgbaFloat32 *dest =
nullptr;
4285 alignas(16) QRgbaFloat32 buffer[BufferSize];
4286 alignas(16) QRgbaFloat32 src_buffer[BufferSize];
4287 BlendSrcGenericRGBFP(
const QSpanData *d,
const Operator &o)
4292 bool isSupported()
const
4294 return op.funcFP && op.destFetchFP && op.srcFetchFP;
4297 const QRgbaFloat32 *fetch(
int x,
int y,
int len,
bool fetchDest)
4299 if (fetchDest || op.destFetchFP == destFetchRGBFP)
4300 dest = op.destFetchFP(buffer, data->rasterBuffer, x, y, len);
4303 return op.srcFetchFP(src_buffer, &op, data, y, x, len);
4306 void process(
int,
int,
int len,
int coverage,
const QRgbaFloat32 *src,
int offset)
4308 op.funcFP(dest + offset, src + offset, len, coverage);
4311 void store(
int x,
int y,
int len)
4314 op.destStoreFP(data->rasterBuffer, x, y, dest, len);
4322 const Operator op = getOperator(data,
nullptr, 0);
4326#if QT_CONFIG(raster_64bit)
4327static void blend_src_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4329 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4330 const Operator op = getOperator(data,
nullptr, 0);
4331 if (op.func64 && op.destFetch64) {
4332 handleSpans<BlendSrcGenericRGB64>(count, spans, data, op);
4334 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4335 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4340#if QT_CONFIG(raster_fp)
4341static void blend_src_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4343 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4344 const Operator op = getOperator(data, spans, count);
4345 if (op.funcFP && op.destFetchFP && op.srcFetchFP) {
4346 handleSpans<BlendSrcGenericRGBFP>(count, spans, data, op);
4348 qCDebug(lcQtGuiDrawHelper,
"blend_src_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4349 handleSpans<BlendSrcGeneric>(count, spans, data, op);
4358 const Operator op = getOperator(data, spans, count);
4360 const int image_width = data->texture.width;
4361 const int image_height = data->texture.height;
4362 const int const_alpha = data->texture.const_alpha;
4363 const int xoff = -qRound(-data->dx);
4364 const int yoff = -qRound(-data->dy);
4365 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch != destFetchARGB32P;
4367 auto function = [=, &op] (
int cStart,
int cEnd)
4369 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4370 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4371 for (
int c = cStart; c < cEnd; ++c) {
4375 int length = spans[c].len;
4377 int sy = yoff + spans[c].y;
4378 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4379 if (sy >= 0 && sy < image_height && sx < image_width) {
4385 if (sx + length > image_width)
4386 length = image_width - sx;
4388 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4391 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4392 uint *dest = fetchDest ? op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4393 op.func(dest, src, l, coverage);
4395 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4407#if QT_CONFIG(raster_64bit)
4408static void blend_untransformed_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4410 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4412 const Operator op = getOperator(data, spans, count);
4414 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4415 return blend_untransformed_generic(count, spans, userData);
4418 const int image_width = data->texture.width;
4419 const int image_height = data->texture.height;
4420 const int const_alpha = data->texture.const_alpha;
4421 const int xoff = -qRound(-data->dx);
4422 const int yoff = -qRound(-data->dy);
4423 const bool solidSource = op.mode == QPainter::CompositionMode_Source && const_alpha == 256 && op.destFetch64 != destFetchRGB64;
4425 auto function = [=, &op] (
int cStart,
int cEnd)
4427 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4428 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4429 for (
int c = cStart; c < cEnd; ++c) {
4433 int length = spans[c].len;
4435 int sy = yoff + spans[c].y;
4436 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4437 if (sy >= 0 && sy < image_height && sx < image_width) {
4443 if (sx + length > image_width)
4444 length = image_width - sx;
4446 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4448 int l = qMin(BufferSize, length);
4449 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4450 QRgba64 *dest = fetchDest ? op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4451 op.func64(dest, src, l, coverage);
4453 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4462 QT_THREAD_PARALLEL_FILLS(function);
4466#if QT_CONFIG(raster_fp)
4467static void blend_untransformed_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4469 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4471 const Operator op = getOperator(data, spans, count);
4473 qCDebug(lcQtGuiDrawHelper,
"blend_untransformed_generic_rgbaf16: unsupported 4xFP16 blend attempted, falling back to 32-bit");
4474 return blend_untransformed_generic(count, spans, userData);
4477 const int image_width = data->texture.width;
4478 const int image_height = data->texture.height;
4479 const int xoff = -qRound(-data->dx);
4480 const int yoff = -qRound(-data->dy);
4481 const bool solidSource = op.mode == QPainter::CompositionMode_Source && data->texture.const_alpha == 256 && op.destFetchFP != destFetchRGBFP;
4483 auto function = [=, &op] (
int cStart,
int cEnd)
4485 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4486 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4487 for (
int c = cStart; c < cEnd; ++c) {
4491 int length = spans[c].len;
4493 int sy = yoff + spans[c].y;
4494 const bool fetchDest = !solidSource || spans[c].coverage < 255;
4495 if (sy >= 0 && sy < image_height && sx < image_width) {
4501 if (sx + length > image_width)
4502 length = image_width - sx;
4504 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4506 int l = qMin(BufferSize, length);
4507 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4508 QRgbaFloat32 *dest = fetchDest ? op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l) : buffer;
4509 op.funcFP(dest, src, l, coverage);
4511 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4520 QT_THREAD_PARALLEL_FILLS(function);
4527 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4528 && data->texture.format != QImage::Format_RGB32) {
4529 blend_untransformed_generic(count, spans, userData);
4533 const Operator op = getOperator(data, spans, count);
4535 const int image_width = data->texture.width;
4536 const int image_height = data->texture.height;
4537 const int const_alpha = data->texture.const_alpha;
4538 const int xoff = -qRound(-data->dx);
4539 const int yoff = -qRound(-data->dy);
4541 auto function = [=, &op] (
int cStart,
int cEnd)
4543 for (
int c = cStart; c < cEnd; ++c) {
4547 int length = spans[c].len;
4549 int sy = yoff + spans[c].y;
4550 if (sy >= 0 && sy < image_height && sx < image_width) {
4556 if (sx + length > image_width)
4557 length = image_width - sx;
4559 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4560 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4561 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4562 op.func(dest, src, length, coverage);
4571 quint16 y, quint8 b)
4573 quint16 t = ((((x & 0x07e0) * a) + ((y & 0x07e0) * b)) >> 5) & 0x07e0;
4574 t |= ((((x & 0xf81f) * a) + ((y & 0xf81f) * b)) >> 5) & 0xf81f;
4580 quint32 y, quint8 b)
4583 t = ((((x & 0xf81f07e0) >> 5) * a) + (((y & 0xf81f07e0) >> 5) * b)) & 0xf81f07e0;
4584 t |= ((((x & 0x07e0f81f) * a) + ((y & 0x07e0f81f) * b)) >> 5) & 0x07e0f81f;
4592 const quint8 ialpha)
4594 const int dstAlign = ((quintptr)dest) & 0x3;
4596 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4601 const int srcAlign = ((quintptr)src) & 0x3;
4602 int length32 = length >> 1;
4603 if (length32 && srcAlign == 0) {
4604 while (length32--) {
4605 const quint32 *src32 =
reinterpret_cast<
const quint32*>(src);
4606 quint32 *dest32 =
reinterpret_cast<quint32*>(dest);
4607 *dest32 = interpolate_pixel_rgb16x2_255(*src32, alpha,
4615 *dest = interpolate_pixel_rgb16_255(*src, alpha, *dest, ialpha);
4624 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4626 if (data->texture.format != QImage::Format_RGB16
4627 || (mode != QPainter::CompositionMode_SourceOver
4628 && mode != QPainter::CompositionMode_Source))
4630 blend_untransformed_generic(count, spans, userData);
4634 const int image_width = data->texture.width;
4635 const int image_height = data->texture.height;
4636 int xoff = -qRound(-data->dx);
4637 int yoff = -qRound(-data->dy);
4639 auto function = [=](
int cStart,
int cEnd)
4641 for (
int c = cStart; c < cEnd; ++c) {
4644 const quint8 coverage = (data->texture.const_alpha * spans[c].coverage) >> 8;
4649 int length = spans[c].len;
4651 int sy = yoff + spans[c].y;
4652 if (sy >= 0 && sy < image_height && sx < image_width) {
4658 if (sx + length > image_width)
4659 length = image_width - sx;
4661 quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans[c].y) + x;
4662 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
4663 if (coverage == 255) {
4664 memcpy(dest, src, length *
sizeof(quint16));
4666 const quint8 alpha = (coverage + 1) >> 3;
4667 const quint8 ialpha = 0x20 - alpha;
4669 blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha);
4682 const Operator op = getOperator(data, spans, count);
4684 const int image_width = data->texture.width;
4685 const int image_height = data->texture.height;
4686 const int const_alpha = data->texture.const_alpha;
4687 int xoff = -qRound(-data->dx) % image_width;
4688 int yoff = -qRound(-data->dy) % image_height;
4691 xoff += image_width;
4693 yoff += image_height;
4695 auto function = [=, &op](
int cStart,
int cEnd)
4697 alignas(16) Q_DECL_UNINITIALIZED uint buffer[BufferSize];
4698 alignas(16) Q_DECL_UNINITIALIZED uint src_buffer[BufferSize];
4699 for (
int c = cStart; c < cEnd; ++c) {
4701 int length = spans[c].len;
4702 int sx = (xoff + spans[c].x) % image_width;
4703 int sy = (spans[c].y + yoff) % image_height;
4709 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4711 int l = qMin(image_width - sx, length);
4714 const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
4715 uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans[c].y, l);
4716 op.func(dest, src, l, coverage);
4718 op.destStore(data->rasterBuffer, x, spans[c].y, dest, l);
4722 if (sx >= image_width)
4730#if QT_CONFIG(raster_64bit)
4731static void blend_tiled_generic_rgb64(
int count,
const QT_FT_Span *spans,
void *userData)
4733 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4735 const Operator op = getOperator(data, spans, count);
4737 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
4738 return blend_tiled_generic(count, spans, userData);
4741 const int image_width = data->texture.width;
4742 const int image_height = data->texture.height;
4743 int xoff = -qRound(-data->dx) % image_width;
4744 int yoff = -qRound(-data->dy) % image_height;
4747 xoff += image_width;
4749 yoff += image_height;
4751 bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
4752 bool isBpp64 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP64;
4753 if (op.destFetch64 == destFetch64Undefined && image_width <= BufferSize && (isBpp32 || isBpp64)) {
4754 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4759 int length = spans->len;
4760 int sx = (xoff + spans->x) % image_width;
4761 int sy = (spans->y + yoff) % image_height;
4767 int sl = qMin(image_width, length);
4768 if (sx > 0 && sl > 0) {
4769 int l = qMin(image_width - sx, sl);
4770 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4771 op.destStore64(data->rasterBuffer, x, y, src, l);
4775 if (sx >= image_width)
4780 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, sl);
4781 op.destStore64(data->rasterBuffer, x, y, src, sl);
4785 if (sx >= image_width)
4789 uint *dest =
reinterpret_cast<uint *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4790 for (
int i = image_width; i < length; ++i)
4791 dest[i] = dest[i - image_width];
4793 quint64 *dest =
reinterpret_cast<quint64 *>(data->rasterBuffer->scanLine(y)) + x - image_width;
4794 for (
int i = image_width; i < length; ++i)
4795 dest[i] = dest[i - image_width];
4802 auto function = [=, &op](
int cStart,
int cEnd)
4804 alignas(16) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
4805 alignas(16) Q_DECL_UNINITIALIZED QRgba64 src_buffer[BufferSize];
4806 for (
int c = cStart; c < cEnd; ++c) {
4808 int length = spans[c].len;
4809 int sx = (xoff + spans[c].x) % image_width;
4810 int sy = (spans[c].y + yoff) % image_height;
4816 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4818 int l = qMin(image_width - sx, length);
4821 const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l);
4822 QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans[c].y, l);
4823 op.func64(dest, src, l, coverage);
4825 op.destStore64(data->rasterBuffer, x, spans[c].y, dest, l);
4829 if (sx >= image_width)
4834 QT_THREAD_PARALLEL_FILLS(function);
4838#if QT_CONFIG(raster_fp)
4839static void blend_tiled_generic_fp(
int count,
const QT_FT_Span *spans,
void *userData)
4841 QSpanData *data =
reinterpret_cast<QSpanData *>(userData);
4843 const Operator op = getOperator(data, spans, count);
4845 qCDebug(lcQtGuiDrawHelper,
"blend_tiled_generic_fp: unsupported 4xFP blend attempted, falling back to 32-bit");
4846 return blend_tiled_generic(count, spans, userData);
4849 const int image_width = data->texture.width;
4850 const int image_height = data->texture.height;
4851 int xoff = -qRound(-data->dx) % image_width;
4852 int yoff = -qRound(-data->dy) % image_height;
4855 xoff += image_width;
4857 yoff += image_height;
4861 auto function = [=, &op](
int cStart,
int cEnd)
4863 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 buffer[BufferSize];
4864 alignas(16) Q_DECL_UNINITIALIZED QRgbaFloat32 src_buffer[BufferSize];
4865 for (
int c = cStart; c < cEnd; ++c) {
4867 int length = spans[c].len;
4868 int sx = (xoff + spans[c].x) % image_width;
4869 int sy = (spans[c].y + yoff) % image_height;
4875 const int coverage = (spans[c].coverage * data->texture.const_alpha) >> 8;
4877 int l = qMin(image_width - sx, length);
4880 const QRgbaFloat32 *src = op.srcFetchFP(src_buffer, &op, data, sy, sx, l);
4881 QRgbaFloat32 *dest = op.destFetchFP(buffer, data->rasterBuffer, x, spans[c].y, l);
4882 op.funcFP(dest, src, l, coverage);
4884 op.destStoreFP(data->rasterBuffer, x, spans[c].y, dest, l);
4888 if (sx >= image_width)
4893 QT_THREAD_PARALLEL_FILLS(function);
4900 if (data->texture.format != QImage::Format_ARGB32_Premultiplied
4901 && data->texture.format != QImage::Format_RGB32) {
4902 blend_tiled_generic(count, spans, userData);
4906 const Operator op = getOperator(data, spans, count);
4908 const int image_width = data->texture.width;
4909 const int image_height = data->texture.height;
4910 int xoff = -qRound(-data->dx) % image_width;
4911 int yoff = -qRound(-data->dy) % image_height;
4914 xoff += image_width;
4916 yoff += image_height;
4917 const auto func = op.func;
4918 const int const_alpha = data->texture.const_alpha;
4920 auto function = [=] (
int cStart,
int cEnd) {
4921 for (
int c = cStart; c < cEnd; ++c) {
4923 int length = spans[c].len;
4924 int sx = (xoff + spans[c].x) % image_width;
4925 int sy = (spans[c].y + yoff) % image_height;
4931 const int coverage = (spans[c].coverage * const_alpha) >> 8;
4933 int l = qMin(image_width - sx, length);
4936 const uint *src = (
const uint *)data->texture.scanLine(sy) + sx;
4937 uint *dest = ((uint *)data
->rasterBuffer->scanLine(spans[c].y)) + x;
4938 func(dest, src, l, coverage);
4942 if (sx >= image_width)
4953 QPainter::CompositionMode mode = data
->rasterBuffer->compositionMode;
4955 if (data->texture.format != QImage::Format_RGB16
4956 || (mode != QPainter::CompositionMode_SourceOver
4957 && mode != QPainter::CompositionMode_Source))
4959 blend_tiled_generic(count, spans, userData);
4963 const int image_width = data->texture.width;
4964 const int image_height = data->texture.height;
4965 int xoff = -qRound(-data->dx) % image_width;
4966 int yoff = -qRound(-data->dy) % image_height;
4969 xoff += image_width;
4971 yoff += image_height;
4973 const int const_alpha = data->texture.const_alpha;
4974 auto function = [=] (
int cStart,
int cEnd) {
4975 for (
int c = cStart; c < cEnd; ++c) {
4976 const quint8 coverage = (const_alpha * spans[c].coverage) >> 8;
4981 int length = spans[c].len;
4982 int sx = (xoff + spans[c].x) % image_width;
4983 int sy = (spans[c].y + yoff) % image_height;
4989 if (coverage == 255) {
4991 length = qMin(image_width,length);
4994 int l = qMin(image_width - sx, length);
4997 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + tx;
4998 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
4999 memcpy(dest, src, l *
sizeof(quint16));
5003 if (sx >= image_width)
5013 int copy_image_width = qMin(image_width,
int(spans[c].len));
5014 length = spans[c].len - copy_image_width;
5015 quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5016 quint16 *dest = src + copy_image_width;
5017 while (copy_image_width < length) {
5018 memcpy(dest, src, copy_image_width *
sizeof(quint16));
5019 dest += copy_image_width;
5020 length -= copy_image_width;
5021 copy_image_width *= 2;
5024 memcpy(dest, src, length *
sizeof(quint16));
5026 const quint8 alpha = (coverage + 1) >> 3;
5027 const quint8 ialpha = 0x20 - alpha;
5030 int l = qMin(image_width - sx, length);
5033 quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans[c].y)) + x;
5034 const quint16 *src = (
const quint16 *)data->texture.scanLine(sy) + sx;
5035 blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
5039 if (sx >= image_width)
5051 blend_untransformed_argb,
5060 blend_untransformed_rgb565,
5069 blend_untransformed_generic,
5070 blend_tiled_generic,
5077#if QT_CONFIG(raster_64bit)
5078static const ProcessSpans processTextureSpansGeneric64[NBlendTypes] = {
5079 blend_untransformed_generic_rgb64,
5080 blend_tiled_generic_rgb64,
5081 blend_src_generic_rgb64,
5082 blend_src_generic_rgb64,
5083 blend_src_generic_rgb64,
5084 blend_src_generic_rgb64
5088#if QT_CONFIG(raster_fp)
5089static const ProcessSpans processTextureSpansGenericFP[NBlendTypes] = {
5090 blend_untransformed_generic_fp,
5091 blend_tiled_generic_fp,
5092 blend_src_generic_fp,
5093 blend_src_generic_fp,
5094 blend_src_generic_fp,
5095 blend_src_generic_fp
5104 case QImage::Format_Invalid:
5105 Q_UNREACHABLE_RETURN();
5106 case QImage::Format_ARGB32_Premultiplied:
5109 case QImage::Format_RGB16:
5112#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5113 case QImage::Format_ARGB32:
5114 case QImage::Format_RGBA8888:
5116 case QImage::Format_BGR30:
5117 case QImage::Format_A2BGR30_Premultiplied:
5118 case QImage::Format_RGB30:
5119 case QImage::Format_A2RGB30_Premultiplied:
5120 case QImage::Format_RGBX64:
5121 case QImage::Format_RGBA64:
5122 case QImage::Format_RGBA64_Premultiplied:
5123 case QImage::Format_Grayscale16:
5124#if !QT_CONFIG(raster_fp)
5125 case QImage::Format_RGBX16FPx4:
5126 case QImage::Format_RGBA16FPx4:
5127 case QImage::Format_RGBA16FPx4_Premultiplied:
5128 case QImage::Format_RGBX32FPx4:
5129 case QImage::Format_RGBA32FPx4:
5130 case QImage::Format_RGBA32FPx4_Premultiplied:
5132#if QT_CONFIG(raster_64bit)
5133 proc = processTextureSpansGeneric64[blendType];
5136#if QT_CONFIG(raster_fp)
5137 case QImage::Format_RGBX16FPx4:
5138 case QImage::Format_RGBA16FPx4:
5139 case QImage::Format_RGBA16FPx4_Premultiplied:
5140 case QImage::Format_RGBX32FPx4:
5141 case QImage::Format_RGBA32FPx4:
5142 case QImage::Format_RGBA32FPx4_Premultiplied:
5143 proc = processTextureSpansGenericFP[blendType];
5150 proc(count, spans, userData);
5156 int *pyinc,
int *poff)
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5172 qreal ryinc = linear.dy * data->m22 * gss *
FIXPT_SIZE;
5173 qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss *
FIXPT_SIZE;
5174 const int limit =
std::numeric_limits<
int>::max() -
FIXPT_SIZE;
5175 if (count && (
std::fabs(ryinc) < limit) && (
std::fabs(roff) < limit)
5176 && (
std::fabs(ryinc * spans->y + roff) < limit)
5177 && (
std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) {
5178 *pyinc =
int(ryinc);
5190 getLinearGradientValues(&linear, data);
5192 CompositionFunctionSolid funcSolid =
5195 int yinc(0), off(0);
5196 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5203 quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
5205 qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5207 funcSolid(dst, spans->len, color, spans->coverage);
5219 getLinearGradientValues(&linear, data);
5221 int yinc(0), off(0);
5222 if (!calculate_fixed_gradient_factors(count, spans, data, linear, &yinc, &off))
5228#if QT_CONFIG(raster_64bit)
5229 data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
5231 data->solidColor = qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
5233 blend_color(1, spans, userData);
5242 bool isVerticalGradient =
5243 data->txop <= QTransform::TxScale &&
5244 data->type == QSpanData::LinearGradient &&
5245 data->gradient.linear.end.x == data->gradient.linear.origin.x;
5247 case QImage::Format_Invalid:
5249 case QImage::Format_RGB32:
5250 case QImage::Format_ARGB32_Premultiplied:
5251 if (isVerticalGradient && blend_vertical_gradient_argb(count, spans, userData))
5253 return blend_src_generic(count, spans, userData);
5254#if defined(__SSE2__
) || defined(__ARM_NEON__) || defined(QT_COMPILER_SUPPORTS_LSX) || (Q_PROCESSOR_WORDSIZE == 8
)
5255 case QImage::Format_ARGB32:
5256 case QImage::Format_RGBA8888:
5258 case QImage::Format_BGR30:
5259 case QImage::Format_A2BGR30_Premultiplied:
5260 case QImage::Format_RGB30:
5261 case QImage::Format_A2RGB30_Premultiplied:
5262 case QImage::Format_RGBX64:
5263 case QImage::Format_RGBA64:
5264 case QImage::Format_RGBA64_Premultiplied:
5265#if !QT_CONFIG(raster_fp)
5266 case QImage::Format_RGBX16FPx4:
5267 case QImage::Format_RGBA16FPx4:
5268 case QImage::Format_RGBA16FPx4_Premultiplied:
5269 case QImage::Format_RGBX32FPx4:
5270 case QImage::Format_RGBA32FPx4:
5271 case QImage::Format_RGBA32FPx4_Premultiplied:
5273#if QT_CONFIG(raster_64bit)
5274 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData))
5276 return blend_src_generic_rgb64(count, spans, userData);
5278#if QT_CONFIG(raster_fp)
5279 case QImage::Format_RGBX16FPx4:
5280 case QImage::Format_RGBA16FPx4:
5281 case QImage::Format_RGBA16FPx4_Premultiplied:
5282 case QImage::Format_RGBX32FPx4:
5283 case QImage::Format_RGBA32FPx4:
5284 case QImage::Format_RGBA32FPx4_Premultiplied:
5285 if (isVerticalGradient && blend_vertical_gradient<blend_color_generic_fp>(count, spans, userData))
5287 return blend_src_generic_fp(count, spans, userData);
5290 if (isVerticalGradient && blend_vertical_gradient<
blend_color_generic>(count, spans, userData))
5292 return blend_src_generic(count, spans, userData);
5297template <
class DST>
static
5299 int x,
int y, DST color,
5301 int mapWidth,
int mapHeight,
int mapStride)
5303 DST *dest =
reinterpret_cast<DST *>(rasterBuffer->scanLine(y)) + x;
5304 const int destStride = rasterBuffer->stride<DST>();
5307 while (--mapHeight >= 0) {
5310 for (
int x = 0; x < mapWidth; x += 8) {
5311 uchar s = map[x >> 3];
5312 for (
int i = 0; i < 8; ++i) {
5317 qt_memfill(dest + x0, color, n);
5332 qt_memfill(dest + x0, color, n);
5337 while (--mapHeight >= 0) {
5340 for (uchar s = *map; s; s <<= 1) {
5344 qt_memfill(dest + x0, color, n);
5352 qt_memfill(dest + x0, color, n);
5360 int x,
int y,
const QRgba64 &color,
5362 int mapWidth,
int mapHeight,
int mapStride)
5364 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, color.toArgb32(),
5365 map, mapWidth, mapHeight, mapStride);
5369 int x,
int y,
const QRgba64 &color,
5371 int mapWidth,
int mapHeight,
int mapStride)
5373 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color.toArgb32()),
5374 map, mapWidth, mapHeight, mapStride);
5377template<QtPixelOrder PixelOrder>
5379 int x,
int y,
const QRgba64 &color,
5381 int mapWidth,
int mapHeight,
int mapStride)
5383 qt_bitmapblit_template<quint32>(rasterBuffer, x, y, qConvertRgb64ToRgb30<PixelOrder>(color),
5384 map, mapWidth, mapHeight, mapStride);
5388 int x,
int y,
const QRgba64 &color,
5390 int mapWidth,
int mapHeight,
int mapStride)
5392 qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color.toRgb16(),
5393 map, mapWidth, mapHeight, mapStride);
5396static inline void grayBlendPixel(quint32 *dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5399 const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5401 QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
5403 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5406static inline void alphamapblend_argb32(quint32 *dst,
int coverage, QRgba64 srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5408 if (coverage == 0) {
5410 }
else if (coverage == 255 || !colorProfile) {
5411 blend_pixel(*dst, src, coverage);
5412 }
else if (*dst < 0xff000000) {
5414 blend_pixel(*dst, src, coverage);
5415 }
else if (src >= 0xff000000) {
5416 grayBlendPixel(dst, coverage, srcLinear, colorProfile);
5420 blend_pixel(s, src);
5422 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5423 grayBlendPixel(dst, coverage, s64, colorProfile);
5427#if QT_CONFIG(raster_64bit)
5429static inline void grayBlendPixel(QRgba64 &dst,
int coverage, QRgba64 srcLinear,
const QColorTrcLut *colorProfile)
5432 QRgba64 dstColor = dst;
5434 if (dstColor.isOpaque())
5435 dstColor = colorProfile->toLinear(dstColor);
5436 else if (!dstColor.isTransparent())
5437 dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
5440 blend_pixel(dstColor, srcLinear, coverage);
5443 if (dstColor.isOpaque())
5444 dstColor = colorProfile->fromLinear(dstColor);
5445 else if (!dstColor.isTransparent())
5446 dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
5451static inline void alphamapblend_generic(
int coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5453 if (coverage == 0) {
5455 }
else if (coverage == 255) {
5456 blend_pixel(dest[x], src);
5457 }
else if (src.isOpaque()) {
5458 grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5461 QRgba64 s = dest[x];
5462 blend_pixel(s, src);
5465 s = colorProfile->toLinear(s);
5466 grayBlendPixel(dest[x], coverage, s, colorProfile);
5470static void qt_alphamapblit_generic_oneline(
const uchar *map,
int len,
5471 const QRgba64 srcColor, QRgba64 *dest,
5472 const QRgba64 color,
5473 const QColorTrcLut *colorProfile)
5475 for (
int j = 0; j < len; ++j)
5476 alphamapblend_generic(map[j], dest, j, srcColor, color, colorProfile);
5479static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
5480 int x,
int y,
const QRgba64 &color,
5482 int mapWidth,
int mapHeight,
int mapStride,
5483 const QClipData *clip,
bool useGammaCorrection)
5485 if (color.isTransparent())
5488 const QColorTrcLut *colorProfile =
nullptr;
5490 if (useGammaCorrection)
5491 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5493 QRgba64 srcColor = color;
5494 if (colorProfile && color.isOpaque())
5495 srcColor = colorProfile->toLinear(srcColor);
5497 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5498 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5499 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5502 for (
int ly = 0; ly < mapHeight; ++ly) {
5504 int length = mapWidth;
5505 while (length > 0) {
5506 int l = qMin(BufferSize, length);
5508 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5509 qt_alphamapblit_generic_oneline(map + i - x, l,
5510 srcColor, dest, color,
5513 destStore64(rasterBuffer, i, y + ly, dest, l);
5520 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5522 int top = qMax(y, 0);
5523 map += (top - y) * mapStride;
5525 const_cast<QClipData *>(clip)->initialize();
5526 for (
int yp = top; yp<bottom; ++yp) {
5527 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5529 for (
int i=0; i<line.count; ++i) {
5530 const QT_FT_Span &clip = line.spans[i];
5532 int start = qMax<
int>(x, clip.x);
5533 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5536 Q_ASSERT(end - start <= BufferSize);
5537 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5538 qt_alphamapblit_generic_oneline(map + start - x, end - start,
5539 srcColor, dest, color,
5542 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5550 int x,
int y,
const QRgba64 &color,
5552 int mapWidth,
int mapHeight,
int mapStride,
5553 const QClipData *clip,
bool useGammaCorrection)
5555 if (color.isTransparent())
5558 const quint32 c = color.toArgb32();
5560 const QColorTrcLut *colorProfile =
nullptr;
5562 if (useGammaCorrection)
5563 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5565 QRgba64 srcColor = color;
5566 if (colorProfile && color.isOpaque())
5567 srcColor = colorProfile->toLinear(srcColor);
5570 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
5571 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
5574 for (
int ly = 0; ly < mapHeight; ++ly) {
5576 int length = mapWidth;
5577 while (length > 0) {
5579 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
5580 for (
int j=0; j < l; ++j) {
5581 const int coverage = map[j + (i - x)];
5582 alphamapblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
5585 destStore(rasterBuffer, i, y + ly, dest, l);
5592 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5594 int top = qMax(y, 0);
5595 map += (top - y) * mapStride;
5597 const_cast<
QClipData *>(clip)->initialize();
5598 for (
int yp = top; yp<bottom; ++yp) {
5599 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5601 for (
int i=0; i<line.count; ++i) {
5602 const QT_FT_Span &clip = line.spans[i];
5604 int start = qMax<
int>(x, clip.x);
5605 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5609 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
5611 for (
int xp=start; xp<end; ++xp) {
5612 const int coverage = map[xp - x];
5613 alphamapblend_argb32(dest + xp - x, coverage, srcColor, color, colorProfile);
5616 destStore(rasterBuffer, start, clip.y, dest, end - start);
5626 if (coverage == 0) {
5628 }
else if (coverage == 255) {
5631 dest[x] = BYTE_MUL_RGB16(srcColor, coverage)
5632 + BYTE_MUL_RGB16(dest[x], 255 - coverage);
5637 int x,
int y,
const QRgba64 &color,
5639 int mapWidth,
int mapHeight,
int mapStride,
5640 const QClipData *clip,
bool useGammaCorrection)
5642 if (useGammaCorrection || !color.isOpaque()) {
5643 qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
5647 const quint16 c = color.toRgb16();
5650 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
5651 const int destStride = rasterBuffer->stride<quint16>();
5652 while (--mapHeight >= 0) {
5653 for (
int i = 0; i < mapWidth; ++i)
5654 alphamapblend_quint16(map[i], dest, i, c);
5659 int top = qMax(y, 0);
5660 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5661 map += (top - y) * mapStride;
5663 const_cast<
QClipData *>(clip)->initialize();
5664 for (
int yp = top; yp<bottom; ++yp) {
5665 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5667 quint16 *dest =
reinterpret_cast<quint16*>(rasterBuffer->scanLine(yp));
5669 for (
int i=0; i<line.count; ++i) {
5670 const QT_FT_Span &clip = line.spans[i];
5672 int start = qMax<
int>(x, clip.x);
5673 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5675 for (
int xp=start; xp<end; ++xp)
5676 alphamapblend_quint16(map[xp - x], dest, xp, c);
5684 int mapWidth,
const QRgba64 &srcColor,
5685 quint32 *dest,
const quint32 c,
5686 const QColorTrcLut *colorProfile)
5688 for (
int i = 0; i < mapWidth; ++i)
5689 alphamapblend_argb32(dest + i, map[i], srcColor, c, colorProfile);
5693 int x,
int y,
const QRgba64 &color,
5695 int mapWidth,
int mapHeight,
int mapStride,
5696 const QClipData *clip,
bool useGammaCorrection)
5698 const quint32 c = color.toArgb32();
5699 const int destStride = rasterBuffer->stride<quint32>();
5701 if (color.isTransparent())
5704 const QColorTrcLut *colorProfile =
nullptr;
5706 if (useGammaCorrection)
5707 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5709 QRgba64 srcColor = color;
5710 if (colorProfile && color.isOpaque())
5711 srcColor = colorProfile->toLinear(srcColor);
5714 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
5715 while (--mapHeight >= 0) {
5716 qt_alphamapblit_argb32_oneline(map, mapWidth, srcColor, dest, c, colorProfile);
5721 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5723 int top = qMax(y, 0);
5724 map += (top - y) * mapStride;
5726 const_cast<
QClipData *>(clip)->initialize();
5727 for (
int yp = top; yp<bottom; ++yp) {
5728 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5730 quint32 *dest =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
5732 for (
int i=0; i<line.count; ++i) {
5733 const QT_FT_Span &clip = line.spans[i];
5734 int start = qMax<
int>(x, clip.x);
5735 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5736 qt_alphamapblit_argb32_oneline(map + start - x, end - start, srcColor, dest + start, c, colorProfile);
5743#if QT_CONFIG(raster_64bit)
5744static void qt_alphamapblit_nonpremul_argb32(QRasterBuffer *rasterBuffer,
5745 int x,
int y,
const QRgba64 &color,
5747 int mapWidth,
int mapHeight,
int mapStride,
5748 const QClipData *clip,
bool useGammaCorrection)
5751 return qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight,
5752 mapStride, clip, useGammaCorrection);
5754 if (color.isTransparent())
5757 const QColorTrcLut *colorProfile =
nullptr;
5759 if (useGammaCorrection)
5760 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
5762 const quint32 c = color.toArgb32();
5763 QRgba64 srcColor = color;
5764 if (colorProfile && color.isOpaque())
5765 srcColor = colorProfile->toLinear(srcColor);
5767 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5768 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5769 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5771 for (
int ly = 0; ly < mapHeight; ++ly) {
5772 bool dstFullyOpaque =
true;
5774 int length = mapWidth;
5775 while (length > 0) {
5776 int l = qMin(BufferSize, length);
5777 quint32 *dest =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y + ly)) + i;
5778 for (
int j = 0; j < l && dstFullyOpaque; ++j)
5779 dstFullyOpaque = (dest[j] & 0xff000000) == 0xff000000;
5780 if (dstFullyOpaque) {
5782 qt_alphamapblit_argb32_oneline(map + i - x, l, srcColor, dest, c, colorProfile);
5785 QRgba64 *dest64 = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5786 qt_alphamapblit_generic_oneline(map + i - x, l,
5787 srcColor, dest64, color,
5790 destStore64(rasterBuffer, i, y + ly, dest64, l);
5802 return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
5805static inline void rgbBlendPixel(quint32 *dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5808 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
5810 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5812 *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
5817#if defined(__SSE2__
)
5818 __m128i vd = _mm_cvtsi32_si128(d);
5819 __m128i vs = _mm_cvtsi32_si128(s);
5820 __m128i va = _mm_cvtsi32_si128(rgbAlpha);
5821 const __m128i vz = _mm_setzero_si128();
5822 vd = _mm_unpacklo_epi8(vd, vz);
5823 vs = _mm_unpacklo_epi8(vs, vz);
5824 va = _mm_unpacklo_epi8(va, vz);
5825 __m128i vb = _mm_xor_si128(_mm_set1_epi16(255), va);
5826 vs = _mm_mullo_epi16(vs, va);
5827 vd = _mm_mullo_epi16(vd, vb);
5828 vd = _mm_add_epi16(vd, vs);
5829 vd = _mm_add_epi16(vd, _mm_srli_epi16(vd, 8));
5830 vd = _mm_add_epi16(vd, _mm_set1_epi16(0x80));
5831 vd = _mm_srli_epi16(vd, 8);
5832 vd = _mm_packus_epi16(vd, vd);
5833 return _mm_cvtsi128_si32(vd);
5835 const int dr = qRed(d);
5836 const int dg = qGreen(d);
5837 const int db = qBlue(d);
5839 const int sr = qRed(s);
5840 const int sg = qGreen(s);
5841 const int sb = qBlue(s);
5843 const int mr = qRed(rgbAlpha);
5844 const int mg = qGreen(rgbAlpha);
5845 const int mb = qBlue(rgbAlpha);
5847 const int nr = qt_div_255(sr * mr + dr * (255 - mr));
5848 const int ng = qt_div_255(sg * mg + dg * (255 - mg));
5849 const int nb = qt_div_255(sb * mb + db * (255 - mb));
5851 return 0xff000000 | (nr << 16) | (ng << 8) | nb;
5855static inline void alphargbblend_argb32(quint32 *dst, uint coverage,
const QRgba64 &srcLinear, quint32 src,
const QColorTrcLut *colorProfile)
5857 if (coverage == 0xff000000) {
5859 }
else if (coverage == 0xffffffff && qAlpha(src) == 255) {
5860 blend_pixel(*dst, src);
5861 }
else if (*dst < 0xff000000) {
5863 blend_pixel(*dst, src, qRgbAvg(coverage));
5864 }
else if (!colorProfile) {
5867 blend_pixel(s, src);
5869 *dst = rgbBlend(*dst, s, coverage);
5870 }
else if (srcLinear.isOpaque()) {
5871 rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
5875 blend_pixel(s, src);
5877 QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s);
5878 rgbBlendPixel(dst, coverage, s64, colorProfile);
5882#if QT_CONFIG(raster_64bit)
5883static inline void rgbBlendPixel(QRgba64 &dst,
int coverage, QRgba64 slinear,
const QColorTrcLut *colorProfile)
5886 const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
5888 QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
5890 dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
5893static inline void alphargbblend_generic(uint coverage, QRgba64 *dest,
int x,
const QRgba64 &srcLinear,
const QRgba64 &src,
const QColorTrcLut *colorProfile)
5895 if (coverage == 0xff000000) {
5897 }
else if (coverage == 0xffffffff) {
5898 blend_pixel(dest[x], src);
5899 }
else if (!dest[x].isOpaque()) {
5901 alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
5902 }
else if (src.isOpaque()) {
5903 rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
5906 QRgba64 s = dest[x];
5907 blend_pixel(s, src);
5910 s = colorProfile->toLinear(s);
5911 rgbBlendPixel(dest[x], coverage, s, colorProfile);
5915static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
5916 int x,
int y,
const QRgba64 &color,
5917 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5918 const QClipData *clip,
bool useGammaCorrection)
5920 if (color.isTransparent())
5923 const QColorTrcLut *colorProfile =
nullptr;
5925 if (useGammaCorrection)
5926 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
5928 QRgba64 srcColor = color;
5929 if (colorProfile && color.isOpaque())
5930 srcColor = colorProfile->toLinear(srcColor);
5932 alignas(8) Q_DECL_UNINITIALIZED QRgba64 buffer[BufferSize];
5933 const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
5934 const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
5937 for (
int ly = 0; ly < mapHeight; ++ly) {
5939 int length = mapWidth;
5940 while (length > 0) {
5941 int l = qMin(BufferSize, length);
5942 QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l);
5943 for (
int j=0; j < l; ++j) {
5944 const uint coverage = src[j + (i - x)];
5945 alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile);
5948 destStore64(rasterBuffer, i, y + ly, dest, l);
5955 int bottom = qMin(y + mapHeight, rasterBuffer->height());
5957 int top = qMax(y, 0);
5958 src += (top - y) * srcStride;
5960 const_cast<QClipData *>(clip)->initialize();
5961 for (
int yp = top; yp<bottom; ++yp) {
5962 const QClipData::ClipLine &line = clip->m_clipLines[yp];
5964 for (
int i=0; i<line.count; ++i) {
5965 const QT_FT_Span &clip = line.spans[i];
5967 int start = qMax<
int>(x, clip.x);
5968 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
5971 Q_ASSERT(end - start <= BufferSize);
5972 QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start);
5974 for (
int xp=start; xp<end; ++xp) {
5975 const uint coverage = src[xp - x];
5976 alphargbblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
5979 destStore64(rasterBuffer, start, clip.y, dest, end - start);
5987 int x,
int y,
const QRgba64 &color,
5988 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
5989 const QClipData *clip,
bool useGammaCorrection)
5991 if (color.isTransparent())
5994 const quint32 c = color.toArgb32();
5996 const QColorTrcLut *colorProfile =
nullptr;
5998 if (useGammaCorrection)
5999 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6001 QRgba64 srcColor = color;
6002 if (colorProfile && color.isOpaque())
6003 srcColor = colorProfile->toLinear(srcColor);
6005 Q_DECL_UNINITIALIZED quint32 buffer[BufferSize];
6006 const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
6007 const DestStoreProc destStore = destStoreProc[rasterBuffer->format];
6010 for (
int ly = 0; ly < mapHeight; ++ly) {
6012 int length = mapWidth;
6013 while (length > 0) {
6015 quint32 *dest = destFetch(buffer, rasterBuffer, i, y + ly, l);
6016 for (
int j=0; j < l; ++j) {
6017 const uint coverage = src[j + (i - x)];
6018 alphargbblend_argb32(dest + j, coverage, srcColor, c, colorProfile);
6021 destStore(rasterBuffer, i, y + ly, dest, l);
6028 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6030 int top = qMax(y, 0);
6031 src += (top - y) * srcStride;
6033 const_cast<
QClipData *>(clip)->initialize();
6034 for (
int yp = top; yp<bottom; ++yp) {
6035 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6037 for (
int i=0; i<line.count; ++i) {
6038 const QT_FT_Span &clip = line.spans[i];
6040 int start = qMax<
int>(x, clip.x);
6041 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6045 quint32 *dest = destFetch(buffer, rasterBuffer, start, clip.y, end - start);
6047 for (
int xp=start; xp<end; ++xp) {
6048 const uint coverage = src[xp - x];
6049 alphargbblend_argb32(dest + xp - start, coverage, srcColor, c, colorProfile);
6052 destStore(rasterBuffer, start, clip.y, dest, end - start);
6061 int x,
int y,
const QRgba64 &color,
6062 const uint *src,
int mapWidth,
int mapHeight,
int srcStride,
6063 const QClipData *clip,
bool useGammaCorrection)
6065 if (color.isTransparent())
6068 const quint32 c = color.toArgb32();
6070 const QColorTrcLut *colorProfile =
nullptr;
6072 if (useGammaCorrection)
6073 colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
6075 QRgba64 srcColor = color;
6076 if (colorProfile && color.isOpaque())
6077 srcColor = colorProfile->toLinear(srcColor);
6080 quint32 *dst =
reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
6081 const int destStride = rasterBuffer->stride<quint32>();
6082 while (--mapHeight >= 0) {
6083 for (
int i = 0; i < mapWidth; ++i) {
6084 const uint coverage = src[i];
6085 alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
6092 int bottom = qMin(y + mapHeight, rasterBuffer->height());
6094 int top = qMax(y, 0);
6095 src += (top - y) * srcStride;
6097 const_cast<
QClipData *>(clip)->initialize();
6098 for (
int yp = top; yp<bottom; ++yp) {
6099 const QClipData::ClipLine &line = clip->m_clipLines[yp];
6101 quint32 *dst =
reinterpret_cast<quint32 *>(rasterBuffer->scanLine(yp));
6103 for (
int i=0; i<line.count; ++i) {
6104 const QT_FT_Span &clip = line.spans[i];
6106 int start = qMax<
int>(x, clip.x);
6107 int end = qMin<
int>(x + mapWidth, clip.x + clip.len);
6109 for (
int xp=start; xp<end; ++xp) {
6110 const uint coverage = src[xp - x];
6111 alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
6121 int x,
int y,
int width,
int height,
6122 const QRgba64 &color)
6124 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6125 color.toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6129 int x,
int y,
int width,
int height,
6130 const QRgba64 &color)
6132 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6133 quint32 c32 = color.toArgb32();
6135 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c16), &c32, 0, 1,
nullptr,
nullptr);
6136 qt_rectfill<quint16>(
reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
6137 c16, x, y, width, height, rasterBuffer->bytesPerLine());
6141 int x,
int y,
int width,
int height,
6142 const QRgba64 &color)
6144 const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
6145 quint32 c32 = color.toArgb32();
6147 layout.storeFromARGB32PM(
reinterpret_cast<uchar *>(&c24), &c32, 0, 1,
nullptr,
nullptr);
6148 qt_rectfill<
quint24>(
reinterpret_cast<
quint24 *>(rasterBuffer->buffer()),
6149 c24, x, y, width, height, rasterBuffer->bytesPerLine());
6153 int x,
int y,
int width,
int height,
6154 const QRgba64 &color)
6156 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6157 color.unpremultiplied().toArgb32(), x, y, width, height, rasterBuffer->bytesPerLine());
6161 int x,
int y,
int width,
int height,
6162 const QRgba64 &color)
6164 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6165 ARGB2RGBA(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6169 int x,
int y,
int width,
int height,
6170 const QRgba64 &color)
6172 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6173 ARGB2RGBA(color.unpremultiplied().toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6176template<QtPixelOrder PixelOrder>
6178 int x,
int y,
int width,
int height,
6179 const QRgba64 &color)
6181 qt_rectfill<quint32>(
reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
6182 qConvertRgb64ToRgb30<PixelOrder>(color), x, y, width, height, rasterBuffer->bytesPerLine());
6186 int x,
int y,
int width,
int height,
6187 const QRgba64 &color)
6189 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6190 color.alpha() >> 8, x, y, width, height, rasterBuffer->bytesPerLine());
6194 int x,
int y,
int width,
int height,
6195 const QRgba64 &color)
6197 qt_rectfill<quint8>(
reinterpret_cast<quint8 *>(rasterBuffer->buffer()),
6198 qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
6202 int x,
int y,
int width,
int height,
6203 const QRgba64 &color)
6205 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6207 store(
reinterpret_cast<uchar *>(&c64), &color, 0, 1,
nullptr,
nullptr);
6208 qt_rectfill<quint64>(
reinterpret_cast<quint64 *>(rasterBuffer->buffer()),
6209 c64, x, y, width, height, rasterBuffer->bytesPerLine());
6213 int x,
int y,
int width,
int height,
6214 const QRgba64 &color)
6216 const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
6218 store(
reinterpret_cast<uchar *>(&c), &color, 0, 1,
nullptr,
nullptr);
6220 c, x, y, width, height, rasterBuffer->bytesPerLine());
6229 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr },
6232 blend_color_generic,
6233 nullptr,
nullptr,
nullptr,
nullptr
6237 blend_color_generic,
6238 nullptr,
nullptr,
nullptr,
nullptr
6242 blend_color_generic,
6243 nullptr,
nullptr,
nullptr,
nullptr
6248 qt_bitmapblit_argb32,
6249 qt_alphamapblit_argb32,
6250 qt_alphargbblit_argb32,
6255 blend_color_generic,
6256 qt_bitmapblit_argb32,
6257#if QT_CONFIG(raster_64bit)
6258 qt_alphamapblit_nonpremul_argb32,
6260 qt_alphamapblit_generic,
6262 qt_alphargbblit_generic,
6263 qt_rectfill_nonpremul_argb32
6268 qt_bitmapblit_argb32,
6269 qt_alphamapblit_argb32,
6270 qt_alphargbblit_argb32,
6275 blend_color_generic,
6276 qt_bitmapblit_quint16,
6277 qt_alphamapblit_quint16,
6278 qt_alphargbblit_generic,
6283 blend_color_generic,
6285 qt_alphamapblit_generic,
6286 qt_alphargbblit_generic,
6291 blend_color_generic,
6293 qt_alphamapblit_generic,
6294 qt_alphargbblit_generic,
6299 blend_color_generic,
6301 qt_alphamapblit_generic,
6302 qt_alphargbblit_generic,
6307 blend_color_generic,
6309 qt_alphamapblit_generic,
6310 qt_alphargbblit_generic,
6315 blend_color_generic,
6317 qt_alphamapblit_generic,
6318 qt_alphargbblit_generic,
6323 blend_color_generic,
6325 qt_alphamapblit_generic,
6326 qt_alphargbblit_generic,
6331 blend_color_generic,
6333 qt_alphamapblit_generic,
6334 qt_alphargbblit_generic,
6339 blend_color_generic,
6341 qt_alphamapblit_generic,
6342 qt_alphargbblit_generic,
6347 blend_color_generic,
6348 qt_bitmapblit_rgba8888,
6349 qt_alphamapblit_generic,
6350 qt_alphargbblit_generic,
6355 blend_color_generic,
6356 qt_bitmapblit_rgba8888,
6357 qt_alphamapblit_generic,
6358 qt_alphargbblit_generic,
6359 qt_rectfill_nonpremul_rgba
6363 blend_color_generic,
6364 qt_bitmapblit_rgba8888,
6365 qt_alphamapblit_generic,
6366 qt_alphargbblit_generic,
6371 blend_color_generic_rgb64,
6372 qt_bitmapblit_rgb30<PixelOrderBGR>,
6373 qt_alphamapblit_generic,
6374 qt_alphargbblit_generic,
6375 qt_rectfill_rgb30<PixelOrderBGR>
6379 blend_color_generic_rgb64,
6380 qt_bitmapblit_rgb30<PixelOrderBGR>,
6381 qt_alphamapblit_generic,
6382 qt_alphargbblit_generic,
6383 qt_rectfill_rgb30<PixelOrderBGR>
6387 blend_color_generic_rgb64,
6388 qt_bitmapblit_rgb30<PixelOrderRGB>,
6389 qt_alphamapblit_generic,
6390 qt_alphargbblit_generic,
6391 qt_rectfill_rgb30<PixelOrderRGB>
6395 blend_color_generic_rgb64,
6396 qt_bitmapblit_rgb30<PixelOrderRGB>,
6397 qt_alphamapblit_generic,
6398 qt_alphargbblit_generic,
6399 qt_rectfill_rgb30<PixelOrderRGB>
6403 blend_color_generic,
6405 qt_alphamapblit_generic,
6406 qt_alphargbblit_generic,
6411 blend_color_generic,
6413 qt_alphamapblit_generic,
6414 qt_alphargbblit_generic,
6419 blend_color_generic_rgb64,
6421 qt_alphamapblit_generic,
6422 qt_alphargbblit_generic,
6427 blend_color_generic_rgb64,
6429 qt_alphamapblit_generic,
6430 qt_alphargbblit_generic,
6435 blend_color_generic_rgb64,
6437 qt_alphamapblit_generic,
6438 qt_alphargbblit_generic,
6443 blend_color_generic_rgb64,
6445 qt_alphamapblit_generic,
6446 qt_alphargbblit_generic,
6451 blend_color_generic,
6453 qt_alphamapblit_generic,
6454 qt_alphargbblit_generic,
6459 blend_color_generic_fp,
6461 qt_alphamapblit_generic,
6462 qt_alphargbblit_generic,
6467 blend_color_generic_fp,
6469 qt_alphamapblit_generic,
6470 qt_alphargbblit_generic,
6475 blend_color_generic_fp,
6477 qt_alphamapblit_generic,
6478 qt_alphargbblit_generic,
6483 blend_color_generic_fp,
6485 qt_alphamapblit_generic,
6486 qt_alphargbblit_generic,
6491 blend_color_generic_fp,
6493 qt_alphamapblit_generic,
6494 qt_alphargbblit_generic,
6499 blend_color_generic_fp,
6501 qt_alphamapblit_generic,
6502 qt_alphargbblit_generic,
6507static_assert(std::size(qDrawHelper) == QImage::NImageFormats);
6509#if !defined(Q_PROCESSOR_X86) && !defined(QT_COMPILER_SUPPORTS_LSX)
6512 qt_memfill_template<quint64>(dest, color, count);
6516#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
6517__attribute__((optimize(
"no-tree-vectorize")))
6521# ifdef QT_COMPILER_SUPPORTS_SSSE3
6522 extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
6523 if (qCpuHasFeature(SSSE3))
6524 return qt_memfill24_ssse3(dest, color, count);
6525# elif defined QT_COMPILER_SUPPORTS_LSX
6526 extern void qt_memfill24_lsx(quint24 *, quint24, qsizetype);
6527 if (qCpuHasFeature(LSX))
6528 return qt_memfill24_lsx(dest, color, count);
6531 const quint32 v = color;
6535 while ((quintptr(dest) & 0x3) && dest < end) {
6541 const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
6542 const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
6543 const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
6545 for ( ; dest <= (end - 4); dest += 4) {
6546 quint32 *dst =
reinterpret_cast<quint32 *>(dest);
6553 switch (end - dest) {
6567 const int align = quintptr(dest) & 0x3;
6574 dest[count - 1] = value;
6576 const quint32 value32 = (value << 16) | value;
6577 qt_memfill32(
reinterpret_cast<quint32*>(dest), value32, count / 2);
6580#if defined(Q_PROCESSOR_X86) || defined(QT_COMPILER_SUPPORTS_LSX)
6581void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count) =
nullptr;
6582void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count) =
nullptr;
6583#elif !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
6586 qt_memfill_template<quint32>(dest, color, count);
6590#ifdef QT_COMPILER_SUPPORTS_SSE4_1
6591template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6592#elif defined(QT_COMPILER_SUPPORTS_LSX)
6593template<QtPixelOrder>
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6603#if defined(Q_PROCESSOR_X86) && !defined(__SSE2__
)
6604 qt_memfill32 = qt_memfill_template<quint32>;
6605 qt_memfill64 = qt_memfill_template<quint64>;
6606#elif defined(__SSE2__
)
6608 qt_memfill32 = qt_memfill32_sse2;
6609 qt_memfill64 = qt_memfill64_sse2;
6611 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
6612 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
6613 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
6614 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
6615 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_sse2;
6616 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_sse2;
6617 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
6619 extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6620 const uchar *srcPixels,
int sbpl,
int srch,
6621 const QRectF &targetRect,
6622 const QRectF &sourceRect,
6625 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6626 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6627 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6628 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
6630 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels,
int dbpl,
6631 const uchar *srcPixels,
int sbpl,
6634 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels,
int dbpl,
6635 const uchar *srcPixels,
int sbpl,
6639 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6640 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
6641 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6642 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6643 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6644 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
6645 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6646 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
6648 extern const uint *
QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer,
const Operator *op,
const QSpanData *data,
6649 int y,
int x,
int length);
6651 qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
6653 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6654 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6655 extern void QT_FASTCALL comp_func_Source_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6656 extern void QT_FASTCALL comp_func_solid_Source_sse2(uint *destPixels,
int length, uint color, uint const_alpha);
6657 extern void QT_FASTCALL comp_func_Plus_sse2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6658 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_sse2;
6659 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_sse2;
6660 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
6661 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_sse2;
6662 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
6664#ifdef QT_COMPILER_SUPPORTS_SSSE3
6665 if (qCpuHasFeature(SSSE3)) {
6666 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels,
int dbpl,
6667 const uchar *srcPixels,
int sbpl,
6671 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer,
const Operator *,
const QSpanData *data,
6672 int y,
int x,
int length);
6673 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6674 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6675 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6676 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
6677 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
6678 extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst,
const uchar *src,
int count);
6679 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
6680 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
6684#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
6685 if (qCpuHasFeature(SSE4_1)) {
6686 extern void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6687 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer,
int count,
const QList<QRgb> *);
6688 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6689 const QList<QRgb> *, QDitherInfo *);
6690 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer,
const uchar *src,
int index,
int count,
6691 const QList<QRgb> *, QDitherInfo *);
6692 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6693 const QList<QRgb> *, QDitherInfo *);
6694 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uint *src,
int count,
6695 const QList<QRgb> *, QDitherInfo *);
6696 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6697 const QList<QRgb> *, QDitherInfo *);
6698 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6699 const QList<QRgb> *, QDitherInfo *);
6700 extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6701 const QList<QRgb> *, QDitherInfo *);
6702 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6703 const QList<QRgb> *, QDitherInfo *);
6704 extern void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest,
const uint *src,
int index,
int count,
6705 const QList<QRgb> *, QDitherInfo *);
6706 extern void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6707 const QList<QRgb> *, QDitherInfo *);
6708 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest,
const QRgba64 *src,
int index,
int count,
6709 const QList<QRgb> *, QDitherInfo *);
6710 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6711 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_sse4(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6712 extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6713 extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6715 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
6716 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
6717 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
6718 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
6719 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4;
6720 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4;
6721 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6722 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6723 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
6724 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
6726 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
6727 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
6728 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
6729 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
6730 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
6731 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
6732 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
6733 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_sse4;
6734 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_sse4;
6735#if QT_CONFIG(raster_64bit)
6736 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
6737 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
6739#if QT_CONFIG(raster_fp)
6740 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_sse4(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6741 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6742 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_sse4(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6743 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_sse4;
6744 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_sse4;
6745 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_sse4;
6750#if defined(QT_COMPILER_SUPPORTS_AVX2)
6751 if (qCpuHasFeature(ArchHaswell)) {
6752 qt_memfill32 = qt_memfill32_avx2;
6753 qt_memfill64 = qt_memfill64_avx2;
6754 extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels,
int dbpl,
6755 const uchar *srcPixels,
int sbpl,
6756 int w,
int h,
int const_alpha);
6757 extern void qt_blend_argb32_on_argb32_avx2(uchar *destPixels,
int dbpl,
6758 const uchar *srcPixels,
int sbpl,
6759 int w,
int h,
int const_alpha);
6760 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6761 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx2;
6762 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6763 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6764 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6765 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx2;
6766 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6767 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx2;
6769 extern void QT_FASTCALL comp_func_Source_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6770 extern void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6771 extern void QT_FASTCALL comp_func_solid_SourceOver_avx2(uint *destPixels,
int length, uint color, uint const_alpha);
6772 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_avx2;
6773 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_avx2;
6774 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
6775#if QT_CONFIG(raster_64bit)
6776 extern void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6777 extern void QT_FASTCALL comp_func_SourceOver_rgb64_avx2(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
6778 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
6779 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_avx2;
6780 qt_functionForMode64_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgb64_avx2;
6781 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
6783#if QT_CONFIG(raster_fp)
6784 extern void QT_FASTCALL comp_func_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6785 extern void QT_FASTCALL comp_func_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
const QRgbaFloat32 *srcPixels,
int length, uint const_alpha);
6786 extern void QT_FASTCALL comp_func_solid_Source_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6787 extern void QT_FASTCALL comp_func_solid_SourceOver_rgbafp_avx2(QRgbaFloat32 *destPixels,
int length, QRgbaFloat32 color, uint const_alpha);
6788 qt_functionForModeFP_C[QPainter::CompositionMode_Source] = comp_func_Source_rgbafp_avx2;
6789 qt_functionForModeFP_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_rgbafp_avx2;
6790 qt_functionForModeSolidFP_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_rgbafp_avx2;
6791 qt_functionForModeSolidFP_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgbafp_avx2;
6794 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6795 int &fx,
int &fy,
int fdx,
int );
6796 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6797 int &fx,
int &fy,
int fdx,
int );
6798 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *b, uint *end,
const QTextureData &image,
6799 int &fx,
int &fy,
int fdx,
int fdy);
6801 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
6802 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
6803 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
6805 extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6806 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer,
int count,
const QList<QRgb> *);
6807 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6808 const QList<QRgb> *, QDitherInfo *);
6809 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
6810 const QList<QRgb> *, QDitherInfo *);
6811 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2;
6812 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
6813 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
6814 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
6816 extern const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
6817 extern const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
6818 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6819 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6820 extern const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6821 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2;
6822 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
6823 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
6824 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
6825 qPixelLayouts[QImage::Format_RGBA64].fetchToRGBA64PM = fetchRGBA64ToRGBA64PM_avx2;
6827 extern const uint *QT_FASTCALL fetchRGB16FToRGB32_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6828 extern const uint *QT_FASTCALL fetchRGBA16FToARGB32PM_avx2(uint *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6829 extern const QRgba64 *QT_FASTCALL fetchRGBA16FPMToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6830 extern const QRgba64 *QT_FASTCALL fetchRGBA16FToRGBA64PM_avx2(QRgba64 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6831 extern void QT_FASTCALL storeRGB16FFromRGB32_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6832 extern void QT_FASTCALL storeRGBA16FFromARGB32PM_avx2(uchar *dest,
const uint *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6833 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6834 qPixelLayouts[QImage::Format_RGBX16FPx4].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6835 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6836 qPixelLayouts[QImage::Format_RGBX16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6837 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToARGB32PM = fetchRGBA16FToARGB32PM_avx2;
6838 qPixelLayouts[QImage::Format_RGBA16FPx4].fetchToRGBA64PM = fetchRGBA16FToRGBA64PM_avx2;
6839 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromARGB32PM = storeRGBA16FFromARGB32PM_avx2;
6840 qPixelLayouts[QImage::Format_RGBA16FPx4].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6841 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToARGB32PM = fetchRGB16FToRGB32_avx2;
6842 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].fetchToRGBA64PM = fetchRGBA16FPMToRGBA64PM_avx2;
6843 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromARGB32PM = storeRGB16FFromRGB32_avx2;
6844 qPixelLayouts[QImage::Format_RGBA16FPx4_Premultiplied].storeFromRGB32 = storeRGB16FFromRGB32_avx2;
6845#if QT_CONFIG(raster_fp)
6846 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA16FToRGBA32F_avx2(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6847 extern void QT_FASTCALL storeRGBX16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6848 extern void QT_FASTCALL storeRGBA16FFromRGBA32F_avx2(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6849 qFetchToRGBA32F[QImage::Format_RGBA16FPx4] = fetchRGBA16FToRGBA32F_avx2;
6850 qStoreFromRGBA32F[QImage::Format_RGBX16FPx4] = storeRGBX16FFromRGBA32F_avx2;
6851 qStoreFromRGBA32F[QImage::Format_RGBA16FPx4] = storeRGBA16FFromRGBA32F_avx2;
6859#if defined(QT_COMPILER_SUPPORTS_LSX)
6860 if (qCpuHasFeature(LSX)) {
6861 qt_memfill32 = qt_memfill32_lsx;
6862 qt_memfill64 = qt_memfill64_lsx;
6864 qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_lsx;
6865 qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_lsx;
6866 qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_lsx;
6867 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_lsx;
6868 qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_lsx;
6869 qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_lsx;
6870 qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_lsx;
6872 extern void qt_scale_image_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6873 const uchar *srcPixels,
int sbpl,
int srch,
6874 const QRectF &targetRect,
6875 const QRectF &sourceRect,
6879 qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6880 qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6881 qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6882 qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_lsx;
6884 extern void qt_blend_rgb32_on_rgb32_lsx(uchar *destPixels,
int dbpl,
6885 const uchar *srcPixels,
int sbpl,
6889 extern void qt_blend_argb32_on_argb32_lsx(uchar *destPixels,
int dbpl,
6890 const uchar *srcPixels,
int sbpl,
6894 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6895 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lsx;
6896 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6897 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6898 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6899 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lsx;
6900 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6901 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lsx;
6903 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_lsx(uint *buffer,
const Operator *op,
const QSpanData *data,
6904 int y,
int x,
int length);
6906 qt_fetch_radial_gradient = qt_fetch_radial_gradient_lsx;
6908 extern void QT_FASTCALL comp_func_SourceOver_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6909 extern void QT_FASTCALL comp_func_solid_SourceOver_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6910 extern void QT_FASTCALL comp_func_Source_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6911 extern void QT_FASTCALL comp_func_solid_Source_lsx(uint *destPixels,
int length, uint color, uint const_alpha);
6912 extern void QT_FASTCALL comp_func_Plus_lsx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
6913 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lsx;
6914 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lsx;
6915 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lsx;
6916 qt_functionForModeSolid_C[QPainter::CompositionMode_Source] = comp_func_solid_Source_lsx;
6917 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_lsx;
6919 extern const uint * QT_FASTCALL qt_fetchUntransformed_888_lsx(uint *buffer,
const Operator *,
const QSpanData *data,
6920 int y,
int x,
int length);
6921 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_lsx;
6922 extern void QT_FASTCALL rbSwap_888_lsx(uchar *dst,
const uchar *src,
int count);
6923 qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_lsx;
6924 qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_lsx;
6926 extern void QT_FASTCALL convertARGB32ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6927 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lsx(uint *buffer,
int count,
const QList<QRgb> *);
6928 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6929 const QList<QRgb> *, QDitherInfo *);
6930 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lsx(uint *buffer,
const uchar *src,
int index,
int count,
6931 const QList<QRgb> *, QDitherInfo *);
6932 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6933 const QList<QRgb> *, QDitherInfo *);
6934 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uint *src,
int count,
6935 const QList<QRgb> *, QDitherInfo *);
6936 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6937 const QList<QRgb> *, QDitherInfo *);
6938 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lsx(QRgba64 *buffer,
const uchar *src,
int index,
int count,
6939 const QList<QRgb> *, QDitherInfo *);
6940 extern void QT_FASTCALL storeARGB32FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6941 const QList<QRgb> *, QDitherInfo *);
6942 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6943 const QList<QRgb> *, QDitherInfo *);
6944 extern void QT_FASTCALL storeRGBXFromARGB32PM_lsx(uchar *dest,
const uint *src,
int index,
int count,
6945 const QList<QRgb> *, QDitherInfo *);
6946 extern void QT_FASTCALL storeARGB32FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6947 const QList<QRgb> *, QDitherInfo *);
6948 extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_lsx(uchar *dest,
const QRgba64 *src,
int index,
int count,
6949 const QList<QRgb> *, QDitherInfo *);
6950 extern void QT_FASTCALL destStore64ARGB32_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6951 extern void QT_FASTCALL destStore64RGBA8888_lsx(QRasterBuffer *rasterBuffer,
int x,
int y,
const QRgba64 *buffer,
int length);
6952 extern void QT_FASTCALL storeRGBA64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6953 extern void QT_FASTCALL storeRGBx64FromRGBA64PM_lsx(uchar *,
const QRgba64 *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
6954 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lsx;
6955 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lsx;
6956 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lsx;
6957 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lsx;
6958 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lsx;
6959 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lsx;
6960 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6961 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6962 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lsx;
6963 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lsx;
6964 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_lsx;
6965 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_lsx;
6966 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_lsx;
6967 qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderBGR>;
6968 qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_lsx<PixelOrderRGB>;
6969 qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_lsx;
6970 qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_lsx;
6971 qStoreFromRGBA64PM[QImage::Format_RGBX64] = storeRGBx64FromRGBA64PM_lsx;
6972 qStoreFromRGBA64PM[QImage::Format_RGBA64] = storeRGBA64FromRGBA64PM_lsx;
6973#if QT_CONFIG(raster_64bit)
6974 destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_lsx;
6975 destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_lsx;
6977#if QT_CONFIG(raster_fp)
6978 extern const QRgbaFloat32 *QT_FASTCALL fetchRGBA32FToRGBA32F_lsx(QRgbaFloat32 *buffer,
const uchar *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6979 extern void QT_FASTCALL storeRGBX32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6980 extern void QT_FASTCALL storeRGBA32FFromRGBA32F_lsx(uchar *dest,
const QRgbaFloat32 *src,
int index,
int count,
const QList<QRgb> *, QDitherInfo *);
6981 qFetchToRGBA32F[QImage::Format_RGBA32FPx4] = fetchRGBA32FToRGBA32F_lsx;
6982 qStoreFromRGBA32F[QImage::Format_RGBX32FPx4] = storeRGBX32FFromRGBA32F_lsx;
6983 qStoreFromRGBA32F[QImage::Format_RGBA32FPx4] = storeRGBA32FFromRGBA32F_lsx;
6987#if defined(QT_COMPILER_SUPPORTS_LASX)
6988 if (qCpuHasFeature(LASX)) {
6989 qt_memfill32 = qt_memfill32_lasx;
6990 qt_memfill64 = qt_memfill64_lasx;
6992 extern void qt_blend_rgb32_on_rgb32_lasx(uchar *destPixels,
int dbpl,
6993 const uchar *srcPixels,
int sbpl,
6994 int w,
int h,
int const_alpha);
6995 extern void qt_blend_argb32_on_argb32_lasx(uchar *destPixels,
int dbpl,
6996 const uchar *srcPixels,
int sbpl,
6997 int w,
int h,
int const_alpha);
6998 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
6999 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_lasx;
7000 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7001 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7002 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7003 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_lasx;
7004 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7005 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_lasx;
7007 extern void QT_FASTCALL comp_func_Source_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7008 extern void QT_FASTCALL comp_func_SourceOver_lasx(uint *destPixels,
const uint *srcPixels,
int length, uint const_alpha);
7009 extern void QT_FASTCALL comp_func_solid_SourceOver_lasx(uint *destPixels,
int length, uint color, uint const_alpha);
7010 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_lasx;
7011 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_lasx;
7012 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_lasx;
7013#if QT_CONFIG(raster_64bit)
7014 extern void QT_FASTCALL comp_func_Source_rgb64_lasx(QRgba64 *destPixels,
const QRgba64 *srcPixels,
int length, uint const_alpha);
7015 extern void QT_FASTCALL comp_func_solid_SourceOver_rgb64_lasx(QRgba64 *destPixels,
int length, QRgba64 color, uint const_alpha);
7016 qt_functionForMode64_C[QPainter::CompositionMode_Source] = comp_func_Source_rgb64_lasx;
7017 qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_lasx;
7020 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7021 int &fx,
int &fy,
int fdx,
int );
7022 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7023 int &fx,
int &fy,
int fdx,
int );
7024 extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx(uint *b, uint *end,
const QTextureData &image,
7025 int &fx,
int &fy,
int fdx,
int fdy);
7027 bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_lasx;
7028 bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_lasx;
7029 bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_lasx;
7031 extern void QT_FASTCALL convertARGB32ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7032 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_lasx(uint *buffer,
int count,
const QList<QRgb> *);
7033 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7034 const QList<QRgb> *, QDitherInfo *);
7035 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_lasx(uint *buffer,
const uchar *src,
int index,
int count,
7036 const QList<QRgb> *, QDitherInfo *);
7037 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_lasx;
7038 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_lasx;
7039 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_lasx;
7040 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_lasx;
7042 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int,
const QList<QRgb> *, QDitherInfo *);
7043 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uint *,
int count,
const QList<QRgb> *, QDitherInfo *);
7044 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7045 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_lasx(QRgba64 *,
const uchar *,
int,
int,
const QList<QRgb> *, QDitherInfo *);
7046 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_lasx;
7047 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_lasx;
7048 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_lasx;
7049 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_lasx;
7055#if defined(__ARM_NEON__)
7056 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7057 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
7058 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7059 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7060#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7061 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7062 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
7063 qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7064 qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
7067 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
7068 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
7069 qt_functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
7071 extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer,
const Operator *op,
const QSpanData *data,
7072 int y,
int x,
int length);
7074 qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
7076 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
7078#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
7079 extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7080 extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer,
int count,
const QList<QRgb> *);
7081 extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7082 const QList<QRgb> *, QDitherInfo *);
7083 extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer,
const uchar *src,
int index,
int count,
7084 const QList<QRgb> *, QDitherInfo *);
7085 extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7086 const QList<QRgb> *, QDitherInfo *);
7087 extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uint *src,
int count,
7088 const QList<QRgb> *, QDitherInfo *);
7089 extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7090 const QList<QRgb> *, QDitherInfo *);
7091 extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer,
const uchar *src,
int index,
int count,
7092 const QList<QRgb> *, QDitherInfo *);
7093 extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7094 const QList<QRgb> *, QDitherInfo *);
7095 extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7096 const QList<QRgb> *, QDitherInfo *);
7097 extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest,
const uint *src,
int index,
int count,
7098 const QList<QRgb> *, QDitherInfo *);
7099 qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
7100 qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
7101 qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
7102 qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon;
7103 qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon;
7104 qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
7105 qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
7106 qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
7107 qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7108 qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7109 qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
7110 qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
7111 qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
7114#if defined(ENABLE_PIXMAN_DRAWHELPERS)
7116 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
7117 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
7118 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
7120 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
7121 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
7123 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
7124 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
7126 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
7128 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
7129 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
7131 qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon;
7132 qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon;
7136#if defined(__MIPS_DSP__)
7138 qt_functionForMode_C[QPainter::CompositionMode_SourceOver] = comp_func_SourceOver_asm_mips_dsp;
7139 qt_functionForMode_C[QPainter::CompositionMode_Source] = comp_func_Source_mips_dsp;
7140 qt_functionForMode_C[QPainter::CompositionMode_DestinationOver] = comp_func_DestinationOver_mips_dsp;
7141 qt_functionForMode_C[QPainter::CompositionMode_SourceIn] = comp_func_SourceIn_mips_dsp;
7142 qt_functionForMode_C[QPainter::CompositionMode_DestinationIn] = comp_func_DestinationIn_mips_dsp;
7143 qt_functionForMode_C[QPainter::CompositionMode_DestinationOut] = comp_func_DestinationOut_mips_dsp;
7144 qt_functionForMode_C[QPainter::CompositionMode_SourceAtop] = comp_func_SourceAtop_mips_dsp;
7145 qt_functionForMode_C[QPainter::CompositionMode_DestinationAtop] = comp_func_DestinationAtop_mips_dsp;
7146 qt_functionForMode_C[QPainter::CompositionMode_Xor] = comp_func_XOR_mips_dsp;
7147 qt_functionForMode_C[QPainter::CompositionMode_SourceOut] = comp_func_SourceOut_mips_dsp;
7149 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_mips_dsp;
7150 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationOver] = comp_func_solid_DestinationOver_mips_dsp;
7151 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceIn] = comp_func_solid_SourceIn_mips_dsp;
7152 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationIn] = comp_func_solid_DestinationIn_mips_dsp;
7153 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceAtop] = comp_func_solid_SourceAtop_mips_dsp;
7154 qt_functionForModeSolid_C[QPainter::CompositionMode_DestinationAtop] = comp_func_solid_DestinationAtop_mips_dsp;
7155 qt_functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
7156 qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
7158 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7159 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
7160 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7161 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
7163 destFetchProc[QImage::Format_ARGB32] = qt_destFetchARGB32_mips_dsp;
7165 destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
7167 sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
7168 sourceFetchUntransformed[QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
7169 sourceFetchUntransformed[QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
7171#if defined(__MIPS_DSPR2__)
7172 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
7173 sourceFetchUntransformed[QImage::Format_RGB16] = qt_fetchUntransformedRGB16_mips_dspr2;
7175 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 uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos)
static const CompositionFunction * functionForMode
static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void blend_color_generic(int count, const QT_FT_Span *spans, void *userData)
static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
uint QT_FASTCALL fetch1Pixel< QPixelLayout::BPP1LSB >(const uchar *src, int index)
static void qt_rectfill_quint64(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
@ BlendTransformedBilinearTiled
@ BlendTransformedBilinear
static SourceFetchProc sourceFetchAny32[]
static SourceFetchProc sourceFetchUntransformed[]
static bool calculate_fixed_gradient_factors(int count, const QT_FT_Span *spans, const QSpanData *data, const LinearGradientValues &linear, int *pyinc, int *poff)
static void blend_color_generic_fp(int count, const QT_FT_Span *spans, void *userData)
static TextureBlendType getBlendType(const QSpanData *data)
static void qt_bitmapblit_rgb30(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP bpp, int x, int y, int length)
Q_CONSTRUCTOR_FUNCTION(qInitDrawhelperFunctions)
static void qInitDrawhelperFunctions()
static void blend_untransformed_rgb565(int count, const QT_FT_Span *spans, void *userData)
static DestStoreProc destStoreProc[]
static QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
static void qt_bitmapblit_rgba8888(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static const SourceFetchProc sourceFetchGeneric[]
static void blend_untransformed_argb(int count, const QT_FT_Span *spans, void *userData)
static SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
static quint16 interpolate_pixel_rgb16_255(quint16 x, quint8 a, quint16 y, quint8 b)
static void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static bool canUseFastMatrixPath(const qreal cx, const qreal cy, const qsizetype length, const QSpanData *data)
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uint *src, int mapWidth, int mapHeight, int srcStride, const QClipData *clip, bool useGammaCorrection)
static void blend_color_generic_rgb64(int count, const QT_FT_Span *spans, void *userData)
void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v)
static void qt_rectfill_gray(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
constexpr int fixed_scale
static bool blend_vertical_gradient_argb(int count, const QT_FT_Span *spans, void *userData)
static Operator getOperator(const QSpanData *data, const QT_FT_Span *spans, int spanCount)
static SourceFetchProc qt_fetch_radial_gradient
static void qt_rectfill_argb32(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static const ProcessSpans processTextureSpansRGB16[NBlendTypes]
static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
static void blend_color_argb(int count, const QT_FT_Span *spans, void *userData)
static void qt_rectfill_alpha(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
static SourceFetchProc sourceFetchAny16[]
static void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes]
static SourceFetchProc sourceFetchARGB32PM[]
static void blend_tiled_rgb565(int count, const QT_FT_Span *spans, void *userData)
static void qt_rectfill_quint24(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
#define QT_THREAD_PARALLEL_FILLS(function)
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uint *src, int mapWidth, int mapHeight, int srcStride, const QClipData *clip, bool useGammaCorrection)
static void blend_src_generic(int count, const QT_FT_Span *spans, void *userData)
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
void fetchTransformedBilinear_pixelBounds< BlendTransformedBilinearTiled >(int max, int, int, int &v1, int &v2)
static void blend_sourceOver_rgb16_rgb16(quint16 *Q_DECL_RESTRICT dest, const quint16 *Q_DECL_RESTRICT src, int length, const quint8 alpha, const quint8 ialpha)
static void blend_untransformed_generic(int count, const QT_FT_Span *spans, void *userData)
static void blend_tiled_argb(int count, const QT_FT_Span *spans, void *userData)
static void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile)
static bool blend_vertical_gradient(int count, const QT_FT_Span *spans, void *userData)
static void blend_tiled_generic(int count, const QT_FT_Span *spans, void *userData)
static const ProcessSpans processTextureSpansGeneric[NBlendTypes]
static QRgb findNearestColor(QRgb color, QRasterBuffer *rbuf)
static void qt_rectfill_fp32x4(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
void handleSpans(int count, const QT_FT_Span *spans, const QSpanData *data, const Operator &op)
static void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, DST color, const uchar *map, int mapWidth, int mapHeight, int mapStride)
static quint32 interpolate_pixel_rgb16x2_255(quint32 x, quint8 a, quint32 y, quint8 b)
static void qt_rectfill_rgb30(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
void qt_memfill24(quint24 *dest, quint24 value, qsizetype count)
void qt_memfill32(quint32 *dest, quint32 value, qsizetype count)
static constexpr int BufferSize
void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
QT_FT_SpanFunc ProcessSpans
QRgbaFloat< float > QRgbaFloat32
DrawHelper qDrawHelper[QImage::NImageFormats]
#define GRADIENT_STOPTABLE_SIZE
void qBlendGradient(int count, const QT_FT_Span *spans, void *userData)
void qBlendTexture(int count, const QT_FT_Span *spans, void *userData)
void qt_memfill64(quint64 *dest, quint64 value, qsizetype count)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
QRasterBuffer * rasterBuffer