First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
15 // Test the video driver kernel extension that provides chunk handle to access video memory.
19 // - Check that the "old" GetMemoryAddress function still works, for legacy compatibility.
20 // - Check that we can get a chunk and that we can read/write the memory belonging to that chunk.
21 // - Check that asking for a DisplayMemoryHandle twice gives the same piece of memory.
22 // - Test that the same memory is available to a second process, by starting second process and
23 // the second process can write to memory. Validate by confirming that the value in the second process
25 // Platforms/Drives/Compatibility:
27 // Assumptions/Requirement/Pre-requisites:
28 // Failures and causes:
29 // Base Port information:
34 #include <videodriver.h>
37 #include <dispchannel.h>
38 #include "t_videomemory.h"
40 LOCAL_D RTest test(_L("T_VIDEOMEMORY"));
43 #define DUMP(x) test.Printf(_L(#x"= %d =0x%08x\n"), x, x)
47 LOCAL_C void RunTestsForScreen(TInt aScreenID)
53 RDisplayChannel displayChannel;
55 test.Next(_L("Open Display Driver"));
57 _LIT(KDisplayDriver, "display0");
58 ret = User::LoadLogicalDevice(KDisplayDriver);
59 test(KErrNone == ret || KErrAlreadyExists == ret);
61 ret = displayChannel.Open(aScreenID);
62 test(KErrNone == ret);
66 test.Next(_L("Checking Display Memory Address"));
68 // This is the real basic form of test:
69 // Get the display memory address from the HAL.
70 // Check that it's not zero - that would be invalid memory.
71 // Try to write to the memory - it should not give a page-fault/crash.
72 // Try to read the memory - we should get the same value as we wrote.
75 volatile TUint32 *pMemory = 0;
76 ret = HAL::Get(aScreenID, HAL::EDisplayMemoryAddress, memoryAddress);
77 test (KErrNone == ret || KErrNotSupported == ret);
81 test.Printf(_L("Display Memory Address = %08x\n"), memoryAddress);
82 // Now check that we can write to memoryAddress:
83 test (memoryAddress != 0);
84 pMemory = reinterpret_cast<TUint32 *>(memoryAddress);
85 *pMemory = KTestValue1;
86 test(KTestValue1 == *pMemory);
90 test.Printf(_L("Memory Address not available from HAL\n"));
93 // Second basic test. Use the HAL to fetch a handle
94 // to the display memory.
95 // Check that the handle is not zero.
96 // Get the base-address of the chunk.
97 // Write this base address with a new value.
98 // Read with the chunk base address to see that teh new value is there.
99 // Read the memory address from the above test and check that it changed
101 // Note that the memory address from above test MAY NOT BE SET - so
102 // check to see if it's non-zero first.
104 test.Next(_L("Checking Display Handle"));
106 volatile TUint32 *pChunkBase = 0;
108 ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
109 test ((KErrNone == ret || KErrNotSupported == ret));
112 // Handle should not be zero.
114 ret = chunk.SetReturnedHandle(handle);
115 test(KErrNone == ret);
117 pChunkBase = reinterpret_cast<TUint32 *>(chunk.Base());
118 test.Printf(_L("Display Memory Address = %08x\n"), reinterpret_cast<TUint>(pChunkBase));
119 *pChunkBase = KTestValue2;
120 test(KTestValue2 == *pChunkBase);
121 // We should see the new value through the pMemory pointer!
124 test(KTestValue2 == *pMemory);
130 test.Printf(_L("Memory Handle not available from HAL - no point in further testing\n"));
135 // Check that we can write to more than the first bit of memory.
136 test.Next(_L("Check that we can write to \"all\" of the memory"));
137 // First, find the mode with the biggest number of bits per pixel:
139 ret = HAL::Get(aScreenID, HAL::EDisplayNumModes, totalModes);
140 test (KErrNone == ret);
141 TInt biggestMode = 0;
142 TInt maxBitsPerPixel = 0;
143 for(TInt mode = 0; mode < totalModes; mode++)
145 TInt bitsPerPixel = mode;
146 ret = HAL::Get(aScreenID, HAL::EDisplayBitsPerPixel, bitsPerPixel);
147 test (KErrNone == ret);
148 if (bitsPerPixel > maxBitsPerPixel)
150 maxBitsPerPixel = bitsPerPixel;
155 TInt offsetToFirstPixel = biggestMode;
156 ret = HAL::Get(aScreenID, HALData::EDisplayOffsetToFirstPixel, offsetToFirstPixel);
157 test(KErrNone == ret);
159 TInt stride = biggestMode;
160 ret = HAL::Get(aScreenID, HALData::EDisplayOffsetBetweenLines, stride);
161 test(KErrNone == ret);
163 TInt yPixels = biggestMode;
164 ret = HAL::Get(aScreenID, HALData::EDisplayYPixels, yPixels);
165 test(KErrNone == ret);
167 // Note this is no attempt to be precise. xPixels is not
168 TUint maxByte = offsetToFirstPixel + stride * yPixels - sizeof(TUint32);
170 volatile TUint32 *memPtr = reinterpret_cast<volatile TUint32 *>(reinterpret_cast<volatile TUint8 *>(pChunkBase) + maxByte);
171 *memPtr = KTestValue1;
172 test(KTestValue1 == *memPtr);
175 // Ask for a second handle and see that this also points to the same bit of memory.
176 test.Next(_L("Checking Display Handle second time"));
177 volatile TUint32 *pChunkBase2 = 0;
178 ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
179 test ((KErrNone == ret || KErrNotSupported == ret));
182 // Handle should not be zero!
185 ret = chunk2.SetReturnedHandle(handle);
186 test(KErrNone == ret);
188 pChunkBase2 = reinterpret_cast<TUint32 *>(chunk2.Base());
189 test.Printf(_L("Display Memory Address = %08x\n"), reinterpret_cast<TUint>(pChunkBase));
190 test(KTestValue2 == *pChunkBase2);
191 *pChunkBase2 = KTestValue3;
192 test(KTestValue3 == *pChunkBase2);
196 test.Next(_L("Checking Display Handle using second process"));
198 // Create a process, let it find the handle of the memory, then read it, and write it.
199 // Check that the value we have is the new value: KTestValue3.
200 _LIT(KProcName, "t_videomemprocess.exe");
203 ret = process.Create(KProcName, KNullDesC);
204 test(KErrNone == ret);
206 TRequestStatus procStatus;
207 process.Logon(procStatus);
208 process.SetParameter(12, aScreenID);
210 User::WaitForRequest(procStatus);
212 test.Next(_L("Checking that second process updated video memory"));
213 // Check that we got the new value.
214 test(KTestValue4 == *pChunkBase);
219 displayChannel.Close();
222 // Now for some negative tests: Attempt to get a handle for a closes display.
223 test.Next(_L("Negative test: Check that we CAN NOT use closed screen"));
224 ret = HAL::Get(aScreenID, HALData::EDisplayMemoryHandle, handle);
225 test (KErrNone != ret);
230 LOCAL_C void NegativeTests(TInt aMaxScreens)
234 // Another few negative tests: Try invalid screen numbers.
235 test.Next(_L("Negative tests: Invalid screen ID's"));
236 ret = HAL::Get(aMaxScreens, HALData::EDisplayMemoryHandle, handle);
237 test (KErrNone != ret);
239 ret = HAL::Get(aMaxScreens+1, HALData::EDisplayMemoryHandle, handle);
240 test (KErrNone != ret);
242 ret = HAL::Get(4718, HALData::EDisplayMemoryHandle, handle);
243 test (KErrNone != ret);
245 ret = HAL::Get(-1, HALData::EDisplayMemoryHandle, handle);
246 test (KErrNone != ret);
251 GLDEF_C TInt E32Main()
258 #if defined(__EPOC32__) && defined(__CPU_X86)
259 test.Printf(_L("Doesn't run on X86\n"));
262 test.Start(_L("Testing Video Memory HAL interfaces"));
265 TInt ret=HAL::Get(HAL::EDisplayNumberOfScreens, screens);
266 test((KErrNone == ret));
267 // We expect that there is at least ONE screen.
270 for(TInt i=0;i<screens;i++)
272 RunTestsForScreen(i);
275 NegativeTests(screens);