1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/dispchan/t_dispchan.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1520 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// This test should not depend on any external data files and should work with
1.18 +// the default (empty) epoc.ini file.
1.19 +// The test should be run without the Graphics GCE enabled but with the Base GCE
1.20 +// driver enabled. On the emulator this can be done by launcing with -Dtextshell --
1.21 +// and on the H4 build a textshell ROM with -DSYMBIAN_BASE_USE_GCE but NOT
1.22 +// -DSYMBIAN_GRAPHICS_USE_GCE
1.23 +// In the visual tests some flickering may occur due to updates to the console. On
1.24 +// the emulator it is possible to configure a second screen so that the console updates
1.25 +// will only happen on one screen. The test automatically runs on every screen available.
1.26 +//
1.27 +//
1.28 +
1.29 +#define __E32TEST_EXTENSION__
1.30 +
1.31 +#include <dispchannel.h>
1.32 +#include <e32std.h>
1.33 +#include <e32std_private.h>
1.34 +#include <e32def.h>
1.35 +#include <e32def_private.h>
1.36 +#include <e32svr.h>
1.37 +#include <e32test.h>
1.38 +#include <pixelformats.h>
1.39 +#include <hal.h>
1.40 +
1.41 +RTest test(_L("Display Channel device driver unit tests"));
1.42 +
1.43 +/** Maximum probable pixel resolution width or height */
1.44 +static const TInt KMaxExpectedPixelRes = 10000;
1.45 +
1.46 +/** Unlikely to ever have a > 1000 Hz refresh rate */
1.47 +static const TInt KMaxExpectedRefreshRate = 1000;
1.48 +
1.49 +/** Time (in microseconds) for each visual test */
1.50 +static const TInt KDrawWaitTime = 1000000;
1.51 +
1.52 +/** Array of supported rotations */
1.53 +static const RDisplayChannel::TDisplayRotation KRotations[] = {
1.54 + RDisplayChannel::ERotationNormal,
1.55 + RDisplayChannel::ERotation90CW,
1.56 + RDisplayChannel::ERotation180,
1.57 + RDisplayChannel::ERotation270CW};
1.58 +static const TInt KNumRotations = sizeof(KRotations) / sizeof(RDisplayChannel::TDisplayRotation);
1.59 +
1.60 +/** Array of pixel formats to try for visual test */
1.61 +static const RDisplayChannel::TPixelFormat KPixelFormats[] = {
1.62 + EUidPixelFormatYUV_422Interleaved16bit, // not supported on emulator but should not be a fatal error
1.63 + EUidPixelFormatXRGB_4444,
1.64 + EUidPixelFormatARGB_4444,
1.65 + EUidPixelFormatRGB_565,
1.66 + EUidPixelFormatXRGB_8888,
1.67 + EUidPixelFormatARGB_8888,
1.68 + EUidPixelFormatARGB_8888_PRE
1.69 +};
1.70 +static const TInt KNumPixelFormats = sizeof(KPixelFormats) / sizeof(RDisplayChannel::TPixelFormat);
1.71 +
1.72 +/**
1.73 +Encapsulates display related HAL information.
1.74 +*/
1.75 +class THalDisplayInfo
1.76 + {
1.77 +public:
1.78 + TBool iIsMono;
1.79 + TBool iIsPalettized;
1.80 + TInt iBitsPerPixel;
1.81 + TInt iMemoryAddress;
1.82 + TInt iMemoryHandle;
1.83 + TInt iState;
1.84 + TInt iColors;
1.85 + TInt iXPixels;
1.86 + TInt iYPixels;
1.87 + TInt iXTwips;
1.88 + TInt iYTwips;
1.89 + TInt iNumModes;
1.90 + TInt iMode;
1.91 + TInt iOffsetBetweenLines;
1.92 + TInt iOffsetToFirstPixel;
1.93 + TBool iIsPixelOrderRGB;
1.94 + TBool iIsPixelOrderLandscape;
1.95 + };
1.96 +
1.97 +/**
1.98 +Helper class that waits for RDisplayChannel asynchronous requests and
1.99 +can cancel them if necessary. The purpose of this class is so that the main
1.100 +test class can create an asynchronous request and also simulate the completion
1.101 +of that request e.g. faking a display change event.
1.102 +*/
1.103 +class CAsyncHelper : public CActive
1.104 + {
1.105 +public:
1.106 + inline CAsyncHelper(RDisplayChannel& aDisp);
1.107 + inline ~CAsyncHelper();
1.108 + inline TRequestStatus& Status();
1.109 + void WaitForOperation(TInt* aResult);
1.110 +private:
1.111 + // From CActive
1.112 + inline void DoCancel();
1.113 + inline void RunL();
1.114 +private:
1.115 + RDisplayChannel& iDisp;
1.116 + TInt* iResult;
1.117 + };
1.118 +
1.119 +inline CAsyncHelper::CAsyncHelper(RDisplayChannel& aDisp) : CActive(EPriorityHigh), iDisp(aDisp) {CActiveScheduler::Add(this);}
1.120 +inline CAsyncHelper::~CAsyncHelper() {Deque();}
1.121 +inline TRequestStatus& CAsyncHelper::Status() {return iStatus;}
1.122 +// Writes the iStatus.Int() to the address defined by the client of this AO
1.123 +inline void CAsyncHelper::RunL() {*iResult = iStatus.Int();}
1.124 +
1.125 +void CAsyncHelper::WaitForOperation(TInt* aResult)
1.126 +/**
1.127 +Invokes SetActive() to wait for the asynchronous operation to complete. The completion
1.128 +code is copied to the aResult when RunL is invoked.
1.129 +@param aResult out parameter that will be set to iStatus.Int()
1.130 +*/
1.131 + {
1.132 + iResult = aResult;
1.133 + // Set the result to default value that is unlikely to be returned by the real API
1.134 + *aResult = KMaxTInt;
1.135 + SetActive();
1.136 + }
1.137 +
1.138 +void CAsyncHelper::DoCancel()
1.139 + {
1.140 + // Driver should fail if cancel is called when there is not standing request
1.141 + // so cancel just attempts to cancel everything.
1.142 + iDisp.CancelGetCompositionBuffer();
1.143 + iDisp.CancelPostUserBuffer();
1.144 + iDisp.CancelWaitForPost();
1.145 + iDisp.NotifyOnDisplayChangeCancel();
1.146 + }
1.147 +
1.148 +/**
1.149 +Class to test device driver for RDisplayChannel
1.150 +*/
1.151 +class CDisplayChannelTest : public CActive
1.152 + {
1.153 + enum TTestState {
1.154 + ETestDisplayInfo,
1.155 + ETestCompositionBuffers,
1.156 + ETestUserBuffers,
1.157 + ETestRotations,
1.158 + ETestDisplayChange,
1.159 + ETestDisplayChangeDoCancel,
1.160 + ETestDisplayChangeCheckCancel,
1.161 + ETestGetCompositionBufferDoCancel,
1.162 + ETestGetCompositionBufferCheckCancel,
1.163 + ETestWaitForPostDoCancel,
1.164 + ETestWaitForPostCheckCancel,
1.165 + ETestResolutions,
1.166 + ETestPixelFormats,
1.167 + ETestBufferFormats,
1.168 + ETestV11inV10,
1.169 + EVisualTest,
1.170 + ETestSecondHandle,
1.171 + ETestBufferTransitions,
1.172 + ETestFinished
1.173 + };
1.174 +
1.175 + public:
1.176 + static CDisplayChannelTest* NewLC(TInt aScreenId);
1.177 + void Start();
1.178 + ~CDisplayChannelTest();
1.179 +
1.180 + private:
1.181 + // From CActive
1.182 + void DoCancel();
1.183 + TInt RunError(TInt aError);
1.184 + void RunL();
1.185 +
1.186 + private:
1.187 + CDisplayChannelTest(TInt aScreenId);
1.188 + void CompleteSelf(TTestState aNextState);
1.189 +
1.190 + // The tests
1.191 + void CheckDisplayInfo();
1.192 + void CheckResolutions();
1.193 + void CheckPixelFormats();
1.194 + void CheckDisplayChange();
1.195 + void CheckCompositionBuffers();
1.196 + void CheckBufferFormat();
1.197 + void CheckUserBuffers();
1.198 + void CheckRotations();
1.199 + TBool IsValidRotation(RDisplayChannel::TDisplayRotation aRotation);
1.200 + TBool IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat);
1.201 + void CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation);
1.202 + void CheckV11inV10();
1.203 + void VisualTest();
1.204 + void DrawLegacyBuffer(TInt aStep);
1.205 + void DrawFillToMemory(TUint8* aFirstPixelAddr, TInt aOffsetBetweenLines,
1.206 + RDisplayChannel::TPixelFormat aPixelFormat, TInt aWidth, TInt aHeight, TInt aStep);
1.207 + void DrawCompositionBuffer(
1.208 + RDisplayChannel::TPostCount& aPostCount,
1.209 + RDisplayChannel::TBufferFormat aBufferFormat,
1.210 + RDisplayChannel::TDisplayRotation aRotation, TInt aStep);
1.211 + void GetHalDisplayInfo();
1.212 + void CheckSecondHandle();
1.213 + void TestBufferTransitions();
1.214 +
1.215 + private:
1.216 + RDisplayChannel iDisp; /// handle to display channel device driver
1.217 + TVersion iVersion; /// version number of disp channel driver interface
1.218 + THalDisplayInfo iHalInfo; /// info about legacy buffer from HAL
1.219 + TInt iScreenId; /// run tests on each screen
1.220 + TTestState iState; /// the current test
1.221 + CAsyncHelper *iAsyncHelper;
1.222 + TInt iAsyncHelperResult; /// set to iAyncHelper::iStatus.Int()
1.223 + RArray<RDisplayChannel::TResolution> iResolutions;
1.224 + RArray<RDisplayChannel::TPixelFormat> iPixelFormats;
1.225 + TInt iVisualTestFormatIndex; /// index of the current pixel format in visual test
1.226 + TInt iVisualTestRotationIndex; /// index of the current rotation in the visual test
1.227 + TUint iDummyCompositionBuffer; /// dummy var used to test cancel of GetCompositionBuffer
1.228 + RDisplayChannel::TPostCount iDummyPostCount; /// dummy var used to test CancelWaitForPost
1.229 + };
1.230 +
1.231 +// Gets a HAL value, logs the result and errors if HAL::Get failed
1.232 +#define DBG_HAL(DEVICE, ATT, VAL, ERR, IN) \
1.233 + { \
1.234 + VAL = IN;\
1.235 + ERR = HAL::Get(DEVICE, ATT, VAL); \
1.236 + test.Printf(_L(#ATT)); \
1.237 + test.Printf(_L(" device %d err = %d, val = %d\n"), DEVICE, ERR, VAL); \
1.238 + test_KErrNone(ERR); \
1.239 + }
1.240 +
1.241 +void CDisplayChannelTest::GetHalDisplayInfo()
1.242 +/**
1.243 +Retrieves display related HAL settings. This also initialises the legacy buffer by retrieving
1.244 +HAL::EDisplayMemoryAddress
1.245 +*/
1.246 + {
1.247 + TInt err = KErrNotSupported;
1.248 +
1.249 + DBG_HAL(iScreenId, HAL::EDisplayMemoryAddress, iHalInfo.iMemoryAddress, err, 0);
1.250 +
1.251 + iHalInfo.iMemoryHandle = 0;
1.252 + err = HAL::Get(iScreenId, HAL::EDisplayMemoryHandle, iHalInfo.iMemoryHandle);
1.253 + test(err == KErrNone || err == KErrNotSupported);
1.254 + test.Printf(_L("HAL::EDisplayMemoryHandle returned err %d\n"), err);
1.255 + if (err == KErrNone)
1.256 + {
1.257 + // Handle is not needed so don't leak it
1.258 + RHandleBase h;
1.259 + h.SetHandle(iHalInfo.iMemoryHandle);
1.260 + h.Close();
1.261 + }
1.262 +
1.263 + // This is mostly for information purposes to ensure the legacy buffer is sane.
1.264 + DBG_HAL(iScreenId, HAL::EDisplayState, iHalInfo.iState, err, 0);
1.265 + DBG_HAL(iScreenId, HAL::EDisplayColors, iHalInfo.iColors, err, 0);
1.266 + DBG_HAL(iScreenId, HAL::EDisplayXPixels, iHalInfo.iXPixels, err, 0);
1.267 + DBG_HAL(iScreenId, HAL::EDisplayYPixels, iHalInfo.iYPixels, err, 0);
1.268 + DBG_HAL(iScreenId, HAL::EDisplayXTwips, iHalInfo.iXTwips, err, 0);
1.269 + DBG_HAL(iScreenId, HAL::EDisplayYTwips, iHalInfo.iYTwips, err, 0);
1.270 + DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderRGB, iHalInfo.iIsPixelOrderRGB, err, 0);
1.271 + DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderLandscape, iHalInfo.iIsPixelOrderLandscape, err, 0);
1.272 +
1.273 + DBG_HAL(iScreenId, HAL::EDisplayNumModes, iHalInfo.iNumModes, err, 0);
1.274 + DBG_HAL(iScreenId, HAL::EDisplayMode, iHalInfo.iMode, err, 0);
1.275 +
1.276 + // Get info for current display mode
1.277 + DBG_HAL(iScreenId, HAL::EDisplayIsMono, iHalInfo.iIsMono, err, iHalInfo.iMode);
1.278 + DBG_HAL(iScreenId, HAL::EDisplayBitsPerPixel, iHalInfo.iBitsPerPixel, err, iHalInfo.iMode);
1.279 + DBG_HAL(iScreenId, HAL::EDisplayOffsetBetweenLines, iHalInfo.iOffsetBetweenLines, err, iHalInfo.iMode);
1.280 + DBG_HAL(iScreenId, HAL::EDisplayOffsetToFirstPixel, iHalInfo.iOffsetToFirstPixel, err, iHalInfo.iMode);
1.281 + DBG_HAL(iScreenId, HAL::EDisplayIsPalettized, iHalInfo.iIsPalettized, err, iHalInfo.iMode);
1.282 + }
1.283 +
1.284 +CDisplayChannelTest::CDisplayChannelTest(TInt aScreenId)
1.285 +/**
1.286 +Constructor
1.287 +@param aScreenId the screen number to run the test on
1.288 +*/
1.289 + : CActive(EPriorityStandard), iScreenId(aScreenId)
1.290 + {
1.291 + TVersion versionRequired = iDisp.VersionRequired();
1.292 + test.Printf(_L("*** Opening display channel for screen %d. Test compiled against version %d.%d.%d ***\n"),
1.293 + iScreenId, versionRequired.iMajor, versionRequired.iMinor, versionRequired.iBuild);
1.294 + TInt err = iDisp.Open(iScreenId);
1.295 + test_KErrNone(err);
1.296 +
1.297 + test.Printf(_L("Successfully opened display channel for screen %d\n"), iScreenId);
1.298 +
1.299 + // This test should be updated if a change to the driver requires a version change
1.300 + err = iDisp.Version(iVersion);
1.301 + if (err == KErrNotSupported)
1.302 + {
1.303 + test.Printf(_L("Version API not supported. Assuming v1.0.0\n"));
1.304 + iVersion.iMajor = 1;
1.305 + iVersion.iMinor = 0;
1.306 + iVersion.iBuild = 0;
1.307 + }
1.308 + else
1.309 + {
1.310 + test.Printf(_L("Display channel driver version %d.%d.%d\n"),
1.311 + iVersion.iMajor, iVersion.iMinor, iVersion.iBuild);
1.312 + test_KErrNone(err);
1.313 + }
1.314 + test(iVersion.iMajor >= 1 && iVersion.iMinor >= 0);
1.315 + GetHalDisplayInfo();
1.316 + CActiveScheduler::Add(this);
1.317 +
1.318 + iAsyncHelper = new CAsyncHelper(iDisp);
1.319 + test_NotNull(iAsyncHelper);
1.320 + }
1.321 +
1.322 +CDisplayChannelTest::~CDisplayChannelTest()
1.323 +/**
1.324 +Destructor
1.325 +*/
1.326 + {
1.327 + Deque();
1.328 + delete iAsyncHelper;
1.329 + iPixelFormats.Close();
1.330 + iResolutions.Close();
1.331 + iDisp.Close();
1.332 + }
1.333 +
1.334 +CDisplayChannelTest* CDisplayChannelTest::NewLC(TInt aScreenId)
1.335 +/**
1.336 +Factory method that creates a new instance of the screen
1.337 +display channel unit test object and places a pointer to this on the cleanup stack
1.338 +
1.339 +@param aScreenId the screen number to run the test on
1.340 +@return a pointer to the new CDisplayTest object.
1.341 +*/
1.342 + {
1.343 + CDisplayChannelTest* self = new(ELeave) CDisplayChannelTest(aScreenId);
1.344 + CleanupStack::PushL(self);
1.345 + return self;
1.346 + }
1.347 +
1.348 +void CDisplayChannelTest::CheckDisplayInfo()
1.349 +/**
1.350 +Check the values returned by CheckDisplayInfo
1.351 +*/
1.352 + {
1.353 + test.Next(_L("Test GetDisplayInfo"));
1.354 + TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
1.355 +
1.356 + test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
1.357 +
1.358 + // This test only works with 24 and 32 BPP displays and crashes otherwise. Test for this and display
1.359 + // a nice human readable message rather than just crashing
1.360 + if ((infoPkg().iBitsPerPixel != 24) && (infoPkg().iBitsPerPixel != 32))
1.361 + {
1.362 + TBuf<256> message;
1.363 +
1.364 + 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);
1.365 + test.Printf(message);
1.366 +
1.367 + // And fail the test for the benefit of automated ONB tests
1.368 + test_Equal(infoPkg().iBitsPerPixel, 24);
1.369 + }
1.370 +
1.371 + test_Compare(infoPkg().iBitsPerPixel, >=, 1);
1.372 + test_Compare(infoPkg().iAvailableRotations, !=, 0);
1.373 +
1.374 + // check for invalid rotations i.e. those not defined by TRotation
1.375 + test((infoPkg().iAvailableRotations & 0xFFF0) == 0);
1.376 +
1.377 + // Check that the refresh rate field isn't garbage
1.378 + test_Compare(infoPkg().iRefreshRateHz, >=, 1);
1.379 + test_Compare(infoPkg().iRefreshRateHz, <=, KMaxExpectedRefreshRate);
1.380 +
1.381 + // Should always be at least one composition buffer
1.382 + test_Compare(infoPkg().iNumCompositionBuffers, >=, 1);
1.383 + }
1.384 +
1.385 +void CDisplayChannelTest::CheckResolutions()
1.386 +/**
1.387 + Validate that the APIs to get / set resolutions.
1.388 +
1.389 + Tests<br>
1.390 + NumberOfResolutions, GetResolutions, GetResolution, GetRotation
1.391 + */
1.392 + {
1.393 + test.Next(_L("Test NumberOfResolutions, GetResolutions, GetResolution, GetRotation"));
1.394 +
1.395 + // Get and reserve space for expected number of resolutions
1.396 + TInt n = iDisp.NumberOfResolutions();
1.397 + test_Compare(n, >=, 1);
1.398 +
1.399 + iResolutions.Reset();
1.400 + test_KErrNone(iResolutions.Reserve(n));
1.401 + for (TInt i = 0; i < n; ++i)
1.402 + {
1.403 + test_KErrNone(iResolutions.Append(RDisplayChannel::TResolution(TSize(0,0), TSize(0,0), 0)));
1.404 + }
1.405 +
1.406 + // Retrieve the resolutions and make sure the number of resolutions returned matches the
1.407 + // expected number. It is assumed that the display state won't be changed during the execution
1.408 + // of this test.
1.409 + TInt actualResolutions = 0;
1.410 + TPtr8 resPtr(reinterpret_cast<TUint8*>(&iResolutions[0]),
1.411 + sizeof(RDisplayChannel::TResolution) * n, sizeof(RDisplayChannel::TResolution) * n);
1.412 + test_KErrNone(iDisp.GetResolutions(resPtr, actualResolutions));
1.413 + test_Equal(n, actualResolutions);
1.414 +
1.415 + test.Printf(_L("Supported resolutions"));
1.416 + for (TInt res = 0; res < n; ++res)
1.417 + {
1.418 + RDisplayChannel::TResolution& r = iResolutions[res];
1.419 + test.Printf(_L("pixelX = %d heightX = %d twipsX = %d twipsY = %d flags = 0x%08x\n"),
1.420 + r.iPixelSize.iWidth, r.iPixelSize.iHeight, r.iTwipsSize.iWidth, r.iTwipsSize.iHeight, r.iFlags);
1.421 +
1.422 + // If either pixel height or pixel width is zero then both must be zero
1.423 + // If either pixel height or pixel width is non-zero then both must be positive
1.424 + test((r.iPixelSize.iHeight == 0 && r.iPixelSize.iWidth == 0) ||
1.425 + (r.iPixelSize.iHeight > 0 && r.iPixelSize.iWidth > 0));
1.426 +
1.427 + // Test resolutions are sane
1.428 + test(r.iPixelSize.iHeight <= KMaxExpectedPixelRes && r.iPixelSize.iWidth <= KMaxExpectedPixelRes);
1.429 +
1.430 + // If either twips height or pixel width is zero then both must be zero
1.431 + // If either twips height or pixel width is non-zero then both must be positive
1.432 + test((r.iTwipsSize.iHeight == 0 && r.iTwipsSize.iWidth == 0) ||
1.433 + (r.iTwipsSize.iHeight > 0 && r.iTwipsSize.iWidth > 0));
1.434 +
1.435 + // twips resolution can be zero iff pixel resolution is also zero
1.436 + test((r.iPixelSize.iHeight == 0 && r.iTwipsSize.iHeight == 0) ||
1.437 + (r.iPixelSize.iHeight > 0 && r.iTwipsSize.iHeight > 0));
1.438 +
1.439 + // At least one rotation must be supported. Ignore other bits in the flags field
1.440 + test(r.iFlags & RDisplayChannel::ERotationAll != 0);
1.441 + }
1.442 +
1.443 + // Get current resolution in pixels
1.444 + TSize currentResolution;
1.445 + test_KErrNone(iDisp.GetResolution(currentResolution));
1.446 +
1.447 + // Get current resolution in twips
1.448 + TSize currentTwips;
1.449 + test_KErrNone(iDisp.GetTwips(currentTwips));
1.450 +
1.451 + RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
1.452 + test(IsValidRotation(currentRotation));
1.453 +
1.454 + // The current resolution and rotation must be in the list of supported resolutions
1.455 + TBool foundCurrentRes = EFalse;
1.456 + for (TInt j = iResolutions.Count() - 1; j >= 0; --j)
1.457 + {
1.458 + if (iResolutions[j].iPixelSize == currentResolution &&
1.459 + iResolutions[j].iTwipsSize == currentTwips &&
1.460 + iResolutions[j].iFlags & currentRotation)
1.461 + {
1.462 + foundCurrentRes = ETrue;
1.463 + break;
1.464 + }
1.465 + }
1.466 + test(foundCurrentRes);
1.467 +
1.468 + // Now and try every supported resolution
1.469 + TInt err;
1.470 + for (TInt k = iResolutions.Count() - 1; k >= 0; --k)
1.471 + {
1.472 + err = iDisp.SetResolution(iResolutions[k].iPixelSize);
1.473 + test(err == KErrNone || err == KErrNotSupported);
1.474 + }
1.475 + // attempt to set back to original resolution, this could fail
1.476 + err = iDisp.SetResolution(currentResolution);
1.477 + test(err == KErrNone || err == KErrNotSupported);
1.478 + }
1.479 +
1.480 +void CDisplayChannelTest::CheckPixelFormats()
1.481 +/**
1.482 + Validates that the pixel format APIs are sane/consistent.
1.483 +
1.484 + In version 1.1 the APIs are just stubs that return KErrNotSupported
1.485 + */
1.486 + {
1.487 + test.Next(_L("Test NumberOfPixelFormats, GetPixelFormats"));
1.488 +
1.489 + // At least one pixel format must be supported
1.490 + TInt n = iDisp.NumberOfPixelFormats();
1.491 +
1.492 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.493 + {
1.494 + test_Compare(n, ==, KErrNotSupported);
1.495 + n = 1; // Override return to test stub for GetPixelFormats
1.496 + }
1.497 + else
1.498 + {
1.499 + test_Compare(n, >=, 1);
1.500 + }
1.501 +
1.502 + TInt err = iPixelFormats.Reserve(n);
1.503 + test_KErrNone(err);
1.504 + for (TInt i = 0; i < n; ++i)
1.505 + {
1.506 + test_KErrNone(iPixelFormats.Append(-1));
1.507 + }
1.508 + TPtr8 pixelFormatsPtr(reinterpret_cast<TUint8*>(&iPixelFormats[0]),
1.509 + sizeof(RDisplayChannel::TPixelFormat) * n, sizeof(RDisplayChannel::TPixelFormat) * n);
1.510 +
1.511 + TInt actualFormats = -1;
1.512 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.513 + {
1.514 + test_Compare(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats), ==, KErrNotSupported);
1.515 + }
1.516 + else
1.517 + {
1.518 + test_KErrNone(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats));
1.519 +
1.520 + // The number of formats shouldn't have changed whilst this test is running
1.521 + test_Equal(n, actualFormats);
1.522 + RArray<RDisplayChannel::TPixelFormat> pixelFormatsArray(
1.523 + reinterpret_cast<RDisplayChannel::TPixelFormat*>(&pixelFormatsPtr[0]), actualFormats);
1.524 +
1.525 + // Check the pixel formats returned are all valid
1.526 + for (TInt pf = pixelFormatsArray.Count() - 1; pf >= 0; --pf)
1.527 + {
1.528 + IsValidPixelFormat(pixelFormatsArray[pf]);
1.529 + }
1.530 + }
1.531 + }
1.532 +
1.533 +void CDisplayChannelTest::CheckDisplayChange()
1.534 +/**
1.535 + Register for display change notification then immediately cancel.
1.536 + */
1.537 + {
1.538 + test.Next(_L("Test NotifyOnDisplayChange, NotifyOnDisplayChangeCancel"));
1.539 + // Cancel should be allowed even if NotifyOnyDisplayChange has not been called
1.540 + iDisp.NotifyOnDisplayChangeCancel();
1.541 +
1.542 + iDisp.NotifyOnDisplayChange(iAsyncHelper->Status());
1.543 + iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
1.544 + }
1.545 +
1.546 +void CDisplayChannelTest::DrawFillToMemory(
1.547 + TUint8* aFirstPixelAddr,
1.548 + TInt aOffsetBetweenLines,
1.549 + RDisplayChannel::TPixelFormat aPixelFormat,
1.550 + TInt aWidth,
1.551 + TInt aHeight,
1.552 + TInt aStep)
1.553 +/**
1.554 + Draws a shaded fill to a memory region
1.555 + @param aFirstPixelAddr the address of the first pixel in the buffer.
1.556 + @param aOffsetBetweenLines offset between pixels at the start of each line
1.557 + @param aBpp bits per pixel
1.558 + @param aWidth width of the region in pixels
1.559 + @param aHeight height of the region in pixels
1.560 + @aStep aStep integer >= 1 to vary the pattern by test number
1.561 + */ {
1.562 + test.Printf(_L("DrawFileToMemory\npixelformat = 0x%08x offsetbetweenlines = %d pixel address = 0x%08x width=%d height = %d\n"),
1.563 + aPixelFormat, aOffsetBetweenLines, aFirstPixelAddr, aWidth, aHeight);
1.564 +
1.565 +
1.566 + TInt xShadeMax = 0xFF;
1.567 + TInt yShadeMax = 0xFF;
1.568 +
1.569 + if (aPixelFormat == EUidPixelFormatRGB_565)
1.570 + {
1.571 + xShadeMax = 0x3F; // 6 bits for green
1.572 + yShadeMax = 0x1F;
1.573 + }
1.574 + else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
1.575 + {
1.576 + xShadeMax = 0x0F;
1.577 + yShadeMax = 0x0F;
1.578 + }
1.579 +
1.580 + aStep = Max(1, aStep);
1.581 + TUint8* lineAddr = aFirstPixelAddr;
1.582 + for (TInt y = 0; y < aHeight; ++y)
1.583 + {
1.584 + TInt yShade = (y * yShadeMax) / aHeight;
1.585 + TUint8* pixelAddr = lineAddr;
1.586 + for (TInt x = 0; x < aWidth; ++x)
1.587 + {
1.588 + TInt xShade = (x * xShadeMax) / aWidth;
1.589 + TUint8 red = 0;
1.590 + TUint8 green = 0;
1.591 + TUint8 blue = 0;
1.592 +
1.593 + if ( aStep == 0 || y > aStep * 10)
1.594 + {
1.595 + // Green top left, blue bottom right
1.596 + green = static_cast<TUint8>(xShadeMax - xShade);
1.597 + blue = static_cast<TUint8>(yShade);
1.598 + }
1.599 + else
1.600 + {
1.601 + // The size of the red band indicates different test steps
1.602 + red = static_cast<TUint8>((yShadeMax * x) / aWidth);
1.603 + }
1.604 +
1.605 + if (aPixelFormat == EUidPixelFormatRGB_565)
1.606 + {
1.607 + *pixelAddr++ = static_cast<TUint8>(blue | (green << 5));
1.608 + *pixelAddr++ = static_cast<TUint8>((green >> 3) | (red << 3));
1.609 + }
1.610 + else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
1.611 + {
1.612 + *pixelAddr++ = static_cast<TUint8>(blue | (green << 4));
1.613 + *pixelAddr++ = red;
1.614 + }
1.615 + else if (aPixelFormat == EUidPixelFormatXRGB_8888 || aPixelFormat == EUidPixelFormatARGB_8888
1.616 + || aPixelFormat == EUidPixelFormatARGB_8888)
1.617 + {
1.618 + *pixelAddr++ = blue;
1.619 + *pixelAddr++ = green;
1.620 + *pixelAddr++ = red;
1.621 + *pixelAddr++ = 0xFF; // unused
1.622 + }
1.623 + }
1.624 + lineAddr += aOffsetBetweenLines;
1.625 + }
1.626 + }
1.627 +
1.628 +void CDisplayChannelTest::DrawLegacyBuffer(TInt aStep)
1.629 + {
1.630 + test.Printf(_L("DrawLegacyBuffer\n"));
1.631 + TInt oldMode;
1.632 + TInt err;
1.633 + err = HAL::Get(iScreenId, HAL::EDisplayMode, oldMode);
1.634 + for (TInt i = 0; i < iHalInfo.iNumModes; ++i)
1.635 + {
1.636 + // Attempt to set the legacy buffer to a mode supporting 32bit (RGBA or RGBX)
1.637 + TInt modeBpp = i;
1.638 + err = HAL::Get(iScreenId, HAL::EDisplayBitsPerPixel, modeBpp);
1.639 +
1.640 + test_KErrNone(err);
1.641 + if ((modeBpp == 24 || modeBpp == 32))
1.642 + {
1.643 + TInt newMode = i;
1.644 + err = HAL::Set(iScreenId, HAL::EDisplayMode, newMode);
1.645 + break;
1.646 + }
1.647 + }
1.648 +
1.649 + GetHalDisplayInfo();
1.650 + err = HAL::Set(iScreenId, HAL::EDisplayMode, oldMode);
1.651 + TUint8* firstPixelAddr = reinterpret_cast<TUint8*>(iHalInfo.iMemoryAddress + iHalInfo.iOffsetToFirstPixel);
1.652 + TInt offsetBetweenLines = iHalInfo.iOffsetBetweenLines;
1.653 + TInt width = iHalInfo.iXPixels;
1.654 + TInt height = iHalInfo.iYPixels;
1.655 +
1.656 + if ((! iHalInfo.iIsPalettized) && iHalInfo.iIsPixelOrderRGB)
1.657 + {
1.658 + DrawFillToMemory(firstPixelAddr, offsetBetweenLines,
1.659 + EUidPixelFormatXRGB_8888, width, height, aStep);
1.660 + }
1.661 + }
1.662 +
1.663 +void CDisplayChannelTest::DrawCompositionBuffer(
1.664 + RDisplayChannel::TPostCount& aPostCount,
1.665 + RDisplayChannel::TBufferFormat aBufferFormat,
1.666 + RDisplayChannel::TDisplayRotation aRotation, TInt aStep)
1.667 +/**
1.668 +Attempts to set the requested buffer format and rotation then draws a shaded fill
1.669 +to the buffer returned by RDisplayChannel::GetCompositionBuffer.
1.670 +If it is not possible to set the desired buffer format then the actual buffer format
1.671 +is used.
1.672 +
1.673 +@param aPostCount out parameter that is set to the post count returned by PostCompositionBuffer
1.674 +@param aBufferFormat the buffer format to use for this test step
1.675 +@param aRotation the rotation to set for this test step
1.676 +@param aStep test step number
1.677 +*/
1.678 + {
1.679 + test.Printf(_L("DrawCompositionBuffer\n"));
1.680 +
1.681 + TBool configChanged;
1.682 + TInt err;
1.683 +
1.684 + RDisplayChannel::TBufferFormat actualBufferFormat(TSize(0,0),0);
1.685 + if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
1.686 + {
1.687 + // It should be possible to set the rotation and the buffer format in either order.
1.688 + // To test this the order is swapped every test step
1.689 + if (aStep % 2 == 0)
1.690 + {
1.691 + test_KErrNone(iDisp.SetRotation(aRotation, configChanged));
1.692 + err = iDisp.SetBufferFormat(aBufferFormat);
1.693 + }
1.694 + else
1.695 + {
1.696 + err = iDisp.SetBufferFormat(aBufferFormat);
1.697 + test_KErrNone(iDisp.SetRotation(aRotation, configChanged));
1.698 + }
1.699 + if (err != KErrNone)
1.700 + {
1.701 + test.Printf(_L("Unable to set buffer format 0x%08x width %d height %d"),
1.702 + aBufferFormat.iPixelFormat, aBufferFormat.iSize.iWidth, aBufferFormat.iSize.iHeight);
1.703 + }
1.704 + test_KErrNone(iDisp.GetBufferFormat(actualBufferFormat));
1.705 + }
1.706 + else
1.707 + {
1.708 + // buffer format not switched in v1.1 so test just validates post / wait for post
1.709 + TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
1.710 + test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
1.711 +
1.712 + err = iDisp.SetRotation(aRotation, configChanged);
1.713 + TInt expectedErr = KErrNone;
1.714 + if ((!IsValidRotation(aRotation)) || ((infoPkg().iAvailableRotations & aRotation) == 0))
1.715 + {
1.716 + expectedErr = KErrArgument;
1.717 + }
1.718 + test(err == expectedErr);
1.719 +
1.720 + actualBufferFormat = aBufferFormat;
1.721 + }
1.722 +
1.723 + // Get the composition buffer index
1.724 + TUint bufferIndex;
1.725 + TRequestStatus status;
1.726 + iDisp.GetCompositionBuffer(bufferIndex, status);
1.727 + User::WaitForRequest(status);
1.728 + test(status == KErrNone);
1.729 +
1.730 + // Now get access to the composition buffer
1.731 + RChunk compChunk;
1.732 + TInt offset = 0;
1.733 + err = iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset);
1.734 + test_KErrNone(err);
1.735 +
1.736 + TUint8* baseAddr = compChunk.Base();
1.737 + TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
1.738 + err = iDisp.GetDisplayInfo(infoPkg);
1.739 + test_KErrNone(err);
1.740 +
1.741 + test.Printf(_L("DrawCompositionBuffer::GetCompositionBufferInfo index = 0x%08x base = 0x%08x offset = 0x%08x\n"),
1.742 + bufferIndex, baseAddr, offset);
1.743 +
1.744 + // Find out structure of the buffer
1.745 + TUint8* firstPixelAddr = baseAddr + offset;
1.746 +
1.747 + // Find out current display dimensions
1.748 + TInt width;
1.749 + TInt height;
1.750 + RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
1.751 + test(IsValidRotation(currentRotation));
1.752 + if (currentRotation == RDisplayChannel::ERotationNormal ||
1.753 + currentRotation == RDisplayChannel::ERotation180)
1.754 + {
1.755 + width = actualBufferFormat.iSize.iWidth;
1.756 + height = actualBufferFormat.iSize.iHeight;
1.757 + }
1.758 + else
1.759 + {
1.760 + height = actualBufferFormat.iSize.iWidth;
1.761 + width = actualBufferFormat.iSize.iHeight;
1.762 + }
1.763 +
1.764 + TInt offsetBetweenLines;
1.765 + if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
1.766 + {
1.767 + offsetBetweenLines = iDisp.NextLineOffset(actualBufferFormat, 0);
1.768 + }
1.769 + else
1.770 + {
1.771 + // NextLineOffset not supported in v1.0 and displayinfo offset doesn't work on H4
1.772 + offsetBetweenLines = 4 * width;
1.773 + }
1.774 + DrawFillToMemory(firstPixelAddr, offsetBetweenLines, actualBufferFormat.iPixelFormat,
1.775 + width, height, aStep);
1.776 +
1.777 + err = iDisp.PostCompositionBuffer(NULL, aPostCount);
1.778 + test_KErrNone(err);
1.779 + User::After(KDrawWaitTime);
1.780 +
1.781 + compChunk.Close();
1.782 + }
1.783 +
1.784 +void CDisplayChannelTest::CheckCompositionBuffers()
1.785 +/**
1.786 + Retrieves the current composition buffer index and checks the information about
1.787 + this buffer.
1.788 + */
1.789 + {
1.790 + test.Next(_L("Test GetCompositionBuffer, CancelGetCompositionBuffer, GetCompositionBufferInfo, PostLegacyBuffer"));
1.791 +
1.792 + iDisp.CancelGetCompositionBuffer(); // Test cancel without an outstanding call
1.793 +
1.794 + TUint bufferIndex;
1.795 + TRequestStatus status;
1.796 + // Get with immediate cancel
1.797 + iDisp.GetCompositionBuffer(bufferIndex, status);
1.798 + iDisp.CancelGetCompositionBuffer();
1.799 + test(status == KErrNone || status == KErrCancel);
1.800 +
1.801 + iDisp.GetCompositionBuffer(bufferIndex, status); // Get, no cancel
1.802 + User::WaitForRequest(status);
1.803 + test(status == KErrNone);
1.804 +
1.805 + RChunk compChunk;
1.806 + TInt offset = 0;
1.807 + test_KErrNone(iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset));
1.808 +
1.809 + // client must be able to read and write to the chunk
1.810 + test(compChunk.IsReadable());
1.811 + test(compChunk.IsWritable());
1.812 + test_Compare(offset, >=, 0);
1.813 +
1.814 + RDisplayChannel::TPostCount postCountA;
1.815 + RDisplayChannel::TPostCount postCountB;
1.816 + test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountA));
1.817 + test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountB));
1.818 + test_Compare(postCountB - postCountA, >=, 1);
1.819 +
1.820 + // Wait for first postcount value
1.821 + iDisp.WaitForPost(postCountA, status);
1.822 + User::WaitForRequest(status);
1.823 + test(status == KErrNone);
1.824 +
1.825 + // It should be possible to wait again on postCountA
1.826 + // and this should complete immediately with KErrNone. However, there
1.827 + // there is bug in the emulator causes this to wait forever.
1.828 +
1.829 + compChunk.Close();
1.830 +
1.831 + // Legacy buffer should have been initialised by retrieval of HAL::EDisplayMemoryAddress
1.832 + test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCountA));
1.833 + test_Compare(postCountA - postCountB, >=, 1);
1.834 + }
1.835 +
1.836 +void CDisplayChannelTest::VisualTest()
1.837 +/**
1.838 +Iterates over the arrays of pixel formats and rotations attempting to
1.839 +draw a shaded fill to the composition buffer
1.840 +*/
1.841 + {
1.842 + test.Next(_L("Visual test"));
1.843 +
1.844 + RDisplayChannel::TPostCount postCount;
1.845 + if (iVisualTestFormatIndex < KNumPixelFormats)
1.846 + {
1.847 + RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);
1.848 + if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
1.849 + {
1.850 + // only one format supported in v1.0 so only one loop needed
1.851 + bufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
1.852 + iVisualTestFormatIndex = KNumPixelFormats - 1;
1.853 + TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
1.854 + iDisp.GetDisplayInfo(infoPkg);
1.855 + bufferFormat.iSize.iWidth = infoPkg().iNormal.iWidth;
1.856 + bufferFormat.iSize.iHeight = infoPkg().iNormal.iHeight;
1.857 + }
1.858 + else
1.859 + {
1.860 + test_KErrNone(iDisp.GetBufferFormat(bufferFormat));
1.861 + bufferFormat.iPixelFormat = KPixelFormats[iVisualTestFormatIndex];
1.862 + }
1.863 + DrawCompositionBuffer(postCount, bufferFormat, KRotations[iVisualTestRotationIndex], iVisualTestRotationIndex);
1.864 + iVisualTestRotationIndex++;
1.865 + if (iVisualTestRotationIndex >= KNumRotations)
1.866 + {
1.867 + iVisualTestRotationIndex = 0;
1.868 + iVisualTestFormatIndex++;
1.869 + }
1.870 + iDisp.WaitForPost(postCount, iStatus);
1.871 + SetActive();
1.872 + }
1.873 + else
1.874 + {
1.875 + // Test drawing to the legacy buffer
1.876 + test.Printf(_L("Drawing to legacy buffer\n"));
1.877 +
1.878 + TBool configChanged;
1.879 + iDisp.SetRotation(KRotations[0], configChanged);
1.880 + DrawLegacyBuffer(20); // Make legacy buffer obviously different
1.881 + test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCount));
1.882 + CompleteSelf(ETestSecondHandle);
1.883 + User::After(KDrawWaitTime);
1.884 + }
1.885 + }
1.886 +
1.887 +void CDisplayChannelTest::CheckBufferFormat()
1.888 +/**
1.889 + Tests the APIs for getting and setting the buffer format.
1.890 + In version 1.1 these APIs are only stubs that return KErrNotSupported
1.891 +
1.892 + @pre CheckResolutions must have called prior to calling this method
1.893 + @pre CheckPixelFormats must have been called prior to calling this method.
1.894 + */
1.895 + {
1.896 + test.Next(_L("Test GetBufferFormat, SetBufferFormat, NextLineOffset, NextPlaneOffset"));
1.897 +
1.898 + RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);
1.899 + TInt err = iDisp.GetBufferFormat(bufferFormat);
1.900 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.901 + {
1.902 + test_Compare(err, ==, KErrNotSupported);
1.903 + }
1.904 + else
1.905 + {
1.906 + test(IsValidPixelFormat(bufferFormat.iPixelFormat));
1.907 + test(bufferFormat.iSize.iHeight > 0 && bufferFormat.iSize.iHeight > 0);
1.908 + // Check that the buffer is at least as large as the current pixel resolution
1.909 + TSize resSize;
1.910 + test_KErrNone(iDisp.GetResolution(resSize));
1.911 + test(bufferFormat.iSize.iHeight >= resSize.iHeight && bufferFormat.iSize.iWidth >= resSize.iWidth);
1.912 + }
1.913 +
1.914 + RDisplayChannel::TBufferFormat newBufferFormat(TSize(iHalInfo.iXPixels, iHalInfo.iYPixels), 0);
1.915 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.916 + {
1.917 + // API not support in 1.1
1.918 + test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrNotSupported);
1.919 + }
1.920 + else
1.921 + {
1.922 + // Tests assumes that 32bpp XRGB888 is supported on most hardware
1.923 + RDisplayChannel::TBufferFormat newBufferFormat(TSize(0,0), EUidPixelFormatXRGB_8888);
1.924 + test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrArgument); // buffer must be large enough for resolution
1.925 +
1.926 + // Should be able to current buffer format
1.927 + test_KErrNone(iDisp.SetBufferFormat(bufferFormat));
1.928 + }
1.929 +
1.930 + // Get current information and check this against new APIs that give
1.931 + // line and plane information for any mode.
1.932 + TSize currentPixelRes;
1.933 + TSize currentTwipRes;
1.934 + RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
1.935 + RDisplayChannel::TBufferFormat currentBufferFormat(TSize(0,0), 0);
1.936 +
1.937 + test_KErrNone(iDisp.GetResolution(currentPixelRes));
1.938 + test_KErrNone(iDisp.GetTwips(currentTwipRes));
1.939 + test_KErrNone(iDisp.GetBufferFormat(currentBufferFormat));
1.940 + RDisplayChannel::TResolution res(currentPixelRes, currentTwipRes, currentRotation);
1.941 +
1.942 + TInt planeOffset = iDisp.NextPlaneOffset(currentBufferFormat, 0);
1.943 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.944 + {
1.945 + test_Compare(planeOffset, ==, KErrNotSupported);
1.946 + }
1.947 + else
1.948 + {
1.949 + // Supported in v1.1
1.950 + test_Compare(planeOffset, >=, 0);
1.951 +
1.952 + if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
1.953 + {
1.954 + // Extended API in v1.2
1.955 + test.Printf(_L("Check that planeoffset APIs match"));
1.956 + TInt planeOffset2 = iDisp.NextPlaneOffset(currentBufferFormat, res, currentRotation, 0);
1.957 + test_Compare(planeOffset, ==, planeOffset2);
1.958 +
1.959 + // check that invalid buffer formats are rejected
1.960 + RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
1.961 + badBufferFormat.iPixelFormat = -1;
1.962 + test(iDisp.NextPlaneOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
1.963 + }
1.964 + }
1.965 +
1.966 + TInt lineOffset = iDisp.NextLineOffset(currentBufferFormat, 0);
1.967 + if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
1.968 + {
1.969 + test_Compare(lineOffset, ==, KErrNotSupported);
1.970 + }
1.971 + else
1.972 + {
1.973 + test_Compare(lineOffset, >, 0); // supported in v1.1
1.974 +
1.975 + if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
1.976 + {
1.977 + // Extended API in v1.2
1.978 + test.Printf(_L("Check that lineoffset APIs match"));
1.979 + TInt lineOffset2 = iDisp.NextLineOffset(currentBufferFormat, res, currentRotation, 0);
1.980 + // stride values must be the same and > 0 for any non-zero resolution and the current
1.981 + // resolution should not be zero in size.
1.982 +
1.983 + test_Compare(lineOffset, ==, lineOffset2);
1.984 + // check that invalid buffer formats are rejected
1.985 + RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
1.986 + badBufferFormat.iPixelFormat = -1;
1.987 + test(iDisp.NextLineOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
1.988 + }
1.989 + }
1.990 + }
1.991 +
1.992 +void CDisplayChannelTest::CheckUserBuffers()
1.993 +/**
1.994 + Test APIs that manage user composition buffers. Since this unit test doesn't
1.995 + have access to the real surfaces the tests are mostly robustness tests.
1.996 + */
1.997 + {
1.998 + test.Next(_L("Test WaitForPost, DeRegisterUserBuffer"));
1.999 +
1.1000 + // Cancel should not fail even if WaitForPost has not been called
1.1001 + iDisp.CancelWaitForPost();
1.1002 +
1.1003 + // Check that cancelling a non-existent post request doesn't fail
1.1004 + iDisp.CancelPostUserBuffer();
1.1005 +
1.1006 + // Make sure wait immediately followed by cancel doesn't crash
1.1007 + TRequestStatus status;
1.1008 + RDisplayChannel::TPostCount postCount = 0;
1.1009 + iDisp.WaitForPost(postCount, status);
1.1010 + iDisp.CancelWaitForPost();
1.1011 + test(status == KErrNone || status == KErrCancel);
1.1012 +
1.1013 + // De-register a non-existent buffer id
1.1014 + RDisplayChannel::TBufferId badBufferId(42);
1.1015 + TInt err = iDisp.DeregisterUserBuffer(badBufferId);
1.1016 + // emulator KErrArugment but on H4 KErrNotFound
1.1017 + test(err == KErrArgument || err == KErrNotFound);
1.1018 +
1.1019 + // Create and use a new buffer, should fail because chunk must be a SHARED chunk
1.1020 + RChunk myChunk;
1.1021 + const TInt chunkSize = 320 * 200 * 4; // actual size is not important because this should fail
1.1022 + err = myChunk.CreateGlobal(KNullDesC, chunkSize, chunkSize, EOwnerProcess);
1.1023 + test_KErrNone(err); // Allocation should not fail under normal conditions
1.1024 + RDisplayChannel::TBufferId myBufferId;
1.1025 + err = iDisp.RegisterUserBuffer(myBufferId, myChunk, 0);
1.1026 + // emulator KErrBadHandle but on H4 KErrArgument
1.1027 + test(err == KErrBadHandle || err == KErrArgument);
1.1028 + myChunk.Close();
1.1029 +
1.1030 + // Try to post a request from a bad buffer id
1.1031 + iDisp.PostUserBuffer(badBufferId, status, NULL, postCount);
1.1032 + User::WaitForRequest(status);
1.1033 + // Emulator KErrArgument H4 KErrNotFound
1.1034 + test(status.Int() == KErrArgument || status.Int() == KErrNotFound);
1.1035 +
1.1036 + // Attempt to register an already existing buffer as a user buffer
1.1037 + TUint compId;
1.1038 + iDisp.GetCompositionBuffer(compId, status);
1.1039 + User::WaitForRequest(status);
1.1040 + RChunk compChunk;
1.1041 + TInt offset;
1.1042 + test_KErrNone(iDisp.GetCompositionBufferInfo(compId, compChunk, offset));
1.1043 + test_KErrNone(iDisp.RegisterUserBuffer(myBufferId, compChunk, offset));
1.1044 + err = iDisp.DeregisterUserBuffer(myBufferId);
1.1045 + test(err == KErrNone || err == KErrInUse);
1.1046 + compChunk.Close();
1.1047 + }
1.1048 +
1.1049 +TBool CDisplayChannelTest::IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat)
1.1050 +/**
1.1051 +Validates whether the value of aPixelFormat corresponds to a valid enum in TUidPixelFormat
1.1052 +@param aPixelFormat the pixel format value to test
1.1053 +@return ETrue if aPixelFormat is valid; otherwise, EFalse is returned.
1.1054 +*/
1.1055 + {
1.1056 + switch (aPixelFormat)
1.1057 + {
1.1058 + case EUidPixelFormatUnknown:
1.1059 + case EUidPixelFormatXRGB_8888:
1.1060 + case EUidPixelFormatBGRX_8888:
1.1061 + case EUidPixelFormatXBGR_8888:
1.1062 + case EUidPixelFormatBGRA_8888:
1.1063 + case EUidPixelFormatARGB_8888:
1.1064 + case EUidPixelFormatABGR_8888:
1.1065 + case EUidPixelFormatARGB_8888_PRE:
1.1066 + case EUidPixelFormatABGR_8888_PRE:
1.1067 + case EUidPixelFormatBGRA_8888_PRE:
1.1068 + case EUidPixelFormatARGB_2101010:
1.1069 + case EUidPixelFormatABGR_2101010:
1.1070 + case EUidPixelFormatBGR_888:
1.1071 + case EUidPixelFormatRGB_888:
1.1072 + case EUidPixelFormatRGB_565:
1.1073 + case EUidPixelFormatBGR_565:
1.1074 + case EUidPixelFormatARGB_1555:
1.1075 + case EUidPixelFormatXRGB_1555:
1.1076 + case EUidPixelFormatARGB_4444:
1.1077 + case EUidPixelFormatARGB_8332:
1.1078 + case EUidPixelFormatBGRX_5551:
1.1079 + case EUidPixelFormatBGRA_5551:
1.1080 + case EUidPixelFormatBGRA_4444:
1.1081 + case EUidPixelFormatBGRX_4444:
1.1082 + case EUidPixelFormatAP_88:
1.1083 + case EUidPixelFormatXRGB_4444:
1.1084 + case EUidPixelFormatXBGR_4444:
1.1085 + case EUidPixelFormatRGB_332:
1.1086 + case EUidPixelFormatA_8:
1.1087 + case EUidPixelFormatBGR_332:
1.1088 + case EUidPixelFormatP_8:
1.1089 + case EUidPixelFormatP_4:
1.1090 + case EUidPixelFormatP_2:
1.1091 + case EUidPixelFormatP_1:
1.1092 + case EUidPixelFormatYUV_420Interleaved:
1.1093 + case EUidPixelFormatYUV_420Planar:
1.1094 + case EUidPixelFormatYUV_420PlanarReversed:
1.1095 + case EUidPixelFormatYUV_420SemiPlanar:
1.1096 + case EUidPixelFormatYUV_422Interleaved:
1.1097 + case EUidPixelFormatYUV_422Planar:
1.1098 + case EUidPixelFormatYUV_422Reversed:
1.1099 + case EUidPixelFormatYUV_422SemiPlanar:
1.1100 + case EUidPixelFormatYUV_422InterleavedReversed:
1.1101 + case EUidPixelFormatYUV_422Interleaved16bit:
1.1102 + case EUidPixelFormatYUV_444Interleaved:
1.1103 + case EUidPixelFormatYUV_444Planar:
1.1104 + case EUidPixelFormatL_8:
1.1105 + case EUidPixelFormatL_4:
1.1106 + case EUidPixelFormatL_2:
1.1107 + case EUidPixelFormatL_1:
1.1108 + case EUidPixelFormatSpeedTaggedJPEG:
1.1109 + case EUidPixelFormatJPEG:
1.1110 + return ETrue;
1.1111 + default:
1.1112 + return EFalse;
1.1113 + }
1.1114 + }
1.1115 +
1.1116 +TBool CDisplayChannelTest::IsValidRotation(RDisplayChannel::TDisplayRotation aRotation)
1.1117 +/**
1.1118 +Checks whether the supplied rotation is a valid rotation. <br>
1.1119 +N.B. Only single rotations are accepted so EFalse is returned for ERotationAll.
1.1120 +@param aRotation the rotation to validate
1.1121 +@return ETrue if the supplied rotation is valid; otherwise, EFalse is returned.
1.1122 +*/
1.1123 + {
1.1124 + switch (aRotation)
1.1125 + {
1.1126 + case RDisplayChannel::ERotationNormal:
1.1127 + case RDisplayChannel::ERotation90CW:
1.1128 + case RDisplayChannel::ERotation180:
1.1129 + case RDisplayChannel::ERotation270CW:
1.1130 + return ETrue;
1.1131 + default:
1.1132 + return EFalse;
1.1133 + }
1.1134 + }
1.1135 +
1.1136 +void CDisplayChannelTest::CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation)
1.1137 +/**
1.1138 +Tests the SetRotation API attempting to set the requested resolution. If the resolution is supported
1.1139 +then SetRotation should succeed and the CurrentRotation should change. Otherwise, SetResolution should
1.1140 +fail and the current rotation should be unchanged.
1.1141 +
1.1142 +@param aSupported The set of supported resolutions for TDisplayInfo
1.1143 +@param aNewRotation The new rotation to set
1.1144 +*/
1.1145 + {
1.1146 + RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
1.1147 + test(IsValidRotation(currentRotation));
1.1148 +
1.1149 + TBool displayConfigChanged = EFalse;
1.1150 + TInt err = iDisp.SetRotation(aNewRotation, displayConfigChanged);
1.1151 + TInt expectedErr = KErrNone;
1.1152 + if ((!IsValidRotation(aNewRotation)) || ((aSupported & aNewRotation) == 0))
1.1153 + {
1.1154 + expectedErr = KErrArgument;
1.1155 + }
1.1156 + test(err == expectedErr);
1.1157 +
1.1158 + // Check whether the rotation should / shouldn't have changed
1.1159 + test (iDisp.CurrentRotation() == (err == KErrNone ? aNewRotation : currentRotation));
1.1160 + }
1.1161 +
1.1162 +void CDisplayChannelTest::CheckRotations()
1.1163 +/**
1.1164 +Tests the SetRotation and GetRotation APIs by attempting to set each valid rotation
1.1165 +plus some invalid rotation values.
1.1166 +If a rotation is valid but not supported then KErrNotSupported should be returned.
1.1167 +*/
1.1168 + {
1.1169 + test.Next(_L("Test CurrentRotation, SetRotation"));
1.1170 +
1.1171 + // Find out supported resolutions
1.1172 + TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
1.1173 + test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
1.1174 +
1.1175 + CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
1.1176 + CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation90CW);
1.1177 + CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation180);
1.1178 + CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation270CW);
1.1179 + CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
1.1180 + CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(-1));
1.1181 + CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(0));
1.1182 + }
1.1183 +
1.1184 +void CDisplayChannelTest::CheckV11inV10()
1.1185 +/**
1.1186 +The purpose of this test is to verify that v1.0 of the display channel driver
1.1187 +returns KErrNotSupported for methods that only exist in newer versions as opposed
1.1188 +to panicking.
1.1189 +To run this test for real t_display needs to be built against v1.1 and then copied
1.1190 +to a v1.0 environment.
1.1191 +
1.1192 +If the version number is > 1.0 then this method does nothing.
1.1193 +*/
1.1194 + {
1.1195 + if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
1.1196 + {
1.1197 + return;
1.1198 + }
1.1199 +
1.1200 + test.Next(_L("Test check v1.1 functions fail gracefully in v1.0"));
1.1201 +
1.1202 + // APIs should fail before evaluating parameters
1.1203 + TInt intDummy;
1.1204 + TInt err;
1.1205 + TBuf8<256> buf;
1.1206 + TSize size;
1.1207 +
1.1208 + test.Printf(_L("Testing display change APIs\n"));
1.1209 + iDisp.NotifyOnDisplayChangeCancel();
1.1210 + TRequestStatus status;
1.1211 + iDisp.NotifyOnDisplayChange(status);
1.1212 + test(status == KErrNotSupported);
1.1213 +
1.1214 + err = iDisp.NumberOfResolutions();
1.1215 + test(err == KErrNotSupported);
1.1216 +
1.1217 + err = iDisp.GetResolutions(buf, intDummy);
1.1218 + test(err == KErrNotSupported);
1.1219 +
1.1220 + err = iDisp.GetResolution(size);
1.1221 + test(err == KErrNotSupported);
1.1222 +
1.1223 + err = iDisp.GetTwips(size);
1.1224 + test(err == KErrNotSupported);
1.1225 +
1.1226 + err = iDisp.NumberOfPixelFormats();
1.1227 + test(err == KErrNotSupported);
1.1228 +
1.1229 + err = iDisp.GetPixelFormats(buf, intDummy);
1.1230 + test(err == KErrNotSupported);
1.1231 +
1.1232 + RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0),0);
1.1233 + err = iDisp.GetBufferFormat(bufferFormat);
1.1234 + test(err == KErrNotSupported);
1.1235 +
1.1236 + err = iDisp.SetBufferFormat(bufferFormat);
1.1237 + test(err == KErrNotSupported);
1.1238 +
1.1239 + err = iDisp.NextPlaneOffset(bufferFormat, 0);
1.1240 + test(err == KErrNotSupported);
1.1241 +
1.1242 + err = iDisp.NextLineOffset(bufferFormat, 0);
1.1243 + test(err == KErrNotSupported);
1.1244 + }
1.1245 +
1.1246 +void CDisplayChannelTest::CheckSecondHandle()
1.1247 +/**
1.1248 +Opens a second RDisplayChannel.
1.1249 +The driver may not support this but must not crash.
1.1250 +*/
1.1251 + {
1.1252 + test.Next(_L("Open a second handle"));
1.1253 + RDisplayChannel disp2;
1.1254 + TInt err = disp2.Open(iScreenId);
1.1255 + test(err == KErrNone || err == KErrInUse);
1.1256 + disp2.Close();
1.1257 + }
1.1258 +
1.1259 +void CDisplayChannelTest::TestBufferTransitions()
1.1260 +/**
1.1261 +Because different buffer types (ie. composition, legacy and user) complete differently, we must test
1.1262 +switching between those different types of buffers to ensure that this is taken into account.
1.1263 +*/
1.1264 + {
1.1265 + // The support code required for this test exists only in the separated GCE display LDD, not in the
1.1266 + // legacy monolithic WINSCW LDD
1.1267 +#if defined(_DEBUG) && !defined(__WINS__)
1.1268 + test.Next(_L("Test transitions between buffer types"));
1.1269 +
1.1270 + TPckgBuf<RDisplayChannel::TDisplayInfo> displayInfo;
1.1271 + test_KErrNone(iDisp.GetDisplayInfo(displayInfo));
1.1272 +
1.1273 + RChunk chunk;
1.1274 + RDisplayChannel::TBufferFormat bufferFormat(TSize(iHalInfo.iXPixels, iHalInfo.iYPixels), displayInfo().iPixelFormat);
1.1275 +
1.1276 + test.Next(_L("Get the LDD to create a user buffer"));
1.1277 + TInt err = iDisp.CreateUserBuffer(bufferFormat, chunk);
1.1278 + test_KErrNone(err);
1.1279 +
1.1280 + test.Next(_L("Register a user buffer"));
1.1281 + RDisplayChannel::TBufferId bufferId;
1.1282 + err = iDisp.RegisterUserBuffer(bufferId, chunk, 0);
1.1283 + test_KErrNone(err);
1.1284 +
1.1285 + test.Next(_L("Post a user buffer"));
1.1286 + TRequestStatus status;
1.1287 + RDisplayChannel::TPostCount postCount;
1.1288 + iDisp.PostUserBuffer(bufferId, status, NULL, postCount);
1.1289 + iDisp.PostLegacyBuffer(NULL, postCount);
1.1290 +
1.1291 + test.Printf(_L("Waiting for user buffer\n"));
1.1292 + User::WaitForRequest(status);
1.1293 + test(status.Int() == KErrNone || status.Int() == KErrCancel);
1.1294 + test.Printf(_L("Waiting for legacy buffer\n"));
1.1295 + iDisp.WaitForPost(postCount, status);
1.1296 + User::WaitForRequest(status);
1.1297 + test_KErrNone(status.Int());
1.1298 +
1.1299 + test.Printf(_L("Getting composition buffer\n"));
1.1300 + TUint bufferIndex;
1.1301 + iDisp.GetCompositionBuffer(bufferIndex, status);
1.1302 + User::WaitForRequest(status);
1.1303 + test_KErrNone(status.Int());
1.1304 +
1.1305 + iDisp.PostUserBuffer(bufferId, status, NULL, postCount);
1.1306 + iDisp.PostCompositionBuffer(NULL, postCount);
1.1307 +
1.1308 + test.Printf(_L("Waiting for user buffer\n"));
1.1309 + User::WaitForRequest(status);
1.1310 + test(status.Int() == KErrNone || status.Int() == KErrCancel);
1.1311 + test.Printf(_L("Waiting for composition buffer\n"));
1.1312 + iDisp.WaitForPost(postCount, status);
1.1313 + User::WaitForRequest(status);
1.1314 + test_KErrNone(status.Int());
1.1315 +
1.1316 + test.Printf(_L("Deregistering user buffers\n"));
1.1317 + err = iDisp.DeregisterUserBuffer(bufferId);
1.1318 + test_KErrNone(err);
1.1319 +
1.1320 + test.Printf(_L("Done, closing shared chunk\n"));
1.1321 + chunk.Close();
1.1322 +#endif // defined(_DEBUG) && !defined(__WINS__)
1.1323 + }
1.1324 +
1.1325 +void CDisplayChannelTest::Start()
1.1326 +/**
1.1327 + Run all of the test cases
1.1328 + */
1.1329 + {
1.1330 + CompleteSelf(ETestDisplayInfo);
1.1331 + }
1.1332 +
1.1333 +void CDisplayChannelTest::CompleteSelf(TTestState aNextState)
1.1334 +/*
1.1335 +Advances to the next test state for test steps that don't invoke
1.1336 +asynchronous requests on this AO.
1.1337 +*/
1.1338 + {
1.1339 + iState = aNextState;
1.1340 + TRequestStatus* status = &iStatus;
1.1341 + SetActive();
1.1342 + User::RequestComplete(status, KErrNone);
1.1343 + }
1.1344 +
1.1345 +void CDisplayChannelTest::DoCancel()
1.1346 + {
1.1347 + iAsyncHelper->Cancel();
1.1348 + }
1.1349 +
1.1350 +TInt CDisplayChannelTest::RunError(TInt aError)
1.1351 + {
1.1352 + test_KErrNone(aError);
1.1353 + return KErrNone;
1.1354 + }
1.1355 +
1.1356 +void CDisplayChannelTest::RunL()
1.1357 +/**
1.1358 + Run all of the tests where the API is defined for that version.
1.1359 + */
1.1360 + {
1.1361 + test_KErrNone(iStatus.Int());
1.1362 +
1.1363 + test.Printf(_L("Test state %d\n"), iState);
1.1364 + switch (iState)
1.1365 + {
1.1366 + case ETestDisplayInfo:
1.1367 + CheckDisplayInfo();
1.1368 + CompleteSelf(ETestCompositionBuffers);
1.1369 + break;
1.1370 + case ETestCompositionBuffers:
1.1371 + CheckCompositionBuffers();
1.1372 + CompleteSelf(ETestUserBuffers);
1.1373 + break;
1.1374 + case ETestUserBuffers:
1.1375 + CheckUserBuffers();
1.1376 + CompleteSelf(ETestRotations);
1.1377 + break;
1.1378 + case ETestRotations:
1.1379 + CheckRotations();
1.1380 + CompleteSelf(ETestWaitForPostDoCancel);
1.1381 + break;
1.1382 + case ETestWaitForPostDoCancel:
1.1383 + // Post the composition buffer, register wait and cancel wait.
1.1384 + iDisp.PostCompositionBuffer(NULL, iDummyPostCount);
1.1385 + iDisp.WaitForPost(iDummyPostCount, iAsyncHelper->Status());
1.1386 + iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
1.1387 + iDisp.CancelWaitForPost();
1.1388 + CompleteSelf(ETestWaitForPostCheckCancel);
1.1389 + break;
1.1390 + case ETestWaitForPostCheckCancel:
1.1391 + test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
1.1392 + CompleteSelf(ETestGetCompositionBufferDoCancel);
1.1393 + break;
1.1394 + case ETestGetCompositionBufferDoCancel:
1.1395 + iDisp.GetCompositionBuffer(iDummyCompositionBuffer, iAsyncHelper->Status());
1.1396 + iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
1.1397 + iDisp.CancelGetCompositionBuffer();
1.1398 + CompleteSelf(ETestGetCompositionBufferCheckCancel);
1.1399 + break;
1.1400 + case ETestGetCompositionBufferCheckCancel:
1.1401 + test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
1.1402 +
1.1403 + if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
1.1404 + {
1.1405 + CompleteSelf(ETestV11inV10);
1.1406 + }
1.1407 + else
1.1408 + {
1.1409 + CompleteSelf(ETestDisplayChange);
1.1410 + }
1.1411 + break;
1.1412 + case ETestDisplayChange: // API in v1.1 +
1.1413 + CheckDisplayChange();
1.1414 + CompleteSelf(ETestDisplayChangeDoCancel);
1.1415 + break;
1.1416 + case ETestDisplayChangeDoCancel: // API in v1.1 +
1.1417 + iDisp.NotifyOnDisplayChangeCancel();
1.1418 + CompleteSelf(ETestDisplayChangeCheckCancel);
1.1419 + break;
1.1420 + case ETestDisplayChangeCheckCancel: // API in v1.1 +
1.1421 + test(iAsyncHelperResult == KErrCancel); // display should not have changed
1.1422 + CompleteSelf(ETestResolutions);
1.1423 + break;
1.1424 + case ETestResolutions: // API in v1.1 +
1.1425 + CheckResolutions();
1.1426 + CompleteSelf(ETestPixelFormats);
1.1427 + break;
1.1428 + case ETestPixelFormats: // API in v1.1 +
1.1429 + CheckPixelFormats();
1.1430 + CompleteSelf(ETestBufferFormats);
1.1431 + break;
1.1432 + case ETestBufferFormats: // API in v1.1 +
1.1433 + CheckBufferFormat();
1.1434 + CompleteSelf(EVisualTest);
1.1435 + break;
1.1436 + case ETestV11inV10:
1.1437 + CheckV11inV10();
1.1438 + CompleteSelf(EVisualTest);
1.1439 + break;
1.1440 + case EVisualTest:
1.1441 + VisualTest(); // visual test is async because of WaitForPost
1.1442 + break;
1.1443 + case ETestSecondHandle:
1.1444 + CheckSecondHandle();
1.1445 + CompleteSelf(ETestBufferTransitions);
1.1446 + break;
1.1447 + case ETestBufferTransitions:
1.1448 + TestBufferTransitions();
1.1449 + CompleteSelf(ETestFinished);
1.1450 + break;
1.1451 + case ETestFinished:
1.1452 + CActiveScheduler::Stop();
1.1453 + break;
1.1454 + default:
1.1455 + test(EFalse);
1.1456 + }
1.1457 + }
1.1458 +
1.1459 +void MainL()
1.1460 +/**
1.1461 + Initialise RTest and run the tests
1.1462 + */
1.1463 + {
1.1464 + test.Start(_L("Testing display channel driver"));
1.1465 +
1.1466 + // If the device driver does not exist then this is considered a pass
1.1467 + // because the display channel is not a mandatory part of the base port
1.1468 + _LIT(KLdd, "display0.ldd");
1.1469 + test.Printf(_L("Loading logical %S\n"), &KLdd);
1.1470 + TInt err = User::LoadLogicalDevice(KLdd);
1.1471 + test(err == KErrNone || err == KErrAlreadyExists || err == KErrNotFound);
1.1472 +
1.1473 + // Only test for kenel memory leaks for non WINSCW builds as the WINSCW LDD is obsolete and would
1.1474 + // take forever to debug
1.1475 +#ifndef __WINS__
1.1476 + __KHEAP_MARK;
1.1477 +#endif // ! __WINS__
1.1478 +
1.1479 + if (err == KErrNone || err == KErrAlreadyExists)
1.1480 + {
1.1481 + TInt numberOfScreens;
1.1482 + User::LeaveIfError(HAL::Get(HAL::EDisplayNumberOfScreens, numberOfScreens));
1.1483 + for (TInt screenNum = 0; screenNum < numberOfScreens; ++screenNum)
1.1484 + {
1.1485 + CActiveScheduler* s = new(ELeave) CActiveScheduler();
1.1486 + CActiveScheduler::Install(s);
1.1487 + CleanupStack::PushL(s);
1.1488 + CDisplayChannelTest* displayTest = CDisplayChannelTest::NewLC(screenNum);
1.1489 + displayTest->Start();
1.1490 + s->Start();
1.1491 + CleanupStack::PopAndDestroy(2, s); // s, displayTest
1.1492 + }
1.1493 + }
1.1494 + else
1.1495 + {
1.1496 + test.Printf(_L("display0.ldd not present. Finishing test.\n"));
1.1497 + }
1.1498 +
1.1499 +#ifndef __WINS__
1.1500 + __KHEAP_MARKEND;
1.1501 +#endif // ! __WINS__
1.1502 +
1.1503 + test.End();
1.1504 + }
1.1505 +
1.1506 +TInt E32Main()
1.1507 +/**
1.1508 + Create cleanup stack, initialise memory checks and run the tests.
1.1509 + */
1.1510 + {
1.1511 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.1512 + if (!cleanup)
1.1513 + {
1.1514 + return KErrNoMemory;
1.1515 + }
1.1516 + __UHEAP_MARK;
1.1517 + test.Title();
1.1518 + TRAPD(err, MainL());
1.1519 + test.Close();
1.1520 + __UHEAP_MARKEND;
1.1521 + delete cleanup;
1.1522 + return err;
1.1523 + }