fbs/fontandbitmapserver/tfbs/tfbsoogm.cpp
branchRCL_3
changeset 163 bbf46f59e123
equal deleted inserted replaced
150:57c618273d5c 163:bbf46f59e123
       
     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 )