os/graphics/graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <hal.h>
sl@0
    17
#include <e32math.h>
sl@0
    18
#include "TAlphaBlend.h"
sl@0
    19
sl@0
    20
sl@0
    21
const TInt KWidth = 10;//Used in alpha blending tests
sl@0
    22
const TInt KHeight = 3;//Used in alpha blending tests
sl@0
    23
const TInt KMaximumAttempts = 2;	// Allow retries on some tests, due to spurious InfoPrints 
sl@0
    24
TBool iExtraLogging1=EFalse;		//Used to trigger logging at times the test fails
sl@0
    25
TBool iExtraLogging2=EFalse;		//Used to trigger logging at times the test fails
sl@0
    26
sl@0
    27
CTAlphaBlending::CTAlphaBlending(CTestStep* aStep):
sl@0
    28
	CTGraphicsBase(aStep),
sl@0
    29
	iDevice(NULL),
sl@0
    30
	iGc(NULL)
sl@0
    31
	{
sl@0
    32
	}
sl@0
    33
sl@0
    34
CTAlphaBlending::~CTAlphaBlending()
sl@0
    35
	{
sl@0
    36
	DeleteGraphicsContext();
sl@0
    37
	DeleteScreenDevice();
sl@0
    38
	}
sl@0
    39
sl@0
    40
void CTAlphaBlending::RunTestCaseL(TInt aCurTestCase)
sl@0
    41
	{
sl@0
    42
	((CTAlphaBlendingStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
sl@0
    43
	switch(aCurTestCase)
sl@0
    44
		{
sl@0
    45
	case 1:
sl@0
    46
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0024"));
sl@0
    47
		INFO_PRINTF1(_L("Alpha blending"));
sl@0
    48
		TestAlphaBlendingL();
sl@0
    49
		break;		
sl@0
    50
	case 2:
sl@0
    51
/**
sl@0
    52
@SYMTestCaseID		GRAPHICS-BITGDI-0114
sl@0
    53
*/
sl@0
    54
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0114"));
sl@0
    55
		INFO_PRINTF1(_L("Alpha blending 2"));
sl@0
    56
		TestAlphaBlending2L();
sl@0
    57
		break;
sl@0
    58
	case 3:
sl@0
    59
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
sl@0
    60
 		INFO_PRINTF1(_L("Alpha blending Correctness test 16MU 16MA"));
sl@0
    61
 		TestAlphaBlendCorrect(EColor16MU, EColor16MU);
sl@0
    62
 		break;
sl@0
    63
 	case 4:
sl@0
    64
 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097"));
sl@0
    65
 		INFO_PRINTF1(_L("Alpha plot test"));
sl@0
    66
		TestAlphaBlendingPlotL();
sl@0
    67
		break;
sl@0
    68
	case 5:
sl@0
    69
/**
sl@0
    70
@SYMTestCaseID		GRAPHICS-BITGDI-0115
sl@0
    71
*/
sl@0
    72
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0115"));
sl@0
    73
		INFO_PRINTF1(_L("Draw bitmap blending"));
sl@0
    74
		DoDrawBitmapTestsL();
sl@0
    75
		break;
sl@0
    76
	case 6:
sl@0
    77
		//DEF118268
sl@0
    78
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
sl@0
    79
		INFO_PRINTF1(_L("Alpha blending Correctness test 16M 16MA"));
sl@0
    80
		TestAlphaBlendCorrect(EColor16M, EColor16MA);
sl@0
    81
		break;
sl@0
    82
	case 7:
sl@0
    83
		((CTAlphaBlendingStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
sl@0
    84
		((CTAlphaBlendingStep*)iStep)->CloseTMSGraphicsStep();
sl@0
    85
		TestComplete();
sl@0
    86
		break;
sl@0
    87
		}
sl@0
    88
	((CTAlphaBlendingStep*)iStep)->RecordTestResultL();
sl@0
    89
	}
sl@0
    90
sl@0
    91
TInt CTAlphaBlending::CreateScreenDevice(TDisplayMode aDisplayMode, CFbsBitGc::TGraphicsOrientation aOrientation)
sl@0
    92
	{
sl@0
    93
	DeleteGraphicsContext();
sl@0
    94
	DeleteScreenDevice();
sl@0
    95
	TRAPD(err, iDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
sl@0
    96
	if(err == KErrNotSupported)
sl@0
    97
		{
sl@0
    98
		return err;
sl@0
    99
		}
sl@0
   100
	TEST2(err, KErrNone);
sl@0
   101
	err = iDevice->CreateContext((CGraphicsContext*&)iGc);
sl@0
   102
	TEST2(err, KErrNone);
sl@0
   103
	if (!iGc->SetOrientation(aOrientation))
sl@0
   104
		{
sl@0
   105
		return(KErrNotSupported);
sl@0
   106
		}
sl@0
   107
	iGc->SetUserDisplayMode(aDisplayMode);
sl@0
   108
	iDevice->ChangeScreenDevice(NULL);
sl@0
   109
	iDevice->SetAutoUpdate(EFalse);
sl@0
   110
	return err;
sl@0
   111
	}
sl@0
   112
sl@0
   113
void CTAlphaBlending::DeleteScreenDevice()
sl@0
   114
	{
sl@0
   115
	delete iDevice;
sl@0
   116
	iDevice = NULL;
sl@0
   117
	}
sl@0
   118
sl@0
   119
void CTAlphaBlending::DeleteGraphicsContext()
sl@0
   120
	{
sl@0
   121
	delete iGc;
sl@0
   122
	iGc = NULL;
sl@0
   123
	}
sl@0
   124
sl@0
   125
// returns the pixel colour from the provided bitmap in aarrggbb format
sl@0
   126
// if pixel is outside the bitmaps limits return top left pixel
sl@0
   127
TUint32 CTAlphaBlending::GetRawPixel(CFbsBitmap* aBitmap, TPoint aPos)
sl@0
   128
	{
sl@0
   129
	TBitmapUtil bmpUtil(aBitmap);	
sl@0
   130
	TUint32 value = 0;
sl@0
   131
	ASSERT(aPos.iX>=0 && aPos.iY>=0);
sl@0
   132
	ASSERT(aPos.iX<aBitmap->SizeInPixels().iWidth && aPos.iY<aBitmap->SizeInPixels().iHeight);
sl@0
   133
	bmpUtil.Begin(aPos);
sl@0
   134
	value = bmpUtil.GetPixel();
sl@0
   135
	bmpUtil.End();
sl@0
   136
	return value;	
sl@0
   137
	}
sl@0
   138
sl@0
   139
/**
sl@0
   140
@SYMTestCaseID		GRAPHICS-BITGDI-0097
sl@0
   141
sl@0
   142
@SYMDEF             DEF113229
sl@0
   143
sl@0
   144
@SYMTestCaseDesc    CDrawThirtyTwoBppBitmapCommon::WriteRgb did not change the dest alpha value to 255 when 
sl@0
   145
					the dest alpha was >0 and <255 and the a soure pen had an alpha of 255	
sl@0
   146
sl@0
   147
@SYMTestPriority    Normal
sl@0
   148
sl@0
   149
@SYMTestStatus      Implemented
sl@0
   150
sl@0
   151
@SYMTestActions     Creates a bitmap, clears it to black (destination) 50% opaque then plots a series of points 
sl@0
   152
					with a 100% opaque pen on it. Tests the resultant alpha value.
sl@0
   153
sl@0
   154
@SYMTestExpectedResults Final alpha value should be 255
sl@0
   155
**/
sl@0
   156
void CTAlphaBlending::TestAlphaBlendingPlotL()
sl@0
   157
	{
sl@0
   158
	const TSize KRectSize(100,100);
sl@0
   159
	const TRect KTargetRect(TPoint(0,0), KRectSize);
sl@0
   160
		
sl@0
   161
	// create the target bitmap
sl@0
   162
	CFbsBitmap* destBmp = new (ELeave) CFbsBitmap;
sl@0
   163
	CleanupStack::PushL(destBmp);
sl@0
   164
	User::LeaveIfError(destBmp->Create(KRectSize, EColor16MA));
sl@0
   165
	destBmp->SetSizeInTwips(KRectSize);
sl@0
   166
	
sl@0
   167
	// create bitmap device and graphics context
sl@0
   168
	CFbsBitmapDevice* destBmpDevice = CFbsBitmapDevice::NewL(destBmp);
sl@0
   169
	CleanupStack::PushL(destBmpDevice);
sl@0
   170
	CFbsBitGc* destGc = NULL;
sl@0
   171
	User::LeaveIfError(destBmpDevice->CreateContext(destGc));
sl@0
   172
	CleanupStack::PushL(destGc);
sl@0
   173
	destGc->SetPenStyle(CGraphicsContext::ENullPen);
sl@0
   174
	destGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
sl@0
   175
		
sl@0
   176
	TDisplayMode screenMode = EColor16MA;
sl@0
   177
	TInt err = CreateScreenDevice(screenMode);
sl@0
   178
	if (err != KErrNone)
sl@0
   179
		{
sl@0
   180
		screenMode = EColor64K;
sl@0
   181
		err = CreateScreenDevice(screenMode);
sl@0
   182
		}
sl@0
   183
	
sl@0
   184
	if(err==KErrNone)
sl@0
   185
		{
sl@0
   186
		const TInt KSqrMin=45;
sl@0
   187
		const TInt KSqrMax=55;
sl@0
   188
						
sl@0
   189
		iGc->SetUserDisplayMode(screenMode);
sl@0
   190
		destGc->SetBrushColor(TRgb(0,0,0,127));
sl@0
   191
		destGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
sl@0
   192
		destGc->Clear(KTargetRect);
sl@0
   193
sl@0
   194
		// copy over to screen dc for anyone watching
sl@0
   195
		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
sl@0
   196
		iDevice->Update();
sl@0
   197
		
sl@0
   198
		// set the pen colour to white and plot some points
sl@0
   199
		destGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
sl@0
   200
		destGc->SetPenStyle(CGraphicsContext::ESolidPen);
sl@0
   201
		destGc->SetPenColor(TRgb(0,70,130,255));
sl@0
   202
		for( TInt y=KSqrMin;y<=KSqrMax;y++)
sl@0
   203
			{
sl@0
   204
			for( TInt x=KSqrMin;x<=KSqrMax;x++)
sl@0
   205
				{
sl@0
   206
				destGc->Plot(TPoint(x,y));
sl@0
   207
				}
sl@0
   208
			}
sl@0
   209
			
sl@0
   210
		// copy over to screen dc for anyone watching
sl@0
   211
		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
sl@0
   212
		iDevice->Update();
sl@0
   213
		
sl@0
   214
		TUint32 actualValue=0;
sl@0
   215
		// check the resulting values alpha values are 0xFF in the square we drew
sl@0
   216
		for( TInt y=KSqrMin;y<=KSqrMax;y++)
sl@0
   217
			{
sl@0
   218
			for( TInt x=KSqrMin;x<=KSqrMax;x++)
sl@0
   219
				{
sl@0
   220
				actualValue = GetRawPixel(destBmp, TPoint(x,y));
sl@0
   221
				if( (actualValue&0xFF000000) != 0xFF000000 )
sl@0
   222
					{
sl@0
   223
					TEST(EFalse);
sl@0
   224
					INFO_PRINTF2(_L("TestAlphaBlendingPlotL() ***FAILED*** - expected alpha value 0xFF got %d "),((actualValue&0xFF000000)>>24));
sl@0
   225
					}
sl@0
   226
				}
sl@0
   227
			}
sl@0
   228
		}
sl@0
   229
		CleanupStack::PopAndDestroy(3); //destGc,destBmpDevice,destBmp
sl@0
   230
	}
sl@0
   231
sl@0
   232
/**
sl@0
   233
  @SYMTestCaseID GRAPHICS-BITGDI-0024
sl@0
   234
 
sl@0
   235
  @SYMDEF             
sl@0
   236
sl@0
   237
  @SYMTestCaseDesc 
sl@0
   238
   
sl@0
   239
	System, GT0173 System Libraries, BITGDI support required for semi-transparent windows
sl@0
   240
	DEF039083 - Using BitBltMasked to do alpha-blending only works if your brush style is "null"
sl@0
   241
	DEF039409 - Wrong part of Alpha Bitmap is used when there is a clipping region 
sl@0
   242
	DEF039669 - The UserDisplayMode is not honoured during the AlphaBlendBitmap function. 
sl@0
   243
	REQ3413 Second overload of CFbsBitGc's AlphaBlendBitmaps - "Supply a second overload of 
sl@0
   244
	CFbsBitGc's AlphaBlendBitmaps function, but with one of the source bitmaps being passed 
sl@0
   245
	as a CFbsBitGc object, so that the screen can be used as a source."
sl@0
   246
sl@0
   247
  @SYMTestPriority High
sl@0
   248
sl@0
   249
  @SYMTestStatus Implemented
sl@0
   250
sl@0
   251
  @SYMTestActions 
sl@0
   252
  	
sl@0
   253
  	Tests alpha blending - for all display modes, some brush styles, user display modes, 
sl@0
   254
	different positions on the screen.
sl@0
   255
  
sl@0
   256
	Shadow/fade mode is no more tested, because the existing BitBltMasked() and the new 
sl@0
   257
	AlphaBlendBitmaps() methods treat it a different way - see MAlphaBlend interface in
sl@0
   258
	ScreenDriver component.
sl@0
   259
sl@0
   260
  @SYMTestExpectedResults Test should perform graphics operations succesfully. 
sl@0
   261
*/
sl@0
   262
sl@0
   263
void CTAlphaBlending::TestAlphaBlendingL()
sl@0
   264
	{
sl@0
   265
	TPoint originPt(0, 0);
sl@0
   266
	TPoint destPt(0, 0);
sl@0
   267
	TRect scrRc1(0, 0, KWidth, KHeight);
sl@0
   268
	TPoint srcPt2(0, 0);
sl@0
   269
	TPoint alphaPt(0, 0);
sl@0
   270
	//
sl@0
   271
	//If we compare CFbsBitGc::BitBltMasked() aguments with CFbsBitGc::AlphaBlending() arguments,
sl@0
   272
	//we will see that AlphaBlending() has more arguments than BitBltMasked() - 
sl@0
   273
	//srcPt2, alphaPt. To make it possible - the comparison between these two methods,
sl@0
   274
	//we have to change aAlphaPt and aSrcPt2 values accordingly with the changes of scrRc1 value.
sl@0
   275
	//
sl@0
   276
	//test 1 - the origin is moved
sl@0
   277
	originPt = TPoint(97, 33);
sl@0
   278
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
sl@0
   279
#if !defined(__X86GCC__)	//These test take too long to run in X86GCC
sl@0
   280
	//test 2 - the origin is (0, 0)
sl@0
   281
	originPt = TPoint(0, 0);
sl@0
   282
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
sl@0
   283
	//test 3 - scrRect1 is not (0, 0, KWidth, KHeight)
sl@0
   284
	scrRc1 = TRect(3, 1, KWidth, KHeight);
sl@0
   285
	alphaPt = TPoint(3, 1);
sl@0
   286
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
sl@0
   287
	//test 4 - restore scrRc1 and alphaPt, move the destination point
sl@0
   288
	scrRc1 = TRect(0, 0, KWidth, KHeight);
sl@0
   289
	alphaPt = TPoint(0, 0);
sl@0
   290
	destPt = TPoint(13, 17);
sl@0
   291
	iExtraLogging1=ETrue;
sl@0
   292
	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
sl@0
   293
	iExtraLogging1=EFalse;
sl@0
   294
#endif	//__X86GCC__
sl@0
   295
	}
sl@0
   296
sl@0
   297
void CTAlphaBlending::DoDrawBitmapTestsL()
sl@0
   298
	{
sl@0
   299
	TDisplayMode modes[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K, 
sl@0
   300
						   EGray256, EGray16, EGray4, EGray2, EColor16};
sl@0
   301
	const TInt KNumTestDisplayModes=sizeof(modes)/sizeof(modes[0]);
sl@0
   302
	for(TInt modeIndex=0;modeIndex<KNumTestDisplayModes;modeIndex++)
sl@0
   303
		{
sl@0
   304
		TDisplayMode screenMode=modes[modeIndex];
sl@0
   305
		if (CreateScreenDevice(screenMode)!=KErrNone)
sl@0
   306
			continue;
sl@0
   307
		DoDrawBitmapTestL(screenMode);
sl@0
   308
		}
sl@0
   309
	}
sl@0
   310
sl@0
   311
void CTAlphaBlending::DoDrawBitmapTestL(TDisplayMode aTestDisplayMode)
sl@0
   312
	{
sl@0
   313
	iGc->Reset();
sl@0
   314
	TBool alphaSupported=(aTestDisplayMode==EColor16MA || aTestDisplayMode==EColor16MAP);
sl@0
   315
	TSize screenSize=iDevice->SizeInPixels();
sl@0
   316
//
sl@0
   317
	const TInt KNumTestSrcSizes=4;
sl@0
   318
	const TSize testSrcSizes[KNumTestSrcSizes]={TSize(2,2),TSize(20,10),TSize(200,5),TSize(55,555)};
sl@0
   319
	for(TInt srcSizeIndex=0;srcSizeIndex<KNumTestSrcSizes;srcSizeIndex++)
sl@0
   320
		{
sl@0
   321
		TSize srcSize(testSrcSizes[srcSizeIndex]);
sl@0
   322
//
sl@0
   323
		CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap;
sl@0
   324
		CleanupStack::PushL(srcBmp);
sl@0
   325
		User::LeaveIfError(srcBmp->Create(srcSize,aTestDisplayMode));
sl@0
   326
		CFbsBitmapDevice* srcDevice = CFbsBitmapDevice::NewL(srcBmp);
sl@0
   327
		CleanupStack::PushL(srcDevice);
sl@0
   328
		CFbsBitGc* srcGc=NULL;
sl@0
   329
		User::LeaveIfError(srcDevice->CreateContext(srcGc));
sl@0
   330
		CleanupStack::PushL(srcGc);
sl@0
   331
//
sl@0
   332
		CFbsBitmap* srcAlpha=new(ELeave) CFbsBitmap;
sl@0
   333
		CleanupStack::PushL(srcAlpha);
sl@0
   334
		User::LeaveIfError(srcAlpha->Create(srcSize,aTestDisplayMode));
sl@0
   335
		CFbsBitmapDevice* srcAlphaDevice = CFbsBitmapDevice::NewL(srcAlpha);
sl@0
   336
		CleanupStack::PushL(srcAlphaDevice);
sl@0
   337
		CFbsBitGc* srcAlphaGc=NULL;
sl@0
   338
		User::LeaveIfError(srcAlphaDevice->CreateContext(srcAlphaGc));
sl@0
   339
		CleanupStack::PushL(srcAlphaGc);
sl@0
   340
		srcAlphaGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
sl@0
   341
//
sl@0
   342
		CFbsBitmap* srcMask=new(ELeave) CFbsBitmap;
sl@0
   343
		CleanupStack::PushL(srcMask);
sl@0
   344
		User::LeaveIfError(srcMask->Create(srcSize,EGray256));
sl@0
   345
		CFbsBitmapDevice* srcMaskDevice = CFbsBitmapDevice::NewL(srcMask);
sl@0
   346
		CleanupStack::PushL(srcMaskDevice);
sl@0
   347
		CFbsBitGc* srcMaskGc=NULL;
sl@0
   348
		User::LeaveIfError(srcMaskDevice->CreateContext(srcMaskGc));
sl@0
   349
		CleanupStack::PushL(srcMaskGc);
sl@0
   350
//
sl@0
   351
		TInt maxX=srcSize.iWidth-1;
sl@0
   352
		TInt maxY=srcSize.iHeight-1;
sl@0
   353
		for(TInt yLoop=0;yLoop<srcSize.iHeight;yLoop++)
sl@0
   354
			{
sl@0
   355
			for(TInt xLoop=0;xLoop<srcSize.iWidth;xLoop++)
sl@0
   356
				{
sl@0
   357
				TPoint plotPos(xLoop,yLoop);
sl@0
   358
				TRgb pen(xLoop*255/maxX,yLoop*255/maxY,(xLoop+yLoop)*128/(maxX+maxY));
sl@0
   359
				srcGc->SetPenColor(pen);
sl@0
   360
				srcGc->Plot(plotPos);
sl@0
   361
				TInt alpha=(xLoop+yLoop)*255/(maxX+maxY);
sl@0
   362
				pen.SetAlpha(alpha);
sl@0
   363
				srcAlphaGc->SetBrushColor(pen);
sl@0
   364
				srcAlphaGc->Clear(TRect(plotPos,TSize(1,1)));
sl@0
   365
				srcMaskGc->SetPenColor(TRgb::Gray256(alpha));
sl@0
   366
				srcMaskGc->Plot(plotPos);
sl@0
   367
				}
sl@0
   368
			}
sl@0
   369
		const TInt KNumTestTargSizes=5;
sl@0
   370
		const TSize testTargSizes[KNumTestTargSizes]={TSize(0,0), TSize(20,1),TSize(30,20),TSize(200,31),TSize(55,5)};
sl@0
   371
		for(TInt targSizeIndex=0;targSizeIndex<KNumTestSrcSizes;targSizeIndex++)
sl@0
   372
			{
sl@0
   373
			TSize targSize(testTargSizes[targSizeIndex]);
sl@0
   374
			if (targSizeIndex==0)
sl@0
   375
				{
sl@0
   376
				targSize=srcSize;	// Special case with no scaling
sl@0
   377
				if (targSize.iWidth>screenSize.iWidth)
sl@0
   378
					targSize.iWidth=screenSize.iWidth;
sl@0
   379
				TInt maxHeight=screenSize.iHeight/3;
sl@0
   380
				if (targSize.iHeight>maxHeight)
sl@0
   381
					targSize.iHeight=maxHeight;
sl@0
   382
				}
sl@0
   383
//
sl@0
   384
			CFbsBitmap* targBmp=new(ELeave) CFbsBitmap;
sl@0
   385
			CleanupStack::PushL(targBmp);
sl@0
   386
			User::LeaveIfError(targBmp->Create(targSize,aTestDisplayMode));
sl@0
   387
			CFbsBitmapDevice* targBmpDevice = CFbsBitmapDevice::NewL(targBmp);
sl@0
   388
			CleanupStack::PushL(targBmpDevice);
sl@0
   389
			CFbsBitGc* targGc=NULL;
sl@0
   390
			User::LeaveIfError(targBmpDevice->CreateContext(targGc));
sl@0
   391
			CleanupStack::PushL(targGc);
sl@0
   392
//
sl@0
   393
			CFbsBitmap* targMask=new(ELeave) CFbsBitmap;
sl@0
   394
			CleanupStack::PushL(targMask);
sl@0
   395
			User::LeaveIfError(targMask->Create(targSize,EGray256));
sl@0
   396
			CFbsBitmapDevice* targMaskDevice = CFbsBitmapDevice::NewL(targMask);
sl@0
   397
			CleanupStack::PushL(targMaskDevice);
sl@0
   398
			CFbsBitGc* targMaskGc=NULL;
sl@0
   399
			User::LeaveIfError(targMaskDevice->CreateContext(targMaskGc));
sl@0
   400
			CleanupStack::PushL(targMaskGc);
sl@0
   401
//
sl@0
   402
			TPoint drawPos;
sl@0
   403
			TRect testRect1(targSize);
sl@0
   404
			iGc->Clear();
sl@0
   405
// First we pre-stretch the source and mask bitmaps into temp bitmaps
sl@0
   406
			targGc->DrawBitmap(TRect(targSize),srcBmp);
sl@0
   407
			targMaskGc->DrawBitmap(TRect(targSize),srcMask);
sl@0
   408
// Then blend them onto the screen with a call to BitBltMasked
sl@0
   409
			iGc->BitBltMasked(drawPos,targBmp,TRect(targSize),targMask,EFalse);
sl@0
   410
			drawPos.iY+=targSize.iHeight;
sl@0
   411
			TRect testRect2(drawPos,targSize);
sl@0
   412
// Next we combine the stretching and masking with one call to DrawBitmapMasked,
sl@0
   413
// this should give the same end result.
sl@0
   414
			iGc->DrawBitmapMasked(testRect2,srcBmp,TRect(srcSize),srcMask,EFalse);
sl@0
   415
			TRect testRect3;
sl@0
   416
			if (alphaSupported)
sl@0
   417
				{
sl@0
   418
// Finally if alpha blending supported we stretch and blend, again to achieve the exact same end result
sl@0
   419
// as the two previous calls. This was specificially done to catch DEF116427.
sl@0
   420
				drawPos.iY+=targSize.iHeight;
sl@0
   421
				testRect3=TRect(drawPos,targSize);
sl@0
   422
				iGc->DrawBitmap(testRect3,srcAlpha);
sl@0
   423
				}
sl@0
   424
//Use this just to check what we've put in the test bitmaps
sl@0
   425
/*
sl@0
   426
			drawPos.iY+=targSize.iHeight+1;
sl@0
   427
			iGc->BitBlt(drawPos,srcBmp);
sl@0
   428
			drawPos.iY+=srcSize.iHeight+1;
sl@0
   429
			iGc->BitBlt(drawPos,srcMask);
sl@0
   430
			drawPos.iY+=srcSize.iHeight+1;
sl@0
   431
			if (alphaSupported)
sl@0
   432
				iGc->BitBlt(drawPos,srcAlpha);
sl@0
   433
*/
sl@0
   434
		   	iDevice->Update();
sl@0
   435
			TBool ret1=iDevice->RectCompare(testRect1,*iDevice,testRect2);
sl@0
   436
		   	TBool ret2=alphaSupported?iDevice->RectCompare(testRect1,*iDevice,testRect3):ETrue;
sl@0
   437
			if (!ret1 || !ret2)
sl@0
   438
				{
sl@0
   439
				INFO_PRINTF4(_L("DrawBitmapTest, ret1=%d, ret2=%d, Screen mode=%d"),ret1,ret2,aTestDisplayMode);
sl@0
   440
				TEST(EFalse);
sl@0
   441
				}
sl@0
   442
			CleanupStack::PopAndDestroy(3,targMask);
sl@0
   443
			CleanupStack::PopAndDestroy(3,targBmp);
sl@0
   444
			}
sl@0
   445
		CleanupStack::PopAndDestroy(3,srcMask);
sl@0
   446
		CleanupStack::PopAndDestroy(3,srcAlpha);
sl@0
   447
		CleanupStack::PopAndDestroy(3,srcBmp);
sl@0
   448
		}
sl@0
   449
	}
sl@0
   450
sl@0
   451
//Tests alpha blending - for all display modes, some brush styles, user display modes, 
sl@0
   452
//different positions on the screen.
sl@0
   453
void CTAlphaBlending::DoAlphaBlendingTestsL(const TPoint& aOrigin,
sl@0
   454
										const TPoint& aDestPt, 
sl@0
   455
										const TRect& aSrcRc1, 
sl@0
   456
										const TPoint& aScrPt2,
sl@0
   457
										const TPoint& aAlphaPt)
sl@0
   458
	{
sl@0
   459
	TBuf<128> buf;
sl@0
   460
	_LIT(KLog,"Origin=(%d,%d) DestPt=(%d,%d) SrcRect=(%d,%d,%d,%d) ScrPt=(%d,%d) AlphaPt=(%d,%d)");
sl@0
   461
	buf.Format(KLog,aOrigin.iX,aOrigin.iY,aDestPt.iX,aDestPt.iY,aSrcRc1.iTl.iX,aSrcRc1.iTl.iY
sl@0
   462
						,aSrcRc1.iBr.iX,aSrcRc1.iBr.iY,aScrPt2.iX,aScrPt2.iY,aAlphaPt.iX,aAlphaPt.iY);
sl@0
   463
	INFO_PRINTF1(buf);
sl@0
   464
	TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
sl@0
   465
						   EGray256, EGray16, EGray4, EGray2, EColor16};
sl@0
   466
	CFbsBitmap* screenBmp = NULL;
sl@0
   467
	CFbsBitmap* srcBmp = NULL;
sl@0
   468
	CFbsBitmap* alphaBmp = NULL;
sl@0
   469
	CGraphicsContext::TBrushStyle brushStyle[] = {CGraphicsContext::ENullBrush, CGraphicsContext::ESolidBrush};
sl@0
   470
	for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
sl@0
   471
		{
sl@0
   472
		for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
sl@0
   473
			{
sl@0
   474
			if (CreateScreenDevice(mode[i],(CFbsBitGc::TGraphicsOrientation)orientation) != KErrNone)
sl@0
   475
				{
sl@0
   476
				continue;
sl@0
   477
				}
sl@0
   478
			iExtraLogging2=(iExtraLogging1 && mode[i]==11);
sl@0
   479
	 		INFO_PRINTF3(_L("Mode=%d, Orientation=%d"), mode[i], orientation);
sl@0
   480
			CreateAlphaBlendingBitmapsLC(screenBmp, srcBmp, alphaBmp, mode[i]);
sl@0
   481
			for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
sl@0
   482
				{
sl@0
   483
				if(mode[i] == EGray4 && brushStyle[j] == CGraphicsContext::ESolidBrush)
sl@0
   484
					{
sl@0
   485
					//When the display mode is EGray4 - Flicker-free blitting is not enabled.
sl@0
   486
					//The screen will be filled with 0xFF color, which is not the same color used by
sl@0
   487
					//the test - 0x00. And BitBltMasked and AlphaBlendBitmaps will produce different results.
sl@0
   488
					continue;
sl@0
   489
					}
sl@0
   490
				iGc->SetOrigin(aOrigin);
sl@0
   491
				iGc->SetBrushStyle(brushStyle[j]);
sl@0
   492
				TDisplayMode userDisplayMode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, 
sl@0
   493
												  EColor4K, EColor64K, EGray256, 
sl@0
   494
												  EGray16, EGray4, EGray2, EColor16};
sl@0
   495
				for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
sl@0
   496
					{
sl@0
   497
					iGc->SetUserDisplayMode(userDisplayMode[l]);
sl@0
   498
					TSize scrDevSize = iDevice->SizeInPixels();
sl@0
   499
					TRect clipRc[] = {TRect(0, 0, scrDevSize.iWidth, scrDevSize.iHeight),
sl@0
   500
										TRect(0, 1, scrDevSize.iWidth, scrDevSize.iHeight), // Tests Y clipping only
sl@0
   501
										TRect(5, 0, scrDevSize.iWidth, scrDevSize.iHeight), // Tests X clipping only
sl@0
   502
										TRect(5, 1, scrDevSize.iWidth, scrDevSize.iHeight),
sl@0
   503
										TRect(3, 0, 14, 23)};//14 and 23 values are not accidental! 
sl@0
   504
															 //Sometimes the method is called with aDestPt(13, 17).
sl@0
   505
					for(TInt k=0;k<TInt(sizeof(clipRc)/sizeof(clipRc[0]));k++)
sl@0
   506
						{
sl@0
   507
						if (iExtraLogging2)
sl@0
   508
							{
sl@0
   509
							_LIT(KLog,"  BrushStyle=%d UserDisplayMode=%d ClipRect=(%d,%d,%d,%d)");
sl@0
   510
			 				INFO_PRINTF7(KLog,j,l,clipRc[k].iTl.iX,clipRc[k].iTl.iY,clipRc[k].iBr.iX,clipRc[k].iBr.iY);
sl@0
   511
							}
sl@0
   512
						iGc->Clear();
sl@0
   513
						iGc->SetClippingRect(clipRc[k]);
sl@0
   514
						DoAlphaBlendingTestL(screenBmp, srcBmp, alphaBmp, aDestPt, aSrcRc1, aScrPt2, aAlphaPt);
sl@0
   515
						iGc->CancelClippingRect();
sl@0
   516
						}
sl@0
   517
					}//end of - for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
sl@0
   518
				iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
sl@0
   519
				}
sl@0
   520
			DestroyAlphaBlendingBitmaps(screenBmp, srcBmp, alphaBmp);
sl@0
   521
			}//end of - for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
sl@0
   522
		}//end of - for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
sl@0
   523
	}
sl@0
   524
sl@0
   525
//The method compares results of two alpha blending methods:
sl@0
   526
//iGc->BitBltMasked() and iGc->AlphaBlendBitmaps().
sl@0
   527
//To make that possible, aScreenBmp is copied to the screen before the call of
sl@0
   528
//iGc->BitBltMasked().
sl@0
   529
void CTAlphaBlending::DoAlphaBlendingTestL(CFbsBitmap* aScreenBmp, 
sl@0
   530
									   const CFbsBitmap* aSrcBmp, 
sl@0
   531
									   const CFbsBitmap* aAlphaBmp,
sl@0
   532
									   const TPoint& aDestPt, 
sl@0
   533
									   const TRect& aSrcRc1, 
sl@0
   534
									   const TPoint& aSrcPt2,
sl@0
   535
									   const TPoint& aAlphaPt)
sl@0
   536
	{
sl@0
   537
	_LIT(KScreenBmpFile, "C:\\BMP_DATA.DAT");
sl@0
   538
	iGc->SetShadowMode(EFalse);
sl@0
   539
   	TInt i;
sl@0
   540
   	TInt res = -1;
sl@0
   541
	TSize scrDevSize = iDevice->SizeInPixels();
sl@0
   542
	TInt allocatedSize = scrDevSize.iWidth * scrDevSize.iHeight * 2;
sl@0
   543
	TRect screenBmpRc;
sl@0
   544
   	//The screen alpha blended data after calling of BitBltMasked() - will be filled after the call
sl@0
   545
	TUint8* screenBmpDestData1 = new (ELeave) TUint8[allocatedSize];
sl@0
   546
	CleanupStack::PushL(screenBmpDestData1);
sl@0
   547
   	//The screen alpha blended data after calling of AlphaBlendingBitmaps() - will be filled after the call
sl@0
   548
	TUint8* screenBmpDestData2 = new (ELeave) TUint8[allocatedSize];
sl@0
   549
	CleanupStack::PushL(screenBmpDestData2);
sl@0
   550
	// Allow an effective restart of the test, since sometimes there are spurious
sl@0
   551
	// InfoPrints that affect the comparisons.
sl@0
   552
	for (TInt attempt = 0; res && (attempt < KMaximumAttempts); attempt++)
sl@0
   553
		{
sl@0
   554
		//Fill the blocks with some default value
sl@0
   555
		Mem::Fill(screenBmpDestData1, allocatedSize, 0xCA);
sl@0
   556
		Mem::Fill(screenBmpDestData2, allocatedSize, 0xCA);
sl@0
   557
	   	//Check screen bitmap size
sl@0
   558
	   	TSize screenBmpSize = aScreenBmp->SizeInPixels();
sl@0
   559
	   	if ((screenBmpSize.iWidth != KWidth) || (screenBmpSize.iHeight != KHeight))
sl@0
   560
	   		{
sl@0
   561
	   		_LIT(KScreenErr,"DoAlphaBlendingTestL test: w:%d!=%d || h:%d!=%d");
sl@0
   562
	   		INFO_PRINTF5(KScreenErr, screenBmpSize.iWidth, KWidth, screenBmpSize.iHeight, KHeight);
sl@0
   563
	   		TEST(EFalse);
sl@0
   564
	   		}
sl@0
   565
		//  Alpha blending using CFbsBitGc::BitBltMasked  //
sl@0
   566
		if (iExtraLogging2)
sl@0
   567
			{
sl@0
   568
			_LIT(KLog1,"    CFbsBitGc::BitBltMasked test");
sl@0
   569
			INFO_PRINTF1(KLog1);
sl@0
   570
			}
sl@0
   571
		//Screen bitmap rectangle
sl@0
   572
		screenBmpRc.SetRect(aDestPt, TSize(aSrcRc1.Width(), aSrcRc1.Height()));
sl@0
   573
		
sl@0
   574
		//Save screen bitmap 
sl@0
   575
		TInt saveAttempts = 5;
sl@0
   576
		TInt err = aScreenBmp->Save(KScreenBmpFile);
sl@0
   577
		while ((err != KErrNone) && saveAttempts--)
sl@0
   578
			{
sl@0
   579
			// Retry the save
sl@0
   580
			_LIT(KSaveRetry,"DoAlphaBlendingTestL: Bitmap save failed, retrying.");
sl@0
   581
			INFO_PRINTF1(KSaveRetry);
sl@0
   582
			User::After(10000); 
sl@0
   583
			err = aScreenBmp->Save(KScreenBmpFile);
sl@0
   584
			}
sl@0
   585
		User::LeaveIfError(err);
sl@0
   586
		
sl@0
   587
		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
sl@0
   588
		//Draw screen bitmap
sl@0
   589
	   	iGc->Clear();
sl@0
   590
		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
sl@0
   591
		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
sl@0
   592
	   	iDevice->Update();
sl@0
   593
	   	//Do BitBltMasked()
sl@0
   594
	   	iGc->BitBltMasked(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, EFalse);
sl@0
   595
	   	iDevice->Update();
sl@0
   596
		//Get screen data and write the data to screenBmpDestData1.
sl@0
   597
		for(i=0;i<scrDevSize.iHeight;i++)
sl@0
   598
	   		{
sl@0
   599
			TPtr8 p(screenBmpDestData1 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
sl@0
   600
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
sl@0
   601
	   		}
sl@0
   602
		//  Alpha blending using explicit form of CFbsBitGc::AlphaBlendBitmaps  //
sl@0
   603
		if (iExtraLogging2)
sl@0
   604
			{
sl@0
   605
			_LIT(KLog2,"    CFbsBitGc::AlphaBlendBitmaps explicit test");
sl@0
   606
			INFO_PRINTF1(KLog2); 
sl@0
   607
			}
sl@0
   608
		//Clear screen
sl@0
   609
	   	iGc->Clear();
sl@0
   610
	   	iDevice->Update();
sl@0
   611
		//Load screen bitmap 
sl@0
   612
		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
sl@0
   613
	   	//Do AlphaBlendBitmaps()
sl@0
   614
	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aScreenBmp, aSrcRc1, 
sl@0
   615
													aSrcPt2, aAlphaBmp, aAlphaPt));
sl@0
   616
	   	iDevice->Update();
sl@0
   617
		//Get screen data and write the data to screenBmpDestData2.
sl@0
   618
		for(i=0;i<scrDevSize.iHeight;i++)
sl@0
   619
	   		{
sl@0
   620
			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
sl@0
   621
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
sl@0
   622
	   		}
sl@0
   623
		//Compare screen bitmaps //
sl@0
   624
		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
sl@0
   625
sl@0
   626
		// colour comparison tolerance between RGB565 components.
sl@0
   627
		const TInt KColourComparisonTolerance = 2;
sl@0
   628
		if (res)
sl@0
   629
			{
sl@0
   630
			TBool testPassed = ETrue;
sl@0
   631
			// strict byte-for-byte comparison of the pixel maps could have failed because blending algorithms may  
sl@0
   632
			// differ slightly, but actual resulting colours may be close enough
sl@0
   633
			for (int byteNumber = 0; byteNumber < allocatedSize; byteNumber+=2)
sl@0
   634
				{
sl@0
   635
				// find any RGB565 value that doesn't match and examine each component
sl@0
   636
				if ( *(TUint16*)(screenBmpDestData1 + byteNumber) != *(TUint16*)(screenBmpDestData2 + byteNumber))
sl@0
   637
					{
sl@0
   638
					TUint16 Rgb1 = *(TUint16*)(screenBmpDestData1 + byteNumber);
sl@0
   639
					TUint16 Rgb2 = *(TUint16*)(screenBmpDestData2 + byteNumber);
sl@0
   640
					
sl@0
   641
					TInt16 Red1 = (Rgb1 & 0xF800) >> 11;
sl@0
   642
					TInt16 Red2 = (Rgb2 & 0xF800) >> 11;
sl@0
   643
					TInt16 DiffRed = Abs(Red1 - Red2);
sl@0
   644
					
sl@0
   645
					TInt16 Green1 = (Rgb1 & 0x07E0) >> 5;
sl@0
   646
					TInt16 Green2 = (Rgb2 & 0x07E0) >> 5;
sl@0
   647
					TInt16 DiffGreen = Abs(Green1 - Green2);
sl@0
   648
					
sl@0
   649
					TInt16 Blue1 = (Rgb1 & 0x001F);
sl@0
   650
					TInt16 Blue2 = (Rgb2 & 0x001F);
sl@0
   651
					TInt16 DiffBlue = Abs(Blue1 - Blue2);
sl@0
   652
					
sl@0
   653
					// is any difference is outside the tolerance break out signaling test failure
sl@0
   654
					if (DiffRed > KColourComparisonTolerance || 
sl@0
   655
						DiffGreen > KColourComparisonTolerance || 
sl@0
   656
						DiffBlue > KColourComparisonTolerance)
sl@0
   657
						{
sl@0
   658
						testPassed = EFalse;
sl@0
   659
						break;
sl@0
   660
						}
sl@0
   661
					}
sl@0
   662
				}
sl@0
   663
			if (testPassed)
sl@0
   664
				{
sl@0
   665
				res = 0;
sl@0
   666
				}
sl@0
   667
			}
sl@0
   668
		
sl@0
   669
		if (res && (attempt < KMaximumAttempts - 1))
sl@0
   670
			{
sl@0
   671
			INFO_PRINTF1(_L("Memory comparison 1 failed, retrying"));
sl@0
   672
			// Skip to next attempt
sl@0
   673
			continue;
sl@0
   674
			}
sl@0
   675
		TEST(res == 0);
sl@0
   676
sl@0
   677
		//  Alpha blending using implicit form of CFbsBitGc::AlphaBlendBitmaps  //
sl@0
   678
		if (iExtraLogging2)
sl@0
   679
			{
sl@0
   680
			_LIT(KLog3,"    CFbsBitGc::AlphaBlendBitmaps implicit test");
sl@0
   681
			INFO_PRINTF1(KLog3);
sl@0
   682
			}
sl@0
   683
		//Clear screen
sl@0
   684
	   	iGc->Clear();
sl@0
   685
	   	iDevice->Update();
sl@0
   686
		//Draw screen bitmap (it's already loaded)
sl@0
   687
		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
sl@0
   688
		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
sl@0
   689
		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
sl@0
   690
	   	iDevice->Update();
sl@0
   691
	   	//Do AlphaBlendBitmaps()
sl@0
   692
	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, aSrcRc1.iTl));
sl@0
   693
	   	iDevice->Update();
sl@0
   694
		//Get screen data and write the data to screenBmpDestData2.
sl@0
   695
		for(i=0;i<scrDevSize.iHeight;i++)
sl@0
   696
	   		{
sl@0
   697
			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
sl@0
   698
			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
sl@0
   699
	   		}
sl@0
   700
		//Compare screen bitmaps //
sl@0
   701
		if (iExtraLogging2)
sl@0
   702
			{
sl@0
   703
			_LIT(KLog4,"    Compare Screen Bitmaps");
sl@0
   704
			INFO_PRINTF1(KLog4);
sl@0
   705
			}
sl@0
   706
		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
sl@0
   707
sl@0
   708
		if (res && (attempt < KMaximumAttempts - 1))
sl@0
   709
			{
sl@0
   710
			INFO_PRINTF1(_L("Memory comparison 2 failed, retrying"));
sl@0
   711
			}
sl@0
   712
		
sl@0
   713
		// Reload the screen bitmap as it was before:
sl@0
   714
		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
sl@0
   715
		}
sl@0
   716
	TEST(res == 0);
sl@0
   717
	
sl@0
   718
	//Destroy the allocated memory blocks
sl@0
   719
	CleanupStack::PopAndDestroy(2);//screenBmpDestData1 & screenBmpDestData2
sl@0
   720
	}
sl@0
   721
sl@0
   722
void CTAlphaBlending::CreateAlphaBlendingBitmapsLC(CFbsBitmap*& aScreenBmp, 
sl@0
   723
											   CFbsBitmap*& aSrcBmp, 
sl@0
   724
											   CFbsBitmap*& aAlphaBmp,
sl@0
   725
											   TDisplayMode aMode)
sl@0
   726
	{
sl@0
   727
	TInt i;
sl@0
   728
	TSize size(KWidth, KHeight);
sl@0
   729
	//The screen data
sl@0
   730
	TUint8 screenBmpSrcData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
sl@0
   731
		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
sl@0
   732
		{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},
sl@0
   733
		{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},
sl@0
   734
		{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}
sl@0
   735
		};
sl@0
   736
	//The source bitmap data
sl@0
   737
	TUint8 srcBmpData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
sl@0
   738
		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
sl@0
   739
		{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},
sl@0
   740
		{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},
sl@0
   741
		{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}
sl@0
   742
		};
sl@0
   743
	//The alpha bitmap data
sl@0
   744
	TUint8 alphaBmpData[KHeight][KWidth + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
sl@0
   745
		{//0   1     2     3     4     5     6     7     8     9     
sl@0
   746
		{0x68, 0x68, 0x68, 0xAC, 0xD9, 0xB2, 0x8F, 0x11, 0xA0, 0xC1, 0x00, 0x00},
sl@0
   747
		{0x71, 0x5A, 0xF6, 0xEE, 0xF9, 0xE5, 0x06, 0x4C, 0xBB, 0x7B, 0x00, 0x00},
sl@0
   748
		{0x9F, 0x99, 0x45, 0x17, 0xA8, 0xF5, 0xFF, 0xD2, 0x22, 0x1D, 0x00, 0x00}
sl@0
   749
		};
sl@0
   750
sl@0
   751
	if(aMode == EColor16MU)
sl@0
   752
		{
sl@0
   753
		
sl@0
   754
		TInt buffer_size = KWidth * 4 ;
sl@0
   755
		TUint8* buffer = new(ELeave) TUint8[buffer_size];
sl@0
   756
		TPtr8 source_ptr(buffer, buffer_size, buffer_size);
sl@0
   757
sl@0
   758
		//Screen bitmap
sl@0
   759
		aScreenBmp = new (ELeave) CFbsBitmap;
sl@0
   760
		CleanupStack::PushL(aScreenBmp);
sl@0
   761
		User::LeaveIfError(aScreenBmp->Create(size, aMode));
sl@0
   762
		for(i=0; i<KHeight; i++)
sl@0
   763
			{
sl@0
   764
			TUint8* bufCur = buffer;
sl@0
   765
			TUint8* bufSrcCur = screenBmpSrcData[i];
sl@0
   766
			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
sl@0
   767
			while(bufSrcCur < bufSrcEnd)
sl@0
   768
				{
sl@0
   769
				*bufCur++ = *bufSrcCur++;
sl@0
   770
				*bufCur++ = *bufSrcCur++;
sl@0
   771
				*bufCur++ = *bufSrcCur++;
sl@0
   772
				*bufCur++ = 0xff;
sl@0
   773
				}
sl@0
   774
			aScreenBmp->SetScanLine(source_ptr, i);
sl@0
   775
			}
sl@0
   776
			
sl@0
   777
		//Source bitmap
sl@0
   778
		aSrcBmp = new (ELeave) CFbsBitmap;
sl@0
   779
		CleanupStack::PushL(aSrcBmp);
sl@0
   780
		User::LeaveIfError(aSrcBmp->Create(size, aMode));
sl@0
   781
		for(i=0; i<KHeight; i++)
sl@0
   782
			{
sl@0
   783
			TUint8* bufCur = buffer;
sl@0
   784
			TUint8* bufSrcCur = srcBmpData[i];
sl@0
   785
			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
sl@0
   786
			while(bufSrcCur < bufSrcEnd)
sl@0
   787
				{
sl@0
   788
				*bufCur++ = *bufSrcCur++;
sl@0
   789
				*bufCur++ = *bufSrcCur++;
sl@0
   790
				*bufCur++ = *bufSrcCur++;
sl@0
   791
				*bufCur++ = 0xff;
sl@0
   792
				}
sl@0
   793
			aSrcBmp->SetScanLine(source_ptr, i);
sl@0
   794
			}
sl@0
   795
			
sl@0
   796
			
sl@0
   797
		//Alpha bitmap
sl@0
   798
		aAlphaBmp = new (ELeave) CFbsBitmap;
sl@0
   799
		CleanupStack::PushL(aAlphaBmp);
sl@0
   800
		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
sl@0
   801
		for(i=0;i<KHeight;i++)
sl@0
   802
			{
sl@0
   803
			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
sl@0
   804
			aAlphaBmp->SetScanLine(p, i);
sl@0
   805
			}
sl@0
   806
			
sl@0
   807
		delete [] buffer;	
sl@0
   808
		}
sl@0
   809
	else
sl@0
   810
		{
sl@0
   811
		//Screen bitmap
sl@0
   812
		aScreenBmp = new (ELeave) CFbsBitmap;
sl@0
   813
		CleanupStack::PushL(aScreenBmp);
sl@0
   814
		User::LeaveIfError(aScreenBmp->Create(size, aMode));
sl@0
   815
		for(i=0;i<KHeight;i++)
sl@0
   816
			{
sl@0
   817
			TPtr8 p(screenBmpSrcData[i], KWidth * 3, KWidth * 3);
sl@0
   818
			aScreenBmp->SetScanLine(p, i);
sl@0
   819
			}
sl@0
   820
		//Source bitmap
sl@0
   821
		aSrcBmp = new (ELeave) CFbsBitmap;
sl@0
   822
		CleanupStack::PushL(aSrcBmp);
sl@0
   823
		User::LeaveIfError(aSrcBmp->Create(size, aMode));
sl@0
   824
		for(i=0;i<KHeight;i++)
sl@0
   825
			{
sl@0
   826
			TPtr8 p(srcBmpData[i], KWidth * 3, KWidth * 3);
sl@0
   827
			aSrcBmp->SetScanLine(p, i);
sl@0
   828
			}
sl@0
   829
		//Alpha bitmap
sl@0
   830
		aAlphaBmp = new (ELeave) CFbsBitmap;
sl@0
   831
		CleanupStack::PushL(aAlphaBmp);
sl@0
   832
		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
sl@0
   833
		for(i=0;i<KHeight;i++)
sl@0
   834
			{
sl@0
   835
			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
sl@0
   836
			aAlphaBmp->SetScanLine(p, i);
sl@0
   837
			}
sl@0
   838
		}	
sl@0
   839
	}
sl@0
   840
sl@0
   841
void CTAlphaBlending::DestroyAlphaBlendingBitmaps(CFbsBitmap*& aScreenBmp, 
sl@0
   842
											  CFbsBitmap*& aSrcBmp, 
sl@0
   843
											  CFbsBitmap*& aAlphaBmp)
sl@0
   844
	{
sl@0
   845
	CleanupStack::PopAndDestroy(aAlphaBmp);
sl@0
   846
	aAlphaBmp = NULL;
sl@0
   847
	CleanupStack::PopAndDestroy(aSrcBmp);
sl@0
   848
	aSrcBmp = NULL;
sl@0
   849
	CleanupStack::PopAndDestroy(aScreenBmp);
sl@0
   850
	aScreenBmp = NULL;
sl@0
   851
	}
sl@0
   852
sl@0
   853
//The test doesn't check anything. It is for debugging only.
sl@0
   854
void CTAlphaBlending::TestAlphaBlending2L()
sl@0
   855
	{
sl@0
   856
	static const TDisplayMode modeList[] = {
sl@0
   857
			EColor64K, EColor256, EColor16MAP, EColor16MA, EColor16MU, EColor4K
sl@0
   858
	};
sl@0
   859
	const TInt KNumTestDisplayModes=sizeof(modeList)/sizeof(modeList[0]);
sl@0
   860
	for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
sl@0
   861
		{
sl@0
   862
		CFbsBitmap* srcBmp = NULL;
sl@0
   863
		CFbsBitmap* alphaBmp = NULL;
sl@0
   864
		TInt err = KErrNotSupported;
sl@0
   865
		// Try several modes
sl@0
   866
		for (TInt modeIndex = 0; (err != KErrNone) && modeIndex < KNumTestDisplayModes; modeIndex++)
sl@0
   867
			{
sl@0
   868
			err = CreateScreenDevice(modeList[modeIndex],(CFbsBitGc::TGraphicsOrientation)orientation);
sl@0
   869
			}
sl@0
   870
		if (err == KErrNotSupported)
sl@0
   871
			{
sl@0
   872
			// Orientation not supported, try next one
sl@0
   873
			continue;
sl@0
   874
			}
sl@0
   875
		TInt j;
sl@0
   876
		//The source bitmap data
sl@0
   877
		TUint8 srcBmpData[100];
sl@0
   878
		for(j=0;j<100;j++)
sl@0
   879
			{
sl@0
   880
			srcBmpData[j] = 0xAA;
sl@0
   881
			}
sl@0
   882
		//The alpha bitmap data
sl@0
   883
		TUint8 alphaBmpData[20];
sl@0
   884
		for(j=0;j<20;j++)
sl@0
   885
			{
sl@0
   886
			alphaBmpData[j] = TUint8(j);
sl@0
   887
			}
sl@0
   888
		//Source bitmap
sl@0
   889
		srcBmp = new (ELeave) CFbsBitmap;
sl@0
   890
		CleanupStack::PushL(srcBmp);
sl@0
   891
		User::LeaveIfError(srcBmp->Create(TSize(100, 1), EColor256));
sl@0
   892
		TPtr8 p1(srcBmpData, 100, 100);
sl@0
   893
		srcBmp->SetScanLine(p1, 0);
sl@0
   894
		//Alpha bitmap
sl@0
   895
		alphaBmp = new (ELeave) CFbsBitmap;
sl@0
   896
		CleanupStack::PushL(alphaBmp);
sl@0
   897
		User::LeaveIfError(alphaBmp->Create(TSize(20, 1), EGray256));
sl@0
   898
		TPtr8 p2(alphaBmpData, 20, 20);
sl@0
   899
		alphaBmp->SetScanLine(p2, 0);
sl@0
   900
		//Do BitBltMasked()
sl@0
   901
		iGc->BitBltMasked(TPoint(20, 20), srcBmp, TRect(10, 0, 100, 1), alphaBmp, EFalse);
sl@0
   902
		iDevice->Update();
sl@0
   903
		iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
sl@0
   904
		//
sl@0
   905
		CleanupStack::PopAndDestroy(alphaBmp);
sl@0
   906
		CleanupStack::PopAndDestroy(srcBmp);
sl@0
   907
		}
sl@0
   908
	}
sl@0
   909
sl@0
   910
TUint32 AlphaBlend(TUint32 aDestPixel, TUint32 aSrcPixel, TUint8 aMask)
sl@0
   911
 	{
sl@0
   912
 	TUint32 dr = (aDestPixel & 0x00FF0000) >> 16;
sl@0
   913
 	TUint32 dg = (aDestPixel & 0x0000FF00) >> 8;
sl@0
   914
 	TUint32 db = aDestPixel & 0x000000FF;
sl@0
   915
 	
sl@0
   916
 	TUint32 sr = (aSrcPixel & 0x00FF0000) >> 16;
sl@0
   917
 	TUint32 sg = (aSrcPixel & 0x0000FF00) >> 8;
sl@0
   918
 	TUint32 sb = aSrcPixel & 0x000000FF;
sl@0
   919
 	
sl@0
   920
 	TUint32 rr = (aMask * sr)/255 + ((0xFF - aMask) * dr)/255;
sl@0
   921
 	TUint32 rg = (aMask * sg)/255 + ((0xFF - aMask) * dg)/255;
sl@0
   922
 	TUint32 rb = (aMask * sb)/255 + ((0xFF - aMask) * db)/255;
sl@0
   923
 	
sl@0
   924
 	return(rr << 16 | rg << 8 | rb | 0xff000000);
sl@0
   925
 	}
sl@0
   926
 
sl@0
   927
inline TUint32 OptimizedBlend32(TInt aPrimaryRed,TInt aPrimaryGreen,TInt aPrimaryBlue,TUint32 aSecondary,TUint8 aAlphaValue)
sl@0
   928
 	{
sl@0
   929
  
sl@0
   930
  	if(aAlphaValue == 0xff)
sl@0
   931
 		{
sl@0
   932
 		return (aPrimaryBlue + (aPrimaryGreen<<8) + (aPrimaryRed<<16)) | 0xff000000;
sl@0
   933
  		}
sl@0
   934
  	else
sl@0
   935
  		{
sl@0
   936
  		const TUint32 alphaValue = (aAlphaValue << 8) + aAlphaValue;
sl@0
   937
  
sl@0
   938
  		const TInt r2 = (aSecondary & 0x00ff0000) >> 16;
sl@0
   939
  		const TInt g2 = (aSecondary & 0x0000ff00) >> 8;
sl@0
   940
  		const TInt b2 = aSecondary & 0x000000ff;
sl@0
   941
  
sl@0
   942
  		const TInt r3 = ((alphaValue * (aPrimaryRed   - r2)) >> 16) + r2;
sl@0
   943
 		const TInt g3 = ((alphaValue * (aPrimaryGreen - g2)) >> 16) + g2;
sl@0
   944
 		const TInt b3 = ((alphaValue * (aPrimaryBlue  - b2)) >> 16) + b2;
sl@0
   945
 
sl@0
   946
 		return (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
sl@0
   947
  		}
sl@0
   948
  	}
sl@0
   949
sl@0
   950
sl@0
   951
/**
sl@0
   952
  @SYMTestCaseID GRAPHICS-BITGDI-0085
sl@0
   953
 
sl@0
   954
  @SYMDEF             
sl@0
   955
sl@0
   956
  @SYMTestCaseDesc 
sl@0
   957
   
sl@0
   958
  @SYMTestPriority High
sl@0
   959
sl@0
   960
  @SYMTestStatus Implemented
sl@0
   961
sl@0
   962
  @SYMTestActions 
sl@0
   963
 
sl@0
   964
  @SYMTestExpectedResults 
sl@0
   965
*/  	
sl@0
   966
// This tests the correctness of the results of alpha-blending with EColor16MA
sl@0
   967
void CTAlphaBlending::TestAlphaBlendCorrect(TDisplayMode /* aScreenMode */, TDisplayMode /* aBitmapMode */)
sl@0
   968
 	{
sl@0
   969
 	// test data
sl@0
   970
 	TUint32 top = 0xFFCCEE55;
sl@0
   971
 	TUint32 beneath = 0xFFEEAA66;
sl@0
   972
 	TUint8 alpha = 0xF0;
sl@0
   973
 	
sl@0
   974
 	TInt maxDiff = 0;
sl@0
   975
 	
sl@0
   976
 	for(TInt i = 0; i < 100000; i++)
sl@0
   977
 		{
sl@0
   978
 		top = Math::Random();
sl@0
   979
 		beneath = Math::Random();
sl@0
   980
 		alpha = Math::Random();
sl@0
   981
 		TUint32 res1 = AlphaBlend(beneath, top, alpha);
sl@0
   982
 		TUint32 res2 = OptimizedBlend32((top >> 16) & 0xFF,(top >>8) & 0xFF,(top & 0xFF),beneath, alpha);
sl@0
   983
 		
sl@0
   984
 		if(res1 != res2)
sl@0
   985
 			{
sl@0
   986
 			TInt diff = 0;
sl@0
   987
 			TInt diff1 = res1 & 0xFF;
sl@0
   988
 			TInt diff2 = res2 & 0xFF;
sl@0
   989
 			
sl@0
   990
 			diff = diff1 - diff2;
sl@0
   991
 			
sl@0
   992
 			if(diff < 0)
sl@0
   993
 				diff*=-1;
sl@0
   994
 				
sl@0
   995
 			if(diff > maxDiff)
sl@0
   996
 				maxDiff = diff;
sl@0
   997
 				
sl@0
   998
 			diff1 = (res1 >> 8) & 0xFF;
sl@0
   999
 			diff2 = (res2 >> 8) & 0xFF;
sl@0
  1000
 			
sl@0
  1001
 			diff = diff1 - diff2;
sl@0
  1002
 			
sl@0
  1003
 			if(diff < 0)
sl@0
  1004
 				diff*=-1;
sl@0
  1005
 				
sl@0
  1006
 			if(diff > maxDiff)
sl@0
  1007
 				maxDiff = diff;
sl@0
  1008
 			
sl@0
  1009
 			
sl@0
  1010
 			diff1 = (res1 >> 16) & 0xFF;
sl@0
  1011
 			diff2 = (res2 >> 16) & 0xFF;
sl@0
  1012
 			
sl@0
  1013
 			diff = diff1 - diff2;
sl@0
  1014
 			
sl@0
  1015
 			if(diff < 0)
sl@0
  1016
 				diff*=-1;
sl@0
  1017
 				
sl@0
  1018
 			if(diff > maxDiff)
sl@0
  1019
 				maxDiff = diff;
sl@0
  1020
 			
sl@0
  1021
 			}
sl@0
  1022
 		}
sl@0
  1023
	
sl@0
  1024
 	INFO_PRINTF1(_L("Results:"));
sl@0
  1025
 		
sl@0
  1026
 	if(maxDiff)
sl@0
  1027
 		INFO_PRINTF2(_L("Max Diff = %i"), maxDiff);
sl@0
  1028
 	else
sl@0
  1029
 		INFO_PRINTF1(_L("Results are identical"));
sl@0
  1030
  	}
sl@0
  1031
sl@0
  1032
//--------------
sl@0
  1033
__CONSTRUCT_STEP__(AlphaBlending)
sl@0
  1034
sl@0
  1035
void CTAlphaBlendingStep::TestSetupL()
sl@0
  1036
	{
sl@0
  1037
	}
sl@0
  1038