From 6cc050c969b6dde1566f2b71f32829e680557350 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 25 Feb 2016 14:08:11 +0100 Subject: Avoid qMin in format conversions when possible Calling qMin often prevents effective vectorization, and it is only necessary when converting from formats with mixed color-channel widths. Change-Id: I2a0f3f3fb528d45be1fd025758f9d915ee1736c0 Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper.cpp | 82 +++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'src/gui/painting') diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 933ff407e2..85c023f1ff 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -245,17 +245,36 @@ static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth() - 8; Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth() - 8; - for (int i = 0; i < count; ++i) { - uint alpha = (src[i] >> alphaShift()) & alphaMask; - uint red = (src[i] >> redShift()) & redMask; - uint green = (src[i] >> greenShift()) & greenMask; - uint blue = (src[i] >> blueShift()) & blueMask; - - alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); - red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); - green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); - blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); - buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; + Q_CONSTEXPR bool mustMin = (alphaWidth() != redWidth()) || + (alphaWidth() != greenWidth()) || + (alphaWidth() != blueWidth()); + + if (mustMin) { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> alphaShift()) & alphaMask; + uint red = (src[i] >> redShift()) & redMask; + uint green = (src[i] >> greenShift()) & greenMask; + uint blue = (src[i] >> blueShift()) & blueMask; + + alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); + red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); + green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); + blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); + buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; + } + } else { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> alphaShift()) & alphaMask; + uint red = (src[i] >> redShift()) & redMask; + uint green = (src[i] >> greenShift()) & greenMask; + uint blue = (src[i] >> blueShift()) & blueMask; + + alpha = ((alpha << alphaLeftShift) | (alpha >> alphaRightShift)) << 24; + red = ((red << redLeftShift) | (red >> redRightShift)) << 16; + green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8; + blue = (blue << blueLeftShift) | (blue >> blueRightShift); + buffer[i] = alpha | red | green | blue; + } } return buffer; @@ -280,17 +299,36 @@ static const QRgba64 *QT_FASTCALL convertARGBPMToARGB64PM(QRgba64 *buffer, const Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth() - 8; Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth() - 8; - for (int i = 0; i < count; ++i) { - uint alpha = (src[i] >> alphaShift()) & alphaMask; - uint red = (src[i] >> redShift()) & redMask; - uint green = (src[i] >> greenShift()) & greenMask; - uint blue = (src[i] >> blueShift()) & blueMask; - - alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); - red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); - green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); - blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); - buffer[i] = QRgba64::fromRgba(red, green, blue, alpha); + Q_CONSTEXPR bool mustMin = (alphaWidth() != redWidth()) || + (alphaWidth() != greenWidth()) || + (alphaWidth() != blueWidth()); + + if (mustMin) { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> alphaShift()) & alphaMask; + uint red = (src[i] >> redShift()) & redMask; + uint green = (src[i] >> greenShift()) & greenMask; + uint blue = (src[i] >> blueShift()) & blueMask; + + alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); + red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); + green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); + blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); + buffer[i] = QRgba64::fromRgba(red, green, blue, alpha); + } + } else { + for (int i = 0; i < count; ++i) { + uint alpha = (src[i] >> alphaShift()) & alphaMask; + uint red = (src[i] >> redShift()) & redMask; + uint green = (src[i] >> greenShift()) & greenMask; + uint blue = (src[i] >> blueShift()) & blueMask; + + alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); + red = (red << redLeftShift) | (red >> redRightShift); + green = (green << greenLeftShift) | (green >> greenRightShift); + blue = (blue << blueLeftShift) | (blue >> blueRightShift); + buffer[i] = QRgba64::fromRgba(red, green, blue, alpha); + } } return buffer; -- cgit v1.2.3