First public contribution.
1 // Copyright (c) 2007-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 "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.
16 #include "testrenderer.h"
17 #include "videoframebuffer.h"
18 #include "testgceharness.h"
20 RTestRendererStep* RTestRendererStep::NewL(const TDesC& aStepName, TBool aTimed)
22 RTestRendererStep* self = new (ELeave) RTestRendererStep(aStepName, aTimed);
26 RTestRendererStep::RTestRendererStep(const TDesC& aStepName, TBool aTimed) :
30 iTestStepName = aStepName;
32 // size for buffer created
35 iVideoFormat.iDataFormat = ERgbRawData;
36 iVideoFormat.iRgbFormat = ERgb32bit888;
39 void RTestRendererStep::MvroVideoBufferAvailable()
41 INFO_PRINTF1(_L("MvroVideoBufferAvailable() callback received"));
42 TRAPD(err, FsmL(EBufferAvailable));
45 ERR_PRINTF2(_L("FsmL(EBufferAvailable) failed with %d"), err);
50 void RTestRendererStep::MvroBufferDisplayed(TInt aBufferId, const TTime& aTime)
52 INFO_PRINTF2(_L("MvroBufferDisplayed() callback received aBufferId=%d"), aBufferId);
53 iBufferId = aBufferId;
54 iDisplayedTime = aTime;
55 TRAPD(err, FsmL(EBufferDisplayed));
58 ERR_PRINTF2(_L("FsmL(EBufferDisplayed) failed with %d"), err);
63 void RTestRendererStep::MvroBufferSkipped(TInt aBufferId)
65 INFO_PRINTF2(_L("MvroBufferSkipped() callback received aBufferId=%d"), aBufferId);
66 iBufferId = aBufferId;
67 TRAPD(err, FsmL(EBufferSkipped));
70 ERR_PRINTF2(_L("FsmL(EBufferSkipped) failed with %d"), err);
75 TVerdict RTestRendererStep::DoTestStepPreambleL()
77 // Install the Active Scheduler
78 iActiveScheduler = new(ELeave) CActiveScheduler;
79 CActiveScheduler::Install(iActiveScheduler);
80 iActiveSchedulerStarted = EFalse;
82 iBuffAvailCallback = 0;
83 iBuffDisplayCallback = 0;
84 iBuffSkipCallback = 0;
86 // The following is required because of the panic tests.
87 // When a thread panics the global pointer is not reset to NULL
88 // and the following test fails because the pointer is hanging.
89 // When testframework creates a thread to run the test step it also
90 // defines a heap and the default process heap is not used. Therefore
91 // when the thread dies the heap is no longer available.
92 CTestGCEHarness::ResetGlobalPointer();
94 // Initialise Window server objects
100 TVerdict RTestRendererStep::DoTestStepPostambleL()
102 CActiveScheduler::Install(NULL);
103 delete iActiveScheduler;
104 iActiveScheduler = NULL;
106 // Destroy Window server objects
112 void RTestRendererStep::InitWservL()
114 TInt err = iWs.Connect();
117 // Access violation if ws is null
118 ERR_PRINTF1(_L("Cannot test, no window server available"));
122 iScreen = new (ELeave) CWsScreenDevice(iWs); // make device for this session
123 User::LeaveIfError(iScreen->Construct()); // and complete its construction
125 iRootWindow = RWindowGroup(iWs);
126 User::LeaveIfError(iRootWindow.Construct((TUint32)this, ETrue));
128 iWindow = new(ELeave) RWindow(iWs);
129 User::LeaveIfError(((RWindow*)iWindow)->Construct(iRootWindow,((TUint32)(this)) + 1));
130 iWindow->SetExtent(TPoint(0,0), TSize(100,100));
131 iWindow->SetVisible(ETrue);
132 iWindow->SetRequiredDisplayMode(EColor16MA);
136 void RTestRendererStep::DeInitWserv()
151 TInt RTestRendererStep::SetBackgroundSurface(TSurfaceId& id)
153 TInt err = iWindow->SetBackgroundSurface(id);
158 void RTestRendererStep::RemoveBackgroundSurface()
160 iWindow->RemoveBackgroundSurface(ETrue);
163 TVerdict RTestRendererStep::DoTestStepL()
167 // Call the state handler from IDLE state
168 TRAPD(err, FsmL(EStartTest));
169 if (err == KErrNone && iTestStepResult == EPass)
171 // Start the scheduler - Done only once !
172 iActiveSchedulerStarted = ETrue;
173 CActiveScheduler::Start();
175 else if (err != KErrNone)
177 ERR_PRINTF2(_L("FsmL(EStartTest) leave with %d"), err);
178 iTestStepResult = EFail;
181 delete iVideoRenderer;
182 iVideoRenderer = NULL;
184 // cleanup test harness
185 CTestGCEHarness::Remove();
189 return iTestStepResult;
192 void RTestRendererStep::FsmL(TTestRendererEvents aEventCode)
198 iFsmState = EStateCreate;
201 INFO_PRINTF2(_L("CVideoRenderer::NewL() Timed=%d"), iTimed);
202 CTestGCEHarness::NewL(numBuffers);
203 iVideoRenderer = CVideoRenderer::NewL(*this, iTimed);
205 INFO_PRINTF1(_L("iVideoRenderer->GetSupportedFormatsL()"));
206 RArray<TUncompressedVideoFormat> expectedArray;
207 CleanupClosePushL(expectedArray);
208 TUncompressedVideoFormat format;
209 format.iDataFormat = ERgbRawData;
210 format.iRgbFormat = ERgb16bit444;
211 expectedArray.AppendL(format); // append EVideoRendererPixelFormatXRGB_4444
212 format.iDataFormat = ERgbRawData;
213 format.iRgbFormat = ERgb16bit565;
214 expectedArray.AppendL(format); // append EVideoRendererPixelFormatRGB_565
215 format.iDataFormat = ERgbRawData;
216 format.iRgbFormat = ERgb32bit888;
217 expectedArray.AppendL(format); // append EVideoRendererPixelFormatXRGB_8888:
219 RArray<TUncompressedVideoFormat> array;
220 CleanupClosePushL(array);
221 iVideoRenderer->GetSupportedFormatsL(array);
222 TInt expectedCount = expectedArray.Count();
223 TESTL(array.Count() == expectedCount);
224 for (TInt i = 0; i < expectedCount; i++)
226 TESTL(expectedArray[i] == array[i]);
229 CleanupStack::PopAndDestroy(2, &expectedArray);
230 CreateSurfaceL(numBuffers);
234 case EBufferAvailable:
235 iBuffAvailCallback++;
236 if (iFsmState == EStateCreate && iBuffAvailCallback == 1)
238 iFsmState = EStateUpdate;
240 // map surface to display
241 TInt err = SetBackgroundSurface(iSurfaceId);
244 ERR_PRINTF2(_L("RWindow::SetBackgroundSurface() returned %d"), err);
249 TTime presentationTime;
250 presentationTime.UniversalTime();
251 TTimeIntervalMicroSeconds microsec(500000); // use half a second delay
252 presentationTime += microsec;
253 GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime);
255 else if (iFsmState == EStateUpdate && iBuffAvailCallback == 2)
257 iFsmState = EStateReleaseBuffer;
259 // buffer is available again after update;
260 // try to get next buffer
261 TVideoFrameBuffer* buffer;
262 INFO_PRINTF1(_L("iVideoRenderer->NextBuffer() after update"));
263 buffer = iVideoRenderer->NextBuffer();
264 TESTL(buffer != NULL);
265 INFO_PRINTF1(_L("iVideoRenderer->ReleaseBuffer()"));
266 iVideoRenderer->ReleaseBuffer(buffer);
268 else if (iFsmState == EStateReleaseBuffer)
270 if (iBuffDisplayCallback == 1)
272 // both release buffer callback and display callback are received, test complete with pass
275 // else continue waiting for more callback
279 ERR_PRINTF2(_L("State %d was not expected when handling buffer available event."), iFsmState);
284 case EBufferDisplayed:
285 iBuffDisplayCallback++;
286 if ((iFsmState != EStateUpdate && iFsmState != EStateReleaseBuffer) ||
289 // not in a valid state
290 ERR_PRINTF2(_L("State %d was not expected when handing buffer displayed event."), iFsmState);
293 if (iFsmState == EStateReleaseBuffer && iBuffAvailCallback == 3)
295 // both release buffer callback and display callback are received, test complete with pass
298 // otherwise, haven't received release callback yet, continue waiting
302 ERR_PRINTF2(_L("Unexpected event code %d in RTestRendererStep::FsmL"), aEventCode);
308 void RTestRendererStep::EndTest(TVerdict aVerdict)
310 iTestStepResult = aVerdict;
311 if (iActiveSchedulerStarted)
313 CActiveScheduler::Stop();
317 void RTestRendererStep::CreateRendererAndSurfaceL(TInt aNumBuffers)
319 INFO_PRINTF2(_L("CVideoRenderer::NewL() Timed=%d"), iTimed);
320 CTestGCEHarness::NewL(aNumBuffers);
321 iVideoRenderer = CVideoRenderer::NewL(*this, iTimed);
322 CreateSurfaceL(aNumBuffers);
325 void RTestRendererStep::CreateSurfaceL(TInt aNumBuffers)
327 INFO_PRINTF1(_L("iVideoRenderer->CreateSurfaceL()"));
328 iVideoRenderer->CreateSurfaceL(iSize, aNumBuffers, iVideoFormat, iSurfaceId);
331 void RTestRendererStep::GetNextBufferAndSubmitUpdateL(TInt aExpectedBufId, TRgb aColor, const TTime& aPresentationTime)
333 TVideoFrameBuffer* buffer = GetNextBufferL(aExpectedBufId, aColor);
334 INFO_PRINTF1(_L("iVideoRenderer->UpdateBuffer()"));
335 iVideoRenderer->UpdateBuffer(buffer, aPresentationTime);
338 TVideoFrameBuffer* RTestRendererStep::GetNextBufferL(TInt aExpectedBufId, TRgb aColor)
340 INFO_PRINTF1(_L("iVideoRenderer->NextBuffer()"));
341 TVideoFrameBuffer* buffer;
342 buffer = iVideoRenderer->NextBuffer();
343 TESTL(buffer != NULL);
344 TESTL(buffer->Format() == iVideoFormat);
345 TESTL(buffer->Stride() == iSize.iWidth * 4); // 4 bite per pixel for ERgb32bit888
346 TESTL(buffer->BufferId() == aExpectedBufId);
347 TESTL(buffer->Buffer() != NULL);
349 TInt bufSize = buffer->Stride() * iSize.iHeight;
350 Mem::Fill(buffer->Buffer(), bufSize, aColor.Internal());
354 RTestRendererReplaceStep* RTestRendererReplaceStep::NewL(const TDesC& aStepName, TBool aTimed)
356 RTestRendererReplaceStep* self = new (ELeave) RTestRendererReplaceStep(aStepName, aTimed);
360 RTestRendererReplaceStep::RTestRendererReplaceStep(const TDesC& aStepName, TBool aTimed) :
361 RTestRendererStep(aStepName, aTimed)
365 void RTestRendererReplaceStep::FsmL(TTestRendererEvents aEventCode)
370 iFsmState = EStateCreate;
371 CreateRendererAndSurfaceL(1);
373 case EBufferAvailable:
374 iBuffAvailCallback++;
375 if (iFsmState == EStateCreate && iBuffAvailCallback == 1)
377 iFsmState = EStateUpdate;
379 // received the first callback, map surface to display
380 TInt err = SetBackgroundSurface(iSurfaceId);
381 TESTL(err == KErrNone);
384 TTime presentationTime(0);
385 GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime);
387 else if (iFsmState == EStateUpdate)
389 if (iBuffDisplayCallback == 1 && iBuffAvailCallback == 2)
391 iFsmState = EStateReplaceSurface;
395 else if (iFsmState == EStateReplaceSurface && iBuffAvailCallback == 1)
397 // received the first callback, map surface to display
398 TInt err = SetBackgroundSurface(iSurfaceId);
401 ERR_PRINTF2(_L("RWindow::SetBackgroundSurface() returned %d"), err);
405 else if (iFsmState == EStateReplaceSurface && iBuffAvailCallback == 2)
407 iFsmState = EStateUpdateAfterReplace;
411 TTime presentationTime1;
412 presentationTime1.UniversalTime();
413 TTimeIntervalMicroSeconds delay(500);
414 TTime presentationTime2 = presentationTime1 + delay;
416 GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime1);
417 GetNextBufferAndSubmitUpdateL(1, KRgbGreen, presentationTime2);
419 else if (iFsmState == EStateUpdateAfterReplace)
421 if (iBuffDisplayCallback == 2 && iBuffAvailCallback == 3)
425 // else continue waiting for more callback
429 // unexpected state, fail test
430 ERR_PRINTF2(_L("State %d was not expected when handling buffer available event."), iFsmState);
435 case EBufferDisplayed:
436 iBuffDisplayCallback++;
437 if (iFsmState == EStateUpdate && iBuffDisplayCallback == 1 && iBufferId == 0)
439 // receive display callback
440 if (iBuffAvailCallback == 2)
442 iFsmState = EStateReplaceSurface;
446 else if (iFsmState == EStateUpdateAfterReplace && iBuffDisplayCallback == 1 && iBufferId == 0)
448 // receive display callback
450 else if (iFsmState == EStateUpdateAfterReplace && iBuffDisplayCallback == 2 && iBufferId == 1)
452 if (iBuffAvailCallback == 3)
456 // else haven't received all callback, continue waiting
460 // not in a valid state
461 ERR_PRINTF2(_L("State %d was not expected when handling buffer displayed event."), iFsmState);
466 ERR_PRINTF1(_L("Frame unexpectedly skipped"));
472 void RTestRendererReplaceStep::ReplaceSurfaceL()
474 // reset the number of callback
475 iBuffDisplayCallback = 0;
476 iBuffAvailCallback = 0;
478 RemoveBackgroundSurface();
480 // received all expected callback for update
481 // destroy surface and create new one for testing replace surface
482 INFO_PRINTF1(_L("iVideoRenderer->DestroySurface()"));
483 iVideoRenderer->DestroySurface(iSurfaceId);
485 CTestGCEHarness::ResetBuffersL(buffers);
486 CreateSurfaceL(buffers);
490 Standard static NewL() taking a callback function
492 CCallBackTimer* CCallBackTimer::NewL(TCallBack aCallBack, TPriority aPriority)
494 CCallBackTimer* self = new(ELeave) CCallBackTimer(aCallBack, aPriority);
495 CleanupStack::PushL(self);
497 CleanupStack::Pop(self);
504 CCallBackTimer::CCallBackTimer(TCallBack aCallBack, TPriority aPriority) :
505 CTimer(aPriority), iCallBack(aCallBack)
507 CActiveScheduler::Add(this);
511 Callback on timer complete
513 void CCallBackTimer::RunL()
515 iCallBack.CallBack();