--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/tdynamicres/src/wsdynamicresbase.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -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 <w32std.h>
+#include "wsdynamicresbase.h"
+#include "teflogextensions.h"
+#include "globalsettings.h"
+#include <bitdraw.h>
+#include <bitdrawinterfaceid.h>
+#include <bitdrawsurface.h>
+#include <graphics/surfaceconfiguration.h>
+#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 (iPass<iRegion.Count())
+ { //Invalidate all the rectangles in the region
+ iWin.BeginRedraw(iRegion[iPass]);
+ CWsDynamicResWinBase::ActivateWithWipe(iGc,iWin,iColor);
+// return true;
+ }
+ else
+ {
+ iGc=NULL;
+// return false;
+ }
+ }
+
+CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(TBool aInvalidate,RWindow& aWin,TRgb aColor)
+ {
+ return CWsDynamicResWinBase::BeginActivateWithWipe(aInvalidate,aWin,aColor);
+ }
+
+CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(TBool aInvalidate,TRect aRect,RWindow& aWin,TRgb aColor)
+ {
+ return CWsDynamicResWinBase::BeginActivateWithWipe(aInvalidate,aRect,aWin,aColor);
+ }
+
+CWindowGc* CWsDynamicResBase::BeginActivateWithWipe(const TRegion& aRegion,RWindow& aWin,TRgb aColor)
+ {
+ return CWsDynamicResWinBase::BeginActivateWithWipe(aRegion,aWin,aColor);
+ }
+
+/** 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
+ *
+ **/
+void CWsDynamicResBase::MakeTestWindowTripleL(TRect aOuterRect,TRgb aOuterColor,TRect aInnerRect,TRgb aInnerColor,TRect aChildRect,TRgb aChildColor)
+ {
+ MakeTestWindowPairL(aOuterRect,aOuterColor,aInnerRect,aInnerColor);
+ ASSERT(iTestFront.WsHandle());
+
+ if (!iTestChild.WsHandle())
+ {
+ iTestChild=RWindow(iSession);
+ ASSERT_EQUALS_X(iTestChild.Construct(iTestFront, ++iWindowHandle), KErrNone);
+ iTestChild.SetRequiredDisplayMode(iDisplayMode);
+ }
+ iTestChild.SetBackgroundColor(aChildColor);
+ iTestChild.SetExtent(aChildRect.iTl,aChildRect.Size());
+ iTestChild.Activate();
+ iTestChild.BeginRedraw();
+ iGc->Activate(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<MSurfaceId*>(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;col<aSrcBitmap->SizeInPixels().iWidth;col++)
+ {
+ for (TInt row=0,brow=srcSize.iHeight-1;row<srcSize.iHeight;row++,brow--)
+ {
+ aSrcBitmap->GetPixel(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<sizeof(TSurfaceConfiguration)> 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!
+// }
+// }
+//
+// }
+// }