Extend high color rendering to image rendering

A previous commit added 16-bit per color-channel precision to
solids and linear gradients. This patch extends that to include
texture data.

To support that pixellayouts now have a method to convert to
RGBA64.

Change-Id: I661ae91bd7038085787003608a0af4add057e478
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
bb10
Allan Sandfeld Jensen 2015-04-09 10:49:27 +02:00
parent 3610513450
commit ac659cd203
3 changed files with 1068 additions and 73 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1139,6 +1139,8 @@ void QT_FASTCALL rasterop_solid_NotDestination(uint *dest, int length, uint colo
struct QPixelLayout;
typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count,
const QPixelLayout *layout, const QRgb *clut);
typedef const QRgba64 *(QT_FASTCALL *ConvertFunc64)(QRgba64 *buffer, const uint *src, int count,
const QPixelLayout *layout, const QRgb *clut);
struct QPixelLayout
{
@ -1168,6 +1170,7 @@ struct QPixelLayout
ConvertFunc convertToARGB32PM;
ConvertFunc convertFromARGB32PM;
ConvertFunc convertFromRGB32;
ConvertFunc64 convertToARGB64PM;
};
typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);

View File

@ -36,6 +36,7 @@
#include <QtGui/qrgba64.h>
#include <QtGui/private/qdrawhelper_p.h>
#include <private/qsimd_p.h>
QT_BEGIN_NAMESPACE
@ -52,20 +53,36 @@ inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
(rgba64.alpha() * alpha256) >> 8);
}
inline QRgba64 multiplyAlpha255(QRgba64 rgba64, uint alpha255)
{
return QRgba64::fromRgba64(qt_div_255(rgba64.red() * alpha255),
qt_div_255(rgba64.green() * alpha255),
qt_div_255(rgba64.blue() * alpha255),
qt_div_255(rgba64.alpha() * alpha255));
}
inline QRgba64 multiplyAlpha65535(QRgba64 rgba64, uint alpha65535)
{
#ifdef __SSE2__
const __m128i va = _mm_shufflelo_epi16(_mm_cvtsi32_si128(alpha65535), _MM_SHUFFLE(0, 0, 0, 0));
__m128i vs = _mm_loadl_epi64((__m128i*)&rgba64);
vs = _mm_unpacklo_epi16(_mm_mullo_epi16(vs, va), _mm_mulhi_epu16(vs, va));
vs = _mm_add_epi32(vs, _mm_srli_epi32(vs, 16));
vs = _mm_add_epi32(vs, _mm_set1_epi32(0x8000));
vs = _mm_srai_epi32(vs, 16);
vs = _mm_packs_epi32(vs, _mm_setzero_si128());
_mm_storel_epi64((__m128i*)&rgba64, vs);
return rgba64;
#else
return QRgba64::fromRgba64(qt_div_65535(rgba64.red() * alpha65535),
qt_div_65535(rgba64.green() * alpha65535),
qt_div_65535(rgba64.blue() * alpha65535),
qt_div_65535(rgba64.alpha() * alpha65535));
#endif
}
inline QRgba64 multiplyAlpha255(QRgba64 rgba64, uint alpha255)
{
#ifdef __SSE2__
return multiplyAlpha65535(rgba64, alpha255 * 257);
#else
return QRgba64::fromRgba64(qt_div_255(rgba64.red() * alpha255),
qt_div_255(rgba64.green() * alpha255),
qt_div_255(rgba64.blue() * alpha255),
qt_div_255(rgba64.alpha() * alpha255));
#endif
}
inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)