os/kernelhwsrv/kerneltest/e32test/video/t_videomemory.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/video/t_videomemory.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,279 @@
     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 +// Overview:
    1.18 +// Test the video driver kernel extension that provides chunk handle to access video memory. 
    1.19 +// API Information:
    1.20 +// HAL, UserSvr
    1.21 +// Details:
    1.22 +// - Check that the "old" GetMemoryAddress function still works, for legacy compatibility.
    1.23 +// - Check that we can get a chunk and that we can read/write the memory belonging to that chunk. 
    1.24 +// - Check that asking for a DisplayMemoryHandle twice gives the same piece of memory.  
    1.25 +// - Test that the same memory is available to a second process, by starting second process and
    1.26 +// the second process can write to memory. Validate by confirming that the value in the second process 
    1.27 +// is changed.
    1.28 +// Platforms/Drives/Compatibility:
    1.29 +// All.
    1.30 +// Assumptions/Requirement/Pre-requisites:
    1.31 +// Failures and causes:
    1.32 +// Base Port information:
    1.33 +// 
    1.34 +//
    1.35 +
    1.36 +#include <e32test.h>
    1.37 +#include <videodriver.h>
    1.38 +#include <hal.h>
    1.39 +#include <e32svr.h>
    1.40 +#include <dispchannel.h>
    1.41 +#include "t_videomemory.h"
    1.42 +
    1.43 +LOCAL_D RTest test(_L("T_VIDEOMEMORY"));
    1.44 +
    1.45 +#ifndef __WINS__
    1.46 +#define DUMP(x) test.Printf(_L(#x"= %d =0x%08x\n"), x, x)
    1.47 +#endif
    1.48 +
    1.49 +
    1.50 +LOCAL_C void RunTestsForScreen(TInt aScreenID)
    1.51 +	{
    1.52 +
    1.53 +	TInt ret = KErrNone;
    1.54 +
    1.55 +#ifdef __WINS__
    1.56 +	RDisplayChannel displayChannel;
    1.57 +	
    1.58 +	test.Next(_L("Open Display Driver"));
    1.59 +	
    1.60 +    _LIT(KDisplayDriver, "display0");
    1.61 +    ret = User::LoadLogicalDevice(KDisplayDriver);
    1.62 +    test(KErrNone == ret || KErrAlreadyExists == ret);
    1.63 +	
    1.64 +	ret = displayChannel.Open(aScreenID);
    1.65 +    test(KErrNone == ret);
    1.66 +		
    1.67 +#endif
    1.68 +
    1.69 +	test.Next(_L("Checking Display Memory Address"));
    1.70 +	
    1.71 +	// This is the real basic form of test:
    1.72 +	// Get the display memory address from the HAL.
    1.73 +	// Check that it's not zero - that would be invalid memory.
    1.74 +	// Try to write to the memory - it should not give a page-fault/crash.
    1.75 +	// Try to read the memory - we should get the same value as we wrote. 
    1.76 +	
    1.77 +	TInt memoryAddress=0;
    1.78 +	volatile TUint32 *pMemory = 0;
    1.79 +	ret = HAL::Get(aScreenID, HAL::EDisplayMemoryAddress, memoryAddress);
    1.80 +	test (KErrNone == ret || KErrNotSupported == ret);
    1.81 +
    1.82 +	if (KErrNone == ret)
    1.83 +		{
    1.84 +		test.Printf(_L("Display Memory Address = %08x\n"), memoryAddress);
    1.85 +		// Now check that we can write to memoryAddress:
    1.86 +		test (memoryAddress != 0);
    1.87 +		pMemory = reinterpret_cast<TUint32 *>(memoryAddress);
    1.88 +		*pMemory = KTestValue1;
    1.89 +		test(KTestValue1 == *pMemory);
    1.90 +		}
    1.91 +	else
    1.92 +		{
    1.93 +		test.Printf(_L("Memory Address not available from HAL\n"));
    1.94 +		}
    1.95 +	
    1.96 +	// Second basic test. Use the HAL to fetch a handle
    1.97 +	// to the display memory. 
    1.98 +	// Check that the handle is not zero. 
    1.99 +	// Get the base-address of the chunk. 
   1.100 +	// Write this base address with a new value.
   1.101 +	// Read with the chunk base address to see that teh new value is there. 
   1.102 +	// Read the memory address from the above test and check that it changed 
   1.103 +	// to the new value.
   1.104 +	// Note that the memory address from above test MAY NOT BE SET - so 
   1.105 +	// check to see if it's non-zero first.
   1.106 +		
   1.107 +	test.Next(_L("Checking Display Handle"));
   1.108 +	TInt handle = 0;
   1.109 +	volatile TUint32 *pChunkBase = 0;
   1.110 +	RChunk chunk;
   1.111 +	ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
   1.112 +	test ((KErrNone == ret || KErrNotSupported == ret));
   1.113 +	if (KErrNone == ret)
   1.114 +		{
   1.115 +		// Handle should not be zero. 
   1.116 +		test(0 != handle);
   1.117 +		ret = chunk.SetReturnedHandle(handle);
   1.118 +		test(KErrNone == ret);
   1.119 +		
   1.120 +		pChunkBase = reinterpret_cast<TUint32 *>(chunk.Base());
   1.121 +		test.Printf(_L("Display Memory Address = %08x\n"), reinterpret_cast<TUint>(pChunkBase));
   1.122 +		*pChunkBase = KTestValue2;
   1.123 +		test(KTestValue2 == *pChunkBase);
   1.124 +		// We should see the new value through the pMemory pointer!
   1.125 +		if (pMemory)
   1.126 +			{
   1.127 +			test(KTestValue2 == *pMemory);
   1.128 +			}
   1.129 +	
   1.130 +		}
   1.131 +	else
   1.132 +		{
   1.133 +		test.Printf(_L("Memory Handle not available from HAL - no point in further testing\n"));
   1.134 +		return;
   1.135 +		}
   1.136 +	
   1.137 +
   1.138 +	// Check that we can write to more than the first bit of memory. 
   1.139 +	test.Next(_L("Check that we can write to \"all\" of the memory"));
   1.140 +	// First, find the mode with the biggest number of bits per pixel:
   1.141 +	TInt totalModes;
   1.142 +	ret = HAL::Get(aScreenID, HAL::EDisplayNumModes, totalModes);
   1.143 +	test (KErrNone == ret);
   1.144 +	TInt biggestMode = 0;
   1.145 +	TInt maxBitsPerPixel = 0;
   1.146 +	for(TInt mode = 0; mode < totalModes; mode++)
   1.147 +		{
   1.148 +		TInt bitsPerPixel = mode;
   1.149 +		ret = HAL::Get(aScreenID, HAL::EDisplayBitsPerPixel, bitsPerPixel);
   1.150 +		test (KErrNone == ret);
   1.151 +		if (bitsPerPixel > maxBitsPerPixel)
   1.152 +			{
   1.153 +			maxBitsPerPixel = bitsPerPixel;
   1.154 +			biggestMode = mode;
   1.155 +			}
   1.156 +		}
   1.157 +	
   1.158 +	TInt offsetToFirstPixel = biggestMode;
   1.159 +	ret = HAL::Get(aScreenID, HALData::EDisplayOffsetToFirstPixel, offsetToFirstPixel);
   1.160 +	test(KErrNone == ret);
   1.161 +	
   1.162 +	TInt stride = biggestMode;
   1.163 +	ret = HAL::Get(aScreenID, HALData::EDisplayOffsetBetweenLines, stride);
   1.164 +	test(KErrNone == ret);
   1.165 +	
   1.166 +	TInt yPixels = biggestMode;
   1.167 +	ret = HAL::Get(aScreenID, HALData::EDisplayYPixels, yPixels);
   1.168 +	test(KErrNone == ret);
   1.169 +	
   1.170 +	// Note this is no attempt to be precise. xPixels is not 
   1.171 +	TUint maxByte = offsetToFirstPixel + stride * yPixels - sizeof(TUint32);
   1.172 +		
   1.173 +	volatile TUint32 *memPtr = reinterpret_cast<volatile TUint32 *>(reinterpret_cast<volatile TUint8 *>(pChunkBase) + maxByte);
   1.174 +	*memPtr = KTestValue1;
   1.175 +	test(KTestValue1 == *memPtr);
   1.176 +	
   1.177 +
   1.178 +	// Ask for a second handle and see that this also points to the same bit of memory.
   1.179 +	test.Next(_L("Checking Display Handle second time"));
   1.180 +	volatile TUint32 *pChunkBase2 = 0;
   1.181 +	ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
   1.182 +	test ((KErrNone == ret || KErrNotSupported == ret));
   1.183 +	if (KErrNone == ret)
   1.184 +		{
   1.185 +		// Handle should not be zero!
   1.186 +		test(0 != handle);
   1.187 +		RChunk chunk2;
   1.188 +		ret = chunk2.SetReturnedHandle(handle);
   1.189 +		test(KErrNone == ret);
   1.190 +		
   1.191 +		pChunkBase2 = reinterpret_cast<TUint32 *>(chunk2.Base());
   1.192 +		test.Printf(_L("Display Memory Address = %08x\n"), reinterpret_cast<TUint>(pChunkBase));
   1.193 +		test(KTestValue2 == *pChunkBase2);
   1.194 +		*pChunkBase2 = KTestValue3;
   1.195 +		test(KTestValue3 == *pChunkBase2);
   1.196 +		chunk2.Close();
   1.197 +		}
   1.198 +	
   1.199 +	test.Next(_L("Checking Display Handle using second process"));
   1.200 +	
   1.201 +	// Create a process, let it find the handle of the memory, then read it, and write it.
   1.202 +	// Check that the value we have is the new value: KTestValue3.
   1.203 +	_LIT(KProcName, "t_videomemprocess.exe");
   1.204 +	RProcess process;
   1.205 +	
   1.206 +	ret = process.Create(KProcName, KNullDesC);
   1.207 +	test(KErrNone == ret);
   1.208 +	
   1.209 +	TRequestStatus procStatus;
   1.210 +	process.Logon(procStatus);
   1.211 +	process.SetParameter(12, aScreenID);
   1.212 +	process.Resume();
   1.213 +	User::WaitForRequest(procStatus);
   1.214 +	
   1.215 +	test.Next(_L("Checking that second process updated video memory"));
   1.216 +	// Check that we got the new value. 
   1.217 +	test(KTestValue4 == *pChunkBase);
   1.218 +	
   1.219 +	chunk.Close();
   1.220 +	
   1.221 +#ifdef __WINS__
   1.222 +	displayChannel.Close();
   1.223 +#endif
   1.224 +	
   1.225 +	// Now for some negative tests: Attempt to get a handle for a closes display.
   1.226 +	test.Next(_L("Negative test: Check that we CAN NOT use closed screen"));
   1.227 +	ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
   1.228 +	test (KErrNone != ret);
   1.229 +	}
   1.230 +
   1.231 +
   1.232 +
   1.233 +LOCAL_C void NegativeTests(TInt aMaxScreens)
   1.234 +	{
   1.235 +	TInt handle;
   1.236 +	TInt ret;
   1.237 +	// Another few negative tests: Try invalid screen numbers.
   1.238 +	test.Next(_L("Negative tests: Invalid screen ID's"));
   1.239 +	ret = HAL::Get(aMaxScreens, HALData::EDisplayMemoryHandle, handle);
   1.240 +	test (KErrNone != ret);
   1.241 +	
   1.242 +	ret = HAL::Get(aMaxScreens+1, HALData::EDisplayMemoryHandle, handle);
   1.243 +	test (KErrNone != ret);
   1.244 +	
   1.245 +	ret = HAL::Get(4718, HALData::EDisplayMemoryHandle, handle);
   1.246 +	test (KErrNone != ret);
   1.247 +	
   1.248 +	ret = HAL::Get(-1, HALData::EDisplayMemoryHandle, handle);
   1.249 +	test (KErrNone != ret);
   1.250 +	}
   1.251 +
   1.252 +
   1.253 +
   1.254 +GLDEF_C TInt E32Main()
   1.255 +//
   1.256 +//
   1.257 +    {
   1.258 +
   1.259 +	test.Title();
   1.260 +//
   1.261 +#if defined(__EPOC32__) && defined(__CPU_X86)
   1.262 +	test.Printf(_L("Doesn't run on X86\n"));
   1.263 +#else
   1.264 +
   1.265 +	test.Start(_L("Testing Video Memory HAL interfaces"));
   1.266 +
   1.267 +	TInt screens = 0;	
   1.268 +	TInt ret=HAL::Get(HAL::EDisplayNumberOfScreens, screens);
   1.269 +	test((KErrNone == ret));
   1.270 +	// We expect that there is at least ONE screen. 
   1.271 +	test((screens > 0));
   1.272 +
   1.273 +	for(TInt i=0;i<screens;i++)
   1.274 +		{
   1.275 +		RunTestsForScreen(i);
   1.276 +		}
   1.277 +	
   1.278 +	NegativeTests(screens);
   1.279 +#endif
   1.280 +	
   1.281 +	return KErrNone;
   1.282 +}