1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicstest/uibench/src/tmultiptreventhandlingperf.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,523 @@
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 "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 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @test
1.22 + @internalComponent - Internal Symbian test code
1.23 +*/
1.24 +
1.25 +#include "tmultiptreventhandlingperf.h"
1.26 +#include <hal.h>
1.27 +
1.28 +_LIT(KPerformanceTimingChunk, "PerformanceTimingChunk");
1.29 +
1.30 +// Number of iterations for eventset
1.31 +const TInt KNumOfIterations = 100;
1.32 +
1.33 +// Maximum descriptor length for results
1.34 +const TInt KMaxDescLength = 528;
1.35 +
1.36 +// Static variables used for synchronisation between threads
1.37 +GLDEF_D TInt NumOfEventsAdded = 0;
1.38 +GLDEF_D RMutex Mutex;
1.39 +GLDEF_D RCondVar ConVar;
1.40 +
1.41 +void MultiPtrPerfPanic(TInt aPanic)
1.42 + {
1.43 + User::Panic(_L("MultiPterEventHanldingPerformancePanic"), aPanic);
1.44 + }
1.45 +
1.46 +// This function opens the chunk and adds the failure description followed by '*'
1.47 +TInt CMultiPtrPerfTestControl::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
1.48 + {
1.49 + TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
1.50 + if (ret != KErrNone)
1.51 + {
1.52 + return ret;
1.53 + }
1.54 + TUint8* desPtr = iChunk.Base() + iChunkOffset;
1.55 + TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
1.56 +
1.57 + TBuf<80> buf;
1.58 + if (aExpPtrNum != aActPtrNum)
1.59 + {
1.60 + _LIT(KFailedPointerNum, "Failed Expected Pointer Num = %d Actual Pointer Num = %d*");
1.61 + buf.AppendFormat(KFailedPointerNum, aExpPtrNum, aActPtrNum);
1.62 + ptrDes.Append(buf);
1.63 + }
1.64 + else if (aErrorCode != KErrNone)
1.65 + {
1.66 + _LIT(KFailedErrorCode, "Failed Errorcode = %d*");
1.67 + buf.AppendFormat(KFailedErrorCode, aErrorCode);
1.68 + ptrDes.Append(buf);
1.69 + }
1.70 + else
1.71 + {
1.72 + _LIT(KFailedWrongCoord, "Failed Coordinates Expected = [%d, %d, %d] Actual = [%d, %d, %d]*");
1.73 + buf.AppendFormat(KFailedWrongCoord, aExp3DPoint.iX, aExp3DPoint.iY, aExp3DPoint.iZ, aActual3DPoint.iX, aActual3DPoint.iY, aActual3DPoint.iZ);
1.74 + ptrDes.Append(buf);
1.75 + }
1.76 +
1.77 + iChunk.Close();
1.78 + return ret;
1.79 + }
1.80 +
1.81 +// This function opens the chunk and adds a pointer event not supported message followed by '#'
1.82 +TInt CMultiPtrPerfTestControl::PointerEventsNotSupported()
1.83 + {
1.84 + iPointerEventNotSupported = ETrue;
1.85 + TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
1.86 + if (ret != KErrNone)
1.87 + {
1.88 + return ret;
1.89 + }
1.90 + TUint8* desPtr = iChunk.Base() + iChunkOffset;
1.91 + TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
1.92 + TBuf<80> buf;
1.93 + _LIT(KPointerEventsNotSupported, "Test Skipped As Pointer Events Are Not Supported By This Configuration#");
1.94 + buf.AppendFormat(KPointerEventsNotSupported);
1.95 + ptrDes.Append(buf);
1.96 + iChunk.Close();
1.97 + return ret;
1.98 + }
1.99 +
1.100 +// This function calulates the average latency, opens the chunk and appends
1.101 +// the same in descriptor form. Then close the child thread and calls function
1.102 +// for creating new thread for events.
1.103 +// If all the events have been tested then stops the tests
1.104 +// by calling active CActiveScheduler::Stop.
1.105 +TInt CMultiPtrPerfTestControl::CalculateLatencyAndStartThread()
1.106 + {
1.107 + TInt ret = KErrNone;
1.108 + switch (iPtrAppUi->TestCaseNum())
1.109 + {
1.110 + case 1:
1.111 + case 5:
1.112 + case 9:
1.113 + case 13:
1.114 + iAverageLatency = iLatency/(4*KNumOfIterations);
1.115 + break;
1.116 + case 2:
1.117 + case 6:
1.118 + case 10:
1.119 + case 14:
1.120 + iAverageLatency = iLatency/(8*KNumOfIterations);
1.121 + break;
1.122 + case 3:
1.123 + case 7:
1.124 + case 11:
1.125 + case 15:
1.126 + iAverageLatency = iLatency/(16*KNumOfIterations);
1.127 + break;
1.128 + case 4:
1.129 + case 8:
1.130 + case 12:
1.131 + case 16:
1.132 + iAverageLatency = iLatency/(32*KNumOfIterations);
1.133 + break;
1.134 + default:
1.135 + MultiPtrPerfPanic(EMultiPtrPerfPanicWrongTest);
1.136 + }
1.137 +
1.138 + ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
1.139 + if (ret != KErrNone)
1.140 + {
1.141 + return ret;
1.142 + }
1.143 + TUint8* desPtr = iChunk.Base() + iChunkOffset;
1.144 + TPtr8 ptrDes(desPtr, iLatLenInLetters, KMaxDescLength);
1.145 +
1.146 + TBuf<66> buf;
1.147 + buf.Num(iAverageLatency);
1.148 + buf.Append(',');
1.149 + ptrDes.Append(buf);
1.150 +
1.151 + // reset the iLatency for next set of test
1.152 + iLatency = 0;
1.153 +
1.154 + // For writing the next latency in chunk memory
1.155 + iLatLenInLetters = ptrDes.Length();
1.156 +
1.157 + iChunk.Close();
1.158 +
1.159 + // Before calling the thread Function close the current thread and then call the function
1.160 + // here when we kill the child thread it releases both mutex and condvar that it holds
1.161 + iPtrAppUi->ChildThread().Kill(KErrNone);
1.162 + iPtrAppUi->ChildThread().Close();
1.163 +
1.164 + if (iPtrAppUi->TestCaseNum() == 16)
1.165 + {
1.166 + // It it is the last test case then stop the active scheduler
1.167 + CActiveScheduler::Stop();
1.168 + return ret;
1.169 + }
1.170 + else
1.171 + {
1.172 + return iPtrAppUi->CreateEventSimulatingThreads();
1.173 + }
1.174 + }
1.175 +
1.176 +// This function is called by Cone whenever a event is outstanding
1.177 +// Here we check if the sent event is same as the expected event in array.
1.178 +// Then resumes the thread for next set of events. When all the events are completed
1.179 +// calls CalculateLatencyAndStartThread
1.180 +void CMultiPtrPerfTestControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
1.181 + {
1.182 + ASSERT(!iPointerEventNotSupported);
1.183 + // The event that is received is (0,0,0) then it is the first event that the test code is sending
1.184 + const TAdvancedPointerEvent* advancedPointerEvent = aPointerEvent.AdvancedPointerEvent();
1.185 +
1.186 + if (iPtrAppUi->TestCaseNum() == 0)
1.187 + {
1.188 + if (advancedPointerEvent->PointerNumber() == 0 && advancedPointerEvent->Position3D() == TPoint3D())
1.189 + {
1.190 + iPtrAppUi->CreateEventSimulatingThreads();
1.191 + return;
1.192 + }
1.193 + else
1.194 + {
1.195 + return; // ignore other events before starting the tests
1.196 + }
1.197 + }
1.198 +
1.199 + // Get the current time.
1.200 + // Subtract from the test start time.
1.201 + TTime currentTime;
1.202 + currentTime.UniversalTime();
1.203 + TInt64 curTime64 = currentTime.Int64();
1.204 + TInt timeSinceTestStart = curTime64 - iPtrAppUi->TestStartTime();
1.205 +
1.206 + // Get the event, get the time stored in Z corodinate
1.207 + // Then subtract the calculated time from Z coordinate
1.208 + iLatency += timeSinceTestStart - advancedPointerEvent->ProximityAndPressure();
1.209 +
1.210 + // Get the current event from buffer and compare it with got event
1.211 + TAdvancedPointerEvent expectedPtrEvent;
1.212 + if(0 == iEventBuffer.Remove(&expectedPtrEvent))
1.213 + {
1.214 + iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNotFound);
1.215 + return;
1.216 + }
1.217 +
1.218 + // Here Z corodinate is not checked.
1.219 + if (expectedPtrEvent.iPosition != advancedPointerEvent->iPosition)
1.220 + {
1.221 + iPtrAppUi->Failed(expectedPtrEvent.Position3D(), advancedPointerEvent->Position3D(), KErrNone);
1.222 + return;
1.223 + }
1.224 +
1.225 + if (expectedPtrEvent.PointerNumber() != advancedPointerEvent->PointerNumber())
1.226 + {
1.227 + iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNone, expectedPtrEvent.PointerNumber(), advancedPointerEvent->PointerNumber());
1.228 + return;
1.229 + }
1.230 +
1.231 + iPtrAppUi->DecrementEventCount();
1.232 + NumOfEventsAdded--;
1.233 +
1.234 + // Event count is zero when all the events have been tested
1.235 + if (iPtrAppUi->EventCount() == 0)
1.236 + {
1.237 + TInt ret = CalculateLatencyAndStartThread();
1.238 + if (ret != KErrNone)
1.239 + {
1.240 + iPtrAppUi->Failed(TPoint3D(), TPoint3D(), ret);
1.241 + return;
1.242 + }
1.243 + }
1.244 + else if (NumOfEventsAdded == 0)
1.245 + {
1.246 + ConVar.Signal();
1.247 + }
1.248 + }
1.249 +
1.250 +void CMultiPtrPerfTestControl::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
1.251 + {
1.252 + iEventBuffer.Add(&aExpEvent);
1.253 + }
1.254 +
1.255 +CMultiPtrPerfTestControl::~CMultiPtrPerfTestControl()
1.256 + {
1.257 + iChunk.Close();
1.258 + }
1.259 +
1.260 +void CMultiPtrPerfTestControl::ConstructL()
1.261 + {
1.262 + iPointerEventNotSupported = EFalse;
1.263 + ConstructL(TPoint(), ControlEnv()->ScreenDevice()->SizeInPixels());
1.264 + }
1.265 +
1.266 +void CMultiPtrPerfTestControl::ConstructL(TPoint aOrigin, TSize aSize)
1.267 + {
1.268 + iEventBuffer.SetLengthL(EEventBufferSize);
1.269 +
1.270 + iPtrAppUi = static_cast<CMultiPtrPerfTestAppUi*>(ControlEnv()->AppUi());
1.271 +
1.272 + CreateWindowL();
1.273 + Window().EnableAdvancedPointers();
1.274 + EnableDragEvents();
1.275 + SetExtent(aOrigin, aSize);
1.276 + ActivateL();
1.277 +
1.278 + // Get the cmdline argument of this process in descriptor
1.279 + // convert the descriptor to number and store it in iChunkOffset
1.280 + TBuf<128> buf;
1.281 + User::CommandLine(buf);
1.282 + TLex lex(buf);
1.283 + User::LeaveIfError(lex.Val(iChunkOffset));
1.284 + }
1.285 +
1.286 +// This function gets the current time and subtracts it from the time when the whole test was started.
1.287 +// Simulates the event and suspends the thread if aWaitAfterEachEvent is ETrue
1.288 +// If aWaitAfterEachEvent is EFalse then it suspends the thread after each set of event i,e after 4, 8, 16 and 32 events
1.289 +void SimulatePointerEvents(TInt aCount, CMultiPtrPerfTestAppUi* appUi, TBool aMultiPtrEvent = EFalse, TBool aWaitAfterEachEvent = ETrue)
1.290 + {
1.291 + TRawEvent rawEvent;
1.292 + TPoint ptrPos;
1.293 + TTime currentTime;
1.294 + TInt64 testStartTime = appUi->TestStartTime();
1.295 + TInt ptrNum = 0;
1.296 + TInt ptrMax = 0;
1.297 + // HAL as already been tested at the start of these tests. So no need to test once again
1.298 + HAL::Get(HALData::EPointerNumberOfPointers, ptrMax);
1.299 +
1.300 + appUi->SetNumberOfEvents((KNumOfIterations*aCount)-1);
1.301 +
1.302 + // For testing time taken for each event and for each set of events we make use of RMutex and RConvar.
1.303 + // RMutex is used not to preempt this thread until events has been added
1.304 + // RConVar is used to hold this thread until the events have been tested
1.305 + for (TInt loop = 0; loop < KNumOfIterations; loop++)
1.306 + {
1.307 + ptrNum = 0;
1.308 + ptrPos.iX = ptrPos.iY = 0;
1.309 + Mutex.Wait();
1.310 + for (TInt count = 0; count < aCount/2; count++, ptrNum++)
1.311 + {
1.312 + if (ptrNum >= ptrMax)
1.313 + {
1.314 + ptrNum = 0;
1.315 + }
1.316 + ptrPos.iX += 2;
1.317 + ptrPos.iY += 1;
1.318 +
1.319 + TWsEvent event;
1.320 + event.InitAdvancedPointerEvent(TPointerEvent::EButton1Down, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
1.321 + appUi->AddExpectedEvent(*event.Pointer());
1.322 + currentTime.UniversalTime();
1.323 + TInt64 curTime64 = currentTime.Int64();
1.324 + TInt timeSinceTestStart = curTime64 - testStartTime;
1.325 + rawEvent.Set(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
1.326 + UserSvr::AddEvent(rawEvent);
1.327 + NumOfEventsAdded++;
1.328 + if (aWaitAfterEachEvent)
1.329 + {
1.330 + while(NumOfEventsAdded)
1.331 + ConVar.Wait(Mutex);
1.332 + }
1.333 +
1.334 + event.InitAdvancedPointerEvent(TPointerEvent::EButton1Up, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
1.335 + appUi->AddExpectedEvent(*event.Pointer());
1.336 + currentTime.UniversalTime();
1.337 + curTime64 = currentTime.Int64();
1.338 + timeSinceTestStart = curTime64 - testStartTime;
1.339 + rawEvent.Set(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
1.340 + UserSvr::AddEvent(rawEvent);
1.341 + NumOfEventsAdded++;
1.342 + if (aWaitAfterEachEvent)
1.343 + {
1.344 + while(NumOfEventsAdded)
1.345 + ConVar.Wait(Mutex);
1.346 + }
1.347 + }
1.348 + if (!aWaitAfterEachEvent)
1.349 + {
1.350 + while(NumOfEventsAdded)
1.351 + ConVar.Wait(Mutex);
1.352 + }
1.353 + Mutex.Signal();
1.354 + }
1.355 + }
1.356 +
1.357 +TInt EventSimulatingThreadStartFunc(TAny* aAny)
1.358 + {
1.359 + CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(aAny);
1.360 +
1.361 + switch(appUi->TestCaseNum()++)
1.362 + {
1.363 + case 0:
1.364 + SimulatePointerEvents(4, appUi);
1.365 + break;
1.366 + case 1:
1.367 + SimulatePointerEvents(8, appUi);
1.368 + break;
1.369 + case 2:
1.370 + SimulatePointerEvents(16, appUi);
1.371 + break;
1.372 + case 3:
1.373 + SimulatePointerEvents(32, appUi);
1.374 + break;
1.375 + case 4:
1.376 + SimulatePointerEvents(4, appUi, ETrue);
1.377 + break;
1.378 + case 5:
1.379 + SimulatePointerEvents(8, appUi, ETrue);
1.380 + break;
1.381 + case 6:
1.382 + SimulatePointerEvents(16, appUi, ETrue);
1.383 + break;
1.384 + case 7:
1.385 + SimulatePointerEvents(32, appUi, ETrue);
1.386 + break;
1.387 + case 8:
1.388 + SimulatePointerEvents(4, appUi, EFalse, EFalse);
1.389 + break;
1.390 + case 9:
1.391 + SimulatePointerEvents(8, appUi, EFalse, EFalse);
1.392 + break;
1.393 + case 10:
1.394 + SimulatePointerEvents(16, appUi, EFalse, EFalse);
1.395 + break;
1.396 + case 11:
1.397 + SimulatePointerEvents(32, appUi, EFalse, EFalse);
1.398 + break;
1.399 + case 12:
1.400 + SimulatePointerEvents(4, appUi, ETrue, EFalse);
1.401 + break;
1.402 + case 13:
1.403 + SimulatePointerEvents(8, appUi, ETrue, EFalse);
1.404 + break;
1.405 + case 14:
1.406 + SimulatePointerEvents(16, appUi, ETrue, EFalse);
1.407 + break;
1.408 + case 15:
1.409 + SimulatePointerEvents(32, appUi, ETrue, EFalse);
1.410 + break;
1.411 + default:
1.412 + break;
1.413 + }
1.414 + return KErrNone;
1.415 + }
1.416 +
1.417 +TInt CMultiPtrPerfTestAppUi::CreateEventSimulatingThreads()
1.418 + {
1.419 + // Depending upon the iTestCase number create thread and simulate events in that thread function
1.420 + TInt ret = KErrNone;
1.421 + _LIT(KSimulateEventsThread, "Events simulating thread");
1.422 + ret = iThread.Create(KSimulateEventsThread, EventSimulatingThreadStartFunc, KDefaultStackSize, 0x4000, 0x4000, this, EOwnerThread);
1.423 + if (ret == KErrNone)
1.424 + {
1.425 + iThread.Resume();
1.426 + }
1.427 + return ret;
1.428 + }
1.429 +
1.430 +void CMultiPtrPerfTestAppUi::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
1.431 + {
1.432 + iControl->AddExpectedEvent(aExpEvent);
1.433 + }
1.434 +
1.435 +void CMultiPtrPerfTestAppUi::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
1.436 + {
1.437 + // Write error description in the memory of shared chunk
1.438 + // so that the main performance test just stops by saying that it failed
1.439 + // and then stop the active scheduler.
1.440 + iControl->Failed(aExp3DPoint, aActual3DPoint, aErrorCode, aExpPtrNum, aActPtrNum);
1.441 + CActiveScheduler::Stop();
1.442 + }
1.443 +
1.444 +void CMultiPtrPerfTestAppUi::PointerEventsNotSupported()
1.445 + {
1.446 + // Write a pointer events not supported message in the memory of shared chunk
1.447 + // so that the main performance test just skips the pointer test
1.448 + iControl->PointerEventsNotSupported();
1.449 + }
1.450 +
1.451 +CMultiPtrPerfTestAppUi::CMultiPtrPerfTestAppUi()
1.452 + {
1.453 + }
1.454 +
1.455 +CMultiPtrPerfTestAppUi::~CMultiPtrPerfTestAppUi()
1.456 + {
1.457 + RemoveFromStack(iControl);
1.458 + delete iControl;
1.459 + }
1.460 +
1.461 +void CMultiPtrPerfTestAppUi::ConstructL()
1.462 + {
1.463 + CCoeAppUi::ConstructL();
1.464 +
1.465 + TTime testStartTime;
1.466 + testStartTime.UniversalTime();
1.467 + iTestStartTime = testStartTime.Int64();
1.468 +
1.469 + iControl = new (ELeave) CMultiPtrPerfTestControl();
1.470 + iControl->ConstructL();
1.471 + AddToStackL(iControl);
1.472 + }
1.473 +
1.474 +void ConstructControlEnvironmentL(CCoeEnv* aCoe)
1.475 + {
1.476 + aCoe->ConstructL();
1.477 + CMultiPtrPerfTestAppUi* appUi=new(ELeave) CMultiPtrPerfTestAppUi();
1.478 + CleanupStack::PushL(appUi); // If it leaves after this then there is no way of deleting the appui
1.479 + aCoe->SetAppUi(appUi); // So pushed it on to cleanup stack
1.480 + aCoe->WsSession().SetAutoFlush(ETrue);
1.481 + appUi->ConstructL();
1.482 + User::LeaveIfError(Mutex.CreateLocal(EOwnerProcess));
1.483 + User::LeaveIfError(ConVar.CreateLocal(EOwnerProcess));
1.484 + CleanupStack::Pop(appUi);
1.485 + }
1.486 +
1.487 +GLDEF_C TInt E32Main()
1.488 + {
1.489 + __UHEAP_MARK;
1.490 + CCoeEnv* coe = new CCoeEnv;
1.491 + if (!coe)
1.492 + {
1.493 + return KErrNoMemory;
1.494 + }
1.495 + TRAPD(err, ConstructControlEnvironmentL(coe));
1.496 + if (err != KErrNone)
1.497 + {
1.498 + delete coe;
1.499 + }
1.500 + else // If KErrNone then no need to delte coe as it is taken care by ConEnv
1.501 + {
1.502 + // Check whether the configuration supports pointer events.
1.503 + // If it dosn't support pointer events then the pointer cursor area will be empty,
1.504 + // in this case skip the test and inform the test framework that the test has been skipped
1.505 + TRect pointerCursorArea = coe->WsSession().PointerCursorArea();
1.506 + if(pointerCursorArea.IsEmpty())
1.507 + {
1.508 + RDebug::Printf("PointerCursorArea is Empty");
1.509 + CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(coe->AppUi());
1.510 + appUi->PointerEventsNotSupported();
1.511 + }
1.512 + else
1.513 + {
1.514 + // First event which starts the test from HandlePointerEventL
1.515 + TRawEvent rawEvent;
1.516 + rawEvent.Set(TRawEvent::EButton1Down, 0, 0, 0, 0);
1.517 + UserSvr::AddEvent(rawEvent);
1.518 + coe->ExecuteD();
1.519 + }
1.520 + Mutex.Close();
1.521 + ConVar.Close();
1.522 + }
1.523 +
1.524 + __UHEAP_MARKEND;
1.525 + return err;
1.526 + }