diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qbackingstore.cpp | 41 | ||||
-rw-r--r-- | src/gui/painting/qcolor.cpp | 105 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_avx2.cpp | 154 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_sse4.cpp | 36 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qpathsimplifier.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpathsimplifier_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qpdf.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qstroker.cpp | 27 | ||||
-rw-r--r-- | src/gui/painting/qtransform.cpp | 19 | ||||
-rw-r--r-- | src/gui/painting/qtransform.h | 2 |
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 ®ion) 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 ®ion) // 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 ®ion) */ 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 ®ion, 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 ®ion, 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 ®ion, 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; |