os/kernelhwsrv/kerneltest/e32test/dispchan/t_dispchan.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 the License "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 // This test should not depend on any external data files and should work with
    15 // the default (empty) epoc.ini file.
    16 // The test should be run without the Graphics GCE enabled but with the Base GCE
    17 // driver enabled. On the emulator this can be done by launcing with -Dtextshell --
    18 // and on the H4 build a textshell ROM with -DSYMBIAN_BASE_USE_GCE but NOT 
    19 // -DSYMBIAN_GRAPHICS_USE_GCE
    20 // In the visual tests some flickering may occur due to updates to the console. On
    21 // the emulator it is possible to configure a second screen so that the console updates
    22 // will only happen on one screen. The test automatically runs on every screen available.
    23 // 
    24 //
    25 
    26 #define __E32TEST_EXTENSION__
    27 
    28 #include <dispchannel.h>
    29 #include <e32std.h>
    30 #include <e32std_private.h>
    31 #include <e32def.h>
    32 #include <e32def_private.h>
    33 #include <e32svr.h>
    34 #include <e32test.h>
    35 #include <pixelformats.h>
    36 #include <hal.h>
    37 
    38 RTest test(_L("Display Channel device driver unit tests"));
    39 
    40 /** Maximum probable pixel resolution width or height */
    41 static const TInt KMaxExpectedPixelRes = 10000;
    42 
    43 /** Unlikely to ever have a > 1000 Hz refresh rate */
    44 static const TInt KMaxExpectedRefreshRate = 1000;
    45 
    46 /** Time (in microseconds) for each visual test */
    47 static const TInt KDrawWaitTime = 1000000;
    48 
    49 /** Array of supported rotations */
    50 static const RDisplayChannel::TDisplayRotation KRotations[] = {
    51 		RDisplayChannel::ERotationNormal, 
    52 		RDisplayChannel::ERotation90CW,
    53 		RDisplayChannel::ERotation180,
    54 		RDisplayChannel::ERotation270CW};
    55 static const TInt KNumRotations = sizeof(KRotations) / sizeof(RDisplayChannel::TDisplayRotation);
    56 
    57 /** Array of pixel formats to try for visual test */
    58 static const RDisplayChannel::TPixelFormat KPixelFormats[] = {
    59 	EUidPixelFormatYUV_422Interleaved16bit,	// not supported on emulator but should not be a fatal error
    60 	EUidPixelFormatXRGB_4444,	
    61 	EUidPixelFormatARGB_4444,
    62 	EUidPixelFormatRGB_565,
    63 	EUidPixelFormatXRGB_8888,
    64 	EUidPixelFormatARGB_8888,
    65 	EUidPixelFormatARGB_8888_PRE	
    66 };
    67 static const TInt KNumPixelFormats = sizeof(KPixelFormats) / sizeof(RDisplayChannel::TPixelFormat);
    68 
    69 /**
    70 Encapsulates display related HAL information. 
    71 */
    72 class THalDisplayInfo 
    73 	{
    74 public:
    75 	TBool iIsMono;
    76 	TBool iIsPalettized;
    77 	TInt iBitsPerPixel;
    78 	TInt iMemoryAddress;
    79 	TInt iMemoryHandle;
    80 	TInt iState;
    81 	TInt iColors;
    82 	TInt iXPixels;
    83 	TInt iYPixels;
    84 	TInt iXTwips;
    85 	TInt iYTwips;
    86 	TInt iNumModes;	
    87 	TInt iMode;
    88 	TInt iOffsetBetweenLines;
    89 	TInt iOffsetToFirstPixel;
    90 	TBool iIsPixelOrderRGB;
    91 	TBool iIsPixelOrderLandscape;
    92 	};
    93 
    94 /**
    95 Helper class that waits for RDisplayChannel asynchronous requests and
    96 can cancel them if necessary. The purpose of this class is so that the main 
    97 test class can create an asynchronous request and also simulate the completion
    98 of that request e.g. faking a display change event.
    99 */
   100 class CAsyncHelper : public CActive
   101 	{
   102 public:
   103 	inline CAsyncHelper(RDisplayChannel& aDisp);
   104 	inline ~CAsyncHelper();
   105 	inline TRequestStatus& Status();
   106 	void WaitForOperation(TInt* aResult);
   107 private:
   108 	// From CActive
   109 	inline void DoCancel();
   110 	inline void RunL();	
   111 private:
   112 	RDisplayChannel& iDisp;
   113 	TInt* iResult;
   114 	};
   115 
   116 inline CAsyncHelper::CAsyncHelper(RDisplayChannel& aDisp) : CActive(EPriorityHigh), iDisp(aDisp) {CActiveScheduler::Add(this);}
   117 inline CAsyncHelper::~CAsyncHelper() {Deque();}
   118 inline TRequestStatus& CAsyncHelper::Status() {return iStatus;}
   119 // Writes the iStatus.Int() to the address defined by the client of this AO
   120 inline void CAsyncHelper::RunL() {*iResult = iStatus.Int();}
   121 
   122 void CAsyncHelper::WaitForOperation(TInt* aResult)
   123 /**
   124 Invokes SetActive() to wait for the asynchronous operation to complete. The completion
   125 code is copied to the aResult when RunL is invoked.
   126 @param aResult	out parameter that will be set to iStatus.Int()
   127 */
   128 	{
   129 	iResult = aResult; 	
   130 	// Set the result to default value that is unlikely to be returned by the real API
   131 	*aResult = KMaxTInt;
   132 	SetActive();
   133 	}
   134 
   135 void CAsyncHelper::DoCancel()
   136 	{
   137 	// Driver should fail if cancel is called when there is not standing request
   138 	// so cancel just attempts to cancel everything.
   139 	iDisp.CancelGetCompositionBuffer();
   140 	iDisp.CancelPostUserBuffer();
   141 	iDisp.CancelWaitForPost();
   142 	iDisp.NotifyOnDisplayChangeCancel();
   143 	}
   144 
   145 /**
   146 Class to test device driver for RDisplayChannel
   147 */
   148 class CDisplayChannelTest : public CActive
   149 	{
   150 	enum TTestState {
   151 		ETestDisplayInfo,
   152 		ETestCompositionBuffers,
   153 		ETestUserBuffers,
   154 		ETestRotations,
   155 		ETestDisplayChange,
   156 		ETestDisplayChangeDoCancel,
   157 		ETestDisplayChangeCheckCancel,
   158 		ETestGetCompositionBufferDoCancel,
   159 		ETestGetCompositionBufferCheckCancel,
   160 		ETestWaitForPostDoCancel,
   161 		ETestWaitForPostCheckCancel,
   162 		ETestResolutions,
   163 		ETestPixelFormats,
   164 		ETestBufferFormats,
   165 		ETestV11inV10,
   166 		EVisualTest,
   167 		ETestSecondHandle,
   168 		ETestBufferTransitions,
   169 		ETestFinished
   170 	};
   171 	
   172 	public:
   173 		static CDisplayChannelTest* NewLC(TInt aScreenId);
   174 		void Start();
   175 		~CDisplayChannelTest();
   176 		
   177 	private:		
   178 		// From CActive
   179 		void DoCancel();
   180 		TInt RunError(TInt aError);
   181 		void RunL();
   182 
   183 	private:		
   184 		CDisplayChannelTest(TInt aScreenId);
   185 		void CompleteSelf(TTestState aNextState);
   186 
   187 		// The tests
   188 		void CheckDisplayInfo();
   189 		void CheckResolutions();
   190 		void CheckPixelFormats();
   191 		void CheckDisplayChange();
   192 		void CheckCompositionBuffers();
   193 		void CheckBufferFormat();
   194 		void CheckUserBuffers();
   195 		void CheckRotations();
   196 		TBool IsValidRotation(RDisplayChannel::TDisplayRotation aRotation);
   197 		TBool IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat);		
   198 		void CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation);
   199 		void CheckV11inV10();
   200 		void VisualTest();
   201 		void DrawLegacyBuffer(TInt aStep);
   202 		void DrawFillToMemory(TUint8* aFirstPixelAddr, TInt aOffsetBetweenLines, 
   203 				RDisplayChannel::TPixelFormat aPixelFormat, TInt aWidth, TInt aHeight, TInt aStep);
   204 		void DrawCompositionBuffer(
   205 				RDisplayChannel::TPostCount& aPostCount, 
   206 				RDisplayChannel::TBufferFormat aBufferFormat,
   207 				RDisplayChannel::TDisplayRotation aRotation, TInt aStep);
   208 		void GetHalDisplayInfo();
   209 		void CheckSecondHandle();
   210 		void TestBufferTransitions();
   211 
   212 	private:
   213 		RDisplayChannel iDisp;			/// handle to display channel device driver
   214 		TVersion iVersion;				/// version number of disp channel driver interface
   215 		THalDisplayInfo iHalInfo;		/// info about legacy buffer from HAL
   216 		TInt iScreenId;					/// run tests on each screen
   217 		TTestState iState;				/// the current test
   218 		CAsyncHelper *iAsyncHelper;				
   219 		TInt iAsyncHelperResult;		/// set to iAyncHelper::iStatus.Int()
   220 		RArray<RDisplayChannel::TResolution> iResolutions;
   221 		RArray<RDisplayChannel::TPixelFormat> iPixelFormats;
   222 		TInt iVisualTestFormatIndex;		/// index of the current pixel format in visual test 
   223 		TInt iVisualTestRotationIndex;		/// index of the current rotation in the visual test
   224 		TUint iDummyCompositionBuffer;		/// dummy var used to test cancel of GetCompositionBuffer
   225 		RDisplayChannel::TPostCount iDummyPostCount;	/// dummy var used to test CancelWaitForPost 
   226 	};
   227 
   228 // Gets a HAL value, logs the result and errors if HAL::Get failed
   229 #define DBG_HAL(DEVICE, ATT, VAL, ERR, IN) \
   230 	{ \
   231 	VAL = IN;\
   232 	ERR = HAL::Get(DEVICE, ATT, VAL); \
   233 	test.Printf(_L(#ATT)); \
   234 	test.Printf(_L(" device %d err = %d, val = %d\n"), DEVICE, ERR, VAL); \
   235 	test_KErrNone(ERR); \
   236 	}
   237 
   238 void CDisplayChannelTest::GetHalDisplayInfo()
   239 /**
   240 Retrieves display related HAL settings. This also initialises the legacy buffer by retrieving
   241 HAL::EDisplayMemoryAddress
   242 */
   243 	{
   244 	TInt err = KErrNotSupported;	
   245 		
   246 	DBG_HAL(iScreenId, HAL::EDisplayMemoryAddress, iHalInfo.iMemoryAddress, err, 0);
   247 			
   248 	iHalInfo.iMemoryHandle = 0;
   249 	err = HAL::Get(iScreenId, HAL::EDisplayMemoryHandle, iHalInfo.iMemoryHandle);
   250 	test(err == KErrNone || err == KErrNotSupported);
   251 	test.Printf(_L("HAL::EDisplayMemoryHandle returned err %d\n"), err);
   252 	if (err == KErrNone)
   253 		{
   254 		// Handle is not needed so don't leak it
   255 		RHandleBase h;
   256 		h.SetHandle(iHalInfo.iMemoryHandle);
   257 		h.Close();
   258 		}
   259 	
   260 	// This is mostly for information purposes to ensure the legacy buffer is sane.
   261 	DBG_HAL(iScreenId, HAL::EDisplayState, iHalInfo.iState, err, 0);
   262 	DBG_HAL(iScreenId, HAL::EDisplayColors, iHalInfo.iColors, err, 0);
   263 	DBG_HAL(iScreenId, HAL::EDisplayXPixels, iHalInfo.iXPixels, err, 0);
   264 	DBG_HAL(iScreenId, HAL::EDisplayYPixels, iHalInfo.iYPixels, err, 0);
   265 	DBG_HAL(iScreenId, HAL::EDisplayXTwips, iHalInfo.iXTwips, err, 0);
   266 	DBG_HAL(iScreenId, HAL::EDisplayYTwips, iHalInfo.iYTwips, err, 0);	
   267 	DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderRGB, iHalInfo.iIsPixelOrderRGB, err, 0);
   268 	DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderLandscape, iHalInfo.iIsPixelOrderLandscape, err, 0);
   269 	
   270 	DBG_HAL(iScreenId, HAL::EDisplayNumModes, iHalInfo.iNumModes, err, 0);		
   271 	DBG_HAL(iScreenId, HAL::EDisplayMode, iHalInfo.iMode, err, 0);
   272 	
   273 	// Get info for current display mode
   274 	DBG_HAL(iScreenId, HAL::EDisplayIsMono, iHalInfo.iIsMono, err, iHalInfo.iMode);
   275 	DBG_HAL(iScreenId, HAL::EDisplayBitsPerPixel, iHalInfo.iBitsPerPixel, err, iHalInfo.iMode);
   276 	DBG_HAL(iScreenId, HAL::EDisplayOffsetBetweenLines, iHalInfo.iOffsetBetweenLines, err, iHalInfo.iMode);
   277 	DBG_HAL(iScreenId, HAL::EDisplayOffsetToFirstPixel, iHalInfo.iOffsetToFirstPixel, err, iHalInfo.iMode);
   278 	DBG_HAL(iScreenId, HAL::EDisplayIsPalettized, iHalInfo.iIsPalettized, err, iHalInfo.iMode);
   279 	}
   280 
   281 CDisplayChannelTest::CDisplayChannelTest(TInt aScreenId)
   282 /**
   283 Constructor
   284 @param aScreenId	the screen number to run the test on
   285 */
   286 	: CActive(EPriorityStandard), iScreenId(aScreenId)
   287 	{	
   288 	TVersion versionRequired = iDisp.VersionRequired();
   289 	test.Printf(_L("*** Opening display channel for screen %d. Test compiled against version %d.%d.%d ***\n"),
   290 			iScreenId, versionRequired.iMajor, versionRequired.iMinor, versionRequired.iBuild);
   291 	TInt err = iDisp.Open(iScreenId);
   292 	test_KErrNone(err);
   293 	
   294 	test.Printf(_L("Successfully opened display channel for screen %d\n"), iScreenId);
   295 
   296 	// This test should be updated if a change to the driver requires a version change
   297 	err = iDisp.Version(iVersion);
   298 	if (err == KErrNotSupported)
   299 		{
   300 		test.Printf(_L("Version API not supported. Assuming v1.0.0\n"));
   301 		iVersion.iMajor = 1;
   302 		iVersion.iMinor = 0;
   303 		iVersion.iBuild = 0;
   304 		}
   305 	else
   306 		{
   307 		test.Printf(_L("Display channel driver version %d.%d.%d\n"), 
   308 				iVersion.iMajor, iVersion.iMinor, iVersion.iBuild);
   309 		test_KErrNone(err);
   310 		}
   311 	test(iVersion.iMajor >= 1 && iVersion.iMinor >= 0);		
   312 	GetHalDisplayInfo();
   313 	CActiveScheduler::Add(this);
   314 	
   315 	iAsyncHelper = new CAsyncHelper(iDisp);
   316 	test_NotNull(iAsyncHelper);
   317 	}
   318 
   319 CDisplayChannelTest::~CDisplayChannelTest()
   320 /**
   321 Destructor
   322 */
   323 	{
   324 	Deque();
   325 	delete iAsyncHelper;
   326 	iPixelFormats.Close();
   327 	iResolutions.Close();
   328 	iDisp.Close();	
   329 	}
   330 
   331 CDisplayChannelTest* CDisplayChannelTest::NewLC(TInt aScreenId)
   332 /**
   333 Factory method that creates a new instance of the screen
   334 display channel unit test object and places a pointer to this on the cleanup stack
   335 
   336 @param aScreenId	the screen number to run the test on
   337 @return	a pointer to the new CDisplayTest object.
   338 */
   339 	{
   340 	CDisplayChannelTest* self = new(ELeave) CDisplayChannelTest(aScreenId);
   341 	CleanupStack::PushL(self);
   342 	return self;
   343 	}
   344 
   345 void CDisplayChannelTest::CheckDisplayInfo()
   346 /**
   347 Check the values returned by CheckDisplayInfo
   348 */
   349 	{
   350 	test.Next(_L("Test GetDisplayInfo"));
   351 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
   352 
   353 	test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
   354 
   355 	// This test only works with 24 and 32 BPP displays and crashes otherwise.  Test for this and display
   356 	// a nice human readable message rather than just crashing
   357 	if ((infoPkg().iBitsPerPixel != 24) && (infoPkg().iBitsPerPixel != 32))
   358 		{
   359 		TBuf<256> message;
   360 
   361 		message.Format(_L("*** Error! %d bits per pixel displays are not supported. ***\n*** Please configure your ROM to use 24 or 32 bits per pixel.  ***\n"), infoPkg().iBitsPerPixel);
   362 		test.Printf(message);
   363 
   364 		// And fail the test for the benefit of automated ONB tests
   365 		test_Equal(infoPkg().iBitsPerPixel, 24);
   366 		}
   367 
   368 	test_Compare(infoPkg().iBitsPerPixel, >=, 1);
   369 	test_Compare(infoPkg().iAvailableRotations, !=, 0);
   370 
   371 	// check for invalid rotations i.e. those not defined by TRotation
   372 	test((infoPkg().iAvailableRotations & 0xFFF0) == 0);
   373 
   374 	// Check that the refresh rate field isn't garbage
   375 	test_Compare(infoPkg().iRefreshRateHz, >=, 1);
   376 	test_Compare(infoPkg().iRefreshRateHz, <=, KMaxExpectedRefreshRate);
   377 
   378 	// Should always be at least one composition buffer
   379 	test_Compare(infoPkg().iNumCompositionBuffers, >=, 1);
   380 	}
   381 
   382 void CDisplayChannelTest::CheckResolutions()
   383 /**
   384  Validate that the APIs to get / set resolutions.
   385 
   386  Tests<br>
   387  NumberOfResolutions, GetResolutions, GetResolution, GetRotation
   388  */
   389 	{
   390 	test.Next(_L("Test NumberOfResolutions, GetResolutions, GetResolution, GetRotation"));
   391 
   392 	// Get and reserve space for expected number of resolutions
   393 	TInt n = iDisp.NumberOfResolutions();
   394 	test_Compare(n, >=, 1);
   395 	
   396 	iResolutions.Reset();
   397 	test_KErrNone(iResolutions.Reserve(n));
   398 	for (TInt i = 0; i < n; ++i)
   399 		{
   400 		test_KErrNone(iResolutions.Append(RDisplayChannel::TResolution(TSize(0,0), TSize(0,0), 0)));
   401 		}
   402 	
   403 	// Retrieve the resolutions and make sure the number of resolutions returned matches the 
   404 	// expected number. It is assumed that the display state won't be changed during the execution
   405 	// of this test.
   406 	TInt actualResolutions = 0;	
   407 	TPtr8 resPtr(reinterpret_cast<TUint8*>(&iResolutions[0]), 
   408 			sizeof(RDisplayChannel::TResolution) * n, sizeof(RDisplayChannel::TResolution) * n);
   409 	test_KErrNone(iDisp.GetResolutions(resPtr, actualResolutions));
   410 	test_Equal(n, actualResolutions);	
   411 
   412 	test.Printf(_L("Supported resolutions"));
   413 	for (TInt res = 0; res < n; ++res)
   414 		{
   415 		RDisplayChannel::TResolution& r = iResolutions[res];
   416 		test.Printf(_L("pixelX = %d heightX = %d twipsX = %d twipsY = %d flags = 0x%08x\n"), 
   417 				r.iPixelSize.iWidth, r.iPixelSize.iHeight, r.iTwipsSize.iWidth, r.iTwipsSize.iHeight, r.iFlags);		
   418 		
   419 		// If either pixel height or pixel width is zero then both must be zero
   420 		// If either pixel height or pixel width is non-zero then both must be positive
   421 		test((r.iPixelSize.iHeight == 0 && r.iPixelSize.iWidth == 0) ||
   422 			 (r.iPixelSize.iHeight > 0 && r.iPixelSize.iWidth > 0));
   423 
   424 		// Test resolutions are sane
   425 		test(r.iPixelSize.iHeight <= KMaxExpectedPixelRes && r.iPixelSize.iWidth <= KMaxExpectedPixelRes);
   426 
   427 		// If either twips height or pixel width is zero then both must be zero
   428 		// If either twips height or pixel width is non-zero then both must be positive
   429 		test((r.iTwipsSize.iHeight == 0 && r.iTwipsSize.iWidth == 0) ||
   430 			 (r.iTwipsSize.iHeight > 0 && r.iTwipsSize.iWidth > 0));
   431 		
   432 		// twips resolution can be zero iff pixel resolution is also zero
   433 		test((r.iPixelSize.iHeight == 0 && r.iTwipsSize.iHeight == 0) ||
   434 			 (r.iPixelSize.iHeight > 0  && r.iTwipsSize.iHeight > 0));
   435 
   436 		// At least one rotation must be supported. Ignore other bits in the flags field
   437 		test(r.iFlags & RDisplayChannel::ERotationAll != 0);
   438 		}
   439 
   440 	// Get current resolution in pixels
   441 	TSize currentResolution;
   442 	test_KErrNone(iDisp.GetResolution(currentResolution));
   443 
   444 	// Get current resolution in twips
   445 	TSize currentTwips;
   446 	test_KErrNone(iDisp.GetTwips(currentTwips));
   447 
   448 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
   449 	test(IsValidRotation(currentRotation));
   450 
   451 	// The current resolution and rotation must be in the list of supported resolutions
   452 	TBool foundCurrentRes = EFalse;
   453 	for (TInt j = iResolutions.Count() - 1; j >= 0; --j)
   454 		{
   455 		if (iResolutions[j].iPixelSize == currentResolution &&
   456 			iResolutions[j].iTwipsSize == currentTwips &&
   457 			iResolutions[j].iFlags & currentRotation)
   458 			{
   459 			foundCurrentRes = ETrue;
   460 			break;
   461 			}
   462 		}
   463 	test(foundCurrentRes);
   464 	
   465 	// Now and try every supported resolution
   466 	TInt err;
   467 	for (TInt k = iResolutions.Count() - 1; k >= 0; --k)
   468 		{
   469 		err = iDisp.SetResolution(iResolutions[k].iPixelSize);
   470 		test(err == KErrNone || err == KErrNotSupported);
   471 		}
   472 	// attempt to set back to original resolution, this could fail
   473 	err = iDisp.SetResolution(currentResolution);
   474 	test(err == KErrNone || err == KErrNotSupported);
   475 	}
   476 
   477 void CDisplayChannelTest::CheckPixelFormats()
   478 /**
   479  Validates that the pixel format APIs are sane/consistent.
   480 
   481  In version 1.1 the APIs are just stubs that return KErrNotSupported
   482  */
   483 	{
   484 	test.Next(_L("Test NumberOfPixelFormats, GetPixelFormats"));
   485 
   486 	// At least one pixel format must be supported
   487 	TInt n = iDisp.NumberOfPixelFormats();
   488 
   489 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   490 		{
   491 		test_Compare(n, ==, KErrNotSupported);
   492 		n = 1; // Override return to test stub for GetPixelFormats
   493 		}
   494 	else
   495 		{
   496 		test_Compare(n, >=, 1);
   497 		}
   498 
   499 	TInt err = iPixelFormats.Reserve(n);
   500 	test_KErrNone(err);
   501 	for (TInt i = 0; i < n; ++i)
   502 		{
   503 		test_KErrNone(iPixelFormats.Append(-1));
   504 		}
   505 	TPtr8 pixelFormatsPtr(reinterpret_cast<TUint8*>(&iPixelFormats[0]),
   506 			sizeof(RDisplayChannel::TPixelFormat) * n, sizeof(RDisplayChannel::TPixelFormat) * n);		
   507 
   508 	TInt actualFormats = -1;	
   509 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   510 		{
   511 		test_Compare(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats), ==, KErrNotSupported);
   512 		}
   513 	else
   514 		{		
   515 		test_KErrNone(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats));
   516 		
   517 		// The number of formats shouldn't have changed whilst this test is running
   518 		test_Equal(n, actualFormats);			
   519 		RArray<RDisplayChannel::TPixelFormat> pixelFormatsArray(
   520 				reinterpret_cast<RDisplayChannel::TPixelFormat*>(&pixelFormatsPtr[0]), actualFormats);
   521 		
   522 		// Check the pixel formats returned are all valid
   523 		for (TInt pf = pixelFormatsArray.Count() - 1; pf >= 0; --pf)
   524 			{
   525 			IsValidPixelFormat(pixelFormatsArray[pf]);
   526 			}		
   527 		}
   528 	}
   529 
   530 void CDisplayChannelTest::CheckDisplayChange()
   531 /**
   532  Register for display change notification then immediately cancel.
   533  */
   534 	{
   535 	test.Next(_L("Test NotifyOnDisplayChange, NotifyOnDisplayChangeCancel"));
   536 	// Cancel should be allowed even if NotifyOnyDisplayChange has not been called
   537 	iDisp.NotifyOnDisplayChangeCancel();
   538 
   539 	iDisp.NotifyOnDisplayChange(iAsyncHelper->Status());
   540 	iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
   541 	}
   542 
   543 void CDisplayChannelTest::DrawFillToMemory(
   544 		TUint8* aFirstPixelAddr, 
   545 		TInt aOffsetBetweenLines, 
   546 		RDisplayChannel::TPixelFormat aPixelFormat, 
   547 		TInt aWidth, 
   548 		TInt aHeight, 
   549 		TInt aStep)
   550 /** 
   551  Draws a shaded fill to a memory region
   552  @param	aFirstPixelAddr			the address of the first pixel in the buffer.
   553  @param	aOffsetBetweenLines		offset between pixels at the start of each line
   554  @param aBpp					bits per pixel
   555  @param	aWidth					width of the region in pixels
   556  @param aHeight					height of the region in pixels
   557  @aStep	aStep					integer >= 1 to vary the pattern by test number 
   558  */	{
   559 	test.Printf(_L("DrawFileToMemory\npixelformat = 0x%08x offsetbetweenlines = %d pixel address = 0x%08x width=%d height = %d\n"), 
   560 			aPixelFormat, aOffsetBetweenLines, aFirstPixelAddr, aWidth, aHeight);	
   561 
   562 
   563 	TInt xShadeMax = 0xFF;
   564 	TInt yShadeMax = 0xFF;
   565 	
   566 	if (aPixelFormat == EUidPixelFormatRGB_565)
   567 		{
   568 		xShadeMax = 0x3F;	// 6 bits for green
   569 		yShadeMax = 0x1F;
   570 		}
   571 	else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
   572 		{
   573 		xShadeMax = 0x0F;
   574 		yShadeMax = 0x0F;
   575 		}
   576 	
   577 	aStep = Max(1, aStep);
   578 	TUint8* lineAddr = aFirstPixelAddr;
   579 	for (TInt y = 0; y < aHeight; ++y)
   580 		{
   581 		TInt yShade = (y * yShadeMax) / aHeight;
   582 		TUint8* pixelAddr = lineAddr;
   583 		for (TInt x = 0; x < aWidth; ++x)
   584 			{
   585 			TInt xShade = (x * xShadeMax) / aWidth;			
   586 			TUint8 red = 0;
   587 			TUint8 green = 0;
   588 			TUint8 blue = 0;
   589 			
   590 			if ( aStep == 0 || y > aStep * 10)
   591 				{
   592 				// Green top left, blue bottom right
   593 				green = static_cast<TUint8>(xShadeMax - xShade);
   594 				blue = static_cast<TUint8>(yShade);
   595 				}							
   596 			else
   597 				{
   598 				// The size of the red band indicates different test steps			
   599 				red = static_cast<TUint8>((yShadeMax * x) / aWidth);
   600 				}
   601 			
   602 			if (aPixelFormat == EUidPixelFormatRGB_565)
   603 				{
   604 				*pixelAddr++ = static_cast<TUint8>(blue | (green << 5));
   605 				*pixelAddr++ = static_cast<TUint8>((green >> 3) | (red << 3));
   606 				}
   607 			else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
   608 				{
   609 				*pixelAddr++ = static_cast<TUint8>(blue | (green << 4));
   610 				*pixelAddr++ = red;					
   611 				}
   612 			else if (aPixelFormat == EUidPixelFormatXRGB_8888 || aPixelFormat == EUidPixelFormatARGB_8888 
   613 					|| aPixelFormat == EUidPixelFormatARGB_8888)
   614 				{
   615 				*pixelAddr++ = blue;
   616 				*pixelAddr++ = green;
   617 				*pixelAddr++ = red;
   618 				*pixelAddr++ = 0xFF;	// unused
   619 				}
   620 			}
   621 		lineAddr += aOffsetBetweenLines;
   622 		}
   623 	}
   624 
   625 void CDisplayChannelTest::DrawLegacyBuffer(TInt aStep)
   626 	{
   627 	test.Printf(_L("DrawLegacyBuffer\n"));
   628 	TInt oldMode;
   629 	TInt err;
   630 	err = HAL::Get(iScreenId, HAL::EDisplayMode, oldMode);
   631 	for (TInt i = 0; i < iHalInfo.iNumModes; ++i)
   632 		{
   633 		// Attempt to set the legacy buffer to a mode supporting 32bit (RGBA or RGBX)
   634 		TInt modeBpp = i;
   635 		err = HAL::Get(iScreenId, HAL::EDisplayBitsPerPixel, modeBpp);
   636 				
   637 		test_KErrNone(err);				
   638 		if ((modeBpp == 24 || modeBpp == 32))
   639 			{
   640 			TInt newMode = i;
   641 			err = HAL::Set(iScreenId, HAL::EDisplayMode, newMode);
   642 			break;
   643 			}
   644 		}
   645 		
   646 	GetHalDisplayInfo();
   647 	err = HAL::Set(iScreenId, HAL::EDisplayMode, oldMode);
   648 	TUint8* firstPixelAddr = reinterpret_cast<TUint8*>(iHalInfo.iMemoryAddress + iHalInfo.iOffsetToFirstPixel);
   649 	TInt offsetBetweenLines = iHalInfo.iOffsetBetweenLines;
   650 	TInt width = iHalInfo.iXPixels;
   651 	TInt height = iHalInfo.iYPixels;
   652 	
   653 	if ((! iHalInfo.iIsPalettized) && iHalInfo.iIsPixelOrderRGB)
   654 		{		
   655 		DrawFillToMemory(firstPixelAddr, offsetBetweenLines,
   656 				EUidPixelFormatXRGB_8888, width, height, aStep);
   657 		}
   658 	}
   659 
   660 void CDisplayChannelTest::DrawCompositionBuffer(
   661 		RDisplayChannel::TPostCount& aPostCount,
   662 		RDisplayChannel::TBufferFormat aBufferFormat,
   663 		RDisplayChannel::TDisplayRotation aRotation, TInt aStep)
   664 /**
   665 Attempts to set the requested buffer format and rotation then draws a shaded fill 
   666 to the buffer returned by RDisplayChannel::GetCompositionBuffer.
   667 If it is not possible to set the desired buffer format then the actual buffer format
   668 is used.
   669 
   670 @param	aPostCount		out parameter that is set to the post count returned by PostCompositionBuffer
   671 @param	aBufferFormat	the buffer format to use for this test step
   672 @param	aRotation		the rotation to set for this test step
   673 @param	aStep			test step number
   674 */
   675 	{
   676 	test.Printf(_L("DrawCompositionBuffer\n"));
   677 		
   678 	TBool configChanged;
   679 	TInt err;
   680 	
   681 	RDisplayChannel::TBufferFormat actualBufferFormat(TSize(0,0),0);
   682 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
   683 		{
   684 		// It should be possible to set the rotation and the buffer format in either order.
   685 		// To test this the order is swapped every test step
   686 		if (aStep % 2 == 0)
   687 			{
   688 			test_KErrNone(iDisp.SetRotation(aRotation, configChanged));
   689 			err = iDisp.SetBufferFormat(aBufferFormat);
   690 			}
   691 		else
   692 			{
   693 			err = iDisp.SetBufferFormat(aBufferFormat);		
   694 			test_KErrNone(iDisp.SetRotation(aRotation, configChanged));		
   695 			}
   696 		if (err != KErrNone)
   697 			{
   698 			test.Printf(_L("Unable to set buffer format 0x%08x width %d height %d"),
   699 					aBufferFormat.iPixelFormat, aBufferFormat.iSize.iWidth, aBufferFormat.iSize.iHeight);
   700 			}			
   701 		test_KErrNone(iDisp.GetBufferFormat(actualBufferFormat));
   702 		}
   703 	else
   704 		{
   705 		// buffer format not switched in v1.1 so test just validates post / wait for post
   706 		TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
   707 		test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
   708 
   709 		err = iDisp.SetRotation(aRotation, configChanged);
   710 		TInt expectedErr = KErrNone;
   711 		if ((!IsValidRotation(aRotation)) || ((infoPkg().iAvailableRotations & aRotation) == 0))
   712 			{
   713 			expectedErr = KErrArgument;
   714 			}
   715 		test(err == expectedErr);
   716 
   717 		actualBufferFormat = aBufferFormat;
   718 		}
   719 	
   720 	// Get the composition buffer index
   721 	TUint bufferIndex;
   722 	TRequestStatus status;
   723 	iDisp.GetCompositionBuffer(bufferIndex, status);
   724 	User::WaitForRequest(status);
   725 	test(status == KErrNone);
   726 
   727 	// Now get access to the composition buffer
   728 	RChunk compChunk;
   729 	TInt offset = 0;
   730 	err = iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset);
   731 	test_KErrNone(err);	
   732 	
   733 	TUint8* baseAddr = compChunk.Base();
   734 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
   735 	err = iDisp.GetDisplayInfo(infoPkg);
   736 	test_KErrNone(err);
   737 	
   738 	test.Printf(_L("DrawCompositionBuffer::GetCompositionBufferInfo index = 0x%08x base = 0x%08x offset = 0x%08x\n"),
   739 			bufferIndex, baseAddr, offset);
   740 	
   741 	// Find out structure of the buffer
   742 	TUint8* firstPixelAddr = baseAddr + offset;	
   743 		
   744 	// Find out current display dimensions
   745 	TInt width;
   746 	TInt height;	
   747 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
   748 	test(IsValidRotation(currentRotation));
   749 	if (currentRotation == RDisplayChannel::ERotationNormal ||
   750 		currentRotation == RDisplayChannel::ERotation180)
   751 		{
   752 		width = actualBufferFormat.iSize.iWidth;
   753 		height = actualBufferFormat.iSize.iHeight;
   754 		}
   755 	else
   756 		{
   757 		height = actualBufferFormat.iSize.iWidth;
   758 		width = actualBufferFormat.iSize.iHeight;
   759 		}	
   760 	
   761 	TInt offsetBetweenLines;
   762 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
   763 		{
   764 		 offsetBetweenLines = iDisp.NextLineOffset(actualBufferFormat, 0);
   765 		}
   766 	else
   767 		{
   768 		// NextLineOffset not supported in v1.0 and displayinfo offset doesn't work on H4
   769 		offsetBetweenLines = 4 * width;
   770 		}
   771 	DrawFillToMemory(firstPixelAddr, offsetBetweenLines, actualBufferFormat.iPixelFormat, 
   772 			width, height, aStep);
   773 
   774 	err = iDisp.PostCompositionBuffer(NULL, aPostCount);
   775 	test_KErrNone(err);
   776 	User::After(KDrawWaitTime);
   777 	
   778 	compChunk.Close();
   779 	}
   780 
   781 void CDisplayChannelTest::CheckCompositionBuffers()
   782 /**
   783  Retrieves the current composition buffer index and checks the information about
   784  this buffer.
   785  */
   786 	{
   787 	test.Next(_L("Test GetCompositionBuffer, CancelGetCompositionBuffer, GetCompositionBufferInfo, PostLegacyBuffer"));
   788 
   789 	iDisp.CancelGetCompositionBuffer();	// Test cancel without an outstanding call
   790 
   791 	TUint bufferIndex;
   792 	TRequestStatus status;
   793 	// Get with immediate cancel
   794 	iDisp.GetCompositionBuffer(bufferIndex, status);
   795 	iDisp.CancelGetCompositionBuffer();
   796 	test(status == KErrNone || status == KErrCancel);
   797 
   798 	iDisp.GetCompositionBuffer(bufferIndex, status);	// Get, no cancel
   799 	User::WaitForRequest(status);
   800 	test(status == KErrNone);
   801 
   802 	RChunk compChunk;
   803 	TInt offset = 0;
   804 	test_KErrNone(iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset));
   805 
   806 	// client must be able to read and write to the chunk
   807 	test(compChunk.IsReadable());
   808 	test(compChunk.IsWritable());
   809 	test_Compare(offset, >=, 0);
   810 
   811 	RDisplayChannel::TPostCount postCountA;
   812 	RDisplayChannel::TPostCount postCountB;
   813 	test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountA));
   814 	test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountB));
   815 	test_Compare(postCountB - postCountA, >=, 1);
   816 	
   817 	// Wait for first postcount value
   818 	iDisp.WaitForPost(postCountA, status);
   819 	User::WaitForRequest(status);
   820 	test(status == KErrNone);
   821 
   822 	// It should be possible to wait again on postCountA
   823 	// and this should complete immediately with KErrNone. However, there
   824 	// there is bug in the emulator causes this to wait forever.
   825 	
   826 	compChunk.Close();
   827 
   828 	// Legacy buffer should have been initialised by retrieval of HAL::EDisplayMemoryAddress 
   829 	test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCountA));
   830 	test_Compare(postCountA - postCountB, >=, 1);	
   831 	}
   832 
   833 void CDisplayChannelTest::VisualTest()
   834 /**
   835 Iterates over the arrays of pixel formats and rotations attempting to 
   836 draw a shaded fill to the composition buffer
   837 */
   838 	{
   839 	test.Next(_L("Visual test"));	
   840 	
   841 	RDisplayChannel::TPostCount postCount;	
   842 	if (iVisualTestFormatIndex < KNumPixelFormats)
   843 		{
   844 		RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);		
   845 		if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
   846 			{
   847 			// only one format supported in v1.0 so only one loop needed
   848 			bufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
   849 			iVisualTestFormatIndex = KNumPixelFormats - 1; 	
   850 			TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
   851 			iDisp.GetDisplayInfo(infoPkg);
   852 			bufferFormat.iSize.iWidth = infoPkg().iNormal.iWidth;
   853 			bufferFormat.iSize.iHeight = infoPkg().iNormal.iHeight;
   854 			}
   855 		else
   856 			{			
   857 			test_KErrNone(iDisp.GetBufferFormat(bufferFormat));
   858 			bufferFormat.iPixelFormat = KPixelFormats[iVisualTestFormatIndex];			
   859 			}
   860 		DrawCompositionBuffer(postCount, bufferFormat, KRotations[iVisualTestRotationIndex], iVisualTestRotationIndex);	
   861 		iVisualTestRotationIndex++;
   862 		if (iVisualTestRotationIndex >= KNumRotations)
   863 			{
   864 			iVisualTestRotationIndex = 0;
   865 			iVisualTestFormatIndex++;
   866 			}
   867 		iDisp.WaitForPost(postCount, iStatus);
   868 		SetActive();
   869 		}
   870 	else
   871 		{
   872 		// Test drawing to the legacy buffer
   873 		test.Printf(_L("Drawing to legacy buffer\n"));
   874 		
   875 		TBool configChanged;
   876 		iDisp.SetRotation(KRotations[0], configChanged);		
   877 		DrawLegacyBuffer(20); // Make legacy buffer obviously different
   878 		test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCount));
   879 		CompleteSelf(ETestSecondHandle);
   880 		User::After(KDrawWaitTime);
   881 		}
   882 	}
   883 
   884 void CDisplayChannelTest::CheckBufferFormat()
   885 /**
   886  Tests the APIs for getting and setting the buffer format.
   887   In version 1.1 these APIs are only stubs that return KErrNotSupported
   888  
   889  @pre CheckResolutions must have called prior to calling this method
   890  @pre CheckPixelFormats must have been called prior to calling this method.
   891  */
   892 	{
   893 	test.Next(_L("Test GetBufferFormat, SetBufferFormat, NextLineOffset, NextPlaneOffset"));
   894 
   895 	RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);
   896 	TInt err = iDisp.GetBufferFormat(bufferFormat);
   897 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   898 		{
   899 		test_Compare(err, ==, KErrNotSupported);
   900 		}
   901 	else
   902 		{
   903 		test(IsValidPixelFormat(bufferFormat.iPixelFormat));
   904 		test(bufferFormat.iSize.iHeight > 0 && bufferFormat.iSize.iHeight > 0);
   905 		// Check that the buffer is at least as large as the current pixel resolution
   906 		TSize resSize;
   907  		test_KErrNone(iDisp.GetResolution(resSize));
   908 		test(bufferFormat.iSize.iHeight >= resSize.iHeight && bufferFormat.iSize.iWidth >= resSize.iWidth);
   909 		}
   910 	
   911 	RDisplayChannel::TBufferFormat newBufferFormat(TSize(iHalInfo.iXPixels, iHalInfo.iYPixels), 0);
   912 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   913 		{
   914 		// API not support in 1.1
   915 		test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrNotSupported);
   916 		}
   917 	else
   918 		{
   919 		// Tests assumes that 32bpp XRGB888 is supported on most hardware
   920 		RDisplayChannel::TBufferFormat newBufferFormat(TSize(0,0), EUidPixelFormatXRGB_8888);
   921 		test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrArgument);	// buffer must be large enough for resolution
   922 						
   923 		// Should be able to current buffer format
   924 		test_KErrNone(iDisp.SetBufferFormat(bufferFormat));
   925 		}
   926 
   927 	// Get current information and check this against new APIs that give 
   928 	// line and plane information for any mode.
   929 	TSize currentPixelRes;
   930 	TSize currentTwipRes;
   931 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
   932 	RDisplayChannel::TBufferFormat currentBufferFormat(TSize(0,0), 0);
   933 	
   934 	test_KErrNone(iDisp.GetResolution(currentPixelRes));
   935 	test_KErrNone(iDisp.GetTwips(currentTwipRes));
   936 	test_KErrNone(iDisp.GetBufferFormat(currentBufferFormat));
   937 	RDisplayChannel::TResolution res(currentPixelRes, currentTwipRes, currentRotation);
   938 
   939 	TInt planeOffset = iDisp.NextPlaneOffset(currentBufferFormat, 0);
   940 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   941 		{
   942 		test_Compare(planeOffset, ==, KErrNotSupported);
   943 		}
   944 	else
   945 		{
   946 		// Supported in v1.1
   947 		test_Compare(planeOffset, >=, 0);
   948 		
   949 		if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
   950 			{
   951 			// Extended API in v1.2
   952 			test.Printf(_L("Check that planeoffset APIs match"));
   953 			TInt planeOffset2 = iDisp.NextPlaneOffset(currentBufferFormat, res, currentRotation, 0);
   954 			test_Compare(planeOffset, ==, planeOffset2);		
   955 							
   956 			// check that invalid buffer formats are rejected
   957 			RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
   958 			badBufferFormat.iPixelFormat = -1;
   959 			test(iDisp.NextPlaneOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
   960 			}
   961 		}
   962 
   963 	TInt lineOffset = iDisp.NextLineOffset(currentBufferFormat, 0);	
   964 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
   965 		{
   966 		test_Compare(lineOffset, ==, KErrNotSupported);
   967 		}
   968 	else
   969 		{
   970 		test_Compare(lineOffset, >, 0);	// supported in v1.1
   971 		
   972 		if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
   973 			{
   974 			// Extended API in v1.2
   975 			test.Printf(_L("Check that lineoffset APIs match"));
   976 			TInt lineOffset2 = iDisp.NextLineOffset(currentBufferFormat, res, currentRotation, 0);
   977 			// stride values must be the same and > 0 for any non-zero resolution and the current
   978 			// resolution should not be zero in size.
   979 			
   980 			test_Compare(lineOffset, ==, lineOffset2);
   981 			// check that invalid buffer formats are rejected
   982 			RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
   983 			badBufferFormat.iPixelFormat = -1;
   984 			test(iDisp.NextLineOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
   985 			}
   986 		}
   987 	}
   988 
   989 void CDisplayChannelTest::CheckUserBuffers()
   990 /**
   991  Test APIs that manage user composition buffers. Since this unit test doesn't
   992  have access to the real surfaces the tests are mostly robustness tests.
   993  */
   994 	{
   995 	test.Next(_L("Test WaitForPost, DeRegisterUserBuffer"));
   996 
   997 	// Cancel should not fail even if WaitForPost has not been called
   998 	iDisp.CancelWaitForPost();
   999 	
  1000 	// Check that cancelling a non-existent post request doesn't fail
  1001 	iDisp.CancelPostUserBuffer();
  1002 
  1003 	// Make sure wait immediately followed by cancel doesn't crash
  1004 	TRequestStatus status;
  1005 	RDisplayChannel::TPostCount postCount = 0;
  1006     iDisp.WaitForPost(postCount, status);
  1007     iDisp.CancelWaitForPost();
  1008 	test(status == KErrNone || status == KErrCancel);
  1009 
  1010 	// De-register a non-existent buffer id
  1011 	RDisplayChannel::TBufferId badBufferId(42);
  1012 	TInt err = iDisp.DeregisterUserBuffer(badBufferId);
  1013 	// emulator KErrArugment but on H4 KErrNotFound	
  1014 	test(err == KErrArgument || err == KErrNotFound);
  1015 
  1016 	// Create and use a new buffer, should fail because chunk must be a SHARED chunk
  1017 	RChunk myChunk;
  1018 	const TInt chunkSize = 320 * 200 * 4; // actual size is not important because this should fail
  1019 	err =  myChunk.CreateGlobal(KNullDesC, chunkSize, chunkSize, EOwnerProcess);
  1020 	test_KErrNone(err); // Allocation should not fail under normal conditions
  1021 	RDisplayChannel::TBufferId myBufferId;
  1022 	err = iDisp.RegisterUserBuffer(myBufferId, myChunk, 0);
  1023 	// emulator KErrBadHandle but on H4 KErrArgument
  1024 	test(err == KErrBadHandle || err == KErrArgument);
  1025 	myChunk.Close();
  1026 
  1027 	// Try to post a request from a bad buffer id
  1028 	iDisp.PostUserBuffer(badBufferId, status, NULL, postCount);
  1029 	User::WaitForRequest(status);
  1030 	// Emulator KErrArgument H4 KErrNotFound
  1031 	test(status.Int() == KErrArgument || status.Int() == KErrNotFound);
  1032 	
  1033 	// Attempt to register an already existing buffer as a user buffer
  1034 	TUint compId;
  1035 	iDisp.GetCompositionBuffer(compId, status);
  1036 	User::WaitForRequest(status);
  1037 	RChunk compChunk;
  1038 	TInt offset;
  1039 	test_KErrNone(iDisp.GetCompositionBufferInfo(compId, compChunk, offset));
  1040 	test_KErrNone(iDisp.RegisterUserBuffer(myBufferId, compChunk, offset));
  1041 	err = iDisp.DeregisterUserBuffer(myBufferId);
  1042 	test(err == KErrNone || err == KErrInUse);
  1043 	compChunk.Close();
  1044 	}
  1045 
  1046 TBool CDisplayChannelTest::IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat)
  1047 /**
  1048 Validates whether the value of aPixelFormat corresponds to a valid enum in TUidPixelFormat
  1049 @param	aPixelFormat	the pixel format value to test
  1050 @return	ETrue if aPixelFormat is valid; otherwise, EFalse is returned.
  1051 */
  1052 	{
  1053 	switch (aPixelFormat)
  1054 		{
  1055 		case EUidPixelFormatUnknown:
  1056 		case EUidPixelFormatXRGB_8888:
  1057 		case EUidPixelFormatBGRX_8888:
  1058 		case EUidPixelFormatXBGR_8888:
  1059 		case EUidPixelFormatBGRA_8888:
  1060 		case EUidPixelFormatARGB_8888:
  1061 		case EUidPixelFormatABGR_8888:
  1062 		case EUidPixelFormatARGB_8888_PRE:
  1063 		case EUidPixelFormatABGR_8888_PRE:
  1064 		case EUidPixelFormatBGRA_8888_PRE:
  1065 		case EUidPixelFormatARGB_2101010:
  1066 		case EUidPixelFormatABGR_2101010:
  1067 		case EUidPixelFormatBGR_888:
  1068 		case EUidPixelFormatRGB_888:
  1069 		case EUidPixelFormatRGB_565:
  1070 		case EUidPixelFormatBGR_565:
  1071 		case EUidPixelFormatARGB_1555:
  1072 		case EUidPixelFormatXRGB_1555:
  1073 		case EUidPixelFormatARGB_4444:
  1074 		case EUidPixelFormatARGB_8332:
  1075 		case EUidPixelFormatBGRX_5551:
  1076 		case EUidPixelFormatBGRA_5551:
  1077 		case EUidPixelFormatBGRA_4444:
  1078 		case EUidPixelFormatBGRX_4444:
  1079 		case EUidPixelFormatAP_88:
  1080 		case EUidPixelFormatXRGB_4444:
  1081 		case EUidPixelFormatXBGR_4444:
  1082 		case EUidPixelFormatRGB_332:
  1083 		case EUidPixelFormatA_8:
  1084 		case EUidPixelFormatBGR_332:
  1085 		case EUidPixelFormatP_8:
  1086 		case EUidPixelFormatP_4:
  1087 		case EUidPixelFormatP_2:
  1088 		case EUidPixelFormatP_1:
  1089 		case EUidPixelFormatYUV_420Interleaved:
  1090 		case EUidPixelFormatYUV_420Planar:
  1091 		case EUidPixelFormatYUV_420PlanarReversed:
  1092 		case EUidPixelFormatYUV_420SemiPlanar:
  1093 		case EUidPixelFormatYUV_422Interleaved:
  1094 		case EUidPixelFormatYUV_422Planar:
  1095 		case EUidPixelFormatYUV_422Reversed:
  1096 		case EUidPixelFormatYUV_422SemiPlanar:
  1097 		case EUidPixelFormatYUV_422InterleavedReversed:
  1098 		case EUidPixelFormatYUV_422Interleaved16bit:
  1099 		case EUidPixelFormatYUV_444Interleaved:
  1100 		case EUidPixelFormatYUV_444Planar:
  1101 		case EUidPixelFormatL_8:
  1102 		case EUidPixelFormatL_4:
  1103 		case EUidPixelFormatL_2:
  1104 		case EUidPixelFormatL_1:
  1105 		case EUidPixelFormatSpeedTaggedJPEG:
  1106 		case EUidPixelFormatJPEG:
  1107 			return ETrue;
  1108 		default:
  1109 			return EFalse;
  1110 		}
  1111 	}
  1112 
  1113 TBool CDisplayChannelTest::IsValidRotation(RDisplayChannel::TDisplayRotation aRotation)
  1114 /**
  1115 Checks whether the supplied rotation is a valid rotation. <br>
  1116 N.B. Only single rotations are accepted so EFalse is returned for ERotationAll.
  1117 @param	aRotation	the rotation to validate
  1118 @return ETrue if the supplied rotation is valid; otherwise, EFalse is returned.
  1119 */
  1120 	{
  1121 	switch (aRotation)
  1122 		{
  1123 		case RDisplayChannel::ERotationNormal:
  1124 		case RDisplayChannel::ERotation90CW:
  1125 		case RDisplayChannel::ERotation180:
  1126 		case RDisplayChannel::ERotation270CW:
  1127 			return ETrue;
  1128 		default:
  1129 			return EFalse;
  1130 		}
  1131 	}
  1132 
  1133 void CDisplayChannelTest::CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation)
  1134 /**
  1135 Tests the SetRotation API attempting to set the requested resolution. If the resolution is supported
  1136 then SetRotation should succeed and the CurrentRotation should change. Otherwise, SetResolution should
  1137 fail and the current rotation should be unchanged.
  1138 
  1139 @param	aSupported		The set of supported resolutions for TDisplayInfo
  1140 @param	aNewRotation	The new rotation to set
  1141 */
  1142 	{
  1143 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
  1144 	test(IsValidRotation(currentRotation));
  1145 
  1146 	TBool displayConfigChanged = EFalse;
  1147 	TInt err = iDisp.SetRotation(aNewRotation, displayConfigChanged);
  1148 	TInt expectedErr = KErrNone;
  1149 	if ((!IsValidRotation(aNewRotation)) || ((aSupported & aNewRotation) == 0))
  1150 		{
  1151 		expectedErr = KErrArgument;
  1152 		}
  1153 	test(err == expectedErr);
  1154 
  1155 	// Check whether the rotation should / shouldn't have changed
  1156 	test (iDisp.CurrentRotation() == (err == KErrNone ? aNewRotation : currentRotation));
  1157 	}
  1158 
  1159 void CDisplayChannelTest::CheckRotations()
  1160 /**
  1161 Tests the SetRotation and GetRotation APIs by attempting to set each valid rotation
  1162 plus some invalid rotation values.
  1163 If a rotation is valid but not supported then KErrNotSupported should be returned.
  1164 */
  1165 	{
  1166 	test.Next(_L("Test CurrentRotation, SetRotation"));
  1167 
  1168 	// Find out supported resolutions
  1169 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
  1170 	test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
  1171 
  1172 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
  1173 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation90CW);
  1174 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation180);
  1175 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation270CW);
  1176 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
  1177 	CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(-1));
  1178 	CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(0));
  1179 	}
  1180 
  1181 void CDisplayChannelTest::CheckV11inV10()
  1182 /**
  1183 The purpose of this test is to verify that v1.0 of the display channel driver
  1184 returns KErrNotSupported for methods that only exist in newer versions as opposed
  1185 to panicking.
  1186 To run this test for real t_display needs to be built against v1.1 and then copied
  1187 to a v1.0 environment.
  1188 
  1189 If the version number is > 1.0 then this method does nothing.
  1190 */
  1191 	{
  1192 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
  1193 		{
  1194 		return;
  1195 		}
  1196 	
  1197 	test.Next(_L("Test check v1.1 functions fail gracefully in v1.0"));
  1198 
  1199 	// APIs should fail before evaluating parameters
  1200 	TInt intDummy;
  1201 	TInt err;
  1202 	TBuf8<256> buf;
  1203 	TSize size;
  1204 	
  1205 	test.Printf(_L("Testing display change APIs\n"));
  1206 	iDisp.NotifyOnDisplayChangeCancel();
  1207 	TRequestStatus status;	
  1208 	iDisp.NotifyOnDisplayChange(status);
  1209 	test(status == KErrNotSupported);
  1210 
  1211 	err = iDisp.NumberOfResolutions();
  1212 	test(err == KErrNotSupported);
  1213 
  1214 	err = iDisp.GetResolutions(buf, intDummy);
  1215 	test(err == KErrNotSupported);
  1216 
  1217 	err = iDisp.GetResolution(size);
  1218 	test(err == KErrNotSupported);
  1219 
  1220 	err = iDisp.GetTwips(size);
  1221 	test(err == KErrNotSupported);
  1222 
  1223 	err = iDisp.NumberOfPixelFormats();
  1224 	test(err == KErrNotSupported);
  1225 
  1226 	err = iDisp.GetPixelFormats(buf, intDummy);
  1227 	test(err == KErrNotSupported);
  1228 
  1229 	RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0),0);
  1230 	err = iDisp.GetBufferFormat(bufferFormat);
  1231 	test(err == KErrNotSupported);
  1232 	
  1233 	err = iDisp.SetBufferFormat(bufferFormat);
  1234 	test(err == KErrNotSupported);
  1235 
  1236 	err = iDisp.NextPlaneOffset(bufferFormat, 0);
  1237 	test(err == KErrNotSupported);
  1238 
  1239 	err = iDisp.NextLineOffset(bufferFormat, 0);
  1240 	test(err == KErrNotSupported);
  1241 	}
  1242 
  1243 void CDisplayChannelTest::CheckSecondHandle()
  1244 /**
  1245 Opens a second RDisplayChannel. 
  1246 The driver may not support this but must not crash. 
  1247 */
  1248 	{
  1249 	test.Next(_L("Open a second handle"));
  1250 	RDisplayChannel disp2;
  1251 	TInt err = disp2.Open(iScreenId);
  1252 	test(err == KErrNone || err == KErrInUse);
  1253 	disp2.Close();
  1254 	}
  1255 
  1256 void CDisplayChannelTest::TestBufferTransitions()
  1257 /**
  1258 Because different buffer types (ie. composition, legacy and user) complete differently, we must test
  1259 switching between those different types of buffers to ensure that this is taken into account.
  1260 */
  1261 	{
  1262 	// The support code required for this test exists only in the separated GCE display LDD, not in the
  1263 	// legacy monolithic WINSCW LDD
  1264 #if defined(_DEBUG) && !defined(__WINS__)
  1265 	test.Next(_L("Test transitions between buffer types"));
  1266 
  1267 	TPckgBuf<RDisplayChannel::TDisplayInfo> displayInfo;
  1268 	test_KErrNone(iDisp.GetDisplayInfo(displayInfo));
  1269 
  1270 	RChunk chunk;
  1271 	RDisplayChannel::TBufferFormat bufferFormat(TSize(iHalInfo.iXPixels, iHalInfo.iYPixels), displayInfo().iPixelFormat);
  1272 
  1273 	test.Next(_L("Get the LDD to create a user buffer"));
  1274 	TInt err = iDisp.CreateUserBuffer(bufferFormat, chunk);
  1275 	test_KErrNone(err);
  1276 
  1277 	test.Next(_L("Register a user buffer"));
  1278 	RDisplayChannel::TBufferId bufferId;
  1279 	err = iDisp.RegisterUserBuffer(bufferId, chunk, 0);
  1280 	test_KErrNone(err);
  1281 
  1282 	test.Next(_L("Post a user buffer"));
  1283 	TRequestStatus status;
  1284 	RDisplayChannel::TPostCount postCount;
  1285 	iDisp.PostUserBuffer(bufferId, status, NULL, postCount);
  1286 	iDisp.PostLegacyBuffer(NULL, postCount);
  1287 
  1288 	test.Printf(_L("Waiting for user buffer\n"));
  1289 	User::WaitForRequest(status);
  1290 	test(status.Int() == KErrNone || status.Int() == KErrCancel);
  1291 	test.Printf(_L("Waiting for legacy buffer\n"));
  1292 	iDisp.WaitForPost(postCount, status);
  1293 	User::WaitForRequest(status);
  1294 	test_KErrNone(status.Int());
  1295 
  1296 	test.Printf(_L("Getting composition buffer\n"));
  1297 	TUint bufferIndex;
  1298 	iDisp.GetCompositionBuffer(bufferIndex, status);
  1299 	User::WaitForRequest(status);
  1300 	test_KErrNone(status.Int());
  1301 
  1302 	iDisp.PostUserBuffer(bufferId, status, NULL, postCount);
  1303 	iDisp.PostCompositionBuffer(NULL, postCount);
  1304 
  1305 	test.Printf(_L("Waiting for user buffer\n"));
  1306 	User::WaitForRequest(status);
  1307 	test(status.Int() == KErrNone || status.Int() == KErrCancel);
  1308 	test.Printf(_L("Waiting for composition buffer\n"));
  1309 	iDisp.WaitForPost(postCount, status);
  1310 	User::WaitForRequest(status);
  1311 	test_KErrNone(status.Int());
  1312 
  1313 	test.Printf(_L("Deregistering user buffers\n"));
  1314 	err = iDisp.DeregisterUserBuffer(bufferId);
  1315 	test_KErrNone(err);
  1316 
  1317 	test.Printf(_L("Done, closing shared chunk\n"));
  1318 	chunk.Close();
  1319 #endif // defined(_DEBUG) && !defined(__WINS__)
  1320 	}
  1321 
  1322 void CDisplayChannelTest::Start()
  1323 /**
  1324  Run all of the test cases
  1325  */
  1326 	{
  1327 	CompleteSelf(ETestDisplayInfo);
  1328 	}
  1329 
  1330 void CDisplayChannelTest::CompleteSelf(TTestState aNextState)
  1331 /*
  1332 Advances to the next test state for test steps that don't invoke
  1333 asynchronous requests on this AO. 
  1334 */
  1335 	{	
  1336 	iState = aNextState;
  1337 	TRequestStatus* status = &iStatus;	
  1338 	SetActive();
  1339 	User::RequestComplete(status, KErrNone);
  1340 	}
  1341 
  1342 void CDisplayChannelTest::DoCancel()
  1343 	{	
  1344 	iAsyncHelper->Cancel();
  1345 	}
  1346 
  1347 TInt CDisplayChannelTest::RunError(TInt aError)
  1348 	{
  1349 	test_KErrNone(aError);
  1350 	return KErrNone;
  1351 	}
  1352 
  1353 void CDisplayChannelTest::RunL()
  1354 /**
  1355  Run all of the tests where the API is defined for that version.
  1356  */
  1357 	{
  1358 	test_KErrNone(iStatus.Int());
  1359 	
  1360 	test.Printf(_L("Test state %d\n"), iState);
  1361 	switch (iState)
  1362 		{
  1363 		case ETestDisplayInfo:
  1364 			CheckDisplayInfo();
  1365 			CompleteSelf(ETestCompositionBuffers);
  1366 			break;
  1367 		case ETestCompositionBuffers:
  1368 			CheckCompositionBuffers();
  1369 			CompleteSelf(ETestUserBuffers);
  1370 			break;
  1371 		case ETestUserBuffers:
  1372 			CheckUserBuffers();
  1373 			CompleteSelf(ETestRotations);
  1374 			break;
  1375 		case ETestRotations:
  1376 			CheckRotations();			
  1377 			CompleteSelf(ETestWaitForPostDoCancel);				
  1378 			break;
  1379 		case ETestWaitForPostDoCancel:
  1380 			// Post the composition buffer, register wait and cancel wait.
  1381 			iDisp.PostCompositionBuffer(NULL, iDummyPostCount);
  1382 			iDisp.WaitForPost(iDummyPostCount, iAsyncHelper->Status());
  1383 			iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
  1384 			iDisp.CancelWaitForPost();
  1385 			CompleteSelf(ETestWaitForPostCheckCancel);
  1386 			break;
  1387 		case ETestWaitForPostCheckCancel:
  1388 			test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
  1389 			CompleteSelf(ETestGetCompositionBufferDoCancel);
  1390 			break;
  1391 		case ETestGetCompositionBufferDoCancel:
  1392 			iDisp.GetCompositionBuffer(iDummyCompositionBuffer, iAsyncHelper->Status());
  1393 			iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
  1394 			iDisp.CancelGetCompositionBuffer();
  1395 			CompleteSelf(ETestGetCompositionBufferCheckCancel);
  1396 			break;
  1397 		case ETestGetCompositionBufferCheckCancel:
  1398 			test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
  1399 			
  1400 			if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
  1401 				{
  1402 				CompleteSelf(ETestV11inV10);
  1403 				}
  1404 			else
  1405 				{
  1406 				CompleteSelf(ETestDisplayChange);
  1407 				}
  1408 			break;
  1409 		case ETestDisplayChange:	// API in v1.1 +
  1410 			CheckDisplayChange();
  1411 			CompleteSelf(ETestDisplayChangeDoCancel);
  1412 			break;			
  1413 		case ETestDisplayChangeDoCancel:	// API in v1.1 +
  1414 			iDisp.NotifyOnDisplayChangeCancel();
  1415 			CompleteSelf(ETestDisplayChangeCheckCancel);
  1416 			break;
  1417 		case ETestDisplayChangeCheckCancel:	// API in v1.1 +
  1418 			test(iAsyncHelperResult == KErrCancel);	// display should not have changed
  1419 			CompleteSelf(ETestResolutions);
  1420 			break;
  1421 		case ETestResolutions:	// API in v1.1 +
  1422 			CheckResolutions();
  1423 			CompleteSelf(ETestPixelFormats);
  1424 			break;
  1425 		case ETestPixelFormats:	// API in v1.1 +
  1426 			CheckPixelFormats();
  1427 			CompleteSelf(ETestBufferFormats);
  1428 			break;
  1429 		case ETestBufferFormats:	// API in v1.1 +
  1430 			CheckBufferFormat();
  1431 			CompleteSelf(EVisualTest);
  1432 			break;
  1433 		case ETestV11inV10:			
  1434 			CheckV11inV10();
  1435 			CompleteSelf(EVisualTest);
  1436 			break;
  1437 		case EVisualTest:
  1438 			VisualTest();	// visual test is async because of WaitForPost
  1439 			break;
  1440 		case ETestSecondHandle:
  1441 			CheckSecondHandle();
  1442 			CompleteSelf(ETestBufferTransitions);
  1443 			break;
  1444 		case ETestBufferTransitions:
  1445 			TestBufferTransitions();
  1446 			CompleteSelf(ETestFinished);
  1447 			break;
  1448 		case ETestFinished:
  1449 			CActiveScheduler::Stop();
  1450 			break;
  1451 		default:
  1452 			test(EFalse);		
  1453 		}
  1454 	}
  1455 
  1456 void MainL()
  1457 /**
  1458  Initialise RTest and run the tests
  1459  */
  1460 	{
  1461 	test.Start(_L("Testing display channel driver"));
  1462 	
  1463 	// If the device driver does not exist then this is considered a pass
  1464 	// because the display channel is not a mandatory part of the base port
  1465 	_LIT(KLdd, "display0.ldd");
  1466 	test.Printf(_L("Loading logical %S\n"), &KLdd);
  1467 	TInt err = User::LoadLogicalDevice(KLdd);	
  1468 	test(err == KErrNone || err == KErrAlreadyExists || err == KErrNotFound);		
  1469 	
  1470 	// Only test for kenel memory leaks for non WINSCW builds as the WINSCW LDD is obsolete and would
  1471 	// take forever to debug
  1472 #ifndef __WINS__
  1473 	__KHEAP_MARK;
  1474 #endif // ! __WINS__
  1475 
  1476 	if (err == KErrNone || err == KErrAlreadyExists)
  1477 		{
  1478 		TInt numberOfScreens;
  1479 		User::LeaveIfError(HAL::Get(HAL::EDisplayNumberOfScreens, numberOfScreens));
  1480 		for (TInt screenNum  = 0; screenNum < numberOfScreens; ++screenNum)
  1481 			{
  1482 			CActiveScheduler* s = new(ELeave) CActiveScheduler();
  1483 			CActiveScheduler::Install(s);
  1484 			CleanupStack::PushL(s);
  1485 			CDisplayChannelTest* displayTest = CDisplayChannelTest::NewLC(screenNum);
  1486 			displayTest->Start();
  1487 			s->Start();
  1488 			CleanupStack::PopAndDestroy(2, s);	// s, displayTest 
  1489 			}
  1490 		}
  1491 	else
  1492 		{
  1493 		test.Printf(_L("display0.ldd not present. Finishing test.\n"));
  1494 		}
  1495 	
  1496 #ifndef __WINS__
  1497 	__KHEAP_MARKEND;
  1498 #endif // ! __WINS__
  1499 
  1500 	test.End();
  1501 	}
  1502 
  1503 TInt E32Main()
  1504 /**
  1505  Create cleanup stack, initialise memory checks and run the tests.
  1506  */
  1507 	{
  1508 	CTrapCleanup* cleanup = CTrapCleanup::New();
  1509 	if (!cleanup)
  1510 		{
  1511 		return KErrNoMemory;
  1512 		}
  1513 	__UHEAP_MARK;
  1514 	test.Title();
  1515 	TRAPD(err, MainL());
  1516 	test.Close();
  1517 	__UHEAP_MARKEND;
  1518 	delete cleanup;
  1519 	return err;
  1520 	}