textrendering/textformatting/test/src/TFormBenchmark.cpp
changeset 0 1fb32624e06b
child 16 748ec5531811
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "TCustomWrap.h"
       
    20 #include "TGraphicsContext.h"
       
    21 #include <e32std.h>
       
    22 #include <e32test.h>
       
    23 #include <frmtlay.h>
       
    24 #include <frmtview.h>
       
    25 #include <txtlaydc.h>
       
    26 #include <fbs.h>
       
    27 #include <w32std.h>
       
    28 #include <txtrich.h>
       
    29 #include <e32math.h>
       
    30 #include <f32file.h>
       
    31 #include <flogger.h>
       
    32 
       
    33 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    34 #include "TAGMA_INTERNAL.H"
       
    35 #endif
       
    36 
       
    37 RFs fs;
       
    38 RFile fileTimeStamps;
       
    39 
       
    40 #if ((defined (__WINS__)) || (defined (__X86GCC__)))
       
    41 	_LIT(KLogTimeStampsName, "c:\\formtimestamps.csv");
       
    42 #else
       
    43 	_LIT(KLogTimeStampsName, "e:\\formtimestamps.csv");
       
    44 #endif
       
    45 
       
    46 _LIT(KEnglish, "Whereas recognition of the inherent dignity and of the equal \
       
    47 and inalienable rights of all members of the human family is the foundation \
       
    48 of freedom, justice and peace in the world, ");
       
    49 const TInt KEnglishRepeats = 119;
       
    50 _LIT(KArabic, "\x644\x645\x651\x627 \x643\x627\x646 \x627\x644\x627\x639\x62A\
       
    51 \x631\x627\x641 \x628\x627\x644\x643\x631\x627\x645\x629 \x627\x644\x645\x62A\
       
    52 \x623\x635\x644\x629 \x641\x64A \x62C\x645\x64A\x639 \x623\x639\x636\x627\
       
    53 \x621 \x627\x644\x623\x633\x631\x629 \x627\x644\x628\x634\x631\x64A\x629\
       
    54  \x648\x628\x62D\x642\x648\x642\x647\x645 \x627\x644\x645\x62A\x633\x627\
       
    55 \x648\x64A\x629 \x627\x644\x62B\x627\x628\x62A\x629 \x647\x648 \x623\x633\
       
    56 \x627\x633 \x627\x644\x62D\x631\x64A\x629 \x648\x627\x644\x639\x62F\x644\
       
    57  \x648\x627\x644\x633\x644\x627\x645 \x641\x64A \x627\x644\x639\x627\x644\
       
    58 \x645. ");
       
    59 const TInt KArabicRepeats = 156;
       
    60 _LIT(KJapanese, "\x4EBA\x985E\x793E\x4F1A\x306E\x3059\x3079\x3066\x306E\x69CB\
       
    61 \x6210\x54E1\x306E\x56FA\x6709\x306E\x5C0A\x53B3\x3068\x5E73\x7B49\x3067\x8B72\
       
    62 \x308B\x3053\x3068\x306E\x3067\x304D\x306A\x3044\x6A29\x5229\x3068\x3092\
       
    63 \x627F\x8A8D\x3059\x308B\x3053\x3068\x306F\x3001\x4E16\x754C\x306B\x304A\
       
    64 \x3051\x308B\x81EA\x7531\x3001\x6B63\x7FA9\x53CA\x3073\x5E73\x548C\x306E\
       
    65 \x57FA\x790E\x3067\x3042\x308B\x306E\x3067\x3001 ");
       
    66 const TInt KJapaneseRepeats = 357;
       
    67 const TInt KDisplayWidth = 100;
       
    68 const TInt KDisplayHeight = 120;
       
    69 
       
    70 
       
    71 _LIT(KFormBenchmark, "TFormBenchmark");
       
    72 RTest test(KFormBenchmark);
       
    73 
       
    74 const TInt KInsertDisplayWidth = 200;
       
    75 const TInt KChangedDisplayWidth = 150;
       
    76 
       
    77 _LIT(KEnglishToInsert1, "Whereas recognition of the inherent dignity");
       
    78 _LIT(KEnglishToInsert2, " and of the equal and inalienable rights of all... and so on");
       
    79 
       
    80 const TInt KEnglishInsertRepeats = 400;
       
    81 const TInt KEnglishScrollRepeats = 100;
       
    82 
       
    83 const TInt KDeleteTextInterval = 10;//we measure delete text once for each 10 deletes, to make the output smaller
       
    84 
       
    85 _LIT8(KDeleteTextFromStart, "Delete text from start\r\n");
       
    86 _LIT8(KInsertTextAtStart, "Insert text at start\r\n");
       
    87 _LIT8(KScrollingUp, "Scrolling up\r\n");
       
    88 _LIT8(KScrollingDown, "Scrolling down\r\n");
       
    89 
       
    90 struct TDocInfo
       
    91 	{
       
    92 	TDocInfo():iDocLength(0), iDocParaCount(0), iLineCount(0){}
       
    93 	TInt iDocLength;
       
    94 	TInt iDocParaCount;
       
    95 	TInt iLineCount;
       
    96 	};
       
    97 
       
    98 struct TTFTimeStamp
       
    99 	{
       
   100 	TInt64 iTime;
       
   101 	TInt iIteration;
       
   102 	};
       
   103 
       
   104 struct TFormattingObjects
       
   105 	{
       
   106 	TRect* iDisplayRect;
       
   107 	CParaFormatLayer* iParFormat;
       
   108 	CCharFormatLayer* iCharFormat;
       
   109 	CRichText* iRichText;
       
   110 	CTextLayout* iLayout;
       
   111 	CTestGraphicsDevice* iDevice;
       
   112 	CTextView* iView;
       
   113 	};
       
   114 
       
   115 /*
       
   116 Functions for writing benchmarking data to the CSV
       
   117 */
       
   118 void WriteSampleDocInfo(TDocInfo aDocInfo, RFile aDest)
       
   119 	{
       
   120 	TBuf8<128> buf;
       
   121 	buf.Format(_L8("Sample text: %d characters: %d paras: %d lines\r\n"), aDocInfo.iDocLength, aDocInfo.iDocParaCount, aDocInfo.iLineCount);
       
   122 	aDest.Write(buf);
       
   123 	}
       
   124 
       
   125 void WriteTimeStampsL(const TDesC8& aTitle, RArray<TTFTimeStamp>& aTimeStamps)
       
   126 	{
       
   127 	fileTimeStamps.Write(aTitle);
       
   128 	for (TInt i = 0; i < aTimeStamps.Count(); i++)
       
   129 		{
       
   130 		TTFTimeStamp timestamp = aTimeStamps[i];
       
   131 		TBuf8<128> buf;
       
   132 		buf.Format(_L8("%d, %Ld\r\n"), timestamp.iIteration, timestamp.iTime/1000);
       
   133 		fileTimeStamps.Write(buf);
       
   134 		}
       
   135 	}
       
   136 
       
   137 TDocInfo GetSampleDocInfoL(TFormattingObjects& aFormattingObjects)
       
   138 	{
       
   139 	TDocInfo docInfo;
       
   140 	const CTmTextLayout& layout = aFormattingObjects.iView->Layout()->TagmaTextLayout();
       
   141 	docInfo.iDocLength = layout.Source()->DocumentLength();
       
   142 	docInfo.iDocParaCount = aFormattingObjects.iRichText->ParagraphCount();
       
   143 //very peculiar way to count the lines...
       
   144 	TCursorPosition::TMovementType move = TCursorPosition::EFLineDown;
       
   145 	while (move == TCursorPosition::EFLineDown)
       
   146 		{
       
   147 		aFormattingObjects.iView->MoveCursorL(move, EFalse);
       
   148 		}
       
   149 	move = TCursorPosition::EFLineUp;
       
   150 	while (move == TCursorPosition::EFLineUp)
       
   151 		{
       
   152 		docInfo.iLineCount++;
       
   153 		aFormattingObjects.iView->MoveCursorL(move, EFalse);
       
   154 		}
       
   155 	return docInfo;
       
   156 	}
       
   157 
       
   158 /*
       
   159 Set up the test document
       
   160 */
       
   161 void SetTextL(CRichText& aText, const TDesC& aSample, TInt aRepeats, TInt aRepeatsPerPara)
       
   162 	{
       
   163 	TInt repeatsInThisPar = 0;
       
   164 	aText.Reset();
       
   165 	for (; aRepeats != 0; --aRepeats)
       
   166 		{
       
   167 		aText.InsertL(0, aSample);
       
   168 		repeatsInThisPar ++;
       
   169 		if (repeatsInThisPar > aRepeatsPerPara)
       
   170 			{
       
   171 			TChar paragraphDelimiter(0x2029);
       
   172 			aText.InsertL(0, paragraphDelimiter);
       
   173 			repeatsInThisPar = 0;
       
   174 			}
       
   175 		}
       
   176 	}
       
   177 
       
   178 _LIT(KOneWord, "blahblahblahblahblahblahblahblah");
       
   179 
       
   180 void BigBufLC(RBuf& aBigBuf)
       
   181 	{
       
   182 	aBigBuf.CreateL(16384);
       
   183 	aBigBuf.CleanupClosePushL();
       
   184 	while(aBigBuf.Length()+KOneWord().Length() < aBigBuf.MaxLength())
       
   185 		{
       
   186 		aBigBuf.Append(KOneWord);
       
   187 		}
       
   188 	}
       
   189 
       
   190 TTimeIntervalMicroSeconds MeasureOpeningL(CTextView& aView)
       
   191 	{
       
   192 	TCursorSelection zero(0, 0);
       
   193 	aView.SetPendingSelection(zero);
       
   194 	TTime start;
       
   195 	TTime end;
       
   196 	start.UniversalTime();
       
   197 	aView.HandleGlobalChangeL();
       
   198 	end.UniversalTime();
       
   199 	return end.MicroSecondsFrom(start);
       
   200 	}
       
   201 
       
   202 TTimeIntervalMicroSeconds MeasureRmsCursorDownL(CTextView& aView)
       
   203 	{
       
   204 	TInt mem;
       
   205 	TInt cells = User::AllocSize(mem);
       
   206 	TReal totalOfSquares = 0;
       
   207 	TTime start;
       
   208 	TTime end;
       
   209 	TCursorPosition::TMovementType move = TCursorPosition::EFLineDown;
       
   210 	while (move == TCursorPosition::EFLineDown)
       
   211 		{
       
   212 		start.UniversalTime();
       
   213 		aView.MoveCursorL(move, EFalse);
       
   214 		end.UniversalTime();
       
   215 		TReal us = end.MicroSecondsFrom(start).Int64();
       
   216 		totalOfSquares += us*us;
       
   217 		}
       
   218 	TReal rms;
       
   219 	Math::Sqrt(rms, totalOfSquares);
       
   220 	cells = User::AllocSize(mem);
       
   221 	return TTimeIntervalMicroSeconds(static_cast<TInt64>(rms));
       
   222 	}
       
   223 
       
   224 TInt NumberOfLines(CTextLayout& aLayout)
       
   225 	{
       
   226 	TTmDocPosSpec dp(aLayout.DocumentLength(), TTmDocPosSpec::ETrailing);
       
   227 	TTmPosInfo2 posInfo;
       
   228 	TTmLineInfo lineInfo;
       
   229 	aLayout.FindDocPos(dp, posInfo, &lineInfo);
       
   230 	return lineInfo.iLineNumber;
       
   231 	}
       
   232 
       
   233 TTimeIntervalMicroSeconds MeasureFormattingL(CTextView& aView)
       
   234 	{
       
   235 	// This looks to me like a defect.
       
   236 	// We have to set the actual doc pos to prevent a crash, even
       
   237 	// though we are setting a pending selection.
       
   238 	// Probably not too serious, though.
       
   239 	aView.SetDocPosL(0, ETrue);
       
   240 	TCursorSelection zero(0, 0);
       
   241 	aView.SetPendingSelection(zero);
       
   242 	TTime start;
       
   243 	TTime end;
       
   244 	start.UniversalTime();
       
   245 	aView.HandleGlobalChangeL();
       
   246 	aView.FinishBackgroundFormattingL();
       
   247 	end.UniversalTime();
       
   248 	end.UniversalTime();
       
   249 	return end.MicroSecondsFrom(start);
       
   250 	}
       
   251 
       
   252 void MeasureDeleteTextFromStartL(RArray<TTFTimeStamp>& aTimeStamps,
       
   253 	TFormattingObjects& aFormattingObjects, TInt64& aSlowest)
       
   254 	{
       
   255 	const CTmTextLayout& tmLayout = aFormattingObjects.iLayout->TagmaTextLayout();
       
   256 	aTimeStamps.Close();
       
   257 	TTime start;
       
   258 	TTime end;
       
   259 	TInt iteration = 0;
       
   260 	TInt64 total = 0;
       
   261 
       
   262 	TInt step = 0;
       
   263 	while(aFormattingObjects.iRichText->DocumentLength() > 0)
       
   264 		{
       
   265 		aFormattingObjects.iRichText->DeleteL(0, 1);
       
   266 		TCursorSelection cursor(0,0);
       
   267 		start.UniversalTime();
       
   268 		aFormattingObjects.iView->HandleInsertDeleteL(cursor, 1, EFalse);
       
   269 		end.UniversalTime();
       
   270 
       
   271 		TInt64 us = end.MicroSecondsFrom(start).Int64();
       
   272 
       
   273 		if(us > aSlowest)
       
   274 			{
       
   275 			aSlowest = us;
       
   276 			}
       
   277 
       
   278 		total += us;
       
   279 		step++;
       
   280 		if(step == KDeleteTextInterval)
       
   281 			{
       
   282 			TInt64 average = total/KDeleteTextInterval;
       
   283 			TTFTimeStamp timestamp;
       
   284 			timestamp.iTime = average;
       
   285 			timestamp.iIteration = iteration;
       
   286 			User::LeaveIfError(aTimeStamps.Append(timestamp));
       
   287 			iteration++;
       
   288 			step = 0;
       
   289 			total = 0;
       
   290 			}
       
   291 		}
       
   292 	}
       
   293 
       
   294 void MeasureInsertTextAtStartL(TInt aRepeats, TInt aRepeatsPerPara, RArray<TTFTimeStamp>& aTimeStamps,
       
   295 	TFormattingObjects& aFormattingObjects, TInt64& aSlowest)
       
   296 	{
       
   297 	aTimeStamps.Close();
       
   298 	TTime start;
       
   299 	TTime end;
       
   300 	TInt repeatsInThisPar = 0;
       
   301 	TViewRectChanges changes;
       
   302 	aFormattingObjects.iRichText->Reset();
       
   303 	for (TInt i = 0; i < aRepeats; i++)
       
   304 		{
       
   305 		TBuf<128> sample;
       
   306 		if ((i%2)==0)
       
   307 			{
       
   308 			sample = KEnglishToInsert1;
       
   309 			}
       
   310 		else
       
   311 			{
       
   312 			sample = KEnglishToInsert2;
       
   313 			}
       
   314 		aFormattingObjects.iRichText->InsertL(0, sample);
       
   315 		TCursorSelection cursor(0, sample.Length());
       
   316 
       
   317 		start.UniversalTime();
       
   318 		aFormattingObjects.iLayout->HandleBlockChangeL(cursor, 0, changes, 0);
       
   319 		end.UniversalTime();
       
   320 
       
   321 		TInt64 us = end.MicroSecondsFrom(start).Int64();
       
   322 		repeatsInThisPar ++;
       
   323 		TTFTimeStamp timestamp;
       
   324 		timestamp.iTime = us;
       
   325 		timestamp.iIteration = i;
       
   326 		User::LeaveIfError(aTimeStamps.Append(timestamp));
       
   327 		if(us > aSlowest)
       
   328 			{
       
   329 			aSlowest = us;
       
   330 			}
       
   331 		if (repeatsInThisPar > aRepeatsPerPara)
       
   332 			{
       
   333 			TChar paragraphDelimiter(0x2029);
       
   334 			aFormattingObjects.iRichText->InsertL(0, paragraphDelimiter);
       
   335 			repeatsInThisPar = 0;
       
   336 			}
       
   337 		}
       
   338 	}
       
   339 
       
   340 void MeasureCursorL(RArray<TTFTimeStamp>& aTimeStamps, TCursorPosition::TMovementType aType,
       
   341 	TFormattingObjects& aFormattingObjects, TInt64& aSlowest)
       
   342 	{
       
   343 	aTimeStamps.Close();
       
   344 	TTime start;
       
   345 	TTime end;
       
   346 	TInt lines = 0;
       
   347 	TCursorPosition::TMovementType move = aType;
       
   348 
       
   349 	while (move == aType)
       
   350 		{
       
   351 		lines++;
       
   352 		start.UniversalTime();
       
   353 		aFormattingObjects.iView->MoveCursorL(move, EFalse);
       
   354 		end.UniversalTime();
       
   355 		TInt64 us = end.MicroSecondsFrom(start).Int64();
       
   356 		TTFTimeStamp timestamp;
       
   357 		timestamp.iTime = us;
       
   358 		timestamp.iIteration = lines;
       
   359 		User::LeaveIfError(aTimeStamps.Append(timestamp));
       
   360 		if(us > aSlowest)
       
   361 			{
       
   362 			aSlowest = us;
       
   363 			}
       
   364 		const CTmTextLayout& tmLayout = aFormattingObjects.iLayout->TagmaTextLayout();
       
   365 		}
       
   366 	}
       
   367 
       
   368 void CreateFormattingObjectsLC(TFormattingObjects& aFormattingObjects)
       
   369 	{
       
   370 	TRect* displayRect = new(ELeave) TRect(0, 0, KDisplayWidth, KDisplayHeight);
       
   371 	CleanupStack::PushL(displayRect);
       
   372 	CParaFormatLayer* paraFormat = CParaFormatLayer::NewL();
       
   373 	CleanupStack::PushL(paraFormat);
       
   374 	CCharFormatLayer* charFormat = CCharFormatLayer::NewL();
       
   375 	CleanupStack::PushL(charFormat);
       
   376 	CRichText* text = CRichText::NewL(paraFormat, charFormat);
       
   377 	CleanupStack::PushL(text);
       
   378 	CTextLayout* layout = CTextLayout::NewL(text, displayRect->Width());
       
   379 	CleanupStack::PushL(layout);
       
   380 	CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect->Size(), 0);
       
   381 	CleanupStack::PushL(device);
       
   382 	// Prevent the line array from using up the memory
       
   383 	device->LineArray().Disable();
       
   384 	CTextView* view = CTextView::NewL(layout, *displayRect,
       
   385 		device, device, 0, 0, 0);
       
   386 	CleanupStack::PushL(view);
       
   387 	// must disable flicker-free redraw or Form will try to use
       
   388 	// the test font with an off-screen (i.e. real) graphics context,
       
   389 	// which will panic.
       
   390 	view->DisableFlickerFreeRedraw();
       
   391 
       
   392 	aFormattingObjects.iDisplayRect = displayRect;
       
   393 	aFormattingObjects.iParFormat = paraFormat;
       
   394 	aFormattingObjects.iCharFormat = charFormat;
       
   395 	aFormattingObjects.iRichText = text;
       
   396 	aFormattingObjects.iLayout = layout;
       
   397 	aFormattingObjects.iDevice = device;
       
   398 	aFormattingObjects.iView = view;
       
   399 	}
       
   400 
       
   401 void DestroyFormattingObjects(TFormattingObjects& aFormattingObjects)
       
   402 	{
       
   403 	CleanupStack::PopAndDestroy(aFormattingObjects.iView);
       
   404 	CleanupStack::PopAndDestroy(aFormattingObjects.iDevice);
       
   405 	CleanupStack::PopAndDestroy(aFormattingObjects.iLayout);
       
   406 	CleanupStack::PopAndDestroy(aFormattingObjects.iRichText);
       
   407 	CleanupStack::PopAndDestroy(aFormattingObjects.iCharFormat);
       
   408 	CleanupStack::PopAndDestroy(aFormattingObjects.iParFormat);
       
   409 	CleanupStack::PopAndDestroy(aFormattingObjects.iDisplayRect);
       
   410 	}
       
   411 
       
   412 /**
       
   413 @SYMTestCaseID SYSLIB-FORMA-UT-1897
       
   414 @SYMTestCaseDesc Benchmarks scrolling text
       
   415 @SYMTestPriority High
       
   416 @SYMTestActions creates document and scrolls it
       
   417 @SYMTestExpectedResults The test must not fail or panic .
       
   418 @SYMDEF DEF092140, DEF092139
       
   419 */
       
   420 void RunScrollingTestL(TInt aRepeats, TInt aRepeatsPerParagraph,
       
   421 	RArray<TTFTimeStamp>& aTimeStampsDown, RArray<TTFTimeStamp>& aTimeStampsUp,
       
   422 	TDocInfo& aDocInfo)
       
   423 	{
       
   424 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1897 "));
       
   425 	TInt docLength = KEnglish().Length() * aRepeats;
       
   426 	TInt paragraphs = aRepeats/aRepeatsPerParagraph;
       
   427 
       
   428 	TFormattingObjects o;
       
   429 	CreateFormattingObjectsLC(o);
       
   430 	o.iLayout->SetWrapWidth(KInsertDisplayWidth);
       
   431 	o.iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
       
   432 	SetTextL(*(o.iRichText), KEnglish, aRepeats, aRepeatsPerParagraph);
       
   433 
       
   434 	TTimeIntervalMicroSeconds opening = MeasureOpeningL(*(o.iView));
       
   435 	TInt64 slowest = 0;
       
   436 	MeasureCursorL(aTimeStampsDown, TCursorPosition::EFLineDown, o, slowest);
       
   437 	MeasureCursorL(aTimeStampsUp, TCursorPosition::EFLineUp, o, slowest);
       
   438 
       
   439 	RDebug::Printf("PERFORMANCE: Syslibs;Form_Scrolling_Slowest_Doc_with_%d_characters_%d_paragraphs;microseconds: %Ld", docLength, paragraphs, slowest);
       
   440 
       
   441 	aDocInfo = GetSampleDocInfoL(o);
       
   442 	DestroyFormattingObjects(o);
       
   443 	}
       
   444 
       
   445 /**
       
   446 @SYMTestCaseID SYSLIB-FORMA-UT-1898
       
   447 @SYMTestCaseDesc Benchmarks inserting, deleting and formatting text
       
   448 @SYMTestPriority High
       
   449 @SYMTestActions creates documents in each language and performs edits and reformats
       
   450 @SYMTestExpectedResults The test must not fail or panic .
       
   451 @SYMDEF DEF092140, DEF092139
       
   452 */
       
   453 void RunEnglishArabicJapaneseBenchmarksL(TFormattingObjects& aFormattingObjects)
       
   454 	{
       
   455 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1898 "));
       
   456 	SetTextL(*aFormattingObjects.iRichText, KEnglish, KEnglishRepeats, KEnglishRepeats);
       
   457 	TTimeIntervalMicroSeconds opening = MeasureOpeningL(*aFormattingObjects.iView);
       
   458 	TTimeIntervalMicroSeconds rmsCursorDown = MeasureRmsCursorDownL(*aFormattingObjects.iView);
       
   459 	TTimeIntervalMicroSeconds englishFormatting = MeasureFormattingL(*aFormattingObjects.iView);
       
   460 	TInt englishLines = NumberOfLines(*aFormattingObjects.iLayout);
       
   461 	SetTextL(*aFormattingObjects.iRichText, KArabic, KArabicRepeats, KArabicRepeats);
       
   462 	TTimeIntervalMicroSeconds arabicFormatting = MeasureFormattingL(*aFormattingObjects.iView);
       
   463 	TInt arabicLines = NumberOfLines(*aFormattingObjects.iLayout);
       
   464 	SetTextL(*aFormattingObjects.iRichText, KJapanese, KJapaneseRepeats, KJapaneseRepeats);
       
   465 	TTimeIntervalMicroSeconds japaneseFormatting = MeasureFormattingL(*aFormattingObjects.iView);
       
   466 	TInt japaneseLines = NumberOfLines(*aFormattingObjects.iLayout);
       
   467 
       
   468 	// Check that the results are fair
       
   469 	TInt minLines;
       
   470 	TInt maxLines;
       
   471 	if (arabicLines < englishLines)
       
   472 		{
       
   473 		minLines = arabicLines;
       
   474 		maxLines = englishLines;
       
   475 		}
       
   476 	else
       
   477 		{
       
   478 		minLines = englishLines;
       
   479 		maxLines = arabicLines;
       
   480 		}
       
   481 	if (japaneseLines < minLines)
       
   482 		minLines = japaneseLines;
       
   483 	else if (maxLines < japaneseLines)
       
   484 		maxLines = japaneseLines;
       
   485 
       
   486 	//Tests that the number of lines in each test is more or less balanced
       
   487 	test(maxLines * 100 <= minLines * 105);
       
   488 
       
   489 	RDebug::Printf("PERFORMANCE: Syslibs;Form_OpeningLargeParagraph;microseconds: %d",
       
   490 		static_cast<TInt>(opening.Int64()));
       
   491 	RDebug::Printf("PERFORMANCE: Syslibs;Form_RmsCursorDown;microseconds: %d",
       
   492 		static_cast<TInt>(rmsCursorDown.Int64()));
       
   493 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormattingEnglish;microseconds: %d",
       
   494 		static_cast<TInt>(englishFormatting.Int64()));
       
   495 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormattingArabic;microseconds: %d",
       
   496 		static_cast<TInt>(arabicFormatting.Int64()));
       
   497 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormattingJapanese;microseconds: %d",
       
   498 		static_cast<TInt>(japaneseFormatting.Int64()));
       
   499 	}
       
   500 
       
   501 /**
       
   502 @SYMTestCaseID SYSLIB-FORMA-UT-1896
       
   503 @SYMTestCaseDesc Benchmarks inserting text from the beginning of a paragraph
       
   504 @SYMTestPriority High
       
   505 @SYMTestActions creates a large paragraph containg just one word and inserts text iteratively from
       
   506 the beginning
       
   507 @SYMTestExpectedResults The test must not fail or panic .
       
   508 @SYMDEF DEF092140, DEF092139
       
   509 */
       
   510 void RunInsertTextTestsL(TInt aRepeats, TInt aRepeatsPerParagraph,
       
   511 	RArray<TTFTimeStamp>& aTimeStamps, TDocInfo& aDocInfo)
       
   512 	{
       
   513 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1896 "));
       
   514 	TFormattingObjects o;
       
   515 	CreateFormattingObjectsLC(o);
       
   516 	TInt64 slowest = 0;
       
   517 	o.iLayout->SetWrapWidth(KInsertDisplayWidth);
       
   518 	o.iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
       
   519 	MeasureInsertTextAtStartL(aRepeats, aRepeatsPerParagraph, aTimeStamps, o, slowest);
       
   520 	aDocInfo = GetSampleDocInfoL(o);
       
   521 
       
   522 	RDebug::Printf("PERFORMANCE: Syslibs;Form_InsertText_Slowest;microseconds: %Ld", slowest);
       
   523 
       
   524 	DestroyFormattingObjects(o);
       
   525 	}
       
   526 
       
   527 /**
       
   528 @SYMTestCaseID SYSLIB-FORMA-UT-1895
       
   529 @SYMTestCaseDesc Benchmarks deleting text from the beginning of a paragraph
       
   530 @SYMTestPriority High
       
   531 @SYMTestActions creates a large paragraph containg just one word and deletes text iteratively from
       
   532 the beginning
       
   533 @SYMTestExpectedResults The test must not fail or panic .
       
   534 @SYMDEF DEF092140, DEF092139
       
   535 */
       
   536 void RunDeleteTextFromStartTest(RArray<TTFTimeStamp>& aTimeStamps, TDocInfo& aDocInfo)
       
   537 	{
       
   538 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1895 "));
       
   539 	TFormattingObjects o;
       
   540 	CreateFormattingObjectsLC(o);
       
   541 	TInt64 slowest = 0;
       
   542 	o.iLayout->SetWrapWidth(KInsertDisplayWidth);
       
   543 	o.iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
       
   544 	RBuf bigbuf;
       
   545 	BigBufLC(bigbuf);
       
   546 	SetTextL(*o.iRichText, bigbuf, 1, 1);
       
   547 	TTimeIntervalMicroSeconds opening = MeasureOpeningL(*o.iView);
       
   548 
       
   549 	MeasureDeleteTextFromStartL(aTimeStamps, o, slowest);
       
   550 	aDocInfo = GetSampleDocInfoL(o);
       
   551 
       
   552 	RDebug::Printf("PERFORMANCE: Syslibs;Form_DeleteText_Slowest;microseconds: %Ld", slowest);
       
   553 
       
   554 	CleanupStack::PopAndDestroy();//bigbuf
       
   555 	DestroyFormattingObjects(o);
       
   556 	}
       
   557 
       
   558 void GetFormattingBenchmarkL(TInt aNumberOfIterations, TInt& aNumberOfCharacters, TInt64& aNormalisedBenchmark)
       
   559 	{
       
   560 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1895 "));
       
   561 	TFormattingObjects o;
       
   562 	CreateFormattingObjectsLC(o);
       
   563 	o.iLayout->SetWrapWidth(KInsertDisplayWidth);
       
   564 	o.iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
       
   565 
       
   566 	SetTextL(*(o.iRichText), KEnglish, aNumberOfIterations, aNumberOfIterations);
       
   567 
       
   568 	TTimeIntervalMicroSeconds ignore = MeasureOpeningL(*(o.iView));
       
   569 	o.iView->SetDocPosL(o.iRichText->DocumentLength());
       
   570 	//make a global change
       
   571 	o.iLayout->SetWrapWidth(KChangedDisplayWidth);
       
   572 	//measure time to reformat for it
       
   573 	TTime start;
       
   574 	TTime end;
       
   575 	start.UniversalTime();
       
   576 	o.iView->HandleGlobalChangeL();
       
   577 	end.UniversalTime();
       
   578 
       
   579 	TTimeIntervalMicroSeconds formattingTime = end.MicroSecondsFrom(start);
       
   580 
       
   581 	aNumberOfCharacters = o.iRichText->DocumentLength();
       
   582 	aNormalisedBenchmark = formattingTime.Int64()/aNumberOfIterations;
       
   583 
       
   584 	DestroyFormattingObjects(o);
       
   585 	}
       
   586 
       
   587 /**
       
   588 @SYMTestCaseID SYSLIB-FORMA-UT-1894
       
   589 @SYMTestCaseDesc Benchmarks formatting text
       
   590 @SYMTestPriority High
       
   591 @SYMTestActions for a series of documents of increasing size consisting of a single paragraph,
       
   592 sets the cursor position to the end of the document, makes a global change and formats it.
       
   593 @SYMTestExpectedResults The test must not fail or panic. The increase in time taken should be
       
   594 roughly linear with the document size.
       
   595 @SYMDEF DEF095401
       
   596 */
       
   597 void RunFormattingBenchmarksL()
       
   598 	{
       
   599 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORMA-UT-1894 "));
       
   600 	TInt numberOfCharacters = 0;
       
   601 	TInt numberOfIterations;
       
   602 	TInt64 normalisedBenchmark = 0;
       
   603 
       
   604 	numberOfIterations = 1;
       
   605 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   606 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   607 
       
   608 	numberOfIterations = 5;
       
   609 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   610 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   611 
       
   612 	numberOfIterations = 10;
       
   613 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   614 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   615 
       
   616 	numberOfIterations = 50;
       
   617 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   618 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   619 
       
   620 	numberOfIterations = 100;
       
   621 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   622 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   623 
       
   624 	numberOfIterations = 250;
       
   625 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   626 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   627 
       
   628 	numberOfIterations = 500;
       
   629 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   630 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   631 
       
   632 	numberOfIterations = 750;
       
   633 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   634 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   635 
       
   636 	numberOfIterations = 1000;
       
   637 	GetFormattingBenchmarkL(numberOfIterations, numberOfCharacters, normalisedBenchmark);
       
   638 	RDebug::Printf("PERFORMANCE: Syslibs;Form_FormatText;document contains %d characters: %Ld microseconds per iteration", numberOfCharacters, normalisedBenchmark);
       
   639 	}
       
   640 
       
   641 void RunBenchmarksL()
       
   642 	{
       
   643 	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
       
   644 	CleanupStack::PushL(scheduler);
       
   645 	CActiveScheduler::Install(scheduler);
       
   646 
       
   647 	RunFormattingBenchmarksL();
       
   648 
       
   649 	TDocInfo docInfo;
       
   650 	RArray<TTFTimeStamp> timestampsDown;
       
   651 	RArray<TTFTimeStamp> timestampsUp;
       
   652 	CleanupClosePushL(timestampsDown);
       
   653 	CleanupClosePushL(timestampsUp);
       
   654 
       
   655 	RunDeleteTextFromStartTest(timestampsUp, docInfo);
       
   656 	WriteSampleDocInfo(docInfo, fileTimeStamps);
       
   657 	WriteTimeStampsL(KDeleteTextFromStart, timestampsUp);
       
   658 
       
   659 	RunInsertTextTestsL(KEnglishInsertRepeats, KEnglishInsertRepeats, timestampsUp, docInfo);
       
   660 	WriteSampleDocInfo(docInfo, fileTimeStamps);
       
   661 	WriteTimeStampsL(KInsertTextAtStart, timestampsUp);
       
   662 
       
   663 	RunScrollingTestL(KEnglishScrollRepeats, KEnglishScrollRepeats, timestampsDown, timestampsUp, docInfo);
       
   664 	WriteSampleDocInfo(docInfo, fileTimeStamps);
       
   665 	WriteTimeStampsL(KScrollingDown, timestampsDown);
       
   666 	WriteTimeStampsL(KScrollingUp, timestampsUp);
       
   667 
       
   668 	RunScrollingTestL(KEnglishScrollRepeats, KEnglishScrollRepeats/2, timestampsDown, timestampsUp, docInfo);
       
   669 	WriteSampleDocInfo(docInfo, fileTimeStamps);
       
   670 	WriteTimeStampsL(KScrollingDown, timestampsDown);
       
   671 	WriteTimeStampsL(KScrollingUp, timestampsUp);
       
   672 
       
   673 	RunScrollingTestL(KEnglishScrollRepeats, KEnglishScrollRepeats/10, timestampsDown, timestampsUp, docInfo);
       
   674 	WriteSampleDocInfo(docInfo, fileTimeStamps);
       
   675 	WriteTimeStampsL(KScrollingDown, timestampsDown);
       
   676 	WriteTimeStampsL(KScrollingUp, timestampsUp);
       
   677 
       
   678 	TFormattingObjects o;
       
   679 	CreateFormattingObjectsLC(o);
       
   680 	RunEnglishArabicJapaneseBenchmarksL(o);
       
   681 	DestroyFormattingObjects(o);
       
   682 
       
   683 	CleanupStack::PopAndDestroy(2);
       
   684 	CleanupStack::PopAndDestroy(scheduler);
       
   685 
       
   686 	}
       
   687 
       
   688 TInt E32Main()
       
   689 	{
       
   690 	test.Title();
       
   691 	test.Start(_L("Start Font/Bitmap Server"));
       
   692 	static CTrapCleanup* TrapCleanup = CTrapCleanup::New();
       
   693 	TInt error = RFbsSession::Connect();
       
   694 	if (error == KErrNotFound)
       
   695 		{
       
   696 		FbsStartup();
       
   697 		error = RFbsSession::Connect();
       
   698 		}
       
   699 	// Tests that FBServ actually starts
       
   700 	test(error == KErrNone);
       
   701 	error = fs.Connect();
       
   702 	test(error == KErrNone);
       
   703 
       
   704 	error = fileTimeStamps.Replace(fs, KLogTimeStampsName, EFileWrite);
       
   705 	RDebug::Printf("> fileTimeStamps.Replace %d", error);
       
   706 	test(error == KErrNone);
       
   707 
       
   708 	test.Next(_L("Run Benchmarks"));
       
   709 	TRAP(error, RunBenchmarksL());
       
   710 	// Tests that the Benchmarks did not run out of memory
       
   711 	// or otherwise leave
       
   712 	test(error == KErrNone);
       
   713 
       
   714 	fileTimeStamps.Close();
       
   715 	fs.Close();
       
   716 	RFbsSession::Disconnect();
       
   717 	delete TrapCleanup;
       
   718 	test.End();
       
   719 	test.Close();
       
   720 	return error;
       
   721 	}
       
   722