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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include <test/tefunit.h> // for ASSERT macros
22 #include <e32msgqueue.h>
24 #include <test/egltestcommonprocess.h>
25 #include <test/egltestcommonconversion.h>
26 #include <test/egltestcommoninisettings.h>
27 #include "egltest_oom_sgimage.h"
30 _LIT(KOOMSection, "OOM");
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;
37 // Deviation in per cent for test 0442 and 0443
38 const TInt KOOMSgImageDeviation = 5;
41 CEglTest_OOM_Base::~CEglTest_OOM_Base()
43 CleanGraphicsResources();
47 TVerdict CEglTest_OOM_Base::doTestStepPreambleL()
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);
56 ERR_PRINTF1(_L("The number iterations is not specified in INI file, the test will not be executed!"));
57 User::Leave(KErrArgument);
60 iImageSize = iniParser->GetImageSize(KOOMSection);
61 if(iImageSize == TSize(0,0))
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);
66 iPixelFormat = KOOMPixelFormat;
68 iThresholdGPUUsedMemory = iniParser->GetThresholdGPUUsedMemory(KOOMSection);
69 if(iThresholdGPUUsedMemory == 0)
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);
75 iThresholdLastIteration = iniParser->GetThresholdLastIteration(KOOMSection);
76 if(iThresholdLastIteration == 0)
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);
82 CleanupStack::PopAndDestroy(iniParser);
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);
87 PrintUsedPixelConfiguration();
91 TVerdict CEglTest_OOM_Base::doTestStepPostambleL()
93 //to keep heap checking happy we have to clean up before destructor
94 CleanGraphicsResources();
95 return CEglTestStep::doTestStepPostambleL();
98 //receive last successful index from the client process
99 void CEglTest_OOM_Base::ReceiveMessageFromClient(RMsgQueue<TEglStepMessageBuffer>& aMessageQueueClientProcParam)
101 TEglStepMessageBuffer param;
102 aMessageQueueClientProcParam.ReceiveBlocking(param);
103 iLastIterationNumber = *(TInt*) (param.iBuf);
106 //send last successful index to the main process for analysis
107 void CEglTest_OOM_Base::SendIndexToMainProcessL(TInt aIndex)
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);
118 //clean Sg/Egl/Vg images allocated. Reset arrays for various deviation variables.
119 void CEglTest_OOM_Base::CleanGraphicsResources()
121 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
122 while(iSurfaces.Count() > 0)
124 eglDestroySurface(iDisplay, iSurfaces[0]);
129 while(iVgImages.Count() > 0)
131 vgDestroyImage(iVgImages[0]);
136 while(iEglImages.Count() > 0)
138 iEglSess->DestroyEGLImage(iDisplay, iEglImages[0]);
139 iEglImages.Remove(0);
143 while(iSgImages.Count() > 0)
145 iSgImages[0].Close();
150 iGPUUsedMemory.Reset();
151 iLastIterations.Reset();
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
160 if(aArray.Count() == 0)
164 for(TInt ii = 1; ii < aArray.Count(); ii++)
166 if(aMin > aArray[ii])
170 if(aMax < aArray[ii])
177 TInt CEglTest_OOM_Base::Deviation(const RArray<TInt>& aArray) const
182 GetMinMax(aArray, min, max);
184 return 0; // to avoid division by zero
185 return (max - min) / (((TReal)(min + max)) / 2) * 100;
188 //Calculate and output deviation of various parameters.
189 //If the measurement for particular parameter doesnt take place, for instance,
190 //due to absence of the extension, the output will be skipped.
191 void CEglTest_OOM_Base::CheckDeviation()
195 if(iGPUUsedMemory.Count() > 0)
197 res = Deviation(iGPUUsedMemory);
198 ASSERT_TRUE(iThresholdGPUUsedMemory >= res);
199 INFO_PRINTF3(_L("GPU used memory deviation %d %%, threshold %d %%"), res, iThresholdGPUUsedMemory);
202 if(iLastIterations.Count() > 0)
204 res = Deviation(iLastIterations);
205 ASSERT_TRUE(iThresholdLastIteration >= res);
206 INFO_PRINTF3(_L("Last iteration deviation %d %%, threshold %d %%"), res, iThresholdLastIteration);
210 void CEglTest_OOM_Base::RetrieveExtensionDataL()
212 PrintEglResourceProfilingInfoL();
213 INFO_PRINTF2(_L("Nember iterations before the failure occurs, %d"), iLastIterationNumber);
214 iLastIterations.Append(iLastIterationNumber);
215 iLastIterationNumber = -1;
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()
223 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
224 #ifdef EGL_PROF_MEMORY_USAGE_THRESHOLD_NOK
228 iEglSess->InitializeL();
230 if(!iPFnEglQueryProfilingDataNOK)
232 iPFnEglQueryProfilingDataNOK = (PFNEGLQUERYPROFILINGDATANOKPROC) eglGetProcAddress("eglQueryProfilingDataNOK");
234 if(!iPFnEglQueryProfilingDataNOK)
237 WARN_PRINTF1(_L("NOK_resource_profiling2 extension is not available"));
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,
251 // Allocate room for the profiling data
252 EGLint* prof_data = (EGLint*)User::AllocL(data_count * sizeof(EGLint));
254 CleanupStack::PushL(prof_data);
256 // Retrieve the profiling data
257 iPFnEglQueryProfilingDataNOK(iDisplay,
258 EGL_PROF_QUERY_GLOBAL_BIT_NOK |
259 EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK,
264 // Iterate over the returned data
266 while (i < data_count)
268 switch (prof_data[i++])
270 case EGL_PROF_TOTAL_MEMORY_NOK:
271 INFO_PRINTF2(_L("Total memory: %d"), prof_data[i++]);
273 case EGL_PROF_USED_MEMORY_NOK:
274 iGPUUsedMemory.AppendL(prof_data[i]);
275 INFO_PRINTF2(_L("Used memory: %d"), prof_data[i++]);
277 case EGL_PROF_PROCESS_ID_NOK:
278 if(sizeof(EGLNativeProcessIdTypeNOK) == 4)
280 INFO_PRINTF2(_L("Process ID(4 bytes), 0x%08X"), prof_data[i++]);
282 else if(sizeof(EGLNativeProcessIdTypeNOK) == 8)
284 EGLNativeProcessIdTypeNOK processId = ((EGLNativeProcessIdTypeNOK)(prof_data[i])) + (((EGLNativeProcessIdTypeNOK)(prof_data[i + 1]))<<32);
286 TProcessId pid(processId);
287 TInt err = process.Open(pid);
290 TPtrC ptr(process.FullName());
291 INFO_PRINTF4(_L("Process ID, %lu - 0x%lu - %S"), processId, processId, &ptr);
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);
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"));
305 case EGL_PROF_PROCESS_USED_PRIVATE_MEMORY_NOK:
306 INFO_PRINTF2(_L("Process used private memory: %d"), prof_data[i++]);
308 case EGL_PROF_PROCESS_USED_SHARED_MEMORY_NOK:
309 INFO_PRINTF2(_L("Process used shared memory: %d"), prof_data[i++]);
314 // Free allocated memory
315 CleanupStack::PopAndDestroy(prof_data);
318 #endif //EGL_PROF_MEMORY_USAGE_THRESHOLD_NOK
319 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
323 @SYMTestCaseID GRAPHICS-EGL-0438
330 OOM test Free VG/Egl/Sg Images while the process which owns them is terminated
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:
342 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
344 From the main process:
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.
353 From client process A:
357 Create context, pbuffer surface.
358 Make pbuffer surface current for the given context
359 Loop until exit condition met
362 Create EglImage with underlying SgImage
363 Create VgImage with underlying EglImage
364 Exit condition Sg/Egl/Vg image creation has failed.
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):
372 Process used private memory
373 Process used shared memory
375 Make the process busy by putting it into the indefinite loop.
377 From client process B:
378 Wait until process A fails with the image creation.
379 Terminate the process A.
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 doesnt decrease over the time.
388 MaxGPUMemoryUsage MinGPUMemoryUsage < Threshold, where Threshold will not exceed
389 5 and exact value to be defined during implementation.
391 TVerdict CEglTest_OOM_CloseVGImageWithTermination::doTestStepL()
393 SetTestStepID(_L("GRAPHICS-EGL-0438"));
394 SetTestStepName(KOOM_CloseVGImageWithTermination);
395 INFO_PRINTF1(_L("CEglTest_Benchmark_Multi_Process_CreateCloseImage::doTestStepL"));
397 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
398 INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImageWithTermination can only be run with SgImage-Lite"));
400 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
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++)
407 // launch 2 processes
408 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
409 RetrieveExtensionDataL();
413 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
416 CloseTMSGraphicsStep();
417 return TestStepResult();
420 void CEglTest_OOM_CloseVGImageWithTermination::doProcessFunctionL(TInt aIdx)
422 INFO_PRINTF2(_L("CEglTest_OOM_CloseVGImageWithTermination::doProcessFunctionL, Process %d"),aIdx);
423 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
428 CreateEglSessionL(aIdx);
429 iEglSess->InitializeL();
430 iEglSess->OpenSgDriverL();
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);
438 iEglSess->CreatePbufferSurfaceAndMakeCurrentL(currentConfig, iImageSize, EGL_OPENVG_API);
440 TSgImageInfo imageInfo;
441 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
442 imageInfo.iPixelFormat = iPixelFormat;
443 imageInfo.iSizeInPixels = iImageSize;
447 TInt res = sgImage.Create(imageInfo, NULL);
448 if(res != KErrNone || sgImage.IsNull())
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));
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))
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);
463 VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages);
464 VGErrorCode vgError = vgGetError();
465 if(vgImage == VG_INVALID_HANDLE || (vgError != VG_NO_ERROR))
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);
472 SendIndexToMainProcessL(index);
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);
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
493 messageQueueProcId.ReceiveBlocking(procId);
494 CleanupStack::PopAndDestroy(&messageQueueProcId);
497 ASSERT_TRUE(process.Open(procId) == KErrNone);
498 process.Kill(KErrNone);
501 // small delay to ensure the kernel finishes the clean-up
502 User::After(1*1000*1000); // 1 second
504 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
508 @SYMTestCaseID GRAPHICS-EGL-0439
515 OOM test Free VG/Egl/Sg Images while the process which owns them exits gracefully
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:
527 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
529 From the main process:
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.
538 From client process A:
542 Create context, pbuffer surface.
543 Make pbuffer surface current for the given context
544 Loop until exit condition met
547 Create EglImage with underlying SgImage
548 Create VgImage with underlying EglImage
549 Exit condition Sg/Egl/Vg image creation has failed.
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):
558 Process used private memory
559 Process used shared memory
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 doesnt decrease over the time.
571 MaxGPUMemoryUsage MinGPUMemoryUsage < Threshold, where Threshold will not exceed
572 5 and exact value to be defined during implementation.
574 TVerdict CEglTest_OOM_CloseVGImage::doTestStepL()
576 SetTestStepID(_L("GRAPHICS-EGL-0439"));
577 SetTestStepName(KOOM_CloseVGImage);
578 INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImage::doTestStepL"));
580 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
581 INFO_PRINTF1(_L("CEglTest_OOM_CloseVGImage can only be run with SgImage-Lite"));
583 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
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++)
590 Test_MultiProcessL(KEglTestStepDllName, 1, TestStepName());
591 RetrieveExtensionDataL();
595 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
598 CloseTMSGraphicsStep();
599 return TestStepResult();
602 void CEglTest_OOM_CloseVGImage::doProcessFunctionL(TInt aIdx)
604 INFO_PRINTF2(_L("CEglTest_OOM_CloseVGImage::doProcessFunctionL, Process %d"),aIdx);
605 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
607 CreateEglSessionL(aIdx);
608 iEglSess->InitializeL();
609 iEglSess->OpenSgDriverL();
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);
617 iEglSess->CreatePbufferSurfaceAndMakeCurrentL(currentConfig, iImageSize, EGL_OPENVG_API);
619 TSgImageInfo imageInfo;
620 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
621 imageInfo.iPixelFormat = iPixelFormat;
622 imageInfo.iSizeInPixels = iImageSize;
627 TInt res = sgImage.Create(imageInfo, NULL);
628 if(res != KErrNone || sgImage.IsNull())
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));
634 iSgImages.AppendL(sgImage);
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))
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);
644 iEglImages.AppendL(eglImage);
646 VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
647 VGErrorCode vgError = vgGetError();
648 if(vgImage == VG_INVALID_HANDLE || (vgError != VG_NO_ERROR))
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);
654 iVgImages.AppendL(vgImage);
657 SendIndexToMainProcessL(index);
659 //now clean everything
660 CleanGraphicsResources();
661 iEglSess->CloseSgDriver();
667 @SYMTestCaseID GRAPHICS-EGL-0440
674 OOM test Free SgImages/Pixmap surfaces while the process which owns them is terminated
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:
686 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
688 From the main process:
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.
697 From client process A:
701 Loop until exit condition met
704 Create Pixmap surface with underlying SgImage
705 Exit condition SgImage/Pixmap surface creation has failed.
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):
712 Process used private memory
713 Process used shared memory
714 Make the process busy by putting it into the indefinite loop.
716 From client process B:
717 Wait until process A fails with the image/surface creation.
718 Terminate the process A.
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 doesnt decrease over the time.
727 MaxGPUMemoryUsage MinGPUMemoryUsage < Threshold, where Threshold will not exceed
728 5 and exact value to be defined during implementation.
730 TVerdict CEglTest_OOM_ClosePixmapSurfaceWithTermination::doTestStepL()
732 SetTestStepID(_L("GRAPHICS-EGL-0438"));
733 SetTestStepName(KOOM_ClosePixmapSurfaceWithTermination);
734 INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination::doTestStepL"));
736 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
737 INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination can only be run with SgImage-Lite"));
739 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
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++)
745 // launch 2 processes
746 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
747 RetrieveExtensionDataL();
751 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
754 CloseTMSGraphicsStep();
755 return TestStepResult();
758 void CEglTest_OOM_ClosePixmapSurfaceWithTermination::doProcessFunctionL(TInt aIdx)
760 INFO_PRINTF2(_L("CEglTest_OOM_ClosePixmapSurfaceWithTermination::doProcessFunctionL, Process %d"),aIdx);
761 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
766 CreateEglSessionL(aIdx);
767 iEglSess->InitializeL();
768 iEglSess->OpenSgDriverL();
771 TSgImageInfo imageInfo;
772 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
773 imageInfo.iPixelFormat = iPixelFormat;
774 imageInfo.iSizeInPixels = iImageSize;
779 TInt res = sgImage.Create(imageInfo, NULL);
780 if(res != KErrNone || sgImage.IsNull())
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));
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,
794 ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib,¤tConfig,1,&config_size));
795 ASSERT_TRUE(currentConfig!=0);
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))
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);
807 SendIndexToMainProcessL(index);
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);
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
828 messageQueueProcId.ReceiveBlocking(procId);
829 CleanupStack::PopAndDestroy(&messageQueueProcId);
832 ASSERT_TRUE(process.Open(procId) == KErrNone);
833 process.Kill(KErrNone);
836 // small delay to ensure the kernel finishes the clean-up
837 User::After(1*1000*1000); // 1 second
839 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
843 @SYMTestCaseID GRAPHICS-EGL-0441
850 OOM test Free SgImages/Pixmap surfaces while the process which owns them exits gracefully
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:
862 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
864 From the main process:
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.
873 From client process A:
877 Loop until exit condition met
880 Create Pixmap surface with underlying SgImage
881 Exit condition SgImage/Pixmap surface creation has failed.
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):
889 Process used private memory
890 Process used shared memory
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 doesnt decrease over the time.
902 TVerdict CEglTest_OOM_ClosePixmapSurface::doTestStepL()
904 SetTestStepID(_L("GRAPHICS-EGL-0441"));
905 SetTestStepName(KOOM_ClosePixmapSurface);
906 INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurface::doTestStepL"));
908 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
909 INFO_PRINTF1(_L("CEglTest_OOM_ClosePixmapSurface can only be run with SgImage-Lite"));
911 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
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++)
918 Test_MultiProcessL(KEglTestStepDllName, 1, TestStepName());
919 RetrieveExtensionDataL();
923 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
926 CloseTMSGraphicsStep();
927 return TestStepResult();
930 void CEglTest_OOM_ClosePixmapSurface::doProcessFunctionL(TInt aIdx)
932 INFO_PRINTF2(_L("CEglTest_OOM_ClosePixmapSurface::doProcessFunctionL, Process %d"),aIdx);
933 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
935 CreateEglSessionL(aIdx);
936 iEglSess->InitializeL();
937 iEglSess->OpenSgDriverL();
940 TSgImageInfo imageInfo;
941 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
942 imageInfo.iPixelFormat = iPixelFormat;
943 imageInfo.iSizeInPixels = iImageSize;
948 TInt res = sgImage.Create(imageInfo, NULL);
949 if(res != KErrNone || sgImage.IsNull())
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));
955 iSgImages.AppendL(sgImage);
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,
964 ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib,¤tConfig,1,&config_size));
965 ASSERT_TRUE(currentConfig!=0);
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))
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);
976 iSurfaces.AppendL(surface);
978 SendIndexToMainProcessL(index);
979 //now clean everything
980 CleanGraphicsResources();
981 iEglSess->CloseSgDriver();
987 @SYMTestCaseID GRAPHICS-EGL-0442
994 OOM test Check SgImages are removed when SgImage handles in multiple processes are closed
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:
1006 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
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.
1015 From client process A:
1019 Loop until exit condition met
1022 Exit condition SgImage surface creation has failed.
1024 Make the process busy by putting it into the indefinite loop.
1026 From client process B:
1032 From client process A:
1036 Check all memory has been deallocated by starting a second loop
1039 Exit condition SgImage surface creation has failed.
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.
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
1053 TVerdict CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL()
1055 SetTestStepID(_L("GRAPHICS-EGL-0442"));
1056 SetTestStepName(KOOM_CloseSgImageDifferentProcess);
1057 INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL"));
1059 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1060 INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageDifferentProcess can only be run with SgImage-Lite"));
1062 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
1065 // launch 2 processes
1066 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
1068 INFO_PRINTF1(_L("Exit: CEglTest_OOM_CloseSgImageDifferentProcess::doTestStepL"));
1069 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1070 RecordTestResultL();
1071 CloseTMSGraphicsStep();
1072 return TestStepResult();
1075 void CEglTest_OOM_CloseSgImageDifferentProcess::doProcessFunctionL(TInt aIdx)
1077 INFO_PRINTF2(_L("CEglTest_OOM_CloseSgImageDifferentProcess::doProcessFunctionL, Process %d"),aIdx);
1078 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1081 CreateEglSessionL(aIdx);
1082 iEglSess->InitializeL();
1083 iEglSess->OpenSgDriverL();
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);
1090 // create as many sgimages until it reaches out of memory
1097 TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
1098 if(res != KErrNone || sgImage.IsNull())
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));
1104 iSgImages.AppendL(sgImage);
1108 // Send to process B how many images it needs to wait for
1111 // send a TInt as a fake SgImage Id
1112 messageQueueSgId.SendBlocking(reinterpret_cast<TSgDrawableId&>(numImages));
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);
1122 // Wait for both processes to reach this point
1125 // Now process B knows how many images needs to wait for
1128 for(TInt index = 0; index<numImages; ++index)
1130 // send Id to other process
1131 messageQueueSgId.SendBlocking(iSgImages[index].Id());
1136 for(TInt index = 0; index<numImages; ++index)
1138 // receive Id from other process
1139 TSgDrawableId sgImageId;
1140 messageQueueSgId.ReceiveBlocking(sgImageId);
1142 // open sgImage with received Id
1144 ASSERT_EQUALS(sgImage.Open(sgImageId), KErrNone);
1146 // close SgImage just created
1151 // Wait for both processes to reach this point
1154 // delete all sgImages created in first process
1157 CleanGraphicsResources();
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)
1164 TInt numImages2 = 0;
1168 TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
1169 if(res != KErrNone || sgImage.IsNull())
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));
1175 iSgImages.AppendL(sgImage);
1177 // clean up these images, we don't really need them
1178 CleanGraphicsResources();
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);
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);
1193 // Wait for both processes to reach this point
1196 //now clean everything
1197 CleanupStack::PopAndDestroy(&messageQueueSgId);
1198 CleanGraphicsResources();
1199 iEglSess->CloseSgDriver();
1201 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1205 @SYMTestCaseID GRAPHICS-EGL-0443
1212 OOM test Check SgImages are removed when SgImage handles in multiple processes are closed
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:
1224 The creation of RSgImages and launching of processes is along the lines of the method outlined in GRAPHICS-EGL-RSGIMAGE_LITE-0406
1226 From the main process:
1227 From client process A:
1231 Loop until exit condition met
1234 Exit condition SgImage surface creation has failed.
1243 Check all memory has been deallocated by starting a second loop
1246 Exit condition SgImage surface creation has failed.
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.
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
1257 TVerdict CEglTest_OOM_CloseSgImageSameThread::doTestStepL()
1259 SetTestStepID(_L("GRAPHICS-EGL-0443"));
1260 SetTestStepName(KOOM_CloseSgImageSameThread);
1261 INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageSameThread::doTestStepL"));
1263 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1264 INFO_PRINTF1(_L("CEglTest_OOM_CloseSgImageSameThread can only be run with SgImage-Lite"));
1266 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
1270 CreateEglSessionL(0);
1271 iEglSess->InitializeL();
1272 iEglSess->OpenSgDriverL();
1274 // create as many sgimages until it reaches out of memory
1279 TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
1280 if(res != KErrNone || sgImage.IsNull())
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));
1286 iSgImages.AppendL(sgImage);
1289 //open a duplicate handle for the created images (can close straightaway)
1290 for(TInt index = 0; index<numImages; ++index)
1293 ASSERT_EQUALS(sgImage.Open(iSgImages[index].Id()), KErrNone);
1294 // close SgImage just created
1298 // clean up all (original) images
1299 CleanGraphicsResources();
1301 // create (again) as many sgimages until it reaches out of memory
1302 TInt numImages2 = 0;
1306 TInt res = sgImage.Create(TSgImageInfo(iImageSize, KOOMPixelFormat, ESgUsageBitOpenVgImage));
1307 if(res != KErrNone || sgImage.IsNull())
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));
1313 iSgImages.AppendL(sgImage);
1316 // clean up everything now
1317 CleanGraphicsResources();
1318 iEglSess->CloseSgDriver();
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);
1328 INFO_PRINTF1(_L("Exit: CEglTest_OOM_CloseSgImageSameThread::doTestStepL"));
1329 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
1331 RecordTestResultL();
1332 CloseTMSGraphicsStep();
1333 return TestStepResult();