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