|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: Test the operation of the Font and Bitmap Server's GOoM plug-in |
|
14 // |
|
15 |
|
16 |
|
17 #include <gdi.h> |
|
18 #include "tfbsoogm.h" |
|
19 |
|
20 |
|
21 |
|
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; |
|
25 |
|
26 |
|
27 void CTFbsOogm::RunTestCaseL( TInt aCurTestCase ) |
|
28 { |
|
29 ( (CTFbsOogmStep*)iStep )->SetTestStepID( KUnknownSYMTestCaseIDName ); |
|
30 |
|
31 switch( aCurTestCase ) |
|
32 { |
|
33 case 1: |
|
34 ( (CTFbsOogmStep*)iStep )->SetTestStepID( _L("GRAPHICS-FBSERV-0675") ); |
|
35 |
|
36 CacheClearanceAndLimitAdjustments(); |
|
37 break; |
|
38 |
|
39 default: |
|
40 ( (CTFbsOogmStep*)iStep )->SetTestStepID( KNotATestSYMTestCaseIDName ); |
|
41 ( (CTFbsOogmStep*)iStep )->CloseTMSGraphicsStep(); |
|
42 TestComplete(); |
|
43 |
|
44 break; |
|
45 } |
|
46 |
|
47 ( (CTFbsOogmStep*)iStep )->RecordTestResultL(); |
|
48 |
|
49 } |
|
50 |
|
51 |
|
52 |
|
53 /** |
|
54 @SYMTestCaseID |
|
55 GRAPHICS-FBSERV-0675 |
|
56 |
|
57 @SYMTestCaseDesc |
|
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. |
|
61 |
|
62 |
|
63 @SYMTestActions |
|
64 Acquire the glyph cache's usage and other metrics. |
|
65 |
|
66 Populate the glyph-cache. |
|
67 |
|
68 Acquire the glyph-cache's usage and other metrics. |
|
69 |
|
70 Precipitate an Out-of-Graphics-Memory condition, triggering the GOOM monitor. |
|
71 |
|
72 Acquire the glyph cache's usage and other metrics. |
|
73 |
|
74 Ensure the glyph-cache has been cleared and its maximum limit reduced. |
|
75 |
|
76 Precipitate a MemoryGood() call from the GOoM framework. |
|
77 |
|
78 Establish that the cache-size limit has been reinstated. |
|
79 |
|
80 @SYMTestExpectedResults |
|
81 The glyph-cache should be cleared in response to OoGM condition and its upper limit reduced. |
|
82 |
|
83 The Glyph-cache's upper limit should be reinstated in response to a memory-good notification. |
|
84 */ |
|
85 void CTFbsOogm::CacheClearanceAndLimitAdjustments() |
|
86 { |
|
87 __UHEAP_MARK; |
|
88 |
|
89 RArray <RSgImage> sgImageArray; |
|
90 RSgDriver sgDriver; |
|
91 TInt err = sgDriver.Open(); |
|
92 |
|
93 if( KErrNone != err ) |
|
94 { |
|
95 TEST( KErrNone == err ); |
|
96 INFO_PRINTF2( _L("SgDriver Open() returned error %d"), err ); |
|
97 |
|
98 return; |
|
99 } |
|
100 |
|
101 if( (NULL == RFbsSession::GetSession()) ) |
|
102 { |
|
103 if( KErrNone != RFbsSession::Connect() ) |
|
104 { |
|
105 TEST( -1 ); |
|
106 INFO_PRINTF1(_L("Failed to connect to FbServ")); |
|
107 |
|
108 goto CleanupAndGo; |
|
109 } |
|
110 } |
|
111 |
|
112 |
|
113 // Establish the initial condition of the glyph-cache. |
|
114 TGlyphCacheMetrics initialGlyphCacheMetrics; |
|
115 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( initialGlyphCacheMetrics ); |
|
116 if( KErrNone != err ) |
|
117 { |
|
118 TEST( KErrNone == err ); |
|
119 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned error %d"), err ); |
|
120 |
|
121 goto CleanupAndGo; |
|
122 } |
|
123 |
|
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 ); |
|
131 |
|
132 |
|
133 TRAP( err, UseGpuL() ); // Populate the glyph cache then acquire its usage metrics. |
|
134 if( KErrNone != err ) |
|
135 { |
|
136 TEST( KErrNone == err ); |
|
137 INFO_PRINTF2( _L("UseGpuL() left with %d"), err ); |
|
138 |
|
139 goto CleanupAndGo; |
|
140 } |
|
141 |
|
142 |
|
143 TGlyphCacheMetrics usageGlyphCacheMetrics; |
|
144 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( usageGlyphCacheMetrics ); |
|
145 if( KErrNone != err ) |
|
146 { |
|
147 TEST( KErrNone == err ); |
|
148 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned %d"), err ); |
|
149 |
|
150 goto CleanupAndGo; |
|
151 } |
|
152 |
|
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 ); |
|
160 |
|
161 |
|
162 |
|
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 ) |
|
166 { |
|
167 TEST( KErrNoGraphicsMemory == err ); |
|
168 INFO_PRINTF2( _L("FillGraphicsMemoryWithImages() returned %d"), err ); |
|
169 |
|
170 goto CleanupAndGo; |
|
171 } |
|
172 |
|
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 ); |
|
178 |
|
179 if( KErrNone != err ) |
|
180 { |
|
181 TEST( KErrNone == err ); |
|
182 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned %d"), err ); |
|
183 |
|
184 goto CleanupAndGo; |
|
185 } |
|
186 |
|
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 ); |
|
194 |
|
195 |
|
196 |
|
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 ) |
|
199 { |
|
200 sgImageArray[i].Close(); |
|
201 } |
|
202 sgImageArray.Reset(); |
|
203 |
|
204 // Await activity from the GOoM monitor |
|
205 User::After( KTFbsOogmFrameworkPause ); |
|
206 TGlyphCacheMetrics reinstatedGlyphCacheMetrics; |
|
207 err = RFbsSession::GetSession()->GetGlyphCacheMetrics( reinstatedGlyphCacheMetrics ); |
|
208 if( KErrNone != err ) |
|
209 { |
|
210 TEST( KErrNone == err ); |
|
211 INFO_PRINTF2( _L("GetGlyphCacheMetrics() returned error %d"), err ); |
|
212 |
|
213 goto CleanupAndGo; |
|
214 } |
|
215 |
|
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 ); |
|
222 |
|
223 |
|
224 |
|
225 CleanupAndGo: |
|
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) |
|
229 { |
|
230 sgImageArray[i].Close(); |
|
231 } |
|
232 |
|
233 // Allow GOoM to make any pending adjustments before proceeding with any further tests. |
|
234 User::After( KTFbsOogmFrameworkPause ); |
|
235 sgImageArray.Close(); |
|
236 sgDriver.Close(); |
|
237 |
|
238 __UHEAP_MARKEND; |
|
239 } |
|
240 |
|
241 |
|
242 |
|
243 CTFbsOogm::CTFbsOogm( CTestStep* aStep ) |
|
244 : CTGraphicsBase(aStep) |
|
245 { |
|
246 } |
|
247 |
|
248 |
|
249 |
|
250 const TInt KNumGlyphCodesLatin = 96; |
|
251 /* |
|
252 Lookup table to convert from ascii code to |
|
253 glyph code for the Deja Vu family of fonts. |
|
254 */ |
|
255 const TUint DejaVuASCIIToGlyphCode[] = |
|
256 { |
|
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, |
|
270 }; |
|
271 |
|
272 |
|
273 |
|
274 void CTFbsOogm::ConstructL() |
|
275 { |
|
276 } |
|
277 |
|
278 |
|
279 CTFbsOogm::~CTFbsOogm() |
|
280 { |
|
281 RFbsSession::Disconnect(); |
|
282 } |
|
283 |
|
284 |
|
285 |
|
286 /** |
|
287 Utility function to fill the GPU memory. |
|
288 */ |
|
289 TInt CTFbsOogm::FillGraphicsMemoryWithImages( const TSize& aSize, RArray<RSgImage>& aImages ) |
|
290 { |
|
291 TInt err = KErrNone; |
|
292 |
|
293 // Loop should terminate with KErrNoGraphicsMemory |
|
294 while( KErrNone == err ) |
|
295 { |
|
296 RSgImage sgImage; |
|
297 err = sgImage.Create( TSgImageInfo(aSize, ESgPixelFormatA_8, ESgUsageBitOpenVgImage) ); |
|
298 if( KErrNone == err ) |
|
299 { |
|
300 err = aImages.Append( sgImage ); |
|
301 } |
|
302 } |
|
303 |
|
304 INFO_PRINTF2( _L("Images created %d"), aImages.Count() ); |
|
305 return err; |
|
306 } |
|
307 |
|
308 |
|
309 |
|
310 /** |
|
311 Utility function to populate the GPU with typeface glyphs. |
|
312 */ |
|
313 void CTFbsOogm::UseGpuL() |
|
314 { |
|
315 _LIT( KTKASTypefaceName, "DejaVu Sans Condensed" ); |
|
316 |
|
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 |
|
320 RSgDriver sgDriver; |
|
321 User::LeaveIfError( sgDriver.Open() ); |
|
322 |
|
323 // CFbsTypefaceStore seems to need an fbserv session open. |
|
324 if( (NULL == RFbsSession::GetSession()) ) |
|
325 { |
|
326 User::LeaveIfError( RFbsSession::Connect() ); |
|
327 } |
|
328 |
|
329 TUint* glyphCodesLatin = new(ELeave) TUint[ KNumGlyphCodesLatin ]; |
|
330 |
|
331 for ( TInt ii = 0; ii < KNumGlyphCodesLatin; ++ii ) |
|
332 { |
|
333 TUint asciiCode = ii+0x20; // ASCII characters from 0020 to 007F |
|
334 glyphCodesLatin[ii] = DejaVuASCIIToGlyphCode[asciiCode]; |
|
335 } |
|
336 |
|
337 iTs = ( CFbsTypefaceStore* )CFbsTypefaceStore::NewL( NULL ); |
|
338 User::LeaveIfError( iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont, TFontSpec(KTKASTypefaceName, 15)) ); |
|
339 |
|
340 TInt iterErr = KErrNone; |
|
341 TInt iterNextErr = KErrNone; |
|
342 |
|
343 for( TInt arraySize = 1; (arraySize < KNumGlyphCodesLatin) && (iterErr == KErrNone); ++arraySize ) |
|
344 { |
|
345 RFbsGlyphDataIterator iter; |
|
346 iterErr = iter.Open( *iFont, glyphCodesLatin, arraySize ); |
|
347 |
|
348 if( KErrNone != iterErr ) |
|
349 { |
|
350 continue; |
|
351 } |
|
352 |
|
353 for ( TInt index = 0; KErrNone == iterNextErr; iterNextErr = iter.Next(), ++index ) |
|
354 { |
|
355 // Iterating through the glyphs should introduce them into the cache |
|
356 if(iter.GlyphCode() != glyphCodesLatin[index]) |
|
357 { |
|
358 INFO_PRINTF4( _L("Wanted glyphcode %d, got %d"), arraySize, glyphCodesLatin[index], iter.GlyphCode() ); |
|
359 } |
|
360 } |
|
361 |
|
362 iterNextErr = KErrNone; |
|
363 iter.Close(); |
|
364 } |
|
365 |
|
366 sgDriver.Close(); |
|
367 } |
|
368 |
|
369 |
|
370 __CONSTRUCT_STEP__( FbsOogm ) |