First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "wsdynamicresbase.h"
18 #include "teflogextensions.h"
19 #include "globalsettings.h"
21 #include <bitdrawinterfaceid.h>
22 #include <bitdrawsurface.h>
23 #include <graphics/surfaceconfiguration.h>
24 #include "regionextend.h"
27 #if defined(__X86GCC__)
28 extern "C" TInt atexit(void (*function)(void))
34 CWsDynamicResBase::CWsDynamicResBase():
39 CWsDynamicResBase::~CWsDynamicResBase()
44 Common set up code for all tests.
46 Creates the session and window group for further windows, plus a simple white
47 background to obscure any unwanted stuff behind the test. Sets up the surface
48 update session and surface manager, to work with surfaces. Creates a screen
49 device for use in the tests.
51 void CWsDynamicResBase::SetupL()
55 void CWsDynamicResBase::SetupL(TBool aUseOtherScreenForInfo)
57 CWsDynamicResWinBase::SetupL(aUseOtherScreenForInfo);
60 //clean-up if previous test abended
61 if (PostTestCleanupInstance().iSharedUtility)
63 //Temp removed - may be causing ONB fails!
64 // if (PostTestCleanupInstance().iSharedUtility->DestroyAll())
66 // INFO_PRINTF1(_L("Destroyed some surfaces from previous test."));
70 if (!PostTestCleanupInstance().iCleanedUpOnExit)
71 PostTestCleanupInstance().iCleanedUpOnExit=EFalse;
73 if (!GCEIsSupported())
75 INFO_PRINTF1(_L("Some Setup skipped: GCE support is not loaded"));
79 TRAPD(err_FailedToCreateSurfaceUtility, iUtility = CSurfaceUtility::NewL( PostTestCleanupInstance().iSharedUtility));
80 ASSERT_EQUALS(err_FailedToCreateSurfaceUtility,KErrNone);
86 Common tear down code for all tests.
88 Windows, group and session created are closed. Screen device is destroyed.
89 Surfaces, manager and update session are closed.
91 void CWsDynamicResBase::TearDownL()
93 CWsDynamicResWinBase::TearDownL();
95 PostTestCleanupInstance().iCleanedUpOnExit=ETrue;
99 * Note that this is not the ideal mechanism.
100 * 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
102 void CWsDynamicResBase::TearDownFromDeleteL()
104 CWsDynamicResBase::TearDownL();
107 //Allocating an instance of surface utility here means all test code instances will share the same instance of the utility class.
108 // Owns the singleton
109 /*static*/ const CWsDynamicResBase::TPostTestCleanup& CWsDynamicResBase::PostTestCleanupInstance()
112 class RPostTestCleanup:public TPostTestCleanup
118 iCleanedUpOnExit=ETrue;
122 // I want to cleanly release the surface utility, but at this point the threads have already been pulled down!
123 // if (iSharedUtility)
124 // delete iSharedUtility;
125 iSharedUtility=NULL; //avoid phoenix behaviour
128 return staticInstance;
131 void CWsDynamicResBase::TPostTestCleanup::CreateSharedUtilityL()const
133 if (iSharedUtility==NULL)
134 iSharedUtility=CSurfaceUtility::NewL();
138 Pause for the given number of milliseconds.
140 @param aMilliseconds Time to wait in milliseconds.
142 void CWsDynamicResBase::Pause(TInt aMilliseconds)
144 User::After(TTimeIntervalMicroSeconds32(aMilliseconds * 1000));
147 void CWsDynamicResBase::LargerTestWindow(TInt aPercentOfBack)
149 TRect newPos=iTestPos;
150 TSize backSize=iTestPos.Size();
151 newPos.Grow((aPercentOfBack-100)*backSize.iWidth/200,(aPercentOfBack-100)*backSize.iHeight/200);
152 iCenteredFrontWinRect=newPos;
153 if (iTestFront.WsHandle())
155 iTestFront.SetExtent(newPos.iTl,newPos.Size());
161 void CWsDynamicResBase::MakeExtraChildWindowL(const RWindowBase& aFromParent,TRect aChildRect,TRgb aChildColor)
163 ASSERT(aFromParent.WsHandle());
164 if (!iTestSecondChild.WsHandle())
166 iTestSecondChild=RWindow(iSession);
167 ASSERT_EQUALS_X(iTestSecondChild.Construct(aFromParent, ++iWindowHandle), KErrNone);
168 iTestSecondChild.SetRequiredDisplayMode(iDisplayMode);
170 iTestSecondChild.SetBackgroundColor(aChildColor);
171 iTestSecondChild.SetExtent(aChildRect.iTl,aChildRect.Size());
172 iTestSecondChild.Activate();
173 iTestSecondChild.BeginRedraw();
174 iGc->Activate(iCompare);
175 iGc->SetBrushColor(iBlue);
178 iTestSecondChild.EndRedraw();
179 iTestSecondChild.SetVisible(ETrue);
182 CWsDynamicResBase::LoopingGcPtr CWsDynamicResBase::LoopBeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
184 InvalidateRegion(aRegion,aWin);
185 return LoopingGcPtr(aRegion,aWin,aColor,GcForWindow(aWin));
188 //This gets called each itteration of the while loop, and is used to step the rectangle count!
189 void CWsDynamicResBase::LoopingGcPtr::operator ++()
192 if (iPass<iRegion.Count())
193 { //Invalidate all the rectangles in the region
194 iWin.BeginRedraw(iRegion[iPass]);
195 CWsDynamicResWinBase::ActivateWithWipe(iGc,iWin,iColor);
205 CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor)
207 return CWsDynamicResWinBase::BeginActivateWithWipe(aInvalidate,aWin,aColor);
210 CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor)
212 return CWsDynamicResWinBase::BeginActivateWithWipe(aInvalidate,aRect,aWin,aColor);
215 CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
217 return CWsDynamicResWinBase::BeginActivateWithWipe(aRegion,aWin,aColor);
221 * Generates a valid surfaceID for the current display mode.
222 * This is then used in negative testing.
226 void CWsDynamicResBase::UISurfaceL(TSurfaceId& aSurfaceId) const
228 CFbsDrawDevice* screenDevice=NULL;
229 TDisplayMode displayMode=iScreenDevice->DisplayMode();
230 screenDevice = CFbsDrawDevice::NewScreenDeviceL(TGlobalSettings::Instance().iScreen, displayMode);
231 CleanupStack::PushL(screenDevice);
233 User::LeaveIfError(screenDevice->GetInterface(KSurfaceInterfaceID, p));
234 MSurfaceId* uiSurface = static_cast<MSurfaceId*>(p);
235 uiSurface->GetSurface(aSurfaceId);
236 CleanupStack::PopAndDestroy(screenDevice);
240 Common set up code for creating a surface based window.
242 Given window and surface objects and a color: creates the window and surface,
243 sets the window to a default size (the same as the surface), sets the background
244 to the bitwise inverse of the given color, sets the surface as the background,
245 fills the surface with the color and completes a redraw to prevent an event.
247 @param aWindow The window object, connected to a session.
248 @param aSurface The surface object, to be initialized.
249 @param aColor The color to fill the surface with.
251 void CWsDynamicResBase::CommonSurfaceWindowSetupL(RWindow& aWindow, TSurfaceId& aSurface, const TRgb& aColor)
255 TRAP(err, aSurface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight),
256 KSurfaceFormat, KSurfaceWidth * KBytesPerPixel));
257 PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err);
258 ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone);
260 aWindow.SetRequiredDisplayMode(iDisplayMode);
261 aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight));
262 aWindow.SetBackgroundColor(TRgb(aColor.Value() ^ 0xFFFFFF));
264 ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(aSurface), KErrNone);
266 TRAP(err, iUtility->FillSurfaceL(aSurface, aColor));
267 PRINT_ON_ERROR2_L(err, _L("Failed to fill surface: %d"), err);
268 DrawUIContent(aWindow);
272 Common set up code for resizing tests.
274 Similar to the common surface window code, but filling the surface with a grid
275 instead of a solid color. The grid lines are always black. Also, the background
276 color is always blue.
278 void CWsDynamicResBase::ResizeTestCommonSetupL(RWindow& aWindow, const TRgb& aColor)
280 // Session and group created in SetUpL()
285 TRAP(err, surface = iUtility->CreateSurfaceL(TSize(KSurfaceWidth, KSurfaceHeight),
286 KSurfaceFormat, KSurfaceWidth * KBytesPerPixel));
287 PRINT_ON_ERROR2_L(err, _L("Failed to create surface: %d"), err);
289 ASSERT_EQUALS_X(aWindow.Construct(iGroup, ++iWindowHandle), KErrNone);
291 aWindow.SetRequiredDisplayMode(iDisplayMode);
292 aWindow.SetExtent(TPoint(0, 0), TSize(KSurfaceWidth, KSurfaceHeight));
293 aWindow.SetBackgroundColor(iBlue);
294 ASSERT_EQUALS_X(aWindow.SetBackgroundSurface(surface), KErrNone);
296 TRAP(err, iUtility->GridFillSurfaceL(surface, aColor, TRgb(0)));
297 PRINT_ON_ERROR2_L(err, _L("Failed to grid fill surface: %d"), err);
298 DrawUIContent(aWindow);
301 CFbsBitmap* CWsDynamicResBase::RotateBitmapLC(const CFbsBitmap* aSrcBitmap)
303 CFbsBitmap* rv=new CFbsBitmap;
304 CleanupStack::PushL(rv);
305 TSize srcSize=aSrcBitmap->SizeInPixels();
306 rv->Create(TSize(srcSize.iHeight,srcSize.iWidth),EColor16MA);
307 TRgb* linestore=new TRgb[srcSize.iHeight];
308 TPtr8 buff((unsigned char*)linestore,srcSize.iHeight*sizeof(TRgb),srcSize.iHeight*sizeof(TRgb));
309 for (TInt col=0;col<aSrcBitmap->SizeInPixels().iWidth;col++)
311 for (TInt row=0,brow=srcSize.iHeight-1;row<srcSize.iHeight;row++,brow--)
313 aSrcBitmap->GetPixel(linestore[row],TPoint(col,brow));
315 rv->SetScanLine(buff,col);
325 // Pattern checking. Is a given pattern still present?
326 // To make life interesting, the pattern is stored backwards!
327 // The pattern is fibonnacci sequence masked to byte:
328 // 1 2 3 5 8 13 21 34 55 89 144 233 121
329 // 98 219 61 24 85 109 194 47 241 32 17 49 66
330 // 115 181 40 221 5 226 231 201 176 121 41 162
333 void Pattern::Fill(void* aTrg,TInt aOffset,TInt aLength)
335 unsigned char* ptr=(unsigned char*)aTrg;
341 *(ptr+aOffset+aLength)=c&0xff;
346 TBool Pattern::Check(void* aTrg,TInt aOffset,TInt aLength)
348 unsigned char* ptr=(unsigned char*)aTrg;
354 if (*(ptr+aOffset+aLength)!=c&0xff)
361 TBool Pattern::CheckVal(void* aTrg,TInt aOffset,TInt aLength,char val)
363 unsigned char* ptr=(unsigned char*)aTrg;
366 if (*(ptr+aOffset+aLength)!=val&0xff)
372 //I have removed these only because they use TRegionExtend
374 //TInt CWsDynamicResBase::RegionDiffForUiLayer(TInt aUiLayer)
376 // EWsDebugGetUILayerConfig, //return: TSurfaceConfig //Index UI layer via EWsDebugArgLayerMask
377 // EWsDebugGetUILayerBase, //return: TRect[]
379 // RRegion layerRegion;
380 // TInt layerRegionLen=iSession.DebugInfo(EWsDebugGetUILayerBase,iSession.ObjInd(0,aUiLayer),layerRegion);
381 // if (layerRegionLen==KErrCancel)
382 // return TRegionExtend::EExact;
383 // ASSERT_TRUE(layerRegionLen>=0);
384 // TBuf8<sizeof(TSurfaceConfiguration)> configBuf(sizeof(TSurfaceConfiguration));
385 // const TSurfaceConfiguration* config;
386 // TInt configLen=iSession.DebugInfo(EWsDebugGetUILayerConfig,iSession.ObjInd(0,aUiLayer),configBuf,config);
387 // ASSERT_TRUE(configLen>=0);
388 // TRect layerExtent;
389 // config->GetExtent(layerExtent);
390 // TInt retVal=TRegionExtend::Cast(layerRegion).TestDifference(layerExtent.Size());
391 // layerRegion.Close();
394 //CWsDynamicResBase::FastPathMode CWsDynamicResBase::DeduceUiFastPathMode()
396 // TInt blendedRegionState=RegionDiffForUiLayer(0);
397 // TInt opaqueRegionState=RegionDiffForUiLayer(1);
398 // if (blendedRegionState&TRegionExtend::ENoIntersect)
400 // if (opaqueRegionState&TRegionExtend::ENoIntersect)
402 // return EFpExternalOpaque; //fullscreen fast-path external surface
405 // if (opaqueRegionState&TRegionExtend::EAdd)
407 // return (FastPathMode)(EFpUiOpaque|EFpUiRegions); //windowed max-opt no blending
411 // return EFpUiOpaque; //full-screen fastpath
416 // if (opaqueRegionState&TRegionExtend::ENoIntersect)
418 // if (blendedRegionState&TRegionExtend::EAdd)
420 // return (FastPathMode)(EFpUiBlended|EFpUiRegions); //windowed max-opt no opaque
424 // return (EFpUiBlended); //full-screen blended
429 // if ((blendedRegionState|opaqueRegionState)&TRegionExtend::EAdd)
431 // return (FastPathMode)(EFpUiComplex|EFpUiRegions); //moxed blending, opaque and external max optimisation
435 // return EFpUiComplex; //Error! blend and opaque both enabled and full-screen!