diff -r bf7481649c98 -r 2717213c588a windowing/windowserver/test/tdynamicres/src/wsdynamicresbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/test/tdynamicres/src/wsdynamicresbase.cpp Tue Jun 22 15:21:29 2010 +0300 @@ -0,0 +1,603 @@ +// 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: +// + +#include +#include "wsdynamicresbase.h" +#include "teflogextensions.h" +#include "globalsettings.h" +#include +#include +#include +#include +#include "regionextend.h" + + +#if defined(__X86GCC__) +extern "C" TInt atexit(void (*function)(void)) + { + return KErrNone; + } +#endif + +CWsDynamicResBase::CWsDynamicResBase(): + iUtility(this) + { + } + +CWsDynamicResBase::~CWsDynamicResBase() + { + } + +/** +Common set up code for all tests. + +Creates the session and window group for further windows, plus a simple white +background to obscure any unwanted stuff behind the test. Sets up the surface +update session and surface manager, to work with surfaces. Creates a screen +device for use in the tests. +*/ +void CWsDynamicResBase::SetupL() + { + SetupL(EFalse); + } +void CWsDynamicResBase::SetupL(TBool aUseOtherScreenForInfo) + { + CWsDynamicResWinBase::SetupL(aUseOtherScreenForInfo); + + +//clean-up if previous test abended + if (PostTestCleanupInstance().iSharedUtility) + { +//Temp removed - may be causing ONB fails! +// if (PostTestCleanupInstance().iSharedUtility->DestroyAll()) +// { +// INFO_PRINTF1(_L("Destroyed some surfaces from previous test.")); +// +// } + } + if (!PostTestCleanupInstance().iCleanedUpOnExit) + PostTestCleanupInstance().iCleanedUpOnExit=EFalse; + + if (!GCEIsSupported()) + { + INFO_PRINTF1(_L("Some Setup skipped: GCE support is not loaded")); + return; + } + + TRAPD(err_FailedToCreateSurfaceUtility, iUtility = CSurfaceUtility::NewL( PostTestCleanupInstance().iSharedUtility)); + ASSERT_EQUALS(err_FailedToCreateSurfaceUtility,KErrNone); + + + } + +/** +Common tear down code for all tests. + +Windows, group and session created are closed. Screen device is destroyed. +Surfaces, manager and update session are closed. +*/ +void CWsDynamicResBase::TearDownL() + { + CWsDynamicResWinBase::TearDownL(); + delete iUtility(); + PostTestCleanupInstance().iCleanedUpOnExit=ETrue; + //Pause(1000); + } +/** + * Note that this is not the ideal mechanism. + * A derived class may thinks its TearDown is safe to do from delete, but in the class it is derived from it may not be safe + **/ +void CWsDynamicResBase::TearDownFromDeleteL() + { + CWsDynamicResBase::TearDownL(); + } + +//Allocating an instance of surface utility here means all test code instances will share the same instance of the utility class. +// Owns the singleton +/*static*/ const CWsDynamicResBase::TPostTestCleanup& CWsDynamicResBase::PostTestCleanupInstance() + { + static + class RPostTestCleanup:public TPostTestCleanup + { + public: + RPostTestCleanup() + { + iSharedUtility=NULL; + iCleanedUpOnExit=ETrue; + } + ~RPostTestCleanup() + { + // I want to cleanly release the surface utility, but at this point the threads have already been pulled down! + // if (iSharedUtility) + // delete iSharedUtility; + iSharedUtility=NULL; //avoid phoenix behaviour + } + } staticInstance; + return staticInstance; + } + +void CWsDynamicResBase::TPostTestCleanup::CreateSharedUtilityL()const + { + if (iSharedUtility==NULL) + iSharedUtility=CSurfaceUtility::NewL(); + } + +/** +Pause for the given number of milliseconds. + +@param aMilliseconds Time to wait in milliseconds. +*/ +void CWsDynamicResBase::Pause(TInt aMilliseconds) + { + User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000)); + } + +/** Creates the normal scenario used by these tests. + * With a large window behind and small window in front. + * If the windows already exist then they are just repositioned and redrawn. + * @param aOuterRect Position of back window + * @param aOuterColor Background colour for back window + * @param aInnerRect Position of front window + * @param aInnerColor Background colour for front window + * + **/ +void CWsDynamicResBase::MakeTestWindowPairL(TRect aOuterRect,TRgb aOuterColor,TRect aInnerRect,TRgb aInnerColor) + { + if (!iTestBack.WsHandle()) + { + iTestBack=RWindow(iSession); + ASSERT_EQUALS_X(iTestBack.Construct(iGroup, ++iWindowHandle), KErrNone); +#ifdef FLICKER + iTestBack.Activate(); +#endif + iTestBack.SetRequiredDisplayMode(iDisplayMode); + iTestBack.SetBackgroundColor(aOuterColor); + iTestBack.SetExtent(aOuterRect.iTl,aOuterRect.Size()); +#ifndef FLICKER + iTestBack.Activate(); +#endif + } + else + { + iTestBack.SetRequiredDisplayMode(iDisplayMode); + iTestBack.SetBackgroundColor(aOuterColor); + iTestBack.SetExtent(aOuterRect.iTl,aOuterRect.Size()); + } + iTestBack.BeginRedraw(); + ActivateWithWipe(iGc,iTestBack,aOuterColor); + iGc->Deactivate(); + iTestBack.EndRedraw(); + iTestBack.SetVisible(ETrue); + + if (!iTestFront.WsHandle()) + { + iTestFront=RWindow(iSession); + ASSERT_EQUALS_X(iTestFront.Construct(iGroup, ++iWindowHandle), KErrNone); +#ifdef FLICKER + iTestFront.Activate(); +#endif + iTestFront.SetRequiredDisplayMode(iDisplayMode); + iTestFront.SetBackgroundColor(aInnerColor); + iTestFront.SetExtent(aInnerRect.iTl,aInnerRect.Size()); + +#ifndef FLICKER + iTestFront.Activate(); +#endif + } + else + { + iTestFront.SetRequiredDisplayMode(iDisplayMode); + iTestFront.SetBackgroundColor(aInnerColor); + iTestFront.SetExtent(aInnerRect.iTl,aInnerRect.Size()); + } + + DrawPlainUI(iTestFront,EFalse,aInnerColor); + iTestFront.SetVisible(ETrue); + + } + +void CWsDynamicResBase::LargerTestWindow(TInt aPercentOfBack) + { + TRect newPos=iTestPos; + TSize backSize=iTestPos.Size(); + newPos.Grow((aPercentOfBack-100)*backSize.iWidth/200,(aPercentOfBack-100)*backSize.iHeight/200); + iCenteredFrontWinRect=newPos; + if (iTestFront.WsHandle()) + { + iTestFront.SetExtent(newPos.iTl,newPos.Size()); + } + + } + +/** Destroys some or all of the test windows so the test can loop (or test the state after destruction. + * The windows are destroyed when the test exits normally. + * Child windows are automatically killed when parent window is killed! + * + **/ +void CWsDynamicResBase::DestroyTestWindowPair(TBool aKillTestBack,TBool aKillTestFront,TBool aKillTestChildren) + { + if (aKillTestBack && iTestBack.WsHandle()) + { + iTestBack.Close(); + } + if (aKillTestFront && iTestFront.WsHandle()) + { + iTestFront.Close(); + } + if (aKillTestChildren) + { + if (iTestChild.WsHandle()) + { + iTestChild.Close(); + } + if (iTestSecondChild.WsHandle()) + { + iTestSecondChild.Close(); + } + } + } +/** Creates a child window inside the front window of the usual test scenario +* With a large window behind and small window in front. + * If the windows already exist then they are just repositioned and redrawn. + * @param aOuterRect Position of back window + * @param aOuterColor Background colour for back window + * @param aInnerRect Position of front window + * @param aInnerColor Background colour for front window + * @param aChildRect Position of child window + * @param aChildColor Background colour for child window + * @param aSecondChildRect Position of Second child window + * @param aSecondChildColor Background colour for Second child window + * + **/ +void CWsDynamicResBase::MakeTestWindowTripleL(TRect aOuterRect,TRgb aOuterColor,TRect aInnerRect,TRgb aInnerColor,TRect aChildRect,TRgb aChildColor,TRect aSecondChildRect,TRgb aSecondChildColor) + { + MakeTestWindowTripleL(aOuterRect,aOuterColor,aInnerRect,aInnerColor,aChildRect,aChildColor); + + MakeExtraChildWindowL(iTestChild,aSecondChildRect,aSecondChildColor); + } + +/** Creates a child window inside the front window of the usual test scenario +* With a large window behind and small window in front. + * If the windows already exist then they are just repositioned and redrawn. + * @param aOuterRect Position of back window + * @param aOuterColor Background colour for back window + * @param aInnerRect Position of front window + * @param aInnerColor Background colour for front window + * @param aChildRect Position of child window + * @param aChildColor Background colour for child window + * @param aSecondChildRect Position of second child window + * @param aSecondChildColor Background colour for second child window + * + **/ +void CWsDynamicResBase::CreateTestWindowQuadL(TRect aOuterRect,TRgb aOuterColor,TRect aInnerRect,TRgb aInnerColor,TRect aChildRect,TRgb aChildColor,TRect aSecondChildRect,TRgb aSecondChildColor) + { + MakeTestWindowTripleL(aOuterRect,aOuterColor,aInnerRect,aInnerColor,aChildRect,aChildColor); + + MakeExtraChildWindowL(iTestFront,aSecondChildRect,aSecondChildColor); + } + +void CWsDynamicResBase::MakeExtraChildWindowL(const RWindowBase& aFromParent,TRect aChildRect,TRgb aChildColor) + { + ASSERT(aFromParent.WsHandle()); + if (!iTestSecondChild.WsHandle()) + { + iTestSecondChild=RWindow(iSession); + ASSERT_EQUALS_X(iTestSecondChild.Construct(aFromParent, ++iWindowHandle), KErrNone); + iTestSecondChild.SetRequiredDisplayMode(iDisplayMode); + } + iTestSecondChild.SetBackgroundColor(aChildColor); + iTestSecondChild.SetExtent(aChildRect.iTl,aChildRect.Size()); + iTestSecondChild.Activate(); + iTestSecondChild.BeginRedraw(); + iGc->Activate(iCompare); + iGc->SetBrushColor(iBlue); + iGc->Clear(); + iGc->Deactivate(); + iTestSecondChild.EndRedraw(); + iTestSecondChild.SetVisible(ETrue); + } + +CWsDynamicResBase::LoopingGcPtr CWsDynamicResBase::LoopBeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor) + { + InvalidateRegion(aRegion,aWin); + return LoopingGcPtr(aRegion,aWin,aColor,GcForWindow(aWin)); + } + +//This gets called each itteration of the while loop, and is used to step the rectangle count! +void CWsDynamicResBase::LoopingGcPtr::operator ++() + { + iPass++; + if (iPassActivate(iCompare); + iGc->SetBrushColor(iBlue); + iGc->Clear(); + iGc->Deactivate(); + iTestChild.EndRedraw(); + iTestChild.SetVisible(ETrue); + } +/** + * Generates a valid surfaceID for the current display mode. + * This is then used in negative testing. + * + * + **/ +void CWsDynamicResBase::UISurfaceL(TSurfaceId& aSurfaceId) const + { + CFbsDrawDevice* screenDevice=NULL; + TDisplayMode displayMode=iScreenDevice->DisplayMode(); + screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode); + CleanupStack::PushL(screenDevice); + TAny* p=NULL; + User::LeaveIfError(screenDevice->GetInterface(KSurfaceInterfaceID, p)); + MSurfaceId* uiSurface = static_cast(p); + uiSurface->GetSurface(aSurfaceId); + CleanupStack::PopAndDestroy(screenDevice); + } + +/** +Common set up code for creating a surface based window. + +Given window and surface objects and a color: creates the window and surface, +sets the window to a default size (the same as the surface), sets the background +to the bitwise inverse of the given color, sets the surface as the background, +fills the surface with the color and completes a redraw to prevent an event. + +@param aWindow The window object, connected to a session. +@param aSurface The surface object, to be initialized. +@param aColor The color to fill the surface with. +*/ +void CWsDynamicResBase::CommonSurfaceWindowSetupL(RWindow& aWindow, TSurfaceId& aSurface, const TRgb& aColor) + { + TInt err = KErrNone; + + TRAP(err, aSurface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight), + KSurfaceFormat, KSurfaceWidth * KBytesPerPixel)); + PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err); + ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone); + + aWindow.SetRequiredDisplayMode(iDisplayMode); + aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight)); + aWindow.SetBackgroundColor(TRgb(aColor.Value() ^ 0xFFFFFF)); + + ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(aSurface), KErrNone); + + TRAP(err, iUtility->FillSurfaceL(aSurface, aColor)); + PRINT_ON_ERROR2_L(err, _L("Failed to fill surface: %d"), err); + DrawUIContent(aWindow); + } + +/** +Common set up code for resizing tests. + +Similar to the common surface window code, but filling the surface with a grid +instead of a solid color. The grid lines are always black. Also, the background +color is always blue. +*/ +void CWsDynamicResBase::ResizeTestCommonSetupL(RWindow& aWindow, const TRgb& aColor) + { + // Session and group created in SetUpL() + + TSurfaceId surface; + TInt err = KErrNone; + + TRAP(err, surface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight), + KSurfaceFormat, KSurfaceWidth * KBytesPerPixel)); + PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err); + + ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone); + + aWindow.SetRequiredDisplayMode(iDisplayMode); + aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight)); + aWindow.SetBackgroundColor(iBlue); + ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(surface), KErrNone); + + TRAP(err, iUtility->GridFillSurfaceL(surface, aColor, TRgb(0))); + PRINT_ON_ERROR2_L(err, _L("Failed to grid fill surface: %d"), err); + DrawUIContent(aWindow); + } + +CFbsBitmap* CWsDynamicResBase::RotateBitmapLC(const CFbsBitmap* aSrcBitmap) + { + CFbsBitmap* rv=new CFbsBitmap; + CleanupStack::PushL(rv); + TSize srcSize=aSrcBitmap->SizeInPixels(); + rv->Create(TSize(srcSize.iHeight,srcSize.iWidth),EColor16MA); + TRgb* linestore=new TRgb[srcSize.iHeight]; + TPtr8 buff((unsigned char*)linestore,srcSize.iHeight*sizeof(TRgb),srcSize.iHeight*sizeof(TRgb)); + for (TInt col=0;colSizeInPixels().iWidth;col++) + { + for (TInt row=0,brow=srcSize.iHeight-1;rowGetPixel(linestore[row],TPoint(col,brow)); + } + rv->SetScanLine(buff,col); + } + delete[] linestore; + return rv; + } + + +// +// +// +// Pattern checking. Is a given pattern still present? +// To make life interesting, the pattern is stored backwards! +// The pattern is fibonnacci sequence masked to byte: +// 1 2 3 5 8 13 21 34 55 89 144 233 121 +// 98 219 61 24 85 109 194 47 241 32 17 49 66 +// 115 181 40 221 5 226 231 201 176 121 41 162 +// +// +void Pattern::Fill(void* aTrg,TInt aOffset,TInt aLength) + { + unsigned char* ptr=(unsigned char*)aTrg; + TInt a=0; + TInt b=1; + while (--aLength) + { + TInt c=a+b; + *(ptr+aOffset+aLength)=c&0xff; + a=b; + b=c; + } + } +TBool Pattern::Check(void* aTrg,TInt aOffset,TInt aLength) + { + unsigned char* ptr=(unsigned char*)aTrg; + TInt a=0; + TInt b=1; + while (--aLength) + { + TInt c=a+b; + if (*(ptr+aOffset+aLength)!=c&0xff) + return EFalse; + a=b; + b=c; + } + return ETrue; + } +TBool Pattern::CheckVal(void* aTrg,TInt aOffset,TInt aLength,char val) + { + unsigned char* ptr=(unsigned char*)aTrg; + while (--aLength) + { + if (*(ptr+aOffset+aLength)!=val&0xff) + return EFalse; + } + return ETrue; + } + +//I have removed these only because they use TRegionExtend +// +//TInt CWsDynamicResBase::RegionDiffForUiLayer(TInt aUiLayer) +// { +// EWsDebugGetUILayerConfig, //return: TSurfaceConfig //Index UI layer via EWsDebugArgLayerMask +// EWsDebugGetUILayerBase, //return: TRect[] +// +// RRegion layerRegion; +// TInt layerRegionLen=iSession.DebugInfo(EWsDebugGetUILayerBase,iSession.ObjInd(0,aUiLayer),layerRegion); +// if (layerRegionLen==KErrCancel) +// return TRegionExtend::EExact; +// ASSERT_TRUE(layerRegionLen>=0); +// TBuf8 configBuf(sizeof(TSurfaceConfiguration)); +// const TSurfaceConfiguration* config; +// TInt configLen=iSession.DebugInfo(EWsDebugGetUILayerConfig,iSession.ObjInd(0,aUiLayer),configBuf,config); +// ASSERT_TRUE(configLen>=0); +// TRect layerExtent; +// config->GetExtent(layerExtent); +// TInt retVal=TRegionExtend::Cast(layerRegion).TestDifference(layerExtent.Size()); +// layerRegion.Close(); +// return retVal; +// } +//CWsDynamicResBase::FastPathMode CWsDynamicResBase::DeduceUiFastPathMode() +// { +// TInt blendedRegionState=RegionDiffForUiLayer(0); +// TInt opaqueRegionState=RegionDiffForUiLayer(1); +// if (blendedRegionState&TRegionExtend::ENoIntersect) +// { +// if (opaqueRegionState&TRegionExtend::ENoIntersect) +// { +// return EFpExternalOpaque; //fullscreen fast-path external surface +// } +// else +// if (opaqueRegionState&TRegionExtend::EAdd) +// { +// return (FastPathMode)(EFpUiOpaque|EFpUiRegions); //windowed max-opt no blending +// } +// else +// { +// return EFpUiOpaque; //full-screen fastpath +// } +// } +// else +// { +// if (opaqueRegionState&TRegionExtend::ENoIntersect) +// { +// if (blendedRegionState&TRegionExtend::EAdd) +// { +// return (FastPathMode)(EFpUiBlended|EFpUiRegions); //windowed max-opt no opaque +// } +// else +// { +// return (EFpUiBlended); //full-screen blended +// } +// } +// else +// { +// if ((blendedRegionState|opaqueRegionState)&TRegionExtend::EAdd) +// { +// return (FastPathMode)(EFpUiComplex|EFpUiRegions); //moxed blending, opaque and external max optimisation +// } +// else +// { +// return EFpUiComplex; //Error! blend and opaque both enabled and full-screen! +// } +// } +// +// } +// }