os/graphics/graphicstest/uibench/src/tfbsglyphdata.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) 2009-2010 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 <test/graphicsfontutils.h>
sl@0
    23
#include <graphics/fbsglyphdataiterator.h>
sl@0
    24
#include <graphics/fbsglyphmetricsarray.h>
sl@0
    25
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
    26
#include <sgresource/sgimage.h>
sl@0
    27
#include <egl/egl.h>
sl@0
    28
#include <vg/openvg.h>
sl@0
    29
typedef EGLBoolean (*TvgCreateEGLImageTargetKHRTypefPtr) (VGeglImageKHR image);
sl@0
    30
#endif
sl@0
    31
#include "tfbsglyphdata.h"
sl@0
    32
sl@0
    33
// Size of EGLSurface used for rendering to, in pixels.
sl@0
    34
const TSize KEglTargetSize(512, 512);
sl@0
    35
sl@0
    36
CTFbsGlyphData::CTFbsGlyphData()
sl@0
    37
	{
sl@0
    38
	SetTestStepName(KTFbsGlyphData);
sl@0
    39
	}
sl@0
    40
sl@0
    41
CTFbsGlyphData::~CTFbsGlyphData()
sl@0
    42
	{
sl@0
    43
	}
sl@0
    44
sl@0
    45
TVerdict CTFbsGlyphData::doTestStepPreambleL()
sl@0
    46
    {
sl@0
    47
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
    48
    User::LeaveIfError(iFbs.Connect());
sl@0
    49
	User::LeaveIfError(iSgDriver.Open());
sl@0
    50
#endif
sl@0
    51
	iCharCodeConverter = CCharCodeConverter::NewL();
sl@0
    52
    return CTe_graphicsperformanceSuiteStepBase::doTestStepPreambleL();
sl@0
    53
    }
sl@0
    54
sl@0
    55
TVerdict CTFbsGlyphData::doTestStepPostambleL()
sl@0
    56
    {
sl@0
    57
    delete iCharCodeConverter;
sl@0
    58
    iCharCodeConverter = NULL;
sl@0
    59
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
    60
    iSgDriver.Close();
sl@0
    61
    iFbs.Disconnect();
sl@0
    62
#endif
sl@0
    63
    return CTe_graphicsperformanceSuiteStepBase::doTestStepPostambleL();
sl@0
    64
    }
sl@0
    65
sl@0
    66
TVerdict CTFbsGlyphData::doTestStepL()
sl@0
    67
	{
sl@0
    68
#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
    69
    INFO_PRINTF1(_L("CTFbsGlyphData can only be run with SgImage 'Lite'"));
sl@0
    70
    return TestStepResult();
sl@0
    71
#else
sl@0
    72
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0178"));
sl@0
    73
	GlyphMetricsArrayL(ETestLanguageLatin, ETrue, 1000);
sl@0
    74
	RecordTestResultL();
sl@0
    75
sl@0
    76
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0179"));
sl@0
    77
	GlyphMetricsArrayL(ETestLanguageLatin, EFalse, 50000);
sl@0
    78
	RecordTestResultL();
sl@0
    79
	
sl@0
    80
    // Tests 180 and 181 require a CMap table in order to convert CharacterCodes to GlyphCodes.
sl@0
    81
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0180"));
sl@0
    82
	GlyphMetricsArrayL(ETestLanguageHindi, ETrue, 25);
sl@0
    83
	RecordTestResultL();
sl@0
    84
	
sl@0
    85
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0181"));
sl@0
    86
	GlyphMetricsArrayL(ETestLanguageHindi, EFalse, 50000);
sl@0
    87
	RecordTestResultL();
sl@0
    88
	
sl@0
    89
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0182"));
sl@0
    90
	GlyphMetricsQuerySingleGlyphL();
sl@0
    91
	RecordTestResultL();
sl@0
    92
	
sl@0
    93
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0183"));
sl@0
    94
	GlyphDataIteratorOpenL(ETestLanguageLatin, ETrue, 50);
sl@0
    95
	RecordTestResultL();
sl@0
    96
sl@0
    97
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0184"));
sl@0
    98
	GlyphDataIteratorOpenL(ETestLanguageLatin, EFalse, 500);
sl@0
    99
	RecordTestResultL();
sl@0
   100
	
sl@0
   101
    // Tests 185 and 186 require a CMap table in order to convert CharacterCodes to GlyphCodes.
sl@0
   102
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0185"));
sl@0
   103
	GlyphDataIteratorOpenL(ETestLanguageHindi, ETrue, 10);
sl@0
   104
	RecordTestResultL();
sl@0
   105
	
sl@0
   106
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0186"));
sl@0
   107
	GlyphDataIteratorOpenL(ETestLanguageHindi, EFalse, 5000);
sl@0
   108
	RecordTestResultL();
sl@0
   109
	
sl@0
   110
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0187"));
sl@0
   111
	GlyphDataIteratorOpenSingleFontL();
sl@0
   112
	RecordTestResultL();
sl@0
   113
	
sl@0
   114
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0188"));
sl@0
   115
	GlyphMetricsQueryUnrasterizedL();
sl@0
   116
	RecordTestResultL();
sl@0
   117
	
sl@0
   118
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0189"));
sl@0
   119
	GlyphMetricsQueryPreRasterizedL();
sl@0
   120
	RecordTestResultL();
sl@0
   121
	
sl@0
   122
	SetTestStepID(_L("GRAPHICS-UI-BENCH-0190"));
sl@0
   123
	GlyphRenderingL();
sl@0
   124
	RecordTestResultL();
sl@0
   125
sl@0
   126
	return TestStepResult();
sl@0
   127
#endif
sl@0
   128
    }
sl@0
   129
sl@0
   130
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
   131
/**
sl@0
   132
@SYMTestCaseID GRAPHICS-UI-BENCH-0178...0181
sl@0
   133
sl@0
   134
@SYMTestType UT
sl@0
   135
sl@0
   136
@SYMPREQ PREQ2678
sl@0
   137
sl@0
   138
@SYMTestCaseDesc 
sl@0
   139
Measures the performance of calling RFbsGlyphMetricsArray::Get() with different sample data.
sl@0
   140
The sample data can be a single word, or a very long array of glyphs, in latin or non-latin
sl@0
   141
alphabets. At each repetition a different font is used, cycled over nine fonts, to reduce the
sl@0
   142
effect of having cached glyphs.
sl@0
   143
sl@0
   144
@SYMTestActions
sl@0
   145
i. Create some sample fonts to cycle through. 
sl@0
   146
ii. Load sample data from config file, specified by aSampleDataKey.
sl@0
   147
iii. Create RFbsGlyphMetricsArray, open on sample data.
sl@0
   148
iv. For each repetition, call RFbsGlyphMetricsArray::Get(), adjusting font at each repetition.
sl@0
   149
v. Measure time from from first to last repetition.
sl@0
   150
sl@0
   151
@param aLanguage The language this test will use.
sl@0
   152
@param aLongData If ETrue, tells the test to use the long sample data string for the test, EFalse
sl@0
   153
	will make the test use the short string data.
sl@0
   154
@param aReps The number of times to repeat the test.
sl@0
   155
*/
sl@0
   156
void CTFbsGlyphData::GlyphMetricsArrayL(TTestLanguage aLanguage, TBool aLongData, TInt aReps)
sl@0
   157
	{
sl@0
   158
	TBuf<128> KTestName;
sl@0
   159
	TPtrC KTestVariant = ConfigKeyNameL(aLanguage, aLongData);
sl@0
   160
	KTestName.Format(_L("GlyphMetricsArray %S"), &KTestVariant);
sl@0
   161
	
sl@0
   162
	// Create some test fonts using the font factory.
sl@0
   163
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   164
	fontFactory->CreateFontsL(aLanguage, 9);
sl@0
   165
sl@0
   166
	// Load the sample string data from the config file.
sl@0
   167
	TInt numGlyphCodes = 0;
sl@0
   168
	TUint* glyphCodes;
sl@0
   169
	LoadConfigSampleDataL(fontFactory->NextFont(), aLanguage, aLongData, glyphCodes, numGlyphCodes);
sl@0
   170
sl@0
   171
	// Run the test.
sl@0
   172
	TInt err = KErrNone;
sl@0
   173
	RFbsGlyphMetricsArray array;
sl@0
   174
	CleanupClosePushL(array);
sl@0
   175
	iProfiler->InitResults();
sl@0
   176
	for (TInt rep = aReps; (rep != 0) && (err == KErrNone); --rep)
sl@0
   177
		{
sl@0
   178
		err = array.Get(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
sl@0
   179
		}
sl@0
   180
	iProfiler->MarkResultSetL();
sl@0
   181
	TESTE(err == KErrNone, err);
sl@0
   182
	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, aReps, numGlyphCodes);
sl@0
   183
	
sl@0
   184
	CleanupStack::PopAndDestroy(2); // array, fontFactory
sl@0
   185
	delete [] glyphCodes;
sl@0
   186
	}
sl@0
   187
sl@0
   188
/**
sl@0
   189
@SYMTestCaseID GRAPHICS-UI-BENCH-0182
sl@0
   190
sl@0
   191
@SYMTestType UT
sl@0
   192
sl@0
   193
@SYMPREQ PREQ2678
sl@0
   194
sl@0
   195
@SYMTestCaseDesc 
sl@0
   196
Measures the performance of calling RFbsGlyphDataIterator::Get() with a single glyph,
sl@0
   197
versus CFont::GetCharacterData(). Using a single glyph code is a very common use case.
sl@0
   198
The glyph and the font is changed at each iteration.
sl@0
   199
sl@0
   200
@SYMTestActions
sl@0
   201
i. Create some sample fonts to cycle through. 
sl@0
   202
ii. Create RFbsGlyphMetricsArray.
sl@0
   203
iii. For each repetition, call RFbsGlyphMetricsArray::Get(), adjusting the glyph at 
sl@0
   204
	each iteration.
sl@0
   205
iv. Measure time from from first to last iteration.
sl@0
   206
v. Repeat steps iii. and iv. with CFont::GetCharacterData().
sl@0
   207
*/
sl@0
   208
void CTFbsGlyphData::GlyphMetricsQuerySingleGlyphL()
sl@0
   209
	{
sl@0
   210
	_LIT(KTestName, "GlyphMetricsQuerySingleGlyph");
sl@0
   211
	const TInt KNumIterations = 50000;
sl@0
   212
	TInt err = KErrNone;
sl@0
   213
	TBuf<128> KTestNameVariant;
sl@0
   214
sl@0
   215
	// Create some test fonts using the font factory.
sl@0
   216
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   217
	
sl@0
   218
	// Run the test for RFbsGlyphMetricsArray, with a different character 
sl@0
   219
	// and font for each iteration.
sl@0
   220
	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
sl@0
   221
	fontFactory->CreateFontsL(ETestLanguageLatin, 9);
sl@0
   222
	RFbsGlyphMetricsArray array;
sl@0
   223
	CleanupClosePushL(array);
sl@0
   224
	iProfiler->InitResults();
sl@0
   225
	for (TInt rep = KNumIterations; rep != 0 && (err == KErrNone); --rep)
sl@0
   226
		{
sl@0
   227
		const TUint KGlyphCode = 32 + (rep % 96);
sl@0
   228
		err = array.Get(*(fontFactory->NextFont()), &KGlyphCode, 1);
sl@0
   229
		}
sl@0
   230
	iProfiler->MarkResultSetL();
sl@0
   231
	TESTE(err == KErrNone, err);
sl@0
   232
	CleanupStack::PopAndDestroy(1); // array
sl@0
   233
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, 1);
sl@0
   234
	fontFactory->ReleaseFonts();
sl@0
   235
	
sl@0
   236
	// Run the test for GetCharacterData(), with a different character
sl@0
   237
	// and font for each iteration.
sl@0
   238
	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
sl@0
   239
	fontFactory->CreateFontsL(ETestLanguageLatin, 9);
sl@0
   240
	TOpenFontCharMetrics metrics;
sl@0
   241
	const TUint8* bitmapData = NULL;
sl@0
   242
	TSize bitmapSize;
sl@0
   243
	iProfiler->InitResults();
sl@0
   244
	for (TInt rep = KNumIterations; rep != 0; --rep)
sl@0
   245
		{
sl@0
   246
		const TUint KGlyphCode = 32 + (rep % 96);
sl@0
   247
		fontFactory->NextFont()->GetCharacterData(KGlyphCode, metrics, bitmapData, bitmapSize);
sl@0
   248
		}
sl@0
   249
	iProfiler->MarkResultSetL();
sl@0
   250
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, 1);
sl@0
   251
	
sl@0
   252
	CleanupStack::PopAndDestroy(1); // fontFactory
sl@0
   253
	}
sl@0
   254
sl@0
   255
/**
sl@0
   256
@SYMTestCaseID GRAPHICS-UI-BENCH-0183...0186
sl@0
   257
sl@0
   258
@SYMTestType UT
sl@0
   259
sl@0
   260
@SYMPREQ PREQ2678
sl@0
   261
sl@0
   262
@SYMTestCaseDesc 
sl@0
   263
Measures the performance of calling RFbsGlyphDataIterator::Open() with different 
sl@0
   264
sample data, and iterating through the data with RFbsGlyphDataIterator::Next(). 
sl@0
   265
The sample data can be a single word, or a very long array of glyphs,
sl@0
   266
in various languages. At each repetition a different font is used, cycled
sl@0
   267
over nine fonts.
sl@0
   268
sl@0
   269
@SYMTestActions
sl@0
   270
i. Create some sample fonts to cycle through. 
sl@0
   271
ii. Create RFbsGlyphDataIterator.
sl@0
   272
iii. For each repetition, call RFbsGlyphDataIterator::Open(), adjusting the glyph at each 
sl@0
   273
	iteration. The font is changed at each repetition.
sl@0
   274
iv. Measure time from from first to last repetition.
sl@0
   275
sl@0
   276
@param aLanguage The language this test will use.
sl@0
   277
@param aLongData If ETrue, tells the test to use the long sample data string for the test, EFalse
sl@0
   278
	will make the test use the short string data.
sl@0
   279
@param aReps The number of times to repeat the test.
sl@0
   280
 */
sl@0
   281
void CTFbsGlyphData::GlyphDataIteratorOpenL(TTestLanguage aLanguage, TBool aLongData, TInt aReps)
sl@0
   282
	{
sl@0
   283
	TBuf<128> KTestName;
sl@0
   284
	TPtrC KTestVariant = ConfigKeyNameL(aLanguage, aLongData);
sl@0
   285
	KTestName.Format(_L("GlyphDataIteratorOpen %S"), &KTestVariant);
sl@0
   286
	
sl@0
   287
	// Create some test fonts using the font factory.
sl@0
   288
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   289
	fontFactory->CreateFontsL(aLanguage, 9);
sl@0
   290
	
sl@0
   291
	// Load the sample string data from the config file.
sl@0
   292
	TInt numGlyphCodes = 0;
sl@0
   293
	TUint* glyphCodes;
sl@0
   294
	LoadConfigSampleDataL(fontFactory->NextFont(), aLanguage, aLongData, glyphCodes, numGlyphCodes);
sl@0
   295
sl@0
   296
	// Run the test.
sl@0
   297
	TInt err = KErrNotFound;
sl@0
   298
	RFbsGlyphDataIterator iter;
sl@0
   299
	CleanupClosePushL(iter);
sl@0
   300
	iProfiler->InitResults();
sl@0
   301
	for (TInt rep = aReps; (rep != 0) && (err == KErrNotFound); --rep)
sl@0
   302
		{
sl@0
   303
		err = iter.Open(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
sl@0
   304
		for (; err == KErrNone; err = iter.Next())
sl@0
   305
			{
sl@0
   306
			// no operation
sl@0
   307
			}
sl@0
   308
		iter.Close();
sl@0
   309
		}
sl@0
   310
	iProfiler->MarkResultSetL();
sl@0
   311
	TESTE(err == KErrNotFound, err);
sl@0
   312
sl@0
   313
	CleanupStack::PopAndDestroy(2); // iter, fontFactory
sl@0
   314
	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, aReps, numGlyphCodes);
sl@0
   315
	delete [] glyphCodes;
sl@0
   316
	}
sl@0
   317
sl@0
   318
/**
sl@0
   319
@SYMTestCaseID GRAPHICS-UI-BENCH-0187
sl@0
   320
sl@0
   321
@SYMTestType UT
sl@0
   322
sl@0
   323
@SYMPREQ PREQ2678
sl@0
   324
sl@0
   325
@SYMTestCaseDesc 
sl@0
   326
Measures the performance of calling RFbsGlyphDataIterator::Open() with different 
sl@0
   327
lengthed arrays but the same font. The sample data is a long array of characters.
sl@0
   328
sl@0
   329
@SYMTestActions
sl@0
   330
i. Create a single test font 
sl@0
   331
ii. Create RFbsGlyphDataIterator.
sl@0
   332
iii. Pass an array to RFbsGlyphDataIterator::Open(), starting with a single glyph.
sl@0
   333
	For each iteration, increase the length of the array by one until the entire
sl@0
   334
	string has been opened.
sl@0
   335
iv. Measure the time to perform all the iterations.
sl@0
   336
sl@0
   337
@param aSampleDataKey The string key to lookup under the GlyphArraySampleText section of the 
sl@0
   338
	config file where the sample data is read.
sl@0
   339
@param aReps The number of times to repeat the test.
sl@0
   340
 */
sl@0
   341
void CTFbsGlyphData::GlyphDataIteratorOpenSingleFontL()
sl@0
   342
	{
sl@0
   343
	_LIT(KTestName, "GlyphDataIteratorOpenSingleFont");
sl@0
   344
	// A cap on the max number of iterations to complete.
sl@0
   345
	const TInt KMaxNumIterations = 200;
sl@0
   346
    const TTestLanguage KTestLanguage = ETestLanguageHindi;
sl@0
   347
	
sl@0
   348
	// Create some test fonts using the font factory.
sl@0
   349
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   350
	fontFactory->CreateFontsL(KTestLanguage, 1);
sl@0
   351
	CFbsFont* font = fontFactory->NextFont();
sl@0
   352
	
sl@0
   353
	// Load the sample string data from the config file.
sl@0
   354
	TInt numGlyphCodes = 0;
sl@0
   355
	TUint* glyphCodes;
sl@0
   356
	LoadConfigSampleDataL(font, KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
sl@0
   357
	
sl@0
   358
	const TInt KNumRepetitions = Min<TInt>(numGlyphCodes - 1, KMaxNumIterations);
sl@0
   359
	RFbsGlyphDataIterator iter;
sl@0
   360
	CleanupClosePushL(iter);
sl@0
   361
	TInt iterErr = KErrNone;
sl@0
   362
	TInt glyphCount = 0;
sl@0
   363
	iProfiler->InitResults();
sl@0
   364
	for (glyphCount = 1; (glyphCount < KNumRepetitions); ++glyphCount)
sl@0
   365
		{
sl@0
   366
		iterErr = iter.Open(*font, glyphCodes, glyphCount);
sl@0
   367
		for (; iterErr == KErrNone; iterErr = iter.Next())
sl@0
   368
			{
sl@0
   369
			// no operation
sl@0
   370
			}
sl@0
   371
		iter.Close();
sl@0
   372
		}
sl@0
   373
	iProfiler->MarkResultSetL();
sl@0
   374
	TEST(glyphCount == KNumRepetitions);
sl@0
   375
	TESTE(iterErr == KErrNotFound, iterErr);
sl@0
   376
	
sl@0
   377
	const TInt KAvgNumCharsPerIteration = KNumRepetitions/2;
sl@0
   378
	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, KNumRepetitions, KAvgNumCharsPerIteration);
sl@0
   379
	
sl@0
   380
	CleanupStack::PopAndDestroy(2); // iter, fontFactory
sl@0
   381
	delete [] glyphCodes;
sl@0
   382
	}
sl@0
   383
/**
sl@0
   384
@SYMTestCaseID GRAPHICS-UI-BENCH-0188
sl@0
   385
sl@0
   386
@SYMTestType UT
sl@0
   387
sl@0
   388
@SYMPREQ PREQ2678
sl@0
   389
sl@0
   390
@SYMTestCaseDesc 
sl@0
   391
Measures the performance of querying the TOpenFontCharMetrics using the different
sl@0
   392
available APIs. RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData()
sl@0
   393
are compared against each other, using the same fonts, and same sample data.
sl@0
   394
This test uses glyphs that have not been rasterized before, therefore for certain
sl@0
   395
APIs this will mean rasterizing the glyphs.
sl@0
   396
sl@0
   397
@SYMTestActions
sl@0
   398
i. Load sample text data from config file.
sl@0
   399
ii. For each of RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData():
sl@0
   400
	1. Create 50 new fonts.
sl@0
   401
	2. Run the test, calling the necessary API once per font/loop.
sl@0
   402
	3. For GetCharacterData() and RFbsGlyphDataIterator(), cycle through each glyph
sl@0
   403
		to ensure all metrics have been retrieved. This is not necessary for 
sl@0
   404
		RFbsGlyphMetricsArray.
sl@0
   405
	4. Measure time between first and last font/loop.
sl@0
   406
	5. Destroy test fonts so that next test has to re-rasterize the glyphs.	
sl@0
   407
sl@0
   408
@SYMTestExpectedResults
sl@0
   409
Since this test uses non-rasterized fonts, RFbsGlyphMetricsArray should be faster than
sl@0
   410
GetCharacterData() and RFbsGlyphDataIterator, which both rasterize the glyphs in order to 
sl@0
   411
get their metrics information.
sl@0
   412
 */
sl@0
   413
void CTFbsGlyphData::GlyphMetricsQueryUnrasterizedL()
sl@0
   414
	{
sl@0
   415
	_LIT(KTestName, "GlyphMetricsQueryUnrasterized");
sl@0
   416
	
sl@0
   417
	TBuf<128> KTestNameVariant;
sl@0
   418
	// First do the test for the iterator. To ensure fair comparison with
sl@0
   419
    // RFbsGlyphMetricsArray, cycle through each iteration to ensure the metrics
sl@0
   420
    // for each glyph is found.
sl@0
   421
    KTestNameVariant.Format(_L("%S RFbsGlyphDataIterator"), &KTestName);
sl@0
   422
    
sl@0
   423
	const TInt KNumFonts = 50;
sl@0
   424
	const TTestLanguage KTestLanguage = ETestLanguageLatin;
sl@0
   425
	
sl@0
   426
	// Create some test fonts using the font factory.
sl@0
   427
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   428
    fontFactory->CreateFontsL(KTestLanguage, KNumFonts);
sl@0
   429
	    
sl@0
   430
	// Load the sample string data from the config file. Both the iterator and the
sl@0
   431
	// array will use this same sample data.
sl@0
   432
	TInt numGlyphCodes = 0;
sl@0
   433
	TUint* glyphCodes;
sl@0
   434
	LoadConfigSampleDataL(fontFactory->NextFont(), KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
sl@0
   435
	
sl@0
   436
	RFbsGlyphDataIterator iter;
sl@0
   437
	CleanupClosePushL(iter);
sl@0
   438
	TInt iterErr = KErrNone;
sl@0
   439
	TInt rep = 0;
sl@0
   440
	iProfiler->InitResults();
sl@0
   441
	for (rep = KNumFonts; (rep != 0); --rep)
sl@0
   442
		{
sl@0
   443
		iterErr = iter.Open(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
sl@0
   444
		for (; iterErr == KErrNone; iterErr = iter.Next())
sl@0
   445
			{
sl@0
   446
			// no operation
sl@0
   447
			}
sl@0
   448
		iter.Close();
sl@0
   449
		}
sl@0
   450
	iProfiler->MarkResultSetL();
sl@0
   451
	TEST(rep == 0);
sl@0
   452
	TESTE(iterErr == KErrNotFound, iterErr);
sl@0
   453
	CleanupStack::PopAndDestroy(1); // iter		
sl@0
   454
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
sl@0
   455
	
sl@0
   456
	// Second, do the test for the array. This should be faster.
sl@0
   457
	// Destroy the fonts and re-create them so that they have to be re-rasterized
sl@0
   458
	// for a fair comparison.
sl@0
   459
	TInt arrayErr = KErrNone;
sl@0
   460
	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
sl@0
   461
	fontFactory->ReleaseFonts();
sl@0
   462
	fontFactory->CreateFontsL(KTestLanguage, KNumFonts);
sl@0
   463
	RFbsGlyphMetricsArray array;
sl@0
   464
	CleanupClosePushL(array);
sl@0
   465
	iProfiler->InitResults();	
sl@0
   466
	for (TInt rep = KNumFonts; (rep != 0) && (arrayErr == KErrNone); --rep)
sl@0
   467
		{
sl@0
   468
		arrayErr = array.Get(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
sl@0
   469
		}
sl@0
   470
	iProfiler->MarkResultSetL();
sl@0
   471
	CleanupStack::PopAndDestroy(1); // array
sl@0
   472
	TEST(rep == 0);
sl@0
   473
	TESTE(arrayErr == KErrNone, arrayErr);
sl@0
   474
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
sl@0
   475
	
sl@0
   476
	// Third, do the test using GetCharacterData() to get the metrics.
sl@0
   477
	// Destroy the fonts and re-create them so that they have to be re-rasterized
sl@0
   478
	// for a fair comparison.
sl@0
   479
	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
sl@0
   480
	fontFactory->ReleaseFonts();
sl@0
   481
	fontFactory->CreateFontsL(KTestLanguage, KNumFonts);	
sl@0
   482
	iProfiler->InitResults();
sl@0
   483
	const TUint8* bitmapData = NULL;
sl@0
   484
	TSize bitmapSize;
sl@0
   485
	TOpenFontCharMetrics metrics;	
sl@0
   486
	for (TInt rep = KNumFonts; (rep != 0); --rep)
sl@0
   487
		{
sl@0
   488
		CFbsFont* font = fontFactory->NextFont(); 
sl@0
   489
		for (TInt glyphIndex = 0; glyphIndex < numGlyphCodes; glyphIndex++)
sl@0
   490
			{
sl@0
   491
			font->GetCharacterData(glyphCodes[glyphIndex], metrics, bitmapData, bitmapSize);
sl@0
   492
			}
sl@0
   493
		}
sl@0
   494
	iProfiler->MarkResultSetL();
sl@0
   495
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
sl@0
   496
	
sl@0
   497
	CleanupStack::PopAndDestroy(1); // fontFactory
sl@0
   498
	delete [] glyphCodes;
sl@0
   499
	}
sl@0
   500
sl@0
   501
/**
sl@0
   502
@SYMTestCaseID GRAPHICS-UI-BENCH-0189
sl@0
   503
sl@0
   504
@SYMTestType UT
sl@0
   505
sl@0
   506
@SYMPREQ PREQ2678
sl@0
   507
sl@0
   508
@SYMTestCaseDesc 
sl@0
   509
Measures the performance of querying the TOpenFontCharMetrics using the different
sl@0
   510
available APIs. RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData()
sl@0
   511
are compared against each other, using the same fonts, and same sample data.
sl@0
   512
This test uses glyphs that have already been rasterized, thereby possibly reducing the 
sl@0
   513
extra overhead this has.
sl@0
   514
sl@0
   515
@SYMTestActions
sl@0
   516
i. Load sample text data from config file.
sl@0
   517
ii. Create test font.
sl@0
   518
iii. Pre-rasterize glyphs using RFbsGlyphDataIterator. This will rasterize the glyphs 
sl@0
   519
	and cause them to be cached for use by all the APIs tested here.
sl@0
   520
iv. For each of RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData():
sl@0
   521
	1. Begin the loop, calling the necessary API once per font/loop.
sl@0
   522
	2. For each glyph, request the glyph metrics.
sl@0
   523
	3. Measure time between first and last font/loop.
sl@0
   524
v. Destroy test font.
sl@0
   525
sl@0
   526
@SYMTestExpectedResults
sl@0
   527
All results should be improved over GlyphMetricsQueryUnrasterized (GRAPHICS-UI-BENCH-0187).
sl@0
   528
since no rasterizing should take place during these tests.
sl@0
   529
 */
sl@0
   530
void CTFbsGlyphData::GlyphMetricsQueryPreRasterizedL()
sl@0
   531
	{
sl@0
   532
	_LIT(KTestName, "GlyphMetricsQueryPreRasterized");
sl@0
   533
	TBuf<128> KTestNameVariant;
sl@0
   534
	const TInt KNumIterations = 500;
sl@0
   535
	const TTestLanguage KTestLanguage = ETestLanguageLatin;
sl@0
   536
sl@0
   537
	// Create a test font using the font factory.
sl@0
   538
    CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   539
    fontFactory->CreateFontsL(ETestLanguageLatin, 1);   
sl@0
   540
    CFbsFont* font = fontFactory->NextFont();
sl@0
   541
	    
sl@0
   542
    TInt numGlyphCodes = 0;
sl@0
   543
	TUint* glyphCodes;
sl@0
   544
	LoadConfigSampleDataL(font, KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
sl@0
   545
	
sl@0
   546
	TInt iterErr = KErrNone;
sl@0
   547
	TInt rep = 0;
sl@0
   548
	// Rasterize the glyphs first.
sl@0
   549
	RFbsGlyphDataIterator iter;
sl@0
   550
	CleanupClosePushL(iter);
sl@0
   551
	for (rep = KNumIterations; (rep != 0) ; --rep)
sl@0
   552
		{
sl@0
   553
		iterErr = iter.Open(*font, glyphCodes, numGlyphCodes);
sl@0
   554
		for (; iterErr == KErrNone; iterErr = iter.Next())
sl@0
   555
			{
sl@0
   556
			// no operation
sl@0
   557
			}
sl@0
   558
		iter.Close();
sl@0
   559
		}
sl@0
   560
	TEST(rep == 0);
sl@0
   561
	TESTE(iterErr == KErrNotFound, iterErr);
sl@0
   562
	
sl@0
   563
	TOpenFontCharMetrics metrics;
sl@0
   564
		
sl@0
   565
	// First do the test for the iterator. To ensure fair comparison with
sl@0
   566
	// RFbsGlyphMetricsArray, cycle through each iteration to ensure the metrics
sl@0
   567
	// for each glyph is found.
sl@0
   568
	iterErr = KErrNone;
sl@0
   569
	KTestNameVariant.Format(_L("%S RFbsGlyphDataIterator"), &KTestName);
sl@0
   570
	iProfiler->InitResults();
sl@0
   571
	for (TInt rep = KNumIterations; (rep != 0); --rep)
sl@0
   572
		{
sl@0
   573
		for (iterErr = iter.Open(*font, glyphCodes, numGlyphCodes); iterErr == KErrNone; iterErr = iter.Next())
sl@0
   574
			{
sl@0
   575
			metrics = iter.Metrics();
sl@0
   576
			}
sl@0
   577
		iter.Close();
sl@0
   578
		}
sl@0
   579
	iProfiler->MarkResultSetL();
sl@0
   580
	TESTE(iterErr == KErrNotFound, iterErr);
sl@0
   581
	CleanupStack::PopAndDestroy(1); // iter
sl@0
   582
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
sl@0
   583
	
sl@0
   584
	
sl@0
   585
	// Second, do the test for the array. This should be faster.
sl@0
   586
	TInt arrayErr = KErrNone;
sl@0
   587
	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
sl@0
   588
	RFbsGlyphMetricsArray array;
sl@0
   589
	CleanupClosePushL(array);
sl@0
   590
	iProfiler->InitResults();
sl@0
   591
	for (TInt rep = KNumIterations; (rep != 0) && (arrayErr == KErrNone); --rep)
sl@0
   592
		{
sl@0
   593
		arrayErr = array.Get(*font, glyphCodes, numGlyphCodes);
sl@0
   594
		for (TInt i = 0; i < numGlyphCodes; ++i)
sl@0
   595
			{
sl@0
   596
			metrics = array[i];
sl@0
   597
			}
sl@0
   598
		}
sl@0
   599
	iProfiler->MarkResultSetL();
sl@0
   600
	TESTE(arrayErr == KErrNone, arrayErr);
sl@0
   601
	CleanupStack::PopAndDestroy(1); // array
sl@0
   602
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
sl@0
   603
	
sl@0
   604
	
sl@0
   605
	// Third, do the test using GetCharacterData() to get the metrics.
sl@0
   606
	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
sl@0
   607
	const TUint8* bitmapData;
sl@0
   608
	TSize bitmapSize;
sl@0
   609
sl@0
   610
	iProfiler->InitResults();
sl@0
   611
	for (TInt rep = KNumIterations; (rep != 0); --rep)
sl@0
   612
		{
sl@0
   613
		for (TInt glyphIndex = 0; glyphIndex < numGlyphCodes; glyphIndex++)
sl@0
   614
			{
sl@0
   615
			font->GetCharacterData(glyphCodes[glyphIndex], metrics, bitmapData, bitmapSize);
sl@0
   616
			}
sl@0
   617
		}
sl@0
   618
	iProfiler->MarkResultSetL();
sl@0
   619
	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
sl@0
   620
	
sl@0
   621
	CleanupStack::PopAndDestroy(1); // fontFactory
sl@0
   622
	delete [] glyphCodes;
sl@0
   623
	}
sl@0
   624
sl@0
   625
/**
sl@0
   626
@SYMTestCaseID GRAPHICS-UI-BENCH-0190
sl@0
   627
sl@0
   628
@SYMTestType UT
sl@0
   629
sl@0
   630
@SYMPREQ PREQ2678
sl@0
   631
sl@0
   632
@SYMTestCaseDesc 
sl@0
   633
Measures the end-to-end performance of using Khronos APIs to render glyphs using the
sl@0
   634
RFbsGlyphDataIterator API. Positioning is very basic and is not reflective of a production-
sl@0
   635
quality text-rendering algorithm, but serves as a useful benchmark of the overall
sl@0
   636
text-rendering performance using this API.
sl@0
   637
sl@0
   638
@SYMTestActions
sl@0
   639
i. Create a sample font to use. 
sl@0
   640
ii. Create a RSgImage to be used as a target for Khronos API rendering.
sl@0
   641
iii. Set-up EGL and OpenVG.
sl@0
   642
iv. Construct RFbsGlyphDataIterator, and open on sample data. At each iteration:
sl@0
   643
	1. Create an EGLImage from the RSgImage.
sl@0
   644
	2. Create a VGImage from the EGLImage.
sl@0
   645
	3. Render the VGImage using vgDrawImage().
sl@0
   646
	4. Destroy VGImage.
sl@0
   647
	5. Destroy EGLImage.
sl@0
   648
	6. Advance the current rendering position for the next glyph, ensuring that every glyph
sl@0
   649
	will be within the bounds of the target surface.
sl@0
   650
v. Measure time from from first to last iteration.
sl@0
   651
*/
sl@0
   652
void CTFbsGlyphData::GlyphRenderingL()
sl@0
   653
	{
sl@0
   654
	_LIT(KTestName, "GlyphRendering");
sl@0
   655
	const TInt KNumIterations = 500;
sl@0
   656
    const TTestLanguage KTestLanguage = ETestLanguageHindi;
sl@0
   657
	
sl@0
   658
	// Create some test fonts using the font factory.
sl@0
   659
	CTFontFactory* fontFactory = CTFontFactory::NewLC();
sl@0
   660
	fontFactory->CreateFontsL(KTestLanguage, 1, 20);
sl@0
   661
	CFbsFont* font = fontFactory->NextFont();
sl@0
   662
	const TInt KFontHeightInPixels = font->HeightInPixels();
sl@0
   663
sl@0
   664
	// Create RSgImage to be used as OpenVG Pixmap Surface
sl@0
   665
sl@0
   666
	RSgImage target;
sl@0
   667
	TInt err = target.Create(TSgImageInfo(KEglTargetSize, ESgPixelFormatARGB_8888_PRE, ESgUsageBitOpenVgSurface));
sl@0
   668
	TESTL(err == KErrNone);
sl@0
   669
	CleanupClosePushL(target);
sl@0
   670
	
sl@0
   671
	// Initialize EGL/OpenVG for rendering.
sl@0
   672
	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
sl@0
   673
	if (display == EGL_NO_DISPLAY)
sl@0
   674
		{
sl@0
   675
		ERR_PRINTF2(_L("Failed to get EGLDisplay. [eglError=%X]"), eglGetError());
sl@0
   676
		User::Leave(KErrGeneral);
sl@0
   677
		}
sl@0
   678
	TESTL(display != EGL_NO_DISPLAY);
sl@0
   679
	if (EGL_FALSE == eglInitialize(display, NULL, NULL))
sl@0
   680
		{
sl@0
   681
		ERR_PRINTF2(_L("Failed to initialize EGLDisplay. [eglError=%X]"), eglGetError());
sl@0
   682
		User::Leave(KErrGeneral);
sl@0
   683
		}
sl@0
   684
	eglBindAPI(EGL_OPENVG_API);
sl@0
   685
	
sl@0
   686
	EGLint imageAttribs[] =
sl@0
   687
	    {
sl@0
   688
	    EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, 
sl@0
   689
	    EGL_NONE
sl@0
   690
	    };
sl@0
   691
	EGLint configAttribs[] = 
sl@0
   692
		{
sl@0
   693
		EGL_MATCH_NATIVE_PIXMAP, (EGLint)&target,
sl@0
   694
		EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
sl@0
   695
		EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT, 
sl@0
   696
		EGL_NONE
sl@0
   697
		};
sl@0
   698
	
sl@0
   699
	const EGLint KPixmapAttribsVgAlphaFormatPre[] = 
sl@0
   700
	    {
sl@0
   701
	    EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE,
sl@0
   702
	    EGL_NONE
sl@0
   703
	    };
sl@0
   704
		
sl@0
   705
	EGLint configId = 0;
sl@0
   706
	EGLint numConfigs = 0;
sl@0
   707
	if (EGL_FALSE == eglChooseConfig(display, configAttribs, &configId, 1, &numConfigs) || numConfigs == 0)
sl@0
   708
		{
sl@0
   709
		ERR_PRINTF3(_L("Failed to find suitable EGLConfig. [eglError=%X, configs=%d]"), eglGetError(), numConfigs);
sl@0
   710
		User::Leave(KErrGeneral);
sl@0
   711
		}
sl@0
   712
	EGLContext context = eglCreateContext(display, configId, EGL_NO_CONTEXT, NULL);
sl@0
   713
	if (context == EGL_NO_CONTEXT)
sl@0
   714
		{
sl@0
   715
		ERR_PRINTF2(_L("Failed to create EGLContext. [eglError=%X]"), eglGetError());
sl@0
   716
		User::Leave(KErrGeneral);
sl@0
   717
		}
sl@0
   718
	EGLSurface surface = eglCreatePixmapSurface(display, configId, &target, KPixmapAttribsVgAlphaFormatPre);
sl@0
   719
	if (EGL_FALSE == eglMakeCurrent(display, surface, surface, context))
sl@0
   720
		{
sl@0
   721
		ERR_PRINTF2(_L("Failed to create make surface and context current. [eglError=%X]"), eglGetError());
sl@0
   722
		eglDestroyContext(display, context);
sl@0
   723
		User::Leave(KErrGeneral);
sl@0
   724
		}
sl@0
   725
	
sl@0
   726
	// Load the necessary EGL extensions...
sl@0
   727
	TvgCreateEGLImageTargetKHRTypefPtr vgCreateImageTargetKHR;
sl@0
   728
	PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
sl@0
   729
	PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
sl@0
   730
	eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
sl@0
   731
	eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
sl@0
   732
	vgCreateImageTargetKHR = reinterpret_cast<TvgCreateEGLImageTargetKHRTypefPtr>(eglGetProcAddress("vgCreateEGLImageTargetKHR"));
sl@0
   733
	if (!eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateImageTargetKHR)
sl@0
   734
		{
sl@0
   735
		ERR_PRINTF1(_L("Failed to get EGL Image extension functions."));
sl@0
   736
		User::Leave(KErrNotSupported);
sl@0
   737
		}
sl@0
   738
	// Now we have an OpenVG window to render to!
sl@0
   739
	
sl@0
   740
	TInt numGlyphCodes = 0;
sl@0
   741
	TUint* glyphCodes;
sl@0
   742
	LoadConfigSampleDataL(font, KTestLanguage, EFalse, glyphCodes, numGlyphCodes); 
sl@0
   743
sl@0
   744
	// Set up an identity matrix compatible with the Symbian co-ordinate system.
sl@0
   745
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
sl@0
   746
	vgScale(1.f, -1.f);
sl@0
   747
	vgTranslate(0, -KFontHeightInPixels);	
sl@0
   748
	VGfloat vgIdentityMatrix[16];
sl@0
   749
	vgGetMatrix(vgIdentityMatrix);
sl@0
   750
	
sl@0
   751
	RFbsGlyphDataIterator iter;
sl@0
   752
	CleanupClosePushL(iter);
sl@0
   753
		
sl@0
   754
	// Render some glyphs.
sl@0
   755
	TInt iterErr = KErrNone;
sl@0
   756
	TInt rep = 0;
sl@0
   757
	vgClear(0, 0, KEglTargetSize.iWidth, KEglTargetSize.iHeight);
sl@0
   758
	TPoint glyphOrigin(0, 0);
sl@0
   759
	iProfiler->InitResults();
sl@0
   760
	for (rep = 0; rep < KNumIterations; rep++)
sl@0
   761
		{
sl@0
   762
		iterErr = iter.Open(*font, glyphCodes, numGlyphCodes);
sl@0
   763
		for (;iterErr == KErrNone; iterErr = iter.Next())
sl@0
   764
			{
sl@0
   765
			const TOpenFontCharMetrics& metrics = iter.Metrics();
sl@0
   766
			const RSgImage& glyphSgImage = iter.Image();
sl@0
   767
			EGLImageKHR eglImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, 
sl@0
   768
					reinterpret_cast<EGLClientBuffer>(&glyphSgImage), imageAttribs);
sl@0
   769
			VGImage vgImage = vgCreateImageTargetKHR(eglImage);
sl@0
   770
			
sl@0
   771
			// wrapped text placement.			
sl@0
   772
			TInt horizAdvance = metrics.HorizAdvance();
sl@0
   773
			if (glyphOrigin.iX + horizAdvance >= KEglTargetSize.iWidth)
sl@0
   774
				{
sl@0
   775
				vgLoadMatrix(vgIdentityMatrix);
sl@0
   776
				glyphOrigin.iX = 0;
sl@0
   777
				glyphOrigin.iY -= KFontHeightInPixels;
sl@0
   778
				if (glyphOrigin.iY - KFontHeightInPixels < -KEglTargetSize.iHeight)
sl@0
   779
					{
sl@0
   780
					glyphOrigin.iY = 0;
sl@0
   781
					}
sl@0
   782
				vgTranslate(glyphOrigin.iX, glyphOrigin.iY);
sl@0
   783
				}
sl@0
   784
			
sl@0
   785
			vgDrawImage(vgImage);
sl@0
   786
			vgDestroyImage(vgImage);
sl@0
   787
			eglDestroyImageKHR(display, eglImage);
sl@0
   788
				
sl@0
   789
			// Move to next glyph position.
sl@0
   790
			glyphOrigin.iX += horizAdvance;
sl@0
   791
			vgTranslate(horizAdvance, 0);
sl@0
   792
			}
sl@0
   793
		iter.Close();
sl@0
   794
		eglSwapBuffers(display, surface);
sl@0
   795
		}
sl@0
   796
	iProfiler->MarkResultSetL();
sl@0
   797
	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, KNumIterations, numGlyphCodes);
sl@0
   798
	TEST(rep == KNumIterations);
sl@0
   799
	TESTE(iterErr == KErrNotFound, iterErr);	
sl@0
   800
	WriteTargetOutput(KTestName());
sl@0
   801
	
sl@0
   802
	eglDestroySurface(display, surface);
sl@0
   803
	eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
sl@0
   804
	eglTerminate(display);
sl@0
   805
	eglReleaseThread();
sl@0
   806
	
sl@0
   807
	CleanupStack::PopAndDestroy(3); // iter, target, fontFactory
sl@0
   808
	delete [] glyphCodes;
sl@0
   809
	}
sl@0
   810
#endif
sl@0
   811
sl@0
   812
/**
sl@0
   813
Captures the EGL Surface (it is assumed to be an OpenVG surface) to a 256-grey CFbsBitmap,
sl@0
   814
used when sanity-checking bitmaps are enabled. 
sl@0
   815
*/
sl@0
   816
CFbsBitmap* CTFbsGlyphData::GetTargetAsBitmapL()
sl@0
   817
	{
sl@0
   818
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
sl@0
   819
	// For debugging purposes only.
sl@0
   820
	// Capture the final state of the EGL Pixmap surface as an mbm.
sl@0
   821
	const TInt KDataStride = KEglTargetSize.iWidth;
sl@0
   822
sl@0
   823
	TUint8* imageScanline = reinterpret_cast<TUint8*>(User::AllocZL(KDataStride));
sl@0
   824
	CleanupStack::PushL(imageScanline);
sl@0
   825
	CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
sl@0
   826
	CleanupStack::PushL(bitmap);
sl@0
   827
	User::LeaveIfError(bitmap->Create(KEglTargetSize, EGray256));
sl@0
   828
	bitmap->BeginDataAccess();
sl@0
   829
	TUint8* dataAddress = reinterpret_cast<TUint8*>(bitmap->DataAddress());
sl@0
   830
	const TInt dataStride = bitmap->DataStride();	
sl@0
   831
	for (TInt scanline = 0; scanline < KEglTargetSize.iHeight; scanline++)
sl@0
   832
		{
sl@0
   833
	    vgReadPixels(imageScanline, KDataStride, VG_A_8, 0, scanline, KEglTargetSize.iWidth, 1);
sl@0
   834
		Mem::Copy(dataAddress, imageScanline, KEglTargetSize.iWidth);
sl@0
   835
		dataAddress += dataStride;
sl@0
   836
		}
sl@0
   837
	bitmap->EndDataAccess(EFalse);
sl@0
   838
	CleanupStack::Pop(2); // bitmap, imageScanline
sl@0
   839
	return bitmap;
sl@0
   840
#else
sl@0
   841
	return NULL;
sl@0
   842
#endif
sl@0
   843
	}
sl@0
   844
sl@0
   845
/**
sl@0
   846
Utility method. Loads sample glyph code data from the config ini file
sl@0
   847
into a TUint array.
sl@0
   848
@param aFont The font that the glyph codes will be associated with.
sl@0
   849
@param aLanguage The language variant to load from the config file as sample data.
sl@0
   850
@param aLongData Whether to use the long variant (ETrue) or short variant (EFalse) 
sl@0
   851
    of the sample data for the given language.
sl@0
   852
@param aGlyphCodes On success, holds an array of glyph codes, to be freed by the caller.
sl@0
   853
@param aNumGlyphCodes On success, holds the count of the glyph code array.
sl@0
   854
@leave KErrNotFound if the test data cannot be found or is empty in the config file.
sl@0
   855
 */
sl@0
   856
void CTFbsGlyphData::LoadConfigSampleDataL(CFbsFont* aFont, TTestLanguage aLanguage, TBool aLongData, TUint*& aGlyphCodes, TInt& aNumGlyphCodes)
sl@0
   857
	{
sl@0
   858
	// The name of the section in the config file to look-up the sample data
sl@0
   859
	_LIT(KConfigFileSampleData, "GlyphDataSampleText");
sl@0
   860
sl@0
   861
	TBuf<32> keyName = ConfigKeyNameL(aLanguage, aLongData);
sl@0
   862
	
sl@0
   863
	// Setup the converter to use the passed font.
sl@0
   864
	iCharCodeConverter->UseFontL(aFont);
sl@0
   865
sl@0
   866
	// Load the sample string data from the config file.
sl@0
   867
	TPtrC sampleText;
sl@0
   868
	TESTL(GetStringFromConfig(KConfigFileSampleData, keyName, sampleText));
sl@0
   869
	aNumGlyphCodes = sampleText.Length();
sl@0
   870
	if (aNumGlyphCodes <= 0)
sl@0
   871
		{
sl@0
   872
		User::Leave(KErrNotFound);
sl@0
   873
		}
sl@0
   874
	aGlyphCodes = new(ELeave) TUint[aNumGlyphCodes];
sl@0
   875
	for (TInt code = 0; code < aNumGlyphCodes; ++code)
sl@0
   876
		{
sl@0
   877
		aGlyphCodes[code] = iCharCodeConverter->GlyphCodeL(sampleText[code]); 
sl@0
   878
		}
sl@0
   879
	}
sl@0
   880
sl@0
   881
/**
sl@0
   882
Creates the name of the key to look for in the config file for the test
sl@0
   883
with the specified parameters.
sl@0
   884
@param aLanguage The language the test will use.
sl@0
   885
@param aLongData Whether to use long or short sample data.
sl@0
   886
@return A descriptor value of the language.
sl@0
   887
@leave KErrNotSupported if aLanguage is not recognised.
sl@0
   888
 */
sl@0
   889
TBufC<32> CTFbsGlyphData::ConfigKeyNameL(TTestLanguage aLanguage, TBool aLongData)
sl@0
   890
	{
sl@0
   891
	if (aLanguage < 0 || aLanguage > 1)
sl@0
   892
		{
sl@0
   893
		User::Leave(KErrNotSupported);
sl@0
   894
		}
sl@0
   895
	TBuf<32> langName[2];
sl@0
   896
	langName[ETestLanguageLatin].Append(_L("Latin"));
sl@0
   897
	langName[ETestLanguageHindi].Append(_L("Hindi"));	
sl@0
   898
	langName[aLanguage].Append((aLongData) ? _L("Long") : _L("Short"));
sl@0
   899
	return langName[aLanguage];
sl@0
   900
	}
sl@0
   901
sl@0
   902
/**
sl@0
   903
Font factory.
sl@0
   904
Utiltiy class for providing fonts for the performance tests.
sl@0
   905
*/
sl@0
   906
sl@0
   907
CTFontFactory::CTFontFactory()
sl@0
   908
	{
sl@0
   909
	}
sl@0
   910
sl@0
   911
CTFontFactory::~CTFontFactory()
sl@0
   912
	{
sl@0
   913
	ReleaseFonts();
sl@0
   914
	delete iTs;
sl@0
   915
	}
sl@0
   916
sl@0
   917
/**
sl@0
   918
@return A new Font Factory ready to create fonts.
sl@0
   919
*/
sl@0
   920
CTFontFactory* CTFontFactory::NewLC()
sl@0
   921
	{
sl@0
   922
	CTFontFactory* fontFactory = new (ELeave) CTFontFactory();
sl@0
   923
	CleanupStack::PushL(fontFactory);
sl@0
   924
	fontFactory->iTs = static_cast<CFbsTypefaceStore*>(CFbsTypefaceStore::NewL(NULL));
sl@0
   925
	return fontFactory;
sl@0
   926
	}
sl@0
   927
sl@0
   928
/**
sl@0
   929
Creates a number of fonts for use by tests. All the fonts are created up-front so 
sl@0
   930
that NextFont() can be called as a very lightweight call, so it can be used inside
sl@0
   931
tests with minimal impact.
sl@0
   932
Once fonts are created, the factory must not be destroyed until the fonts it created
sl@0
   933
are finished with.
sl@0
   934
@param aLanaugeMask Which language needs to be supported by the returned fonts.
sl@0
   935
@param aNumFonts The number of fonts to create
sl@0
   936
@param aStartSizeInPixels The lower bound font height of the fonts that are created. All
sl@0
   937
	fonts will be at least as big as this value.
sl@0
   938
*/
sl@0
   939
void CTFontFactory::CreateFontsL(TTestLanguage aLanguageMask, TInt aNumFonts, TInt aStartSizeInPixels)
sl@0
   940
	{
sl@0
   941
	ReleaseFonts();
sl@0
   942
	
sl@0
   943
	RArray <TPtrC> typefaceNames;
sl@0
   944
	CleanupClosePushL(typefaceNames);
sl@0
   945
	switch(aLanguageMask)
sl@0
   946
		{
sl@0
   947
		case ETestLanguageHindi:	
sl@0
   948
			User::LeaveIfError(typefaceNames.Reserve(1));
sl@0
   949
			typefaceNames.Append(_L("Devanagari OT Eval"));
sl@0
   950
			break;
sl@0
   951
		case ETestLanguageLatin:
sl@0
   952
			User::LeaveIfError(typefaceNames.Reserve(3));
sl@0
   953
			typefaceNames.Append(_L("DejaVu Sans Condensed"));
sl@0
   954
			typefaceNames.Append(_L("DejaVu Serif"));
sl@0
   955
			typefaceNames.Append(_L("DejaVu Sans Mono"));
sl@0
   956
			break;
sl@0
   957
		default:
sl@0
   958
			User::Leave(KErrNotSupported);
sl@0
   959
		}
sl@0
   960
	const TInt KNumTypefaces = typefaceNames.Count();
sl@0
   961
		
sl@0
   962
	iFont = new CFbsFont*[aNumFonts];
sl@0
   963
	for (TInt count = 0; count < aNumFonts; ++count)
sl@0
   964
		{
sl@0
   965
		// After every KNumTypefaces font, increase size by 5.
sl@0
   966
		TInt size = aStartSizeInPixels + (5 *(count / KNumTypefaces));
sl@0
   967
		TPtrC typefaceName = typefaceNames[count % KNumTypefaces];
sl@0
   968
		TFontSpec fontSpec(typefaceName, size);
sl@0
   969
		User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont[count], fontSpec));
sl@0
   970
		++iNumFonts;
sl@0
   971
		}
sl@0
   972
	iCurFont = -1;
sl@0
   973
	CleanupStack::PopAndDestroy(1); // typefaceNames
sl@0
   974
	}
sl@0
   975
/**
sl@0
   976
Releases all created fonts and frees associated memory.
sl@0
   977
*/
sl@0
   978
void CTFontFactory::ReleaseFonts()
sl@0
   979
	{
sl@0
   980
	for (TInt font = 0; font < iNumFonts; ++font)
sl@0
   981
		{
sl@0
   982
		iTs->ReleaseFont(iFont[font]);
sl@0
   983
		}
sl@0
   984
	delete [] iFont;
sl@0
   985
	iFont = NULL;
sl@0
   986
	iNumFonts = 0;
sl@0
   987
	}
sl@0
   988
sl@0
   989
/**
sl@0
   990
@return The next font to be used. If it reaches the last font, the next font will
sl@0
   991
	cycle back around to the first font.
sl@0
   992
*/
sl@0
   993
CFbsFont* CTFontFactory::NextFont()
sl@0
   994
	{
sl@0
   995
	return iFont[++iCurFont%iNumFonts];
sl@0
   996
	}