First public contribution.
1 // Copyright (c) 2009-2010 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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
13 // Description: Test the operation of the Font and Bitmap Server's GOoM plug-in
22 const TInt KTFbsOogmFrameworkPause = 500000; // How long does this need to be in order to be reliable?
23 const TInt KTFbsOogmImageSizeX = 2048;
24 const TInt KTFbsOogmImageSizeY = 2048;
27 void CTFbsOogm::RunTestCaseL( TInt aCurTestCase )
29 ( (CTFbsOogmStep*)iStep )->SetTestStepID( KUnknownSYMTestCaseIDName );
31 switch( aCurTestCase )
34 ( (CTFbsOogmStep*)iStep )->SetTestStepID( _L("GRAPHICS-FBSERV-0675") );
36 CacheClearanceAndLimitAdjustments();
40 ( (CTFbsOogmStep*)iStep )->SetTestStepID( KNotATestSYMTestCaseIDName );
41 ( (CTFbsOogmStep*)iStep )->CloseTMSGraphicsStep();
47 ( (CTFbsOogmStep*)iStep )->RecordTestResultL();
58 Tests the operation of Font and Bitmap server's Out-Of-Graphics-Memory plugin.
59 ie Ensure that the hardware glyph cache is cleared in response to a low graphics
60 memory notification, and that the cache's maximum size limit is reduced.
64 Acquire the glyph cache's usage and other metrics.
66 Populate the glyph-cache.
68 Acquire the glyph-cache's usage and other metrics.
70 Precipitate an Out-of-Graphics-Memory condition, triggering the GOOM monitor.
72 Acquire the glyph cache's usage and other metrics.
74 Ensure the glyph-cache has been cleared and its maximum limit reduced.
76 Precipitate a MemoryGood() call from the GOoM framework.
78 Establish that the cache-size limit has been reinstated.
80 @SYMTestExpectedResults
81 The glyph-cache should be cleared in response to OoGM condition and its upper limit reduced.
83 The Glyph-cache's upper limit should be reinstated in response to a memory-good notification.
85 void CTFbsOogm::CacheClearanceAndLimitAdjustments()
89 RArray <RSgImage> sgImageArray;
91 TInt err = sgDriver.Open();
95 TEST( KErrNone == err );
96 INFO_PRINTF2( _L("SgDriver Open() returned error %d"), err );
101 if( (NULL == RFbsSession::GetSession()) )
103 if( KErrNone != RFbsSession::Connect() )
106 INFO_PRINTF1(_L("Failed to connect to FbServ"));
113 // Establish the initial condition of the glyph-cache.
114 TGlyphCacheMetrics initialGlyphCacheMetrics;
115 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( initialGlyphCacheMetrics );
116 if( KErrNone != err )
118 TEST( KErrNone == err );
119 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned error %d"), err );
124 // Check that initial conditions are as expected.
125 // There was a test here for a cache-size of zero, but this was felt to be a hazardous assumption.
126 TEST( initialGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
127 INFO_PRINTF4( _L("Initial iMaxCacheSizeInBytes %d iCacheSizeInBytes %d iGpuCacheSizeLimitIsMax %d "),
128 initialGlyphCacheMetrics.iMaxCacheSizeInBytes,
129 initialGlyphCacheMetrics.iCacheSizeInBytes,
130 initialGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
133 TRAP( err, UseGpuL() ); // Populate the glyph cache then acquire its usage metrics.
134 if( KErrNone != err )
136 TEST( KErrNone == err );
137 INFO_PRINTF2( _L("UseGpuL() left with %d"), err );
143 TGlyphCacheMetrics usageGlyphCacheMetrics;
144 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( usageGlyphCacheMetrics );
145 if( KErrNone != err )
147 TEST( KErrNone == err );
148 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned %d"), err );
153 // Check that the glyph cache has been populated
154 TEST( usageGlyphCacheMetrics.iCacheSizeInBytes > initialGlyphCacheMetrics.iCacheSizeInBytes);
155 TEST( usageGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
156 INFO_PRINTF4( _L("Usage iMaxCacheSizeInBytes %d iCacheSizeInBytes %d iGpuCacheSizeLimitIsMax %d "),
157 usageGlyphCacheMetrics.iMaxCacheSizeInBytes,
158 usageGlyphCacheMetrics.iCacheSizeInBytes,
159 usageGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
163 // Precipitate the GOoM framework's call into the Plug-in's FreeRam() method.
164 err = FillGraphicsMemoryWithImages( TSize(KTFbsOogmImageSizeX, KTFbsOogmImageSizeY), sgImageArray );
165 if( KErrNoGraphicsMemory != err )
167 TEST( KErrNoGraphicsMemory == err );
168 INFO_PRINTF2( _L("FillGraphicsMemoryWithImages() returned %d"), err );
173 // Await the GOOM framework's call into FbServ's OoGM plugin,
174 // then establish the cache's usage and other metrics.
175 User::After( KTFbsOogmFrameworkPause );
176 TGlyphCacheMetrics postOogmGlyphCacheMetrics;
177 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( postOogmGlyphCacheMetrics );
179 if( KErrNone != err )
181 TEST( KErrNone == err );
182 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned %d"), err );
187 // The cache should have been cleared and the maximum size limit reduced.
188 TEST( 0 == postOogmGlyphCacheMetrics.iCacheSizeInBytes );
189 TEST( !postOogmGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
190 INFO_PRINTF4( _L("Post-Oogm iMaxCacheSizeInBytes %d iCacheSizeInBytes %d iGpuCacheSizeLimitIsMax %d "),
191 postOogmGlyphCacheMetrics.iMaxCacheSizeInBytes,
192 postOogmGlyphCacheMetrics.iCacheSizeInBytes,
193 postOogmGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
197 // Remove the images. This should provoke a GOoM monitor call into the plug-in's MemoryGood().
198 for ( TInt i = sgImageArray.Count()-1; i >= 0; --i )
200 sgImageArray[i].Close();
202 sgImageArray.Reset();
204 // Await activity from the GOoM monitor
205 User::After( KTFbsOogmFrameworkPause );
206 TGlyphCacheMetrics reinstatedGlyphCacheMetrics;
207 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( reinstatedGlyphCacheMetrics );
208 if( KErrNone != err )
210 TEST( KErrNone == err );
211 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned error %d"), err );
216 // Cache size limit should have been increased
217 TEST( reinstatedGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
218 INFO_PRINTF4( _L("After Mem Clear iMaxCacheSizeInBytes %d iCacheSizeInBytes %d iGpuCacheSizeLimitIsMax %d "),
219 reinstatedGlyphCacheMetrics.iMaxCacheSizeInBytes,
220 reinstatedGlyphCacheMetrics.iCacheSizeInBytes,
221 reinstatedGlyphCacheMetrics.iGpuCacheSizeLimitIsMax );
226 // Release any images before closing the array.
227 // If the test was successful this should already be empty.
228 for (TInt i = sgImageArray.Count()-1; i >= 0; --i)
230 sgImageArray[i].Close();
233 // Allow GOoM to make any pending adjustments before proceeding with any further tests.
234 User::After( KTFbsOogmFrameworkPause );
235 sgImageArray.Close();
243 CTFbsOogm::CTFbsOogm( CTestStep* aStep )
244 : CTGraphicsBase(aStep)
250 const TInt KNumGlyphCodesLatin = 96;
252 Lookup table to convert from ascii code to
253 glyph code for the Deja Vu family of fonts.
255 const TUint DejaVuASCIIToGlyphCode[] =
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 3, 4, 5, 6, 7, 8, 9, 10,
261 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
262 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
263 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
264 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
265 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
266 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
267 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
268 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
269 91, 92, 93, 94, 95, 96, 97, 98,
274 void CTFbsOogm::ConstructL()
279 CTFbsOogm::~CTFbsOogm()
281 RFbsSession::Disconnect();
287 Utility function to fill the GPU memory.
289 TInt CTFbsOogm::FillGraphicsMemoryWithImages( const TSize& aSize, RArray<RSgImage>& aImages )
293 // Loop should terminate with KErrNoGraphicsMemory
294 while( KErrNone == err )
297 err = sgImage.Create( TSgImageInfo(aSize, ESgPixelFormatA_8, ESgUsageBitOpenVgImage) );
298 if( KErrNone == err )
300 err = aImages.Append( sgImage );
304 INFO_PRINTF2( _L("Images created %d"), aImages.Count() );
311 Utility function to populate the GPU with typeface glyphs.
313 void CTFbsOogm::UseGpuL()
315 _LIT( KTKASTypefaceName, "DejaVu Sans Condensed" );
317 // Need to open one of these "in the context" of this process in order
318 // to manipulate RSgImages. Even though we are only calling 'Open', 'Next' and 'Close' on
319 // RFbsGlyphDataIterator
321 User::LeaveIfError( sgDriver.Open() );
323 // CFbsTypefaceStore seems to need an fbserv session open.
324 if( (NULL == RFbsSession::GetSession()) )
326 User::LeaveIfError( RFbsSession::Connect() );
329 TUint* glyphCodesLatin = new(ELeave) TUint[ KNumGlyphCodesLatin ];
331 for ( TInt ii = 0; ii < KNumGlyphCodesLatin; ++ii )
333 TUint asciiCode = ii+0x20; // ASCII characters from 0020 to 007F
334 glyphCodesLatin[ii] = DejaVuASCIIToGlyphCode[asciiCode];
337 iTs = ( CFbsTypefaceStore* )CFbsTypefaceStore::NewL( NULL );
338 User::LeaveIfError( iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont, TFontSpec(KTKASTypefaceName, 15)) );
340 TInt iterErr = KErrNone;
341 TInt iterNextErr = KErrNone;
343 for( TInt arraySize = 1; (arraySize < KNumGlyphCodesLatin) && (iterErr == KErrNone); ++arraySize )
345 RFbsGlyphDataIterator iter;
346 iterErr = iter.Open( *iFont, glyphCodesLatin, arraySize );
348 if( KErrNone != iterErr )
353 for ( TInt index = 0; KErrNone == iterNextErr; iterNextErr = iter.Next(), ++index )
355 // Iterating through the glyphs should introduce them into the cache
356 if(iter.GlyphCode() != glyphCodesLatin[index])
358 INFO_PRINTF4( _L("Wanted glyphcode %d, got %d"), arraySize, glyphCodesLatin[index], iter.GlyphCode() );
362 iterNextErr = KErrNone;
370 __CONSTRUCT_STEP__( FbsOogm )