windowing/windowserver/test/t_stress/src/comparison.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @test
       
    19  @internalComponent
       
    20 */
       
    21  
       
    22 
       
    23 #include <e32std.h>
       
    24 #include <fbs.h>
       
    25 
       
    26 #include "test_step_logger.h"
       
    27 #include "comparison.h"
       
    28 #include "utils.h"
       
    29 #include "compwin.h"
       
    30 #include "crpwin.h"
       
    31 #include "edgedwin.h"
       
    32 #include "coordinatewin.h"
       
    33 #include "backedupwin.h"
       
    34 #include "enormouswin.h"
       
    35 #include "animatedwin.h"
       
    36 #include "spritewin.h"
       
    37 #include "panic.h"
       
    38 
       
    39 
       
    40 const TInt KSteps = 10;
       
    41 
       
    42 CComparison::COperationTimer::COperationTimer(CComparison* aComp):CTimer(0), iComp(aComp)
       
    43 {}
       
    44 
       
    45 void CComparison::COperationTimer::ConstructL()
       
    46 	{
       
    47 	CTimer::ConstructL();
       
    48 	}
       
    49 
       
    50 void CComparison::COperationTimer::DoCancel()
       
    51 	{}
       
    52 
       
    53 void CComparison::COperationTimer::RunL()
       
    54 	{
       
    55 	iComp->Tick();
       
    56 	}
       
    57 
       
    58 
       
    59 /*-------------------------------------------------------------------------*/
       
    60 // COneShotCompare
       
    61 CComparison::COneShotCompare* CComparison::COneShotCompare::NewL(TInt aPriority, CComparison& aComparison)
       
    62 	{
       
    63 	return new(ELeave)CComparison::COneShotCompare(aPriority, aComparison);
       
    64 	}
       
    65 
       
    66 CComparison::COneShotCompare::COneShotCompare(TInt aPriority, CComparison& aComparison)
       
    67 	:CAsyncOneShot(aPriority), iComparison(aComparison)
       
    68 	{
       
    69 	}
       
    70 
       
    71 void CComparison::COneShotCompare::RunL()
       
    72 	{
       
    73 	iComparison.iScreen->CopyScreenToBitmap(iComparison.iScreenBitmap);
       
    74 	iComparison.SetVerifyTick(User::NTickCount());
       
    75 	iComparison.Verify(iComparison.iScreenBitmap);
       
    76 	}
       
    77 /*-------------------------------------------------------------------------*/
       
    78 
       
    79 _LIT(KConfigurationWindowSuffix, "-Window");
       
    80 
       
    81 /*******************************************************************************
       
    82 This is the stresslet itself
       
    83 *******************************************************************************/
       
    84 CComparison * CComparison::NewLC(MTestStepReporter& aReporter)
       
    85 	{
       
    86 	CComparison * self = new (ELeave) CComparison(aReporter);
       
    87 	CleanupStack::PushL(self);
       
    88 	self->ConstructL();
       
    89 	return self;
       
    90 	}
       
    91 
       
    92 void CComparison::ConstructL()
       
    93 	{
       
    94 	iWatchCat = CTestExecWatchCat::NewL( CExecutionContext::ECtxRandomAndRecord );
       
    95 	}
       
    96 
       
    97 CComparison::CComparison (MTestStepReporter& aReporter):
       
    98 	CStresslet(aReporter), iDifferenceBitmap(NULL), iDifferenceDevice(NULL), iOneShotCompare(NULL)
       
    99 	{
       
   100 	}
       
   101 
       
   102 /**
       
   103  Sets stress-test configuration (read from ini file).
       
   104  @param aRunData configuration data
       
   105  @param aConfFactory a factory interface for creating "section" readers. These
       
   106  are used to supply configuration data for each window type.
       
   107  */
       
   108 void CComparison::SetRunDataL(const TRunData& aRunData, MTestStepConfigurationContextFactory* aConfFactory)
       
   109 	{
       
   110 	iData = aRunData;
       
   111 	User::LeaveIfError(iFs.Connect());
       
   112 	iFs.MkDirAll(iData.loggingPath);
       
   113 	iWatchCat->SetLoggingPathL(iData.loggingPath);
       
   114 
       
   115 	//each window type can have its own configuration
       
   116 	MTestStepConfigurationContext* context; //context created by the factory argument
       
   117 	RBuf section; //section name (window-type + "-window"
       
   118 	section.Create(32);
       
   119 	CleanupStack::PushL(&section);
       
   120 
       
   121 	struct STestStepConfEntry
       
   122 		{
       
   123 		const TPtrC8 iType;	//section name
       
   124 		void (*iFunc)(const MTestStepConfigurationContext*); //configuration loader
       
   125 		} confLoaders[] = 
       
   126 		{
       
   127 			{KCommonWindowType(),    CCompWin::LoadConfiguration},
       
   128 			{KAnimatedWindowType(),   CAnimatedWin::LoadConfiguration},
       
   129 			{KBackedupWindowType(),   CBackedupWin::LoadConfiguration},
       
   130 			{KCoordinateWindowType(), CCoordinateWin::LoadConfiguration},
       
   131 			{KCrpWindowType(),        CCrpWin::LoadConfiguration},
       
   132 			{KEdgedWindowType(),      CEdgedWin::LoadConfiguration},
       
   133 			{KEnormousWindowType(),   CEnormousWin::LoadConfiguration},
       
   134 			{KSpritedWindowType(),    CSpritedWin::LoadConfiguration}
       
   135 		};
       
   136 
       
   137 	for (int i=0; i<sizeof(confLoaders)/sizeof(STestStepConfEntry); i++)
       
   138 		{
       
   139 		section.Copy(confLoaders[i].iType);
       
   140 		section.Append(KConfigurationWindowSuffix);
       
   141 		context = aConfFactory->GetConfigurationContextLC(section);
       
   142 		confLoaders[i].iFunc(context);
       
   143 		CleanupStack::PopAndDestroy(context);
       
   144 		}
       
   145 	
       
   146 	CleanupStack::Pop(&section);
       
   147 	}
       
   148 
       
   149 void CComparison::StartL()
       
   150 	{
       
   151 	iStartTime.UniversalTime();
       
   152 	if (iData.randomSeed > -1)
       
   153 		{
       
   154 		//use seed from ini file
       
   155 		iFirstSeed = iData.randomSeed;
       
   156 		}
       
   157 	else 
       
   158 		{
       
   159 		// randomize seed by time
       
   160 		iFirstSeed = iStartTime.Int64();
       
   161 		}
       
   162 	TRnd::SetSeed(iFirstSeed);
       
   163 	
       
   164 	iWasOk = ETrue;
       
   165 	iMode = EAct;
       
   166 	iErrorNum = 0;
       
   167 	iWinGroup=new(ELeave) RWindowGroup(Session());
       
   168 	User::LeaveIfError(iWinGroup->Construct( (TUint32)(iWinGroup) ));
       
   169 	iWinGroup->SetOrdinalPosition(0,0);
       
   170 
       
   171 	//make sure at least minNumWindows are created, or if it's zero no limit
       
   172 	iNumWindowsLeft = iData.minNumWindows;
       
   173 
       
   174 	iScreen = new (ELeave) CWsScreenDevice(Session());	
       
   175 	User::LeaveIfError(iScreen->Construct(0));
       
   176 	TDisplayMode screenMode = iScreen->DisplayMode();
       
   177 	
       
   178 	iScreenBitmap = new (ELeave) CFbsBitmap;
       
   179 	iScreenBitmap->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode);
       
   180 	
       
   181 	iBackground = new(ELeave) RBlankWindow(Session());
       
   182 	iBackground->Construct(*iWinGroup,reinterpret_cast<TUint32>(iBackground));
       
   183 	iBackground->SetColor(KRgbBlack);
       
   184 	iBackground->SetExtent(TPoint(0,0), TSize(iData.windowWidth, iData.windowHeight));
       
   185 	iBackground->SetOrdinalPosition(0);
       
   186 	iBackground->Activate();
       
   187 
       
   188 	iCurrentBmp = 0;
       
   189 	iLastBmp = 1;
       
   190 	iBmpGc = CFbsBitGc::NewL();
       
   191 	for (TInt bmp = 0; bmp < 2; ++bmp)
       
   192 		{
       
   193 		iBitmap[bmp] = new (ELeave) CFbsBitmap;
       
   194 		iBitmap[bmp]->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode); //EColor16MU); //
       
   195 		iDevice[bmp] = CFbsBitmapDevice::NewL(iBitmap[bmp]);
       
   196 		//clear bitmap background
       
   197 		iBmpGc->Activate(iDevice[bmp]);
       
   198 		iBmpGc->Reset();
       
   199 		iBmpGc->SetPenStyle(CGraphicsContext::ENullPen);
       
   200 		iBmpGc->SetBrushColor(KRgbBlack);
       
   201 		iBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   202 		TPoint origin(0,0);
       
   203 		TRect rect(origin, TSize(iData.windowWidth, iData.windowHeight));
       
   204 		iBmpGc->DrawRect(rect);
       
   205 		}
       
   206 
       
   207 	iDifferenceBitmap = new (ELeave) CFbsBitmap;
       
   208 	iDifferenceBitmap->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode); //EColor16MU); //
       
   209 	iDifferenceDevice = CFbsBitmapDevice::NewL(iDifferenceBitmap);
       
   210 
       
   211 	iTimer = new(ELeave) COperationTimer(this);
       
   212 	iTimer->ConstructL();
       
   213 	CActiveScheduler::Add (iTimer);
       
   214 	iTimer->After(iData.initPeriod);
       
   215 	}
       
   216 
       
   217 /**
       
   218  Simulate a Left key stroke
       
   219  */
       
   220 void CComparison::Touch()
       
   221 	{
       
   222 	User::ResetInactivityTime();
       
   223 
       
   224 	TRawEvent keyDown;  
       
   225 	keyDown.Set(TRawEvent::EKeyDown,EStdKeyLeftArrow);
       
   226 	Session().SimulateRawEvent(keyDown);
       
   227 	
       
   228 	TRawEvent keyUp;
       
   229 	keyUp.Set(TRawEvent::EKeyUp,EStdKeyLeftArrow);
       
   230 	Session().SimulateRawEvent(keyUp);
       
   231 	}
       
   232 
       
   233 /**
       
   234  Non leaving version of TickL that reports failures
       
   235  */
       
   236 TInt CComparison::Tick()
       
   237 	{
       
   238 	TRAPD(err, TickL());
       
   239 	if (err)
       
   240 		{
       
   241 		REPORT_EVENT( EFalse );
       
   242 		}
       
   243 	return err;
       
   244 	}
       
   245 
       
   246 /**
       
   247  Called periodically 
       
   248  */
       
   249 void CComparison::TickL()
       
   250 	{
       
   251 	if (iMustConclude)
       
   252 		{
       
   253 		WriteLog();
       
   254 		ConcludeNow();
       
   255 		return;
       
   256 		}
       
   257 	if (0 == iTestNum % 100)
       
   258 		{
       
   259 		Touch();
       
   260 		}
       
   261 	DoStuffL();
       
   262 	if (iStuffDone)
       
   263 		{
       
   264 		++iTestNum;
       
   265 		}
       
   266 	}
       
   267 
       
   268 /**
       
   269  Dispatch work to selected operation by mode
       
   270  */
       
   271 void CComparison::DoStuffL()
       
   272 	{
       
   273 	iStuffDone = EFalse;
       
   274 	switch (iMode)
       
   275 		{
       
   276 		case EAct:
       
   277 			ActL();
       
   278 			break;
       
   279 		case EMove:
       
   280 			MoveL();
       
   281 			break;
       
   282 		case EResize:
       
   283 			ResizeL();
       
   284 			break;
       
   285 		};
       
   286 	if (iWasOk && iData.compareBitmaps && iStuffDone)
       
   287 		{
       
   288 		Session().Flush();
       
   289 		// schedule a delayed compare, will take place after all updates to windows
       
   290 		if (iOneShotCompare == NULL)
       
   291 			{
       
   292 			iOneShotCompare = CComparison::COneShotCompare::NewL(EPriorityMuchLess, *this);
       
   293 			}
       
   294 		iOneShotCompare->Call();
       
   295 		}
       
   296 	else
       
   297 		{
       
   298 		if (iTestNum > iData.maxRunCycles && iNumWindowsLeft == 0)
       
   299 			{
       
   300 			iMustConclude = ETrue;
       
   301 			}
       
   302 		iTimer->After(iData.period);
       
   303 		}
       
   304 	Session().Flush();
       
   305 
       
   306 	Session().Finish(); 
       
   307 	}
       
   308 	
       
   309 /**
       
   310  Performs a random operation on a random window
       
   311  Operation can be one of create, destroy, move, bring to front/back,
       
   312  resize, tick, toggle-visibility
       
   313  */
       
   314 void CComparison::ActL()
       
   315 	{
       
   316 	TInt action = TRnd::rnd(EACount);
       
   317 	if (iWindows.Count() == 0)
       
   318 		{
       
   319 		action = 0;
       
   320 		}
       
   321 	
       
   322 	iBehaviour.iWin = RandomWindow();
       
   323 	iAct = static_cast<TAct>(action);
       
   324 	switch(iAct)
       
   325 		{
       
   326 		case EACreate:
       
   327 			CreateWindowL();
       
   328 			break;
       
   329 		case EADestroy:
       
   330 			DestroyWindow();
       
   331 			break;
       
   332 		case EAMove:
       
   333 			MoveWindow();
       
   334 			break;
       
   335 		case EAFront:
       
   336 			BringWindowToFrontL();
       
   337 			break;
       
   338 		case EABack:
       
   339 			SendWindowToBackL();
       
   340 			break;
       
   341 		case EAResize:
       
   342 			ResizeWindow();
       
   343 			break;
       
   344 		case EATick:
       
   345 			TickWindowL();
       
   346 			break;
       
   347 		case EAToggleVisible:
       
   348 			ToggleVisible();
       
   349 			break;
       
   350 		} //lint !e787 enum constant TAct::EACount not used within switch
       
   351 	}
       
   352 
       
   353 void CComparison::MoveL()
       
   354 	{
       
   355 	if (iBehaviour.iCount < 1)
       
   356 		{
       
   357 		iMode = EAct;
       
   358 		}
       
   359 	else
       
   360 		{
       
   361 		TPoint pos = iBehaviour.iWin->Pos() + iBehaviour.iPos;
       
   362 		iBehaviour.iWin->SetPos(pos);
       
   363 		--iBehaviour.iCount;
       
   364 		iStuffDone = ETrue;
       
   365 		}
       
   366 	}
       
   367 
       
   368 void CComparison::ResizeL()
       
   369 	{
       
   370 	if (iBehaviour.iCount < 1)
       
   371 		{
       
   372 		iMode = EAct;
       
   373 		}
       
   374 	else
       
   375 		{
       
   376 		TSize size = iBehaviour.iWin->Size();
       
   377 		size.iWidth += iBehaviour.iPos.iX;
       
   378 		size.iHeight += iBehaviour.iPos.iY;
       
   379 		iBehaviour.iWin->SetSize(size);
       
   380 		--iBehaviour.iCount;
       
   381 		iStuffDone = ETrue;
       
   382 		}
       
   383 	}
       
   384 
       
   385 /**
       
   386  Sets the position for a future window-move command, the actual move will be 
       
   387  done in the next step 
       
   388  */
       
   389 void CComparison::MoveWindow()
       
   390 	{
       
   391 	__UHEAP_MARK;
       
   392 	if (iBehaviour.iWin)
       
   393 		{
       
   394 		TPoint pos = TPoint(TRnd::rnd(KPosLimit), TRnd::rnd(KPosLimit));
       
   395 		pos.iX -= iBehaviour.iWin->Size().iWidth / 2;
       
   396 		pos.iY -= iBehaviour.iWin->Size().iHeight / 2;
       
   397 		iBehaviour.iPos = pos - iBehaviour.iWin->Pos();
       
   398 		iBehaviour.iCount = KSteps;
       
   399 		iBehaviour.iPos.iX /= iBehaviour.iCount;
       
   400 		iBehaviour.iPos.iY /= iBehaviour.iCount;
       
   401 		iMode = EMove;
       
   402 		}
       
   403 	__UHEAP_MARKEND;
       
   404 	}
       
   405 
       
   406 /**
       
   407  Sets the size for a future window-resize command, the actual resize will be 
       
   408  done in the next step 
       
   409  */
       
   410 void CComparison::ResizeWindow()
       
   411 	{
       
   412 	__UHEAP_MARK;
       
   413 	if (iBehaviour.iWin)
       
   414 		{
       
   415 		TPoint newsize = TPoint(TRnd::rnd(KPosLimit), TRnd::rnd(KPosLimit));
       
   416 		TPoint oldsize;
       
   417 		oldsize.iX = iBehaviour.iWin->Size().iWidth;
       
   418 		oldsize.iY = iBehaviour.iWin->Size().iHeight;
       
   419 		iBehaviour.iPos = newsize - oldsize;
       
   420 		iBehaviour.iCount = KSteps;
       
   421 		iBehaviour.iPos.iX /= iBehaviour.iCount;
       
   422 		iBehaviour.iPos.iY /= iBehaviour.iCount;
       
   423 		iMode = EResize;
       
   424 		}
       
   425 	__UHEAP_MARKEND;
       
   426 	}
       
   427 
       
   428 void CComparison::BringWindowToFrontL()
       
   429 	{
       
   430 	__UHEAP_MARK;
       
   431 	CCompWin* win = iBehaviour.iWin;
       
   432 	if (win)
       
   433 		{
       
   434 		win->BringToFrontL();
       
   435 		TInt pos = FindTopWindow(win);
       
   436 		if (pos >= 0)
       
   437 			{
       
   438 			iWindows.Remove(pos);
       
   439 			iWindows.Append(win);
       
   440 			}
       
   441 		iStuffDone = ETrue;
       
   442 		}
       
   443 	__UHEAP_MARKEND;
       
   444 	}
       
   445 	
       
   446 void CComparison::SendWindowToBackL()
       
   447 	{
       
   448 	__UHEAP_MARK;
       
   449 	TInt ord = iBackground->OrdinalPosition();
       
   450 	if (ord > 0)
       
   451 		{
       
   452 		CCompWin* win = iBehaviour.iWin;
       
   453 		if (win)
       
   454 			{
       
   455 			TInt pos = FindTopWindow(win);
       
   456 			if (pos >= 0)
       
   457 				{
       
   458 				iWindows.Remove(pos);
       
   459 				iWindows.Insert(win, 0);
       
   460 				win->Window()->SetOrdinalPosition(ord - 1);
       
   461 				}
       
   462 			else
       
   463 				{
       
   464 				win->SendToBackL();
       
   465 				}
       
   466 			iStuffDone = ETrue;
       
   467 			}
       
   468 		}
       
   469 	__UHEAP_MARKEND;
       
   470 	}
       
   471 
       
   472 TInt CComparison::FindTopWindow(CCompWin* win)
       
   473 	{
       
   474 	return iWindows.Find(win);
       
   475 	}
       
   476 	
       
   477 /**
       
   478  Returns a random window (which may be a NULL window)
       
   479 */
       
   480 CCompWin * CComparison::RandomWindow()
       
   481 	{
       
   482 	if (iWindows.Count() == 0)
       
   483 		{
       
   484 		return 0;
       
   485 		}
       
   486 	
       
   487 	TInt num = TRnd::rnd(iWindows.Count() + 1);
       
   488 	
       
   489 	if (num == iWindows.Count())
       
   490 		{
       
   491 		return 0;
       
   492 		}
       
   493 	else
       
   494 		{
       
   495 		return iWindows[num]->RandomWindow();
       
   496 		}
       
   497 	}
       
   498 
       
   499 void CComparison::CreateWindowL()
       
   500 	{
       
   501 	CCompWin* parent = iBehaviour.iWin;
       
   502 	CCompWin* win = CCompWin::NewLC(Session(), iWinGroup, parent, WindowGc());
       
   503 	iBehaviour.iWin = win;
       
   504 	if (!parent)
       
   505 		{
       
   506 		iWindows.AppendL(win);
       
   507 		}
       
   508 	CleanupStack::Pop(win);
       
   509 	if (iNumWindowsLeft > 0)	//decrement window count
       
   510 		{
       
   511 		--iNumWindowsLeft;
       
   512 		}
       
   513 	iStuffDone = ETrue;
       
   514 	}	
       
   515 
       
   516 void CComparison::DestroyWindow()
       
   517 	{
       
   518 	CCompWin* win = iBehaviour.iWin;
       
   519 	if (win)
       
   520 		{
       
   521 		TInt num = iWindows.Find(win);
       
   522 		if (num != KErrNotFound)
       
   523 			{
       
   524 			iWindows.Remove(num);
       
   525 			}
       
   526 		delete win;
       
   527 		iBehaviour.iWin = 0; // rby added
       
   528 		iStuffDone = ETrue;
       
   529 		}
       
   530 	}	
       
   531 
       
   532 void CComparison::TickWindowL()
       
   533 	{
       
   534 	CCompWin* win = iBehaviour.iWin;
       
   535 	if (win)
       
   536 		{
       
   537 		if (win->TickL())
       
   538 			{
       
   539 			iStuffDone = ETrue;
       
   540 			}
       
   541 		}
       
   542 	}
       
   543 	
       
   544 void CComparison::ToggleVisible()
       
   545 	{
       
   546 	__UHEAP_MARK;
       
   547 	CCompWin* win = iBehaviour.iWin;
       
   548 	if (win)
       
   549 		{
       
   550 		win->ToggleVisible();
       
   551 		iStuffDone = ETrue;
       
   552 		}
       
   553 	__UHEAP_MARKEND;
       
   554 	}
       
   555 
       
   556 void CComparison::HandleRedraw(TWsRedrawEvent &aEvent)
       
   557 	{
       
   558 	__UHEAP_MARK;
       
   559 	if (aEvent.Handle() != reinterpret_cast<TUint32>(iBackground))
       
   560 		{
       
   561 		reinterpret_cast<CCompWin*>(aEvent.Handle())->HandleRedraw(aEvent);
       
   562 		}
       
   563 	Session().Flush();
       
   564 	__UHEAP_MARKEND;
       
   565 	}
       
   566 
       
   567 void CComparison::HandleEvent(TWsEvent &/*aEvent*/)
       
   568 	{	
       
   569 	}
       
   570 
       
   571 /**
       
   572  Compares two bitmaps. Comparison is done on a pixel-by-pixel basis.
       
   573  If the bitmaps are of different sizes, the smaller axis of each is used for
       
   574  comparison (top-left subregions).
       
   575  First different pixel is stored in internally.
       
   576  @return ETrue if bitmaps match, EFalse otherwise.
       
   577 */
       
   578 TBool CComparison::BitmapsMatch(const CFbsBitmap * aBitmap1, const CFbsBitmap * aBitmap2)
       
   579 	{
       
   580 	TDisplayMode mode1 = aBitmap1->DisplayMode();
       
   581 	TDisplayMode mode2 = aBitmap2->DisplayMode();
       
   582 	
       
   583 	TSize bmpSize = aBitmap1->SizeInPixels();
       
   584 	TSize bmpSize2 = aBitmap2->SizeInPixels();
       
   585 	if (bmpSize2.iWidth < bmpSize.iWidth)
       
   586 		{
       
   587 		bmpSize.iWidth = bmpSize2.iWidth;
       
   588 		}
       
   589 	if (bmpSize2.iHeight < bmpSize.iHeight)
       
   590 		{
       
   591 		bmpSize.iHeight = bmpSize2.iHeight;
       
   592 		}
       
   593 	
       
   594 	TRgb c1;
       
   595 	TRgb c2;
       
   596 	for (TInt y=0; y < bmpSize.iHeight; y++)
       
   597 		{
       
   598 		for (TInt x=0; x < bmpSize.iWidth; x++)
       
   599 			{
       
   600 			TPoint point(x, y);
       
   601 			aBitmap1->GetPixel(c1, point);
       
   602 			aBitmap2->GetPixel(c2, point);
       
   603 			if (c1 != c2)
       
   604        			{
       
   605        			iPixel1 = c1.Value();
       
   606        			iPixel2 = c2.Value();
       
   607        			iPixelPos = point;
       
   608 				return EFalse;
       
   609 				}
       
   610 			}		
       
   611 		}
       
   612 	return ETrue;		
       
   613 	}
       
   614 void CComparison::Verify(CFbsBitmap * aServerBmp)
       
   615 	{	
       
   616 	//Copy the currentBmp to lastBmp
       
   617 	TInt dataStride = iBitmap[iCurrentBmp]->DataStride();
       
   618 	TInt sizeInByte = dataStride * iBitmap[iCurrentBmp]->SizeInPixels().iHeight;
       
   619 	TUint32* bitmapAddressSource = iBitmap[iCurrentBmp]->DataAddress();
       
   620 	TUint32* bitmapAddressTarget = iBitmap[iLastBmp]->DataAddress();
       
   621 	memcpy(bitmapAddressTarget, bitmapAddressSource, sizeInByte);
       
   622 	// This method is only used by the animation and sprite windows; ignores 
       
   623 	// comparisons for times that are too close to the sprite change. But as the 
       
   624 	// difference error drifts, there is no point relying on it.
       
   625 	if (!WindowsReadyForVerification())
       
   626 		{
       
   627 		Tick();
       
   628 		return;
       
   629 		}
       
   630 
       
   631 	if (iWasOk)
       
   632 		{
       
   633 		DrawBitmap();
       
   634 		
       
   635 		const TBool bmpMatch = BitmapsMatch(aServerBmp, iBitmap[iCurrentBmp]);
       
   636 		REPORT_EVENT( bmpMatch );
       
   637 		
       
   638 #ifdef __WINSCW__		
       
   639 		if ( !bmpMatch )
       
   640 			{
       
   641 			__DEBUGGER();
       
   642 			}
       
   643 #endif
       
   644 		
       
   645 		if (!iData.saveOnlyDifferent || !bmpMatch)
       
   646 			{
       
   647 			TBuf<128> fileName;
       
   648 			fileName.Append(iData.loggingPath);
       
   649 			fileName.Append(_L("Stresslet_Comparison_"));
       
   650 			if (iData.saveOnlyDifferent)
       
   651 				{
       
   652 				fileName.AppendNumFixedWidthUC((TUint)iErrorNum, EDecimal, 3);
       
   653 				}
       
   654 			else
       
   655 				{
       
   656 				fileName.AppendNumFixedWidthUC((TUint)iTestNum, EDecimal, 3);
       
   657 				}
       
   658 			TInt baseLength = fileName.Length();
       
   659 			
       
   660 			//previous is saved only when saving different bitmaps 
       
   661 			//otherwise it is always the same as the previous expected
       
   662 			if (iData.saveOnlyDifferent)
       
   663 				{
       
   664 				fileName.Append(_L("_Previous.mbm"));
       
   665 				__ASSERT_ALWAYS(KErrNone == iBitmap[iLastBmp]->Save(fileName), Panic(EPanic6));
       
   666 				}
       
   667 			
       
   668 			fileName.SetLength(baseLength);
       
   669 			fileName.Append(_L("_Expected.mbm"));
       
   670 			__ASSERT_ALWAYS(KErrNone == iBitmap[iCurrentBmp]->Save(fileName), Panic(EPanic7));
       
   671 			
       
   672 			fileName.SetLength(baseLength);
       
   673 			fileName.Append(_L("_Screen.mbm"));
       
   674 			__ASSERT_ALWAYS(KErrNone == aServerBmp->Save(fileName), Panic(EPanic8));
       
   675 
       
   676 			//store difference between expected and screen bitmaps (XOR image)
       
   677 			if (iData.saveDifferenceBitmap)
       
   678 				{
       
   679 				iBmpGc->Activate(iDifferenceDevice);
       
   680 				iBmpGc->Reset();
       
   681 				iBmpGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
       
   682 				iBmpGc->BitBlt(TPoint(0,0), iBitmap[iCurrentBmp]);
       
   683 				iBmpGc->SetDrawMode(CGraphicsContext::EDrawModeXOR);
       
   684 				iBmpGc->BitBlt(TPoint(0,0), aServerBmp);
       
   685 				iBmpGc->Reset();
       
   686 				fileName.SetLength(baseLength);
       
   687 				fileName.Append(_L("_Difference.mbm"));
       
   688 				__ASSERT_ALWAYS(KErrNone == iDifferenceBitmap->Save(fileName), Panic(EPanic19));
       
   689 				}
       
   690 			
       
   691 			fileName.SetLength(baseLength);
       
   692 			fileName.Append(_L("_info.txt"));
       
   693 			RFile file;
       
   694 			TInt err = file.Create(iFs, fileName, EFileWrite);
       
   695 			if (err != KErrNone)
       
   696 				err = file.Replace(iFs, fileName, EFileWrite);
       
   697 			if (err == KErrNone)
       
   698 				{
       
   699 				TBuf8<128> info;
       
   700 				info.Append(_L8("Seed = "));
       
   701 				info.AppendNum(iFirstSeed);
       
   702 				info.Append(_L8("\n"));
       
   703 				file.Write(info);
       
   704 				info.SetLength(0);
       
   705 				TTime now;
       
   706 				now.UniversalTime();
       
   707 				info.Append(_L8(" Runtime = "));
       
   708 				info.AppendNum(now.MicroSecondsFrom(iStartTime).Int64() / 1000);
       
   709 				info.Append(_L8(" ms\r\n"));
       
   710 				file.Write(info);
       
   711 				info.SetLength(0);
       
   712 				info.Append(_L8("Action = ["));
       
   713 				info.AppendNum((TInt64)iAct);
       
   714 				info.Append(_L8("]   Mode = ["));
       
   715 				info.AppendNum((TInt64)iMode);
       
   716 				info.Append(_L8("]   Test = ["));
       
   717 				info.AppendNum((TInt64)iTestNum);
       
   718 				info.Append(_L8("]\r\n"));
       
   719 				file.Write(info);
       
   720 				info.SetLength(0);
       
   721 				info.Append(_L8("Pixel at ["));
       
   722 				info.AppendNum((TInt64)iPixelPos.iX);
       
   723 				info.Append(_L8(","));
       
   724 				info.AppendNum((TInt64)iPixelPos.iY);
       
   725 				info.Append(_L8("] mismatch screen 0x"));
       
   726 				info.AppendNum((TInt64)iPixel1, EHex);
       
   727 				info.Append(_L8(" != bitmap 0x"));
       
   728 				info.AppendNum((TInt64)iPixel2, EHex);
       
   729 				info.Append(_L8("\r\n\r\n"));
       
   730 				file.Write(info);
       
   731 				
       
   732 				TPoint zero(0,0);
       
   733 				for (TInt num = 0; num < iWindows.Count(); ++num)
       
   734 					{
       
   735 					iWindows[num]->Dump(file, zero, 0, iBehaviour.iWin);
       
   736 					info.SetLength(0);
       
   737 					info.Append(_L8("\r\n"));
       
   738 					file.Write(info);
       
   739 					}				
       
   740 				file.Close();
       
   741 				}
       
   742 			else
       
   743 				{
       
   744 				//failed create logfile
       
   745 				__ASSERT_ALWAYS(EFalse, Panic(EPanic9));
       
   746 				}
       
   747 			
       
   748 			if (!bmpMatch)
       
   749 				{
       
   750 				++iErrorNum;
       
   751 				}
       
   752 			}
       
   753 		}	
       
   754 	if ((iTestNum > iData.maxRunCycles && iNumWindowsLeft == 0) || !iWasOk)
       
   755 		{
       
   756 		iMustConclude = ETrue;
       
   757 		}
       
   758 	iTimer->After(iData.period);
       
   759 	}
       
   760 
       
   761 /**
       
   762 Write information(eg. seed, starttime, endtime and time elapse) to Stresslet_Log.txt file 
       
   763 */
       
   764 void CComparison::WriteLog()
       
   765 	{
       
   766 	TBuf<128> fileName;
       
   767 	fileName.Append(iData.loggingPath);
       
   768 	fileName.Append(_L("Stresslet_Log.txt"));
       
   769 	RFile file;
       
   770 	TInt err = file.Create(iFs, fileName, EFileWrite);
       
   771 	if (err != KErrNone)
       
   772 		{
       
   773 		err = file.Replace(iFs, fileName, EFileWrite);
       
   774 		}
       
   775 	if (err == KErrNone)
       
   776 		{
       
   777 		TBuf8<128> info;
       
   778 		info.Append(_L8("Seed = "));
       
   779 		info.AppendNum(iFirstSeed);
       
   780 		info.Append(_L8("\r\n"));
       
   781 		file.Write(info);
       
   782 		info.SetLength(0);
       
   783 		TBuf<40> dateTimeString;
       
   784 	    _LIT(KFormat2,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
       
   785 	    iStartTime.FormatL(dateTimeString,KFormat2);
       
   786 		info.Append(_L8("StartTime = "));
       
   787 		info.Append(dateTimeString);
       
   788 		info.Append(_L8("\r\n"));
       
   789 		TTime now;
       
   790 		now.UniversalTime();
       
   791 		now.FormatL(dateTimeString,KFormat2);
       
   792 		info.Append(_L8("Endtime = "));
       
   793 		info.Append(dateTimeString);
       
   794 		info.Append(_L8("\r\n"));
       
   795 		info.Append(_L8("Elapse = "));
       
   796 		info.AppendNum(now.MicroSecondsFrom(iStartTime).Int64() / 1000);
       
   797 		info.Append(_L8(" ms\r\n"));
       
   798 		file.Write(info);
       
   799 		file.Close();
       
   800 		}
       
   801 	}
       
   802 /**
       
   803  Returns true if all visible windows are ready for verification
       
   804  */
       
   805 TBool CComparison::WindowsReadyForVerification() const
       
   806 	{
       
   807 	TBool res = ETrue;
       
   808 	TInt idx = 0;
       
   809 	while ( idx < iWindows.Count() && res )
       
   810 		{
       
   811 		if ( iWindows[ idx ]->IsVisible() )
       
   812 			{
       
   813 			res = iWindows[ idx ]->QueryReadyForVerification();
       
   814 			}
       
   815 		idx++;
       
   816 		}
       
   817 	return res;
       
   818 	}
       
   819 
       
   820 /**
       
   821  Calls all windows to draw themselves on a bitmap
       
   822  */
       
   823 void CComparison::DrawBitmap()
       
   824 	{
       
   825 	iBmpGc->Activate(iDevice[iCurrentBmp]);
       
   826 	iBmpGc->Reset();
       
   827 
       
   828 	// clear background area
       
   829 	iBmpGc->SetPenStyle(CGraphicsContext::ENullPen);
       
   830 	iBmpGc->SetBrushColor(KRgbBlack);
       
   831 	iBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   832 
       
   833 	TPoint origin(0,0);
       
   834 	TRect rect(origin, TSize(iData.windowWidth, iData.windowHeight));
       
   835 
       
   836 	//create a region containing all screen, subtract all visible windows
       
   837 	RRegion backClipping(rect);
       
   838 	if (!iData.clearAllBackground)
       
   839 		{
       
   840 		for (TInt num = 0; num < iWindows.Count(); ++num)
       
   841 			{
       
   842 			if (iWindows[num]->IsVisible())
       
   843 				iWindows[num]->SubSelfFromRegion(backClipping, rect, origin);
       
   844 			}
       
   845 		}
       
   846 	
       
   847 	//clip drawing to background only & clear
       
   848 	iBmpGc->SetClippingRegion(backClipping);
       
   849 	iBmpGc->DrawRect(rect);
       
   850 	//go back to no clipping
       
   851 	iBmpGc->CancelClipping();
       
   852 	backClipping.Close();
       
   853 
       
   854 	for (TInt num = 0; num < iWindows.Count(); ++num)
       
   855 		{
       
   856 		if (iWindows[num]->IsVisible())
       
   857 			{
       
   858 			iWindows[num]->ClearBitmapBackground(iBmpGc, rect, origin);
       
   859 			iWindows[num]->DrawBitmap(iBmpGc, rect, origin);
       
   860 			}
       
   861 		}
       
   862 	}
       
   863 	
       
   864 void CComparison::SetVerifyTick(TUint32 aTick)
       
   865 	{
       
   866 	for (TInt num = 0; num < iWindows.Count(); ++num)
       
   867 		{
       
   868 		if (iWindows[num]->IsVisible())
       
   869 			iWindows[num]->SetVerifyTick(aTick);
       
   870 		}
       
   871 	}
       
   872 
       
   873 CComparison::~CComparison()
       
   874 	{
       
   875 	iFs.Close();
       
   876 	
       
   877 	if (iBackground)
       
   878 		{
       
   879 		iBackground->Close();
       
   880 		delete iBackground;
       
   881 		}	
       
   882 	
       
   883 	iWindows.ResetAndDestroy();
       
   884 	if (iWinGroup)
       
   885 		{
       
   886 		iWinGroup->Close();
       
   887 		delete iWinGroup;
       
   888 		}
       
   889 
       
   890 	delete iOneShotCompare; //delayed compare
       
   891 
       
   892 	delete iDifferenceDevice;
       
   893 	delete iDifferenceBitmap;
       
   894 	
       
   895 	for (TInt bmp = 0; bmp < 2; ++bmp)
       
   896 		{
       
   897 		delete iDevice[bmp];
       
   898 		delete iBitmap[bmp];
       
   899 		}
       
   900 	
       
   901 	delete iBmpGc;
       
   902 	delete iTimer;
       
   903 
       
   904 	delete iScreenBitmap;
       
   905 	delete iScreen;
       
   906 	}