From a2ec5e88f657b52c7eecffd2904aa59cd9644d14 Mon Sep 17 00:00:00 2001 From: "rjesup%wgate.com" Date: Tue, 19 Feb 2002 01:48:33 +0000 Subject: [PATCH] Bug 125025: Animations use a lot of CPU, even when not visible. r=pavlov, sr=brendan. Heavily optimizes all the bit-twiddling in mask generation which was 1/2 of where the CPU time was going. git-svn-id: svn://10.0.0.236/trunk@114860 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/libpr0n/src/imgContainer.cpp | 95 ++++++++++++++++---- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/mozilla/modules/libpr0n/src/imgContainer.cpp b/mozilla/modules/libpr0n/src/imgContainer.cpp index ebd06019587..6ec79ff8b32 100644 --- a/mozilla/modules/libpr0n/src/imgContainer.cpp +++ b/mozilla/modules/libpr0n/src/imgContainer.cpp @@ -747,38 +747,95 @@ void imgContainer::BuildCompositeMask(gfxIImageFrame *aCompositingFrame, gfxIIma case gfxIFormats::RGB_A1: case gfxIFormats::BGR_A1: { - - for(PRUint32 y=overlayYOffset, i=0; - i>3); // Windows and OS/2 have the funky bottom up data storage we need to account for #if defined(XP_WIN) || defined(XP_OS2) - offset = ((heightOverlay - 1) * abprOverlay) - i*abprOverlay; + offset = (heightOverlay - 1) * abprOverlay; #else - offset = i*abprOverlay; + offset = 0; #endif - PRUint8* overlayLine = overlayAlphaData + offset; - for (PRUint32 x=overlayXOffset, j=0; - j>3] & (1<<((7-j)&0x7))) - alphaLine[x>>3] |= 1<<((7-x)&0x7); + PRUint8* overlayLine = overlayAlphaData + offset; + + /* + This is the number of pixels of offset between alpha and overlay + (the number of bits at the front of alpha to skip when starting + a row). + I.e:, for a mask_offset of 3: + (these are representations of bits) + overlay 'pixels': 76543210 hgfedcba + alpha: xxx76543 210hgfed ... + where 'x' is data already in alpha + the first 5 pixels of overlay are or'd into the low 5 bits of alpha + */ + PRUint8 mask_offset = (overlayXOffset & 0x7); + + for(PRUint32 i=0; i < height; i++) { + PRUint8 pixels; + PRUint32 j; + // use locals to avoid keeping track of how much we need to add + // at the end of a line. we don't really need this since we may + // be able to calculate the ending offsets, but it's simpler and + // cheap. + PRUint8 *localOverlay = overlayLine; + PRUint8 *localAlpha = alphaLine; + + for (j = width; j >= 8; j -= 8) { + // don't do in for(...) to avoid reference past end of buffer + pixels = *localOverlay++; + + if (pixels == 0) { + // no bits to set - iterate and bump output pointer + localAlpha++; + } + else { + // for the last few bits of a line, we need to special-case it + if (mask_offset == 0) { + // simple case, no offset + *localAlpha++ |= pixels; + } + else { + *localAlpha++ |= (pixels >> mask_offset); + *localAlpha |= (pixels << (8U-mask_offset)); + } + } } + if (j != 0) { + // handle the end of the line, 1 to 7 pixels + pixels = *localOverlay++; + if (pixels != 0) { + // last few bits have to be handled more carefully if + // width is not a multiple of 8. + + // set bits we don't want to change to 0 + pixels = (pixels >> (8U-j)) << (8U-j); + *localAlpha++ |= (pixels >> mask_offset); + // don't touch this byte unless we have bits for it + if (j > (8U - mask_offset)) + *localAlpha |= (pixels << (8U-mask_offset)); + } + } + +/// Windows and OS/2 have the funky bottom up data storage we need to account for +#if defined(XP_WIN) || defined(XP_OS2) + alphaLine -= abprComposite; + overlayLine -= abprOverlay; +#else + alphaLine += abprComposite; + overlayLine += abprOverlay; +#endif } } - break; default: break;