summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qblendfunctions.cpp
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-04-20 07:49:14 +0200
committerGunnar Sletta <gunnar@trolltech.com>2009-04-20 10:10:41 +0200
commit8047e8b5ac359e7470211a37e266d429c3641839 (patch)
tree76f2bfd7627d86c108db43cb98f1b31c4ba523ae /src/gui/painting/qblendfunctions.cpp
parent2c5ec5867c0d40f17906aa7b23380218d392970a (diff)
Make the 32-bit ARGBPM on 16-bit RGB blend function faster
The "optimized" version of this function was actually slower by quite a bit, so revert it to the old "trivial" code. Reviewed-by: Samuel
Diffstat (limited to 'src/gui/painting/qblendfunctions.cpp')
-rw-r--r--src/gui/painting/qblendfunctions.cpp134
1 files changed, 33 insertions, 101 deletions
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 70cea4d6f9..dd7b0161be 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -416,113 +416,45 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
}
quint16 *dst = (quint16 *) destPixels;
- int dstExtraStride = dbpl / 2 - w;
-
- const quint32 *src = (const quint32 *) srcPixels;
- int srcExtraStride = sbpl / 4 - w;
+ quint32 *src = (quint32 *) srcPixels;
for (int y=0; y<h; ++y) {
- int length = w;
- const int dstAlign = ((quintptr)dst) & 0x3;
- if (dstAlign) {
- const quint8 alpha = qAlpha(*src);
- if (alpha) {
- quint16 s = convert_argb32_to_rgb16(*src);
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
- }
- ++dst;
- ++src;
- --length;
- }
+ for (int x=0; x<w; ++x) {
- const int length32 = length >> 1;
- const int srcAlign = ((quintptr)src) & 0x3;
- if (length32) {
- if (srcAlign) {
- for (int i = 0; i < length32; ++i) {
- quint32 *dest32 = reinterpret_cast<quint32*>(dst);
- const quint8 a1 = qAlpha(src[0]);
- const quint8 a2 = qAlpha(src[1]);
- quint32 s;
-
- if (!a1 && !a2) {
- src += 2;
- dst +=2;
- continue;
- }
-
- s = convert_argb32_to_rgb16(src[0])
- | (convert_argb32_to_rgb16(src[1]) << 16);
-
- if (a1 == a2) {
- if (a1 < 255) {
- const quint8 sa = ((255 - a1)+1) >> 3;
- s += BYTE_MUL_RGB16_32(*dest32, sa);
- }
- } else {
- if (a1 < 255)
- s += BYTE_MUL_RGB16(dst[0], 255 - a1);
- if (a2 < 255)
- s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
- }
-
- *dest32 = s;
- src += 2;
- dst += 2;
- }
- } else {
- for (int i = 0; i < length32; ++i) {
- quint32 *dest32 = reinterpret_cast<quint32*>(dst);
- const quint8 a1 = qAlpha(src[0]);
- const quint8 a2 = qAlpha(src[1]);
- quint32 s;
-
- if (!a1 && !a2) {
- src += 2;
- dst +=2;
- continue;
- }
-
- const quint64 *src64 =
- reinterpret_cast<const quint64*>(src);
- s = qConvertRgb32To16x2(*src64);
-
- if (a1 == a2) {
- if (a1 < 255) {
- const quint8 sa = ((255 - a1)+1) >> 3;
- s += BYTE_MUL_RGB16_32(*dest32, sa);
- }
- } else {
- if (a1 < 255)
- s += BYTE_MUL_RGB16(dst[0], 255 - a1);
- if (a2 < 255)
- s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
- }
-
- *dest32 = s;
- src += 2;
- dst += 2;
- }
- }
- }
- const int tail = length & 0x1;
- if (tail) {
- const quint8 alpha = qAlpha(*src);
- if (alpha) {
- quint16 s = convert_argb32_to_rgb16(*src);
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
+ quint32 spix = src[x];
+ quint32 alpha = spix >> 24;
+
+ if (alpha == 255) {
+ dst[x] = convert_argb32_to_rgb16(spix);
+ } else if (alpha != 0) {
+ quint32 dpix = dst[x];
+
+ quint32 sia = 255 - alpha;
+
+ quint32 sr = (spix >> 8) & 0xf800;
+ quint32 sg = (spix >> 5) & 0x07e0;
+ quint32 sb = (spix >> 3) & 0x001f;
+
+ quint32 dr = (dpix & 0x0000f800);
+ quint32 dg = (dpix & 0x000007e0);
+ quint32 db = (dpix & 0x0000001f);
+
+ quint32 siar = dr * sia;
+ quint32 siag = dg * sia;
+ quint32 siab = db * sia;
+
+ quint32 rr = sr + ((siar + (siar>>8) + (0x80 << 8)) >> 8);
+ quint32 rg = sg + ((siag + (siag>>8) + (0x80 << 3)) >> 8);
+ quint32 rb = sb + ((siab + (siab>>8) + (0x80 >> 3)) >> 8);
+
+ dst[x] = (rr & 0xf800)
+ | (rg & 0x07e0)
+ | (rb);
}
- ++dst;
- ++src;
}
- dst += dstExtraStride;
- src += srcExtraStride;
+ dst = (quint16 *) (((uchar *) dst) + dbpl);
+ src = (quint32 *) (((uchar *) src) + sbpl);
}
-
}