summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qimage.cpp2
-rw-r--r--src/gui/image/qimage_conversions.cpp218
-rw-r--r--src/gui/painting/qcolormatrix_p.h6
-rw-r--r--src/gui/painting/qcolorspace.cpp31
-rw-r--r--src/gui/painting/qcolorspace.h9
-rw-r--r--src/gui/painting/qcolortransferfunction_p.h4
-rw-r--r--src/gui/painting/qdrawhelper.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp45
-rw-r--r--src/gui/painting/qicc.cpp3
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp20
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/rhi/qrhid3d11.cpp1
-rw-r--r--src/gui/rhi/qrhimetal.mm37
13 files changed, 180 insertions, 205 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 86130132a4..dda407181a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3370,7 +3370,7 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
\sa {QImage#Image Transformations}{Image Transformations}
*/
-inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
+static inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
{
const RbSwapFunc func = layout->rbSwap;
if (!func) {
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 539bac222a..9e1df7058c 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -564,6 +564,67 @@ static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFl
return true;
}
+static void convert_rgbswap_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const RbSwapFunc func = qPixelLayouts[src->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ func(dest_data, src_data, src->width);
+
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
+static bool convert_rgbswap_generic_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ const RbSwapFunc func = qPixelLayouts[data->format].rbSwap;
+ Q_ASSERT(func);
+
+ const qsizetype bpl = data->bytes_per_line;
+ uchar *line_data = data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ func(line_data, line_data, data->width);
+ line_data += bpl;
+ }
+
+ switch (data->format) {
+ case QImage::Format_RGB888:
+ data->format = QImage::Format_BGR888;
+ break;
+ case QImage::Format_BGR888:
+ data->format = QImage::Format_RGB888;
+ break;
+ case QImage::Format_BGR30:
+ data->format = QImage::Format_RGB30;
+ break;
+ case QImage::Format_A2BGR30_Premultiplied:
+ data->format = QImage::Format_A2RGB30_Premultiplied;
+ break;
+ case QImage::Format_RGB30:
+ data->format = QImage::Format_BGR30;
+ break;
+ case QImage::Format_A2RGB30_Premultiplied:
+ data->format = QImage::Format_A2BGR30_Premultiplied;
+ break;
+ default:
+ Q_UNREACHABLE();
+ data->format = QImage::Format_Invalid;
+ return false;
+ }
+ return true;
+}
+
template<QtPixelOrder PixelOrder, bool RGBA>
static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
@@ -693,74 +754,10 @@ static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConve
return true;
}
-static void convert_BGR30_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB30 || src->format == QImage::Format_BGR30 ||
- src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30 ||
- dest->format == QImage::Format_A2RGB30_Premultiplied || dest->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = qRgbSwapRgb30(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30 ||
- data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- uint *rgb_data = (uint *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const uint *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = qRgbSwapRgb30(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
-
- switch (data->format) {
- case QImage::Format_BGR30:
- data->format = QImage::Format_RGB30;
- break;
- case QImage::Format_A2BGR30_Premultiplied:
- data->format = QImage::Format_A2RGB30_Premultiplied;
- break;
- case QImage::Format_RGB30:
- data->format = QImage::Format_BGR30;
- break;
- case QImage::Format_A2RGB30_Premultiplied:
- data->format = QImage::Format_A2BGR30_Premultiplied;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversionFlags flags)
{
Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30);
- if (!convert_BGR30_to_RGB30_inplace(data, flags))
+ if (!convert_rgbswap_generic_inplace(data, flags))
return false;
if (data->format == QImage::Format_RGB30)
@@ -1421,69 +1418,6 @@ static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt
}
}
-static void convert_RGB888_to_BGR888(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
- Q_ASSERT(dest->format == QImage::Format_RGB888 || dest->format == QImage::Format_BGR888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const qsizetype sbpl = src->bytes_per_line;
- const qsizetype dbpl = dest->bytes_per_line;
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- int pixel = 0;
- // Handle 4 pixels (12 bytes) at a time
- for (; pixel + 3 < src->width; pixel += 4) {
- const uchar *src = src_data + pixel * 3;
- quint32 *dest_packed = (quint32 *) (dest_data + pixel * 3);
- dest_packed[0] = (src[5] << 24) | (src[0] << 16) | (src[1] << 8) | (src[2] << 0);
- dest_packed[1] = (src[7] << 24) | (src[8] << 16) | (src[3] << 8) | (src[4] << 0);
- dest_packed[2] = (src[9] << 24) | (src[10] << 16) | (src[11] << 8) | (src[6] << 0);
- }
-
- // epilog: handle left over pixels
- for (; pixel < src->width; ++pixel) {
- dest_data[pixel * 3 + 0] = src_data[pixel * 3 + 2];
- dest_data[pixel * 3 + 1] = src_data[pixel * 3 + 1];
- dest_data[pixel * 3 + 2] = src_data[pixel * 3 + 0];
- }
-
- src_data += sbpl;
- dest_data += dbpl;
- }
-}
-
-static bool convert_RGB888_to_BGR888_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB888 || data->format == QImage::Format_BGR888);
-
- const qsizetype bpl = data->bytes_per_line;
- uchar *line_data = data->data;
-
- for (int i = 0; i < data->height; ++i) {
- for (int j = 0; j < data->width; ++j)
- qSwap(line_data[j * 3 + 0], line_data[j * 3 + 2]);
- line_data += bpl;
- }
-
- switch (data->format) {
- case QImage::Format_RGB888:
- data->format = QImage::Format_BGR888;
- break;
- case QImage::Format_BGR888:
- data->format = QImage::Format_RGB888;
- break;
- default:
- Q_UNREACHABLE();
- data->format = QImage::Format_Invalid;
- return false;
- }
- return true;
-}
-
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2635,7 +2569,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
}, // Format_RGB888
{
@@ -2781,8 +2715,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
convert_passthrough,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_BGR30
@@ -2809,7 +2743,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<false>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
0, 0,
0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
@@ -2833,8 +2767,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_BGR30_to_RGB30,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
+ convert_rgbswap_generic,
0,
convert_passthrough,
0, 0, 0, 0, 0, 0, 0
@@ -2860,7 +2794,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
- convert_BGR30_to_RGB30,
+ convert_rgbswap_generic,
convert_A2RGB30_PM_to_RGB30<false>,
0,
0, 0,
@@ -3013,7 +2947,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGB888_to_BGR888,
+ convert_rgbswap_generic,
0,
0,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
@@ -3161,7 +3095,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_ARGB8555_Premultiplied
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace
+ convert_rgbswap_generic_inplace
}, // Format_RGB888
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -3267,7 +3201,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0, // self
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, 0,
0, 0, 0, 0, 0
@@ -3295,7 +3229,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
{
@@ -3318,7 +3252,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
@@ -3345,7 +3279,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30_inplace<true>,
- convert_BGR30_to_RGB30_inplace,
+ convert_rgbswap_generic_inplace,
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
0, 0,
@@ -3427,7 +3361,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
}, // Format_Grayscale16
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- convert_RGB888_to_BGR888_inplace,
+ convert_rgbswap_generic_inplace,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_BGR888
};
diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h
index 66db95df7e..70d2137119 100644
--- a/src/gui/painting/qcolormatrix_p.h
+++ b/src/gui/painting/qcolormatrix_p.h
@@ -226,12 +226,6 @@ public:
{ 0.1351922452f, 0.7118769884f, 0.0000000000f },
{ 0.0313525312f, 0.0000856627f, 0.8251883388f } };
}
- static QColorMatrix toXyzFromBt2020()
- {
- return QColorMatrix { { 0.6506130099f, 0.2695676684f, -0.0018652577f },
- { 0.1865101457f, 0.6840794086f, 0.0172256753f },
- { 0.1270887405f, 0.0463530831f, 0.8098278046f } };
- }
};
inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2)
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index 39ab358879..720c531e3f 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -70,12 +70,6 @@ QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries)
bluePoint = QPointF(0.150, 0.060);
whitePoint = QColorVector::D65Chromaticity();
break;
- case QColorSpace::Primaries::Bt2020:
- redPoint = QPointF(0.708, 0.292);
- greenPoint = QPointF(0.190, 0.797);
- bluePoint = QPointF(0.131, 0.046);
- whitePoint = QColorVector::D65Chromaticity();
- break;
case QColorSpace::Primaries::AdobeRgb:
redPoint = QPointF(0.640, 0.330);
greenPoint = QPointF(0.210, 0.710);
@@ -191,11 +185,6 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::NamedColorSpace namedColorSp
transferFunction = QColorSpace::TransferFunction::ProPhotoRgb;
description = QStringLiteral("ProPhoto RGB");
break;
- case QColorSpace::Bt2020:
- primaries = QColorSpace::Primaries::Bt2020;
- transferFunction = QColorSpace::TransferFunction::Bt2020;
- description = QStringLiteral("BT.2020");
- break;
default:
Q_UNREACHABLE();
}
@@ -277,14 +266,6 @@ void QColorSpacePrivate::identifyColorSpace()
}
}
break;
- case QColorSpace::Primaries::Bt2020:
- if (transferFunction == QColorSpace::TransferFunction::Bt2020) {
- namedColorSpace = QColorSpace::Bt2020;
- if (description.isEmpty())
- description = QStringLiteral("BT.2020");
- return;
- }
- break;
default:
break;
}
@@ -335,12 +316,6 @@ void QColorSpacePrivate::setTransferFunction()
if (qFuzzyIsNull(gamma))
gamma = 1.8f;
break;
- case QColorSpace::TransferFunction::Bt2020:
- trc[0].m_type = QColorTrc::Type::Function;
- trc[0].m_fun = QColorTransferFunction::fromBt2020();
- if (qFuzzyIsNull(gamma))
- gamma = 1.961f;
- break;
case QColorSpace::TransferFunction::Custom:
break;
default:
@@ -415,8 +390,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\l{http://www.color.org/chardata/rgb/DCIP3.xalter}{ICC registration of DCI-P3}
\value ProPhotoRgb The Pro Photo RGB color space, also known as ROMM RGB is a very wide gamut color space.
\l{http://www.color.org/chardata/rgb/rommrgb.xalter}{ICC registration of ROMM RGB}
- \value Bt2020 BT.2020 also known as Rec.2020 is the color space of HDR TVs.
- \l{http://www.color.org/chardata/rgb/BT2020.xalter}{ICC registration of BT.2020}
*/
/*!
@@ -429,7 +402,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value AdobeRgb The Adobe RGB primaries
\value DciP3D65 The DCI-P3 primaries with the D65 whitepoint
\value ProPhotoRgb The ProPhoto RGB primaries with the D50 whitepoint
- \value Bt2020 The BT.2020 primaries
*/
/*!
@@ -442,7 +414,6 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
\value Gamma A transfer function that is a real gamma curve based on the value of gamma()
\value SRgb The sRGB transfer function, composed of linear and gamma parts
\value ProPhotoRgb The ProPhoto RGB transfer function, composed of linear and gamma parts
- \value Bt2020 The BT.2020 transfer function, composed of linear and gamma parts
*/
/*!
@@ -457,7 +428,7 @@ QColorSpace::QColorSpace()
*/
QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
{
- static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::Bt2020 + 1];
+ static QColorSpacePrivate *predefinedColorspacePrivates[QColorSpace::ProPhotoRgb + 1];
if (!predefinedColorspacePrivates[namedColorSpace]) {
predefinedColorspacePrivates[namedColorSpace] = new QColorSpacePrivate(namedColorSpace);
predefinedColorspacePrivates[namedColorSpace]->ref.ref();
diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h
index 11987b9a37..e6bc62d58a 100644
--- a/src/gui/painting/qcolorspace.h
+++ b/src/gui/painting/qcolorspace.h
@@ -59,8 +59,7 @@ public:
SRgbLinear,
AdobeRgb,
DisplayP3,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(NamedColorSpace)
enum class Primaries {
@@ -68,8 +67,7 @@ public:
SRgb,
AdobeRgb,
DciP3D65,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(Primaries)
enum class TransferFunction {
@@ -77,8 +75,7 @@ public:
Linear,
Gamma,
SRgb,
- ProPhotoRgb,
- Bt2020,
+ ProPhotoRgb
};
Q_ENUM(TransferFunction)
diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h
index fd7cfa2b2b..0575dbd888 100644
--- a/src/gui/painting/qcolortransferfunction_p.h
+++ b/src/gui/painting/qcolortransferfunction_p.h
@@ -130,10 +130,6 @@ public:
{
return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f);
}
- static QColorTransferFunction fromBt2020()
- {
- return QColorTransferFunction(1.0f / 1.0993f, 0.0993f / 1.0993f, 1.0f / 4.5f, 0.08145f, 0.0f, 0.0f, 2.2f);
- }
static QColorTransferFunction fromProPhotoRgb()
{
return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f);
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c17bf2ddfd..edb363ac69 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -669,8 +669,7 @@ static void QT_FASTCALL rbSwap_rgb30(uchar *d, const uchar *s, int count)
{
const uint *src = reinterpret_cast<const uint *>(s);
uint *dest = reinterpret_cast<uint *>(d);
- for (int i = 0; i < count; ++i)
- dest[i] = qRgbSwapRgb30(src[i]);
+ UNALIASED_CONVERSION_LOOP(dest, src, count, qRgbSwapRgb30);
}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
@@ -6774,6 +6773,9 @@ static void qInitDrawhelperFunctions()
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
+ extern void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count);
+ qPixelLayouts[QImage::Format_RGB888].rbSwap = rbSwap_888_ssse3;
+ qPixelLayouts[QImage::Format_BGR888].rbSwap = rbSwap_888_ssse3;
}
#endif // SSSE3
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 35d61c3e6c..14d7047bb6 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -40,7 +40,7 @@
#include <private/qdrawhelper_x86_p.h>
-#ifdef QT_COMPILER_SUPPORTS_SSSE3
+#if defined(QT_COMPILER_SUPPORTS_SSSE3)
#include <private/qdrawingprimitive_sse2_p.h>
@@ -254,6 +254,49 @@ void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count)
}
}
+void QT_FASTCALL rbSwap_888_ssse3(uchar *dst, const uchar *src, int count)
+{
+ int i = 0;
+
+ const static __m128i shuffleMask1 = _mm_setr_epi8(2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, /*!!*/15);
+ const static __m128i shuffleMask2 = _mm_setr_epi8(0, /*!!*/1, 4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11, /*!!*/14, 15);
+ const static __m128i shuffleMask3 = _mm_setr_epi8(/*!!*/0, 3, 2, 1, 6, 5, 4, 9, 8, 7, 12, 11, 10, 15, 14, 13);
+
+ for (; i + 15 < count; i += 16) {
+ __m128i s1 = _mm_loadu_si128((const __m128i *)src);
+ __m128i s2 = _mm_loadu_si128((const __m128i *)(src + 16));
+ __m128i s3 = _mm_loadu_si128((const __m128i *)(src + 32));
+ s1 = _mm_shuffle_epi8(s1, shuffleMask1);
+ s2 = _mm_shuffle_epi8(s2, shuffleMask2);
+ s3 = _mm_shuffle_epi8(s3, shuffleMask3);
+ _mm_storeu_si128((__m128i *)dst, s1);
+ _mm_storeu_si128((__m128i *)(dst + 16), s2);
+ _mm_storeu_si128((__m128i *)(dst + 32), s3);
+
+ // Now fix the last four misplaced values
+ std::swap(dst[15], dst[17]);
+ std::swap(dst[30], dst[32]);
+
+ src += 48;
+ dst += 48;
+ }
+
+ if (src != dst) {
+ SIMD_EPILOGUE(i, count, 15) {
+ dst[0] = src[2];
+ dst[1] = src[1];
+ dst[2] = src[0];
+ dst += 3;
+ src += 3;
+ }
+ } else {
+ SIMD_EPILOGUE(i, count, 15) {
+ std::swap(dst[0], dst[2]);
+ dst += 3;
+ }
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_COMPILER_SUPPORTS_SSSE3
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
index 45b64de960..18f212f8e9 100644
--- a/src/gui/painting/qicc.cpp
+++ b/src/gui/painting/qicc.cpp
@@ -687,9 +687,6 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
} else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
- } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) {
- qCDebug(lcIcc) << "fromIccProfile: BT.2020 primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::Bt2020;
}
if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c71d82546a..601dc97be1 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -446,14 +446,22 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->setRedBlueSwizzle(false);
}
- // There is no way to tell if the OpenGL-rendered content is premultiplied or not.
- // For compatibility, assume that it is not, and use normal alpha blend always.
- if (d_ptr->premultiplied)
- funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
-
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
+ bool blendIsPremultiplied = d_ptr->premultiplied;
for (int i = 0; i < textures->count(); ++i) {
- if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
+ const QPlatformTextureList::Flags flags = textures->flags(i);
+ if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
+ if (!blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = true;
+ }
+ } else {
+ if (blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = false;
+ }
+ }
+ if (flags.testFlag(QPlatformTextureList::StacksOnTop))
blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
}
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 414d2bf0de..4f08b0092f 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -81,7 +81,8 @@ class Q_GUI_EXPORT QPlatformTextureList : public QObject
public:
enum Flag {
StacksOnTop = 0x01,
- TextureIsSrgb = 0x02
+ TextureIsSrgb = 0x02,
+ NeedsPremultipliedAlphaBlending = 0x04
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 3e136cdb80..9e8533be23 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -1220,7 +1220,6 @@ void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cb
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
quint32 bpl = 0;
- QSize blockDim;
textureFormatInfo(texD->m_format, size, &bpl, nullptr);
box.left = dp.x();
box.top = dp.y();
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 07753c985c..dfa79edb00 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -997,11 +997,44 @@ void QRhiMetal::setVertexInput(QRhiCommandBuffer *cb,
}
}
+QSize safeOutputSize(QRhiMetal *rhiD, QMetalCommandBuffer *cbD)
+{
+ QSize size = cbD->currentTarget->pixelSize();
+
+ // So now we have the issue that the texture (drawable) size may have
+ // changed again since swapchain buildOrResize() was called. This can
+ // happen for example when interactively resizing the window a lot in one
+ // go, and command buffer building happens on a dedicated thread (f.ex.
+ // using the threaded render loop of Qt Quick).
+ //
+ // This is only an issue when running in debug mode with XCode because Metal
+ // validation will fail when setting viewport or scissor with the real size
+ // being smaller than what we think it is. So query the drawable size right
+ // here, in debug mode at least.
+ //
+ // In addition, we have to take the smaller of the two widths and heights
+ // to be safe, apparently. In some cases validation seems to think that the
+ // "render pass width" (or height) is the old(?) value.
+
+#ifdef QT_DEBUG
+ if (cbD->currentTarget->resourceType() == QRhiResource::RenderTarget) {
+ Q_ASSERT(rhiD->currentSwapChain);
+ const QSize otherSize = rhiD->currentSwapChain->surfacePixelSize();
+ size.setWidth(qMin(size.width(), otherSize.width()));
+ size.setHeight(qMin(size.height(), otherSize.height()));
+ }
+#else
+ Q_UNUSED(rhiD);
+#endif
+
+ return size;
+}
+
void QRhiMetal::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
{
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
- const QSize outputSize = cbD->currentTarget->pixelSize();
+ const QSize outputSize = safeOutputSize(this, cbD);
// x,y is top-left in MTLViewportRect but bottom-left in QRhiViewport
float x, y, w, h;
@@ -1033,7 +1066,7 @@ void QRhiMetal::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::RenderPass);
Q_ASSERT(QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->m_flags.testFlag(QRhiGraphicsPipeline::UsesScissor));
- const QSize outputSize = cbD->currentTarget->pixelSize();
+ const QSize outputSize = safeOutputSize(this, cbD);
// x,y is top-left in MTLScissorRect but bottom-left in QRhiScissor
int x, y, w, h;