graphicsdeviceinterface/screendriver/swins/AccelHard.cpp
changeset 0 5d03bc08d59c
--- /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 <windows.h>
+#include <windowsx.h>
+#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<<EColor256,												//iDisplayModes;
+	0,															//iClipping;
+	TGraphicsAcceleratorCaps::EMaskBitmapMatchingDisplayMode,	//iMaskType;
+	0,															//iTransparency;
+	0,															//iAlphaChannel;
+	TGraphicsAcceleratorCaps::EAlphaBitmapGray256,				//iAlphaBitmap;
+	(TUint)TGraphicsAcceleratorCaps::EPatternSizeAny,			//iPatternSizes;
+	TGraphicsAcceleratorCaps::EPatternMatchingDisplayMode,		//iPattern;
+	0,															//iPolygon;
+	{TGraphicsAcceleratorCaps::EOrientationCapNormal,0,0,0}		//iReserved[0] is used for supported orientations, iReserved[1]-iReserved[3] are reserved;
+	};
+
+//
+// CHardwareGraphicsAccelerator
+//
+
+/** 
+Allocates and constructs an instance of a derived class and initialises its 
+capabilities.
+
+@param aBitmap The hardware bitmap for the accelerator to draw to.
+@return Pointer to the initialised graphics accelerator object.
+@see TGraphicsAcceleratorCaps::iDisplayModes 
+@leave KErrNoMemory There is no memory to allocate the graphics accelerator
+       KErrNotSupported There is no graphics accelerator supporting the display mode given by the bitmap parameter
+*/
+EXPORT_C CHardwareGraphicsAccelerator* CHardwareGraphicsAccelerator::NewL(RHardwareBitmap aBitmap)
+	{
+	TAcceleratedBitmapInfo hwBitmapInfo;
+	aBitmap.GetInfo(hwBitmapInfo);
+
+	switch(hwBitmapInfo.iDisplayMode)
+		{
+		case EColor256:
+			return CColor256HardwareGraphicsAccelerator::NewL(aBitmap);
+		default:
+			User::Leave(KErrNotSupported);
+			return NULL;
+		}
+	}
+
+/** 
+Gets the generic capabilities of the accelerator, including which display modes 
+are supported for the bitmap passed to NewL().
+
+Generic capabilities apply to all hardware graphics accelerators on the device. 
+The function is static, so it can be used to find out the capabilities of 
+graphics accelerators before deciding on whether or not to create one.
+
+The CGraphicsAccelerator::Capabilities() function provides information about 
+the capabilities of a particular graphics accelerator.
+
+As capabilities may vary depending on the display mode of a bitmap, this method 
+should indicate as supported any features which are only available in some 
+display modes.
+@return Generic capabilities for hardware graphics accelerators. 
+*/
+EXPORT_C const TGraphicsAcceleratorCaps* CHardwareGraphicsAccelerator::GenericCapabilities()
+	{
+	return &HardwareAcceleratorCapabilities;
+	}
+
+//
+// CColor256HardwareGraphicsAccelerator
+//
+
+CColor256HardwareGraphicsAccelerator* CColor256HardwareGraphicsAccelerator::NewL(RHardwareBitmap aBitmap)
+	{
+	CColor256HardwareGraphicsAccelerator* self = new (ELeave) CColor256HardwareGraphicsAccelerator;
+	CleanupStack::PushL(self);
+	self->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<ptrLimit)
+				*(ptr++) = aFillValue;
+			*ptr = aFillValue;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else if(leftMask==0xFFFFFFFF) // first pixel starts on a word boundary but last doesn't
+		{
+		do
+			{
+			while(ptr<ptrLimit) 
+				*(ptr++) = aFillValue;
+
+			TUint32 pixels = *ptr;
+			pixels &= ~ rightMask;
+			pixels |= aFillValue&rightMask;
+			*ptr = pixels;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else if(rightMask==0) // last pixel lies on a word boundary but first doesn't
+		{
+		do
+			{
+			TUint32 pixels = *ptr;
+			pixels &= ~ leftMask;
+			pixels |= aFillValue&leftMask;
+			*(ptr++) = pixels;
+
+			while(ptr<ptrLimit)
+				*(ptr++) = aFillValue;
+			*ptr = aFillValue;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else // both last and first pixels in a line don't lie on a word boundary
+		{
+		do
+			{
+			TUint32 pixels = *ptr;
+			pixels &= ~ leftMask;
+			pixels |= aFillValue&leftMask;
+			*(ptr++) = pixels;
+
+			while(ptr<ptrLimit)
+				*(ptr++) = aFillValue;
+
+			pixels = *ptr;
+			pixels &= ~ rightMask;
+			pixels |= aFillValue&rightMask;
+			*ptr = pixels;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+
+	//Unlock();
+	return;
+error:
+//	Unlock();
+	GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap);
+	}
+
+TInt CColor256HardwareGraphicsAccelerator::DoFilledRectWithPattern(const TRect& aRect,TGopFillPattern aPattern)
+	{
+	if(aPattern.iBitmap.Type() != TAcceleratedBitmapSpec::EHardwareBitmap)
+		return KErrNotSupported;
+
+	TInt handle = aPattern.iBitmap.Handle();
+	RHardwareBitmap aBitmap(handle);
+
+	TAcceleratedBitmapInfo patternBitmapInfo;
+	aBitmap.GetInfo(patternBitmapInfo);
+
+    if(patternBitmapInfo.iDisplayMode != EColor256)
+		return KErrNotSupported;
+
+	//point to the first pixel of a row
+	TUint8* ptrPattern8 = (TUint8*)patternBitmapInfo.iAddress;
+	//point to the last pixels of a row
+	TUint8* ptrLimitPattern8 = ptrPattern8 + (patternBitmapInfo.iSize.iWidth - 1);
+	//current pixel to copy
+	TUint8* ptrCurrentPixelPattern8 = ptrPattern8;
+	TInt pitchPattern = patternBitmapInfo.iLinePitch;
+	//point to the last pixel of the pattern bitmap
+    TUint8* ptrEndPattern8 = ptrLimitPattern8 + pitchPattern * (patternBitmapInfo.iSize.iHeight - 1);
+	TInt xOffsetPattern = 0;
+	TInt difOrigins = 0;
+
+	TUint8* ptr8 = (TUint8*)iBitmapInfo.iAddress;
+	TUint8* ptrLimit8;
+	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;
+
+	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<ptrLimit8)
+			{
+			if(ptrCurrentPixelPattern8 == ptrLimitPattern8)
+				{
+				*ptr8 = *ptrCurrentPixelPattern8;
+				ptr8++;
+				ptrCurrentPixelPattern8 = ptrPattern8;
+				}
+			else
+				*(ptr8++) = *(ptrCurrentPixelPattern8++);
+			} 
+			//check if on the last row
+			if(ptrLimitPattern8 == ptrEndPattern8)
+				{
+				ptrPattern8 = (TUint8*)patternBitmapInfo.iAddress;
+				ptrLimitPattern8 = ptrPattern8 + patternBitmapInfo.iSize.iWidth - 1;
+                ptrCurrentPixelPattern8 = ptrPattern8 + xOffsetPattern;
+				}
+			else
+				{
+				ptrPattern8 += pitchPattern;
+				ptrLimitPattern8 += pitchPattern;
+                ptrCurrentPixelPattern8 = ptrPattern8 + xOffsetPattern;
+				}
+
+		ptr8 = ptr8+ptrPitch;
+		ptrLimit8= ptrLimit8+pitch;
+		}
+	while(--height);
+
+	return KErrNone;
+error:
+	GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap);
+	return KErrNone; // Will not be executed but prevents compiler warnings
+	}
+
+void CColor256HardwareGraphicsAccelerator::DoInvertRect(const TRect& aRect)
+	{
+	//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);
+	}
+
+	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<ptrLimit)
+				{
+				*(ptr++) = ~(*(ptr)) ;
+				}
+			*ptr = ~(*(ptr));
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else if(leftMask==0xFFFFFFFF) // first pixel starts on a word boundary but last doesn't
+		{
+		do
+			{
+			while(ptr<ptrLimit)
+				{
+				*(ptr++) = ~(*(ptr)) ;
+				}
+
+			TUint32 pixels = *ptr;
+			pixelsInverted = ~pixels;
+			pixels &= ~ rightMask;
+			pixels |= (pixelsInverted & rightMask);
+			*ptr = pixels;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else if(rightMask==0) // last pixel lies on a word boundary but first doesn't
+		{
+		do
+			{
+			TUint32 pixels = *ptr;
+			pixelsInverted = ~pixels;
+			pixels &= ~ leftMask;
+			pixels |= (pixelsInverted & leftMask);
+			*(ptr++) = pixels;
+
+			while(ptr<ptrLimit)
+				{
+				*(ptr++) = ~(*(ptr)) ;
+				}
+			*ptr = ~(*(ptr));
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+	else // both last and first pixels in a line don't lie on a word boundary
+		{
+		do
+			{
+			TUint32 pixels = *ptr;
+			pixelsInverted = ~pixels;
+			pixels &= ~ leftMask;
+			pixels |= (pixelsInverted & leftMask);
+			*(ptr++) = pixels;
+
+			while(ptr<ptrLimit)
+				{
+				*(ptr++) = ~(*(ptr));
+				}
+
+			pixels = *ptr;
+			pixelsInverted = ~pixels;
+			pixels &= ~ rightMask;
+			pixels |= (pixelsInverted & rightMask);
+			*ptr = pixels;
+
+			ptr = (TUint32*)((TUint8*)ptr+ptrPitch);
+			ptrLimit = (TUint32*)((TUint8*)ptrLimit+pitch);
+			}
+		while(--height);
+		}
+
+	return;
+error:
+	GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap);
+	}
+
+void CColor256HardwareGraphicsAccelerator::DoFadeRect(const TRect& aRect,const TGopFadeParams aFade)
+	{
+
+	TUint8* ptr8 = (TUint8*)iBitmapInfo.iAddress;
+	TUint8* prtLimit8;
+	TInt ptrPitch;
+	TInt pitch;
+	TInt height;
+
+	TInt scale = aFade.iScale;
+	TInt offset = aFade.iOffset;
+
+	TRgb color;
+
+	{
+	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;
+
+	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<prtLimit8)
+			{
+			TUint8 index = *ptr8;
+			color = TRgb::Color256(index);
+
+			TInt32 value = color.Internal();
+
+			TInt b = (((value & 0x000000ff) * scale) >> 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<prtLimitSource8)
+				*(ptrDest8++) = *(ptrSource8++);
+
+			ptrSource8 = ptrSource8+ptrPitchSource;
+			prtLimitSource8 = prtLimitSource8+pitchSource;
+			ptrDest8 = ptrDest8+ptrPitchDest;
+			ptrLimitDest8 = ptrLimitDest8+pitchDest;
+			}
+		while(--height);
+		}
+	else
+		{
+		//distances in bit from the left edge
+		xSourceStart <<= sourceBitmapInfo.iPixelShift;
+		xSourceEnd <<= sourceBitmapInfo.iPixelShift;
+		xDestStart <<= iBitmapInfo.iPixelShift;
+		xDestEnd <<= iBitmapInfo.iPixelShift;
+
+		ptrSource32 = (TUint32*)((TUint8*)ptrSource32 + ySourceStart*sourceBitmapInfo.iLinePitch);
+	    ptrDest32 = (TUint32*)((TUint8*)ptrDest32 + destRect.iTl.iY*iBitmapInfo.iLinePitch);
+
+	    leftMask = ~((1<<(xSourceStart&0x1F))-1);
+	    rightMask = (1<<(xSourceEnd&0x1F))-1;
+
+		xSourceStart >>= 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<prtLimitSource32)
+					*(ptrDest32++) = *(ptrSource32++);
+				*ptrDest32 = *ptrSource32;
+
+				ptrSource32 = (TUint32*)((TUint8*)ptrSource32+ptrPitchSource);
+				prtLimitSource32 = (TUint32*)((TUint8*)prtLimitSource32+pitchSource);
+				ptrDest32 = (TUint32*)((TUint8*)ptrDest32+ptrPitchDest);
+				ptrLimitDest32 = (TUint32*)((TUint8*)ptrLimitDest32+pitchDest);
+				}
+			while(--height);
+			}
+			else if(leftMask==0xFFFFFFFF) // first pixel starts on a word boundary but last doesn't
+				{
+				do
+					{
+					while(ptrSource32<prtLimitSource32) 
+					*(ptrDest32++) = *(ptrSource32++);
+
+					TInt pixelsSource = *ptrSource32;
+					TInt pixelsDest = *ptrDest32;
+					pixelsSource &= rightMask;
+					pixelsDest &= ~ rightMask;
+					pixelsDest |= pixelsSource;
+					*ptrDest32 = pixelsDest;
+
+					ptrSource32 = (TUint32*)((TUint8*)ptrSource32+ptrPitchSource);
+					prtLimitSource32 = (TUint32*)((TUint8*)prtLimitSource32+pitchSource);
+					ptrDest32 = (TUint32*)((TUint8*)ptrDest32+ptrPitchDest);
+					ptrLimitDest32 = (TUint32*)((TUint8*)ptrLimitDest32+pitchDest);
+					}
+				while(--height);
+				}
+			else if(rightMask==0) // last pixel lies on a word boundary but first doesn't
+				{
+				do
+					{
+					TInt pixelsSource = *ptrSource32;
+					TInt pixelsDest = *ptrDest32;
+					pixelsSource &= leftMask;
+					pixelsDest &= ~ leftMask;
+					pixelsDest |= pixelsSource;
+					*(ptrDest32++) = pixelsDest;
+					ptrSource32++;
+
+					while(ptrSource32<prtLimitSource32)
+						*(ptrDest32++) = *(ptrSource32++);
+					*ptrDest32 = *ptrSource32;
+
+					ptrSource32 = (TUint32*)((TUint8*)ptrSource32+ptrPitchSource);
+					prtLimitSource32 = (TUint32*)((TUint8*)prtLimitSource32+pitchSource);
+					ptrDest32 = (TUint32*)((TUint8*)ptrDest32+ptrPitchDest);
+					ptrLimitDest32 = (TUint32*)((TUint8*)ptrLimitDest32+pitchDest);
+					}
+				while(--height);
+				}
+			else // both last and first pixels in a line don't lie on a word boundary
+				{
+				do
+					{
+					TInt pixelsSource = *ptrSource32;
+					TInt pixelsDest = *ptrDest32;
+					pixelsSource &= leftMask;
+					pixelsDest &= ~ leftMask;
+					pixelsDest |= pixelsSource;
+					*(ptrDest32++) = pixelsDest;
+					ptrSource32++;
+
+					while(ptrSource32<prtLimitSource32)
+						*(ptrDest32++) = *(ptrSource32++);
+
+					pixelsSource = *ptrSource32;
+					pixelsDest = *ptrDest32;
+					pixelsSource &= rightMask;
+					pixelsDest &= ~ rightMask;
+					pixelsDest |= pixelsSource;
+					*ptrDest32 = pixelsDest;
+
+					ptrSource32 = (TUint32*)((TUint8*)ptrSource32+ptrPitchSource);
+					prtLimitSource32 = (TUint32*)((TUint8*)prtLimitSource32+pitchSource);
+					ptrDest32 = (TUint32*)((TUint8*)ptrDest32+ptrPitchDest);
+					ptrLimitDest32 = (TUint32*)((TUint8*)ptrLimitDest32+pitchDest);
+					}
+				while(--height);
+				}
+			}
+	return KErrNone;
+error:
+	GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap);
+	return KErrNone; // Will not be executed but prevents compiler warnings
+	}
+
+TInt CColor256HardwareGraphicsAccelerator::DoBitBltMasked(const TPoint& aDestination,const TAcceleratedBitmapSpec& aSourceBitmapSpec,const TRect& aSourceRect,const TAcceleratedBitmapSpec& aMaskBitmapSpec)
+	{
+    //Destination Bitmap
+	TUint8* ptrDest8 = (TUint8*)iBitmapInfo.iAddress;
+	TUint8* ptrLimitDest8;
+
+	//Source Bitmap
+	if(aSourceBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap)
+		return KErrNotSupported;
+
+	TInt handleSourceBitmap = aSourceBitmapSpec.Handle();
+	RHardwareBitmap sourceBitmap(handleSourceBitmap);
+
+	TAcceleratedBitmapInfo sourceBitmapInfo;
+	sourceBitmap.GetInfo(sourceBitmapInfo);
+
+	TUint8* ptrSource8 = (TUint8*)sourceBitmapInfo.iAddress;
+	TUint8* prtLimitSource8;
+
+
+	//Mask Bitmap
+	if(aMaskBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap)
+		return KErrNotSupported;
+
+	TInt handleMaskBitmap = aMaskBitmapSpec.Handle();
+	RHardwareBitmap maskBitmap(handleMaskBitmap);
+
+	TAcceleratedBitmapInfo maskBitmapInfo;
+	maskBitmap.GetInfo(maskBitmapInfo);
+
+    if((sourceBitmapInfo.iDisplayMode != EColor256) || (maskBitmapInfo.iDisplayMode != EColor256))
+		return KErrNotSupported;
+
+	
+	TUint8* ptrMask8 = (TUint8*)maskBitmapInfo.iAddress;
+	TUint8* ptrLimitMask8;
+
+
+	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;
+
+	TInt ptrPitchSource;
+	TInt pitchSource;
+	TInt ptrPitchDest;
+	TInt pitchDest;
+	TInt ptrPitchMask;
+	TInt pitchMask;
+
+	TInt height;
+
+	TRect area(aSourceRect); //final area from aSourceRect to blit
+	TRect destRect(aSourceRect.Size());
+    
+	if(sourceBitmapInfo.iSize != maskBitmapInfo.iSize)
+		return KErrNotSupported;
+
+	//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;
+
+    //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<prtLimitSource8)
+			{
+		    *ptrDest8 = (TUint8)((*ptrSource8 & (~(*ptrMask8))) | (*ptrDest8 & *ptrMask8));
+			ptrMask8++;
+			ptrDest8++;
+			ptrSource8++;
+			}
+
+		ptrSource8 = ptrSource8+ptrPitchSource;
+		prtLimitSource8 = prtLimitSource8+pitchSource;
+		ptrDest8 = ptrDest8+ptrPitchDest;
+		ptrLimitDest8 = ptrLimitDest8+pitchDest;
+		ptrMask8 = ptrMask8+ptrPitchMask;
+		ptrLimitMask8 = ptrLimitMask8+pitchMask;
+		}
+	while(--height);
+
+	
+	return KErrNone;
+error:
+	GraphicsAcceleratorPanic(EGraphicsAcceleratorAttemptedDrawOutsideBitmap);
+	return KErrNone; // Will not be executed but prevents compiler warnings
+	}
+
+TInt CColor256HardwareGraphicsAccelerator::DoBitBltAlphaBitmap(const TPoint& aDestination,const TAcceleratedBitmapSpec& aSourceBitmapSpec,const TRect& aSourceRect,const TAcceleratedBitmapSpec& aAlphaBitmapSpec)
+	{
+
+    //Destination Bitmap
+	TUint8* ptrDest8 = (TUint8*)iBitmapInfo.iAddress;
+	TUint8* ptrLimitDest8;
+
+	//Source Bitmap
+	if(aSourceBitmapSpec.Type() != TAcceleratedBitmapSpec::EHardwareBitmap)
+		return KErrNotSupported;
+
+	TInt handleSourceBitmap = aSourceBitmapSpec.Handle();
+	RHardwareBitmap sourceBitmap(handleSourceBitmap);
+
+	TAcceleratedBitmapInfo sourceBitmapInfo;
+	sourceBitmap.GetInfo(sourceBitmapInfo);
+
+	TUint8* ptrSource8 = (TUint8*)sourceBitmapInfo.iAddress;
+	TUint8* prtLimitSource8;
+
+	//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;
+	TUint8* ptrLimitAlpha8;
+
+	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;
+
+	TInt ptrPitchSource;
+	TInt pitchSource;
+	TInt ptrPitchDest;
+	TInt pitchDest;
+	TInt ptrPitchAlpha;
+	TInt pitchAlpha;
+
+	TInt height;
+
+	TRect area(aSourceRect); //final area from aSourceRect to blit
+	TRect destRect(aSourceRect.Size());
+
+	TRgb color;
+    
+	if(sourceBitmapInfo.iSize != alphaBitmapInfo.iSize)
+		return KErrNotSupported;
+
+	//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;
+
+    //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<prtLimitSource8)
+			{
+			//Source color information
+			TUint8 index = *ptrSource8;
+			color = TRgb::Color256(index);
+			TUint32 value = color.Internal();
+			TInt blueSource = (value & 0x000000ff);
+			TInt greenSource = (value  & 0x0000ff00) >> 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(gop<limit)
+		{
+		error = Operation(*gop);
+		if(error!=KErrNone)
+			break;
+		gop = gop->Next();
+		}
+
+	//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(gop<limit)
+		{
+		error = Operation(*gop,aNumClipRects,aClipRects);
+		if(error!=KErrNone)
+			break;
+		gop = gop->Next();
+		}
+
+	//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);
+	}
+