diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/screendriver/sbit/FastBlend.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/screendriver/sbit/FastBlend.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,2583 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include "../inc/BMDRAW.H" +#include + +// Current plan is to depreciate 16MA targets so we have removed acceleration of these. +// To re-enable put the __SUPPORT_16MA_TARGET__ back in +//#define __SUPPORT_16MA_TARGET__ + +// Enabling __CHECK_ALPHA01__ causes checks for alpha values of 0 and 1 to be made to attempt to +// accelerate handling of these cases. This may not always work as branching the execution path +// can potentially lose more time than is gained. + +#define __CHECK_ALPHA01__ + +#define WRITE_RUN \ + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 7: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 6: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 5: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 4: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 3: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 2: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 1: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN2ROT \ + FORCEINLINE static void write2rot(const TUint8* aSrc, TUint8* aDst, TInt aLen, TInt aSrcStep, TInt aDstStep) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 7: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 6: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 5: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 4: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 3: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 2: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + case 1: write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN2H \ + static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen); + +#define WRITE_RUN2C(class3232) \ + void class3232::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 7: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 6: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 5: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 4: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 3: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 2: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + case 1: write(aSrc, aDst);aSrc+=4;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN2416 \ + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 7: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 6: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 5: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 4: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 3: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 2: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 1: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN3216 \ + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 7: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 6: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 5: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 4: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 3: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 2: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 1: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN3216C2(class3216) \ + void class3216::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 7: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 6: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 5: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 4: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 3: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 2: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + case 1: write(aSrc, aDst);aSrc+=4;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN2416C2(class2416) \ + void class2416::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 7: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 6: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 5: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 4: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 3: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 2: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + case 1: write(aSrc, aDst);aSrc+=3;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_RUN1632 \ + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 7: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 6: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 5: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 4: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 3: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 2: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + case 1: write(aSrc, aDst);aSrc+=2;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +// Using non-inline versions can make better usage of registers, need to experiment to find fastest mix + +#define WRITE_RUN1632C(class1632) \ + void class1632::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)\ + { \ + const TUint16* lowAdd = Convert16to32bppLow();\ + const TUint32* highAdd = Convert16to32bppHigh();\ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 7: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 6: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 5: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 4: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 3: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 2: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + case 1: Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN \ + FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 7: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 6: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 5: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 4: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 3: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 2: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + case 1: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN3216 \ + FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 7: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 6: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 5: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 4: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 3: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 2: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + case 1: writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN2416 \ + FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 7: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 6: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 5: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 4: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 3: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 2: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + case 1: writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN1632 \ + FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 7: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 6: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 5: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 4: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 3: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 2: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + case 1: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN1632H \ + static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen); + +#define WRITE_ALPHA_MASK_RUN1632C(class1632) \ + void class1632::writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + const TUint8* srcPtr=aSrc;\ + TUint8* dstPtr=aDst;\ + const TUint8* alphaPtr=aAlpha;\ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 7: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 6: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 5: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 4: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 3: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 2: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + case 1: writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \ + } while ((aLen -= 8) > 0); \ + } \ + aSrc=srcPtr;\ + aDst=dstPtr;\ + aAlpha=alphaPtr;\ + } + +#define WRITE_ALPHA_MASK_RUN1616 \ + FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 7: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 6: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 5: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 4: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 3: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 2: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + case 1: writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN_ROT32 \ + FORCEINLINE static void writeAlphaMaskRot(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen, TInt aSrcStride, TInt aMaskStride)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 7: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 6: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 5: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 4: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 3: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 2: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + case 1: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define WRITE_ALPHA_MASK_RUN_ROT16 \ + FORCEINLINE static void writeAlphaMaskRot(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen, TInt aSrcStride, TInt aMaskStride)\ + { \ + switch (aLen % 8) /* aLen > 0 assumed */ \ + { \ + case 0: do { writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 7: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 6: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 5: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 4: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 3: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 2: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + case 1: writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \ + } while ((aLen -= 8) > 0); \ + } \ + } + +#define MultAlphaWithSrcAlpha(aAlpha, aSrc)\ + {\ + const TUint32 src=*(TUint32*)aSrc;\ + TUint32 srcAlpha=src>>24;\ + aAlpha=(aAlpha*srcAlpha);\ + aAlpha+=srcAlpha;\ + aAlpha>>=8;\ + } + +// Takes a pre-multipled alpha source and additionally multiplies it by the alpha +// value so the source is effectively now pre-multiplied by both it's own alpha +// and the specified alpha. +// No aAlpha==0xFF or ==0 checks as should never come here in those situations +#define MultMapSrcByAlpha(aAlpha, aSrc)\ + {\ + TUint32 d1 = (aSrc>>8)&0x00FF00FF;\ + d1=d1*aAlpha+d1;\ + TUint32 d2=aSrc&0x00FF00FF;\ + d2=d2*aAlpha+d2;\ + aSrc=(d1&0xFF00FF00)|((d2&0xFF00FF00)>>8);\ + } + +#define Write16MTo64K(aSrc, aDst)\ + {\ + TInt color64K=(aSrc & 0x0000f8) >> 3;\ + color64K|=(aSrc & 0x00fc00) >> 5;\ + color64K|=(aSrc & 0xf80000) >> 8;\ + *(TUint16*)aDst = color64K;\ + } + +// Calc new alpha as src+(1-src)*dst; +#define CalcDestMultAlpha(aDestMultAlpha, aDA, aSrcAlpha, aDstAlpha)\ + {\ + const TUint32 srcAlpha=aSrcAlpha;\ + const TUint32 dstAlpha=aDstAlpha;\ + aDA=dstAlpha<<16;\ + aDA=aDA*(0x100-srcAlpha);\ + aDA+=srcAlpha<<24;\ + aDestMultAlpha=(((0x100-srcAlpha)*dstAlpha)>>8)+1;\ + } + +// Note: This function assumes incoming rgb's are shifted up by an extra 8 bits as that's the +// most efficient way of processing the preceding functions with this final write to 64K handling +// the extra shift down. +#define WriteRedBlueAndGreenTo64K(aRedBlue, aGreen, aDst)\ + {\ + TInt targ64K=(aRedBlue&0x00f800) >> 11;\ + targ64K|=(aRedBlue&0xf8000000) >> 16;\ + targ64K|=(aGreen&0xfc0000) >> 13;\ + *(TUint16*)aDst = targ64K;\ + } + + +// Used for calculating blending from a MAP source to any of 16M dest formats. +#define CalcMapToMxRGBA(aSrcPixel, aDst, aDestMult, aDestAG, aDestRB)\ + {\ + const TUint32 dstPixel=*(TUint32*)aDst;\ + aDestAG=(dstPixel&0xFF00FF00)>>8;\ + aDestAG=aDestAG*aDestMult;\ + aDestAG+=aSrcPixel&0xFF00FF00;\ + aDestRB=dstPixel&0x00FF00FF;\ + aDestRB=(aDestRB*aDestMult)>>8;\ + aDestRB+=aSrcPixel&0x00FF00FF;\ + } + +// Used For non MAP source blending using dest=src*alpha+dest*destAlpha +// aDestMultAlpha is typically (1-aAlpha) or (srcAlpha+(1-srcAlpha)*destAlpha) +#define CalcMxToMxRGBA2A(aMxMxSrcPixel, aMxMxDestPixel, aMxMxAlpha, aMxMxDestMultAlpha, aMxMxDestAG, aMxMxDestRB)\ + {\ + aMxMxDestAG=(aMxMxDestPixel & 0xFF00FF00)>>8;\ + aMxMxDestAG=aMxMxDestAG*aMxMxDestMultAlpha;\ + TUint32 srcAG=(aMxMxSrcPixel&0xFF00FF00)>>8;\ + aMxMxDestAG&=0xFF00FF00;\ + TUint32 alphaPlus1=aMxMxAlpha+1;\ + aMxMxDestAG+=srcAG*alphaPlus1;\ + aMxMxDestRB=aMxMxDestPixel&0x00FF00FF;\ + aMxMxDestRB=aMxMxDestRB*aMxMxDestMultAlpha;\ + aMxMxDestRB&=0xFF00FF00;\ + TUint32 srcRB=(aMxMxSrcPixel&0x00FF00FF);\ + aMxMxDestRB+=srcRB*alphaPlus1;\ + aMxMxDestRB>>=8;\ + } + +// Used For non MAP source blending using dest=src*alpha+dest*(1-alpha) +#define CalcMxToMxRGBA(aSrc, aDest, aAlpha, aDestAG, aDestRB)\ + {\ + const TUint32 srcPixel=*(TUint32*)aSrc;\ + const TUint32 dstPixel=*(TUint32*)aDst;\ + const TUint32 oneMinusAlpha = 0x100 - aAlpha;\ + CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, oneMinusAlpha , aDestAG, aDestRB);\ + } + +#define WriteMu(aDestAG, aDestRB, aDst)\ + *(TUint32*)aDst=(aDestAG&0xFF00FF00)|(aDestRB&0x00FF00FF)|0xFF000000 + +#define WriteMxA(aDestG, aDestRB, aDestA, aDst)\ + *(TUint32*)aDst=(aDestG&0x0000FF00)|(aDestRB&0x00FF00FF)|(aDestA&0xFF000000) + +#define WriteMx(aDestAG, aDestRB, aDst)\ + *(TUint32*)aDst=(aDestAG&0xFF00FF00)|(aDestRB&0x00FF00FF) + +struct TMapToMu + { + #define writeMapMu(aSrc, aDst)\ + {\ + const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\ + TUint32 d1;\ + TUint32 d2;\ + CalcMapToMxRGBA(aSrc,aDst,oneMinusAlpha,d1,d2);\ + WriteMu(d1,d2,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + *(TUint32*)aDst = src; + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + writeMapMu(src, aDst); + } + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src>0x00FFFFFF) +#endif + { + MultMapSrcByAlpha(aAlpha,src); + // No aAlpha==0xFF check as should never come here in that situation + writeMapMu(src, aDst); + } + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMapToMa + { + #define writeMapMa(aSrc, aDst)\ + {\ + const TUint32 d=*(TUint32*)aDst;\ + TUint32 da;\ + TUint32 destMultAlpha;\ + CalcDestMultAlpha(destMultAlpha,da,aSrc>>24,d>>24);\ + TUint32 d1;\ + TUint32 d2;\ + CalcMapToMxRGBA(aSrc,aDst,destMultAlpha,d1,d2);\ + WriteMxA(d1,d2,da,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src>0x00FFFFFF) + { + if (src >= 0xFF000000) + *(TUint32*)aDst=src; + else + writeMapMa(src,aDst); + } +#else + writeMapMa(src,aDst); +#endif + } + WRITE_RUN + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src>0x00FFFFFF) +#endif + { + MultMapSrcByAlpha(aAlpha,src); + // No aAlpha==0xFF check as should never come here in that situation + writeMapMa(src,aDst); + } + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMapToMap + { + #define writeMapMap(aSrc, aDst)\ + {\ + const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\ + TUint32 d1;\ + TUint32 d2;\ + CalcMapToMxRGBA(aSrc,aDst,oneMinusAlpha,d1,d2);\ + WriteMx(d1,d2,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + *(TUint32*)aDst = src; + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + writeMapMap(src,aDst); + } + WRITE_RUN + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src<=0x00FFFFFF) + return; +#endif + MultMapSrcByAlpha(aAlpha,src); + // No aAlpha==0xFF check as should never come here in that situation + writeMapMap(src,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMaToMu + { + #define writeMaMu(aSrc, aAlpha, aDst)\ + {\ + TUint32 d1;\ + TUint32 d2;\ + CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);\ + WriteMu(d1,d2,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + *(TUint32*)aDst = src; + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + const TUint32 alpha=src>>24; + writeMaMu(aSrc,alpha,aDst); + } + WRITE_RUN + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + MultAlphaWithSrcAlpha(aAlpha,aSrc); + writeMaMu(aSrc,aAlpha,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMuToMu + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + *(TUint32*)aDst = *(TUint32*)aSrc; + } + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + aSrc+=aLen*4; + aDst+=aLen*4; + } + FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + } + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 d1; + TUint32 d2; + CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2); + WriteMu(d1,d2,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMuToMa + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + *(TUint32*)aDst = (*(TUint32*)aSrc); + } + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + aSrc+=aLen*4; + aDst+=aLen*4; + } + FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + } + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 da; + TUint32 d1; + TUint32 d2; + TUint32 destMultAlpha; + const TUint32 d = *(TUint32*)aDst; + CalcDestMultAlpha(destMultAlpha,da,aAlpha,d>>24); + const TUint32 srcPixel=*(TUint32*)aSrc; + const TUint32 dstPixel=*(TUint32*)aDst; + CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, destMultAlpha, d1, d2); + WriteMxA(d1,d2,da,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMaToMa + { + #define writeMaMa(aSrc, aAlpha, aDst)\ + {\ + TUint32 da;\ + TUint32 d1;\ + TUint32 d2;\ + TUint32 destMultAlpha;\ + const TUint32 d = *(TUint32*)aDst;\ + CalcDestMultAlpha(destMultAlpha,da,aAlpha,d>>24);\ + const TUint32 srcPixel=*(TUint32*)aSrc;\ + const TUint32 dstPixel=*(TUint32*)aDst;\ + CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, destMultAlpha, d1, d2);\ + WriteMxA(d1,d2,da,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + *(TUint32*)aDst = src; + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + const TUint32 alpha=src>>24; + writeMaMa(aSrc,alpha,aDst); + } + WRITE_RUN + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + MultAlphaWithSrcAlpha(aAlpha,aSrc); + writeMaMa(aSrc,aAlpha,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMaToMap + { + #define writeMaToMap(aSrc, aAlpha, aDst)\ + {\ + const TUint32 d = *(TUint32*)aDst;\ + const TUint32 oneMinusAlpha = 0x100-aAlpha;\ + TUint32 da=(d&0xFF000000)>>8;\ + da=da*oneMinusAlpha;\ + da+=aAlpha<<24;\ + TUint32 d1;\ + TUint32 d2;\ + CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);\ + WriteMxA(d1,d2,da,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + *(TUint32*)aDst = src; + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + const TUint32 alpha=src>>24; + writeMaToMap(aSrc,alpha,aDst); + } + WRITE_RUN + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + MultAlphaWithSrcAlpha(aAlpha,aSrc); + writeMaToMap(aSrc,aAlpha,aDst); + } + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct TMuToMap + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + *(TUint32*)aDst = (*(TUint32*)aSrc); + } + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + aSrc+=aLen*4; + aDst+=aLen*4; + } + FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) + { + Mem::Move(aDst,aSrc,aLen*sizeof(TUint32)); + } + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 d1; + TUint32 d2; + CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2); + WriteMx(d1,d2,aDst); + } + WRITE_ALPHA_MASK_RUN_ROT32 + WRITE_RUN2ROT + WRITE_ALPHA_MASK_RUN + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +WRITE_RUN2C(TMapToMap) +WRITE_RUN2C(TMapToMa) +WRITE_RUN2C(TMapToMu) +WRITE_RUN2C(TMaToMap) +WRITE_RUN2C(TMaToMa) +WRITE_RUN2C(TMaToMu) + +// reads green value from 64K source, or's it with 0xFF alpha channel, and leaves +// it shifted down by 8 ready for multiplying by alpha value. +#define ReadGreen64K(aRG64KGreen, aRG64KSrc)\ + aRG64KGreen=(aRG64KSrc&0x07E0)>>3;\ + aRG64KGreen=((aRG64KGreen+(aRG64KGreen>>6))&0x000000FF)|0x00FF0000; + +// Reads the red and blue values from a 64K source into their RGBA values. +#define ReadRedBlue64K(aRedBlue,aColor64K)\ + {\ + aRedBlue=(aColor64K&0xF800)<<8;\ + aRedBlue|=(aColor64K&0x001F)<<3;\ + aRedBlue+=aRedBlue>>5;\ + aRedBlue&=0x00FF00FF;\ + } + +// reads green value from 64K source into aGreen and red and blue into aRedBlue +// All left in correct place for 16M operations +#define Read64KColors(aGreen,aRedBlue,aPtr)\ + {\ + const TUint32 r64Kcolor64K=*(TUint16*)aPtr;\ + aGreen=(r64Kcolor64K&0x07E0)<<5;\ + aGreen+=aGreen>>6;\ + aGreen&=0x0000FF00;\ + ReadRedBlue64K(aRedBlue,r64Kcolor64K);\ + } + +struct TMapTo64K + { + #define writeMap64K(aSrc, aDst)\ + {\ + TUint32 green;\ + TUint32 redBlue;\ + Read64KColors(green,redBlue,aDst);\ + const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\ + green=green*oneMinusAlpha;\ + green+=(aSrc<<8)&0x00FF00FF;\ + redBlue=redBlue*oneMinusAlpha;\ + redBlue+=(aSrc&0x00FF00FF)<<8;\ + WriteRedBlueAndGreenTo64K(redBlue,green,aDst);\ + } + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + Write16MTo64K(src,aDst); + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + writeMap64K(src,aDst); + } + WRITE_RUN2H + WRITE_RUN3216 + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src<=0x00FFFFFF) + return; +#endif + MultMapSrcByAlpha(aAlpha,src); + // No aAlpha==0xFF check as should never come here in that situation + writeMap64K(src,aDst); + } + WRITE_ALPHA_MASK_RUN3216 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));}; + }; + +// Calculates green and redBlue shifted up by 8, that will be sorted in WriteRedBlueAndGreenTo64K +// this works out the most efficient way of getting the end result +// +// Note +++ +// Having the extra +greenSrc and +redBlueSrc (as in lines shown below) gives a better result, but +// is inconsistent with old code and causes test code failures, so it has been removed. +// greenSrc=greenSrc*aAlpha+greenSrc; +// redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; +#define WriteMaOrMuTo64K(aSrc, aDst, aAlpha)\ + {\ + const TUint32 src=*(TUint32*)aSrc;\ + TUint32 green;\ + TUint32 redBlue;\ + Read64KColors(green,redBlue,aDst);\ + const TUint32 oneMinusAlpha = 0x100-aAlpha;\ + green=green*oneMinusAlpha;\ + TUint32 greenSrc=src&0x0000FF00;\ + greenSrc=greenSrc*aAlpha;\ + green+=greenSrc;\ + redBlue=redBlue*oneMinusAlpha;\ + TUint32 redBlueSrc=src&0x00FF00FF;\ + redBlueSrc=redBlueSrc*aAlpha;\ + redBlue+=redBlueSrc;\ + WriteRedBlueAndGreenTo64K(redBlue,green,aDst);\ + } + +struct TMTo64K + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=aSrc[0]+(aSrc[1]<<8)+(aSrc[2]<<16); + Write16MTo64K(src,aDst); + } + WRITE_RUN2416 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + const TUint32 src=aSrc[0]+(aSrc[1]<<8)+(aSrc[2]<<16); + TUint32 green; + TUint32 redBlue; + Read64KColors(green,redBlue,aDst); + const TUint32 oneMinusAlpha = 0x100-aAlpha; + green=green*oneMinusAlpha; + TUint32 greenSrc=src&0x0000FF00; + greenSrc=greenSrc*aAlpha+greenSrc; + green+=greenSrc; + redBlue=redBlue*oneMinusAlpha; + TUint32 redBlueSrc=src&0x00FF00FF; + redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; + redBlue+=redBlueSrc; + WriteRedBlueAndGreenTo64K(redBlue,green,aDst); + } + WRITE_ALPHA_MASK_RUN2416 + FORCEINLINE static TInt SrcPixelBytes() {return(3);}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));}; + }; + +struct TMuTo64K + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; + Write16MTo64K(src,aDst); + } + WRITE_RUN3216 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + WriteMaOrMuTo64K(aSrc,aDst,aAlpha); + } + WRITE_ALPHA_MASK_RUN3216 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));}; + }; + +struct TMaTo64K + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + const TUint32 src=*(TUint32*)aSrc; +#if defined(__CHECK_ALPHA01__) + if (src >= 0xFF000000) + { + Write16MTo64K(src,aDst); + return; + } + if (src <= 0x00FFFFFF) + return; +#endif + const TUint32 alpha=src>>24; + WriteMaOrMuTo64K(aSrc,aDst,alpha); + } + WRITE_RUN3216 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + MultAlphaWithSrcAlpha(aAlpha,aSrc); + WriteMaOrMuTo64K(aSrc,aDst,aAlpha); + } + WRITE_ALPHA_MASK_RUN3216 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));}; + }; + +struct T64KTo64K + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + *(TUint16*)aDst=*(const TUint16 *)aSrc; + } + FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) + { + Mem::Copy(aDst,aSrc,aLen*sizeof(TUint16)); + aSrc+=aLen*2; + aDst+=aLen*2; + } + FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) + { + Mem::Copy(aDst,aSrc,aLen*sizeof(TUint16)); + } + WRITE_ALPHA_MASK_RUN_ROT16 + WRITE_RUN2ROT + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + const TUint32 oneMinusAlpha = 0x100-aAlpha; +// + TUint32 green; + TUint32 redBlue; + Read64KColors(green,redBlue,aDst); + green=green*oneMinusAlpha; + TUint32 greenSrc; + TUint32 redBlueSrc; + Read64KColors(greenSrc,redBlueSrc,aSrc); +// See note +++ +// greenSrc=greenSrc*aAlpha+greenSrc; + greenSrc=greenSrc*aAlpha; + green+=greenSrc; // needs shift down by 8, but do that when going to 64K +// + redBlue=redBlue*oneMinusAlpha; +// See note +++ +// redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; + redBlueSrc=redBlueSrc*aAlpha; + redBlue+=redBlueSrc; // needs shift down by 8, but do that when going to 64K + WriteRedBlueAndGreenTo64K(redBlue,green,aDst); + } + WRITE_ALPHA_MASK_RUN1616 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));}; + }; + +#define Write64KTo16M(aSrc, aDst)\ + TUint32 w6216Mgreen;\ + TUint32 w6216MredBlue;\ + Read64KColors(w6216Mgreen,w6216MredBlue, aSrc);\ + WriteMu(w6216Mgreen,w6216MredBlue,aDst); + +#define Write64KTo16MLookup(aSrc, aDst, aLowAdd, aHighAdd)\ + {\ + const TUint32 srcData=*(TUint16*)aSrc;\ + *(TUint32*)aDst = aHighAdd[srcData>>8] | aLowAdd[srcData&0xff];\ + } + +struct T64KToMu + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + Write64KTo16M(aSrc,aDst); + } + WRITE_RUN1632 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + const TUint32 oneMinusAlpha = 0x100-aAlpha; + const TUint32 d = *(TUint32*)aDst; + TUint32 src=*(TUint16*)aSrc; +// + TUint32 green = (d&0x0000FF00)>>8; + green=green*oneMinusAlpha; + TUint32 greenSrc; + ReadGreen64K(greenSrc,src); +// See note +++ +// greenSrc=greenSrc*aAlpha+greenSrc; + greenSrc=greenSrc*aAlpha; + green+=greenSrc; +// + TUint32 redBlue = d&0x00FF00FF; + redBlue=redBlue*oneMinusAlpha; + TUint32 redBlueSrc; + ReadRedBlue64K(redBlueSrc,src); +// See note +++ +// redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; + redBlueSrc=redBlueSrc*aAlpha; + redBlue+=redBlueSrc; +// + redBlue>>=8; + WriteMu(green,redBlue,aDst); + } + WRITE_ALPHA_MASK_RUN1632 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +struct T64KToMa + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + Write64KTo16M(aSrc,aDst); + } + WRITE_RUN1632 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + const TUint32 destSrc = *(TUint32*)aDst; + TUint32 destAlpha=destSrc>>24; +// Calc new alpha as src+(1-src)*dst; + destAlpha=(0x100-aAlpha)*destAlpha; + TUint32 targDestPixel=(destAlpha>>8)<<24; + targDestPixel+=aAlpha<<24; +// + TUint32 greenAlpha=(destSrc>>8)&0x000000FF; + const TUint32 destMultAlpha = (destAlpha>>8)+1; + greenAlpha=greenAlpha*destMultAlpha; + TUint32 redBlue = destSrc&0x00FF00FF; + redBlue=redBlue*destMultAlpha; +// + TUint32 src=*(TUint16*)aSrc; + TUint32 greenSrc; + ReadGreen64K(greenSrc,src); + greenSrc=greenSrc*aAlpha+greenSrc; + greenAlpha+=greenSrc; + targDestPixel|=greenAlpha&0x0000FF00; +// + TUint32 redBlueSrc; + ReadRedBlue64K(redBlueSrc,src); + redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; + redBlue+=redBlueSrc; +// + targDestPixel|=(redBlue>>8)&0x00FF00FF; + *(TUint32*)aDst=targDestPixel; + } + WRITE_ALPHA_MASK_RUN1632H + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +WRITE_ALPHA_MASK_RUN1632C(T64KToMa) + +struct T64KToMap + { + FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst) + { + Write64KTo16M(aSrc,aDst); + } + WRITE_RUN1632 + WRITE_RUN2H + FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha) + { + const TUint32 oneMinusAlpha = 0x100-aAlpha; + const TUint32 d = *(TUint32*)aDst; + TUint32 src=*(TUint16*)aSrc; +// + TUint32 greenAlpha = (d&0xFF00FF00)>>8; + greenAlpha=greenAlpha*oneMinusAlpha; + TUint32 greenSrc; + ReadGreen64K(greenSrc,src); + greenSrc=greenSrc*aAlpha+greenSrc; + greenAlpha&=0xFF00FF00; // Needed to stop adding rounding errors together in next step + greenAlpha+=greenSrc; +// + TUint32 redBlue = d&0x00FF00FF; + redBlue=redBlue*oneMinusAlpha; + TUint32 redBlueSrc; + ReadRedBlue64K(redBlueSrc,src); + redBlueSrc=redBlueSrc*aAlpha+redBlueSrc; + redBlue&=0xFF00FF00; // Needed to stop adding rounding errors together in next step + redBlue+=redBlueSrc; // needs shift down by 8, but do that when writing to dest +// + redBlue>>=8; + WriteMx(greenAlpha,redBlue,aDst); + } + WRITE_ALPHA_MASK_RUN1632 + FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));}; + FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));}; + }; + +WRITE_RUN1632C(T64KToMap) +WRITE_RUN1632C(T64KToMa) +WRITE_RUN1632C(T64KToMu) +WRITE_RUN3216C2(TMapTo64K) +WRITE_RUN3216C2(TMaTo64K) +WRITE_RUN3216C2(TMuTo64K) +WRITE_RUN2416C2(TMTo64K) + +inline TInt InitDda(TInt &aDdaCount, TBool &aStretching, TInt aSrcValue, TInt aDstValue, TInt aSkipSteps) + { + aDdaCount=0; + aStretching=aDstValue>aSrcValue; + TInt skip=0; + if (aStretching) + { + aDdaCount=aDstValue-1; + while(aSkipSteps--) + { + aDdaCount-=aSrcValue; + if (aDdaCount<0) + { + skip++; + aDdaCount+=aDstValue; + } + } + } + else + { + aDdaCount=aSrcValue-1; + while(aSkipSteps) + { + aDdaCount-=aDstValue; + if (aDdaCount<0) + { + aSkipSteps--; + aDdaCount+=aSrcValue; + } + skip++; + } + } + return(skip); + } + +inline void DdaStep(TInt &aDdaCount, TBool aStretching, TInt aSrcValue, TInt aDstValue, TInt &aSkipCount) + { + if (aStretching) + { + aDdaCount-=aSrcValue; + if (aDdaCount<0) + { + aSkipCount++; + aDdaCount+=aDstValue; + } + } + else + { + do + { + aSkipCount++; + aDdaCount-=aDstValue; + } while(aDdaCount>=0); + aDdaCount+=aSrcValue; + } + } + +template +static void ScaledFastBlit(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, TRect& aDstRect, const TRect &aClipRect) + { + TInt srcWidth = aSrcRect.Width(); + TInt srcHeight = aSrcRect.Height(); + TInt dstWidth = aDstRect.Width(); + TInt dstHeight = aDstRect.Height(); +// + TInt yDdaCount; + TBool yStretching; + TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY); +// + TInt xDdaCountBase; + TBool xStretching; + TInt sxOffset=aSrcRect.iTl.iX+InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX); + sxOffset*=op::SrcPixelBytes(); +// + const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY; + const TInt xCount=aClipRect.Width(); + TUint8* dstPixelBase = aDataAddress + aDstStride*aClipRect.iTl.iY + aClipRect.iTl.iX*op::DestPixelBytes(); + for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y) + { + const TUint8* srcPixel = aSrcBase + aSrcStride*ySrcOffset + sxOffset; + TUint8* dstPixel = dstPixelBase; + TInt xCountDown=xCount; + TInt ddaCount = xDdaCountBase; + if (xStretching) + { + do + { + op::write(srcPixel, dstPixel); + dstPixel+=op::DestPixelBytes(); + ddaCount-=srcWidth; + if (ddaCount<0) + { + srcPixel+=op::SrcPixelBytes(); + ddaCount+=dstWidth; + } + } while(--xCountDown); + } + else + { + do + { + op::write(srcPixel, dstPixel); + dstPixel+=op::DestPixelBytes(); + do + { + srcPixel+=op::SrcPixelBytes(); + ddaCount-=dstWidth; + } while(ddaCount>=0); + ddaCount+=srcWidth; + } while(--xCountDown); + } + dstPixelBase+=aDstStride; + DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset); + } + } + +template +static void UnscaledFastBlit(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos) + { + const TInt blitWidth = aSrcRect.Width(); + const TUint8* srcPixel = aSrcBase + aSrcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX*op::SrcPixelBytes(); + TUint8* dstPixel = aDataAddress + aDstStride*aDstPos.iY + aDstPos.iX*op::DestPixelBytes(); + const TUint8* dstPixelEnd = dstPixel+aSrcRect.Height()*aDstStride; + do + { + op::write2(srcPixel,dstPixel,blitWidth); + srcPixel+=aSrcStride; + dstPixel+=aDstStride; + } while(dstPixel(aSrcBase) + srcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX; + TUint32* dstPixel = ((TUint32*)aDataAddress) + dstStride*aDstPos.iY + dx; + const TInt copyLen=dstWidth*4; + for (TInt linesToGo=aSrcRect.Height();linesToGo;--linesToGo) + { + // Andy - not convinced that this function is any good atall + // try stdlib memcpy instead. + Mem::Move(dstPixel, srcPixel, copyLen); + srcPixel+=srcStride; + dstPixel+=dstStride; + } + } + +template +static void UnscaledFastBlitRot(const TUint8* aSrcBase, CFbsDrawDevice::TOrientation aOrientation, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TSize &aDestSize, TUint32* aScanLineBuffer) + { + TInt srcStep=op::SrcPixelBytes(); + TInt dstStep=op::DestPixelBytes(); + TInt dstStride=aDstStride; + TInt blitWidth = aSrcRect.Width(); + TInt blitHeight = aSrcRect.Height(); + const TUint8* srcPixel = aSrcBase + aSrcRect.iTl.iY*aSrcStride + aSrcRect.iTl.iX*srcStep; + const TUint8* srcPixelEnd = srcPixel + blitHeight*aSrcStride; + TUint8* dstPixel = aDataAddress; + + + switch(aOrientation) + { + case CFbsDrawDevice::EOrientationRotated90: + dstPixel += (aDstPos.iX*aDstStride + (aDestSize.iWidth-aDstPos.iY-1)*op::DestPixelBytes()); + dstStep = aDstStride; + dstStride = - op::DestPixelBytes(); + break; + case CFbsDrawDevice::EOrientationRotated180: + dstPixel += ( (aDestSize.iHeight - aDstPos.iY -1 )*aDstStride +(aDestSize.iWidth - aDstPos.iX -1)*op::DestPixelBytes() ) ; + dstStep = -dstStep; + dstStride = -aDstStride; + break; + case CFbsDrawDevice::EOrientationRotated270: + dstPixel += ( (aDestSize.iHeight- aDstPos.iX - 1 )*aDstStride + aDstPos.iY*op::DestPixelBytes() ) ; + dstStep = -aDstStride; + dstStride = op::DestPixelBytes(); + break; + } + do + { + Mem::Copy(aScanLineBuffer, srcPixel, blitWidth*srcStep); + op::write2rot((TUint8*)aScanLineBuffer, dstPixel, blitWidth, srcStep, dstStep); + srcPixel+=aSrcStride; + dstPixel+=dstStride; + } + while(srcPixel +static void ScaledFastBlitMaskedG2(const TUint8* aSrcBase, TInt aSrcStride, const TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TBool aInvertMask, TUint8 *aDataAddress, TInt aDstStride, const TRect& aDstRect, const TRect &aClipRect) + { + TInt sx = aSrcRect.iTl.iX; + TInt sxOffset=sx*op::SrcPixelBytes(); + + TInt srcWidth = aSrcRect.Width(); + TInt srcHeight = aSrcRect.Height(); + TInt dstWidth = aDstRect.Width(); + TInt dstHeight = aDstRect.Height(); +// + TInt yDdaCount; + TBool yStretching; + TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY); +// + TInt xDdaCountBase; + TBool xStretching; + TInt xOffsetBase=InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX); +// + const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY; + const TInt xCount=aClipRect.Width(); + TUint8* dstPixelBase = aDataAddress+aDstStride*aClipRect.iTl.iY+aClipRect.iTl.iX*op::DestPixelBytes(); + for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y) + { + const TUint8* srcPixel = aSrcBase+aSrcStride*ySrcOffset+sxOffset; + const TUint32* mskRowBase = (const TUint32*)(aMaskBase+aMaskStride*ySrcOffset); + TUint8* dstPixel = dstPixelBase; + TInt xCountDown=xCount; + TInt curMaskOffset=-1; + TUint32 maskbits=0; + TInt xOffset=xOffsetBase; + TInt ddaCount = xDdaCountBase; + if (xStretching) + { + do + { + const TInt maskOffset=xOffset+sx; + TInt maskBitOffset=maskOffset>>5; + if (curMaskOffset==maskBitOffset) + { +blitIt1: const TInt mask=1<<(maskOffset%32); + if (maskbits&mask) + op::write(srcPixel, dstPixel); + dstPixel+=op::DestPixelBytes(); + ddaCount-=srcWidth; + if (ddaCount<0) + { + xOffset++; + srcPixel+=op::SrcPixelBytes(); + ddaCount+=dstWidth; + } + continue; + } + maskbits=*(mskRowBase+maskBitOffset); + if (aInvertMask) + maskbits=~maskbits; + curMaskOffset=maskBitOffset; + goto blitIt1; + } while(--xCountDown); + } + else + { + do + { + const TInt maskOffset=xOffset+sx; + TInt maskBitOffset=maskOffset>>5; + if (curMaskOffset==maskBitOffset) + { +blitIt2: const TInt mask=1<<(maskOffset%32); + if (maskbits&mask) + op::write(srcPixel, dstPixel); + dstPixel+=op::DestPixelBytes(); + do + { + xOffset++; + srcPixel+=op::SrcPixelBytes(); + ddaCount-=dstWidth; + } while(ddaCount>=0); + ddaCount+=srcWidth; + continue; + } + maskbits=*(mskRowBase+maskBitOffset); + if (aInvertMask) + maskbits=~maskbits; + curMaskOffset=maskBitOffset; + goto blitIt2; + } while(--xCountDown); + } + dstPixelBase+=aDstStride; + DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset); + } + } + +template +static void UnscaledFastBlitMaskedG2(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TBool aInvertMask, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TPoint& aMaskSrcPos, const TSize &aMaskSize) + { + TInt sx = aSrcRect.iTl.iX; + TInt sy = aSrcRect.iTl.iY; + TInt dx = aDstPos.iX; + TInt dy = aDstPos.iY; + + TInt dstWidth = aSrcRect.Width(); + TInt dstHeight = aSrcRect.Height(); + TInt maskWidth=aMaskSize.iWidth; + TInt maskHeight=aMaskSize.iHeight; + TInt maskXStart=aMaskSrcPos.iX%maskWidth; + TInt maskStartShift=maskXStart&0x1F; + TInt xMaskLoopCount=1+(dstWidth-1)/maskWidth; + const TUint8* mskBasePtr=aMaskBase + (maskXStart/32)*4; + for(TInt xMaskLoop=0;xMaskLoop +static void ScaledFastBlitMaskedG256(const TUint8* aSrcBase, TInt aSrcStride, const TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TUint8 *aDataAddress, TInt aDstStride, const TRect& aDstRect, const TRect &aClipRect) + { + TInt sx = aSrcRect.iTl.iX; + TInt sxOffset=sx*op::SrcPixelBytes(); + + TInt srcWidth = aSrcRect.Width(); + TInt srcHeight = aSrcRect.Height(); + TInt dstWidth = aDstRect.Width(); + TInt dstHeight = aDstRect.Height(); +// + TInt yDdaCount; + TBool yStretching; + TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY); +// + TInt xDdaCountBase; + TBool xStretching; + TInt xOffsetBase=InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX); +// + const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY; + const TInt xCount=aClipRect.Width(); + TUint8* dstPixelBase = aDataAddress+aClipRect.iTl.iY*aDstStride+aClipRect.iTl.iX*op::DestPixelBytes(); + for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y) + { + const TUint8* srcRowBase = aSrcBase+aSrcStride*ySrcOffset+sxOffset; + const TUint8* mskRowBase = aMaskBase+aMaskStride*ySrcOffset+sx; + TUint8* dstPixel = dstPixelBase; + TInt xCountDown=xCount; + TInt xOffset=xOffsetBase; +// + TInt ddaCount = xDdaCountBase; + if (xStretching) + { + do + { + TUint mask=*(mskRowBase+xOffset); + if (mask==0xFF) + op::write(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel); + else if (mask!=0) + op::writeMask(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel, mask); + dstPixel+=op::DestPixelBytes(); +// + ddaCount-=srcWidth; + if (ddaCount<0) + { + xOffset++; + ddaCount+=dstWidth; + } + } while(--xCountDown); + } + else + { + do + { + TUint mask=*(mskRowBase+xOffset); + if (mask==0xFF) + op::write(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel); + else if (mask!=0) + op::writeMask(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel, mask); + dstPixel+=op::DestPixelBytes(); +// + do + { + xOffset++; + ddaCount-=dstWidth; + } while(ddaCount>=0); + ddaCount+=srcWidth; + } while(--xCountDown); + } + dstPixelBase+=aDstStride; + DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset); + } + } + +template +static void UnscaledFastBlitMaskedG256(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TPoint& aMaskSrcPos, const TSize &aMaskSize) + { + TInt dstWidth = aSrcRect.Width(); + const TInt dstHeight = aSrcRect.Height(); + const TUint8* srcPixelStart = aSrcBase + aSrcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX*op::SrcPixelBytes(); + TUint8* dstPixelStart = aDataAddress + aDstStride*aDstPos.iY + aDstPos.iX*op::DestPixelBytes(); + TInt yPos=0; + const TInt maskWidth=aMaskSize.iWidth; + const TInt maskHeight=aMaskSize.iHeight; + const TInt maskStartOffset=aMaskSrcPos.iX%maskWidth; + FOREVER + { + const TUint8* srcPixel=srcPixelStart; + const TUint8* maskBase=aMaskBase + (aMaskStride*((aMaskSrcPos.iY+yPos)%maskHeight)); + const TUint8* mskPixel=maskBase + maskStartOffset; + const TUint8* mskEnd=maskBase + maskWidth; + if (dstWidth<(mskEnd-mskPixel)) + mskEnd=mskPixel+dstWidth; + TUint8* dstPixel=dstPixelStart; + const TUint8* runStart=mskPixel; + TInt toGo=dstWidth; + FOREVER + { +// Into skip loop first, assume start of scanline more likely to be masked out than set + TInt runLen1=0; +skipPixels: + while(mskPixel +static void UnscaledFastBlitMaskedRotG256(const TUint8* aSrcBase, CFbsDrawDevice::TOrientation aOrientation, + TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, + TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TSize &aDestSize, + const TPoint& aMaskSrcPos, const TSize &aMaskSize) + { + TPoint dstPos(aDstPos); + TInt srcStep=op::SrcPixelBytes(); + TInt maskStep=1; + TRect srcRect(aSrcRect); + TSize maskSize(aMaskSize); + TPoint maskSrcPos(aMaskSrcPos); + switch(aOrientation) + { + case CFbsDrawDevice::EOrientationRotated90: + srcStep=-aSrcStride; + aSrcStride=op::SrcPixelBytes(); + maskStep=-aMaskStride; + aMaskStride=1; + dstPos.iX=aDestSize.iWidth-aDstPos.iY-aSrcRect.Height(); + dstPos.iY=aDstPos.iX; + srcRect.SetRect(aSrcRect.iTl.iY,aSrcRect.iTl.iX,aSrcRect.iBr.iY,aSrcRect.iBr.iX); + maskSize.SetSize(aMaskSize.iHeight,aMaskSize.iWidth); + maskSrcPos.iX=aMaskSrcPos.iY; + maskSrcPos.iY=aMaskSrcPos.iX; + break; + case CFbsDrawDevice::EOrientationRotated180: + srcStep=-op::SrcPixelBytes(); + maskStep=-1; + aSrcStride=-aSrcStride; + aMaskStride=-aMaskStride; + dstPos.iX=aDestSize.iWidth-aDstPos.iX-aSrcRect.Width(); + dstPos.iY=aDestSize.iHeight-aDstPos.iY-aSrcRect.Height(); + break; + case CFbsDrawDevice::EOrientationRotated270: + srcStep=aSrcStride; + aSrcStride=-op::SrcPixelBytes(); + maskStep=aMaskStride; + aMaskStride=-1; + dstPos.iX=aDstPos.iY; + dstPos.iY=aDestSize.iHeight-aDstPos.iX-aSrcRect.Width(); + srcRect.SetRect(aSrcRect.iTl.iY,aSrcRect.iTl.iX,aSrcRect.iBr.iY,aSrcRect.iBr.iX); + maskSrcPos.iX=aMaskSrcPos.iY; + maskSrcPos.iY=aMaskSrcPos.iX; + maskSize.SetSize(aMaskSize.iHeight,aMaskSize.iWidth); + break; + } + const TUint8* srcPixelStart = aSrcBase; + if (srcStep>0) + srcPixelStart+=srcRect.iTl.iX*srcStep; + else + srcPixelStart-=(srcRect.iBr.iX-1)*srcStep; + if (aSrcStride>0) + srcPixelStart+=srcRect.iTl.iY*aSrcStride; + else + srcPixelStart-=(srcRect.iBr.iY-1)*aSrcStride; +// + const TInt dstWidth = srcRect.Width(); + const TInt dstHeight = srcRect.Height(); + TUint8* dstPixelStart = aDataAddress + aDstStride*dstPos.iY + dstPos.iX*op::DestPixelBytes(); + TInt yPos=0; + const TInt maskWidth=dstWidth0?maskSrcPos.iX:srcRect.iBr.iX-1)%maskSize.iWidth; + FOREVER + { + const TUint8* srcPixel=srcPixelStart; + const TUint8* maskBase=aMaskBase; + TInt maskYpos=(maskSrcPos.iY+yPos)%maskHeight; + if (aMaskStride>0) + maskBase+=maskYpos*aMaskStride; + else + { + TInt maskEndPos=(maskSrcPos.iY+dstHeight-1-yPos)%maskHeight; + maskBase-=maskEndPos*aMaskStride; + } + const TUint8* mskPixel=maskBase; + const TUint8* mskEnd=maskBase; + if (maskStep>0) + { + mskPixel+=maskStartOffset*maskStep; + mskEnd+=maskSize.iWidth*maskStep; + } + else + { + maskBase-=(maskSize.iWidth-1)*maskStep; + mskPixel-=maskStartOffset*maskStep; + mskEnd+=maskStep; + } + const TInt maskToGo=(mskEnd-mskPixel)/maskStep; + if (maskToGo>dstWidth) + mskEnd=mskPixel+dstWidth*maskStep; + TUint8* dstPixel=dstPixelStart; + const TUint8* runStart=mskPixel; + TInt toGo=dstWidth; + FOREVER + { +// Into skip loop first, assume start of scanline more likely to be masked out than set + TInt runLen1=0; +skipPixels: + while(mskPixel!=mskEnd && *mskPixel==0) + mskPixel+=maskStep; + const TInt runSubLen1=(mskPixel-runStart)/maskStep; + runLen1+=runSubLen1; + toGo-=runSubLen1; + if (mskPixel==mskEnd && toGo!=0) + { + mskPixel=maskBase; + runStart=maskBase; + if (toGo=aSrcSize.iWidth) + aSrcRect.Move(-(aSrcRect.iTl.iX/aSrcSize.iWidth)*aSrcSize.iWidth,0); + if (aSrcRect.iTl.iY<0) + { + TInt negOffset=1-(aSrcRect.iTl.iY+1)/aSrcSize.iHeight; + aSrcRect.Move(0,negOffset*aSrcSize.iHeight); + } + else if (aSrcRect.iTl.iY>=aSrcSize.iHeight) + aSrcRect.Move(0,-(aSrcRect.iTl.iY/aSrcSize.iHeight)*aSrcSize.iHeight); + if (aSrcRect.iBr.iY>aSrcSize.iHeight) + aSrcRect.iBr.iY=aSrcSize.iHeight; + if (aSrcRect.iBr.iX>aSrcSize.iWidth) + aSrcRect.iBr.iX=aSrcSize.iWidth; + } + +void CDrawBitmap::GetBlendPosAndRect(TRect &aDstRect, TRect &aSrcRect, const TRect &aDstRectIn, const TRect &aSrcRectIn, const TSize &aSrcSize) + { + aDstRect=aDstRectIn; + aSrcRect=aSrcRectIn; + if (aSrcRect.iTl.iX<0) + aSrcRect.iTl.iX=0; + if (aSrcRect.iTl.iY<0) + aSrcRect.iTl.iY=0; + TInt extraWidth=aSrcRect.iBr.iX-aSrcSize.iWidth; + if (extraWidth>0) + aSrcRect.iBr.iX-=extraWidth; + TInt extraHeight=aSrcRect.iBr.iY-aSrcSize.iHeight; + if (extraHeight>0) + aSrcRect.iBr.iY-=extraHeight; + } + +TInt CDrawBitmap::FastBlendBitmapMaskedScaled(const TRect &aClipRect, const TRect& aDest, + const TRect& aSrcRect, const TUint32 *aSrcBase, TInt aSrcLinePitch, + TDisplayMode aSrcDisplayMode, const TSize &aSrcSize, + const TUint32* aMaskBase, TInt aMaskStride, TDisplayMode aMaskDisplayMode, const TSize &aMaskSize,TBool aInvertMask, + CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode) + { + if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcLinePitch) || + !FastBlendMaskSupported(aMaskDisplayMode, aMaskStride) || + iOrientation!=EOrientationNormal) + return(KErrNotSupported); + TRect srcRect; + TRect dstRect; + GetBlendPosAndRect(dstRect,srcRect,aDest,aSrcRect,aSrcSize); + const TInt KDestModeShift=8; + const TInt KMaskModeShift=16; +#define MASKED_MODE_SWITCH(src,dest,mask) case src|(dest<aMaskSize.iWidth || srcRect.iBr.iY>aMaskSize.iHeight) + return(KErrNotSupported); + TUint8 *dstBits=reinterpret_cast(iBits); + TInt dstStride=iScanLineWords*4; + const TUint8* srcBase=reinterpret_cast(aSrcBase); + const TUint8 *maskBits=reinterpret_cast(aMaskBase); + if (!dstRect.IsEmpty() && !srcRect.IsEmpty()) + { + switch (switchValue) + { +// 16MA source + MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + // 16MU source + MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + // 16MAP source + MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + // 64K source + MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; +#if defined(__SUPPORT_16MA_TARGET__) + MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray2): + ScaledFastBlitMaskedG2(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray256): + ScaledFastBlitMaskedG256(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect); + break; +#endif + default: + return KErrNotSupported; + } + } + return(KErrNone); + } + +TInt CDrawBitmap::FastBlendBitmapScaled(const TRect &aClipRect, const TRect& aDest, const TRect& aSrcRect, const TUint32 *aSrcBase, TInt aSrcLinePitch, TDisplayMode aSrcDisplayMode, const TSize &aSrcSize, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode) + { + if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcLinePitch)) + return(KErrNotSupported); + TRect srcRect; + TRect dstRect; + GetBlendPosAndRect(dstRect,srcRect,aDest,aSrcRect,aSrcSize); + const TInt KDestModeShift=8; +#define MODE_SWITCH(src,dest) case src|(dest<(iBits); + TInt dstStride=iScanLineWords*4; + const TUint8* srcBase=reinterpret_cast(aSrcBase); + if (!dstRect.IsEmpty() && !srcRect.IsEmpty()) + { + switch (switchValue) + { +// 16MA Source + MODE_SWITCH(EColor16MA,EColor16MU): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MA,EColor16MAP): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MA,EColor64K): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; +// 16MAP Source + MODE_SWITCH(EColor16MAP,EColor16MU): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MAP,EColor16MAP): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MAP,EColor64K): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; +// 16MU Source + MODE_SWITCH(EColor16MU,EColor16MU): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MU,EColor64K): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + // No EColor16MU to EColor16MAP fast blit performed because it + // cannot be guaranteed that the alpha channel of the EColor16MU + // source is 0xFF, which any fast blit would require. +// 64K Source + MODE_SWITCH(EColor64K,EColor16MU): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor64K,EColor16MAP): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor64K,EColor64K): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; +// 16M source + MODE_SWITCH(EColor16M,EColor64K): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; +#if defined(__SUPPORT_16MA_TARGET__) + MODE_SWITCH(EColor16MA,EColor16MA): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor16MAP,EColor16MA): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + MODE_SWITCH(EColor64K,EColor16MA): + ScaledFastBlit(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect); + break; + // No EColor16MU to EColor16MA fast blit performed because it + // cannot be guaranteed that the alpha channel of the EColor16MU + // source is 0xFF, which any fast blit would require. +#endif + default: + return KErrNotSupported; + } + } + return KErrNone; + } + +TInt CDrawBitmap::DoFastBlendBitmap(const TPoint &aDest, const TRect& aSrcRect, const TUint8 *aSrcBase, TInt aSrcLinePitch, TDisplayMode aSrcDisplayMode, const TSize &aSrcSize) + { + const TInt KDestModeShift=8; + TInt dstStride=iScanLineWords*4; + TUint8 *dstBits=(TUint8*)iBits; +#define MODE_SWITCH(src,dest) case src|(dest<(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MA,EColor16MAP): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MA,EColor64K): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + // 16MAP Source + MODE_SWITCH(EColor16MAP,EColor16MU): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MAP,EColor16MAP): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MAP,EColor64K): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + // 16MU Source + MODE_SWITCH(EColor16MU,EColor16MU): + ReplaceBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MU,EColor64K): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + // No EColor16MU to EColor16MAP fast blit performed because it + // cannot be guaranteed that the alpha channel of the EColor16MU + // source is 0xFF, which any fast blit would require. + // 64K Source + MODE_SWITCH(EColor64K,EColor16MU): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor64K,EColor16MAP): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor64K,EColor64K): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + // 16M Source + MODE_SWITCH(EColor16M,EColor64K): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; +#if defined(__SUPPORT_16MA_TARGET__) + MODE_SWITCH(EColor16MA,EColor16MA): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor16MAP,EColor16MA): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + MODE_SWITCH(EColor64K,EColor16MA): + UnscaledFastBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos); + break; + // No EColor16MU to EColor16MA fast blit performed because it + // cannot be guaranteed that the alpha channel of the EColor16MU + // source is 0xFF, which any fast blit would require. +#endif + default: + return KErrNotSupported; + } + } + else + { + switch (switchValue) + { + // 16MA Source + MODE_SWITCH(EColor16MA,EColor16MU): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + MODE_SWITCH(EColor16MA,EColor16MAP): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + // 16MAP Source + MODE_SWITCH(EColor16MAP,EColor16MU): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + MODE_SWITCH(EColor16MAP,EColor16MAP): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + // 16MU Source + MODE_SWITCH(EColor16MU,EColor16MU): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + MODE_SWITCH(EColor16MU,EColor16MAP): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + // 64K Source + MODE_SWITCH(EColor64K,EColor64K): + UnscaledFastBlitRot(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer); + break; + default: + return KErrNotSupported; + } + } + dstPos.iX+=srcRect.Width(); + } + dstPos.iY+=srcRect.Height(); + } + return KErrNone; + } + +TBool CDrawBitmap::FastBlendSupported(TDisplayMode aSrcDisplayMode, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode, TInt aSrcLinePitch) + { + // FastBlend supports all combinations of EColor16Mxx and EColor64K, and when User Display Mode is ENone. + if ((iUserDispMode != EColor64K && iUserDispMode != EColor16M && + iUserDispMode != EColor16MU && iUserDispMode != EColor16MA && + iUserDispMode != EColor16MAP && iUserDispMode != ENone)) + { + return (EFalse); + } + if (!IsScalingOff() || + !iOriginIsZero) + { + return(EFalse); + } + return((aDrawMode==CGraphicsContext::EDrawModePEN || (aDrawMode==CGraphicsContext::EDrawModeWriteAlpha && !IsAlphaChannel(aSrcDisplayMode))) && + aShadowMode==CFbsDrawDevice::ENoShadow && aSrcLinePitch>0); + } + +TBool CDrawBitmap::FastBlendMaskSupported(TDisplayMode aMaskDisplayMode, TInt aMaskStride) + { + return((aMaskDisplayMode==EGray2 || aMaskDisplayMode==EGray256) && aMaskStride>0); + } + +/** +CDrawBitmap::BlendBitmap() implementation. +@internalTechnology +*/ +TInt CDrawBitmap::FastBlendBitmap(const TPoint& aDest, CFbsDrawDevice* aSrcDrawDevice, const TRect& aSrcRect, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode) + { + TInt srcPitch=aSrcDrawDevice->ScanLineBytes(); + if (!FastBlendSupported(aSrcDrawDevice->DisplayMode(), aDrawMode, aShadowMode, srcPitch)) + return(KErrNotSupported); + MScalingSettings* scalingSettings=NULL; + if (aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, + reinterpret_cast(scalingSettings))==KErrNone) + { + if (!scalingSettings->IsScalingOff()) + return(KErrNotSupported); + } + MDrawDeviceOrigin* originInterface = NULL; + if(aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, + reinterpret_cast (originInterface)) == KErrNone) + { + TPoint origin; + originInterface->Get(origin); + if (origin.iX!=0 || origin.iY!=0) + return(KErrNotSupported); + } + MDrawDeviceOrientation* orientationInterface=NULL; + if(aSrcDrawDevice->GetInterface(KOrientationInterfaceID, + reinterpret_cast (orientationInterface))!=KErrNone || (orientationInterface && orientationInterface->Orientation() != 0)) + { + return KErrNotSupported; + } + TAny* interface=NULL; + TInt ret=aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface); + if (ret!=KErrNone) + return(ret); + MFastBlit2 *fb2=reinterpret_cast(interface); + const TUint8* srcBase = reinterpret_cast(fb2->Bits()); + return(DoFastBlendBitmap(aDest, aSrcRect, srcBase, srcPitch, aSrcDrawDevice->DisplayMode(), aSrcDrawDevice->SizeInPixels())); + } + +TInt CDrawBitmap::FastBlendBitmap(const TPoint& aDest, const TUint32* aSrcBase, TInt aSrcStride, const TSize& aSrcSize, const TRect& aSrcRect, TDisplayMode aDisplayMode, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode) + { + if (!FastBlendSupported(aDisplayMode, aDrawMode, aShadowMode, aSrcStride)) + return(KErrNotSupported); + return(DoFastBlendBitmap(aDest, aSrcRect, reinterpret_cast(aSrcBase), aSrcStride, aDisplayMode, aSrcSize)); + } + +TInt CDrawBitmap::FastBlendBitmapMasked(const TPoint& aDest, const TUint32* aSrcBase, TInt aSrcStride, const TSize& aSrcSize, const TRect& aSrcRect, TDisplayMode aSrcDisplayMode, const TUint32* aMaskBase, TInt aMaskStride, TDisplayMode aMaskDisplayMode, const TSize &aMaskSize, const TPoint &aMaskSrcPos, TBool aInvertMask, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode) + { + if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcStride) || + !FastBlendMaskSupported(aMaskDisplayMode, aMaskStride)) + return(KErrNotSupported); + TRect srcRect; + GetBlendPosAndRect(srcRect,aSrcRect,aSrcSize,TPoint(0,0)); + const TInt KDestModeShift=8; + const TInt KMaskModeShift=16; + TInt dstStride=iScanLineWords*4; +#define MASKED_MODE_SWITCH(src,dest,mask) case src|(dest<(aSrcBase); + TUint8 *dstBits=(TUint8*)iBits; + const TUint8 *maskBits=reinterpret_cast(aMaskBase); + if (iOrientation==EOrientationNormal) + { + switch (switchValue) + { +// 16MA source + MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; +// 16MU source + MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; +// 16MAP source + MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; +// 64K source + MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; +#if defined(__SUPPORT_16MA_TARGET__) + MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray2): + UnscaledFastBlitMaskedG2(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray256): + UnscaledFastBlitMaskedG256(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize); + break; +#endif + default: + return KErrNotSupported; + } + } + else + { + switch (switchValue) + { + // 16MA Source + MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + // 16MAP Source + MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + // 16MU Source + MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + // 64K Source + MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256): + UnscaledFastBlitMaskedRotG256(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize); + break; + default: + return KErrNotSupported; + } + } + return KErrNone; + }