graphicsdeviceinterface/bitgdi/tbit/tbitblt.cpp
author Faisal Memon <faisal.memon@nokia.com>
Fri, 25 Jun 2010 17:49:58 +0100
branchEGL_MERGE
changeset 105 158b2308cc08
parent 0 5d03bc08d59c
permissions -rw-r--r--
Fix def files so that the implementation agnostic interface definition has no non-standards defined entry points, and change the eglrefimpl specific implementation to place its private entry points high up in the ordinal order space in the implementation region, not the standards based entrypoints region.

// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include <hal.h>
#include "tbitblt.h"

//_LIT(KBit16BitmapOnZ, "z:\\system\\data\\16bit.mbm");
_LIT(KBit32BitmapOnZ, "z:\\system\\data\\32bit_2.mbm");

/**
Create a new virtual bitmap device
*/
CVirtualBitmapDevice*  CVirtualBitmapDevice::NewL(TDisplayMode aDisplayMode, TSize aSize)
	{
	CVirtualBitmapDevice* self = new(ELeave) CVirtualBitmapDevice();
	CleanupStack::PushL(self);
	self->ConstructL(aDisplayMode, aSize);
	CleanupStack::Pop(self);
	return self;
	}

void CVirtualBitmapDevice::ConstructL(TDisplayMode aDisplayMode, TSize aSize)
	{	
	// Attempt to create a screen device
	CFbsScreenDevice* screenDevice = NULL;
	TRAPD(ret, screenDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
	if (ret != KErrNone)
		{
		// Screen device cannot be created so create a off screen bitmap device
		iBitmap = new(ELeave) CFbsBitmap;
		iBitmap->Create(aSize, aDisplayMode);
		iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
		iIsScreenDevice = EFalse;
		}
	else
		{
		screenDevice->SetAutoUpdate(EFalse);
		iBitmapDevice = screenDevice;
		iIsScreenDevice = ETrue;
		}
	}

CVirtualBitmapDevice::~CVirtualBitmapDevice()
	{
	delete iBitmapDevice;
	delete iBitmap;
	}

/**
Update implements the same method on CFbsScreenDevice to Update the screen. This only works on a screen device.
Off screen bitmaps do not have to be updated and no action will be taken in this case.
*/
void CVirtualBitmapDevice::Update()
	{
	if (iIsScreenDevice)
		{
		CFbsScreenDevice* screenDevice = static_cast<CFbsScreenDevice*>(iBitmapDevice);
		screenDevice->Update();
		}
	}

/**
Returns the actual bitmap device
*/
CBitmapDevice& CVirtualBitmapDevice::BitmapDevice()
	{
	return *iBitmapDevice;
	}

//  CTBitBlt Methods
CTBitBlt::CTBitBlt(CTestStep* aStep) :
	CTGraphicsBase(aStep)
	{
	}

CTBitBlt::~CTBitBlt()
	{
	delete iBitmap;
	}

void CTBitBlt::ConstructL()
	{
	INFO_PRINTF1(_L("Pre-test setup"));
	iBitmap=new(ELeave) CFbsBitmap;
	User::LeaveIfError(iBitmap->Load(KBit32BitmapOnZ,0,EFalse));  //EMbmTbmpTcolor
	}

void CTBitBlt::RunTestCaseL(TInt aCurTestCase)
	{
	((CTBitBltStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
	switch(aCurTestCase)
		{
	case 1:
		((CTBitBltStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0017"));
		TestBitBltPositionsL(EFalse);	// Uncompressed bitmaps
		TestBitBltPositionsL(ETrue);	// Compressed bitmaps
		break;
	case 2:
		((CTBitBltStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
		((CTBitBltStep*)iStep)->CloseTMSGraphicsStep();
		TestComplete();
		break;
		}
	((CTBitBltStep*)iStep)->RecordTestResultL();
	}

/**
Captures the screen data from aDevice and returns it as a TUint8 buffer in EColor256.

@param aDevice the bitmap device to capture
@param aScreenByteSize the size of the returned data
@return the screen data in EColor256
*/
TUint8* CTBitBlt::CaptureDeviceDataLC(CBitmapDevice& aDevice, TInt& aScreenByteSize)
	{
	TSize scrDevSize = aDevice.SizeInPixels();
	TDisplayMode displayMode = aDevice.DisplayMode();

	// Create memory to hold device data assuming EColor256
	aScreenByteSize = scrDevSize.iWidth * scrDevSize.iHeight;
	TUint8* screenData = new (ELeave) TUint8[aScreenByteSize];
	CleanupArrayDeletePushL(screenData);

	// Fill the blocks with some default value
	Mem::Fill(screenData, aScreenByteSize, 0xCA);

	// Get screen data and write the data to screenBmp.
	for(TInt y=0; y<scrDevSize.iHeight;y++)
   		{
		TPtr8 p(screenData + y * scrDevSize.iWidth, scrDevSize.iWidth, scrDevSize.iWidth);
		aDevice.GetScanLine(p, TPoint(0, y), scrDevSize.iWidth, EColor256); // Get Scanline and convert to EColor256 if not already in that display mode
   		}
   	return screenData;
	}

/**
Creates a bitmap image of what is meant to be displayed on the screen without using any bitblt methods.
This bitmap is compared with the one on screen and returns 0 if they match.

@param aDevice the screen device to capture
@param aGc graphics context for aDevice
@param aScreenSize the size of the display of aDevice
@param aBitmapSize the size of the bitmap
@param aScreenMode the screen mode to use
@param aOffset the offset of the bitmap from the top left corner of the display
@param aRect the clipping rectangle for the bitmap
@return if bitmap matches what is on the screen 0 is returned
*/
TInt CTBitBlt::CreateBitmapImageAndCompareL(CVirtualBitmapDevice& aDevice, CFbsBitGc& aGc, TSize aScreenSize, TSize aBitmapSize, TDisplayMode aScreenMode, TPoint aOffset, TRect& aRect)
	{
	// Create Bitmap
	CFbsBitmap* tBitmap = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(tBitmap);
	tBitmap->Create(aScreenSize, aScreenMode);

	// Create Bitmap Device
	CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL(tBitmap);
	CleanupStack::PushL(bmpDevice);

	// Create GC for bitmap device and draw a some graphics
	CFbsBitGc* bmpGc;
	User::LeaveIfError(bmpDevice->CreateContext(bmpGc));
	CleanupStack::PushL(bmpGc);
	bmpGc->Clear();
	bmpGc->SetClippingRect(TRect(aRect.iTl.iX+aOffset.iX, aRect.iTl.iY+aOffset.iY, aRect.iBr.iX+aOffset.iY, aRect.iBr.iY+aOffset.iY));
	for (TInt i = aBitmapSize.iWidth/2; i>0; --i)
		{
		bmpGc->SetPenColor(TRgb::Color256(i));
		bmpGc->DrawRect(TRect(i+aOffset.iX,i+aOffset.iY,aBitmapSize.iWidth - i + aOffset.iX, aBitmapSize.iHeight - i + aOffset.iY));
		}
	bmpGc->CancelClippingRect();

	// Now compare tBitmap with what is on the screen
	TInt allocatedSize;
	TUint8* screenData = CaptureDeviceDataLC(aDevice.BitmapDevice(), allocatedSize);
	TUint8* testData = CaptureDeviceDataLC(*bmpDevice, allocatedSize);
	TInt res = Mem::Compare(screenData, allocatedSize, testData, allocatedSize);
	// Display on screen
	aGc.Clear();
	aGc.BitBlt(TPoint(0,0), tBitmap, TRect(TPoint(0,0), aScreenSize));
	aDevice.Update();
	CleanupStack::PopAndDestroy(5, tBitmap);
	return res;
	}

/**
Bitblts a bitmap and compares it with how it should look

@param aDevice the screen device to capture
@param aGc graphics context for aDevice
@param aBitmap the bitmap to bitblt
@param aScreenMode the screen mode
@param aPointStart the top left point to start displaying the bitmap
@param aRect the clipping rectangle for the bitmap
*/
void CTBitBlt::SimpleBitBltAndTestL(CVirtualBitmapDevice& aDevice, CFbsBitGc& aGc, CFbsBitmap& aBitmap, TDisplayMode aScreenMode, TPoint aStartPoint, TRect& aRect)
	{
	aGc.Clear();
	aGc.BitBlt(aStartPoint, &aBitmap, aRect);
	aDevice.Update();
	TPoint offset(10,10);
	TInt res = CreateBitmapImageAndCompareL(aDevice, aGc, aDevice.BitmapDevice().SizeInPixels(), aBitmap.SizeInPixels(), aScreenMode, offset, aRect);
	TEST(res == 0);
	}

/**
	@SYMTestCaseID GRAPHICS-BITGDI-0017
 
	@SYMDEF DEF105390
   
	@SYMTestCaseDesc  Tests simple BitBlt using clipping rect is various places.
 
	@SYMTestPriority Low
  
	@SYMTestStatus Implemented
   
	@SYMTestActions Test the BitBlt function for positioning by blitting only some part of the image.
   
	@SYMTestExpectedResults Test should perform graphics operations succesfully.

 */

void CTBitBlt::TestBitBltPositionsL(TBool aDoCompressed)
	{
	if(aDoCompressed)
		{
		INFO_PRINTF1(_L("BitBlt Positions testing : Compressed Bitmaps"));
		}
	else
		{
		INFO_PRINTF1(_L("BitBlt Positions testing : Uncompressed Bitmaps"));
		}

	TDisplayMode dstDispMode[] = {EColor16M, EColor16MU, EColor256, EColor4K, EColor64K};	
	TDisplayMode dispMode[] = {EColor16MA, EColor16MAP, EColor16M, EColor16MU, EColor256, EColor4K, EColor64K, EGray256, EGray16, EGray4, EGray2, EColor16};	

	for(TInt dstDispModeIndex = 0; dstDispModeIndex < TInt(sizeof(dstDispMode)/sizeof(dstDispMode[0])); dstDispModeIndex++)
		{
		// Test for each display mode
		for(TInt dispModeIndex = 0; dispModeIndex < TInt(sizeof(dispMode)/sizeof(dispMode[0])); dispModeIndex++)
			{
			INFO_PRINTF3(_L("Display Mode Index = %d/%d"), dstDispModeIndex, dispModeIndex);
		
			// Setup screen device to 16MA
			TSize size = TSize(640,200);
			iVirtualBmpDevice = CVirtualBitmapDevice::NewL(dstDispMode[dstDispModeIndex], size);
			CBitmapDevice& screenDevice = iVirtualBmpDevice->BitmapDevice();		

			CFbsBitGc* gc=NULL;
			User::LeaveIfError(screenDevice.CreateContext((CGraphicsContext*&)gc));
			TEST(gc!=NULL);
			CleanupStack::PushL(gc);
			for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
				{
				gc->Reset();
				if (!gc->SetOrientation((CFbsBitGc::TGraphicsOrientation)orientation))
					continue;
				if (orientation&1 && dispMode[dispModeIndex]==EColor16M)
					{//zzz Skipping this case due to DEF120222 that causes the verification code to fail
					continue;
					}
				TSize screenSize = screenDevice.SizeInPixels();

				// Create Bitmap
				CFbsBitmap* bitmap32 = new(ELeave) CFbsBitmap;
				TEST(bitmap32!=NULL);
				CleanupStack::PushL(bitmap32);
				TSize bitmapSize = screenSize - TSize(20, 20); 	// Make bitmap smaller than screen by 20 pixels
				bitmap32->Create(bitmapSize, dispMode[dispModeIndex]);

				// Create Bitmap Device
				CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL(bitmap32);
				TEST(bmpDevice!=NULL);
				CleanupStack::PushL(bmpDevice);

				// Create GC for bitmap device and draw some graphics
				CFbsBitGc* bmpGc;
				User::LeaveIfError(bmpDevice->CreateContext(bmpGc));
				TEST(bmpGc!=NULL);
				CleanupStack::PushL(bmpGc);
				bmpGc->Clear();
				for (TInt i = bitmapSize.iWidth/2; i>0; --i)
					{
					bmpGc->SetPenColor(TRgb::Color256(i));	
					bmpGc->DrawRect(TRect(i,i,bitmapSize.iWidth - i, bitmapSize.iHeight - i));
					}

				if (aDoCompressed)
					{
					bitmap32->Compress();
					}

				gc->Clear();

				// Display whole bitmap with larger rect
				TPoint startPoint(10,10);
				TRect rect(0,0,bitmapSize.iWidth+50, bitmapSize.iHeight+50);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Display whole bitmap
				startPoint = TPoint(10,10);
				rect = TRect(0,0,bitmapSize.iWidth, bitmapSize.iHeight);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Display TL of bitmap
				startPoint = TPoint(10,10);
				rect = TRect(0,0,bitmapSize.iWidth/2, bitmapSize.iHeight/2);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Display TR of bitmap
				startPoint = TPoint(bitmapSize.iWidth/2+10, 10);
				rect = TRect(bitmapSize.iWidth/2,0,bitmapSize.iWidth,bitmapSize.iHeight/2);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Display BL of bitmap
				startPoint = TPoint(10, bitmapSize.iHeight/2+10);
				rect = TRect(0,bitmapSize.iHeight/2,bitmapSize.iWidth/2,bitmapSize.iHeight);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Display BR of bitmap
				startPoint = TPoint(bitmapSize.iWidth/2+10,bitmapSize.iHeight/2+10);
				rect = TRect(bitmapSize.iWidth/2,bitmapSize.iHeight/2,bitmapSize.iWidth,bitmapSize.iHeight);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				// Centre of bitmap
				startPoint = TPoint(bitmapSize.iWidth/4+10,bitmapSize.iHeight/4+10);
				rect = TRect(bitmapSize.iWidth/4,bitmapSize.iHeight/4,bitmapSize.iWidth/4+bitmapSize.iWidth/4,bitmapSize.iHeight/4+bitmapSize.iHeight/4);
				SimpleBitBltAndTestL(*iVirtualBmpDevice, *gc, *bitmap32, dispMode[dispModeIndex], startPoint, rect);

				CleanupStack::PopAndDestroy(3, bitmap32);
				}
			CleanupStack::PopAndDestroy(gc);
			delete iVirtualBmpDevice;
			iVirtualBmpDevice = NULL;
			}
		}
	}

//--------------
__CONSTRUCT_STEP__(BitBlt)

void CTBitBltStep::TestSetupL()
	{
	}

void CTBitBltStep::TestClose()
	{
	}