Update contrib.
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 "tinterleaving.h"
17 #include "tdirectgdieglcontent_client.h"
18 #include "tdirectgdieglcontent_clientserver.h"
19 #include <graphics/sgimage_sw.h>
20 #include <graphics/directgdiimagetarget.h>
21 #include <graphics/directgdidriver.h>
25 A utility class used by the templated function CleanupResetAndDestroyPushL() to create
26 a TCleanupItem item that will perform a ResetAndDestroy() operation on the class T type object.
27 Used for cleanup RPointerArray objects.
29 template <class T> class CleanupResetAndDestroy
32 static void PushL(T &aRef)
34 CleanupStack::PushL(TCleanupItem(&ResetAndDestroy, &aRef));
38 static void ResetAndDestroy(TAny *aPtr)
40 (STATIC_CAST(T *, aPtr))->ResetAndDestroy();
45 Helper function for pushing CleanupResetAndDestroy object onto CleanupStack.
47 template <class T> void CleanupResetAndDestroyPushL(T &aRef)
49 CleanupResetAndDestroy<T>::PushL(aRef);
52 CTInterleaving::CTInterleaving()
54 SetTestStepName(KTDirectGdiInterleavingStep);
57 CTInterleaving::~CTInterleaving()
63 GRAPHICS-DIRECTGDI-INTERLEAVING-0001
83 Test synchronized drawing with egl content
91 @SYMTestActions Establish connection to EglContentServer.
92 Render frame synchronized with EGL content in following way:
93 - Draw multicolor checkboard to gdi target
94 - Get EGL content sgimage id from EglContentServer in synchronous mode.
95 - Using obtained id create DirectGdi image source and draw it on target with DrawResource() method.
96 - Draw semi-transparent vertical bars to gdi target.
97 Repeat above steps a few times.
99 @SYMTestExpectedResults
100 Valid set of bitmaps should be created.
101 These bitmaps should be the same as a reference bitmaps.
103 void CTInterleaving::TestSyncL()
105 _LIT(KTestName, "Interleaving-Sync"); //test case name
106 // start EGL content server
107 REglContentSession eglContentSession;
108 TESTNOERRORL(eglContentSession.Connect());
109 CleanupClosePushL(eglContentSession);
111 // render few frames synchronized with egl content
112 for(TInt frame=0; frame<10; frame++)
116 DrawDirectGdiCheckboardToTarget();
117 TESTNOERRORL(iGc->GetError());
119 // get egl content sgimage id
120 TSgDrawableId imageId;
121 TESTNOERRORL(eglContentSession.GetSyncImage(imageId));
123 DrawImageToTargetL(imageId);
124 TESTNOERRORL(iGc->GetError());
126 DrawDirectGdiBarsToTarget();
127 TESTNOERRORL(iGc->GetError());
131 testName.Append(KTestName);
132 testName.AppendNum(frame);
133 TESTNOERRORL(CTDirectGdiStepBase::WriteTargetOutput(iTestParams, testName));
136 CleanupStack::PopAndDestroy(&eglContentSession);
141 GRAPHICS-DIRECTGDI-INTERLEAVING-0002
161 Test asynchronous drawing of egl content
169 @SYMTestActions Establish connection to EglContentServer.
170 Render frame in following way:
171 - Draw multicolor checkboard to gdi target
172 - Get EGL content sgimage id and frame number from EglContentServer in asynchronous mode.
173 - Using obtained id create DirectGdi image source and draw it on target with DrawResource() method.
174 - Draw semi-transparent vertical bars to gdi target.
175 - Find currently created target bitmap in stored bitmaps array.
176 Use frame number obtained from EglContentServer as an array index.
177 If it not exists in this array, store it. Otherwise compare it with stored one pixel by pixel.
178 Test fails when this comparison fails.
179 EglContentServer produce ten different frames,
180 so for proper testing repeat above steps at least fifty times.
182 @SYMTestExpectedResults Valid set of bitmaps should be created.
183 These bitmaps should be the same as a reference bitmaps.
185 void CTInterleaving::TestAsyncL(TBool aDebug)
187 _LIT(KTestName, "Interleaving-Async"); //test case name
189 // start EGL content server
190 REglContentSession eglContentSession;
191 TESTNOERRORL(eglContentSession.Connect());
192 CleanupClosePushL(eglContentSession);
194 // prepare array to store frames
195 RPointerArray<CFbsBitmap> storedBitmaps(KEglContentAsyncMaxFrames);
196 CleanupResetAndDestroyPushL(storedBitmaps);
197 for(TInt i=0; i<KEglContentAsyncMaxFrames; i++)
199 storedBitmaps.AppendL(NULL);
202 // prepare line buffers for bitmap comparision
203 TInt bufSize = iGdiTarget->SizeInPixels().iWidth*4; // buffer is 32-bit BGRA
204 HBufC8* lineBuf1 = HBufC8::NewLC(bufSize);
205 HBufC8* lineBuf2 = HBufC8::NewLC(bufSize);
207 // With the EGL context continuously being generated, we cannot guarantee that
208 // all the frames will be retrieved.
209 // However, in theory, the probability of picking each frame can be
210 // approximated to a uniform discrete distribution.
211 // So we can work out how many times we need to pick a frame to get all
212 // the unique frames 99% of the time.
213 // This works out to be approximately 65 times for 10 unique frames.
214 const TInt KNumTriesToGetAllFrames = 65;
218 WARN_PRINTF1(_L("Note: Due to the nature of the test, it may be possible that not all the frames are captured"));
220 TInt64 seed = (TInt64)User::FastCounter();
222 // render few frames asynchronous from egl content
223 for(TInt frame=0; frame<KNumTriesToGetAllFrames; frame++)
227 DrawDirectGdiCheckboardToTarget();
228 TESTNOERRORL(iGc->GetError());
230 // get egl content sgimage id
231 TSgDrawableId imageId;
235 TESTNOERRORL(eglContentSession.GetAsyncImage(imageId, fnum));
236 // Due to the nature of the asynchronous test, where the frames are
237 // continuously being rendered and we can only dip in and pick the last
238 // rendered frame, it cannot be guaranteed that all the unique frames will
239 // be retrieved. This could be due to this loop and the EGL content
240 // generation running in harmony. To try to overcome this, introduce
241 // a random delay between 0 and 3 frames (0 seconds to 100 milliseconds -
242 // EGL content generated at 30fps).
243 TInt delay = Math::Rand(seed)%100000;
248 TESTNOERRORL(eglContentSession.GetAsyncImageDebug(imageId, fnum));
251 DrawImageToTargetL(imageId);
252 TESTNOERRORL(iGc->GetError());
254 DrawDirectGdiBarsToTarget();
255 TESTNOERRORL(iGc->GetError());
257 iGdiTarget->Finish();
258 CFbsBitmap* targetBitmap = iGdiTarget->GetTargetFbsBitmapL();
260 if(storedBitmaps[fnum] != NULL)
262 // compare with previously stored bitmap
263 TUint32 cmpMask; // BGRA mask
264 if((iTestParams.iTargetPixelFormat == EUidPixelFormatXRGB_8888) ||
265 (iTestParams.iTargetPixelFormat == EUidPixelFormatXRGB_4444))
267 cmpMask = 0xffffff00; // exclude unused pixel part from comparision
271 cmpMask = 0xffffffff;
274 TInt width = targetBitmap->SizeInPixels().iWidth;
275 TInt height = targetBitmap->SizeInPixels().iHeight;
277 TPtr8 linePtr1(lineBuf1->Des());
278 TPtr8 linePtr2(lineBuf2->Des());
282 // compare pixel by pixel
283 for(TInt line=0; line<height; line++)
285 targetBitmap->GetScanLine(linePtr1, TPoint(0, line), width, EColor16MA);
286 storedBitmaps[fnum]->GetScanLine(linePtr2, TPoint(0, line), width, EColor16MA);
288 const TUint32* pPtr1 = (const TUint32*)linePtr1.Ptr();
289 const TUint32* pPtr2 = (const TUint32*)linePtr2.Ptr();
290 for(TInt x=0; x<width; x++)
292 if((pPtr1[x] & cmpMask) != (pPtr2[x] & cmpMask))
295 break; // break inner loop
300 break; // break outer loop if test failed in inner loop
305 INFO_PRINTF2(_L("Frame %d not equal to previous one"), fnum);
311 // copy and store target bitmap
312 storedBitmaps[fnum] = new(ELeave) CFbsBitmap();
313 TESTL(storedBitmaps[fnum]->Create(targetBitmap->SizeInPixels(), targetBitmap->DisplayMode()) == KErrNone);
314 Mem::Copy((TUint8*)storedBitmaps[fnum]->DataAddress(),
315 (TUint8*)targetBitmap->DataAddress(),
316 storedBitmaps[fnum]->DataStride()*storedBitmaps[fnum]->SizeInPixels().iHeight);
320 testName.Append(KTestName);
323 _LIT(KDebug, "Debug");
324 testName.Append(KDebug);
326 testName.AppendNum(fnum);
327 TESTNOERRORL(CTDirectGdiStepBase::WriteTargetOutput(iTestParams, testName));
331 CleanupStack::PopAndDestroy(4, &eglContentSession);
335 Draw multicolor checkboard to gdi target.
337 void CTInterleaving::DrawDirectGdiCheckboardToTarget()
339 const TInt width = iGdiTarget->SizeInPixels().iWidth;
340 const TInt height = iGdiTarget->SizeInPixels().iHeight;
341 const TInt rwidth = 13;
342 const TInt rheight = 13;
344 iGc->SetPenStyle(DirectGdi::ENullPen);
345 iGc->SetBrushStyle(DirectGdi::ESolidBrush);
348 for(TInt y=0; y<height; y+=rheight)
350 for(TInt x=0; x<width; x+=rwidth)
352 iGc->SetBrushColor(KColor16Table[color%16]);
354 iGc->DrawRect(TRect(TPoint(x, y), TSize(rwidth, rheight)));
360 Draw semi-transparent vertical bars to gdi target.
362 void CTInterleaving::DrawDirectGdiBarsToTarget()
365 TSize size(iGdiTarget->SizeInPixels());
366 size -= TSize(80, 80);
367 TSize barSize(size.iWidth/10, size.iHeight);
369 iGc->SetPenStyle(DirectGdi::ENullPen);
370 iGc->SetBrushStyle(DirectGdi::ESolidBrush);
372 for(TInt i=0; i<size.iWidth; i+=barSize.iWidth)
374 TRgb color(255, 0, 0, 25*i/barSize.iWidth);
375 iGc->SetBrushColor(color);
376 iGc->DrawRect(TRect(pos+TPoint(i, 0), barSize));
381 Draw four rotated EGL images to gdi target.
383 void CTInterleaving::DrawImageToTargetL(TSgDrawableId aImageId)
385 // prepare sgimage from id
387 TESTNOERRORL(image.Open(aImageId));
388 CleanupClosePushL(image);
390 TESTNOERRORL(CDirectGdiDriver::Open());
392 CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static();
393 TESTL(dgdiDriver != NULL);
394 CleanupClosePushL(*dgdiDriver);
396 // prepare DirectGdi image source
397 RDirectGdiDrawableSource source(*dgdiDriver);
398 TESTNOERRORL(source.Create(image));
399 CleanupClosePushL(source);
401 // draw sgimage resorce on gdi target
402 TDrawableSourceAndEquivRotatedBmps imageSource;
403 imageSource.iDrawableSrc = &source;
405 TSize size(iGdiTarget->SizeInPixels());
406 size -= TSize(40, 40);
410 size2 -= TSize(10, 10);
412 iGc->DrawResource(TRect(pos, size2), imageSource);
413 TESTNOERRORL(iGc->GetError());
414 iGc->DrawResource(TRect(pos+TPoint(size.iWidth, 0), size2), imageSource, DirectGdi::EGraphicsRotation90);
415 TESTNOERRORL(iGc->GetError());
416 iGc->DrawResource(TRect(pos+TPoint(0, size.iHeight), size2), imageSource, DirectGdi::EGraphicsRotation180);
417 TESTNOERRORL(iGc->GetError());
418 iGc->DrawResource(TRect(pos+size.AsPoint(), size2), imageSource, DirectGdi::EGraphicsRotation270);
419 TESTNOERRORL(iGc->GetError());
421 CleanupStack::PopAndDestroy(3, &image);
425 Override of base class virtual
426 @leave Gets system wide error code
427 @return - TVerdict code
429 TVerdict CTInterleaving::doTestStepPreambleL()
431 CTDirectGdiStepBase::doTestStepPreambleL();
432 return TestStepResult();
436 Override of base class pure virtual
437 Our implementation only gets called if the base class doTestStepPreambleL() did
438 not leave. That being the case, the current test result value will be EPass.
439 @leave Gets system wide error code
440 @return TVerdict code
442 TVerdict CTInterleaving::doTestStepL()
444 // Test for each target pixel format
445 for(TInt targetPixelFormatIndex = iTargetPixelFormatArray.Count() - 1; targetPixelFormatIndex >= 0 ; targetPixelFormatIndex--)
447 iTestParams.iTargetPixelFormat = iTargetPixelFormatArray[targetPixelFormatIndex];
449 SetTargetL(iTestParams.iTargetPixelFormat, EOneContextOneTarget, TSize(400, 400));
452 CloseTMSGraphicsStep();
453 return TestStepResult();
457 Override of base class virtual
458 @leave Gets system wide error code
459 @return - TVerdict code
461 TVerdict CTInterleaving::doTestStepPostambleL()
463 CTDirectGdiStepBase::doTestStepPostambleL();
464 return TestStepResult();
468 Override of base class pure virtual
469 Lists the tests to be run
471 void CTInterleaving::RunTestsL()
475 SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0001"));
478 SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0002"));
481 SetTestStepID(_L("GRAPHICS-DIRECTGDI-INTERLEAVING-0002"));