diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-05-17 12:26:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-05-22 11:04:16 +0000 |
commit | 7fbc7c9600b37e6adb4c3acf679d3e07b04bdb8e (patch) | |
tree | 967139f45a3d551297a1249208a1f830973f16df /src/gui/image/qimage_conversions.cpp | |
parent | e794c1bb797fad2bff579075c499d27c42055c02 (diff) |
Optimize conversion from unpremultiplied to opaque formats
Save unnecessary premultiply and unpremultiplication when converting
from an unpremultiplied format like ARGB32 to any opaque format like
RGB32 or RGB16.
Change-Id: I73f58200ff5c62fb07910e6f2b1c29b7e254d327
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/gui/image/qimage_conversions.cpp')
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 50fad1566c..659e7d9901 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -126,8 +126,8 @@ static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint return buffer; } -static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count, - const QVector<QRgb> *, QDitherInfo *) +static const uint *QT_FASTCALL maskRGB32(uint *buffer, const uint *src, int count, + const QVector<QRgb> *, QDitherInfo *) { for (int i = 0; i < count; ++i) buffer[i] = 0xff000000 |src[i]; @@ -160,8 +160,9 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. convertFromARGB32PM = destLayout->convertFromRGB32; } else { + // The drawhelpers do not mask the alpha value in RGB32, we want to here. if (src->format == QImage::Format_RGB32) - convertToARGB32PM = convertRGB32ToARGB32PM; + convertToARGB32PM = maskRGB32; if (dest->format == QImage::Format_RGB32) { #ifdef QT_COMPILER_SUPPORTS_SSE4_1 if (qCpuHasFeature(SSE4_1)) @@ -171,6 +172,15 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio convertFromARGB32PM = convertRGB32FromARGB32PM; } } + if ((src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888) && + destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + // Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format. + convertToARGB32PM = qPixelLayouts[src->format + 1].convertToARGB32PM; + if (dest->format == QImage::Format_RGB32) + convertFromARGB32PM = maskRGB32; + else + convertFromARGB32PM = destLayout->convertFromRGB32; + } QDitherInfo dither; QDitherInfo *ditherPtr = 0; if ((flags & Qt::PreferDither) && (flags & Qt::Dither_Mask) != Qt::ThresholdDither) @@ -221,7 +231,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im convertFromARGB32PM = destLayout->convertFromRGB32; } else { if (data->format == QImage::Format_RGB32) - convertToARGB32PM = convertRGB32ToARGB32PM; + convertToARGB32PM = maskRGB32; if (dst_format == QImage::Format_RGB32) { #ifdef QT_COMPILER_SUPPORTS_SSE4_1 if (qCpuHasFeature(SSE4_1)) @@ -231,6 +241,15 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im convertFromARGB32PM = convertRGB32FromARGB32PM; } } + if ((data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888) && + destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + // Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format. + convertToARGB32PM = qPixelLayouts[data->format + 1].convertToARGB32PM; + if (dst_format == QImage::Format_RGB32) + convertFromARGB32PM = maskRGB32; + else + convertFromARGB32PM = destLayout->convertFromRGB32; + } QDitherInfo dither; QDitherInfo *ditherPtr = 0; if ((flags & Qt::PreferDither) && (flags & Qt::Dither_Mask) != Qt::ThresholdDither) |