First public contribution.
1 // Copyright (c) 2005-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.
19 @internalComponent - Internal Symbian test code
22 #include "te_graphicsperformanceSuiteStepBase.h"
23 #include "te_graphicsperformanceSuiteDefs.h"
26 #include <bitdrawinterfaceid.h>
27 #include <bmalphablend.h>
29 #include <graphics/gdi/gdiconsts.h>
30 #include <graphics/fbsdefs.h>
37 _LIT(KBitmapDrive, "c:");
39 _LIT(KBitmapDrive, "e:");
41 _LIT(KBitmapPath, "\\uibench_sanity\\%S.mbm");
44 Gets the size of the hardware display in pixels
45 @return TSize object containing the screen size
47 TSize GetDisplaySizeInPixels()
50 HAL::Get(HALData::EDisplayXPixels, x); // Get number x pixel of screen
52 HAL::Get(HALData::EDisplayYPixels, y); // Get number y pixel of screen
57 Returns the size of the target used for off-screen drawing
58 @return TSize object containing the pixmap size.
60 TSize GetPixmapSizeInPixels()
62 return TSize(1000, 1000);
66 Create a new virtual bitmap device
68 CVirtualBitmapDevice* CVirtualBitmapDevice::NewL(TDisplayMode aDisplayMode, TBool aForceOffscreen)
70 CVirtualBitmapDevice* self = new(ELeave) CVirtualBitmapDevice();
71 CleanupStack::PushL(self);
72 self->ConstructL(aDisplayMode, aForceOffscreen);
73 CleanupStack::Pop(self);
78 @param aDisplayMode The displaymode of the bitmap to create.
79 @param aForceOffscreen If ETrue, a bitmap device is created instead of a screen device, regardless
80 of whether the screen supports the display mode.
82 void CVirtualBitmapDevice::ConstructL(TDisplayMode aDisplayMode, TBool aForceOffscreen)
84 // Attempt to create a screen device if not asked to use offscreen bitmap.
85 CFbsScreenDevice* screenDevice = NULL;
90 TRAP(ret, screenDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
93 if (aForceOffscreen || ret != KErrNone)
95 // Screen device cannot be created, or we didn't want one, so create an off screen bitmap device
96 iBitmap = new(ELeave) CFbsBitmap;
97 TSize scsize= (aForceOffscreen) ? GetPixmapSizeInPixels() : GetDisplaySizeInPixels();
98 iBitmap->Create(scsize, aDisplayMode);
99 iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
100 iIsScreenDevice = EFalse;
104 screenDevice->SetAutoUpdate(ETrue);
105 iBitmapDevice = screenDevice;
106 iIsScreenDevice = ETrue;
110 int CVirtualBitmapDevice::CreateContext(CGraphicsContext *&aGc)
112 return iBitmapDevice->CreateContext(aGc);
115 TSize CVirtualBitmapDevice::SizeInPixels() const
117 return iBitmapDevice->SizeInPixels();
121 TInt CVirtualBitmapDevice::isScreenDevice()
123 return iIsScreenDevice;
126 CVirtualBitmapDevice::~CVirtualBitmapDevice()
128 delete iBitmapDevice;
134 Implements the same method on CFbsScreenDevice to Update the screen. This only works on a screen device.
135 Off screen bitmaps do not have to be updated and no action will be taken in this case.
137 void CVirtualBitmapDevice::Update()
141 CFbsScreenDevice* screenDevice = static_cast<CFbsScreenDevice*>(iBitmapDevice);
143 screenDevice->Update();
148 Returns the actual bitmap device
150 CBitmapDevice& CVirtualBitmapDevice::BitmapDevice()
152 return *iBitmapDevice;
156 Returns the actual bitmap
158 CFbsBitmap& CVirtualBitmapDevice::Bitmap()
164 Create a new virtual draw device
166 CVirtualDrawDevice* CVirtualDrawDevice::NewL(TDisplayMode aDisplayMode)
168 CVirtualDrawDevice* self = new(ELeave) CVirtualDrawDevice();
169 CleanupStack::PushL(self);
170 self->ConstructL(aDisplayMode);
171 CleanupStack::Pop(self);
175 void CVirtualDrawDevice::ConstructL(TDisplayMode aDisplayMode)
177 // Attempt to create a screen device
178 CFbsDrawDevice* drawDevice = NULL;
179 TRAPD(ret, drawDevice = CFbsDrawDevice::NewScreenDeviceL(KDefaultScreenNo, aDisplayMode));
182 // Screen device cannot be created so create an off screen bitmap draw device
183 iSize = GetDisplaySizeInPixels();
184 iDrawDevice = CFbsDrawDevice::NewBitmapDeviceL(iSize, aDisplayMode, ByteSize(iSize, aDisplayMode) / iSize.iHeight);
185 iDeviceMemory = new (ELeave) TUint8[ByteSize(iSize, aDisplayMode)];
186 iDrawDevice->SetBits(iDeviceMemory);
187 iIsDrawDevice = EFalse;
191 iDrawDevice = drawDevice;
192 iSize = iDrawDevice->SizeInPixels();
193 iDrawDevice->SetAutoUpdate(ETrue);
194 iIsDrawDevice = ETrue;
198 TInt CVirtualDrawDevice::ByteSize(const TSize& aSize, TDisplayMode aDisplayMode)
200 TInt wordSize = aSize.iWidth;
204 wordSize = (wordSize + 31) / 32;
207 wordSize = (wordSize + 15) / 16;
211 wordSize = (wordSize + 7) / 8;
215 wordSize = (wordSize + 3) / 4;
219 wordSize = (wordSize + 1) / 2;
222 wordSize = (((wordSize * 3) + 11) / 12) * 3;
226 //Should not be changed!
231 return wordSize * aSize.iHeight * 4;
234 CFbsDrawDevice& CVirtualDrawDevice::DrawDevice()
239 CVirtualDrawDevice::~CVirtualDrawDevice()
242 delete[] iDeviceMemory;
245 TBool CVirtualDrawDevice::IsDrawDevice()
247 return iIsDrawDevice;
250 const TDesC& CTe_graphicsperformanceSuiteStepBase::ColorModeName(TDisplayMode aMode)
252 _LIT(KColor4K,"Color4K");
253 _LIT(KColor64K,"Color64K");
254 _LIT(KColor16M,"Color16M");
255 _LIT(KColor16MU,"Color16MU");
256 _LIT(KColor16MA,"Color16MA");
257 _LIT(KColor16MAP,"Color16MAP");
258 _LIT(KUnknown,"Unknown");
279 Implementation of CTestStep base class virtual
280 It is used for doing all initialisation common to derived classes in here.
281 Make it being able to leave if there are any errors here as there's no point in
282 trying to run a test step if anything fails.
283 The leave will be picked up by the framework.
287 TVerdict CTe_graphicsperformanceSuiteStepBase::doTestStepPreambleL()
289 SetTestStepResult(EPass);
291 // Create and install Active Scheduler in case tests require active objects
292 iScheduler = new(ELeave) CActiveScheduler;
293 CActiveScheduler::Install(iScheduler);
296 TESTNOERRORL(RFbsSession::Connect());
297 HAL::Get(HALData::ECPUSpeed,iCPUSpeed);
298 INFO_PRINTF2(_L("CPUSpeed: %i kHz"),iCPUSpeed);
300 // get input for tests from .ini file
301 TEST(GetIntFromConfig(_L("Profiling"), _L("DoProfiling"), iDoProfiling));
302 TEST(GetBoolFromConfig(_L("SanityCheck"), _L("Bitmaps"), iShowBitmaps));
309 iProfiler = CTProfiler::NewL(*this);
311 return TestStepResult();
315 Implementation of CTestStep base class virtual
316 It is used for doing all after test treatment common to derived classes in here.
317 Make it being able to leave
318 The leave will be picked up by the framework.
322 TVerdict CTe_graphicsperformanceSuiteStepBase::doTestStepPostambleL()
328 return TestStepResult();
331 CTe_graphicsperformanceSuiteStepBase::~CTe_graphicsperformanceSuiteStepBase()
337 delete iScreenDevice;
340 RFbsSession::Disconnect();
344 CTe_graphicsperformanceSuiteStepBase::CTe_graphicsperformanceSuiteStepBase()
348 CVirtualBitmapDevice* CTe_graphicsperformanceSuiteStepBase::ScreenDevice()
350 TEST(iScreenDevice!=NULL); // Ensure it is valid
351 return iScreenDevice;
355 Destroys and recreates the current target device.
357 @param aScreenMode The display mode of the target being created
358 @param aForceOffscreen If ETrue, an offscreen buffer is used as the target instead of the screen. The
359 dimensions of the buffer are retrieved from GetPixmapSizeInPixels.
361 void CTe_graphicsperformanceSuiteStepBase::SetScreenModeL(TDisplayMode aScreenMode, TBool aForceOffscreen)
363 delete iScreenDevice;
364 iScreenDevice = NULL;
366 iScreenDevice = CVirtualBitmapDevice::NewL(aScreenMode, aForceOffscreen);
367 if (iScreenDevice->isScreenDevice())
369 INFO_PRINTF2(_L("SetScreenMode - supported: %S"),&ColorModeName(aScreenMode));
373 if (!aForceOffscreen)
375 INFO_PRINTF2(_L("SetScreenMode - not supported(using off screen bitmap instead): %S"),&ColorModeName(aScreenMode));
379 INFO_PRINTF2(_L("SetScreenMode - using off screen bitmap as requested: %S"),&ColorModeName(aScreenMode));
384 User::LeaveIfError(iScreenDevice->CreateContext((CGraphicsContext*&)iGc));
385 iScreenSize = iScreenDevice->SizeInPixels();
388 void CTe_graphicsperformanceSuiteStepBase::SetDrawDeviceModeL(TDisplayMode aScreenMode)
393 iDrawDevice = CVirtualDrawDevice::NewL(aScreenMode);
394 if (iDrawDevice->IsDrawDevice())
396 INFO_PRINTF2(_L("SetDrawDeviceMode - supported: %S"),&ColorModeName(aScreenMode));
400 INFO_PRINTF2(_L("SetDrawDeviceMode - not supported(using off screen bitmap instead): %S"),&ColorModeName(aScreenMode));
404 TInt CTe_graphicsperformanceSuiteStepBase::GetDrawDeviceInterfaceL(TInt aInterfaceId, TAny*& aInterface)
406 User::LeaveIfNull(iDrawDevice);
407 return iDrawDevice->DrawDevice().GetInterface(aInterfaceId, aInterface);
410 void CTe_graphicsperformanceSuiteStepBase::ClearDrawDeviceL(TRgb aColor)
412 User::LeaveIfNull(iDrawDevice);
413 CFbsDrawDevice& drawDevice = iDrawDevice->DrawDevice();
414 TSize size = drawDevice.SizeInPixels();
415 drawDevice.SetShadowMode(CFbsDrawDevice::ENoShadow);
416 drawDevice.WriteRgbMulti(0,0,size.iWidth,size.iHeight,aColor,CGraphicsContext::EDrawModePEN);
420 Creates a bitmap for given size and display mode and leaves it on the cleanup stack
422 @return pointer to a created CFbsBitmap
424 CFbsBitmap* CTe_graphicsperformanceSuiteStepBase::CreateSoftwareBitmapLC(const TSize& aSize, TDisplayMode aMode)
426 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
427 CleanupStack::PushL(bitmap);
428 User::LeaveIfError(bitmap->Create(aSize, aMode));
433 Copy a bitmap into another bitmap (generally in a different displaymode)
434 tiles destination bitmap with source
436 void CTe_graphicsperformanceSuiteStepBase::CopyBitmapL(CFbsBitmap* aDst, CFbsBitmap* aSrc)
438 TSize srcSize = aSrc->SizeInPixels();
439 TSize dstSize = aDst->SizeInPixels();
440 CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(aDst);
441 CleanupStack::PushL(dev);
442 CFbsBitGc* gc = NULL;
443 if ( 0 == dev->CreateContext(gc) )
445 CleanupStack::PushL(gc);
447 gc->SetBrushColor(TRANSPARENT_BLACK);
448 gc->SetBrushStyle(CGraphicsContext::ENullBrush);
449 gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
451 gc->SetDrawMode(CGraphicsContext::EDrawModePEN);
452 for(point.iY=0; point.iY<dstSize.iHeight; point.iY+=srcSize.iHeight)
454 for(point.iX=0; point.iX<dstSize.iWidth; point.iX+=srcSize.iWidth)
456 gc->BitBlt(point, aSrc);
459 CleanupStack::PopAndDestroy(gc);
461 CleanupStack::PopAndDestroy(dev);
465 Copy a source bitmap into a new bitmap with the specified display mode
467 CFbsBitmap* CTe_graphicsperformanceSuiteStepBase::CopyIntoNewBitmapL(CFbsBitmap* aSrc, TDisplayMode aDisplayMode)
469 CFbsBitmap* dstBmp = new(ELeave) CFbsBitmap;
470 CleanupStack::PushL(dstBmp);
471 TInt ret=dstBmp->Create(aSrc->SizeInPixels(), aDisplayMode);
472 User::LeaveIfError(ret);
473 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(dstBmp);
474 CleanupStack::PushL(bitmapDevice);
476 ret = bitmapDevice->CreateContext(gc);
477 User::LeaveIfError(ret);
478 CleanupStack::PushL(gc);
479 gc->BitBlt(TPoint(0,0), aSrc);
480 CleanupStack::PopAndDestroy(2, bitmapDevice); // gc, bitmapDevice
481 CleanupStack::Pop(dstBmp);
486 Loads a bitmap from a file
488 @param aName the filename of the bitmap to load
489 @param aIndex the index of the bitmap to load in the file
491 CFbsBitmap* CTe_graphicsperformanceSuiteStepBase::LoadBitmapL(const TDesC& aName, TInt aIndex)
493 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
494 CleanupStack::PushL(bitmap);
495 User::LeaveIfError(bitmap->Load(aName, aIndex));
496 CleanupStack::Pop(bitmap);
501 Interpolates between the two TRgb values aHi and aLo including alpha channel, with the value aX and the denoinator aN
503 TRgb CTe_graphicsperformanceSuiteStepBase::InterpolateColour(TRgb aLo, TRgb aHi, TInt aX, TInt aN)
507 TUint8 a = (TUint8)( (aHi.Alpha()*aX + aLo.Alpha()*y)/aN );
508 TUint8 r = (TUint8)( (aHi.Red()*aX + aLo.Red()*y)/aN );
509 TUint8 g = (TUint8)( (aHi.Green()*aX + aLo.Green()*y)/aN );
510 TUint8 b = (TUint8)( (aHi.Blue()*aX + aLo.Blue()*y)/aN );
512 return TRgb(r, g, b, a);
516 Draws a VerticalGradient onto a CFbsBitmap from top/color aLo to bottom/aHi
518 void CTe_graphicsperformanceSuiteStepBase::VerticalGradientAlphaL(CFbsBitmap* aBitmap, TRgb aLo, TRgb aHi)
520 const TSize size = aBitmap->SizeInPixels();
521 const TDisplayMode mode = aBitmap->DisplayMode();
522 const TInt scanLineLength = CFbsBitmap::ScanLineLength(size.iWidth, mode);
523 HBufC8* buffer = HBufC8::NewL(scanLineLength);
524 CleanupStack::PushL(buffer);
525 TPtr8 des = buffer->Des();
526 des.SetLength(scanLineLength);
527 for(TInt i=0; i<size.iHeight; i++)
529 TRgb color = InterpolateColour(aLo, aHi, i, size.iHeight);
534 TUint8 g = color.Gray256();
535 TUint8* p = (TUint8*)des.Ptr();
536 for(TInt j=0; j<size.iWidth; j++)
544 TUint16 g = color._Color64K();
545 TUint16* p = (TUint16*)des.Ptr();
546 for(TInt j=0; j<size.iWidth/2; j++)
554 TUint32 rgba = color._Color16MU();
555 TUint32* p = (TUint32*)des.Ptr();
556 for(TInt j=0; j<(size.iWidth/4); j++)
564 TUint32 rgba = color._Color16MA();
565 TUint32* p = (TUint32*)des.Ptr();
566 for(TInt j=0; j<(size.iWidth/4); j++)
574 TUint32 rgba = color._Color16MAP();
575 TUint32* p = (TUint32*)des.Ptr();
576 for(TInt j=0; j<(size.iWidth/4); j++)
586 aBitmap->SetScanLine(des, i);
588 CleanupStack::PopAndDestroy(buffer);
592 Create a checked board
593 @param aPixelFormat The pixel format for create the target bitmap
594 @param aSize The size of the bitmap
595 @param aChecksPerAxis Number of checks on X and Y.
597 CFbsBitmap* CTe_graphicsperformanceSuiteStepBase::CreateCheckedBoardL(TDisplayMode aDisplayMode, TSize aSize, TSize aChecksPerAxis) const
600 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
601 CleanupStack::PushL(bitmap);
602 bitmap->Create(aSize, aDisplayMode);
604 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
605 CleanupStack::PushL(bitmapDevice);
607 CFbsBitGc* bitGc = NULL;
608 User::LeaveIfError(bitmapDevice->CreateContext(bitGc));
609 CleanupStack::PushL(bitGc);
612 bitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
613 bitGc->SetPenStyle(CGraphicsContext::ENullPen);
615 const TSize checkerSize((TReal)aSize.iWidth/aChecksPerAxis.iWidth,(TReal)aSize.iHeight/aChecksPerAxis.iHeight);
616 TInt brushColour = 0;
617 for(point.iY = 0; point.iY < aSize.iHeight; point.iY += checkerSize.iHeight)
619 for(point.iX = 0; point.iX < aSize.iWidth; point.iX += checkerSize.iWidth)
621 bitGc->SetBrushColor(KColor16Table[brushColour++ & 0x0F]);
622 TRect rect(point, checkerSize);
623 bitGc->DrawRect(rect);
627 CleanupStack::PopAndDestroy(2, bitmapDevice);
628 CleanupStack::Pop(bitmap);
634 Creates a new CFbsBitmap representing the screen/off-screen bitmap. It is the client's
635 responsibility to delete it.
637 @see CTDirectGdiTestBase::GetTargetAsBitmapL.
638 @return A pointer to the newly created bitmap.
639 @leave If there was a problem copying from the source to the target.
641 CFbsBitmap* CTe_graphicsperformanceSuiteStepBase::GetTargetAsBitmapL()
643 iScreenDevice->Update();
644 CFbsBitmap* bitmapCopy = CopyIntoNewBitmapL(&(iScreenDevice->Bitmap()), iScreenDevice->BitmapDevice().DisplayMode());
649 Creates an mbm file showing the state of the target.
651 @param aName The name of the mbm file to produce. Any spaces are replaced by underscores
653 @return KErrNone if bitmap output has been turned off in the config file, or if it was successful.
654 KErrNoMemory if there is not enough memory to create the bitmap.
656 TInt CTe_graphicsperformanceSuiteStepBase::WriteTargetOutput(TPtrC aName)
663 CFbsBitmap* target = NULL;
664 TRAPD(err, target = GetTargetAsBitmapL();)
671 TBuf<KMaxFileName> fileName;
672 fileName.Append(aName);
674 // replace spaces with underscores.
675 TInt pos = fileName.Locate(TChar(' '));
676 while(pos != KErrNotFound)
678 fileName[pos] = TChar('_');
679 pos = fileName.Locate(TChar(' '));
683 mbmFile.Append(KBitmapDrive);
684 mbmFile.AppendFormat(KBitmapPath, &fileName);
686 err = target->Save(mbmFile);
693 void CTe_graphicsperformanceSuiteStepBase::ExtractListL(TPtrC aList, RArray<TPtrC>& aListItems)
695 TPtrC tempBuf = aList;
696 TInt position = tempBuf.Find(_L(","));
698 while(position != KErrNotFound)
700 aListItems.AppendL(tempBuf.Left(position));
701 tempBuf.Set(tempBuf.Mid(position + 2));
702 position = tempBuf.Find(_L(","));
705 if (position == KErrNotFound)
707 aListItems.AppendL(tempBuf);