1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1038 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <hal.h>
1.20 +#include <e32math.h>
1.21 +#include "TAlphaBlend.h"
1.22 +
1.23 +
1.24 +const TInt KWidth = 10;//Used in alpha blending tests
1.25 +const TInt KHeight = 3;//Used in alpha blending tests
1.26 +const TInt KMaximumAttempts = 2; // Allow retries on some tests, due to spurious InfoPrints
1.27 +TBool iExtraLogging1=EFalse; //Used to trigger logging at times the test fails
1.28 +TBool iExtraLogging2=EFalse; //Used to trigger logging at times the test fails
1.29 +
1.30 +CTAlphaBlending::CTAlphaBlending(CTestStep* aStep):
1.31 + CTGraphicsBase(aStep),
1.32 + iDevice(NULL),
1.33 + iGc(NULL)
1.34 + {
1.35 + }
1.36 +
1.37 +CTAlphaBlending::~CTAlphaBlending()
1.38 + {
1.39 + DeleteGraphicsContext();
1.40 + DeleteScreenDevice();
1.41 + }
1.42 +
1.43 +void CTAlphaBlending::RunTestCaseL(TInt aCurTestCase)
1.44 + {
1.45 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
1.46 + switch(aCurTestCase)
1.47 + {
1.48 + case 1:
1.49 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0024"));
1.50 + INFO_PRINTF1(_L("Alpha blending"));
1.51 + TestAlphaBlendingL();
1.52 + break;
1.53 + case 2:
1.54 +/**
1.55 +@SYMTestCaseID GRAPHICS-BITGDI-0114
1.56 +*/
1.57 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0114"));
1.58 + INFO_PRINTF1(_L("Alpha blending 2"));
1.59 + TestAlphaBlending2L();
1.60 + break;
1.61 + case 3:
1.62 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
1.63 + INFO_PRINTF1(_L("Alpha blending Correctness test 16MU 16MA"));
1.64 + TestAlphaBlendCorrect(EColor16MU, EColor16MU);
1.65 + break;
1.66 + case 4:
1.67 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097"));
1.68 + INFO_PRINTF1(_L("Alpha plot test"));
1.69 + TestAlphaBlendingPlotL();
1.70 + break;
1.71 + case 5:
1.72 +/**
1.73 +@SYMTestCaseID GRAPHICS-BITGDI-0115
1.74 +*/
1.75 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0115"));
1.76 + INFO_PRINTF1(_L("Draw bitmap blending"));
1.77 + DoDrawBitmapTestsL();
1.78 + break;
1.79 + case 6:
1.80 + //DEF118268
1.81 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
1.82 + INFO_PRINTF1(_L("Alpha blending Correctness test 16M 16MA"));
1.83 + TestAlphaBlendCorrect(EColor16M, EColor16MA);
1.84 + break;
1.85 + case 7:
1.86 + ((CTAlphaBlendingStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
1.87 + ((CTAlphaBlendingStep*)iStep)->CloseTMSGraphicsStep();
1.88 + TestComplete();
1.89 + break;
1.90 + }
1.91 + ((CTAlphaBlendingStep*)iStep)->RecordTestResultL();
1.92 + }
1.93 +
1.94 +TInt CTAlphaBlending::CreateScreenDevice(TDisplayMode aDisplayMode, CFbsBitGc::TGraphicsOrientation aOrientation)
1.95 + {
1.96 + DeleteGraphicsContext();
1.97 + DeleteScreenDevice();
1.98 + TRAPD(err, iDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
1.99 + if(err == KErrNotSupported)
1.100 + {
1.101 + return err;
1.102 + }
1.103 + TEST2(err, KErrNone);
1.104 + err = iDevice->CreateContext((CGraphicsContext*&)iGc);
1.105 + TEST2(err, KErrNone);
1.106 + if (!iGc->SetOrientation(aOrientation))
1.107 + {
1.108 + return(KErrNotSupported);
1.109 + }
1.110 + iGc->SetUserDisplayMode(aDisplayMode);
1.111 + iDevice->ChangeScreenDevice(NULL);
1.112 + iDevice->SetAutoUpdate(EFalse);
1.113 + return err;
1.114 + }
1.115 +
1.116 +void CTAlphaBlending::DeleteScreenDevice()
1.117 + {
1.118 + delete iDevice;
1.119 + iDevice = NULL;
1.120 + }
1.121 +
1.122 +void CTAlphaBlending::DeleteGraphicsContext()
1.123 + {
1.124 + delete iGc;
1.125 + iGc = NULL;
1.126 + }
1.127 +
1.128 +// returns the pixel colour from the provided bitmap in aarrggbb format
1.129 +// if pixel is outside the bitmaps limits return top left pixel
1.130 +TUint32 CTAlphaBlending::GetRawPixel(CFbsBitmap* aBitmap, TPoint aPos)
1.131 + {
1.132 + TBitmapUtil bmpUtil(aBitmap);
1.133 + TUint32 value = 0;
1.134 + ASSERT(aPos.iX>=0 && aPos.iY>=0);
1.135 + ASSERT(aPos.iX<aBitmap->SizeInPixels().iWidth && aPos.iY<aBitmap->SizeInPixels().iHeight);
1.136 + bmpUtil.Begin(aPos);
1.137 + value = bmpUtil.GetPixel();
1.138 + bmpUtil.End();
1.139 + return value;
1.140 + }
1.141 +
1.142 +/**
1.143 +@SYMTestCaseID GRAPHICS-BITGDI-0097
1.144 +
1.145 +@SYMDEF DEF113229
1.146 +
1.147 +@SYMTestCaseDesc CDrawThirtyTwoBppBitmapCommon::WriteRgb did not change the dest alpha value to 255 when
1.148 + the dest alpha was >0 and <255 and the a soure pen had an alpha of 255
1.149 +
1.150 +@SYMTestPriority Normal
1.151 +
1.152 +@SYMTestStatus Implemented
1.153 +
1.154 +@SYMTestActions Creates a bitmap, clears it to black (destination) 50% opaque then plots a series of points
1.155 + with a 100% opaque pen on it. Tests the resultant alpha value.
1.156 +
1.157 +@SYMTestExpectedResults Final alpha value should be 255
1.158 +**/
1.159 +void CTAlphaBlending::TestAlphaBlendingPlotL()
1.160 + {
1.161 + const TSize KRectSize(100,100);
1.162 + const TRect KTargetRect(TPoint(0,0), KRectSize);
1.163 +
1.164 + // create the target bitmap
1.165 + CFbsBitmap* destBmp = new (ELeave) CFbsBitmap;
1.166 + CleanupStack::PushL(destBmp);
1.167 + User::LeaveIfError(destBmp->Create(KRectSize, EColor16MA));
1.168 + destBmp->SetSizeInTwips(KRectSize);
1.169 +
1.170 + // create bitmap device and graphics context
1.171 + CFbsBitmapDevice* destBmpDevice = CFbsBitmapDevice::NewL(destBmp);
1.172 + CleanupStack::PushL(destBmpDevice);
1.173 + CFbsBitGc* destGc = NULL;
1.174 + User::LeaveIfError(destBmpDevice->CreateContext(destGc));
1.175 + CleanupStack::PushL(destGc);
1.176 + destGc->SetPenStyle(CGraphicsContext::ENullPen);
1.177 + destGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
1.178 +
1.179 + TDisplayMode screenMode = EColor16MA;
1.180 + TInt err = CreateScreenDevice(screenMode);
1.181 + if (err != KErrNone)
1.182 + {
1.183 + screenMode = EColor64K;
1.184 + err = CreateScreenDevice(screenMode);
1.185 + }
1.186 +
1.187 + if(err==KErrNone)
1.188 + {
1.189 + const TInt KSqrMin=45;
1.190 + const TInt KSqrMax=55;
1.191 +
1.192 + iGc->SetUserDisplayMode(screenMode);
1.193 + destGc->SetBrushColor(TRgb(0,0,0,127));
1.194 + destGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
1.195 + destGc->Clear(KTargetRect);
1.196 +
1.197 + // copy over to screen dc for anyone watching
1.198 + iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
1.199 + iDevice->Update();
1.200 +
1.201 + // set the pen colour to white and plot some points
1.202 + destGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
1.203 + destGc->SetPenStyle(CGraphicsContext::ESolidPen);
1.204 + destGc->SetPenColor(TRgb(0,70,130,255));
1.205 + for( TInt y=KSqrMin;y<=KSqrMax;y++)
1.206 + {
1.207 + for( TInt x=KSqrMin;x<=KSqrMax;x++)
1.208 + {
1.209 + destGc->Plot(TPoint(x,y));
1.210 + }
1.211 + }
1.212 +
1.213 + // copy over to screen dc for anyone watching
1.214 + iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
1.215 + iDevice->Update();
1.216 +
1.217 + TUint32 actualValue=0;
1.218 + // check the resulting values alpha values are 0xFF in the square we drew
1.219 + for( TInt y=KSqrMin;y<=KSqrMax;y++)
1.220 + {
1.221 + for( TInt x=KSqrMin;x<=KSqrMax;x++)
1.222 + {
1.223 + actualValue = GetRawPixel(destBmp, TPoint(x,y));
1.224 + if( (actualValue&0xFF000000) != 0xFF000000 )
1.225 + {
1.226 + TEST(EFalse);
1.227 + INFO_PRINTF2(_L("TestAlphaBlendingPlotL() ***FAILED*** - expected alpha value 0xFF got %d "),((actualValue&0xFF000000)>>24));
1.228 + }
1.229 + }
1.230 + }
1.231 + }
1.232 + CleanupStack::PopAndDestroy(3); //destGc,destBmpDevice,destBmp
1.233 + }
1.234 +
1.235 +/**
1.236 + @SYMTestCaseID GRAPHICS-BITGDI-0024
1.237 +
1.238 + @SYMDEF
1.239 +
1.240 + @SYMTestCaseDesc
1.241 +
1.242 + System, GT0173 System Libraries, BITGDI support required for semi-transparent windows
1.243 + DEF039083 - Using BitBltMasked to do alpha-blending only works if your brush style is "null"
1.244 + DEF039409 - Wrong part of Alpha Bitmap is used when there is a clipping region
1.245 + DEF039669 - The UserDisplayMode is not honoured during the AlphaBlendBitmap function.
1.246 + REQ3413 Second overload of CFbsBitGc's AlphaBlendBitmaps - "Supply a second overload of
1.247 + CFbsBitGc's AlphaBlendBitmaps function, but with one of the source bitmaps being passed
1.248 + as a CFbsBitGc object, so that the screen can be used as a source."
1.249 +
1.250 + @SYMTestPriority High
1.251 +
1.252 + @SYMTestStatus Implemented
1.253 +
1.254 + @SYMTestActions
1.255 +
1.256 + Tests alpha blending - for all display modes, some brush styles, user display modes,
1.257 + different positions on the screen.
1.258 +
1.259 + Shadow/fade mode is no more tested, because the existing BitBltMasked() and the new
1.260 + AlphaBlendBitmaps() methods treat it a different way - see MAlphaBlend interface in
1.261 + ScreenDriver component.
1.262 +
1.263 + @SYMTestExpectedResults Test should perform graphics operations succesfully.
1.264 +*/
1.265 +
1.266 +void CTAlphaBlending::TestAlphaBlendingL()
1.267 + {
1.268 + TPoint originPt(0, 0);
1.269 + TPoint destPt(0, 0);
1.270 + TRect scrRc1(0, 0, KWidth, KHeight);
1.271 + TPoint srcPt2(0, 0);
1.272 + TPoint alphaPt(0, 0);
1.273 + //
1.274 + //If we compare CFbsBitGc::BitBltMasked() aguments with CFbsBitGc::AlphaBlending() arguments,
1.275 + //we will see that AlphaBlending() has more arguments than BitBltMasked() -
1.276 + //srcPt2, alphaPt. To make it possible - the comparison between these two methods,
1.277 + //we have to change aAlphaPt and aSrcPt2 values accordingly with the changes of scrRc1 value.
1.278 + //
1.279 + //test 1 - the origin is moved
1.280 + originPt = TPoint(97, 33);
1.281 + DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
1.282 +#if !defined(__X86GCC__) //These test take too long to run in X86GCC
1.283 + //test 2 - the origin is (0, 0)
1.284 + originPt = TPoint(0, 0);
1.285 + DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
1.286 + //test 3 - scrRect1 is not (0, 0, KWidth, KHeight)
1.287 + scrRc1 = TRect(3, 1, KWidth, KHeight);
1.288 + alphaPt = TPoint(3, 1);
1.289 + DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
1.290 + //test 4 - restore scrRc1 and alphaPt, move the destination point
1.291 + scrRc1 = TRect(0, 0, KWidth, KHeight);
1.292 + alphaPt = TPoint(0, 0);
1.293 + destPt = TPoint(13, 17);
1.294 + iExtraLogging1=ETrue;
1.295 + DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
1.296 + iExtraLogging1=EFalse;
1.297 +#endif //__X86GCC__
1.298 + }
1.299 +
1.300 +void CTAlphaBlending::DoDrawBitmapTestsL()
1.301 + {
1.302 + TDisplayMode modes[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
1.303 + EGray256, EGray16, EGray4, EGray2, EColor16};
1.304 + const TInt KNumTestDisplayModes=sizeof(modes)/sizeof(modes[0]);
1.305 + for(TInt modeIndex=0;modeIndex<KNumTestDisplayModes;modeIndex++)
1.306 + {
1.307 + TDisplayMode screenMode=modes[modeIndex];
1.308 + if (CreateScreenDevice(screenMode)!=KErrNone)
1.309 + continue;
1.310 + DoDrawBitmapTestL(screenMode);
1.311 + }
1.312 + }
1.313 +
1.314 +void CTAlphaBlending::DoDrawBitmapTestL(TDisplayMode aTestDisplayMode)
1.315 + {
1.316 + iGc->Reset();
1.317 + TBool alphaSupported=(aTestDisplayMode==EColor16MA || aTestDisplayMode==EColor16MAP);
1.318 + TSize screenSize=iDevice->SizeInPixels();
1.319 +//
1.320 + const TInt KNumTestSrcSizes=4;
1.321 + const TSize testSrcSizes[KNumTestSrcSizes]={TSize(2,2),TSize(20,10),TSize(200,5),TSize(55,555)};
1.322 + for(TInt srcSizeIndex=0;srcSizeIndex<KNumTestSrcSizes;srcSizeIndex++)
1.323 + {
1.324 + TSize srcSize(testSrcSizes[srcSizeIndex]);
1.325 +//
1.326 + CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap;
1.327 + CleanupStack::PushL(srcBmp);
1.328 + User::LeaveIfError(srcBmp->Create(srcSize,aTestDisplayMode));
1.329 + CFbsBitmapDevice* srcDevice = CFbsBitmapDevice::NewL(srcBmp);
1.330 + CleanupStack::PushL(srcDevice);
1.331 + CFbsBitGc* srcGc=NULL;
1.332 + User::LeaveIfError(srcDevice->CreateContext(srcGc));
1.333 + CleanupStack::PushL(srcGc);
1.334 +//
1.335 + CFbsBitmap* srcAlpha=new(ELeave) CFbsBitmap;
1.336 + CleanupStack::PushL(srcAlpha);
1.337 + User::LeaveIfError(srcAlpha->Create(srcSize,aTestDisplayMode));
1.338 + CFbsBitmapDevice* srcAlphaDevice = CFbsBitmapDevice::NewL(srcAlpha);
1.339 + CleanupStack::PushL(srcAlphaDevice);
1.340 + CFbsBitGc* srcAlphaGc=NULL;
1.341 + User::LeaveIfError(srcAlphaDevice->CreateContext(srcAlphaGc));
1.342 + CleanupStack::PushL(srcAlphaGc);
1.343 + srcAlphaGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
1.344 +//
1.345 + CFbsBitmap* srcMask=new(ELeave) CFbsBitmap;
1.346 + CleanupStack::PushL(srcMask);
1.347 + User::LeaveIfError(srcMask->Create(srcSize,EGray256));
1.348 + CFbsBitmapDevice* srcMaskDevice = CFbsBitmapDevice::NewL(srcMask);
1.349 + CleanupStack::PushL(srcMaskDevice);
1.350 + CFbsBitGc* srcMaskGc=NULL;
1.351 + User::LeaveIfError(srcMaskDevice->CreateContext(srcMaskGc));
1.352 + CleanupStack::PushL(srcMaskGc);
1.353 +//
1.354 + TInt maxX=srcSize.iWidth-1;
1.355 + TInt maxY=srcSize.iHeight-1;
1.356 + for(TInt yLoop=0;yLoop<srcSize.iHeight;yLoop++)
1.357 + {
1.358 + for(TInt xLoop=0;xLoop<srcSize.iWidth;xLoop++)
1.359 + {
1.360 + TPoint plotPos(xLoop,yLoop);
1.361 + TRgb pen(xLoop*255/maxX,yLoop*255/maxY,(xLoop+yLoop)*128/(maxX+maxY));
1.362 + srcGc->SetPenColor(pen);
1.363 + srcGc->Plot(plotPos);
1.364 + TInt alpha=(xLoop+yLoop)*255/(maxX+maxY);
1.365 + pen.SetAlpha(alpha);
1.366 + srcAlphaGc->SetBrushColor(pen);
1.367 + srcAlphaGc->Clear(TRect(plotPos,TSize(1,1)));
1.368 + srcMaskGc->SetPenColor(TRgb::Gray256(alpha));
1.369 + srcMaskGc->Plot(plotPos);
1.370 + }
1.371 + }
1.372 + const TInt KNumTestTargSizes=5;
1.373 + const TSize testTargSizes[KNumTestTargSizes]={TSize(0,0), TSize(20,1),TSize(30,20),TSize(200,31),TSize(55,5)};
1.374 + for(TInt targSizeIndex=0;targSizeIndex<KNumTestSrcSizes;targSizeIndex++)
1.375 + {
1.376 + TSize targSize(testTargSizes[targSizeIndex]);
1.377 + if (targSizeIndex==0)
1.378 + {
1.379 + targSize=srcSize; // Special case with no scaling
1.380 + if (targSize.iWidth>screenSize.iWidth)
1.381 + targSize.iWidth=screenSize.iWidth;
1.382 + TInt maxHeight=screenSize.iHeight/3;
1.383 + if (targSize.iHeight>maxHeight)
1.384 + targSize.iHeight=maxHeight;
1.385 + }
1.386 +//
1.387 + CFbsBitmap* targBmp=new(ELeave) CFbsBitmap;
1.388 + CleanupStack::PushL(targBmp);
1.389 + User::LeaveIfError(targBmp->Create(targSize,aTestDisplayMode));
1.390 + CFbsBitmapDevice* targBmpDevice = CFbsBitmapDevice::NewL(targBmp);
1.391 + CleanupStack::PushL(targBmpDevice);
1.392 + CFbsBitGc* targGc=NULL;
1.393 + User::LeaveIfError(targBmpDevice->CreateContext(targGc));
1.394 + CleanupStack::PushL(targGc);
1.395 +//
1.396 + CFbsBitmap* targMask=new(ELeave) CFbsBitmap;
1.397 + CleanupStack::PushL(targMask);
1.398 + User::LeaveIfError(targMask->Create(targSize,EGray256));
1.399 + CFbsBitmapDevice* targMaskDevice = CFbsBitmapDevice::NewL(targMask);
1.400 + CleanupStack::PushL(targMaskDevice);
1.401 + CFbsBitGc* targMaskGc=NULL;
1.402 + User::LeaveIfError(targMaskDevice->CreateContext(targMaskGc));
1.403 + CleanupStack::PushL(targMaskGc);
1.404 +//
1.405 + TPoint drawPos;
1.406 + TRect testRect1(targSize);
1.407 + iGc->Clear();
1.408 +// First we pre-stretch the source and mask bitmaps into temp bitmaps
1.409 + targGc->DrawBitmap(TRect(targSize),srcBmp);
1.410 + targMaskGc->DrawBitmap(TRect(targSize),srcMask);
1.411 +// Then blend them onto the screen with a call to BitBltMasked
1.412 + iGc->BitBltMasked(drawPos,targBmp,TRect(targSize),targMask,EFalse);
1.413 + drawPos.iY+=targSize.iHeight;
1.414 + TRect testRect2(drawPos,targSize);
1.415 +// Next we combine the stretching and masking with one call to DrawBitmapMasked,
1.416 +// this should give the same end result.
1.417 + iGc->DrawBitmapMasked(testRect2,srcBmp,TRect(srcSize),srcMask,EFalse);
1.418 + TRect testRect3;
1.419 + if (alphaSupported)
1.420 + {
1.421 +// Finally if alpha blending supported we stretch and blend, again to achieve the exact same end result
1.422 +// as the two previous calls. This was specificially done to catch DEF116427.
1.423 + drawPos.iY+=targSize.iHeight;
1.424 + testRect3=TRect(drawPos,targSize);
1.425 + iGc->DrawBitmap(testRect3,srcAlpha);
1.426 + }
1.427 +//Use this just to check what we've put in the test bitmaps
1.428 +/*
1.429 + drawPos.iY+=targSize.iHeight+1;
1.430 + iGc->BitBlt(drawPos,srcBmp);
1.431 + drawPos.iY+=srcSize.iHeight+1;
1.432 + iGc->BitBlt(drawPos,srcMask);
1.433 + drawPos.iY+=srcSize.iHeight+1;
1.434 + if (alphaSupported)
1.435 + iGc->BitBlt(drawPos,srcAlpha);
1.436 +*/
1.437 + iDevice->Update();
1.438 + TBool ret1=iDevice->RectCompare(testRect1,*iDevice,testRect2);
1.439 + TBool ret2=alphaSupported?iDevice->RectCompare(testRect1,*iDevice,testRect3):ETrue;
1.440 + if (!ret1 || !ret2)
1.441 + {
1.442 + INFO_PRINTF4(_L("DrawBitmapTest, ret1=%d, ret2=%d, Screen mode=%d"),ret1,ret2,aTestDisplayMode);
1.443 + TEST(EFalse);
1.444 + }
1.445 + CleanupStack::PopAndDestroy(3,targMask);
1.446 + CleanupStack::PopAndDestroy(3,targBmp);
1.447 + }
1.448 + CleanupStack::PopAndDestroy(3,srcMask);
1.449 + CleanupStack::PopAndDestroy(3,srcAlpha);
1.450 + CleanupStack::PopAndDestroy(3,srcBmp);
1.451 + }
1.452 + }
1.453 +
1.454 +//Tests alpha blending - for all display modes, some brush styles, user display modes,
1.455 +//different positions on the screen.
1.456 +void CTAlphaBlending::DoAlphaBlendingTestsL(const TPoint& aOrigin,
1.457 + const TPoint& aDestPt,
1.458 + const TRect& aSrcRc1,
1.459 + const TPoint& aScrPt2,
1.460 + const TPoint& aAlphaPt)
1.461 + {
1.462 + TBuf<128> buf;
1.463 + _LIT(KLog,"Origin=(%d,%d) DestPt=(%d,%d) SrcRect=(%d,%d,%d,%d) ScrPt=(%d,%d) AlphaPt=(%d,%d)");
1.464 + buf.Format(KLog,aOrigin.iX,aOrigin.iY,aDestPt.iX,aDestPt.iY,aSrcRc1.iTl.iX,aSrcRc1.iTl.iY
1.465 + ,aSrcRc1.iBr.iX,aSrcRc1.iBr.iY,aScrPt2.iX,aScrPt2.iY,aAlphaPt.iX,aAlphaPt.iY);
1.466 + INFO_PRINTF1(buf);
1.467 + TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
1.468 + EGray256, EGray16, EGray4, EGray2, EColor16};
1.469 + CFbsBitmap* screenBmp = NULL;
1.470 + CFbsBitmap* srcBmp = NULL;
1.471 + CFbsBitmap* alphaBmp = NULL;
1.472 + CGraphicsContext::TBrushStyle brushStyle[] = {CGraphicsContext::ENullBrush, CGraphicsContext::ESolidBrush};
1.473 + for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
1.474 + {
1.475 + for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
1.476 + {
1.477 + if (CreateScreenDevice(mode[i],(CFbsBitGc::TGraphicsOrientation)orientation) != KErrNone)
1.478 + {
1.479 + continue;
1.480 + }
1.481 + iExtraLogging2=(iExtraLogging1 && mode[i]==11);
1.482 + INFO_PRINTF3(_L("Mode=%d, Orientation=%d"), mode[i], orientation);
1.483 + CreateAlphaBlendingBitmapsLC(screenBmp, srcBmp, alphaBmp, mode[i]);
1.484 + for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
1.485 + {
1.486 + if(mode[i] == EGray4 && brushStyle[j] == CGraphicsContext::ESolidBrush)
1.487 + {
1.488 + //When the display mode is EGray4 - Flicker-free blitting is not enabled.
1.489 + //The screen will be filled with 0xFF color, which is not the same color used by
1.490 + //the test - 0x00. And BitBltMasked and AlphaBlendBitmaps will produce different results.
1.491 + continue;
1.492 + }
1.493 + iGc->SetOrigin(aOrigin);
1.494 + iGc->SetBrushStyle(brushStyle[j]);
1.495 + TDisplayMode userDisplayMode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256,
1.496 + EColor4K, EColor64K, EGray256,
1.497 + EGray16, EGray4, EGray2, EColor16};
1.498 + for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
1.499 + {
1.500 + iGc->SetUserDisplayMode(userDisplayMode[l]);
1.501 + TSize scrDevSize = iDevice->SizeInPixels();
1.502 + TRect clipRc[] = {TRect(0, 0, scrDevSize.iWidth, scrDevSize.iHeight),
1.503 + TRect(0, 1, scrDevSize.iWidth, scrDevSize.iHeight), // Tests Y clipping only
1.504 + TRect(5, 0, scrDevSize.iWidth, scrDevSize.iHeight), // Tests X clipping only
1.505 + TRect(5, 1, scrDevSize.iWidth, scrDevSize.iHeight),
1.506 + TRect(3, 0, 14, 23)};//14 and 23 values are not accidental!
1.507 + //Sometimes the method is called with aDestPt(13, 17).
1.508 + for(TInt k=0;k<TInt(sizeof(clipRc)/sizeof(clipRc[0]));k++)
1.509 + {
1.510 + if (iExtraLogging2)
1.511 + {
1.512 + _LIT(KLog," BrushStyle=%d UserDisplayMode=%d ClipRect=(%d,%d,%d,%d)");
1.513 + INFO_PRINTF7(KLog,j,l,clipRc[k].iTl.iX,clipRc[k].iTl.iY,clipRc[k].iBr.iX,clipRc[k].iBr.iY);
1.514 + }
1.515 + iGc->Clear();
1.516 + iGc->SetClippingRect(clipRc[k]);
1.517 + DoAlphaBlendingTestL(screenBmp, srcBmp, alphaBmp, aDestPt, aSrcRc1, aScrPt2, aAlphaPt);
1.518 + iGc->CancelClippingRect();
1.519 + }
1.520 + }//end of - for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
1.521 + iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
1.522 + }
1.523 + DestroyAlphaBlendingBitmaps(screenBmp, srcBmp, alphaBmp);
1.524 + }//end of - for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
1.525 + }//end of - for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
1.526 + }
1.527 +
1.528 +//The method compares results of two alpha blending methods:
1.529 +//iGc->BitBltMasked() and iGc->AlphaBlendBitmaps().
1.530 +//To make that possible, aScreenBmp is copied to the screen before the call of
1.531 +//iGc->BitBltMasked().
1.532 +void CTAlphaBlending::DoAlphaBlendingTestL(CFbsBitmap* aScreenBmp,
1.533 + const CFbsBitmap* aSrcBmp,
1.534 + const CFbsBitmap* aAlphaBmp,
1.535 + const TPoint& aDestPt,
1.536 + const TRect& aSrcRc1,
1.537 + const TPoint& aSrcPt2,
1.538 + const TPoint& aAlphaPt)
1.539 + {
1.540 + _LIT(KScreenBmpFile, "C:\\BMP_DATA.DAT");
1.541 + iGc->SetShadowMode(EFalse);
1.542 + TInt i;
1.543 + TInt res = -1;
1.544 + TSize scrDevSize = iDevice->SizeInPixels();
1.545 + TInt allocatedSize = scrDevSize.iWidth * scrDevSize.iHeight * 2;
1.546 + TRect screenBmpRc;
1.547 + //The screen alpha blended data after calling of BitBltMasked() - will be filled after the call
1.548 + TUint8* screenBmpDestData1 = new (ELeave) TUint8[allocatedSize];
1.549 + CleanupStack::PushL(screenBmpDestData1);
1.550 + //The screen alpha blended data after calling of AlphaBlendingBitmaps() - will be filled after the call
1.551 + TUint8* screenBmpDestData2 = new (ELeave) TUint8[allocatedSize];
1.552 + CleanupStack::PushL(screenBmpDestData2);
1.553 + // Allow an effective restart of the test, since sometimes there are spurious
1.554 + // InfoPrints that affect the comparisons.
1.555 + for (TInt attempt = 0; res && (attempt < KMaximumAttempts); attempt++)
1.556 + {
1.557 + //Fill the blocks with some default value
1.558 + Mem::Fill(screenBmpDestData1, allocatedSize, 0xCA);
1.559 + Mem::Fill(screenBmpDestData2, allocatedSize, 0xCA);
1.560 + //Check screen bitmap size
1.561 + TSize screenBmpSize = aScreenBmp->SizeInPixels();
1.562 + if ((screenBmpSize.iWidth != KWidth) || (screenBmpSize.iHeight != KHeight))
1.563 + {
1.564 + _LIT(KScreenErr,"DoAlphaBlendingTestL test: w:%d!=%d || h:%d!=%d");
1.565 + INFO_PRINTF5(KScreenErr, screenBmpSize.iWidth, KWidth, screenBmpSize.iHeight, KHeight);
1.566 + TEST(EFalse);
1.567 + }
1.568 + // Alpha blending using CFbsBitGc::BitBltMasked //
1.569 + if (iExtraLogging2)
1.570 + {
1.571 + _LIT(KLog1," CFbsBitGc::BitBltMasked test");
1.572 + INFO_PRINTF1(KLog1);
1.573 + }
1.574 + //Screen bitmap rectangle
1.575 + screenBmpRc.SetRect(aDestPt, TSize(aSrcRc1.Width(), aSrcRc1.Height()));
1.576 +
1.577 + //Save screen bitmap
1.578 + TInt saveAttempts = 5;
1.579 + TInt err = aScreenBmp->Save(KScreenBmpFile);
1.580 + while ((err != KErrNone) && saveAttempts--)
1.581 + {
1.582 + // Retry the save
1.583 + _LIT(KSaveRetry,"DoAlphaBlendingTestL: Bitmap save failed, retrying.");
1.584 + INFO_PRINTF1(KSaveRetry);
1.585 + User::After(10000);
1.586 + err = aScreenBmp->Save(KScreenBmpFile);
1.587 + }
1.588 + User::LeaveIfError(err);
1.589 +
1.590 + User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
1.591 + //Draw screen bitmap
1.592 + iGc->Clear();
1.593 + iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
1.594 + iGc->DrawBitmap(screenBmpRc, aScreenBmp);
1.595 + iDevice->Update();
1.596 + //Do BitBltMasked()
1.597 + iGc->BitBltMasked(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, EFalse);
1.598 + iDevice->Update();
1.599 + //Get screen data and write the data to screenBmpDestData1.
1.600 + for(i=0;i<scrDevSize.iHeight;i++)
1.601 + {
1.602 + TPtr8 p(screenBmpDestData1 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
1.603 + iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
1.604 + }
1.605 + // Alpha blending using explicit form of CFbsBitGc::AlphaBlendBitmaps //
1.606 + if (iExtraLogging2)
1.607 + {
1.608 + _LIT(KLog2," CFbsBitGc::AlphaBlendBitmaps explicit test");
1.609 + INFO_PRINTF1(KLog2);
1.610 + }
1.611 + //Clear screen
1.612 + iGc->Clear();
1.613 + iDevice->Update();
1.614 + //Load screen bitmap
1.615 + User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
1.616 + //Do AlphaBlendBitmaps()
1.617 + User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aScreenBmp, aSrcRc1,
1.618 + aSrcPt2, aAlphaBmp, aAlphaPt));
1.619 + iDevice->Update();
1.620 + //Get screen data and write the data to screenBmpDestData2.
1.621 + for(i=0;i<scrDevSize.iHeight;i++)
1.622 + {
1.623 + TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
1.624 + iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
1.625 + }
1.626 + //Compare screen bitmaps //
1.627 + res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
1.628 +
1.629 + // colour comparison tolerance between RGB565 components.
1.630 + const TInt KColourComparisonTolerance = 2;
1.631 + if (res)
1.632 + {
1.633 + TBool testPassed = ETrue;
1.634 + // strict byte-for-byte comparison of the pixel maps could have failed because blending algorithms may
1.635 + // differ slightly, but actual resulting colours may be close enough
1.636 + for (int byteNumber = 0; byteNumber < allocatedSize; byteNumber+=2)
1.637 + {
1.638 + // find any RGB565 value that doesn't match and examine each component
1.639 + if ( *(TUint16*)(screenBmpDestData1 + byteNumber) != *(TUint16*)(screenBmpDestData2 + byteNumber))
1.640 + {
1.641 + TUint16 Rgb1 = *(TUint16*)(screenBmpDestData1 + byteNumber);
1.642 + TUint16 Rgb2 = *(TUint16*)(screenBmpDestData2 + byteNumber);
1.643 +
1.644 + TInt16 Red1 = (Rgb1 & 0xF800) >> 11;
1.645 + TInt16 Red2 = (Rgb2 & 0xF800) >> 11;
1.646 + TInt16 DiffRed = Abs(Red1 - Red2);
1.647 +
1.648 + TInt16 Green1 = (Rgb1 & 0x07E0) >> 5;
1.649 + TInt16 Green2 = (Rgb2 & 0x07E0) >> 5;
1.650 + TInt16 DiffGreen = Abs(Green1 - Green2);
1.651 +
1.652 + TInt16 Blue1 = (Rgb1 & 0x001F);
1.653 + TInt16 Blue2 = (Rgb2 & 0x001F);
1.654 + TInt16 DiffBlue = Abs(Blue1 - Blue2);
1.655 +
1.656 + // is any difference is outside the tolerance break out signaling test failure
1.657 + if (DiffRed > KColourComparisonTolerance ||
1.658 + DiffGreen > KColourComparisonTolerance ||
1.659 + DiffBlue > KColourComparisonTolerance)
1.660 + {
1.661 + testPassed = EFalse;
1.662 + break;
1.663 + }
1.664 + }
1.665 + }
1.666 + if (testPassed)
1.667 + {
1.668 + res = 0;
1.669 + }
1.670 + }
1.671 +
1.672 + if (res && (attempt < KMaximumAttempts - 1))
1.673 + {
1.674 + INFO_PRINTF1(_L("Memory comparison 1 failed, retrying"));
1.675 + // Skip to next attempt
1.676 + continue;
1.677 + }
1.678 + TEST(res == 0);
1.679 +
1.680 + // Alpha blending using implicit form of CFbsBitGc::AlphaBlendBitmaps //
1.681 + if (iExtraLogging2)
1.682 + {
1.683 + _LIT(KLog3," CFbsBitGc::AlphaBlendBitmaps implicit test");
1.684 + INFO_PRINTF1(KLog3);
1.685 + }
1.686 + //Clear screen
1.687 + iGc->Clear();
1.688 + iDevice->Update();
1.689 + //Draw screen bitmap (it's already loaded)
1.690 + User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
1.691 + iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
1.692 + iGc->DrawBitmap(screenBmpRc, aScreenBmp);
1.693 + iDevice->Update();
1.694 + //Do AlphaBlendBitmaps()
1.695 + User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, aSrcRc1.iTl));
1.696 + iDevice->Update();
1.697 + //Get screen data and write the data to screenBmpDestData2.
1.698 + for(i=0;i<scrDevSize.iHeight;i++)
1.699 + {
1.700 + TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
1.701 + iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
1.702 + }
1.703 + //Compare screen bitmaps //
1.704 + if (iExtraLogging2)
1.705 + {
1.706 + _LIT(KLog4," Compare Screen Bitmaps");
1.707 + INFO_PRINTF1(KLog4);
1.708 + }
1.709 + res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
1.710 +
1.711 + if (res && (attempt < KMaximumAttempts - 1))
1.712 + {
1.713 + INFO_PRINTF1(_L("Memory comparison 2 failed, retrying"));
1.714 + }
1.715 +
1.716 + // Reload the screen bitmap as it was before:
1.717 + User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
1.718 + }
1.719 + TEST(res == 0);
1.720 +
1.721 + //Destroy the allocated memory blocks
1.722 + CleanupStack::PopAndDestroy(2);//screenBmpDestData1 & screenBmpDestData2
1.723 + }
1.724 +
1.725 +void CTAlphaBlending::CreateAlphaBlendingBitmapsLC(CFbsBitmap*& aScreenBmp,
1.726 + CFbsBitmap*& aSrcBmp,
1.727 + CFbsBitmap*& aAlphaBmp,
1.728 + TDisplayMode aMode)
1.729 + {
1.730 + TInt i;
1.731 + TSize size(KWidth, KHeight);
1.732 + //The screen data
1.733 + TUint8 screenBmpSrcData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
1.734 + {//0 1 2 3 4 5 6 7 8 9
1.735 + {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},
1.736 + {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},
1.737 + {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}
1.738 + };
1.739 + //The source bitmap data
1.740 + TUint8 srcBmpData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
1.741 + {//0 1 2 3 4 5 6 7 8 9
1.742 + {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},
1.743 + {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},
1.744 + {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}
1.745 + };
1.746 + //The alpha bitmap data
1.747 + TUint8 alphaBmpData[KHeight][KWidth + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
1.748 + {//0 1 2 3 4 5 6 7 8 9
1.749 + {0x68, 0x68, 0x68, 0xAC, 0xD9, 0xB2, 0x8F, 0x11, 0xA0, 0xC1, 0x00, 0x00},
1.750 + {0x71, 0x5A, 0xF6, 0xEE, 0xF9, 0xE5, 0x06, 0x4C, 0xBB, 0x7B, 0x00, 0x00},
1.751 + {0x9F, 0x99, 0x45, 0x17, 0xA8, 0xF5, 0xFF, 0xD2, 0x22, 0x1D, 0x00, 0x00}
1.752 + };
1.753 +
1.754 + if(aMode == EColor16MU)
1.755 + {
1.756 +
1.757 + TInt buffer_size = KWidth * 4 ;
1.758 + TUint8* buffer = new(ELeave) TUint8[buffer_size];
1.759 + TPtr8 source_ptr(buffer, buffer_size, buffer_size);
1.760 +
1.761 + //Screen bitmap
1.762 + aScreenBmp = new (ELeave) CFbsBitmap;
1.763 + CleanupStack::PushL(aScreenBmp);
1.764 + User::LeaveIfError(aScreenBmp->Create(size, aMode));
1.765 + for(i=0; i<KHeight; i++)
1.766 + {
1.767 + TUint8* bufCur = buffer;
1.768 + TUint8* bufSrcCur = screenBmpSrcData[i];
1.769 + TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
1.770 + while(bufSrcCur < bufSrcEnd)
1.771 + {
1.772 + *bufCur++ = *bufSrcCur++;
1.773 + *bufCur++ = *bufSrcCur++;
1.774 + *bufCur++ = *bufSrcCur++;
1.775 + *bufCur++ = 0xff;
1.776 + }
1.777 + aScreenBmp->SetScanLine(source_ptr, i);
1.778 + }
1.779 +
1.780 + //Source bitmap
1.781 + aSrcBmp = new (ELeave) CFbsBitmap;
1.782 + CleanupStack::PushL(aSrcBmp);
1.783 + User::LeaveIfError(aSrcBmp->Create(size, aMode));
1.784 + for(i=0; i<KHeight; i++)
1.785 + {
1.786 + TUint8* bufCur = buffer;
1.787 + TUint8* bufSrcCur = srcBmpData[i];
1.788 + TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
1.789 + while(bufSrcCur < bufSrcEnd)
1.790 + {
1.791 + *bufCur++ = *bufSrcCur++;
1.792 + *bufCur++ = *bufSrcCur++;
1.793 + *bufCur++ = *bufSrcCur++;
1.794 + *bufCur++ = 0xff;
1.795 + }
1.796 + aSrcBmp->SetScanLine(source_ptr, i);
1.797 + }
1.798 +
1.799 +
1.800 + //Alpha bitmap
1.801 + aAlphaBmp = new (ELeave) CFbsBitmap;
1.802 + CleanupStack::PushL(aAlphaBmp);
1.803 + User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
1.804 + for(i=0;i<KHeight;i++)
1.805 + {
1.806 + TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
1.807 + aAlphaBmp->SetScanLine(p, i);
1.808 + }
1.809 +
1.810 + delete [] buffer;
1.811 + }
1.812 + else
1.813 + {
1.814 + //Screen bitmap
1.815 + aScreenBmp = new (ELeave) CFbsBitmap;
1.816 + CleanupStack::PushL(aScreenBmp);
1.817 + User::LeaveIfError(aScreenBmp->Create(size, aMode));
1.818 + for(i=0;i<KHeight;i++)
1.819 + {
1.820 + TPtr8 p(screenBmpSrcData[i], KWidth * 3, KWidth * 3);
1.821 + aScreenBmp->SetScanLine(p, i);
1.822 + }
1.823 + //Source bitmap
1.824 + aSrcBmp = new (ELeave) CFbsBitmap;
1.825 + CleanupStack::PushL(aSrcBmp);
1.826 + User::LeaveIfError(aSrcBmp->Create(size, aMode));
1.827 + for(i=0;i<KHeight;i++)
1.828 + {
1.829 + TPtr8 p(srcBmpData[i], KWidth * 3, KWidth * 3);
1.830 + aSrcBmp->SetScanLine(p, i);
1.831 + }
1.832 + //Alpha bitmap
1.833 + aAlphaBmp = new (ELeave) CFbsBitmap;
1.834 + CleanupStack::PushL(aAlphaBmp);
1.835 + User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
1.836 + for(i=0;i<KHeight;i++)
1.837 + {
1.838 + TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
1.839 + aAlphaBmp->SetScanLine(p, i);
1.840 + }
1.841 + }
1.842 + }
1.843 +
1.844 +void CTAlphaBlending::DestroyAlphaBlendingBitmaps(CFbsBitmap*& aScreenBmp,
1.845 + CFbsBitmap*& aSrcBmp,
1.846 + CFbsBitmap*& aAlphaBmp)
1.847 + {
1.848 + CleanupStack::PopAndDestroy(aAlphaBmp);
1.849 + aAlphaBmp = NULL;
1.850 + CleanupStack::PopAndDestroy(aSrcBmp);
1.851 + aSrcBmp = NULL;
1.852 + CleanupStack::PopAndDestroy(aScreenBmp);
1.853 + aScreenBmp = NULL;
1.854 + }
1.855 +
1.856 +//The test doesn't check anything. It is for debugging only.
1.857 +void CTAlphaBlending::TestAlphaBlending2L()
1.858 + {
1.859 + static const TDisplayMode modeList[] = {
1.860 + EColor64K, EColor256, EColor16MAP, EColor16MA, EColor16MU, EColor4K
1.861 + };
1.862 + const TInt KNumTestDisplayModes=sizeof(modeList)/sizeof(modeList[0]);
1.863 + for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
1.864 + {
1.865 + CFbsBitmap* srcBmp = NULL;
1.866 + CFbsBitmap* alphaBmp = NULL;
1.867 + TInt err = KErrNotSupported;
1.868 + // Try several modes
1.869 + for (TInt modeIndex = 0; (err != KErrNone) && modeIndex < KNumTestDisplayModes; modeIndex++)
1.870 + {
1.871 + err = CreateScreenDevice(modeList[modeIndex],(CFbsBitGc::TGraphicsOrientation)orientation);
1.872 + }
1.873 + if (err == KErrNotSupported)
1.874 + {
1.875 + // Orientation not supported, try next one
1.876 + continue;
1.877 + }
1.878 + TInt j;
1.879 + //The source bitmap data
1.880 + TUint8 srcBmpData[100];
1.881 + for(j=0;j<100;j++)
1.882 + {
1.883 + srcBmpData[j] = 0xAA;
1.884 + }
1.885 + //The alpha bitmap data
1.886 + TUint8 alphaBmpData[20];
1.887 + for(j=0;j<20;j++)
1.888 + {
1.889 + alphaBmpData[j] = TUint8(j);
1.890 + }
1.891 + //Source bitmap
1.892 + srcBmp = new (ELeave) CFbsBitmap;
1.893 + CleanupStack::PushL(srcBmp);
1.894 + User::LeaveIfError(srcBmp->Create(TSize(100, 1), EColor256));
1.895 + TPtr8 p1(srcBmpData, 100, 100);
1.896 + srcBmp->SetScanLine(p1, 0);
1.897 + //Alpha bitmap
1.898 + alphaBmp = new (ELeave) CFbsBitmap;
1.899 + CleanupStack::PushL(alphaBmp);
1.900 + User::LeaveIfError(alphaBmp->Create(TSize(20, 1), EGray256));
1.901 + TPtr8 p2(alphaBmpData, 20, 20);
1.902 + alphaBmp->SetScanLine(p2, 0);
1.903 + //Do BitBltMasked()
1.904 + iGc->BitBltMasked(TPoint(20, 20), srcBmp, TRect(10, 0, 100, 1), alphaBmp, EFalse);
1.905 + iDevice->Update();
1.906 + iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
1.907 + //
1.908 + CleanupStack::PopAndDestroy(alphaBmp);
1.909 + CleanupStack::PopAndDestroy(srcBmp);
1.910 + }
1.911 + }
1.912 +
1.913 +TUint32 AlphaBlend(TUint32 aDestPixel, TUint32 aSrcPixel, TUint8 aMask)
1.914 + {
1.915 + TUint32 dr = (aDestPixel & 0x00FF0000) >> 16;
1.916 + TUint32 dg = (aDestPixel & 0x0000FF00) >> 8;
1.917 + TUint32 db = aDestPixel & 0x000000FF;
1.918 +
1.919 + TUint32 sr = (aSrcPixel & 0x00FF0000) >> 16;
1.920 + TUint32 sg = (aSrcPixel & 0x0000FF00) >> 8;
1.921 + TUint32 sb = aSrcPixel & 0x000000FF;
1.922 +
1.923 + TUint32 rr = (aMask * sr)/255 + ((0xFF - aMask) * dr)/255;
1.924 + TUint32 rg = (aMask * sg)/255 + ((0xFF - aMask) * dg)/255;
1.925 + TUint32 rb = (aMask * sb)/255 + ((0xFF - aMask) * db)/255;
1.926 +
1.927 + return(rr << 16 | rg << 8 | rb | 0xff000000);
1.928 + }
1.929 +
1.930 +inline TUint32 OptimizedBlend32(TInt aPrimaryRed,TInt aPrimaryGreen,TInt aPrimaryBlue,TUint32 aSecondary,TUint8 aAlphaValue)
1.931 + {
1.932 +
1.933 + if(aAlphaValue == 0xff)
1.934 + {
1.935 + return (aPrimaryBlue + (aPrimaryGreen<<8) + (aPrimaryRed<<16)) | 0xff000000;
1.936 + }
1.937 + else
1.938 + {
1.939 + const TUint32 alphaValue = (aAlphaValue << 8) + aAlphaValue;
1.940 +
1.941 + const TInt r2 = (aSecondary & 0x00ff0000) >> 16;
1.942 + const TInt g2 = (aSecondary & 0x0000ff00) >> 8;
1.943 + const TInt b2 = aSecondary & 0x000000ff;
1.944 +
1.945 + const TInt r3 = ((alphaValue * (aPrimaryRed - r2)) >> 16) + r2;
1.946 + const TInt g3 = ((alphaValue * (aPrimaryGreen - g2)) >> 16) + g2;
1.947 + const TInt b3 = ((alphaValue * (aPrimaryBlue - b2)) >> 16) + b2;
1.948 +
1.949 + return (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
1.950 + }
1.951 + }
1.952 +
1.953 +
1.954 +/**
1.955 + @SYMTestCaseID GRAPHICS-BITGDI-0085
1.956 +
1.957 + @SYMDEF
1.958 +
1.959 + @SYMTestCaseDesc
1.960 +
1.961 + @SYMTestPriority High
1.962 +
1.963 + @SYMTestStatus Implemented
1.964 +
1.965 + @SYMTestActions
1.966 +
1.967 + @SYMTestExpectedResults
1.968 +*/
1.969 +// This tests the correctness of the results of alpha-blending with EColor16MA
1.970 +void CTAlphaBlending::TestAlphaBlendCorrect(TDisplayMode /* aScreenMode */, TDisplayMode /* aBitmapMode */)
1.971 + {
1.972 + // test data
1.973 + TUint32 top = 0xFFCCEE55;
1.974 + TUint32 beneath = 0xFFEEAA66;
1.975 + TUint8 alpha = 0xF0;
1.976 +
1.977 + TInt maxDiff = 0;
1.978 +
1.979 + for(TInt i = 0; i < 100000; i++)
1.980 + {
1.981 + top = Math::Random();
1.982 + beneath = Math::Random();
1.983 + alpha = Math::Random();
1.984 + TUint32 res1 = AlphaBlend(beneath, top, alpha);
1.985 + TUint32 res2 = OptimizedBlend32((top >> 16) & 0xFF,(top >>8) & 0xFF,(top & 0xFF),beneath, alpha);
1.986 +
1.987 + if(res1 != res2)
1.988 + {
1.989 + TInt diff = 0;
1.990 + TInt diff1 = res1 & 0xFF;
1.991 + TInt diff2 = res2 & 0xFF;
1.992 +
1.993 + diff = diff1 - diff2;
1.994 +
1.995 + if(diff < 0)
1.996 + diff*=-1;
1.997 +
1.998 + if(diff > maxDiff)
1.999 + maxDiff = diff;
1.1000 +
1.1001 + diff1 = (res1 >> 8) & 0xFF;
1.1002 + diff2 = (res2 >> 8) & 0xFF;
1.1003 +
1.1004 + diff = diff1 - diff2;
1.1005 +
1.1006 + if(diff < 0)
1.1007 + diff*=-1;
1.1008 +
1.1009 + if(diff > maxDiff)
1.1010 + maxDiff = diff;
1.1011 +
1.1012 +
1.1013 + diff1 = (res1 >> 16) & 0xFF;
1.1014 + diff2 = (res2 >> 16) & 0xFF;
1.1015 +
1.1016 + diff = diff1 - diff2;
1.1017 +
1.1018 + if(diff < 0)
1.1019 + diff*=-1;
1.1020 +
1.1021 + if(diff > maxDiff)
1.1022 + maxDiff = diff;
1.1023 +
1.1024 + }
1.1025 + }
1.1026 +
1.1027 + INFO_PRINTF1(_L("Results:"));
1.1028 +
1.1029 + if(maxDiff)
1.1030 + INFO_PRINTF2(_L("Max Diff = %i"), maxDiff);
1.1031 + else
1.1032 + INFO_PRINTF1(_L("Results are identical"));
1.1033 + }
1.1034 +
1.1035 +//--------------
1.1036 +__CONSTRUCT_STEP__(AlphaBlending)
1.1037 +
1.1038 +void CTAlphaBlendingStep::TestSetupL()
1.1039 + {
1.1040 + }
1.1041 +