os/graphics/fbs/fontandbitmapserver/tfbs/tfbsbase.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
/**
sl@0
    17
 @file
sl@0
    18
 @test
sl@0
    19
 @internalComponent - Internal Symbian test code
sl@0
    20
*/
sl@0
    21
sl@0
    22
#include "tfbsbase.h"
sl@0
    23
#include "fbsmessage.h"
sl@0
    24
sl@0
    25
CTFbsBase::CTFbsBase(CTestStep* aStep, TBool aRunWithLowMemory):
sl@0
    26
	CTGraphicsBase(aStep), 
sl@0
    27
	iTestStep(*aStep), 
sl@0
    28
	iLastTestCase(EFalse),
sl@0
    29
	iRunWithLowMemory(aRunWithLowMemory)
sl@0
    30
	{
sl@0
    31
	}
sl@0
    32
sl@0
    33
CTFbsBase::~CTFbsBase()
sl@0
    34
	{
sl@0
    35
	}
sl@0
    36
sl@0
    37
/** Run the passed the test case. Classes that inherit from CTFbsBase should override this
sl@0
    38
and choose which test case to run depending on the passed test case number. Test cases are 
sl@0
    39
run once normally, 1..n times with out of memory (OOM) testing switched on for the FBServ 
sl@0
    40
heap and 1..n times with OOM testing switched on for the current heap.
sl@0
    41
  
sl@0
    42
@param aCurTestCase The number of the test case to run
sl@0
    43
 */
sl@0
    44
void CTFbsBase::RunTestCaseL(TInt aCurTestCase)
sl@0
    45
	{
sl@0
    46
	if(iLastTestCase)
sl@0
    47
		{
sl@0
    48
		TestComplete();
sl@0
    49
		return;
sl@0
    50
		}
sl@0
    51
		
sl@0
    52
	INFO_PRINTF2(_L("***** Starting test case %i *****"), aCurTestCase);
sl@0
    53
	
sl@0
    54
	// Run the test normally first
sl@0
    55
	iCurrentRunIsLowMemory = EFalse;
sl@0
    56
	TRAPD(err, RunFbsTestL(aCurTestCase));
sl@0
    57
	if(KErrNone != err)
sl@0
    58
		{
sl@0
    59
		iTestStep.SetTestStepResult(EFail);
sl@0
    60
		}
sl@0
    61
sl@0
    62
#ifndef _DEBUG
sl@0
    63
	if(iRunWithLowMemory)
sl@0
    64
		{
sl@0
    65
		iRunWithLowMemory = EFalse;
sl@0
    66
		INFO_PRINTF1(_L("WARNING: Can't run out of memory tests under a release build. OOM tests set to run in ini file so turning OOM tests off."));
sl@0
    67
		}
sl@0
    68
#endif
sl@0
    69
sl@0
    70
	// Run the test in out of memory conditions, checking both the FBServ heap and the
sl@0
    71
	// current thread's heap for memory leaks
sl@0
    72
	if(iRunWithLowMemory)
sl@0
    73
		{
sl@0
    74
		iCurrentRunIsLowMemory = ETrue;
sl@0
    75
		RFbsSession* fbsSession = RFbsSession::GetSession();
sl@0
    76
		ASSERT(fbsSession);
sl@0
    77
sl@0
    78
		INFO_PRINTF2(_L("***** Running Out Of Memory Tests on test case %i (FBSERV heap) *****"), aCurTestCase);
sl@0
    79
		
sl@0
    80
		// Save the current state of test step results
sl@0
    81
		TVerdict currentTestStepResult = iTestStep.TestStepResult();
sl@0
    82
		
sl@0
    83
		// Create 1000 pixel wide bitmap to prevent allocation of scanline buffer
sl@0
    84
		// during testings, to allow for memory leak testing
sl@0
    85
		const TSize KSizeInPixels 		= TSize(1000,1);
sl@0
    86
		const TDisplayMode KDisplayMode	= EColor64K;
sl@0
    87
		CFbsBitmap* bmp = new(ELeave) CFbsBitmap;
sl@0
    88
		CleanupStack::PushL(bmp);
sl@0
    89
		User::LeaveIfError(bmp->Create(KSizeInPixels, KDisplayMode));
sl@0
    90
		CleanupStack::PopAndDestroy(bmp);
sl@0
    91
sl@0
    92
		// Run the test with heap checking for the FbServ heap
sl@0
    93
		for(TInt failAfter=1; failAfter < 1000; ++failAfter)
sl@0
    94
			{
sl@0
    95
			INFO_PRINTF2(_L("***** Set fail after %i allocs (FBSERV heap) *****"), failAfter);
sl@0
    96
sl@0
    97
			// Count cells so we can know if any leaked
sl@0
    98
			TInt cellsStart = fbsSession->SendCommand(EFbsMessHeapCount, RFbsSession::EHeapFailTypeHeapMemory);
sl@0
    99
			fbsSession->SendCommand(EFbsMessSetHeapFail, RFbsSession::EHeapFailTypeHeapMemory, failAfter);
sl@0
   100
sl@0
   101
			// Run test case (implemented by sub class)
sl@0
   102
			TRAPD(err, RunFbsTestL(aCurTestCase));
sl@0
   103
sl@0
   104
			fbsSession->SendCommand(EFbsMessSetHeapReset, RFbsSession::EHeapFailTypeHeapMemory);
sl@0
   105
			TInt cellsEnd = fbsSession->SendCommand(EFbsMessHeapCount, RFbsSession::EHeapFailTypeHeapMemory);
sl@0
   106
			if(cellsStart < cellsEnd)
sl@0
   107
				{
sl@0
   108
				// leaked.
sl@0
   109
				TInt leakedCells = cellsEnd - cellsStart;
sl@0
   110
				ERR_PRINTF3(_L("***** On loop number %i we leaked %i cells (FBSERV heap) *****"), failAfter, leakedCells);
sl@0
   111
				currentTestStepResult = EFail;
sl@0
   112
				}
sl@0
   113
		
sl@0
   114
			// Check to see if any failures reported within test case run
sl@0
   115
			if(KErrNone == err)
sl@0
   116
				{
sl@0
   117
				INFO_PRINTF3(_L("***** Test case %i completed successfully after %d iterations (FBSERV heap) *****"), aCurTestCase, failAfter);
sl@0
   118
				break;
sl@0
   119
				}
sl@0
   120
			}
sl@0
   121
		
sl@0
   122
		// Run the test with heap checking for the current thread's heap
sl@0
   123
		TInt tryCount = 0;
sl@0
   124
		INFO_PRINTF2(_L("***** Running Out Of Memory Tests on test case %i, current thread's heap (current heap) *****"), aCurTestCase);
sl@0
   125
		
sl@0
   126
		FOREVER
sl@0
   127
			{					
sl@0
   128
			TInt err = KErrNone;
sl@0
   129
			
sl@0
   130
			// count cells so we can know how many we leaked
sl@0
   131
			TInt cellsStart = User::CountAllocCells();
sl@0
   132
			++tryCount;
sl@0
   133
			INFO_PRINTF2(_L("***** Set fail after %d allocs (current heap) *****"), tryCount);
sl@0
   134
			
sl@0
   135
			__UHEAP_FAILNEXT(tryCount);
sl@0
   136
			__UHEAP_MARK;											
sl@0
   137
			
sl@0
   138
			TRAP(err, RunFbsTestL(aCurTestCase));
sl@0
   139
	
sl@0
   140
			TBool finishedCorrectly = EFalse;
sl@0
   141
			if ((err == KErrNone))
sl@0
   142
				{
sl@0
   143
				// claims to have finished correctly, and we're not failing every alloc
sl@0
   144
				finishedCorrectly = iStep->CheckForHeapFailNext();
sl@0
   145
				}		
sl@0
   146
			__UHEAP_RESET;
sl@0
   147
			TInt cellsEnd = User::CountAllocCells();
sl@0
   148
			if (cellsStart < cellsEnd)
sl@0
   149
				{
sl@0
   150
				// leaked.
sl@0
   151
				TInt leakedCells = cellsEnd - cellsStart;
sl@0
   152
				ERR_PRINTF3(_L("***** On loop number %d we leaked %d cells (current heap). About to cause panic."),tryCount,leakedCells);				
sl@0
   153
				}
sl@0
   154
			__UHEAP_MARKEND;
sl@0
   155
			
sl@0
   156
			// check to see if we finished all OOM testing successfully
sl@0
   157
			if ((err == KErrNone) && finishedCorrectly)
sl@0
   158
				{				
sl@0
   159
				INFO_PRINTF3(_L("***** Test case %i completed successfully after %d iterations (current heap) *****"), aCurTestCase, tryCount);
sl@0
   160
				break;
sl@0
   161
				}
sl@0
   162
			
sl@0
   163
			if (tryCount == 999)
sl@0
   164
				{
sl@0
   165
				ERR_PRINTF1(_L("***** OOM testing stopped after 999 iterations (current heap)"));
sl@0
   166
				break;				
sl@0
   167
				}
sl@0
   168
			}
sl@0
   169
		
sl@0
   170
		// Restore test step result and ignore any test failures the out of memory tests produce
sl@0
   171
		iTestStep.SetTestStepResult(currentTestStepResult);
sl@0
   172
		}		
sl@0
   173
	}
sl@0
   174
sl@0
   175
/** Helper method for extracting a TRgb colour from the passed buffer given a pixel
sl@0
   176
offset in to the buffer and a display mode.
sl@0
   177
sl@0
   178
@param aBuffer A buffer to extract the colour from.
sl@0
   179
@param aPixelOffset A pixel offset to use in to the buffer.
sl@0
   180
@param aDispMode The display mode to use when converting the pixel colour to TRgb.
sl@0
   181
 */
sl@0
   182
TRgb CTFbsBase::ExtractRgb(TUint8* aBuffer, TInt aPixelOffset, TDisplayMode aDispMode)
sl@0
   183
	{
sl@0
   184
	switch (aDispMode)
sl@0
   185
		{
sl@0
   186
	case EGray2:
sl@0
   187
		{
sl@0
   188
		TUint8 byte = *(aBuffer + (aPixelOffset >> 3));
sl@0
   189
		if (byte & (1 << (aPixelOffset & 7)))
sl@0
   190
			return KRgbWhite;
sl@0
   191
		return KRgbBlack;
sl@0
   192
		}
sl@0
   193
	case EGray4:
sl@0
   194
		{
sl@0
   195
		TUint8 byte = *(aBuffer + (aPixelOffset >> 2));
sl@0
   196
		byte >>= ((aPixelOffset & 3) << 1);
sl@0
   197
		return TRgb::Gray4(byte & 3);
sl@0
   198
		}
sl@0
   199
	case EGray16:
sl@0
   200
		{
sl@0
   201
		TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
sl@0
   202
		if (aPixelOffset & 1)
sl@0
   203
			byte >>= 4;
sl@0
   204
		return TRgb::Gray16(byte & 0xf);
sl@0
   205
		}
sl@0
   206
	case EGray256:
sl@0
   207
		return TRgb::Gray256(*(aBuffer + aPixelOffset));
sl@0
   208
	case EColor16:
sl@0
   209
		{
sl@0
   210
		TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
sl@0
   211
		if (aPixelOffset & 1)
sl@0
   212
			byte >>= 4;
sl@0
   213
		return TRgb::Color16(byte & 0xf);
sl@0
   214
		}
sl@0
   215
	case EColor256:
sl@0
   216
		return TRgb::Color256(*(aBuffer + aPixelOffset));
sl@0
   217
	case EColor4K:
sl@0
   218
		{
sl@0
   219
		TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
sl@0
   220
		return TRgb::Color4K(doubleByte & 0xfff);
sl@0
   221
		}
sl@0
   222
	case EColor64K:
sl@0
   223
		{
sl@0
   224
		TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
sl@0
   225
		return TRgb::Color64K(doubleByte);
sl@0
   226
		}
sl@0
   227
	case EColor16M:
sl@0
   228
		{
sl@0
   229
		aBuffer += aPixelOffset * 3;
sl@0
   230
		TInt value = *aBuffer++;
sl@0
   231
		value |= *aBuffer++ << 8;
sl@0
   232
		value |= *aBuffer << 16;
sl@0
   233
		return TRgb::Color16M(value);
sl@0
   234
		}
sl@0
   235
	case ERgb:
sl@0
   236
		return *(((TRgb*)aBuffer) + aPixelOffset);
sl@0
   237
	case EColor16MU:
sl@0
   238
		{
sl@0
   239
		return TRgb::Color16MU(*(((TUint32*)aBuffer) + aPixelOffset));
sl@0
   240
		}
sl@0
   241
	case EColor16MA:
sl@0
   242
		{
sl@0
   243
		return TRgb::Color16MA(*(((TUint32*)aBuffer) + aPixelOffset));
sl@0
   244
		}	
sl@0
   245
	case EColor16MAP:
sl@0
   246
		{
sl@0
   247
		return TRgb::_Color16MAP(*(((TUint32*)aBuffer) + aPixelOffset));
sl@0
   248
		}	
sl@0
   249
	default:
sl@0
   250
		break;
sl@0
   251
		};
sl@0
   252
	return KRgbBlack;
sl@0
   253
	}
sl@0
   254
sl@0
   255
/** Function to be used by classes that inherit from CTFbsBase. SetLastTestCase()
sl@0
   256
should be called after the last test case for a class is called to signal that 
sl@0
   257
testing has finished for that class.
sl@0
   258
 */
sl@0
   259
void CTFbsBase::SetLastTestCase()
sl@0
   260
	{
sl@0
   261
	iLastTestCase = ETrue;
sl@0
   262
	}