diff -r 000000000000 -r 5d03bc08d59c windowing/windowserver/test/t_stress/src/comparison.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/test/t_stress/src/comparison.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,906 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +/** + @file + @test + @internalComponent +*/ + + +#include +#include + +#include "test_step_logger.h" +#include "comparison.h" +#include "utils.h" +#include "compwin.h" +#include "crpwin.h" +#include "edgedwin.h" +#include "coordinatewin.h" +#include "backedupwin.h" +#include "enormouswin.h" +#include "animatedwin.h" +#include "spritewin.h" +#include "panic.h" + + +const TInt KSteps = 10; + +CComparison::COperationTimer::COperationTimer(CComparison* aComp):CTimer(0), iComp(aComp) +{} + +void CComparison::COperationTimer::ConstructL() + { + CTimer::ConstructL(); + } + +void CComparison::COperationTimer::DoCancel() + {} + +void CComparison::COperationTimer::RunL() + { + iComp->Tick(); + } + + +/*-------------------------------------------------------------------------*/ +// COneShotCompare +CComparison::COneShotCompare* CComparison::COneShotCompare::NewL(TInt aPriority, CComparison& aComparison) + { + return new(ELeave)CComparison::COneShotCompare(aPriority, aComparison); + } + +CComparison::COneShotCompare::COneShotCompare(TInt aPriority, CComparison& aComparison) + :CAsyncOneShot(aPriority), iComparison(aComparison) + { + } + +void CComparison::COneShotCompare::RunL() + { + iComparison.iScreen->CopyScreenToBitmap(iComparison.iScreenBitmap); + iComparison.SetVerifyTick(User::NTickCount()); + iComparison.Verify(iComparison.iScreenBitmap); + } +/*-------------------------------------------------------------------------*/ + +_LIT(KConfigurationWindowSuffix, "-Window"); + +/******************************************************************************* +This is the stresslet itself +*******************************************************************************/ +CComparison * CComparison::NewLC(MTestStepReporter& aReporter) + { + CComparison * self = new (ELeave) CComparison(aReporter); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CComparison::ConstructL() + { + iWatchCat = CTestExecWatchCat::NewL( CExecutionContext::ECtxRandomAndRecord ); + } + +CComparison::CComparison (MTestStepReporter& aReporter): + CStresslet(aReporter), iDifferenceBitmap(NULL), iDifferenceDevice(NULL), iOneShotCompare(NULL) + { + } + +/** + Sets stress-test configuration (read from ini file). + @param aRunData configuration data + @param aConfFactory a factory interface for creating "section" readers. These + are used to supply configuration data for each window type. + */ +void CComparison::SetRunDataL(const TRunData& aRunData, MTestStepConfigurationContextFactory* aConfFactory) + { + iData = aRunData; + User::LeaveIfError(iFs.Connect()); + iFs.MkDirAll(iData.loggingPath); + iWatchCat->SetLoggingPathL(iData.loggingPath); + + //each window type can have its own configuration + MTestStepConfigurationContext* context; //context created by the factory argument + RBuf section; //section name (window-type + "-window" + section.Create(32); + CleanupStack::PushL(§ion); + + struct STestStepConfEntry + { + const TPtrC8 iType; //section name + void (*iFunc)(const MTestStepConfigurationContext*); //configuration loader + } confLoaders[] = + { + {KCommonWindowType(), CCompWin::LoadConfiguration}, + {KAnimatedWindowType(), CAnimatedWin::LoadConfiguration}, + {KBackedupWindowType(), CBackedupWin::LoadConfiguration}, + {KCoordinateWindowType(), CCoordinateWin::LoadConfiguration}, + {KCrpWindowType(), CCrpWin::LoadConfiguration}, + {KEdgedWindowType(), CEdgedWin::LoadConfiguration}, + {KEnormousWindowType(), CEnormousWin::LoadConfiguration}, + {KSpritedWindowType(), CSpritedWin::LoadConfiguration} + }; + + for (int i=0; iGetConfigurationContextLC(section); + confLoaders[i].iFunc(context); + CleanupStack::PopAndDestroy(context); + } + + CleanupStack::Pop(§ion); + } + +void CComparison::StartL() + { + iStartTime.UniversalTime(); + if (iData.randomSeed > -1) + { + //use seed from ini file + iFirstSeed = iData.randomSeed; + } + else + { + // randomize seed by time + iFirstSeed = iStartTime.Int64(); + } + TRnd::SetSeed(iFirstSeed); + + iWasOk = ETrue; + iMode = EAct; + iErrorNum = 0; + iWinGroup=new(ELeave) RWindowGroup(Session()); + User::LeaveIfError(iWinGroup->Construct( (TUint32)(iWinGroup) )); + iWinGroup->SetOrdinalPosition(0,0); + + //make sure at least minNumWindows are created, or if it's zero no limit + iNumWindowsLeft = iData.minNumWindows; + + iScreen = new (ELeave) CWsScreenDevice(Session()); + User::LeaveIfError(iScreen->Construct(0)); + TDisplayMode screenMode = iScreen->DisplayMode(); + + iScreenBitmap = new (ELeave) CFbsBitmap; + iScreenBitmap->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode); + + iBackground = new(ELeave) RBlankWindow(Session()); + iBackground->Construct(*iWinGroup,reinterpret_cast(iBackground)); + iBackground->SetColor(KRgbBlack); + iBackground->SetExtent(TPoint(0,0), TSize(iData.windowWidth, iData.windowHeight)); + iBackground->SetOrdinalPosition(0); + iBackground->Activate(); + + iCurrentBmp = 0; + iLastBmp = 1; + iBmpGc = CFbsBitGc::NewL(); + for (TInt bmp = 0; bmp < 2; ++bmp) + { + iBitmap[bmp] = new (ELeave) CFbsBitmap; + iBitmap[bmp]->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode); //EColor16MU); // + iDevice[bmp] = CFbsBitmapDevice::NewL(iBitmap[bmp]); + //clear bitmap background + iBmpGc->Activate(iDevice[bmp]); + iBmpGc->Reset(); + iBmpGc->SetPenStyle(CGraphicsContext::ENullPen); + iBmpGc->SetBrushColor(KRgbBlack); + iBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + TPoint origin(0,0); + TRect rect(origin, TSize(iData.windowWidth, iData.windowHeight)); + iBmpGc->DrawRect(rect); + } + + iDifferenceBitmap = new (ELeave) CFbsBitmap; + iDifferenceBitmap->Create(TSize(iData.windowWidth, iData.windowHeight), screenMode); //EColor16MU); // + iDifferenceDevice = CFbsBitmapDevice::NewL(iDifferenceBitmap); + + iTimer = new(ELeave) COperationTimer(this); + iTimer->ConstructL(); + CActiveScheduler::Add (iTimer); + iTimer->After(iData.initPeriod); + } + +/** + Simulate a Left key stroke + */ +void CComparison::Touch() + { + User::ResetInactivityTime(); + + TRawEvent keyDown; + keyDown.Set(TRawEvent::EKeyDown,EStdKeyLeftArrow); + Session().SimulateRawEvent(keyDown); + + TRawEvent keyUp; + keyUp.Set(TRawEvent::EKeyUp,EStdKeyLeftArrow); + Session().SimulateRawEvent(keyUp); + } + +/** + Non leaving version of TickL that reports failures + */ +TInt CComparison::Tick() + { + TRAPD(err, TickL()); + if (err) + { + REPORT_EVENT( EFalse ); + } + return err; + } + +/** + Called periodically + */ +void CComparison::TickL() + { + if (iMustConclude) + { + WriteLog(); + ConcludeNow(); + return; + } + if (0 == iTestNum % 100) + { + Touch(); + } + DoStuffL(); + if (iStuffDone) + { + ++iTestNum; + } + } + +/** + Dispatch work to selected operation by mode + */ +void CComparison::DoStuffL() + { + iStuffDone = EFalse; + switch (iMode) + { + case EAct: + ActL(); + break; + case EMove: + MoveL(); + break; + case EResize: + ResizeL(); + break; + }; + if (iWasOk && iData.compareBitmaps && iStuffDone) + { + Session().Flush(); + // schedule a delayed compare, will take place after all updates to windows + if (iOneShotCompare == NULL) + { + iOneShotCompare = CComparison::COneShotCompare::NewL(EPriorityMuchLess, *this); + } + iOneShotCompare->Call(); + } + else + { + if (iTestNum > iData.maxRunCycles && iNumWindowsLeft == 0) + { + iMustConclude = ETrue; + } + iTimer->After(iData.period); + } + Session().Flush(); + + Session().Finish(); + } + +/** + Performs a random operation on a random window + Operation can be one of create, destroy, move, bring to front/back, + resize, tick, toggle-visibility + */ +void CComparison::ActL() + { + TInt action = TRnd::rnd(EACount); + if (iWindows.Count() == 0) + { + action = 0; + } + + iBehaviour.iWin = RandomWindow(); + iAct = static_cast(action); + switch(iAct) + { + case EACreate: + CreateWindowL(); + break; + case EADestroy: + DestroyWindow(); + break; + case EAMove: + MoveWindow(); + break; + case EAFront: + BringWindowToFrontL(); + break; + case EABack: + SendWindowToBackL(); + break; + case EAResize: + ResizeWindow(); + break; + case EATick: + TickWindowL(); + break; + case EAToggleVisible: + ToggleVisible(); + break; + } //lint !e787 enum constant TAct::EACount not used within switch + } + +void CComparison::MoveL() + { + if (iBehaviour.iCount < 1) + { + iMode = EAct; + } + else + { + TPoint pos = iBehaviour.iWin->Pos() + iBehaviour.iPos; + iBehaviour.iWin->SetPos(pos); + --iBehaviour.iCount; + iStuffDone = ETrue; + } + } + +void CComparison::ResizeL() + { + if (iBehaviour.iCount < 1) + { + iMode = EAct; + } + else + { + TSize size = iBehaviour.iWin->Size(); + size.iWidth += iBehaviour.iPos.iX; + size.iHeight += iBehaviour.iPos.iY; + iBehaviour.iWin->SetSize(size); + --iBehaviour.iCount; + iStuffDone = ETrue; + } + } + +/** + Sets the position for a future window-move command, the actual move will be + done in the next step + */ +void CComparison::MoveWindow() + { + __UHEAP_MARK; + if (iBehaviour.iWin) + { + TPoint pos = TPoint(TRnd::rnd(KPosLimit), TRnd::rnd(KPosLimit)); + pos.iX -= iBehaviour.iWin->Size().iWidth / 2; + pos.iY -= iBehaviour.iWin->Size().iHeight / 2; + iBehaviour.iPos = pos - iBehaviour.iWin->Pos(); + iBehaviour.iCount = KSteps; + iBehaviour.iPos.iX /= iBehaviour.iCount; + iBehaviour.iPos.iY /= iBehaviour.iCount; + iMode = EMove; + } + __UHEAP_MARKEND; + } + +/** + Sets the size for a future window-resize command, the actual resize will be + done in the next step + */ +void CComparison::ResizeWindow() + { + __UHEAP_MARK; + if (iBehaviour.iWin) + { + TPoint newsize = TPoint(TRnd::rnd(KPosLimit), TRnd::rnd(KPosLimit)); + TPoint oldsize; + oldsize.iX = iBehaviour.iWin->Size().iWidth; + oldsize.iY = iBehaviour.iWin->Size().iHeight; + iBehaviour.iPos = newsize - oldsize; + iBehaviour.iCount = KSteps; + iBehaviour.iPos.iX /= iBehaviour.iCount; + iBehaviour.iPos.iY /= iBehaviour.iCount; + iMode = EResize; + } + __UHEAP_MARKEND; + } + +void CComparison::BringWindowToFrontL() + { + __UHEAP_MARK; + CCompWin* win = iBehaviour.iWin; + if (win) + { + win->BringToFrontL(); + TInt pos = FindTopWindow(win); + if (pos >= 0) + { + iWindows.Remove(pos); + iWindows.Append(win); + } + iStuffDone = ETrue; + } + __UHEAP_MARKEND; + } + +void CComparison::SendWindowToBackL() + { + __UHEAP_MARK; + TInt ord = iBackground->OrdinalPosition(); + if (ord > 0) + { + CCompWin* win = iBehaviour.iWin; + if (win) + { + TInt pos = FindTopWindow(win); + if (pos >= 0) + { + iWindows.Remove(pos); + iWindows.Insert(win, 0); + win->Window()->SetOrdinalPosition(ord - 1); + } + else + { + win->SendToBackL(); + } + iStuffDone = ETrue; + } + } + __UHEAP_MARKEND; + } + +TInt CComparison::FindTopWindow(CCompWin* win) + { + return iWindows.Find(win); + } + +/** + Returns a random window (which may be a NULL window) +*/ +CCompWin * CComparison::RandomWindow() + { + if (iWindows.Count() == 0) + { + return 0; + } + + TInt num = TRnd::rnd(iWindows.Count() + 1); + + if (num == iWindows.Count()) + { + return 0; + } + else + { + return iWindows[num]->RandomWindow(); + } + } + +void CComparison::CreateWindowL() + { + CCompWin* parent = iBehaviour.iWin; + CCompWin* win = CCompWin::NewLC(Session(), iWinGroup, parent, WindowGc()); + iBehaviour.iWin = win; + if (!parent) + { + iWindows.AppendL(win); + } + CleanupStack::Pop(win); + if (iNumWindowsLeft > 0) //decrement window count + { + --iNumWindowsLeft; + } + iStuffDone = ETrue; + } + +void CComparison::DestroyWindow() + { + CCompWin* win = iBehaviour.iWin; + if (win) + { + TInt num = iWindows.Find(win); + if (num != KErrNotFound) + { + iWindows.Remove(num); + } + delete win; + iBehaviour.iWin = 0; // rby added + iStuffDone = ETrue; + } + } + +void CComparison::TickWindowL() + { + CCompWin* win = iBehaviour.iWin; + if (win) + { + if (win->TickL()) + { + iStuffDone = ETrue; + } + } + } + +void CComparison::ToggleVisible() + { + __UHEAP_MARK; + CCompWin* win = iBehaviour.iWin; + if (win) + { + win->ToggleVisible(); + iStuffDone = ETrue; + } + __UHEAP_MARKEND; + } + +void CComparison::HandleRedraw(TWsRedrawEvent &aEvent) + { + __UHEAP_MARK; + if (aEvent.Handle() != reinterpret_cast(iBackground)) + { + reinterpret_cast(aEvent.Handle())->HandleRedraw(aEvent); + } + Session().Flush(); + __UHEAP_MARKEND; + } + +void CComparison::HandleEvent(TWsEvent &/*aEvent*/) + { + } + +/** + Compares two bitmaps. Comparison is done on a pixel-by-pixel basis. + If the bitmaps are of different sizes, the smaller axis of each is used for + comparison (top-left subregions). + First different pixel is stored in internally. + @return ETrue if bitmaps match, EFalse otherwise. +*/ +TBool CComparison::BitmapsMatch(const CFbsBitmap * aBitmap1, const CFbsBitmap * aBitmap2) + { + TDisplayMode mode1 = aBitmap1->DisplayMode(); + TDisplayMode mode2 = aBitmap2->DisplayMode(); + + TSize bmpSize = aBitmap1->SizeInPixels(); + TSize bmpSize2 = aBitmap2->SizeInPixels(); + if (bmpSize2.iWidth < bmpSize.iWidth) + { + bmpSize.iWidth = bmpSize2.iWidth; + } + if (bmpSize2.iHeight < bmpSize.iHeight) + { + bmpSize.iHeight = bmpSize2.iHeight; + } + + TRgb c1; + TRgb c2; + for (TInt y=0; y < bmpSize.iHeight; y++) + { + for (TInt x=0; x < bmpSize.iWidth; x++) + { + TPoint point(x, y); + aBitmap1->GetPixel(c1, point); + aBitmap2->GetPixel(c2, point); + if (c1 != c2) + { + iPixel1 = c1.Value(); + iPixel2 = c2.Value(); + iPixelPos = point; + return EFalse; + } + } + } + return ETrue; + } +void CComparison::Verify(CFbsBitmap * aServerBmp) + { + //Copy the currentBmp to lastBmp + TInt dataStride = iBitmap[iCurrentBmp]->DataStride(); + TInt sizeInByte = dataStride * iBitmap[iCurrentBmp]->SizeInPixels().iHeight; + TUint32* bitmapAddressSource = iBitmap[iCurrentBmp]->DataAddress(); + TUint32* bitmapAddressTarget = iBitmap[iLastBmp]->DataAddress(); + memcpy(bitmapAddressTarget, bitmapAddressSource, sizeInByte); + // This method is only used by the animation and sprite windows; ignores + // comparisons for times that are too close to the sprite change. But as the + // difference error drifts, there is no point relying on it. + if (!WindowsReadyForVerification()) + { + Tick(); + return; + } + + if (iWasOk) + { + DrawBitmap(); + + const TBool bmpMatch = BitmapsMatch(aServerBmp, iBitmap[iCurrentBmp]); + REPORT_EVENT( bmpMatch ); + +#ifdef __WINSCW__ + if ( !bmpMatch ) + { + __DEBUGGER(); + } +#endif + + if (!iData.saveOnlyDifferent || !bmpMatch) + { + TBuf<128> fileName; + fileName.Append(iData.loggingPath); + fileName.Append(_L("Stresslet_Comparison_")); + if (iData.saveOnlyDifferent) + { + fileName.AppendNumFixedWidthUC((TUint)iErrorNum, EDecimal, 3); + } + else + { + fileName.AppendNumFixedWidthUC((TUint)iTestNum, EDecimal, 3); + } + TInt baseLength = fileName.Length(); + + //previous is saved only when saving different bitmaps + //otherwise it is always the same as the previous expected + if (iData.saveOnlyDifferent) + { + fileName.Append(_L("_Previous.mbm")); + __ASSERT_ALWAYS(KErrNone == iBitmap[iLastBmp]->Save(fileName), Panic(EPanic6)); + } + + fileName.SetLength(baseLength); + fileName.Append(_L("_Expected.mbm")); + __ASSERT_ALWAYS(KErrNone == iBitmap[iCurrentBmp]->Save(fileName), Panic(EPanic7)); + + fileName.SetLength(baseLength); + fileName.Append(_L("_Screen.mbm")); + __ASSERT_ALWAYS(KErrNone == aServerBmp->Save(fileName), Panic(EPanic8)); + + //store difference between expected and screen bitmaps (XOR image) + if (iData.saveDifferenceBitmap) + { + iBmpGc->Activate(iDifferenceDevice); + iBmpGc->Reset(); + iBmpGc->SetDrawMode(CGraphicsContext::EDrawModePEN); + iBmpGc->BitBlt(TPoint(0,0), iBitmap[iCurrentBmp]); + iBmpGc->SetDrawMode(CGraphicsContext::EDrawModeXOR); + iBmpGc->BitBlt(TPoint(0,0), aServerBmp); + iBmpGc->Reset(); + fileName.SetLength(baseLength); + fileName.Append(_L("_Difference.mbm")); + __ASSERT_ALWAYS(KErrNone == iDifferenceBitmap->Save(fileName), Panic(EPanic19)); + } + + fileName.SetLength(baseLength); + fileName.Append(_L("_info.txt")); + RFile file; + TInt err = file.Create(iFs, fileName, EFileWrite); + if (err != KErrNone) + err = file.Replace(iFs, fileName, EFileWrite); + if (err == KErrNone) + { + TBuf8<128> info; + info.Append(_L8("Seed = ")); + info.AppendNum(iFirstSeed); + info.Append(_L8("\n")); + file.Write(info); + info.SetLength(0); + TTime now; + now.UniversalTime(); + info.Append(_L8(" Runtime = ")); + info.AppendNum(now.MicroSecondsFrom(iStartTime).Int64() / 1000); + info.Append(_L8(" ms\r\n")); + file.Write(info); + info.SetLength(0); + info.Append(_L8("Action = [")); + info.AppendNum((TInt64)iAct); + info.Append(_L8("] Mode = [")); + info.AppendNum((TInt64)iMode); + info.Append(_L8("] Test = [")); + info.AppendNum((TInt64)iTestNum); + info.Append(_L8("]\r\n")); + file.Write(info); + info.SetLength(0); + info.Append(_L8("Pixel at [")); + info.AppendNum((TInt64)iPixelPos.iX); + info.Append(_L8(",")); + info.AppendNum((TInt64)iPixelPos.iY); + info.Append(_L8("] mismatch screen 0x")); + info.AppendNum((TInt64)iPixel1, EHex); + info.Append(_L8(" != bitmap 0x")); + info.AppendNum((TInt64)iPixel2, EHex); + info.Append(_L8("\r\n\r\n")); + file.Write(info); + + TPoint zero(0,0); + for (TInt num = 0; num < iWindows.Count(); ++num) + { + iWindows[num]->Dump(file, zero, 0, iBehaviour.iWin); + info.SetLength(0); + info.Append(_L8("\r\n")); + file.Write(info); + } + file.Close(); + } + else + { + //failed create logfile + __ASSERT_ALWAYS(EFalse, Panic(EPanic9)); + } + + if (!bmpMatch) + { + ++iErrorNum; + } + } + } + if ((iTestNum > iData.maxRunCycles && iNumWindowsLeft == 0) || !iWasOk) + { + iMustConclude = ETrue; + } + iTimer->After(iData.period); + } + +/** +Write information(eg. seed, starttime, endtime and time elapse) to Stresslet_Log.txt file +*/ +void CComparison::WriteLog() + { + TBuf<128> fileName; + fileName.Append(iData.loggingPath); + fileName.Append(_L("Stresslet_Log.txt")); + RFile file; + TInt err = file.Create(iFs, fileName, EFileWrite); + if (err != KErrNone) + { + err = file.Replace(iFs, fileName, EFileWrite); + } + if (err == KErrNone) + { + TBuf8<128> info; + info.Append(_L8("Seed = ")); + info.AppendNum(iFirstSeed); + info.Append(_L8("\r\n")); + file.Write(info); + info.SetLength(0); + TBuf<40> dateTimeString; + _LIT(KFormat2,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3"); + iStartTime.FormatL(dateTimeString,KFormat2); + info.Append(_L8("StartTime = ")); + info.Append(dateTimeString); + info.Append(_L8("\r\n")); + TTime now; + now.UniversalTime(); + now.FormatL(dateTimeString,KFormat2); + info.Append(_L8("Endtime = ")); + info.Append(dateTimeString); + info.Append(_L8("\r\n")); + info.Append(_L8("Elapse = ")); + info.AppendNum(now.MicroSecondsFrom(iStartTime).Int64() / 1000); + info.Append(_L8(" ms\r\n")); + file.Write(info); + file.Close(); + } + } +/** + Returns true if all visible windows are ready for verification + */ +TBool CComparison::WindowsReadyForVerification() const + { + TBool res = ETrue; + TInt idx = 0; + while ( idx < iWindows.Count() && res ) + { + if ( iWindows[ idx ]->IsVisible() ) + { + res = iWindows[ idx ]->QueryReadyForVerification(); + } + idx++; + } + return res; + } + +/** + Calls all windows to draw themselves on a bitmap + */ +void CComparison::DrawBitmap() + { + iBmpGc->Activate(iDevice[iCurrentBmp]); + iBmpGc->Reset(); + + // clear background area + iBmpGc->SetPenStyle(CGraphicsContext::ENullPen); + iBmpGc->SetBrushColor(KRgbBlack); + iBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + + TPoint origin(0,0); + TRect rect(origin, TSize(iData.windowWidth, iData.windowHeight)); + + //create a region containing all screen, subtract all visible windows + RRegion backClipping(rect); + if (!iData.clearAllBackground) + { + for (TInt num = 0; num < iWindows.Count(); ++num) + { + if (iWindows[num]->IsVisible()) + iWindows[num]->SubSelfFromRegion(backClipping, rect, origin); + } + } + + //clip drawing to background only & clear + iBmpGc->SetClippingRegion(backClipping); + iBmpGc->DrawRect(rect); + //go back to no clipping + iBmpGc->CancelClipping(); + backClipping.Close(); + + for (TInt num = 0; num < iWindows.Count(); ++num) + { + if (iWindows[num]->IsVisible()) + { + iWindows[num]->ClearBitmapBackground(iBmpGc, rect, origin); + iWindows[num]->DrawBitmap(iBmpGc, rect, origin); + } + } + } + +void CComparison::SetVerifyTick(TUint32 aTick) + { + for (TInt num = 0; num < iWindows.Count(); ++num) + { + if (iWindows[num]->IsVisible()) + iWindows[num]->SetVerifyTick(aTick); + } + } + +CComparison::~CComparison() + { + iFs.Close(); + + if (iBackground) + { + iBackground->Close(); + delete iBackground; + } + + iWindows.ResetAndDestroy(); + if (iWinGroup) + { + iWinGroup->Close(); + delete iWinGroup; + } + + delete iOneShotCompare; //delayed compare + + delete iDifferenceDevice; + delete iDifferenceBitmap; + + for (TInt bmp = 0; bmp < 2; ++bmp) + { + delete iDevice[bmp]; + delete iBitmap[bmp]; + } + + delete iBmpGc; + delete iTimer; + + delete iScreenBitmap; + delete iScreen; + }