b=484864; StretchDIBits takes too long (Do 32->24 conversion before calling StretchDIBits); r=jrmuizel

This commit is contained in:
Vladimir Vukicevic 2009-04-14 15:12:38 -07:00
Родитель 4fbc43f426
Коммит 0ba32b706d
1 изменённых файлов: 66 добавлений и 0 удалений

Просмотреть файл

@ -84,6 +84,9 @@
#define PAINT_USE_IMAGE_SURFACE
// do 32->24 conversion before calling StretchDIBits
#define PAINT_USE_IMAGE_SURFACE_24BPP
#ifdef WINCE_WINDOWS_MOBILE
#define WINCE_HAVE_SOFTKB
#include "tpcshell.h"
@ -6075,6 +6078,69 @@ PRBool nsWindow::OnPaint(HDC aDC)
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
#ifdef PAINT_USE_IMAGE_SURFACE_24BPP
// On Windows CE/Windows Mobile, 24bpp packed-pixel sources
// seem to be far faster to blit than 32bpp (see bug 484864).
// So, convert the bits to 24bpp by stripping out the unused
// alpha byte. 24bpp DIBs also have scanlines that are 4-byte
// aligned though, so that must be taken into account.
int srcstride = surfaceSize.width*4;
int dststride = surfaceSize.width*3;
dststride = (dststride + 3) & ~3;
// Convert in place
for (int j = 0; j < surfaceSize.height; ++j) {
unsigned int *src = (unsigned int*) (targetSurface->Data() + j*srcstride);
unsigned int *dst = (unsigned int*) (targetSurface->Data() + j*dststride);
// go 4 pixels at a time, since each 4 pixels
// turns into 3 DWORDs when converted into BGR:
// BGRx BGRx BGRx BGRx -> BGRB GRBG RBGR
//
// However, since we're dealing with little-endian ints, this is actually:
// xRGB xrgb xRGB xrgb -> bRGB GBrg rgbR
int width_left = surfaceSize.width;
while (width_left > 4) {
unsigned int a = *src++;
unsigned int b = *src++;
unsigned int c = *src++;
unsigned int d = *src++;
*dst++ = (a & 0x00ffffff) | (b << 24);
*dst++ = ((b & 0x00ffff00) >> 8) | (c << 16);
*dst++ = ((c & 0x00ff0000) >> 16) | (d << 8);
width_left -= 4;
}
// then finish up whatever number of pixels are left,
// using bytes.
unsigned char *bsrc = (unsigned char*) src;
unsigned char *bdst = (unsigned char*) dst;
switch (width_left) {
case 3:
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
bsrc++;
case 2:
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
bsrc++;
case 1:
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
*bdst++ = *bsrc++;
bsrc++;
case 0:
break;
}
}
bi.biBitCount = 24;
#endif
StretchDIBits(hDC,
ps.rcPaint.left, ps.rcPaint.top,
surfaceSize.width, surfaceSize.height,