os/graphics/egl/egltest/src/egltest_oom_sgimage.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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:
    14 //
    15 
    16 /**
    17  @file
    18  @test
    19 */
    20 
    21 #include <test/tefunit.h> // for ASSERT macros
    22 #include <e32msgqueue.h>
    23 
    24 #include <test/egltestcommonprocess.h>
    25 #include <test/egltestcommonconversion.h>
    26 #include <test/egltestcommoninisettings.h>
    27 #include "egltest_oom_sgimage.h"
    28 
    29 
    30 _LIT(KOOMSection, "OOM");
    31 
    32 
    33 //Since we want to exhaust the memory it probably makes sense to use any 32bpp mode  
    34 //There is no need to put it into INI file
    35 const TUidPixelFormat KOOMPixelFormat = EUidPixelFormatARGB_8888; 
    36 
    37 // Deviation in per cent for test 0442 and 0443
    38 const TInt KOOMSgImageDeviation = 5; 
    39 
    40 
    41 CEglTest_OOM_Base::~CEglTest_OOM_Base()
    42     {
    43     CleanGraphicsResources();
    44     CleanAll();
    45     }
    46 
    47 TVerdict CEglTest_OOM_Base::doTestStepPreambleL()
    48     {
    49     TVerdict verdict = CEglTestStep::doTestStepPreambleL();
    50     //read all parameters from config
    51     CEglTestCommonIniSettings* iniParser = CEglTestCommonIniSettings::NewL();
    52     CleanupStack::PushL(iniParser);
    53     iNumIterations = iniParser->GetNumberOfIterations(KOOMSection);
    54     if(!iNumIterations)
    55         {
    56         ERR_PRINTF1(_L("The number iterations is not specified in INI file, the test will not be executed!"));
    57         User::Leave(KErrArgument);      
    58         }
    59     
    60     iImageSize = iniParser->GetImageSize(KOOMSection);
    61     if(iImageSize == TSize(0,0))
    62         {
    63         ERR_PRINTF1(_L("The image size whether is not specified in INI file or is TSize(0,0), the test will not be executed!"));
    64         User::Leave(KErrArgument);      
    65         }
    66     iPixelFormat = KOOMPixelFormat;
    67     
    68     iThresholdGPUUsedMemory = iniParser->GetThresholdGPUUsedMemory(KOOMSection);
    69     if(iThresholdGPUUsedMemory == 0)
    70         {
    71         ERR_PRINTF1(_L("Threshold GPU used memory whether is not specified in INI file or is 0, the test will not be executed!"));
    72         User::Leave(KErrArgument);      
    73         }
    74 
    75     iThresholdLastIteration = iniParser->GetThresholdLastIteration(KOOMSection);
    76     if(iThresholdLastIteration == 0)
    77         {
    78         ERR_PRINTF1(_L("Threshold last iteration whether is not specified in INI file or is 0, the test will not be executed!"));
    79         User::Leave(KErrArgument);      
    80         }
    81     
    82     CleanupStack::PopAndDestroy(iniParser);
    83 
    84     INFO_PRINTF4(_L("**** The test will be run in following configuration: number of iterations %d, image size (%d, %d)"), iNumIterations, iImageSize.iWidth, iImageSize.iHeight);
    85     INFO_PRINTF3(_L("**** Threshold GPU used memory %d, threshold last iteration %d"), iThresholdGPUUsedMemory, iThresholdLastIteration);
    86     
    87     PrintUsedPixelConfiguration();    
    88     return verdict;
    89     }
    90 
    91 TVerdict CEglTest_OOM_Base::doTestStepPostambleL()
    92     {
    93     //to keep heap checking happy we have to clean up before destructor 
    94     CleanGraphicsResources();
    95     return CEglTestStep::doTestStepPostambleL();
    96     }
    97 
    98 //receive last successful index from the client process
    99 void CEglTest_OOM_Base::ReceiveMessageFromClient(RMsgQueue<TEglStepMessageBuffer>& aMessageQueueClientProcParam) 
   100     {
   101     TEglStepMessageBuffer param;
   102     aMessageQueueClientProcParam.ReceiveBlocking(param);
   103     iLastIterationNumber = *(TInt*) (param.iBuf);
   104     }
   105 
   106 //send last successful index to the main process for analysis
   107 void CEglTest_OOM_Base::SendIndexToMainProcessL(TInt aIndex)
   108     {
   109     TEglStepMessageBuffer param;
   110     RMsgQueue<TEglStepMessageBuffer> messageQueueClientProcParam;
   111     CleanupClosePushL(messageQueueClientProcParam);
   112     User::LeaveIfError(messageQueueClientProcParam.Open(EProcSlotCustomClientParam, EOwnerProcess));
   113     *((TInt*)param.iBuf) = aIndex;
   114     messageQueueClientProcParam.SendBlocking(param);
   115     CleanupStack::PopAndDestroy(&messageQueueClientProcParam);
   116     }
   117 
   118 //clean Sg/Egl/Vg images allocated. Reset arrays for various deviation variables.
   119 void CEglTest_OOM_Base::CleanGraphicsResources()
   120     {
   121 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   122     while(iSurfaces.Count() > 0)
   123         {
   124         eglDestroySurface(iDisplay, iSurfaces[0]);
   125         iSurfaces.Remove(0);
   126         }
   127     iSurfaces.Reset();
   128 
   129     while(iVgImages.Count() > 0)
   130         {
   131         vgDestroyImage(iVgImages[0]);
   132         iVgImages.Remove(0);
   133         }
   134     iVgImages.Reset();
   135 
   136     while(iEglImages.Count() > 0)
   137         {
   138         iEglSess->DestroyEGLImage(iDisplay, iEglImages[0]);
   139         iEglImages.Remove(0);
   140         }
   141     iEglImages.Reset();
   142     
   143     while(iSgImages.Count() > 0)
   144         {
   145         iSgImages[0].Close();
   146         iSgImages.Remove(0);
   147         }
   148     iSgImages.Reset();
   149 
   150     iGPUUsedMemory.Reset();
   151     iLastIterations.Reset();
   152 #endif
   153     }
   154 
   155 //if an array is empty, it returns zero for both aMin and aMax
   156 void CEglTest_OOM_Base::GetMinMax(const RArray<TInt>& aArray, TInt& aMin, TInt& aMax) const
   157     {
   158     aMin = 0;
   159     aMax = 0;
   160     if(aArray.Count() == 0)
   161         return;
   162     aMax = aArray[0];
   163     aMin = aArray[0];
   164     for(TInt ii = 1; ii < aArray.Count(); ii++)
   165         {
   166         if(aMin > aArray[ii])
   167             {
   168             aMin = aArray[ii];
   169             }
   170         if(aMax < aArray[ii])
   171             {
   172             aMax = aArray[ii];
   173             }
   174         }
   175     }
   176 
   177 TInt CEglTest_OOM_Base::Deviation(const RArray<TInt>& aArray) const
   178     {
   179     TInt min = 0;
   180     TInt max = 0;
   181     
   182     GetMinMax(aArray, min, max);
   183     if(max == 0) 
   184         return 0; // to avoid division by zero
   185     return (max - min) / (((TReal)(min + max)) / 2) * 100;  
   186     }
   187 
   188 //Calculate and output deviation of various parameters. 
   189 //If the measurement for particular parameter doesn’t take place, for instance, 
   190 //due to absence of the extension, the output will be skipped. 
   191 void CEglTest_OOM_Base::CheckDeviation()
   192     {
   193     TInt res = KErrNone;
   194     
   195     if(iGPUUsedMemory.Count() > 0)
   196         {
   197         res = Deviation(iGPUUsedMemory);
   198         ASSERT_TRUE(iThresholdGPUUsedMemory >= res);
   199         INFO_PRINTF3(_L("GPU used memory deviation %d %%, threshold %d %%"), res, iThresholdGPUUsedMemory);
   200         }
   201     
   202     if(iLastIterations.Count() > 0)
   203         {
   204         res = Deviation(iLastIterations);
   205         ASSERT_TRUE(iThresholdLastIteration >= res);
   206         INFO_PRINTF3(_L("Last iteration deviation %d %%, threshold %d %%"), res, iThresholdLastIteration);
   207         }
   208     }
   209 
   210 void CEglTest_OOM_Base::RetrieveExtensionDataL()
   211     {
   212     PrintEglResourceProfilingInfoL();
   213     INFO_PRINTF2(_L("Nember iterations before the failure occurs, %d"), iLastIterationNumber);
   214     iLastIterations.Append(iLastIterationNumber);
   215     iLastIterationNumber = -1;
   216     }
   217 
   218 //Print GPU information provided be NOK_resource_profiling2 egl extension
   219 //Some data, like GPU usage, will be memorized for further comparison
   220 //This extension is optional and may not be present in the system
   221 void CEglTest_OOM_Base::PrintEglResourceProfilingInfoL()
   222     {
   223 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   224 #ifdef EGL_PROF_MEMORY_USAGE_THRESHOLD_NOK    
   225 
   226     GetDisplayL();
   227     CreateEglSessionL();
   228     iEglSess->InitializeL();    
   229     
   230     if(!iPFnEglQueryProfilingDataNOK)
   231         {
   232         iPFnEglQueryProfilingDataNOK = (PFNEGLQUERYPROFILINGDATANOKPROC) eglGetProcAddress("eglQueryProfilingDataNOK");
   233     
   234         if(!iPFnEglQueryProfilingDataNOK)
   235             {
   236             CleanAll();
   237             WARN_PRINTF1(_L("NOK_resource_profiling2 extension is not available"));
   238             return;
   239             }
   240         }
   241         
   242     EGLint data_count;
   243     // Find out how much profiling data is available 
   244     iPFnEglQueryProfilingDataNOK(iDisplay, 
   245                              EGL_PROF_QUERY_GLOBAL_BIT_NOK | 
   246                              EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK,
   247                              NULL,
   248                              0,
   249                              &data_count);
   250 
   251     // Allocate room for the profiling data
   252     EGLint* prof_data = (EGLint*)User::AllocL(data_count * sizeof(EGLint));
   253 
   254     CleanupStack::PushL(prof_data);
   255     
   256     // Retrieve the profiling data 
   257     iPFnEglQueryProfilingDataNOK(iDisplay, 
   258                              EGL_PROF_QUERY_GLOBAL_BIT_NOK | 
   259                              EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK,
   260                              prof_data,
   261                              data_count,
   262                              &data_count);
   263 
   264     // Iterate over the returned data 
   265     EGLint i = 0;
   266     while (i < data_count)
   267     {
   268         switch (prof_data[i++])
   269         {
   270         case EGL_PROF_TOTAL_MEMORY_NOK:
   271             INFO_PRINTF2(_L("Total memory: %d"), prof_data[i++]);
   272             break;
   273         case EGL_PROF_USED_MEMORY_NOK:
   274             iGPUUsedMemory.AppendL(prof_data[i]);
   275             INFO_PRINTF2(_L("Used memory: %d"), prof_data[i++]);
   276             break;
   277         case EGL_PROF_PROCESS_ID_NOK:    
   278             if(sizeof(EGLNativeProcessIdTypeNOK) == 4)
   279                 {
   280                 INFO_PRINTF2(_L("Process ID(4 bytes), 0x%08X"), prof_data[i++]);
   281                 }
   282             else if(sizeof(EGLNativeProcessIdTypeNOK) == 8)
   283                 {
   284                 EGLNativeProcessIdTypeNOK processId = ((EGLNativeProcessIdTypeNOK)(prof_data[i])) + (((EGLNativeProcessIdTypeNOK)(prof_data[i + 1]))<<32);
   285                 RProcess process;
   286                 TProcessId pid(processId);
   287                 TInt err = process.Open(pid);
   288                 if (err == KErrNone)
   289                     {
   290                     TPtrC ptr(process.FullName());
   291                     INFO_PRINTF4(_L("Process ID, %lu - 0x%lu - %S"), processId, processId, &ptr);
   292                     process.Close();
   293                     }
   294                 else
   295                     {//this parameter is not in use in the test, thus is no point to set an error.
   296                     WARN_PRINTF4(_L("Process ID, %lu - 0x%lx, fail to open process with error %d"), processId, processId, err);
   297                     }                    
   298                 i += 2;
   299                 }
   300             else
   301                 {//this parameter is for information only. It doesn't impact our measurement. So there is no need to set an error.
   302                 WARN_PRINTF1(_L("Unknown EGLNativeProcessIdTypeNOK"));
   303                 }
   304             break;
   305         case EGL_PROF_PROCESS_USED_PRIVATE_MEMORY_NOK:
   306             INFO_PRINTF2(_L("Process used private memory: %d"), prof_data[i++]);
   307             break;
   308         case EGL_PROF_PROCESS_USED_SHARED_MEMORY_NOK:
   309             INFO_PRINTF2(_L("Process used shared memory: %d"), prof_data[i++]);
   310             break;
   311         }
   312     }
   313 
   314     // Free allocated memory 
   315     CleanupStack::PopAndDestroy(prof_data);
   316     CleanAll();
   317     
   318 #endif //EGL_PROF_MEMORY_USAGE_THRESHOLD_NOK    
   319 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE   
   320     }
   321 
   322 /**
   323 @SYMTestCaseID GRAPHICS-EGL-0438
   324 
   325 @SYMTestPriority 1
   326 
   327 @SYMPREQ 2637
   328 
   329 @SYMTestCaseDesc
   330     OOM test – Free VG/Egl/Sg Images while the process which owns them is terminated
   331 
   332 @SYMTestActions
   333 Environmental settings:
   334 •   Image Size: w50 h50
   335 •   List of simulated load: 0%
   336 •   List of pixel formats
   337 ESgPixelFormatARGB_8888
   338 •   Client process priorities - all the same
   339 •   Client process random parameters:
   340 -   None
   341 
   342 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
   343 
   344     From the main process:
   345     For i = 0 to N
   346     Spawn 2 client processes A and B.
   347         Signal all client processes to start by use of a semaphore
   348         Wait until client processes exit
   349     If the test fails not due to the memory allocation record an error code to the log file then set a test result as a failure and skip further actions.
   350     End loop
   351     Exit
   352 
   353     From client process A:
   354     Get EGL display
   355     Initialize EGL
   356     Open RSgDriver
   357     Create context, pbuffer surface.
   358     Make pbuffer surface current for the given context  
   359     Loop until exit condition met
   360     Start loop:
   361 Create SgImage
   362 Create EglImage with underlying SgImage
   363     Create VgImage with underlying EglImage
   364     Exit condition – Sg/Egl/Vg image creation has failed.
   365 End loop:
   366     Destroy the pbuffer surface
   367 Log the last iteration number and exact operation which precedes a failure. 
   368 In the environment supporting NOK_resource_profiling2 extension retrieve for further analyzes the following GPU profiling data (if available):
   369 •   Total memory
   370 •   Used memory
   371 •   Process ID
   372 •   Process used private memory
   373 •   Process used shared memory
   374 
   375 Make the process busy by putting it into the indefinite loop.
   376     
   377     From client process B:
   378     Wait until process A fails with the image creation.
   379     Terminate the process A.
   380 
   381 @SYMTestExpectedResults
   382 For each step from 0 to N in the main process, 
   383 -   Image allocation failure must happen at approximately the same iteration in process A. 
   384     MaxIterationNumber – MinIterationNumber < Threashold, where Treashold will not 
   385     exceeds 5 and exact value to be defined during implementation. 
   386 -   GPU memory usage retrieved through NOK_resource_profiling2 extension, if available, 
   387     is consistent and doesn’t decrease over the time. 
   388     MaxGPUMemoryUsage – MinGPUMemoryUsage < Threshold, where Threshold will not exceed 
   389     5 and exact value to be defined during implementation. 
   390 */
   391 TVerdict CEglTest_OOM_CloseVGImageWithTermination::doTestStepL()
   392     {
   393     SetTestStepID(_L("GRAPHICS-EGL-0438"));
   394     SetTestStepName(KOOM_CloseVGImageWithTermination);
   395     INFO_PRINTF1(_L("CEglTest_Benchmark_Multi_Process_CreateCloseImage::doTestStepL"));
   396 
   397 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   398 	INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImageWithTermination can only be run with SgImage-Lite"));
   399 #else
   400     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
   401     if(ret)
   402         {
   403         // The extension is supported
   404         // if the test fails not due to the memory allocation, then skip further actions
   405         for(TInt index = 0; (index < iNumIterations) && (TestStepResult()== EPass); index++)
   406             {
   407             // launch 2 processes
   408             Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
   409             RetrieveExtensionDataL();
   410             }
   411         CheckDeviation();
   412         }
   413 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   414 
   415     RecordTestResultL();
   416     CloseTMSGraphicsStep();
   417     return TestStepResult();
   418     }
   419 
   420 void CEglTest_OOM_CloseVGImageWithTermination::doProcessFunctionL(TInt aIdx)
   421     {
   422     INFO_PRINTF2(_L("CEglTest_OOM_CloseVGImageWithTermination::doProcessFunctionL, Process %d"),aIdx);
   423 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   424 
   425     if(aIdx == 0)
   426         {
   427         GetDisplayL();
   428         CreateEglSessionL(aIdx);
   429         iEglSess->InitializeL();    
   430         iEglSess->OpenSgDriverL();
   431 
   432         //create a dummy surface and context for the purpose of enabling use of VG
   433         TEglTestConfig pbufferFormat = EglTestConversion::VgFormatToPBufferSurfaceFormat(EglTestConversion::PixelFormatToVgFormat(iPixelFormat));
   434         EGLConfig currentConfig = 0;
   435         TRAPD(res, currentConfig = iEglSess->GetConfigExactMatchL( pbufferFormat ));
   436         User::LeaveIfError(res);
   437         
   438         iEglSess->CreatePbufferSurfaceAndMakeCurrentL(currentConfig, iImageSize, EGL_OPENVG_API);
   439         TInt index = 0;
   440         TSgImageInfo imageInfo;
   441         imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
   442         imageInfo.iPixelFormat = iPixelFormat;
   443         imageInfo.iSizeInPixels = iImageSize;
   444         for(;;++index)
   445             {
   446             RSgImage sgImage;
   447             TInt res = sgImage.Create(imageInfo, NULL);
   448             if(res != KErrNone || sgImage.IsNull())
   449                 {
   450                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected %d or %d"), index, res, KErrNoMemory, KErrNoGraphicsMemory);
   451                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
   452                 break;
   453                 }
   454             EGLImageKHR eglImages = iEglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&sgImage,const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
   455             EGLint eglError = eglGetError();
   456             if((eglImages == EGL_NO_IMAGE_KHR) || (eglError != EGL_SUCCESS))
   457                 {
   458                 INFO_PRINTF4(_L("***Fail to create EGLImage after %d attempts, error: %d, expected: %d"), index, eglError, EGL_BAD_ALLOC);
   459                 ASSERT_TRUE(eglError == EGL_BAD_ALLOC);
   460                 break;
   461                 }
   462 
   463             VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages);
   464             VGErrorCode vgError = vgGetError();
   465             if(vgImage == VG_INVALID_HANDLE || (vgError != VG_NO_ERROR))
   466                 {
   467                 INFO_PRINTF4(_L("***Fail to create VGImage after %d attempts, error: %d, expected: %d"), index, vgError, VG_OUT_OF_MEMORY_ERROR);
   468                 ASSERT_TRUE(vgError == VG_OUT_OF_MEMORY_ERROR);
   469                 break;
   470                 }
   471             } //for
   472         SendIndexToMainProcessL(index);
   473         }
   474     Rendezvous(aIdx);
   475     
   476     //create the queue to send/receive Process ID between processes
   477     RMsgQueue<TProcessId> messageQueueProcId;
   478     User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess));
   479     CleanupClosePushL(messageQueueProcId);
   480     
   481     if(aIdx == 0)
   482         {
   483         // Sending Process ID to other process... so that the other process can kill it.
   484         TProcessId procId = RProcess().Id();
   485         messageQueueProcId.SendBlocking(procId);
   486         CleanupStack::PopAndDestroy(&messageQueueProcId);
   487         //go into indefinite loop which will be terminated by the second process
   488         for(;;) { }
   489         }
   490     else
   491         {
   492         TProcessId procId;
   493         messageQueueProcId.ReceiveBlocking(procId);
   494         CleanupStack::PopAndDestroy(&messageQueueProcId);
   495 
   496         RProcess process;
   497         ASSERT_TRUE(process.Open(procId) == KErrNone);
   498         process.Kill(KErrNone);
   499         process.Close();
   500         
   501         // small delay to ensure the kernel finishes the clean-up
   502         User::After(1*1000*1000); // 1 second
   503         }
   504 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   505     }
   506 
   507 /**
   508 @SYMTestCaseID GRAPHICS-EGL-0439
   509 
   510 @SYMTestPriority 1
   511 
   512 @SYMPREQ 2637
   513 
   514 @SYMTestCaseDesc
   515     OOM test – Free VG/Egl/Sg Images while the process which owns them exits gracefully
   516 
   517 @SYMTestActions
   518 Environmental settings:
   519 •   Image Size: w50 h50
   520 •   List of simulated load: 0%
   521 •   List of pixel formats
   522 ESgPixelFormatARGB_8888
   523 •   Client process priorities - all the same
   524 •   Client process random parameters:
   525 -   None
   526 
   527 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
   528 
   529     From the main process:
   530     For i = 0 to N
   531     Spawn 1 client process.
   532         Signal client process to start by use of a semaphore
   533         Wait until client process exits
   534     If the test fails not due to the memory allocation record an error code to the log file then set a test result as a failure and skip further actions.
   535     End loop
   536     Exit
   537 
   538     From client process A:
   539     Get EGL display
   540     Initialize EGL
   541     Open RSgDriver
   542     Create context, pbuffer surface.
   543     Make pbuffer surface current for the given context  
   544     Loop until exit condition met
   545     Start loop:
   546 Create SgImage
   547 Create EglImage with underlying SgImage
   548     Create VgImage with underlying EglImage
   549     Exit condition – Sg/Egl/Vg image creation has failed.
   550 End loop:
   551     Destroy the pbuffer surface
   552 Log the last iteration number and exact operation which precedes a failure. 
   553 Close all allocated graphics resources (Sg/Egl/Vg images)
   554 In the environment supporting NOK_resource_profiling2 extension, retrieve for further analyzes the following GPU profiling data (if available):
   555 •   Total memory
   556 •   Used memory
   557 •   Process ID
   558 •   Process used private memory
   559 •   Process used shared memory
   560 
   561 Terminate EGL
   562 Close RSgDriver
   563 
   564 @SYMTestExpectedResults
   565 For each step from 0 to N in the main process, 
   566 -   Image allocation failure must happen at approximately the same iteration in process A. 
   567     MaxIterationNumber – MinIterationNumber < Threashold, where Treashold will not 
   568     exceeds 5 and exact value to be defined during implementation. 
   569 -   GPU memory usage retrieved through NOK_resource_profiling2 extension, if available, 
   570     is consistent and doesn’t decrease over the time.
   571     MaxGPUMemoryUsage – MinGPUMemoryUsage < Threshold, where Threshold will not exceed 
   572     5 and exact value to be defined during implementation. 
   573 */
   574 TVerdict CEglTest_OOM_CloseVGImage::doTestStepL()
   575     {
   576     SetTestStepID(_L("GRAPHICS-EGL-0439"));
   577     SetTestStepName(KOOM_CloseVGImage);
   578     INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImage::doTestStepL"));
   579 
   580 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   581     INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImage can only be run with SgImage-Lite"));
   582 #else
   583     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
   584     if(ret)
   585         {
   586         // if the test fails not due to the memory allocation, then skip further actions
   587         for(TInt index = 0; (index < iNumIterations) && (TestStepResult()== EPass); index++)
   588             {
   589             // launch 1 process
   590             Test_MultiProcessL(KEglTestStepDllName, 1, TestStepName());
   591             RetrieveExtensionDataL();
   592             }
   593         CheckDeviation();
   594         }
   595 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   596 
   597     RecordTestResultL();
   598     CloseTMSGraphicsStep();
   599     return TestStepResult();
   600     }
   601 
   602 void CEglTest_OOM_CloseVGImage::doProcessFunctionL(TInt aIdx)
   603     {
   604     INFO_PRINTF2(_L("CEglTest_OOM_CloseVGImage::doProcessFunctionL, Process %d"),aIdx);
   605 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   606     GetDisplayL();
   607     CreateEglSessionL(aIdx);
   608     iEglSess->InitializeL();    
   609     iEglSess->OpenSgDriverL();
   610 
   611     //create a dummy surface and context for the purpose of enabling use of VG
   612     TEglTestConfig pbufferFormat = EglTestConversion::VgFormatToPBufferSurfaceFormat(EglTestConversion::PixelFormatToVgFormat(iPixelFormat));
   613     EGLConfig currentConfig = 0;
   614     TRAPD(res, currentConfig = iEglSess->GetConfigExactMatchL( pbufferFormat ));
   615     User::LeaveIfError(res);
   616 
   617     iEglSess->CreatePbufferSurfaceAndMakeCurrentL(currentConfig, iImageSize, EGL_OPENVG_API);
   618     TInt index = 0;
   619     TSgImageInfo imageInfo;
   620     imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
   621     imageInfo.iPixelFormat = iPixelFormat;
   622     imageInfo.iSizeInPixels = iImageSize;
   623 
   624     for(;;++index)
   625         {
   626         RSgImage sgImage;
   627         TInt res = sgImage.Create(imageInfo, NULL);
   628         if(res != KErrNone || sgImage.IsNull())
   629             {
   630             INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), index, res, KErrNoMemory, KErrNoGraphicsMemory);
   631             ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
   632             break;
   633             }
   634         iSgImages.AppendL(sgImage);
   635         
   636         EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&sgImage,const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
   637         EGLint eglError = eglGetError();
   638         if((eglImage == EGL_NO_IMAGE_KHR) || (eglError != EGL_SUCCESS))
   639             {
   640             INFO_PRINTF4(_L("***Fail to create EGLImage after %d attempts, error: %d, expected: %d"), index, eglError, EGL_BAD_ALLOC);
   641             ASSERT_TRUE(eglError == EGL_BAD_ALLOC);
   642             break;
   643             }
   644         iEglImages.AppendL(eglImage);
   645         
   646         VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
   647         VGErrorCode vgError = vgGetError();
   648         if(vgImage == VG_INVALID_HANDLE || (vgError != VG_NO_ERROR))
   649             {
   650             INFO_PRINTF4(_L("***Fail to create VGImage after %d attempts, error: %d, expected: %d"), index, vgError, VG_OUT_OF_MEMORY_ERROR);
   651             ASSERT_TRUE(vgError == VG_OUT_OF_MEMORY_ERROR);
   652             break;
   653             }
   654         iVgImages.AppendL(vgImage);
   655         }
   656 
   657     SendIndexToMainProcessL(index);
   658     
   659     //now clean everything
   660     CleanGraphicsResources();
   661     iEglSess->CloseSgDriver();
   662     CleanAll();
   663 #endif    
   664     }    
   665 
   666 /**
   667 @SYMTestCaseID GRAPHICS-EGL-0440
   668 
   669 @SYMTestPriority 1
   670 
   671 @SYMPREQ 2637
   672 
   673 @SYMTestCaseDesc
   674     OOM test – Free SgImages/Pixmap surfaces while the process which owns them is terminated
   675 
   676 @SYMTestActions
   677 Environmental settings:
   678 •   Image Size: w50 h50
   679 •   List of simulated load: 0%
   680 •   List of pixel formats
   681 ESgPixelFormatARGB_8888
   682 •   Client process priorities - all the same
   683 •   Client process random parameters:
   684 -   None
   685 
   686 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
   687 
   688     From the main process:
   689     For i = 0 to N
   690         Spawn 2 client processes A and B.
   691         Signal all client processes to start by use of a semaphore
   692         Wait until client processes exit
   693     If the test fails not due to the memory allocation record an error code to the log file then set a test result as a failure and skip further actions.
   694     End loop
   695     Exit
   696 
   697     From client process A:
   698     Get EGL display
   699     Initialize EGL
   700     Open RSgDriver
   701     Loop until exit condition met
   702     Start loop:
   703         Create SgImage
   704         Create Pixmap surface with underlying SgImage
   705         Exit condition – SgImage/Pixmap surface creation has failed.
   706     End loop:
   707     Log the last iteration number and exact operation which precedes a failure. 
   708     In the environment supporting NOK_resource_profiling2 extension retrieve for further analyzes the following GPU profiling data (if available):
   709         •   Total memory
   710         •   Used memory
   711         •   Process ID
   712         •   Process used private memory
   713         •   Process used shared memory
   714     Make the process busy by putting it into the indefinite loop.
   715     
   716     From client process B:
   717     Wait until process A fails with the image/surface creation.
   718     Terminate the process A.
   719 
   720 @SYMTestExpectedResults
   721 For each step from 0 to N in the main process, 
   722 -   Image or surface allocation failure must happen at approximately the same iteration 
   723     in process A. MaxIterationNumber – MinIterationNumber < Threashold, 
   724     where Treashold will not exceeds 5 and exact value to be defined during implementation. 
   725 -   GPU memory usage retrieved through NOK_resource_profiling2 extension, if available, 
   726     is consistent and doesn’t decrease over the time.
   727     MaxGPUMemoryUsage – MinGPUMemoryUsage < Threshold, where Threshold will not exceed 
   728     5 and exact value to be defined during implementation. 
   729 */
   730 TVerdict CEglTest_OOM_ClosePixmapSurfaceWithTermination::doTestStepL()
   731     {
   732     SetTestStepID(_L("GRAPHICS-EGL-0438"));
   733     SetTestStepName(KOOM_ClosePixmapSurfaceWithTermination);
   734     INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination::doTestStepL"));
   735 
   736 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   737     INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination can only be run with SgImage-Lite"));
   738 #else
   739     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
   740     if(ret)
   741         {
   742         // if the test fails not due to the memory allocation, then skip further actions
   743         for(TInt index = 0; (index < iNumIterations) && (TestStepResult()== EPass); index++)
   744             {
   745             // launch 2 processes
   746             Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
   747             RetrieveExtensionDataL();
   748             }
   749         CheckDeviation();
   750         }
   751 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   752 
   753     RecordTestResultL();
   754     CloseTMSGraphicsStep();
   755     return TestStepResult();
   756     }
   757 
   758 void CEglTest_OOM_ClosePixmapSurfaceWithTermination::doProcessFunctionL(TInt aIdx)
   759     {
   760     INFO_PRINTF2(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination::doProcessFunctionL, Process %d"),aIdx);
   761 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   762 
   763     if(aIdx == 0)
   764         {
   765         GetDisplayL();
   766         CreateEglSessionL(aIdx);
   767         iEglSess->InitializeL();    
   768         iEglSess->OpenSgDriverL();
   769 
   770         TInt index = 0;
   771         TSgImageInfo imageInfo;
   772         imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
   773         imageInfo.iPixelFormat = iPixelFormat;
   774         imageInfo.iSizeInPixels = iImageSize;
   775 
   776         for(;;++index)
   777             {
   778             RSgImage sgImage;
   779             TInt res = sgImage.Create(imageInfo, NULL);
   780             if(res != KErrNone || sgImage.IsNull())
   781                 {
   782                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), index, res, KErrNoMemory, KErrNoGraphicsMemory);
   783                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
   784                 break;
   785                 }
   786             
   787             EGLConfig currentConfig = 0;
   788             const EGLint KAttrib[] = { EGL_MATCH_NATIVE_PIXMAP,   (TInt)&sgImage,
   789                                        EGL_RENDERABLE_TYPE,       EGL_OPENVG_BIT,
   790                                        EGL_SURFACE_TYPE,          EGL_PIXMAP_BIT,
   791                                        EGL_NONE };
   792             
   793             EGLint config_size;
   794             ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib,&currentConfig,1,&config_size));
   795             ASSERT_TRUE(currentConfig!=0);
   796             
   797             // Create a pixmap surface from the native image
   798             EGLSurface surface = eglCreatePixmapSurface(iDisplay, currentConfig, &sgImage, NULL);
   799             EGLint eglError = eglGetError();
   800             if((surface == EGL_NO_SURFACE) || (eglError != EGL_SUCCESS))
   801                 {
   802                 INFO_PRINTF4(_L("***Fail to create Pixmap surface after %d attempts, error: %d, expected: %d"), index, eglError, EGL_BAD_ALLOC);
   803                 ASSERT_TRUE(eglError == EGL_BAD_ALLOC);
   804                 break;
   805                 }            
   806             } //for
   807         SendIndexToMainProcessL(index);
   808         }
   809     Rendezvous(aIdx);
   810     
   811     //create the queue to send/receive Process ID between processes
   812     RMsgQueue<TProcessId> messageQueueProcId;
   813     User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess));
   814     CleanupClosePushL(messageQueueProcId);
   815     
   816     if(aIdx == 0)
   817         {
   818         // Sending Process ID to other process... so that the other process can kill it.
   819         TProcessId procId = RProcess().Id();
   820         messageQueueProcId.SendBlocking(procId);
   821         CleanupStack::PopAndDestroy(&messageQueueProcId);
   822         //go into indefinite loop which will be terminated by the second process
   823         for(;;) { }
   824         }
   825     else
   826         {
   827         TProcessId procId;
   828         messageQueueProcId.ReceiveBlocking(procId);
   829         CleanupStack::PopAndDestroy(&messageQueueProcId);
   830 
   831         RProcess process;
   832         ASSERT_TRUE(process.Open(procId) == KErrNone);
   833         process.Kill(KErrNone);
   834 		process.Close();
   835 
   836         // small delay to ensure the kernel finishes the clean-up
   837         User::After(1*1000*1000); // 1 second
   838         }
   839 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   840     }
   841 
   842 /**
   843 @SYMTestCaseID GRAPHICS-EGL-0441
   844 
   845 @SYMTestPriority 1
   846 
   847 @SYMPREQ 2637
   848 
   849 @SYMTestCaseDesc
   850     OOM test – Free SgImages/Pixmap surfaces while the process which owns them exits gracefully
   851 
   852 @SYMTestActions
   853 Environmental settings:
   854 •   Image Size: w50 h50
   855 •   List of simulated load: 0%
   856 •   List of pixel formats
   857 ESgPixelFormatARGB_8888
   858 •   Client process priorities - all the same
   859 •   Client process random parameters:
   860 -   None
   861 
   862 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
   863 
   864     From the main process:
   865     For i = 0 to N
   866         Spawn 1 client process.
   867         Signal client process to start by use of a semaphore
   868         Wait until client process exits
   869     If the test fails not due to the memory allocation record an error code to the log file then set a test result as a failure and skip further actions.
   870     End loop
   871     Exit
   872 
   873     From client process A:
   874     Get EGL display
   875     Initialize EGL
   876     Open RSgDriver
   877     Loop until exit condition met
   878     Start loop:
   879         Create SgImage
   880         Create Pixmap surface with underlying SgImage
   881         Exit condition – SgImage/Pixmap surface creation has failed.
   882     End loop:
   883     Log the last iteration number and exact operation which precedes a failure.
   884     CLose all allocated graphics resources (SgImages/Pixmap surfaces) 
   885     In the environment supporting NOK_resource_profiling2 extension retrieve for further analyzes the following GPU profiling data (if available):
   886         •   Total memory
   887         •   Used memory
   888         •   Process ID
   889         •   Process used private memory
   890         •   Process used shared memory
   891     Terminate EGL
   892     Close RSgDriver
   893 
   894 @SYMTestExpectedResults
   895 For each step from 0 to N in the main process, 
   896 -   Image or surface allocation failure must happen at approximately the same iteration in process A. 
   897     MaxIterationNumber – MinIterationNumber < Threashold, 
   898     where Treashold will not exceeds 5 and exact value to be defined during implementation. 
   899 -   GPU memory usage retrieved through NOK_resource_profiling2 extension, 
   900     if available, is consistent and doesn’t decrease over the time. 
   901 */
   902 TVerdict CEglTest_OOM_ClosePixmapSurface::doTestStepL()
   903     {
   904     SetTestStepID(_L("GRAPHICS-EGL-0441"));
   905     SetTestStepName(KOOM_ClosePixmapSurface);
   906     INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurface::doTestStepL"));
   907 
   908 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   909     INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurface can only be run with SgImage-Lite"));
   910 #else
   911     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
   912     if(ret)
   913         {
   914         // if the test fails not due to the memory allocation, then skip further actions
   915         for(TInt index = 0; (index < iNumIterations) && (TestStepResult()== EPass); index++)
   916             {
   917             // launch 1 process
   918             Test_MultiProcessL(KEglTestStepDllName, 1, TestStepName());
   919             RetrieveExtensionDataL();
   920             } //for
   921         CheckDeviation();
   922         }
   923 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   924 
   925     RecordTestResultL();
   926     CloseTMSGraphicsStep();
   927     return TestStepResult();
   928     }
   929 
   930 void CEglTest_OOM_ClosePixmapSurface::doProcessFunctionL(TInt aIdx)
   931     {
   932     INFO_PRINTF2(_L("CEglTest_OOM_ClosePixmapSurface::doProcessFunctionL, Process %d"),aIdx);
   933 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   934     GetDisplayL();
   935     CreateEglSessionL(aIdx);
   936     iEglSess->InitializeL();    
   937     iEglSess->OpenSgDriverL();
   938 
   939     TInt index = 0;
   940     TSgImageInfo imageInfo;
   941     imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
   942     imageInfo.iPixelFormat = iPixelFormat;
   943     imageInfo.iSizeInPixels = iImageSize;
   944 
   945     for(;;++index)
   946         {
   947         RSgImage sgImage;
   948         TInt res = sgImage.Create(imageInfo, NULL);
   949         if(res != KErrNone || sgImage.IsNull())
   950             {
   951             INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), index, res, KErrNoMemory, KErrNoGraphicsMemory);
   952             ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
   953             break;
   954             }
   955         iSgImages.AppendL(sgImage);
   956         
   957         EGLConfig currentConfig = 0;
   958         const EGLint KAttrib[] = { EGL_MATCH_NATIVE_PIXMAP,   (TInt)&sgImage,
   959                                    EGL_RENDERABLE_TYPE,       EGL_OPENVG_BIT,
   960                                    EGL_SURFACE_TYPE,          EGL_PIXMAP_BIT,
   961                                    EGL_NONE };
   962         
   963         EGLint config_size;
   964         ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib,&currentConfig,1,&config_size));
   965         ASSERT_TRUE(currentConfig!=0);
   966         
   967         // Create a pixmap surface from the native image
   968         EGLSurface surface = eglCreatePixmapSurface(iDisplay, currentConfig, &sgImage, NULL);
   969         EGLint eglError = eglGetError();
   970         if((surface == EGL_NO_SURFACE) || (eglError != EGL_SUCCESS))
   971             {
   972             INFO_PRINTF4(_L("***Fail to create Pixmap surface after %d attempts, error: %d, expected: %d "), index, eglError, EGL_BAD_ALLOC);
   973             ASSERT_TRUE(eglError == EGL_BAD_ALLOC);
   974             break;
   975             }       
   976         iSurfaces.AppendL(surface);
   977         } //for
   978     SendIndexToMainProcessL(index);
   979     //now clean everything
   980     CleanGraphicsResources();
   981     iEglSess->CloseSgDriver();
   982     CleanAll();
   983 #endif    
   984     }    
   985 
   986 /**
   987 @SYMTestCaseID GRAPHICS-EGL-0442
   988 
   989 @SYMTestPriority 1
   990 
   991 @SYMPREQ 2637
   992 
   993 @SYMTestCaseDesc
   994     OOM test – Check SgImages are removed when SgImage handles in multiple processes are closed
   995 
   996 @SYMTestActions
   997 Environmental settings:
   998 •   Image Size: as per ini file
   999 •   List of simulated load: 0%
  1000 •   List of pixel formats
  1001 ESgPixelFormatARGB_8888
  1002 •   Client process priorities - all the same
  1003 •   Client process random parameters:
  1004 -   None
  1005 
  1006 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
  1007 
  1008     From the main process:
  1009         Spawn 2 client processes A and B.
  1010         Wait until client processes exit
  1011     If the test fails not due to the memory allocation record an error code to the log file then set a test result as a failure and skip further actions.
  1012     End loop
  1013     Exit
  1014 
  1015     From client process A:
  1016     Get EGL display
  1017     Initialize EGL
  1018     Open RSgDriver
  1019     Loop until exit condition met
  1020     Start loop:
  1021         Create SgImage
  1022         Exit condition – SgImage surface creation has failed.
  1023     End loop:
  1024     Make the process busy by putting it into the indefinite loop.
  1025     
  1026     From client process B:
  1027     Start loop:
  1028         Open SgImage
  1029         Close SgImage
  1030     End loop:
  1031 
  1032     From client process A:
  1033     Start loop:
  1034         Close SgImage
  1035     End loop:
  1036     Check all memory has been deallocated by starting a second loop
  1037         Start loop 2:
  1038             Create SgImage
  1039             Exit condition – SgImage surface creation has failed.
  1040         End loop:
  1041     Check that the amount of images created within this loop 2 is similar to loop 1,
  1042     meaning that all images were correctly freed.
  1043     Cleanup everything
  1044     
  1045     Terminate process A
  1046     Terminate process B
  1047     
  1048 @SYMTestExpectedResults
  1049 For each step from 0 to N in the main process, 
  1050 -   Image or surface allocation failure must happen at approximately the same iteration 
  1051     in process A.  
  1052 */
  1053 TVerdict CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL()
  1054     {
  1055     SetTestStepID(_L("GRAPHICS-EGL-0442"));
  1056     SetTestStepName(KOOM_CloseSgImageDifferentProcess);
  1057     INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL"));
  1058 
  1059 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1060     INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageDifferentProcess can only be run with SgImage-Lite"));
  1061 #else
  1062     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
  1063     if(ret)
  1064         {
  1065         // launch 2 processes
  1066         Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
  1067         }
  1068     INFO_PRINTF1(_L("Exit: CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL"));
  1069 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1070     RecordTestResultL();
  1071     CloseTMSGraphicsStep();
  1072     return TestStepResult();
  1073     }
  1074 
  1075 void CEglTest_OOM_CloseSgImageDifferentProcess::doProcessFunctionL(TInt aIdx)
  1076     {
  1077     INFO_PRINTF2(_L("CEglTest_OOM_CloseSgImageDifferentProcess::doProcessFunctionL, Process %d"),aIdx);
  1078 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1079 
  1080     GetDisplayL();
  1081     CreateEglSessionL(aIdx);
  1082     iEglSess->InitializeL();
  1083     iEglSess->OpenSgDriverL();
  1084 
  1085     //create the queue to send/receive SgImage ID between processes
  1086     RMsgQueue<TSgDrawableId> messageQueueSgId;
  1087     User::LeaveIfError(messageQueueSgId.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
  1088     CleanupClosePushL(messageQueueSgId);
  1089 
  1090     // create as many sgimages until it reaches out of memory
  1091     TInt numImages = 0;
  1092     if(aIdx == 0)
  1093         {
  1094         for(;;++numImages)
  1095             {
  1096             RSgImage sgImage;
  1097             TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
  1098             if(res != KErrNone || sgImage.IsNull())
  1099                 {
  1100                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), numImages, res, KErrNoMemory, KErrNoGraphicsMemory);
  1101                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
  1102                 break;
  1103                 }
  1104             iSgImages.AppendL(sgImage);
  1105             }
  1106         }
  1107     
  1108     // Send to process B how many images it needs to wait for
  1109     if(aIdx == 0)
  1110         {
  1111        // send a TInt as a  fake SgImage Id
  1112         messageQueueSgId.SendBlocking(reinterpret_cast<TSgDrawableId&>(numImages));
  1113         }
  1114     else if (aIdx == 1)
  1115         {
  1116         // receive the fake SgImage Id and convert it to a TInt
  1117         TSgDrawableId fakeId;
  1118         messageQueueSgId.ReceiveBlocking(fakeId);
  1119         numImages = reinterpret_cast<TInt&>(fakeId);
  1120         }
  1121     
  1122     // Wait for both processes to reach this point
  1123     Rendezvous(aIdx);
  1124     
  1125     // Now process B knows how many images needs to wait for
  1126     if(aIdx == 0)
  1127         {
  1128         for(TInt index = 0; index<numImages; ++index)
  1129             {
  1130             // send Id to other process
  1131             messageQueueSgId.SendBlocking(iSgImages[index].Id());
  1132             }
  1133         }
  1134     else if(aIdx == 1)
  1135         {
  1136         for(TInt index = 0; index<numImages; ++index)
  1137             {
  1138             // receive Id from other process
  1139             TSgDrawableId sgImageId;
  1140             messageQueueSgId.ReceiveBlocking(sgImageId);
  1141             
  1142             // open sgImage with received Id
  1143             RSgImage sgImage;
  1144             ASSERT_EQUALS(sgImage.Open(sgImageId), KErrNone);
  1145 
  1146             // close SgImage just created
  1147             sgImage.Close();
  1148             }
  1149         }
  1150 
  1151     // Wait for both processes to reach this point
  1152     Rendezvous(aIdx);
  1153 
  1154     // delete all sgImages created in first process
  1155     if(aIdx == 0)
  1156         {
  1157         CleanGraphicsResources();
  1158         }
  1159 
  1160     // create (again) as many sgimages until it reaches out of memory
  1161     // note that process B needs to be alive (hence the Rendezvous further down)
  1162     if(aIdx == 0)
  1163         {
  1164         TInt numImages2 = 0;
  1165         for(;;++numImages2)
  1166             {
  1167             RSgImage sgImage;
  1168             TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
  1169             if(res != KErrNone || sgImage.IsNull())
  1170                 {
  1171                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), numImages2, res, KErrNoMemory, KErrNoGraphicsMemory);
  1172                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
  1173                 break;
  1174                 }
  1175             iSgImages.AppendL(sgImage);
  1176             }
  1177         // clean up these images, we don't really need them
  1178         CleanGraphicsResources();
  1179         
  1180         // check numbers...
  1181         INFO_PRINTF2(_L("***Num sgImages created first time: %d."), numImages);
  1182         INFO_PRINTF2(_L("***Num sgImages created second time: %d."), numImages2);
  1183         TInt deviation = Abs(((numImages2*100) / numImages) - 100);
  1184         ASSERT_TRUE(deviation < KOOMSgImageDeviation);
  1185         INFO_PRINTF3(_L("***Deviation: %d%% (must be less than %d%%)"), deviation, KOOMSgImageDeviation);
  1186 
  1187         // This test does not need to send anything, but since OOM test framework expects something
  1188         // we can send a fake index so that the test is not waiting for it forever.
  1189         const TInt KTestNotUsedData = 0;
  1190         SendIndexToMainProcessL(KTestNotUsedData); 
  1191         }
  1192 
  1193     // Wait for both processes to reach this point
  1194     Rendezvous(aIdx);
  1195 
  1196     //now clean everything
  1197     CleanupStack::PopAndDestroy(&messageQueueSgId);
  1198     CleanGraphicsResources();
  1199     iEglSess->CloseSgDriver();
  1200     CleanAll();
  1201 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1202     }
  1203 
  1204 /**
  1205 @SYMTestCaseID GRAPHICS-EGL-0443
  1206 
  1207 @SYMTestPriority 1
  1208 
  1209 @SYMPREQ 2637
  1210 
  1211 @SYMTestCaseDesc
  1212     OOM test – Check SgImages are removed when SgImage handles in multiple processes are closed
  1213 
  1214 @SYMTestActions
  1215 Environmental settings:
  1216 •   Image Size: as per ini file
  1217 •   List of simulated load: 0%
  1218 •   List of pixel formats
  1219 ESgPixelFormatARGB_8888
  1220 •   Client process priorities - all the same
  1221 •   Client process random parameters:
  1222 -   None
  1223 
  1224 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
  1225 
  1226     From the main process:
  1227     From client process A:
  1228     Get EGL display
  1229     Initialize EGL
  1230     Open RSgDriver
  1231     Loop until exit condition met
  1232     Start loop:
  1233         Create SgImage
  1234         Exit condition – SgImage surface creation has failed.
  1235     End loop:
  1236     Start loop:
  1237         Open SgImage
  1238         Close SgImage
  1239     End loop:
  1240     Start loop:
  1241         Close SgImage
  1242     End loop:
  1243     Check all memory has been deallocated by starting a second loop
  1244         Start loop 2:
  1245             Create SgImage
  1246             Exit condition – SgImage surface creation has failed.
  1247         End loop:
  1248     Check that the amount of images created within this loop 2 is similar to loop 1,
  1249     meaning that all images were correctly freed.
  1250     Cleanup everything
  1251     
  1252 @SYMTestExpectedResults
  1253 For each step from 0 to N in the main process, 
  1254 -   Image or surface allocation failure must happen at approximately the same iteration 
  1255     in process A.  
  1256 */
  1257 TVerdict CEglTest_OOM_CloseSgImageSameThread::doTestStepL()
  1258     {
  1259     SetTestStepID(_L("GRAPHICS-EGL-0443"));
  1260     SetTestStepName(KOOM_CloseSgImageSameThread);
  1261     INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageSameThread::doTestStepL"));
  1262 
  1263 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1264     INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageSameThread can only be run with SgImage-Lite"));
  1265 #else
  1266     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
  1267     if(ret)
  1268         {
  1269         GetDisplayL();
  1270         CreateEglSessionL(0);
  1271         iEglSess->InitializeL();
  1272         iEglSess->OpenSgDriverL();
  1273     
  1274         // create as many sgimages until it reaches out of memory
  1275         TInt numImages = 0;
  1276         for(;;++numImages)
  1277             {
  1278             RSgImage sgImage;
  1279             TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
  1280             if(res != KErrNone || sgImage.IsNull())
  1281                 {
  1282                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), numImages, res, KErrNoMemory, KErrNoGraphicsMemory);
  1283                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
  1284                 break;
  1285                 }
  1286             iSgImages.AppendL(sgImage);
  1287             }
  1288 
  1289         //open a duplicate handle for the created images (can close straightaway)
  1290         for(TInt index = 0; index<numImages; ++index)
  1291             {
  1292             RSgImage sgImage;
  1293             ASSERT_EQUALS(sgImage.Open(iSgImages[index].Id()), KErrNone);
  1294             // close SgImage just created
  1295             sgImage.Close();
  1296             }
  1297 
  1298         // clean up all (original) images
  1299         CleanGraphicsResources();
  1300 
  1301         // create (again) as many sgimages until it reaches out of memory
  1302         TInt numImages2 = 0;
  1303         for(;;++numImages2)
  1304             {
  1305             RSgImage sgImage;
  1306             TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
  1307             if(res != KErrNone || sgImage.IsNull())
  1308                 {
  1309                 INFO_PRINTF5(_L("***Fail to create RSgImage after %d attempts, error: %d, expected: %d or %d"), numImages2, res, KErrNoMemory, KErrNoGraphicsMemory);
  1310                 ASSERT_TRUE((res == KErrNoMemory) || (res == KErrNoGraphicsMemory));
  1311                 break;
  1312                 }
  1313             iSgImages.AppendL(sgImage);
  1314             }
  1315             
  1316         // clean up everything now
  1317         CleanGraphicsResources();
  1318         iEglSess->CloseSgDriver();
  1319         CleanAll();
  1320 
  1321         // check numbers...
  1322         INFO_PRINTF2(_L("***Num sgImages created first time: %d."), numImages);
  1323         INFO_PRINTF2(_L("***Num sgImages created second time: %d."), numImages2);
  1324         TInt deviation = Abs(((numImages2*100) / numImages) - 100);
  1325         ASSERT_TRUE(deviation < KOOMSgImageDeviation);
  1326         INFO_PRINTF3(_L("***Deviation: %d%% (must be less than %d%%)"), deviation, KOOMSgImageDeviation);
  1327         }
  1328     INFO_PRINTF1(_L("Exit: CEglTest_OOM_CloseSgImageSameThread::doTestStepL"));
  1329 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1330 
  1331     RecordTestResultL();
  1332     CloseTMSGraphicsStep();
  1333     return TestStepResult();
  1334     }
  1335