diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/screendriver/swins/AccelHard.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/screendriver/swins/AccelHard.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,1763 @@ +// Copyright (c) 2001-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 "Accelhard.h" + +// Windows headers... +#define UNICODE +#pragma warning( disable : 4201 ) +#define WIN32_LEAN_AND_MEAN +#define NOSERVICE +#include +#include +#pragma warning( default : 4201 ) + +#include "_WININC.H" + +LOCAL_D const TGraphicsAcceleratorCaps HardwareAcceleratorCapabilities = + { + sizeof(TGraphicsAcceleratorCaps), //TInt iStructureSize; // The size of this class + 1, //TInt iVersion; // == 1 to specify current API + 0, //Tint iVendorUid; // Optional ID + 1<ConstructL(aBitmap); + CleanupStack::Pop(); + return(self); + } + +void CColor256HardwareGraphicsAccelerator::ConstructL(RHardwareBitmap aBitmap) + { + CHardwareGraphicsAcceleratorBase::ConstructL(aBitmap); + iCaps = &HardwareAcceleratorCapabilities; // We only do Color256 + //Some explanations about "-aBitmap.iHandle - 1" expression. + //Before "Multiple screens" update aBitmap.iHandle with value -1 meant that the related + //RHardwareBitmap object is a screen bitmap. Positive aBitmap.iHandle values - it was + //an in-memory RHardwareBitmap object. + //After "Multiple screens" update, the meaning of aBitmap.iHandle's value is: + // - Positive value - in-memory hardware bitmap; + // - Negative value - screen number: "-1" - screen 0, "-2" - screen 1, "-3" - screen 2, ...; + if (aBitmap.iHandle < 0) + { + iScreenNo = -aBitmap.iHandle - 1; + } + } + +TUint32 CColor256HardwareGraphicsAccelerator::FillValue(TRgb aColor) + { + TUint32 value = aColor.Color256(); + value |= value<<8; + value |= value<<16; + return value; + } + +void CColor256HardwareGraphicsAccelerator::DoUpdateScreen(const TRect& aRect) + { + TInt lx = aRect.iTl.iX & ~3; + TInt rx = (aRect.iBr.iX + 3) & ~3; + + TUint8* srcePtr = iBitmapInfo.iAddress+iBitmapInfo.iLinePitch*aRect.iTl.iY+lx; + TUint8* srcePtrLimit = srcePtr + rx - lx; + + TInt linePitch = iBitmapInfo.iLinePitch; + + RWindows* window = ::WindowHandler(iScreenNo); + for(TInt row = aRect.iTl.iY; row < aRect.iBr.iY; row++) + { + TUint8* tempSrcePtr = srcePtr; + TUint8* destPixel = window->PixelAddress(lx,row); + TRgb pixelColor; + + if(window->iPalette) + { + while (tempSrcePtr < srcePtrLimit) + { + pixelColor = window->iPalette[*tempSrcePtr++]; + destPixel[0] = TUint8(pixelColor.Blue()); + destPixel[1] = TUint8(pixelColor.Green()); + destPixel[2] = TUint8(pixelColor.Red()); + destPixel += 3; + } + } + else + { + while (tempSrcePtr < srcePtrLimit) + { + pixelColor = TRgb::Color256(*tempSrcePtr++); + destPixel[0] = TUint8(pixelColor.Blue()); + destPixel[1] = TUint8(pixelColor.Green()); + destPixel[2] = TUint8(pixelColor.Red()); + destPixel += 3; + } + } + + srcePtr += linePitch; + srcePtrLimit += linePitch; + } + + RRegion region; + region.AddRect(aRect); + window->Update(region,window->iEpocBitmapSize); + region.Close(); + } + +void CColor256HardwareGraphicsAccelerator::DoFillRect(const TRect& aRect,TUint32 aFillValue) + { + //Lock(); + + TUint32* ptr = (TUint32*)iBitmapInfo.iAddress; + TUint32* ptrLimit; + TUint32 leftMask; + TUint32 rightMask; + TInt ptrPitch; + TInt pitch; + TInt height; + + { + TInt yStart = aRect.iTl.iY; + TInt yEnd = aRect.iBr.iY; + + if(yStart<0) + goto error; + if(yStart>=yEnd) + goto error; + if(yEnd>iBitmapInfo.iSize.iHeight) + goto error; + + ptr = (TUint32*)((TUint8*)ptr+yStart*iBitmapInfo.iLinePitch); + height = yEnd-yStart; + } + + { + TInt xStart = aRect.iTl.iX; + TInt xEnd = aRect.iBr.iX; + + if(xStart<0) + goto error; + if(xStart>=xEnd) + goto error; + if(xEnd>iBitmapInfo.iSize.iWidth) + goto error; + + xStart <<= iBitmapInfo.iPixelShift; + xEnd <<= iBitmapInfo.iPixelShift; + + leftMask = ~((1<<(xStart&0x1F))-1); + rightMask = (1<<(xEnd&0x1F))-1; + + xStart >>= 5; + xEnd = (xEnd-1)>>5; + ptrLimit = ptr+xEnd; + ptr += xStart; + + pitch = iBitmapInfo.iLinePitch; + ptrPitch = pitch-((TInt)ptrLimit-(TInt)ptr); + } + + if((ptr==ptrLimit) && (leftMask!=0xFFFFFFFF)) // all pixels in a line are in the same word + { + if((leftMask != 0) && (rightMask !=0)) + leftMask &= rightMask; + else if(rightMask != 0) + leftMask = rightMask; + + aFillValue &= leftMask; + do + { + TUint32 pixels = *ptr; + pixels &= ~ leftMask; + pixels |= aFillValue; + *(ptr) = pixels; + ptr = (TUint32*)((TUint8*)ptr+ptrPitch); + } + while(--height); + } + else if((leftMask==0xFFFFFFFF)&&(rightMask==0)) // all pixels in a line fit into whole words + { + do + { + while(ptr=yEnd) + goto error; + if(yEnd>iBitmapInfo.iSize.iHeight) + goto error; + + ptr8 = ptr8+yStart*iBitmapInfo.iLinePitch; + height = yEnd-yStart; + } + + { + TInt xStart = aRect.iTl.iX; + TInt xEnd = aRect.iBr.iX; + + if(xStart<0) + goto error; + if(xStart>=xEnd) + goto error; + if(xEnd>iBitmapInfo.iSize.iWidth) + goto error; + + ptrLimit8 = ptr8 + xEnd; + ptr8 += xStart; + + pitch = iBitmapInfo.iLinePitch; + ptrPitch = pitch-((TInt)ptrLimit8-(TInt)ptr8); + } + + difOrigins = (aRect.iTl.iX - aPattern.iOrigin.iX) % patternBitmapInfo.iSize.iWidth; + if(difOrigins < 0) + { + ptrCurrentPixelPattern8 = ptrLimitPattern8 + difOrigins + 1; + xOffsetPattern = patternBitmapInfo.iSize.iWidth + difOrigins; + } + if(difOrigins > 0) + { + ptrCurrentPixelPattern8 = ptrPattern8 + difOrigins; + xOffsetPattern = difOrigins; + } + + difOrigins = (aRect.iTl.iY - aPattern.iOrigin.iY) % patternBitmapInfo.iSize.iHeight; + if(difOrigins < 0) + { + TInt totalPitch = pitchPattern*(patternBitmapInfo.iSize.iHeight + difOrigins); + ptrCurrentPixelPattern8 += totalPitch; + ptrPattern8 += totalPitch ; + ptrLimitPattern8 += totalPitch; + } + if(difOrigins > 0) + { + TInt totalPitch = (pitchPattern * (difOrigins)); + ptrCurrentPixelPattern8 += totalPitch; + ptrPattern8 += totalPitch; + ptrLimitPattern8 += totalPitch; + } + + do + { + while(ptr8=yEnd) + goto error; + if(yEnd>iBitmapInfo.iSize.iHeight) + goto error; + + ptr = (TUint32*)((TUint8*)ptr+yStart*iBitmapInfo.iLinePitch); + height = yEnd-yStart; + } + + { + TInt xStart = aRect.iTl.iX; + TInt xEnd = aRect.iBr.iX; + + if(xStart<0) + goto error; + if(xStart>=xEnd) + goto error; + if(xEnd>iBitmapInfo.iSize.iWidth) + goto error; + + xStart <<= iBitmapInfo.iPixelShift; + xEnd <<= iBitmapInfo.iPixelShift; + + leftMask = ~((1<<(xStart&0x1F))-1); + rightMask = (1<<(xEnd&0x1F))-1; + + xStart >>= 5; + xEnd = (xEnd-1)>>5; + ptrLimit = ptr+xEnd; + ptr += xStart; + + pitch = iBitmapInfo.iLinePitch; + ptrPitch = pitch-((TInt)ptrLimit-(TInt)ptr); + } + + TUint32 pixelsInverted; + if((ptr==ptrLimit) && (leftMask!=0xFFFFFFFF)) // all pixels in a line are in the same word + { + if((leftMask != 0) && (rightMask !=0)) + leftMask &= rightMask; + else if(rightMask != 0) + leftMask = rightMask; + + do + { + TUint32 pixels = *ptr; + pixelsInverted = ~ pixels; + + pixels &= ~ leftMask; + pixelsInverted &= leftMask; + + pixels |= pixelsInverted; + *(ptr) = pixels; + ptr = (TUint32*)((TUint8*)ptr+ptrPitch); + } + while(--height); + } + else if((leftMask==0xFFFFFFFF)&&(rightMask==0)) // all pixels in a line fit into whole words + { + do + { + while(ptr=yEnd) + goto error; + if(yEnd>iBitmapInfo.iSize.iHeight) + goto error; + + ptr8 = (ptr8 + yStart*iBitmapInfo.iLinePitch); + height = yEnd-yStart; + } + + { + TInt xStart = aRect.iTl.iX; + TInt xEnd = aRect.iBr.iX; + + if(xStart<0) + goto error; + if(xStart>=xEnd) + goto error; + if(xEnd>iBitmapInfo.iSize.iWidth) + goto error; + + prtLimit8 = ptr8 + (xEnd); + ptr8 += xStart; + pitch = iBitmapInfo.iLinePitch; + ptrPitch = pitch-((TInt)prtLimit8-(TInt)ptr8); + } + + do + { + while(ptr8> 8) + offset; + TInt g = (((value & 0x0000ff00) * scale) >> 16) + offset; + //the multiplication by scale can overflow into the sign bit, so we shift down in two steps + TInt r = ((((value & 0x00ff0000) >> 16) * scale) >> 8) + offset; + + color = TRgb(r,g,b); + *(ptr8++) = (TUint8)color.Color256(); + } + + ptr8 = ptr8+ptrPitch; + prtLimit8 = prtLimit8+pitch; + } + while(--height); + + //Unlock(); + return; +error: + //Unlock(); + GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap); + } + +TInt CColor256HardwareGraphicsAccelerator::DoBitBlt(const TPoint& aDestination,const TAcceleratedBitmapSpec& aSourceBitmapSpec,const TRect& aSourceRect) + { + if(aSourceBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handle = aSourceBitmapSpec.Handle(); + RHardwareBitmap sourceBitmap(handle); + + TAcceleratedBitmapInfo sourceBitmapInfo; + sourceBitmap.GetInfo(sourceBitmapInfo); + + if(sourceBitmapInfo.iDisplayMode != EColor256) + return KErrNotSupported; + + TUint32* ptrSource32 = (TUint32*)sourceBitmapInfo.iAddress; + TUint32* prtLimitSource32; + + TUint32* ptrDest32 = (TUint32*)iBitmapInfo.iAddress; + TUint32* ptrLimitDest32; + + TUint8* ptrSource8 = (TUint8*)ptrSource32; + TUint8* prtLimitSource8; + + TUint8* ptrDest8 = (TUint8*)ptrDest32; + TUint8* ptrLimitDest8; + + + TInt ySourceStart = aSourceRect.iTl.iY; + TInt ySourceEnd = aSourceRect.iBr.iY; + TInt xSourceStart = aSourceRect.iTl.iX; + TInt xSourceEnd = aSourceRect.iBr.iX; + + TInt yDestStart; + TInt yDestEnd; + TInt xDestStart; + TInt xDestEnd; + + TUint32 leftMask; + TUint32 rightMask; + + TInt ptrPitchSource; + TInt pitchSource; + TInt ptrPitchDest; + TInt pitchDest; + + TInt height; + + + TRect area(aSourceRect); //final area from aSourceRect to blit + TRect destRect(aSourceRect.Size()); + + //aSource + if(ySourceStart<0) + goto error; + if(ySourceStart>=ySourceEnd) + goto error; + if(ySourceEnd>sourceBitmapInfo.iSize.iHeight) + goto error; + + if(xSourceStart<0) + goto error; + if(xSourceStart>=xSourceEnd) + goto error; + if(xSourceEnd>sourceBitmapInfo.iSize.iWidth) + goto error; + + destRect.Move(aDestination); + if(!destRect.Intersects(TRect(iBitmapInfo.iSize))) + return KErrNone; + + //save parameters + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + destRect.Intersection(TRect(iBitmapInfo.iSize)); + + ySourceStart += destRect.iTl.iY - yDestStart; + ySourceEnd += destRect.iBr.iY - yDestEnd; + xSourceStart += destRect.iTl.iX - xDestStart; + xSourceEnd += destRect.iBr.iX - xDestEnd; + + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + area.SetRect(xSourceStart,ySourceStart,xSourceEnd,ySourceEnd); + height = ySourceEnd - ySourceStart; + + + if(!((xSourceStart&0x1F) == (xDestStart&0x1F))) // source and dest are not aligned + { + ptrSource8 = (ptrSource8 + ySourceStart*sourceBitmapInfo.iLinePitch); + prtLimitSource8 = ptrSource8 + (xSourceEnd); + ptrSource8 += xSourceStart; + + ptrDest8 = (ptrDest8 + yDestStart*iBitmapInfo.iLinePitch); + ptrLimitDest8 = ptrDest8 + (xDestEnd); + ptrDest8 += xDestStart; + + pitchSource = sourceBitmapInfo.iLinePitch; + ptrPitchSource = pitchSource -((TInt)prtLimitSource8 - (TInt)ptrSource8); + + pitchDest = iBitmapInfo.iLinePitch; + ptrPitchDest = pitchDest - ((TInt)ptrLimitDest8 - (TInt)ptrDest8); + + do + { + while(ptrSource8>= 5; + xSourceEnd = (xSourceEnd-1) >> 5; + xDestStart >>= 5; + xDestEnd = (xDestEnd-1) >> 5; + + prtLimitSource32 = ptrSource32 + xSourceEnd; + ptrSource32 += xSourceStart; + ptrLimitDest32 = ptrDest32 + xDestEnd; + ptrDest32 += xDestStart; + + pitchSource = sourceBitmapInfo.iLinePitch; + ptrPitchSource = pitchSource -((TInt)prtLimitSource32 - (TInt)ptrSource32); + pitchDest = iBitmapInfo.iLinePitch; + ptrPitchDest = pitchDest - ((TInt)ptrLimitDest32 - (TInt)ptrDest32); + + if((ptrSource32==prtLimitSource32) && (leftMask!=0xFFFFFFFF)) // all pixels in a line are in the same word + { + if((leftMask != 0) && (rightMask !=0)) + leftMask &= rightMask; + else if(rightMask != 0) + leftMask = rightMask; + do + { + TInt pixelsSource = *ptrSource32; + TInt pixelsDest = *ptrDest32; + pixelsSource &= leftMask; + pixelsDest &= ~ leftMask; + pixelsDest |= pixelsSource; + *(ptrDest32) = pixelsDest; + ptrSource32 = (TUint32*)((TUint8*)ptrSource32+ptrPitchSource); + ptrDest32 = (TUint32*)((TUint8*)ptrDest32+ptrPitchDest); + } + while(--height); + } + else if((leftMask==0xFFFFFFFF)&&(rightMask==0)) // all pixels in a line fit into whole words + { + do + { + while(ptrSource32=ySourceEnd) + goto error; + if(ySourceEnd>sourceBitmapInfo.iSize.iHeight) + goto error; + + if(xSourceStart<0) + goto error; + if(xSourceStart>=xSourceEnd) + goto error; + if(xSourceEnd>sourceBitmapInfo.iSize.iWidth) + goto error; + + + destRect.Move(aDestination); + if(!destRect.Intersects(TRect(iBitmapInfo.iSize))) + return KErrNone; + + //save parameters + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + destRect.Intersection(TRect(iBitmapInfo.iSize)); + + ySourceStart += destRect.iTl.iY - yDestStart; + ySourceEnd += destRect.iBr.iY - yDestEnd; + xSourceStart += destRect.iTl.iX - xDestStart; + xSourceEnd += destRect.iBr.iX - xDestEnd; + + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + area.SetRect(xSourceStart,ySourceStart,xSourceEnd,ySourceEnd); + height = ySourceEnd - ySourceStart; + + //Source Bitmap + ptrSource8 = (ptrSource8 + ySourceStart*sourceBitmapInfo.iLinePitch); + prtLimitSource8 = ptrSource8 + (xSourceEnd); + ptrSource8 += xSourceStart; + + pitchSource = sourceBitmapInfo.iLinePitch; + ptrPitchSource = pitchSource -((TInt)prtLimitSource8 - (TInt)ptrSource8); + + //Destination Bitmap + ptrDest8 = (ptrDest8 + yDestStart*iBitmapInfo.iLinePitch); + ptrLimitDest8 = ptrDest8 + (xDestEnd); + ptrDest8 += xDestStart; + + pitchDest = iBitmapInfo.iLinePitch; + ptrPitchDest = pitchDest - ((TInt)ptrLimitDest8 - (TInt)ptrDest8); + + //Mask Bitmap + ptrMask8 = (ptrMask8 + ySourceStart*maskBitmapInfo.iLinePitch); + ptrLimitMask8 = ptrMask8 + (xSourceEnd); + ptrMask8 += xSourceStart; + + pitchMask = maskBitmapInfo.iLinePitch; + ptrPitchMask = pitchMask -((TInt)ptrLimitMask8 - (TInt)ptrMask8); + + do + { + while(ptrSource8=ySourceEnd) + goto error; + if(ySourceEnd>sourceBitmapInfo.iSize.iHeight) + goto error; + + if(xSourceStart<0) + goto error; + if(xSourceStart>=xSourceEnd) + goto error; + if(xSourceEnd>sourceBitmapInfo.iSize.iWidth) + goto error; + + + destRect.Move(aDestination); + if(!destRect.Intersects(TRect(iBitmapInfo.iSize))) + return KErrNone; + + //save parameters + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + destRect.Intersection(TRect(iBitmapInfo.iSize)); + + ySourceStart += destRect.iTl.iY - yDestStart; + ySourceEnd += destRect.iBr.iY - yDestEnd; + xSourceStart += destRect.iTl.iX - xDestStart; + xSourceEnd += destRect.iBr.iX - xDestEnd; + + yDestStart = destRect.iTl.iY; + yDestEnd = destRect.iBr.iY; + xDestStart = destRect.iTl.iX; + xDestEnd = destRect.iBr.iX; + + area.SetRect(xSourceStart,ySourceStart,xSourceEnd,ySourceEnd); + height = ySourceEnd - ySourceStart; + + //Source Bitmap + ptrSource8 = (ptrSource8 + ySourceStart*sourceBitmapInfo.iLinePitch); + prtLimitSource8 = ptrSource8 + (xSourceEnd); + ptrSource8 += xSourceStart; + + pitchSource = sourceBitmapInfo.iLinePitch; + ptrPitchSource = pitchSource -((TInt)prtLimitSource8 - (TInt)ptrSource8); + + //Destination Bitmap + ptrDest8 = (ptrDest8 + yDestStart*iBitmapInfo.iLinePitch); + ptrLimitDest8 = ptrDest8 + (xDestEnd); + ptrDest8 += xDestStart; + + pitchDest = iBitmapInfo.iLinePitch; + ptrPitchDest = pitchDest - ((TInt)ptrLimitDest8 - (TInt)ptrDest8); + + //Alpha Bitmap + ptrAlpha8 = (ptrAlpha8 + ySourceStart*alphaBitmapInfo.iLinePitch); + ptrLimitAlpha8 = ptrAlpha8 + (xSourceEnd); + ptrAlpha8 += xSourceStart; + + pitchAlpha = alphaBitmapInfo.iLinePitch; + ptrPitchAlpha = pitchAlpha -((TInt)ptrLimitAlpha8 - (TInt)ptrAlpha8); + + do + { + while(ptrSource8> 8; + TInt redSource = (value & 0x00ff0000) >> 16; + + //Dest color information + index= *ptrDest8; + color = TRgb::Color256(index); + value = color.Internal(); + TInt blueDest = (value & 0x000000ff); + TInt greenDest = (value & 0x0000ff00) >> 8; + TInt redDest= (value & 0x00ff0000) >> 16; + + TInt inverseMask = 255 - *ptrAlpha8; + + redDest = ((redSource * (*ptrAlpha8) + redSource) + (redDest * inverseMask + redDest)) >> 8; + greenDest = ((greenSource * (*ptrAlpha8) + greenSource) + (greenDest * inverseMask + greenDest)) >> 8; + blueDest = ((blueSource * (*ptrAlpha8) + blueSource) + (blueDest * inverseMask + blueDest)) >> 8; + + color = TRgb(redDest,greenDest,blueDest); + *ptrDest8 = TUint8(color.Color256()); + + ptrAlpha8++; + ptrDest8++; + ptrSource8++; + } + + ptrSource8 = ptrSource8+ptrPitchSource; + prtLimitSource8 = prtLimitSource8+pitchSource; + ptrDest8 = ptrDest8+ptrPitchDest; + ptrLimitDest8 = ptrLimitDest8+pitchDest; + ptrAlpha8 = ptrAlpha8+ptrPitchAlpha; + ptrLimitAlpha8 = ptrLimitAlpha8+pitchAlpha; + } + while(--height); + + + return KErrNone; +error: + GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap); + return KErrNone; // Will not be executed but prevents compiler warnings + } + +TInt CColor256HardwareGraphicsAccelerator::DoAlphaBlendTwoBitmaps(const TPoint& aDestination,const TAcceleratedBitmapSpec& aSrceBitmapSpec1,const TAcceleratedBitmapSpec& aSrceBitmapSpec2,const TRect& aSourceRect,const TPoint& aSrcPt2,const TAcceleratedBitmapSpec& aAlphaBitmapSpec,const TPoint& aAlphaPt) + { + //Destination Bitmap + TUint8* ptrDest8 = (TUint8*)iBitmapInfo.iAddress; + + // First Source Bitmap + if(aSrceBitmapSpec1.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handleSourceBitmap1 = aSrceBitmapSpec1.Handle(); + RHardwareBitmap sourceBitmap1(handleSourceBitmap1); + + TAcceleratedBitmapInfo sourceBitmap1Info; + sourceBitmap1.GetInfo(sourceBitmap1Info); + + TUint8* ptrSourceOne8 = (TUint8*)sourceBitmap1Info.iAddress; + + // Second Source Bitmap + if(aSrceBitmapSpec2.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handleSourceBitmap2 = aSrceBitmapSpec2.Handle(); + RHardwareBitmap sourceBitmap2(handleSourceBitmap2); + + TAcceleratedBitmapInfo sourceBitmap2Info; + sourceBitmap2.GetInfo(sourceBitmap2Info); + + TUint8* ptrSourceTwo8 = (TUint8*)sourceBitmap2Info.iAddress; + + //Alpha Bitmap + if(aAlphaBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handleAlphaBitmap = aAlphaBitmapSpec.Handle(); + RHardwareBitmap alphaBitmap(handleAlphaBitmap); + + TAcceleratedBitmapInfo alphaBitmapInfo; + alphaBitmap.GetInfo(alphaBitmapInfo); + + if((sourceBitmap1Info.iDisplayMode != EColor256) || (sourceBitmap2Info.iDisplayMode != EColor256) || (alphaBitmapInfo.iDisplayMode != EGray256)) + return KErrNotSupported; + + TUint8* ptrAlpha8 = (TUint8*)alphaBitmapInfo.iAddress; + + TRect destRect(aSourceRect.Size()); + + if((sourceBitmap1Info.iSize != alphaBitmapInfo.iSize) && (sourceBitmap2Info.iSize != alphaBitmapInfo.iSize)) + return KErrNotSupported; + + // Check bounds on the source rectangle + if(aSourceRect.iTl.iY<0) + goto error; + if(aSourceRect.iTl.iY>=aSourceRect.iBr.iY) + goto error; + if(aSourceRect.iBr.iY>sourceBitmap1Info.iSize.iHeight) + goto error; + if(aSourceRect.iTl.iX<0) + goto error; + if(aSourceRect.iTl.iX>=aSourceRect.iBr.iX) + goto error; + if(aSourceRect.iBr.iX>sourceBitmap1Info.iSize.iWidth) + goto error; + + // Find writeable area of the destination rectangle + destRect.Move(aDestination); + if(!destRect.Intersects(TRect(iBitmapInfo.iSize))) + return KErrNone; + destRect.Intersection(TRect(iBitmapInfo.iSize)); + + // Iterate through the pixels and blend to the destination + TInt srceY = aSourceRect.iTl.iY; + TInt src2Y = aSrcPt2.iY; + TInt srcaY = aAlphaPt.iY; + TInt destY = destRect.iTl.iY; + while (destY < destRect.iBr.iY) + { + TInt srceX = aSourceRect.iTl.iX; + TInt src2X = aSrcPt2.iX; + TInt destX = destRect.iTl.iX; + TInt srcaX = aAlphaPt.iX; + + while (destX < destRect.iBr.iX) + { + // First Source color information + TUint8 index = ptrSourceOne8[srceY*sourceBitmap1Info.iLinePitch+srceX]; + TRgb color = TRgb::Color256(index); + TUint32 value = color.Internal(); + TInt blueSource1 = (value & 0x000000ff); + TInt greenSource1 = (value & 0x0000ff00) >> 8; + TInt redSource1 = (value & 0x00ff0000) >> 16; + + // Second Source color information + index = ptrSourceTwo8[src2Y*sourceBitmap2Info.iLinePitch+src2X]; + color = TRgb::Color256(index); + value = color.Internal(); + TInt blueSource2 = (value & 0x000000ff); + TInt greenSource2 = (value & 0x0000ff00) >> 8; + TInt redSource2 = (value & 0x00ff0000) >> 16; + + TUint8 alpha = ptrAlpha8[srcaY*alphaBitmapInfo.iLinePitch+srcaX]; + TInt inverseMask = 255 - alpha; + + // Blend + TInt redDest = ((alpha * (redSource1 - redSource2)) >> 8) + redSource2; + TInt greenDest = ((alpha * (greenSource1 - greenSource2)) >> 8) + greenSource2; + TInt blueDest = ((alpha * (blueSource1 - blueSource2)) >> 8) + blueSource2; + + color = TRgb(redDest,greenDest,blueDest); + ptrDest8[destY*iBitmapInfo.iLinePitch+destX] = TUint8(color.Color256()); + + ++srceX; + ++src2X; + ++destX; + ++srcaX; + } + + ++srceY; + ++destY; + ++src2Y; + ++srcaY; + } + + return KErrNone; +error: + GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap); + return KErrNone; // Will not be executed but prevents compiler warnings + } + +TInt CColor256HardwareGraphicsAccelerator::DoAlphaBlendOneBitmap(const TPoint& aDestination,const TAcceleratedBitmapSpec& aSrceBitmapSpec,const TRect& aSourceRect,const TAcceleratedBitmapSpec& aAlphaBitmapSpec,const TPoint& aAlphaPt) + { + //Destination Bitmap + TUint8* ptrDest8 = (TUint8*)iBitmapInfo.iAddress; + + // Source Bitmap + if(aSrceBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handleSourceBitmap = aSrceBitmapSpec.Handle(); + RHardwareBitmap sourceBitmap(handleSourceBitmap); + + TAcceleratedBitmapInfo sourceBitmapInfo; + sourceBitmap.GetInfo(sourceBitmapInfo); + + TUint8* ptrSource8 = (TUint8*)sourceBitmapInfo.iAddress; + + //Alpha Bitmap + if(aAlphaBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap) + return KErrNotSupported; + + TInt handleAlphaBitmap = aAlphaBitmapSpec.Handle(); + RHardwareBitmap alphaBitmap(handleAlphaBitmap); + + TAcceleratedBitmapInfo alphaBitmapInfo; + alphaBitmap.GetInfo(alphaBitmapInfo); + + if((sourceBitmapInfo.iDisplayMode != EColor256) || (alphaBitmapInfo.iDisplayMode != EGray256)) + return KErrNotSupported; + + TUint8* ptrAlpha8 = (TUint8*)alphaBitmapInfo.iAddress; + + TRect destRect(aSourceRect.Size()); + + if(sourceBitmapInfo.iSize != alphaBitmapInfo.iSize) + return KErrNotSupported; + + // Check bounds on the source rectangle + if(aSourceRect.iTl.iY<0) + goto error; + if(aSourceRect.iTl.iY>=aSourceRect.iBr.iY) + goto error; + if(aSourceRect.iBr.iY>sourceBitmapInfo.iSize.iHeight) + goto error; + if(aSourceRect.iTl.iX<0) + goto error; + if(aSourceRect.iTl.iX>=aSourceRect.iBr.iX) + goto error; + if(aSourceRect.iBr.iX>sourceBitmapInfo.iSize.iWidth) + goto error; + + // Find writeable area of the destination rectangle + destRect.Move(aDestination); + if(!destRect.Intersects(TRect(iBitmapInfo.iSize))) + return KErrNone; + destRect.Intersection(TRect(iBitmapInfo.iSize)); + + // Iterate through the pixels and blend to the destination + TInt srceY = aSourceRect.iTl.iY; + TInt srcaY = aAlphaPt.iY; + TInt destY = destRect.iTl.iY; + while (destY < destRect.iBr.iY) + { + TInt srceX = aSourceRect.iTl.iX; + TInt destX = destRect.iTl.iX; + TInt srcaX = aAlphaPt.iX; + + while (destX < destRect.iBr.iX) + { + // First Source color information + TUint8 index = ptrSource8[srceY*sourceBitmapInfo.iLinePitch+srceX]; + TRgb color = TRgb::Color256(index); + TUint32 value = color.Internal(); + TInt blueSource = (value & 0x000000ff); + TInt greenSource = (value & 0x0000ff00) >> 8; + TInt redSource = (value & 0x00ff0000) >> 16; + + // Second Source color information + index = ptrDest8[destY*iBitmapInfo.iLinePitch+destX]; + color = TRgb::Color256(index); + value = color.Internal(); + TInt blueDest = (value & 0x000000ff); + TInt greenDest = (value & 0x0000ff00) >> 8; + TInt redDest = (value & 0x00ff0000) >> 16; + + TUint8 alpha = ptrAlpha8[srcaY*alphaBitmapInfo.iLinePitch+srcaX]; + TInt inverseMask = 255 - alpha; + + // Blend + redDest = ((alpha * (redSource - redDest)) >> 8) + redDest; + greenDest = ((alpha * (greenSource - greenDest)) >> 8) + greenDest; + blueDest = ((alpha * (blueSource - blueDest)) >> 8) + blueDest; + + color = TRgb(redDest,greenDest,blueDest); + ptrDest8[destY*iBitmapInfo.iLinePitch+destX] = TUint8(color.Color256()); + + ++srceX; + ++destX; + ++srcaX; + } + + ++srceY; + ++destY; + ++srcaY; + } + + return KErrNone; +error: + GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap); + return KErrNone; // Will not be executed but prevents compiler warnings + } + +// +// CHardwareGraphicsAcceleratorBase +// + +void CHardwareGraphicsAcceleratorBase::ConstructL(RHardwareBitmap aBitmap) + { + aBitmap.GetInfo(iBitmapInfo); + iIsScreen = (aBitmap.iHandle < 0)?1:0; + } + +const TGraphicsAcceleratorCaps* CHardwareGraphicsAcceleratorBase::Capabilities() + { + return iCaps; + } + +TInt CHardwareGraphicsAcceleratorBase::Operation(const TGraphicsOperation& aOperation) + { + switch(aOperation.Function()) + { + case TGraphicsOperation::EFilledRect: + { + const TGopFilledRect& op = *(const TGopFilledRect*)&aOperation; + DoFillRect(op.iRect,FillValue(op.iColor)); + UpdateScreen(op.iRect); + return KErrNone; + } + case TGraphicsOperation::EFilledRectWithPattern: + { + const TGopFilledRectWithPattern& op = *(const TGopFilledRectWithPattern*)&aOperation; + TInt error = DoFilledRectWithPattern(op.iRect,op.iPattern); + if(error==KErrNone) + UpdateScreen(op.iRect); + return error; + } + case TGraphicsOperation::EInvertRect: + { + const TGopInvertRect& op = *(const TGopInvertRect*)&aOperation; + DoInvertRect(op.iRect); + UpdateScreen(op.iRect); + return KErrNone; + } + case TGraphicsOperation::EFadeRect: + { + const TGopFadeRect& op = *(const TGopFadeRect*)&aOperation; + DoFadeRect(op.iRect,op.iFade); + UpdateScreen(op.iRect); + return KErrNone; + } + case TGraphicsOperation::EBitBlt: + { + const TGopBitBlt& op = *(const TGopBitBlt*)&aOperation; + TInt error = DoBitBlt(op.iDestination,op.iSourceBitmap,op.iSourceRect); + if(error==KErrNone) + { + TRect rect(op.iSourceRect.Size()); + rect.Move(op.iDestination); + UpdateScreen(rect); + } + return error; + } + case TGraphicsOperation::EBitBltMasked: + { + const TGopBitBltMasked& op = *(const TGopBitBltMasked*)&aOperation; + TInt error = DoBitBltMasked(op.iDestination,op.iSourceBitmap,op.iSourceRect,op.iMask); + if(error==KErrNone) + { + TRect rect(op.iSourceRect.Size()); + rect.Move(op.iDestination); + UpdateScreen(rect); + } + return error; + } + case TGraphicsOperation::EBitBltTransparent: + case TGraphicsOperation::EBitBltAlphaChannel: + case TGraphicsOperation::EBitBltAlphaBitmap: + { + const TGopBitBltAlphaBitmap& op = *(const TGopBitBltAlphaBitmap*)&aOperation; + TInt error = DoBitBltAlphaBitmap(op.iDestination,op.iSourceBitmap,op.iSourceRect,op.iAlphaBitmap); + if(error==KErrNone) + { + TRect rect(op.iSourceRect.Size()); + rect.Move(op.iDestination); + UpdateScreen(rect); + } + return error; + } + case TGraphicsOperation::EAlphaBlendTwoBitmaps: + { + const TGopAlphaBlendTwoBitmaps& op = *(const TGopAlphaBlendTwoBitmaps*)&aOperation; + TInt error = DoAlphaBlendTwoBitmaps(op.iDestination,op.iSourceBmp1,op.iSourceBmp2,op.iSourceRect,op.iSrcPt2,op.iAlphaBmp,op.iAlphaPt); + if(error==KErrNone) + { + TRect rect(op.iSourceRect.Size()); + rect.Move(op.iDestination); + UpdateScreen(rect); + } + return error; + } + case TGraphicsOperation::EAlphaBlendOneBitmap: + { + const TGopAlphaBlendOneBitmap& op = *(const TGopAlphaBlendOneBitmap*)&aOperation; + TInt error = DoAlphaBlendOneBitmap(op.iDestination,op.iSourceBmp,op.iSourceRect,op.iAlphaBmp,op.iAlphaPt); + if(error==KErrNone) + { + TRect rect(op.iSourceRect.Size()); + rect.Move(op.iDestination); + UpdateScreen(rect); + } + return error; + } + case TGraphicsOperation::EFilledRectUsingDrawMode: + case TGraphicsOperation::EScaledBitBlt: + case TGraphicsOperation::EScaledBitBltMasked: + case TGraphicsOperation::EScaledBitBltTransparent: + case TGraphicsOperation::EScaledBitBltAlphaChannel: + case TGraphicsOperation::EScaledBitBltAlphaBitmap: + case TGraphicsOperation::EFilledPolygon: + case TGraphicsOperation::EFilledPolygonWithPattern: + default: + return KErrNotSupported; + } + } + +TInt CHardwareGraphicsAcceleratorBase::Operation(const TGraphicsOperation& aOperation,TInt /*aNumClipRects*/,TRect* /*aClipRects*/) + { + switch(aOperation.Function()) + { + case TGraphicsOperation::EFilledRect: + case TGraphicsOperation::EFilledRectUsingDrawMode: + case TGraphicsOperation::EFilledRectWithPattern: + case TGraphicsOperation::EInvertRect: + case TGraphicsOperation::EFadeRect: + case TGraphicsOperation::EBitBlt: + case TGraphicsOperation::EBitBltMasked: + case TGraphicsOperation::EBitBltTransparent: + case TGraphicsOperation::EBitBltAlphaChannel: + case TGraphicsOperation::EBitBltAlphaBitmap: + case TGraphicsOperation::EScaledBitBlt: + case TGraphicsOperation::EScaledBitBltMasked: + case TGraphicsOperation::EScaledBitBltTransparent: + case TGraphicsOperation::EScaledBitBltAlphaChannel: + case TGraphicsOperation::EScaledBitBltAlphaBitmap: + case TGraphicsOperation::EFilledPolygon: + case TGraphicsOperation::EFilledPolygonWithPattern: + default: + return KErrNotSupported; + } + } + +TInt CHardwareGraphicsAcceleratorBase::Operation(TDes8& aBuffer) + { + //Lock(); + + TInt error = KErrNone; + TGraphicsOperation* gop = (TGraphicsOperation*) aBuffer.Ptr(); + TGraphicsOperation* limit = (TGraphicsOperation*) ((TUint8*)gop+aBuffer.Length()); + + while(gopNext(); + } + + //Unlock(); + + if(error==KErrNone) + { + __ASSERT_ALWAYS(gop==limit,GraphicsAcceleratorPanic(EGraphicsAcceleratorPanicInvalidOperationBuffer)); + } + else + { + aBuffer.SetLength((TUint8*)gop-aBuffer.Ptr()); + } + + return error; + } + +TInt CHardwareGraphicsAcceleratorBase::Operation(TDes8& aBuffer,TInt aNumClipRects,TRect* aClipRects) + { + //Lock(); + + TInt error = KErrNone; + TGraphicsOperation* gop = (TGraphicsOperation*) aBuffer.Ptr(); + TGraphicsOperation* limit = (TGraphicsOperation*) ((TUint8*)gop+aBuffer.Length()); + + while(gopNext(); + } + + //Unlock(); + + if(error==KErrNone) + { + __ASSERT_ALWAYS(gop==limit,GraphicsAcceleratorPanic(EGraphicsAcceleratorPanicInvalidOperationBuffer)); + } + else + { + aBuffer.SetLength((TUint8*)gop-aBuffer.Ptr()); + } + + return error; + } + +// Empty implementations +void CHardwareGraphicsAcceleratorBase::Reserved_1() {}; +void CHardwareGraphicsAcceleratorBase::Reserved_2() {}; +void CHardwareGraphicsAcceleratorBase::Reserved_3() {}; +void CHardwareGraphicsAcceleratorBase::Reserved_4() {}; + +// +// Misc +// + +GLREF_C void GraphicsAcceleratorPanic(TGraphicsAcceleratorPanic aPanicCode) + { + _LIT(KSCDVGraphicsAcceleratorPanicCategory,"Graphics Accelerator"); + User::Panic(KSCDVGraphicsAcceleratorPanicCategory,aPanicCode); + } +