summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qbackingstore.cpp41
-rw-r--r--src/gui/painting/qcolor.cpp105
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp154
-rw-r--r--src/gui/painting/qdrawhelper_sse4.cpp36
-rw-r--r--src/gui/painting/qpainter.cpp9
-rw-r--r--src/gui/painting/qpainterpath.cpp6
-rw-r--r--src/gui/painting/qpathsimplifier.cpp2
-rw-r--r--src/gui/painting/qpathsimplifier_p.h2
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/painting/qstroker.cpp27
-rw-r--r--src/gui/painting/qtransform.cpp19
-rw-r--r--src/gui/painting/qtransform.h2
12 files changed, 227 insertions, 178 deletions
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 8d71d1c3a9..d935deb4d6 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -62,7 +62,7 @@ public:
}
QWindow *window;
- QPlatformBackingStore *platformBackingStore;
+ QPlatformBackingStore *platformBackingStore = nullptr;
QScopedPointer<QImage> highDpiBackingstore;
QRegion staticContents;
QSize size;
@@ -95,8 +95,6 @@ public:
QBackingStore::QBackingStore(QWindow *window)
: d_ptr(new QBackingStorePrivate(window))
{
- d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(window);
- d_ptr->platformBackingStore->setBackingStore(this);
}
/*!
@@ -131,7 +129,8 @@ void QBackingStore::beginPaint(const QRegion &region)
d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio())
resize(size());
- d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
+ QPlatformBackingStore *platformBackingStore = handle();
+ platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
// When QtGui is applying a high-dpi scale factor the backing store
// creates a "large" backing store image. This image needs to be
@@ -139,7 +138,7 @@ void QBackingStore::beginPaint(const QRegion &region)
// devicePixelRatio. Do this on a separate image instance that shares
// the image data to avoid having the new devicePixelRatio be propagated
// back to the platform plugin.
- QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = platformBackingStore->paintDevice();
if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) {
QImage *source = static_cast<QImage *>(device);
const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
@@ -168,7 +167,7 @@ void QBackingStore::beginPaint(const QRegion &region)
*/
QPaintDevice *QBackingStore::paintDevice()
{
- QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = handle()->paintDevice();
if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image)
return d_ptr->highDpiBackingstore.data();
@@ -189,7 +188,18 @@ void QBackingStore::endPaint()
if (paintDevice()->paintingActive())
qWarning() << "QBackingStore::endPaint() called with active painter on backingstore paint device";
- d_ptr->platformBackingStore->endPaint();
+ handle()->endPaint();
+}
+
+static bool isRasterSurface(QWindow *window)
+{
+ switch (window->surfaceType()) {
+ case QSurface::RasterSurface:
+ case QSurface::RasterGLSurface:
+ return true;
+ default:
+ return false;
+ };
}
/*!
@@ -220,6 +230,13 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
return;
}
+ if (!isRasterSurface(window)) {
+ qWarning() << "Attempted flush to non-raster surface" << window << "of type" << window->surfaceType()
+ << (window->inherits("QWidgetWindow") ? "(consider using Qt::WA_PaintOnScreen to exclude "
+ "from backingstore sync)" : "");
+ return;
+ }
+
#ifdef QBACKINGSTORE_DEBUG
if (window && window->isTopLevel() && !qt_window_private(window)->receivedExpose) {
qWarning().nospace() << "QBackingStore::flush() called with non-exposed window "
@@ -229,7 +246,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients));
- d_ptr->platformBackingStore->flush(window, QHighDpi::toNativeLocalRegion(region, window),
+ handle()->flush(window, QHighDpi::toNativeLocalRegion(region, window),
QHighDpi::toNativeLocalPosition(offset, window));
}
@@ -241,7 +258,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
void QBackingStore::resize(const QSize &size)
{
d_ptr->size = size;
- d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
+ handle()->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
}
/*!
@@ -268,7 +285,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
return false;
- return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
+ return handle()->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
nativeDx, nativeDy);
}
@@ -349,6 +366,10 @@ void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPo
*/
QPlatformBackingStore *QBackingStore::handle() const
{
+ if (!d_ptr->platformBackingStore) {
+ d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window);
+ d_ptr->platformBackingStore->setBackingStore(const_cast<QBackingStore*>(this));
+ }
return d_ptr->platformBackingStore;
}
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index b3fa1eedde..07202f5b1c 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -541,7 +541,15 @@ static QStringList get_colornames()
\section1 The HSL Color Model
HSL is similar to HSV, however instead of the Value parameter, HSL
- specifies a Lightness parameter.
+ specifies a Lightness parameter which maps somewhat differently to the
+ brightness of the color.
+
+ Similarly, the HSL saturation value is not in general the same as the HSV
+ saturation value for the same color. hslSaturation() provides the color's
+ HSL saturation value, while saturation() and hsvSaturation() provides the
+ HSV saturation value.
+
+ The hue value is defined to be the same in HSL and HSV.
\section1 The CMYK Color Model
@@ -1098,7 +1106,7 @@ void QColor::setHsv(int h, int s, int v, int a)
These components can be retrieved individually using the hslHueF(),
hslSaturationF(), lightnessF() and alphaF() functions.
- \sa setHsl()
+ \sa getHsl(), setHslF(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const
{
@@ -1128,7 +1136,7 @@ void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const
These components can be retrieved individually using the hslHue(),
hslSaturation(), lightness() and alpha() functions.
- \sa setHsl()
+ \sa getHslF(), setHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
void QColor::getHsl(int *h, int *s, int *l, int *a) const
{
@@ -1619,11 +1627,11 @@ void QColor::setBlueF(qreal blue)
}
/*!
- Returns the hue color component of this color.
+ Returns the HSV hue color component of this color.
The color is implicitly converted to HSV.
- \sa hsvHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa hsvHue(), hslHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
int QColor::hue() const Q_DECL_NOTHROW
@@ -1632,9 +1640,9 @@ int QColor::hue() const Q_DECL_NOTHROW
}
/*!
- Returns the hue color component of this color.
+ Returns the HSV hue color component of this color.
- \sa hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa hueF(), hslHue(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
int QColor::hsvHue() const Q_DECL_NOTHROW
{
@@ -1644,11 +1652,11 @@ int QColor::hsvHue() const Q_DECL_NOTHROW
}
/*!
- Returns the saturation color component of this color.
+ Returns the HSV saturation color component of this color.
The color is implicitly converted to HSV.
- \sa hsvSaturation(), saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color
+ \sa hsvSaturation(), hslSaturation(), saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color
Model}
*/
@@ -1658,9 +1666,9 @@ int QColor::saturation() const Q_DECL_NOTHROW
}
/*!
- Returns the saturation color component of this color.
+ Returns the HSV saturation color component of this color.
- \sa saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa saturationF(), hslSaturation(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
int QColor::hsvSaturation() const Q_DECL_NOTHROW
{
@@ -1682,11 +1690,11 @@ int QColor::value() const Q_DECL_NOTHROW
}
/*!
- Returns the hue color component of this color.
+ Returns the HSV hue color component of this color.
The color is implicitly converted to HSV.
- \sa hsvHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa hsvHueF(), hslHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
qreal QColor::hueF() const Q_DECL_NOTHROW
{
@@ -1696,7 +1704,7 @@ qreal QColor::hueF() const Q_DECL_NOTHROW
/*!
Returns the hue color component of this color.
- \sa hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
+ \sa hue(), hslHueF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
Model}
*/
qreal QColor::hsvHueF() const Q_DECL_NOTHROW
@@ -1707,11 +1715,11 @@ qreal QColor::hsvHueF() const Q_DECL_NOTHROW
}
/*!
- Returns the saturation color component of this color.
+ Returns the HSV saturation color component of this color.
The color is implicitly converted to HSV.
- \sa hsvSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
+ \sa hsvSaturationF(), hslSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
Model}
*/
qreal QColor::saturationF() const Q_DECL_NOTHROW
@@ -1720,9 +1728,9 @@ qreal QColor::saturationF() const Q_DECL_NOTHROW
}
/*!
- Returns the saturation color component of this color.
+ Returns the HSV saturation color component of this color.
- \sa saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa saturation(), hslSaturationF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
qreal QColor::hsvSaturationF() const Q_DECL_NOTHROW
{
@@ -1746,9 +1754,9 @@ qreal QColor::valueF() const Q_DECL_NOTHROW
/*!
\since 4.6
- Returns the hue color component of this color.
+ Returns the HSL hue color component of this color.
- \sa getHslF(), getHsl()
+ \sa hslHueF(), hsvHue(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
int QColor::hslHue() const Q_DECL_NOTHROW
{
@@ -1760,9 +1768,9 @@ int QColor::hslHue() const Q_DECL_NOTHROW
/*!
\since 4.6
- Returns the saturation color component of this color.
+ Returns the HSL saturation color component of this color.
- \sa saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
+ \sa hslSaturationF(), hsvSaturation(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
int QColor::hslSaturation() const Q_DECL_NOTHROW
{
@@ -1788,9 +1796,9 @@ int QColor::lightness() const Q_DECL_NOTHROW
/*!
\since 4.6
- Returns the hue color component of this color.
+ Returns the HSL hue color component of this color.
- \sa hue(), getHslF()
+ \sa hslHue(), hsvHueF(), getHslF()
*/
qreal QColor::hslHueF() const Q_DECL_NOTHROW
{
@@ -1802,9 +1810,9 @@ qreal QColor::hslHueF() const Q_DECL_NOTHROW
/*!
\since 4.6
- Returns the saturation color component of this color.
+ Returns the HSL saturation color component of this color.
- \sa saturationF(), getHslF()
+ \sa hslSaturation(), hsvSaturationF(), getHslF(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
qreal QColor::hslSaturationF() const Q_DECL_NOTHROW
{
@@ -2124,7 +2132,7 @@ QColor QColor::toHsv() const Q_DECL_NOTHROW
/*!
Creates and returns an HSL QColor based on this color.
- \sa fromHsl(), convertTo(), isValid()
+ \sa fromHsl(), convertTo(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
QColor QColor::toHsl() const Q_DECL_NOTHROW
{
@@ -2193,27 +2201,32 @@ QColor QColor::toCmyk() const Q_DECL_NOTHROW
color.cspec = Cmyk;
color.ct.acmyk.alpha = ct.argb.alpha;
- // rgb -> cmy
- const qreal r = ct.argb.red / qreal(USHRT_MAX);
- const qreal g = ct.argb.green / qreal(USHRT_MAX);
- const qreal b = ct.argb.blue / qreal(USHRT_MAX);
- qreal c = qreal(1.0) - r;
- qreal m = qreal(1.0) - g;
- qreal y = qreal(1.0) - b;
-
- // cmy -> cmyk
- const qreal k = qMin(c, qMin(m, y));
-
- if (!qFuzzyIsNull(k - 1)) {
+ if (!ct.argb.red && !ct.argb.green && !ct.argb.blue) {
+ // Avoid div-by-0 below
+ color.ct.acmyk.cyan = 0;
+ color.ct.acmyk.magenta = 0;
+ color.ct.acmyk.yellow = 0;
+ color.ct.acmyk.black = USHRT_MAX;
+ } else {
+ // rgb -> cmy
+ const qreal r = ct.argb.red / qreal(USHRT_MAX);
+ const qreal g = ct.argb.green / qreal(USHRT_MAX);
+ const qreal b = ct.argb.blue / qreal(USHRT_MAX);
+ qreal c = qreal(1.0) - r;
+ qreal m = qreal(1.0) - g;
+ qreal y = qreal(1.0) - b;
+
+ // cmy -> cmyk
+ const qreal k = qMin(c, qMin(m, y));
c = (c - k) / (qreal(1.0) - k);
m = (m - k) / (qreal(1.0) - k);
y = (y - k) / (qreal(1.0) - k);
- }
- color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
- color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
- color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
- color.ct.acmyk.black = qRound(k * USHRT_MAX);
+ color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
+ color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
+ color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
+ color.ct.acmyk.black = qRound(k * USHRT_MAX);
+ }
return color;
}
@@ -2431,7 +2444,7 @@ QColor QColor::fromHsvF(qreal h, qreal s, qreal v, qreal a)
The value of \a s, \a l, and \a a must all be in the range 0-255; the value
of \a h must be in the range 0-359.
- \sa toHsl(), fromHslF(), isValid()
+ \sa toHsl(), fromHslF(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
QColor QColor::fromHsl(int h, int s, int l, int a)
{
@@ -2463,7 +2476,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a)
All the values must be in the range 0.0-1.0.
- \sa toHsl(), fromHsl(), isValid()
+ \sa toHsl(), fromHsl(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
{
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index 4a3e24d6d5..2b3cc9b226 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -995,16 +995,11 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *
}
}
-static inline __m128i maskFromCount(qsizetype count)
+static inline __m256i epilogueMaskFromCount(qsizetype count)
{
Q_ASSERT(count > 0);
- static const qint64 data[] = { -1, -1, 0, 0 };
- auto ptr = reinterpret_cast<const quint8 *>(data) + sizeof(__m128i);
-
- if (count > int(sizeof(__m128i)))
- return _mm_set1_epi8(-1);
-
- return _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr - count));
+ static const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
+ return _mm256_add_epi32(offsetMask, _mm256_set1_epi32(-count));
}
template<bool RGBA>
@@ -1050,40 +1045,39 @@ static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype
}
}
- for ( ; i < count; i += 4) {
- __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask);
- __m128i mask = maskFromCount((count - i) * sizeof(*src));
- maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask);
- __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask);
+ if (i < count) {
+ const __m256i epilogueMask = epilogueMaskFromCount(count - i);
+ __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask);
+ const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
- if (!_mm_testz_si128(srcVector, maskedAlphaMask)) {
+ if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
// keep the two _mm_test[zc]_siXXX next to each other
- bool cf = _mm_testc_si128(srcVector, maskedAlphaMask);
+ bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask);
if (RGBA)
- srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask));
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
if (!cf) {
- __m128i src1 = _mm_unpacklo_epi8(srcVector, _mm256_castsi256_si128(zero));
- __m128i src2 = _mm_unpackhi_epi8(srcVector, _mm256_castsi256_si128(zero));
- __m128i alpha1 = _mm_shuffle_epi8(src1, _mm256_castsi256_si128(shuffleMask));
- __m128i alpha2 = _mm_shuffle_epi8(src2, _mm256_castsi256_si128(shuffleMask));
- src1 = _mm_mullo_epi16(src1, alpha1);
- src2 = _mm_mullo_epi16(src2, alpha2);
- src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 8));
- src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 8));
- src1 = _mm_add_epi16(src1, _mm256_castsi256_si128(half));
- src2 = _mm_add_epi16(src2, _mm256_castsi256_si128(half));
- src1 = _mm_srli_epi16(src1, 8);
- src2 = _mm_srli_epi16(src2, 8);
- src1 = _mm_blend_epi16(src1, alpha1, 0x88);
- src2 = _mm_blend_epi16(src2, alpha2, 0x88);
- srcVector = _mm_packus_epi16(src1, src2);
- _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, srcVector);
+ __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero);
+ __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero);
+ __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ src1 = _mm256_mullo_epi16(src1, alpha1);
+ src2 = _mm256_mullo_epi16(src2, alpha2);
+ src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8));
+ src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8));
+ src1 = _mm256_add_epi16(src1, half);
+ src2 = _mm256_add_epi16(src2, half);
+ src1 = _mm256_srli_epi16(src1, 8);
+ src2 = _mm256_srli_epi16(src2, 8);
+ src1 = _mm256_blend_epi16(src1, alpha1, 0x88);
+ src2 = _mm256_blend_epi16(src2, alpha2, 0x88);
+ srcVector = _mm256_packus_epi16(src1, src2);
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector);
} else {
if (buffer != src || RGBA)
- _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, srcVector);
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector);
}
} else {
- _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, _mm256_castsi256_si128(zero));
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, zero);
}
}
}
@@ -1116,13 +1110,13 @@ template<bool RGBA>
static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizetype count)
{
qsizetype i = 0;
- const __m256i alphaMask = _mm256_broadcastsi128_si256(_mm_set1_epi32(0xff000000));
+ const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15));
const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15));
const __m256i zero = _mm256_setzero_si256();
for (; i < count - 7; i += 8) {
- __m256i src1, src2;
+ __m256i dst1, dst2;
__m256i srcVector = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i));
if (!_mm256_testz_si256(srcVector, alphaMask)) {
// keep the two _mm_test[zc]_siXXX next to each other
@@ -1138,64 +1132,66 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety
// after unpacklo/hi [ P1, P2; P3, P4 ] [ P5, P6; P7, P8 ]
srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0));
+ const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector);
+ const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector);
if (!cf) {
- src1 = _mm256_unpacklo_epi8(srcVector, zero);
- src2 = _mm256_unpackhi_epi8(srcVector, zero);
- __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
- __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
- src1 = _mm256_mullo_epi16(src1, alpha1);
- src2 = _mm256_mullo_epi16(src2, alpha2);
- alpha1 = _mm256_unpacklo_epi8(srcVector, srcVector);
- alpha2 = _mm256_unpackhi_epi8(srcVector, srcVector);
- src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 7));
- src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 7));
- src1 = _mm256_blend_epi16(src1, alpha1, 0x88);
- src2 = _mm256_blend_epi16(src2, alpha2, 0x88);
+ const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ dst1 = _mm256_mulhi_epu16(src1, alpha1);
+ dst2 = _mm256_mulhi_epu16(src2, alpha2);
+ dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15));
+ dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15));
+ dst1 = _mm256_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm256_blend_epi16(dst2, src2, 0x88);
} else {
- src1 = _mm256_unpacklo_epi8(srcVector, srcVector);
- src2 = _mm256_unpackhi_epi8(srcVector, srcVector);
+ dst1 = src1;
+ dst2 = src2;
}
} else {
- src1 = src2 = zero;
+ dst1 = dst2 = zero;
}
- _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), src1);
- _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, src2);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), dst1);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, dst2);
}
- for ( ; i < count; i += 4) {
- __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask);
- __m128i mask = maskFromCount((count - i) * sizeof(*src));
- maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask);
- __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask);
- __m256i src;
+ if (i < count) {
+ __m256i epilogueMask = epilogueMaskFromCount(count - i);
+ const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
+ __m256i dst1, dst2;
+ __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask);
- if (!_mm_testz_si128(srcVector, maskedAlphaMask)) {
+ if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
// keep the two _mm_test[zc]_siXXX next to each other
- bool cf = _mm_testc_si128(srcVector, maskedAlphaMask);
+ bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask);
if (!RGBA)
- srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask));
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
+ srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0));
+ const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector);
+ const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector);
if (!cf) {
- src = _mm256_cvtepu8_epi16(srcVector);
- __m256i alpha = _mm256_shuffle_epi8(src, shuffleMask);
- src = _mm256_mullo_epi16(src, alpha);
-
- __m128i alpha1 = _mm_unpacklo_epi8(srcVector, srcVector);
- __m128i alpha2 = _mm_unpackhi_epi8(srcVector, srcVector);
- alpha = _mm256_inserti128_si256(_mm256_castsi128_si256(alpha1), alpha2, 1);
- src = _mm256_add_epi16(src, _mm256_srli_epi16(src, 7));
- src = _mm256_blend_epi16(src, alpha, 0x88);
+ const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ dst1 = _mm256_mulhi_epu16(src1, alpha1);
+ dst2 = _mm256_mulhi_epu16(src2, alpha2);
+ dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15));
+ dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15));
+ dst1 = _mm256_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm256_blend_epi16(dst2, src2, 0x88);
} else {
- const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector);
- const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector);
- src = _mm256_castsi128_si256(src1);
- src = _mm256_inserti128_si256(src, src2, 1);
+ dst1 = src1;
+ dst2 = src2;
}
} else {
- src = zero;
+ dst1 = dst2 = zero;
}
- __m256i xmask = _mm256_cvtepi32_epi64(mask);
- _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i), xmask, src);
- };
+ epilogueMask = _mm256_permute4x64_epi64(epilogueMask, _MM_SHUFFLE(3, 1, 2, 0));
+ _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i),
+ _mm256_unpacklo_epi32(epilogueMask, epilogueMask),
+ dst1);
+ _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i + 4),
+ _mm256_unpackhi_epi32(epilogueMask, epilogueMask),
+ dst2);
+ }
}
const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count,
diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp
index 1da3b75ade..d9a687b1b4 100644
--- a/src/gui/painting/qdrawhelper_sse4.cpp
+++ b/src/gui/painting/qdrawhelper_sse4.cpp
@@ -107,28 +107,26 @@ static void convertARGBToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int cou
for (; i < count - 3; i += 4) {
__m128i srcVector = _mm_loadu_si128((const __m128i *)&src[i]);
if (!_mm_testz_si128(srcVector, alphaMask)) {
- if (!_mm_testc_si128(srcVector, alphaMask)) {
- if (!RGBA)
- srcVector = _mm_shuffle_epi8(srcVector, rgbaMask);
- __m128i src1 = _mm_unpacklo_epi8(srcVector, zero);
- __m128i src2 = _mm_unpackhi_epi8(srcVector, zero);
+ bool cf = _mm_testc_si128(srcVector, alphaMask);
+
+ if (!RGBA)
+ srcVector = _mm_shuffle_epi8(srcVector, rgbaMask);
+ const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector);
+ const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector);
+ if (!cf) {
__m128i alpha1 = _mm_shuffle_epi8(src1, shuffleMask);
__m128i alpha2 = _mm_shuffle_epi8(src2, shuffleMask);
- src1 = _mm_mullo_epi16(src1, alpha1);
- src2 = _mm_mullo_epi16(src2, alpha2);
- alpha1 = _mm_unpacklo_epi8(srcVector, srcVector);
- alpha2 = _mm_unpackhi_epi8(srcVector, srcVector);
- src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 7));
- src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 7));
- src1 = _mm_blend_epi16(src1, alpha1, 0x88);
- src2 = _mm_blend_epi16(src2, alpha2, 0x88);
- _mm_storeu_si128((__m128i *)&buffer[i], src1);
- _mm_storeu_si128((__m128i *)&buffer[i + 2], src2);
+ __m128i dst1 = _mm_mulhi_epu16(src1, alpha1);
+ __m128i dst2 = _mm_mulhi_epu16(src2, alpha2);
+ // Map 0->0xfffe to 0->0xffff
+ dst1 = _mm_add_epi16(dst1, _mm_srli_epi16(dst1, 15));
+ dst2 = _mm_add_epi16(dst2, _mm_srli_epi16(dst2, 15));
+ // correct alpha value:
+ dst1 = _mm_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm_blend_epi16(dst2, src2, 0x88);
+ _mm_storeu_si128((__m128i *)&buffer[i], dst1);
+ _mm_storeu_si128((__m128i *)&buffer[i + 2], dst2);
} else {
- if (!RGBA)
- srcVector = _mm_shuffle_epi8(srcVector, rgbaMask);
- const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector);
- const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector);
_mm_storeu_si128((__m128i *)&buffer[i], src1);
_mm_storeu_si128((__m128i *)&buffer[i + 2], src2);
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index c746df9dd6..95e6bda78b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -2981,7 +2981,10 @@ void QPainter::setMatrix(const QMatrix &matrix, bool combine)
const QMatrix &QPainter::matrix() const
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
return worldMatrix();
+QT_WARNING_POP
}
@@ -4216,7 +4219,7 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
*/
void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd)
{
- drawRoundRect(QRectF(rect), xRnd, yRnd);
+ drawRoundedRect(QRectF(rect), xRnd, yRnd, Qt::RelativeSize);
}
/*!
@@ -4230,7 +4233,7 @@ void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd)
*/
void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
{
- drawRoundRect(QRectF(x, y, w, h), xRnd, yRnd);
+ drawRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize);
}
#endif
@@ -8346,7 +8349,7 @@ void QPainter::resetTransform()
d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
d->state->worldMatrix = QTransform();
- setMatrixEnabled(false);
+ setWorldMatrixEnabled(false);
setViewTransformEnabled(false);
if (d->extended)
d->extended->transformChanged();
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index cb8bb9dfcf..42f94d038f 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -3318,7 +3318,7 @@ void QPainterPath::addRoundRect(const QRectF &rect,
xRnd = int(roundness * rect.height()/rect.width());
else
yRnd = int(roundness * rect.width()/rect.height());
- addRoundRect(rect, xRnd, yRnd);
+ addRoundedRect(rect, xRnd, yRnd, Qt::RelativeSize);
}
/*!
@@ -3339,7 +3339,7 @@ void QPainterPath::addRoundRect(const QRectF &rect,
void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
int xRnd, int yRnd)
{
- addRoundRect(QRectF(x, y, w, h), xRnd, yRnd);
+ addRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize);
}
/*!
@@ -3363,7 +3363,7 @@ void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
int roundness)
{
- addRoundRect(QRectF(x, y, w, h), roundness);
+ addRoundedRect(QRectF(x, y, w, h), roundness, Qt::RelativeSize);
}
#endif
diff --git a/src/gui/painting/qpathsimplifier.cpp b/src/gui/painting/qpathsimplifier.cpp
index 40585ec502..4251840bbc 100644
--- a/src/gui/painting/qpathsimplifier.cpp
+++ b/src/gui/painting/qpathsimplifier.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
diff --git a/src/gui/painting/qpathsimplifier_p.h b/src/gui/painting/qpathsimplifier_p.h
index 6ef298f6bf..6c0062c592 100644
--- a/src/gui/painting/qpathsimplifier_p.h
+++ b/src/gui/painting/qpathsimplifier_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index b23cc903b1..6bdc82a8e9 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1542,7 +1542,7 @@ bool QPdfEngine::end()
Q_D(QPdfEngine);
d->writeTail();
- d->stream->unsetDevice();
+ d->stream->setDevice(nullptr);
qDeleteAll(d->fonts);
d->fonts.clear();
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 0a3d802b21..c01531caf2 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -456,12 +456,12 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
return;
}
#endif
+ QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y),
+ qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y));
+ QPointF isect;
+ QLineF::IntersectType type = prevLine.intersect(nextLine, &isect);
if (join == FlatJoin) {
- QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y),
- qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y));
- QPointF isect;
- QLineF::IntersectType type = prevLine.intersect(nextLine, &isect);
QLineF shortCut(prevLine.p2(), nextLine.p1());
qreal angle = shortCut.angleTo(prevLine);
if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
@@ -473,12 +473,6 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qt_real_to_fixed(nextLine.y1()));
} else {
- QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y),
- qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y));
-
- QPointF isect;
- QLineF::IntersectType type = prevLine.intersect(nextLine, &isect);
-
if (join == MiterJoin) {
qreal appliedMiterLimit = qt_fixed_to_real(m_strokeWidth * m_miterLimit);
@@ -513,7 +507,11 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qfixed offset = m_strokeWidth / 2;
QLineF l1(prevLine);
- l1.translate(l1.dx(), l1.dy());
+ qreal dp = QPointF::dotProduct(QPointF(prevLine.dx(), prevLine.dy()), QPointF(nextLine.dx(), nextLine.dy()));
+ if (dp > 0) // same direction, means that prevLine is from a bezier that has been "reversed" by shifting
+ l1 = QLineF(prevLine.p2(), prevLine.p1());
+ else
+ l1.translate(l1.dx(), l1.dy());
l1.setLength(qt_fixed_to_real(offset));
QLineF l2(nextLine.p2(), nextLine.p1());
l2.translate(l2.dx(), l2.dy());
@@ -571,7 +569,11 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
// first control line
QLineF l1 = prevLine;
- l1.translate(l1.dx(), l1.dy());
+ qreal dp = QPointF::dotProduct(QPointF(prevLine.dx(), prevLine.dy()), QPointF(nextLine.dx(), nextLine.dy()));
+ if (dp > 0) // same direction, means that prevLine is from a bezier that has been "reversed" by shifting
+ l1 = QLineF(prevLine.p2(), prevLine.p1());
+ else
+ l1.translate(l1.dx(), l1.dy());
l1.setLength(QT_PATH_KAPPA * offset);
// second control line, find through normal between prevLine and focal.
@@ -706,7 +708,6 @@ template <class Iterator> bool qt_stroke_side(Iterator *it,
QPointF(qt_fixed_to_real(e.x), qt_fixed_to_real(e.y)),
QPointF(qt_fixed_to_real(cp2.x), qt_fixed_to_real(cp2.y)),
QPointF(qt_fixed_to_real(ep.x), qt_fixed_to_real(ep.y)));
-
int count = bezier.shifted(offsetCurves,
MAX_OFFSET,
offset,
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 5f9e037ff0..816514a695 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1517,8 +1517,23 @@ QRegion QTransform::map(const QRegion &r) const
return copy;
}
- if (t == TxScale && r.rectCount() == 1)
- return QRegion(mapRect(r.boundingRect()));
+ if (t == TxScale) {
+ QRegion res;
+ if (m11() < 0 || m22() < 0) {
+ for (const QRect &rect : r)
+ res += mapRect(rect);
+ } else {
+ QVarLengthArray<QRect, 32> rects;
+ rects.reserve(r.rectCount());
+ for (const QRect &rect : r) {
+ QRect nr = mapRect(rect);
+ if (!nr.isEmpty())
+ rects.append(nr);
+ }
+ res.setRects(rects.constData(), rects.count());
+ }
+ return res;
+ }
QPainterPath p = map(qt_regionToPath(r));
return p.toFillPolygon(QTransform()).toPolygon();
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index 7460a405be..1e322d435a 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -245,10 +245,12 @@ inline qreal QTransform::determinant() const
return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
}
+#if QT_DEPRECATED_SINCE(5, 13)
inline qreal QTransform::det() const
{
return determinant();
}
+#endif
inline qreal QTransform::m11() const
{
return affine._m11;