graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp
author Gareth Stockwell <gareth.stockwell@accenture.com>
Fri, 05 Nov 2010 17:31:20 +0000
branchbug235_bringup_0
changeset 215 097e92a68d68
parent 0 5d03bc08d59c
permissions -rw-r--r--
Added GLES 1.x spinning cube-rendering code to eglbringuptest The coordinate, color and index data are uploaded to server-side buffers by the CGLES1Cube::KhrSetup function. CGLES1Cube::KhrPaint just sets the view matrix and issues a draw command. Which demo to display can be selected by passing its name on the command line, e.g. eglbringuptest vgline eglbringuptest gles1cube If no name is provided, the application defaults to vgline.

// Copyright (c) 2004-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 <hal.h>
#include <e32math.h>
#include "TAlphaBlend.h"


const TInt KWidth = 10;//Used in alpha blending tests
const TInt KHeight = 3;//Used in alpha blending tests
const TInt KMaximumAttempts = 2;	// Allow retries on some tests, due to spurious InfoPrints 
TBool iExtraLogging1=EFalse;		//Used to trigger logging at times the test fails
TBool iExtraLogging2=EFalse;		//Used to trigger logging at times the test fails

CTAlphaBlending::CTAlphaBlending(CTestStep* aStep):
	CTGraphicsBase(aStep),
	iDevice(NULL),
	iGc(NULL)
	{
	}

CTAlphaBlending::~CTAlphaBlending()
	{
	DeleteGraphicsContext();
	DeleteScreenDevice();
	}

void CTAlphaBlending::RunTestCaseL(TInt aCurTestCase)
	{
	((CTAlphaBlendingStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
	switch(aCurTestCase)
		{
	case 1:
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0024"));
		INFO_PRINTF1(_L("Alpha blending"));
		TestAlphaBlendingL();
		break;		
	case 2:
/**
@SYMTestCaseID		GRAPHICS-BITGDI-0114
*/
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0114"));
		INFO_PRINTF1(_L("Alpha blending 2"));
		TestAlphaBlending2L();
		break;
	case 3:
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
 		INFO_PRINTF1(_L("Alpha blending Correctness test 16MU 16MA"));
 		TestAlphaBlendCorrect(EColor16MU, EColor16MU);
 		break;
 	case 4:
 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097"));
 		INFO_PRINTF1(_L("Alpha plot test"));
		TestAlphaBlendingPlotL();
		break;
	case 5:
/**
@SYMTestCaseID		GRAPHICS-BITGDI-0115
*/
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0115"));
		INFO_PRINTF1(_L("Draw bitmap blending"));
		DoDrawBitmapTestsL();
		break;
	case 6:
		//DEF118268
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
		INFO_PRINTF1(_L("Alpha blending Correctness test 16M 16MA"));
		TestAlphaBlendCorrect(EColor16M, EColor16MA);
		break;
	case 7:
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
		((CTAlphaBlendingStep*)iStep)->CloseTMSGraphicsStep();
		TestComplete();
		break;
		}
	((CTAlphaBlendingStep*)iStep)->RecordTestResultL();
	}

TInt CTAlphaBlending::CreateScreenDevice(TDisplayMode aDisplayMode, CFbsBitGc::TGraphicsOrientation aOrientation)
	{
	DeleteGraphicsContext();
	DeleteScreenDevice();
	TRAPD(err, iDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
	if(err == KErrNotSupported)
		{
		return err;
		}
	TEST2(err, KErrNone);
	err = iDevice->CreateContext((CGraphicsContext*&)iGc);
	TEST2(err, KErrNone);
	if (!iGc->SetOrientation(aOrientation))
		{
		return(KErrNotSupported);
		}
	iGc->SetUserDisplayMode(aDisplayMode);
	iDevice->ChangeScreenDevice(NULL);
	iDevice->SetAutoUpdate(EFalse);
	return err;
	}

void CTAlphaBlending::DeleteScreenDevice()
	{
	delete iDevice;
	iDevice = NULL;
	}

void CTAlphaBlending::DeleteGraphicsContext()
	{
	delete iGc;
	iGc = NULL;
	}

// returns the pixel colour from the provided bitmap in aarrggbb format
// if pixel is outside the bitmaps limits return top left pixel
TUint32 CTAlphaBlending::GetRawPixel(CFbsBitmap* aBitmap, TPoint aPos)
	{
	TBitmapUtil bmpUtil(aBitmap);	
	TUint32 value = 0;
	ASSERT(aPos.iX>=0 && aPos.iY>=0);
	ASSERT(aPos.iX<aBitmap->SizeInPixels().iWidth && aPos.iY<aBitmap->SizeInPixels().iHeight);
	bmpUtil.Begin(aPos);
	value = bmpUtil.GetPixel();
	bmpUtil.End();
	return value;	
	}

/**
@SYMTestCaseID		GRAPHICS-BITGDI-0097

@SYMDEF             DEF113229

@SYMTestCaseDesc    CDrawThirtyTwoBppBitmapCommon::WriteRgb did not change the dest alpha value to 255 when 
					the dest alpha was >0 and <255 and the a soure pen had an alpha of 255	

@SYMTestPriority    Normal

@SYMTestStatus      Implemented

@SYMTestActions     Creates a bitmap, clears it to black (destination) 50% opaque then plots a series of points 
					with a 100% opaque pen on it. Tests the resultant alpha value.

@SYMTestExpectedResults Final alpha value should be 255
**/
void CTAlphaBlending::TestAlphaBlendingPlotL()
	{
	const TSize KRectSize(100,100);
	const TRect KTargetRect(TPoint(0,0), KRectSize);
		
	// create the target bitmap
	CFbsBitmap* destBmp = new (ELeave) CFbsBitmap;
	CleanupStack::PushL(destBmp);
	User::LeaveIfError(destBmp->Create(KRectSize, EColor16MA));
	destBmp->SetSizeInTwips(KRectSize);
	
	// create bitmap device and graphics context
	CFbsBitmapDevice* destBmpDevice = CFbsBitmapDevice::NewL(destBmp);
	CleanupStack::PushL(destBmpDevice);
	CFbsBitGc* destGc = NULL;
	User::LeaveIfError(destBmpDevice->CreateContext(destGc));
	CleanupStack::PushL(destGc);
	destGc->SetPenStyle(CGraphicsContext::ENullPen);
	destGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
		
	TDisplayMode screenMode = EColor16MA;
	TInt err = CreateScreenDevice(screenMode);
	if (err != KErrNone)
		{
		screenMode = EColor64K;
		err = CreateScreenDevice(screenMode);
		}
	
	if(err==KErrNone)
		{
		const TInt KSqrMin=45;
		const TInt KSqrMax=55;
						
		iGc->SetUserDisplayMode(screenMode);
		destGc->SetBrushColor(TRgb(0,0,0,127));
		destGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
		destGc->Clear(KTargetRect);

		// copy over to screen dc for anyone watching
		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
		iDevice->Update();
		
		// set the pen colour to white and plot some points
		destGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
		destGc->SetPenStyle(CGraphicsContext::ESolidPen);
		destGc->SetPenColor(TRgb(0,70,130,255));
		for( TInt y=KSqrMin;y<=KSqrMax;y++)
			{
			for( TInt x=KSqrMin;x<=KSqrMax;x++)
				{
				destGc->Plot(TPoint(x,y));
				}
			}
			
		// copy over to screen dc for anyone watching
		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
		iDevice->Update();
		
		TUint32 actualValue=0;
		// check the resulting values alpha values are 0xFF in the square we drew
		for( TInt y=KSqrMin;y<=KSqrMax;y++)
			{
			for( TInt x=KSqrMin;x<=KSqrMax;x++)
				{
				actualValue = GetRawPixel(destBmp, TPoint(x,y));
				if( (actualValue&0xFF000000) != 0xFF000000 )
					{
					TEST(EFalse);
					INFO_PRINTF2(_L("TestAlphaBlendingPlotL() ***FAILED*** - expected alpha value 0xFF got %d "),((actualValue&0xFF000000)>>24));
					}
				}
			}
		}
		CleanupStack::PopAndDestroy(3); //destGc,destBmpDevice,destBmp
	}

/**
  @SYMTestCaseID GRAPHICS-BITGDI-0024
 
  @SYMDEF             

  @SYMTestCaseDesc 
   
	System, GT0173 System Libraries, BITGDI support required for semi-transparent windows
	DEF039083 - Using BitBltMasked to do alpha-blending only works if your brush style is "null"
	DEF039409 - Wrong part of Alpha Bitmap is used when there is a clipping region 
	DEF039669 - The UserDisplayMode is not honoured during the AlphaBlendBitmap function. 
	REQ3413 Second overload of CFbsBitGc's AlphaBlendBitmaps - "Supply a second overload of 
	CFbsBitGc's AlphaBlendBitmaps function, but with one of the source bitmaps being passed 
	as a CFbsBitGc object, so that the screen can be used as a source."

  @SYMTestPriority High

  @SYMTestStatus Implemented

  @SYMTestActions 
  	
  	Tests alpha blending - for all display modes, some brush styles, user display modes, 
	different positions on the screen.
  
	Shadow/fade mode is no more tested, because the existing BitBltMasked() and the new 
	AlphaBlendBitmaps() methods treat it a different way - see MAlphaBlend interface in
	ScreenDriver component.

  @SYMTestExpectedResults Test should perform graphics operations succesfully. 
*/

void CTAlphaBlending::TestAlphaBlendingL()
	{
	TPoint originPt(0, 0);
	TPoint destPt(0, 0);
	TRect scrRc1(0, 0, KWidth, KHeight);
	TPoint srcPt2(0, 0);
	TPoint alphaPt(0, 0);
	//
	//If we compare CFbsBitGc::BitBltMasked() aguments with CFbsBitGc::AlphaBlending() arguments,
	//we will see that AlphaBlending() has more arguments than BitBltMasked() - 
	//srcPt2, alphaPt. To make it possible - the comparison between these two methods,
	//we have to change aAlphaPt and aSrcPt2 values accordingly with the changes of scrRc1 value.
	//
	//test 1 - the origin is moved
	originPt = TPoint(97, 33);
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
#if !defined(__X86GCC__)	//These test take too long to run in X86GCC
	//test 2 - the origin is (0, 0)
	originPt = TPoint(0, 0);
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
	//test 3 - scrRect1 is not (0, 0, KWidth, KHeight)
	scrRc1 = TRect(3, 1, KWidth, KHeight);
	alphaPt = TPoint(3, 1);
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
	//test 4 - restore scrRc1 and alphaPt, move the destination point
	scrRc1 = TRect(0, 0, KWidth, KHeight);
	alphaPt = TPoint(0, 0);
	destPt = TPoint(13, 17);
	iExtraLogging1=ETrue;
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
	iExtraLogging1=EFalse;
#endif	//__X86GCC__
	}

void CTAlphaBlending::DoDrawBitmapTestsL()
	{
	TDisplayMode modes[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K, 
						   EGray256, EGray16, EGray4, EGray2, EColor16};
	const TInt KNumTestDisplayModes=sizeof(modes)/sizeof(modes[0]);
	for(TInt modeIndex=0;modeIndex<KNumTestDisplayModes;modeIndex++)
		{
		TDisplayMode screenMode=modes[modeIndex];
		if (CreateScreenDevice(screenMode)!=KErrNone)
			continue;
		DoDrawBitmapTestL(screenMode);
		}
	}

void CTAlphaBlending::DoDrawBitmapTestL(TDisplayMode aTestDisplayMode)
	{
	iGc->Reset();
	TBool alphaSupported=(aTestDisplayMode==EColor16MA || aTestDisplayMode==EColor16MAP);
	TSize screenSize=iDevice->SizeInPixels();
//
	const TInt KNumTestSrcSizes=4;
	const TSize testSrcSizes[KNumTestSrcSizes]={TSize(2,2),TSize(20,10),TSize(200,5),TSize(55,555)};
	for(TInt srcSizeIndex=0;srcSizeIndex<KNumTestSrcSizes;srcSizeIndex++)
		{
		TSize srcSize(testSrcSizes[srcSizeIndex]);
//
		CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap;
		CleanupStack::PushL(srcBmp);
		User::LeaveIfError(srcBmp->Create(srcSize,aTestDisplayMode));
		CFbsBitmapDevice* srcDevice = CFbsBitmapDevice::NewL(srcBmp);
		CleanupStack::PushL(srcDevice);
		CFbsBitGc* srcGc=NULL;
		User::LeaveIfError(srcDevice->CreateContext(srcGc));
		CleanupStack::PushL(srcGc);
//
		CFbsBitmap* srcAlpha=new(ELeave) CFbsBitmap;
		CleanupStack::PushL(srcAlpha);
		User::LeaveIfError(srcAlpha->Create(srcSize,aTestDisplayMode));
		CFbsBitmapDevice* srcAlphaDevice = CFbsBitmapDevice::NewL(srcAlpha);
		CleanupStack::PushL(srcAlphaDevice);
		CFbsBitGc* srcAlphaGc=NULL;
		User::LeaveIfError(srcAlphaDevice->CreateContext(srcAlphaGc));
		CleanupStack::PushL(srcAlphaGc);
		srcAlphaGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
//
		CFbsBitmap* srcMask=new(ELeave) CFbsBitmap;
		CleanupStack::PushL(srcMask);
		User::LeaveIfError(srcMask->Create(srcSize,EGray256));
		CFbsBitmapDevice* srcMaskDevice = CFbsBitmapDevice::NewL(srcMask);
		CleanupStack::PushL(srcMaskDevice);
		CFbsBitGc* srcMaskGc=NULL;
		User::LeaveIfError(srcMaskDevice->CreateContext(srcMaskGc));
		CleanupStack::PushL(srcMaskGc);
//
		TInt maxX=srcSize.iWidth-1;
		TInt maxY=srcSize.iHeight-1;
		for(TInt yLoop=0;yLoop<srcSize.iHeight;yLoop++)
			{
			for(TInt xLoop=0;xLoop<srcSize.iWidth;xLoop++)
				{
				TPoint plotPos(xLoop,yLoop);
				TRgb pen(xLoop*255/maxX,yLoop*255/maxY,(xLoop+yLoop)*128/(maxX+maxY));
				srcGc->SetPenColor(pen);
				srcGc->Plot(plotPos);
				TInt alpha=(xLoop+yLoop)*255/(maxX+maxY);
				pen.SetAlpha(alpha);
				srcAlphaGc->SetBrushColor(pen);
				srcAlphaGc->Clear(TRect(plotPos,TSize(1,1)));
				srcMaskGc->SetPenColor(TRgb::Gray256(alpha));
				srcMaskGc->Plot(plotPos);
				}
			}
		const TInt KNumTestTargSizes=5;
		const TSize testTargSizes[KNumTestTargSizes]={TSize(0,0), TSize(20,1),TSize(30,20),TSize(200,31),TSize(55,5)};
		for(TInt targSizeIndex=0;targSizeIndex<KNumTestSrcSizes;targSizeIndex++)
			{
			TSize targSize(testTargSizes[targSizeIndex]);
			if (targSizeIndex==0)
				{
				targSize=srcSize;	// Special case with no scaling
				if (targSize.iWidth>screenSize.iWidth)
					targSize.iWidth=screenSize.iWidth;
				TInt maxHeight=screenSize.iHeight/3;
				if (targSize.iHeight>maxHeight)
					targSize.iHeight=maxHeight;
				}
//
			CFbsBitmap* targBmp=new(ELeave) CFbsBitmap;
			CleanupStack::PushL(targBmp);
			User::LeaveIfError(targBmp->Create(targSize,aTestDisplayMode));
			CFbsBitmapDevice* targBmpDevice = CFbsBitmapDevice::NewL(targBmp);
			CleanupStack::PushL(targBmpDevice);
			CFbsBitGc* targGc=NULL;
			User::LeaveIfError(targBmpDevice->CreateContext(targGc));
			CleanupStack::PushL(targGc);
//
			CFbsBitmap* targMask=new(ELeave) CFbsBitmap;
			CleanupStack::PushL(targMask);
			User::LeaveIfError(targMask->Create(targSize,EGray256));
			CFbsBitmapDevice* targMaskDevice = CFbsBitmapDevice::NewL(targMask);
			CleanupStack::PushL(targMaskDevice);
			CFbsBitGc* targMaskGc=NULL;
			User::LeaveIfError(targMaskDevice->CreateContext(targMaskGc));
			CleanupStack::PushL(targMaskGc);
//
			TPoint drawPos;
			TRect testRect1(targSize);
			iGc->Clear();
// First we pre-stretch the source and mask bitmaps into temp bitmaps
			targGc->DrawBitmap(TRect(targSize),srcBmp);
			targMaskGc->DrawBitmap(TRect(targSize),srcMask);
// Then blend them onto the screen with a call to BitBltMasked
			iGc->BitBltMasked(drawPos,targBmp,TRect(targSize),targMask,EFalse);
			drawPos.iY+=targSize.iHeight;
			TRect testRect2(drawPos,targSize);
// Next we combine the stretching and masking with one call to DrawBitmapMasked,
// this should give the same end result.
			iGc->DrawBitmapMasked(testRect2,srcBmp,TRect(srcSize),srcMask,EFalse);
			TRect testRect3;
			if (alphaSupported)
				{
// Finally if alpha blending supported we stretch and blend, again to achieve the exact same end result
// as the two previous calls. This was specificially done to catch DEF116427.
				drawPos.iY+=targSize.iHeight;
				testRect3=TRect(drawPos,targSize);
				iGc->DrawBitmap(testRect3,srcAlpha);
				}
//Use this just to check what we've put in the test bitmaps
/*
			drawPos.iY+=targSize.iHeight+1;
			iGc->BitBlt(drawPos,srcBmp);
			drawPos.iY+=srcSize.iHeight+1;
			iGc->BitBlt(drawPos,srcMask);
			drawPos.iY+=srcSize.iHeight+1;
			if (alphaSupported)
				iGc->BitBlt(drawPos,srcAlpha);
*/
		   	iDevice->Update();
			TBool ret1=iDevice->RectCompare(testRect1,*iDevice,testRect2);
		   	TBool ret2=alphaSupported?iDevice->RectCompare(testRect1,*iDevice,testRect3):ETrue;
			if (!ret1 || !ret2)
				{
				INFO_PRINTF4(_L("DrawBitmapTest, ret1=%d, ret2=%d, Screen mode=%d"),ret1,ret2,aTestDisplayMode);
				TEST(EFalse);
				}
			CleanupStack::PopAndDestroy(3,targMask);
			CleanupStack::PopAndDestroy(3,targBmp);
			}
		CleanupStack::PopAndDestroy(3,srcMask);
		CleanupStack::PopAndDestroy(3,srcAlpha);
		CleanupStack::PopAndDestroy(3,srcBmp);
		}
	}

//Tests alpha blending - for all display modes, some brush styles, user display modes, 
//different positions on the screen.
void CTAlphaBlending::DoAlphaBlendingTestsL(const TPoint& aOrigin,
										const TPoint& aDestPt, 
										const TRect& aSrcRc1, 
										const TPoint& aScrPt2,
										const TPoint& aAlphaPt)
	{
	TBuf<128> buf;
	_LIT(KLog,"Origin=(%d,%d) DestPt=(%d,%d) SrcRect=(%d,%d,%d,%d) ScrPt=(%d,%d) AlphaPt=(%d,%d)");
	buf.Format(KLog,aOrigin.iX,aOrigin.iY,aDestPt.iX,aDestPt.iY,aSrcRc1.iTl.iX,aSrcRc1.iTl.iY
						,aSrcRc1.iBr.iX,aSrcRc1.iBr.iY,aScrPt2.iX,aScrPt2.iY,aAlphaPt.iX,aAlphaPt.iY);
	INFO_PRINTF1(buf);
	TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
						   EGray256, EGray16, EGray4, EGray2, EColor16};
	CFbsBitmap* screenBmp = NULL;
	CFbsBitmap* srcBmp = NULL;
	CFbsBitmap* alphaBmp = NULL;
	CGraphicsContext::TBrushStyle brushStyle[] = {CGraphicsContext::ENullBrush, CGraphicsContext::ESolidBrush};
	for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
		{
		for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
			{
			if (CreateScreenDevice(mode[i],(CFbsBitGc::TGraphicsOrientation)orientation) != KErrNone)
				{
				continue;
				}
			iExtraLogging2=(iExtraLogging1 && mode[i]==11);
	 		INFO_PRINTF3(_L("Mode=%d, Orientation=%d"), mode[i], orientation);
			CreateAlphaBlendingBitmapsLC(screenBmp, srcBmp, alphaBmp, mode[i]);
			for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
				{
				if(mode[i] == EGray4 && brushStyle[j] == CGraphicsContext::ESolidBrush)
					{
					//When the display mode is EGray4 - Flicker-free blitting is not enabled.
					//The screen will be filled with 0xFF color, which is not the same color used by
					//the test - 0x00. And BitBltMasked and AlphaBlendBitmaps will produce different results.
					continue;
					}
				iGc->SetOrigin(aOrigin);
				iGc->SetBrushStyle(brushStyle[j]);
				TDisplayMode userDisplayMode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, 
												  EColor4K, EColor64K, EGray256, 
												  EGray16, EGray4, EGray2, EColor16};
				for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
					{
					iGc->SetUserDisplayMode(userDisplayMode[l]);
					TSize scrDevSize = iDevice->SizeInPixels();
					TRect clipRc[] = {TRect(0, 0, scrDevSize.iWidth, scrDevSize.iHeight),
										TRect(0, 1, scrDevSize.iWidth, scrDevSize.iHeight), // Tests Y clipping only
										TRect(5, 0, scrDevSize.iWidth, scrDevSize.iHeight), // Tests X clipping only
										TRect(5, 1, scrDevSize.iWidth, scrDevSize.iHeight),
										TRect(3, 0, 14, 23)};//14 and 23 values are not accidental! 
															 //Sometimes the method is called with aDestPt(13, 17).
					for(TInt k=0;k<TInt(sizeof(clipRc)/sizeof(clipRc[0]));k++)
						{
						if (iExtraLogging2)
							{
							_LIT(KLog,"  BrushStyle=%d UserDisplayMode=%d ClipRect=(%d,%d,%d,%d)");
			 				INFO_PRINTF7(KLog,j,l,clipRc[k].iTl.iX,clipRc[k].iTl.iY,clipRc[k].iBr.iX,clipRc[k].iBr.iY);
							}
						iGc->Clear();
						iGc->SetClippingRect(clipRc[k]);
						DoAlphaBlendingTestL(screenBmp, srcBmp, alphaBmp, aDestPt, aSrcRc1, aScrPt2, aAlphaPt);
						iGc->CancelClippingRect();
						}
					}//end of - for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
				iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
				}
			DestroyAlphaBlendingBitmaps(screenBmp, srcBmp, alphaBmp);
			}//end of - for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
		}//end of - for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
	}

//The method compares results of two alpha blending methods:
//iGc->BitBltMasked() and iGc->AlphaBlendBitmaps().
//To make that possible, aScreenBmp is copied to the screen before the call of
//iGc->BitBltMasked().
void CTAlphaBlending::DoAlphaBlendingTestL(CFbsBitmap* aScreenBmp, 
									   const CFbsBitmap* aSrcBmp, 
									   const CFbsBitmap* aAlphaBmp,
									   const TPoint& aDestPt, 
									   const TRect& aSrcRc1, 
									   const TPoint& aSrcPt2,
									   const TPoint& aAlphaPt)
	{
	_LIT(KScreenBmpFile, "C:\\BMP_DATA.DAT");
	iGc->SetShadowMode(EFalse);
   	TInt i;
   	TInt res = -1;
	TSize scrDevSize = iDevice->SizeInPixels();
	TInt allocatedSize = scrDevSize.iWidth * scrDevSize.iHeight * 2;
	TRect screenBmpRc;
   	//The screen alpha blended data after calling of BitBltMasked() - will be filled after the call
	TUint8* screenBmpDestData1 = new (ELeave) TUint8[allocatedSize];
	CleanupStack::PushL(screenBmpDestData1);
   	//The screen alpha blended data after calling of AlphaBlendingBitmaps() - will be filled after the call
	TUint8* screenBmpDestData2 = new (ELeave) TUint8[allocatedSize];
	CleanupStack::PushL(screenBmpDestData2);
	// Allow an effective restart of the test, since sometimes there are spurious
	// InfoPrints that affect the comparisons.
	for (TInt attempt = 0; res && (attempt < KMaximumAttempts); attempt++)
		{
		//Fill the blocks with some default value
		Mem::Fill(screenBmpDestData1, allocatedSize, 0xCA);
		Mem::Fill(screenBmpDestData2, allocatedSize, 0xCA);
	   	//Check screen bitmap size
	   	TSize screenBmpSize = aScreenBmp->SizeInPixels();
	   	if ((screenBmpSize.iWidth != KWidth) || (screenBmpSize.iHeight != KHeight))
	   		{
	   		_LIT(KScreenErr,"DoAlphaBlendingTestL test: w:%d!=%d || h:%d!=%d");
	   		INFO_PRINTF5(KScreenErr, screenBmpSize.iWidth, KWidth, screenBmpSize.iHeight, KHeight);
	   		TEST(EFalse);
	   		}
		//  Alpha blending using CFbsBitGc::BitBltMasked  //
		if (iExtraLogging2)
			{
			_LIT(KLog1,"    CFbsBitGc::BitBltMasked test");
			INFO_PRINTF1(KLog1);
			}
		//Screen bitmap rectangle
		screenBmpRc.SetRect(aDestPt, TSize(aSrcRc1.Width(), aSrcRc1.Height()));
		
		//Save screen bitmap 
		TInt saveAttempts = 5;
		TInt err = aScreenBmp->Save(KScreenBmpFile);
		while ((err != KErrNone) && saveAttempts--)
			{
			// Retry the save
			_LIT(KSaveRetry,"DoAlphaBlendingTestL: Bitmap save failed, retrying.");
			INFO_PRINTF1(KSaveRetry);
			User::After(10000); 
			err = aScreenBmp->Save(KScreenBmpFile);
			}
		User::LeaveIfError(err);
		
		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
		//Draw screen bitmap
	   	iGc->Clear();
		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
	   	iDevice->Update();
	   	//Do BitBltMasked()
	   	iGc->BitBltMasked(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, EFalse);
	   	iDevice->Update();
		//Get screen data and write the data to screenBmpDestData1.
		for(i=0;i<scrDevSize.iHeight;i++)
	   		{
			TPtr8 p(screenBmpDestData1 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
	   		}
		//  Alpha blending using explicit form of CFbsBitGc::AlphaBlendBitmaps  //
		if (iExtraLogging2)
			{
			_LIT(KLog2,"    CFbsBitGc::AlphaBlendBitmaps explicit test");
			INFO_PRINTF1(KLog2); 
			}
		//Clear screen
	   	iGc->Clear();
	   	iDevice->Update();
		//Load screen bitmap 
		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
	   	//Do AlphaBlendBitmaps()
	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aScreenBmp, aSrcRc1, 
													aSrcPt2, aAlphaBmp, aAlphaPt));
	   	iDevice->Update();
		//Get screen data and write the data to screenBmpDestData2.
		for(i=0;i<scrDevSize.iHeight;i++)
	   		{
			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
	   		}
		//Compare screen bitmaps //
		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);

		// colour comparison tolerance between RGB565 components.
		const TInt KColourComparisonTolerance = 2;
		if (res)
			{
			TBool testPassed = ETrue;
			// strict byte-for-byte comparison of the pixel maps could have failed because blending algorithms may  
			// differ slightly, but actual resulting colours may be close enough
			for (int byteNumber = 0; byteNumber < allocatedSize; byteNumber+=2)
				{
				// find any RGB565 value that doesn't match and examine each component
				if ( *(TUint16*)(screenBmpDestData1 + byteNumber) != *(TUint16*)(screenBmpDestData2 + byteNumber))
					{
					TUint16 Rgb1 = *(TUint16*)(screenBmpDestData1 + byteNumber);
					TUint16 Rgb2 = *(TUint16*)(screenBmpDestData2 + byteNumber);
					
					TInt16 Red1 = (Rgb1 & 0xF800) >> 11;
					TInt16 Red2 = (Rgb2 & 0xF800) >> 11;
					TInt16 DiffRed = Abs(Red1 - Red2);
					
					TInt16 Green1 = (Rgb1 & 0x07E0) >> 5;
					TInt16 Green2 = (Rgb2 & 0x07E0) >> 5;
					TInt16 DiffGreen = Abs(Green1 - Green2);
					
					TInt16 Blue1 = (Rgb1 & 0x001F);
					TInt16 Blue2 = (Rgb2 & 0x001F);
					TInt16 DiffBlue = Abs(Blue1 - Blue2);
					
					// is any difference is outside the tolerance break out signaling test failure
					if (DiffRed > KColourComparisonTolerance || 
						DiffGreen > KColourComparisonTolerance || 
						DiffBlue > KColourComparisonTolerance)
						{
						testPassed = EFalse;
						break;
						}
					}
				}
			if (testPassed)
				{
				res = 0;
				}
			}
		
		if (res && (attempt < KMaximumAttempts - 1))
			{
			INFO_PRINTF1(_L("Memory comparison 1 failed, retrying"));
			// Skip to next attempt
			continue;
			}
		TEST(res == 0);

		//  Alpha blending using implicit form of CFbsBitGc::AlphaBlendBitmaps  //
		if (iExtraLogging2)
			{
			_LIT(KLog3,"    CFbsBitGc::AlphaBlendBitmaps implicit test");
			INFO_PRINTF1(KLog3);
			}
		//Clear screen
	   	iGc->Clear();
	   	iDevice->Update();
		//Draw screen bitmap (it's already loaded)
		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
	   	iDevice->Update();
	   	//Do AlphaBlendBitmaps()
	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, aSrcRc1.iTl));
	   	iDevice->Update();
		//Get screen data and write the data to screenBmpDestData2.
		for(i=0;i<scrDevSize.iHeight;i++)
	   		{
			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
	   		}
		//Compare screen bitmaps //
		if (iExtraLogging2)
			{
			_LIT(KLog4,"    Compare Screen Bitmaps");
			INFO_PRINTF1(KLog4);
			}
		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);

		if (res && (attempt < KMaximumAttempts - 1))
			{
			INFO_PRINTF1(_L("Memory comparison 2 failed, retrying"));
			}
		
		// Reload the screen bitmap as it was before:
		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
		}
	TEST(res == 0);
	
	//Destroy the allocated memory blocks
	CleanupStack::PopAndDestroy(2);//screenBmpDestData1 & screenBmpDestData2
	}

void CTAlphaBlending::CreateAlphaBlendingBitmapsLC(CFbsBitmap*& aScreenBmp, 
											   CFbsBitmap*& aSrcBmp, 
											   CFbsBitmap*& aAlphaBmp,
											   TDisplayMode aMode)
	{
	TInt i;
	TSize size(KWidth, KHeight);
	//The screen data
	TUint8 screenBmpSrcData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
		{0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0x30, 0x31, 0x32, 0x40, 0x41, 0x42, 0x50, 0x51, 0x51, 0x60, 0x61, 0x62, 0x70, 0x71, 0x72, 0x80, 0x81, 0x82, 0x90, 0x91, 0x92, 0xA0, 0xA1, 0xA2, 0x00, 0x00},
		{0x19, 0x18, 0x17, 0x29, 0x28, 0x27, 0x39, 0x38, 0x37, 0x49, 0x48, 0x47, 0x59, 0x58, 0x57, 0x69, 0x68, 0x67, 0x79, 0x78, 0x77, 0x89, 0x88, 0x87, 0x99, 0x98, 0x97, 0xA9, 0xA8, 0xA7, 0x00, 0x00},
		{0x1F, 0x1E, 0x1D, 0x2F, 0x2E, 0x2D, 0x3F, 0x3E, 0x3D, 0x4F, 0x4E, 0x4D, 0x5F, 0x5E, 0x5D, 0x6F, 0x6E, 0x6D, 0x7F, 0x7E, 0x7D, 0x8F, 0x8E, 0x8D, 0x9F, 0x9E, 0x9D, 0xAF, 0xAE, 0xAD, 0x00, 0x00}
		};
	//The source bitmap data
	TUint8 srcBmpData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
		{0x32, 0x67, 0xA2, 0x11, 0x34, 0x67, 0xC5, 0xA3, 0x91, 0x01, 0xB3, 0xA8, 0xF3, 0x3F, 0x1E, 0x88, 0x11, 0x12, 0xAE, 0xEE, 0x9A, 0x56, 0x12, 0x81, 0xB4, 0xCA, 0x91, 0xFF, 0x1A, 0x2A, 0x00, 0x00},
		{0x02, 0xB1, 0xE2, 0xAA, 0xBB, 0x13, 0x22, 0xA8, 0xC3, 0x75, 0x8D, 0xFF, 0xA4, 0xAB, 0x00, 0xC5, 0xA6, 0x22, 0xBB, 0x09, 0xC1, 0x97, 0x25, 0xC6, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00},
		{0x32, 0x50, 0x76, 0x27, 0xCC, 0x45, 0x81, 0xE5, 0xE9, 0xB7, 0xCD, 0x11, 0x32, 0xB1, 0x23, 0xFF, 0x71, 0x11, 0xCC, 0xAA, 0xF2, 0x98, 0x13, 0x8C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00}
		};
	//The alpha bitmap data
	TUint8 alphaBmpData[KHeight][KWidth + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
		{//0   1     2     3     4     5     6     7     8     9     
		{0x68, 0x68, 0x68, 0xAC, 0xD9, 0xB2, 0x8F, 0x11, 0xA0, 0xC1, 0x00, 0x00},
		{0x71, 0x5A, 0xF6, 0xEE, 0xF9, 0xE5, 0x06, 0x4C, 0xBB, 0x7B, 0x00, 0x00},
		{0x9F, 0x99, 0x45, 0x17, 0xA8, 0xF5, 0xFF, 0xD2, 0x22, 0x1D, 0x00, 0x00}
		};

	if(aMode == EColor16MU)
		{
		
		TInt buffer_size = KWidth * 4 ;
		TUint8* buffer = new(ELeave) TUint8[buffer_size];
		TPtr8 source_ptr(buffer, buffer_size, buffer_size);

		//Screen bitmap
		aScreenBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aScreenBmp);
		User::LeaveIfError(aScreenBmp->Create(size, aMode));
		for(i=0; i<KHeight; i++)
			{
			TUint8* bufCur = buffer;
			TUint8* bufSrcCur = screenBmpSrcData[i];
			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
			while(bufSrcCur < bufSrcEnd)
				{
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = 0xff;
				}
			aScreenBmp->SetScanLine(source_ptr, i);
			}
			
		//Source bitmap
		aSrcBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aSrcBmp);
		User::LeaveIfError(aSrcBmp->Create(size, aMode));
		for(i=0; i<KHeight; i++)
			{
			TUint8* bufCur = buffer;
			TUint8* bufSrcCur = srcBmpData[i];
			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
			while(bufSrcCur < bufSrcEnd)
				{
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = *bufSrcCur++;
				*bufCur++ = 0xff;
				}
			aSrcBmp->SetScanLine(source_ptr, i);
			}
			
			
		//Alpha bitmap
		aAlphaBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aAlphaBmp);
		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
		for(i=0;i<KHeight;i++)
			{
			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
			aAlphaBmp->SetScanLine(p, i);
			}
			
		delete [] buffer;	
		}
	else
		{
		//Screen bitmap
		aScreenBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aScreenBmp);
		User::LeaveIfError(aScreenBmp->Create(size, aMode));
		for(i=0;i<KHeight;i++)
			{
			TPtr8 p(screenBmpSrcData[i], KWidth * 3, KWidth * 3);
			aScreenBmp->SetScanLine(p, i);
			}
		//Source bitmap
		aSrcBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aSrcBmp);
		User::LeaveIfError(aSrcBmp->Create(size, aMode));
		for(i=0;i<KHeight;i++)
			{
			TPtr8 p(srcBmpData[i], KWidth * 3, KWidth * 3);
			aSrcBmp->SetScanLine(p, i);
			}
		//Alpha bitmap
		aAlphaBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(aAlphaBmp);
		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
		for(i=0;i<KHeight;i++)
			{
			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
			aAlphaBmp->SetScanLine(p, i);
			}
		}	
	}

void CTAlphaBlending::DestroyAlphaBlendingBitmaps(CFbsBitmap*& aScreenBmp, 
											  CFbsBitmap*& aSrcBmp, 
											  CFbsBitmap*& aAlphaBmp)
	{
	CleanupStack::PopAndDestroy(aAlphaBmp);
	aAlphaBmp = NULL;
	CleanupStack::PopAndDestroy(aSrcBmp);
	aSrcBmp = NULL;
	CleanupStack::PopAndDestroy(aScreenBmp);
	aScreenBmp = NULL;
	}

//The test doesn't check anything. It is for debugging only.
void CTAlphaBlending::TestAlphaBlending2L()
	{
	static const TDisplayMode modeList[] = {
			EColor64K, EColor256, EColor16MAP, EColor16MA, EColor16MU, EColor4K
	};
	const TInt KNumTestDisplayModes=sizeof(modeList)/sizeof(modeList[0]);
	for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
		{
		CFbsBitmap* srcBmp = NULL;
		CFbsBitmap* alphaBmp = NULL;
		TInt err = KErrNotSupported;
		// Try several modes
		for (TInt modeIndex = 0; (err != KErrNone) && modeIndex < KNumTestDisplayModes; modeIndex++)
			{
			err = CreateScreenDevice(modeList[modeIndex],(CFbsBitGc::TGraphicsOrientation)orientation);
			}
		if (err == KErrNotSupported)
			{
			// Orientation not supported, try next one
			continue;
			}
		TInt j;
		//The source bitmap data
		TUint8 srcBmpData[100];
		for(j=0;j<100;j++)
			{
			srcBmpData[j] = 0xAA;
			}
		//The alpha bitmap data
		TUint8 alphaBmpData[20];
		for(j=0;j<20;j++)
			{
			alphaBmpData[j] = TUint8(j);
			}
		//Source bitmap
		srcBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(srcBmp);
		User::LeaveIfError(srcBmp->Create(TSize(100, 1), EColor256));
		TPtr8 p1(srcBmpData, 100, 100);
		srcBmp->SetScanLine(p1, 0);
		//Alpha bitmap
		alphaBmp = new (ELeave) CFbsBitmap;
		CleanupStack::PushL(alphaBmp);
		User::LeaveIfError(alphaBmp->Create(TSize(20, 1), EGray256));
		TPtr8 p2(alphaBmpData, 20, 20);
		alphaBmp->SetScanLine(p2, 0);
		//Do BitBltMasked()
		iGc->BitBltMasked(TPoint(20, 20), srcBmp, TRect(10, 0, 100, 1), alphaBmp, EFalse);
		iDevice->Update();
		iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
		//
		CleanupStack::PopAndDestroy(alphaBmp);
		CleanupStack::PopAndDestroy(srcBmp);
		}
	}

TUint32 AlphaBlend(TUint32 aDestPixel, TUint32 aSrcPixel, TUint8 aMask)
 	{
 	TUint32 dr = (aDestPixel & 0x00FF0000) >> 16;
 	TUint32 dg = (aDestPixel & 0x0000FF00) >> 8;
 	TUint32 db = aDestPixel & 0x000000FF;
 	
 	TUint32 sr = (aSrcPixel & 0x00FF0000) >> 16;
 	TUint32 sg = (aSrcPixel & 0x0000FF00) >> 8;
 	TUint32 sb = aSrcPixel & 0x000000FF;
 	
 	TUint32 rr = (aMask * sr)/255 + ((0xFF - aMask) * dr)/255;
 	TUint32 rg = (aMask * sg)/255 + ((0xFF - aMask) * dg)/255;
 	TUint32 rb = (aMask * sb)/255 + ((0xFF - aMask) * db)/255;
 	
 	return(rr << 16 | rg << 8 | rb | 0xff000000);
 	}
 
inline TUint32 OptimizedBlend32(TInt aPrimaryRed,TInt aPrimaryGreen,TInt aPrimaryBlue,TUint32 aSecondary,TUint8 aAlphaValue)
 	{
  
  	if(aAlphaValue == 0xff)
 		{
 		return (aPrimaryBlue + (aPrimaryGreen<<8) + (aPrimaryRed<<16)) | 0xff000000;
  		}
  	else
  		{
  		const TUint32 alphaValue = (aAlphaValue << 8) + aAlphaValue;
  
  		const TInt r2 = (aSecondary & 0x00ff0000) >> 16;
  		const TInt g2 = (aSecondary & 0x0000ff00) >> 8;
  		const TInt b2 = aSecondary & 0x000000ff;
  
  		const TInt r3 = ((alphaValue * (aPrimaryRed   - r2)) >> 16) + r2;
 		const TInt g3 = ((alphaValue * (aPrimaryGreen - g2)) >> 16) + g2;
 		const TInt b3 = ((alphaValue * (aPrimaryBlue  - b2)) >> 16) + b2;
 
 		return (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
  		}
  	}


/**
  @SYMTestCaseID GRAPHICS-BITGDI-0085
 
  @SYMDEF             

  @SYMTestCaseDesc 
   
  @SYMTestPriority High

  @SYMTestStatus Implemented

  @SYMTestActions 
 
  @SYMTestExpectedResults 
*/  	
// This tests the correctness of the results of alpha-blending with EColor16MA
void CTAlphaBlending::TestAlphaBlendCorrect(TDisplayMode /* aScreenMode */, TDisplayMode /* aBitmapMode */)
 	{
 	// test data
 	TUint32 top = 0xFFCCEE55;
 	TUint32 beneath = 0xFFEEAA66;
 	TUint8 alpha = 0xF0;
 	
 	TInt maxDiff = 0;
 	
 	for(TInt i = 0; i < 100000; i++)
 		{
 		top = Math::Random();
 		beneath = Math::Random();
 		alpha = Math::Random();
 		TUint32 res1 = AlphaBlend(beneath, top, alpha);
 		TUint32 res2 = OptimizedBlend32((top >> 16) & 0xFF,(top >>8) & 0xFF,(top & 0xFF),beneath, alpha);
 		
 		if(res1 != res2)
 			{
 			TInt diff = 0;
 			TInt diff1 = res1 & 0xFF;
 			TInt diff2 = res2 & 0xFF;
 			
 			diff = diff1 - diff2;
 			
 			if(diff < 0)
 				diff*=-1;
 				
 			if(diff > maxDiff)
 				maxDiff = diff;
 				
 			diff1 = (res1 >> 8) & 0xFF;
 			diff2 = (res2 >> 8) & 0xFF;
 			
 			diff = diff1 - diff2;
 			
 			if(diff < 0)
 				diff*=-1;
 				
 			if(diff > maxDiff)
 				maxDiff = diff;
 			
 			
 			diff1 = (res1 >> 16) & 0xFF;
 			diff2 = (res2 >> 16) & 0xFF;
 			
 			diff = diff1 - diff2;
 			
 			if(diff < 0)
 				diff*=-1;
 				
 			if(diff > maxDiff)
 				maxDiff = diff;
 			
 			}
 		}
	
 	INFO_PRINTF1(_L("Results:"));
 		
 	if(maxDiff)
 		INFO_PRINTF2(_L("Max Diff = %i"), maxDiff);
 	else
 		INFO_PRINTF1(_L("Results are identical"));
  	}

//--------------
__CONSTRUCT_STEP__(AlphaBlending)

void CTAlphaBlendingStep::TestSetupL()
	{
	}