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