egl/egltest/src/egltest_benchmark_sgimage.cpp
changeset 0 5d03bc08d59c
child 26 15986eb6c500
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/egltest/src/egltest_benchmark_sgimage.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,966 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @test
+*/
+
+#include <test/tefunit.h> // for ASSERT macros
+#include <e32msgqueue.h>
+
+#include <test/tprofiler.h>
+#include <test/egltestcommonprocess.h>
+#include <test/egltestcommonconversion.h>
+#include <test/egltestcommoninisettings.h>
+
+#include "egltest_benchmark_sgimage.h"
+
+//In general, there is no checking of the returned errors for the API we will be profiling
+//we assume that the basic operations will just work, as they have been tested in many other places
+//we don’t want error checking to interfere with the profiling itself 
+//to enable error checking, uncomment the macro below 
+//#define ENABLE_CHECKING_WHILST_PROFILING    1 
+
+_LIT(KBenchmarkSection, "Benchmark");
+
+//data will be used to cleanup VgImages if leaving occurs
+NONSHARABLE_CLASS(CVgImageDeleteData) : public CBase
+    {
+public:
+    CVgImageDeleteData(VGImage*& aVgImages, TInt aNumVgImages) :
+        iVgImages(aVgImages),
+        iNumVgImages(aNumVgImages)
+        {
+        }
+    ~CVgImageDeleteData();
+private:    
+    VGImage*& iVgImages;//the ownership will be transferred and cleanup function will destroy this array
+    TInt iNumVgImages;
+    };
+
+CVgImageDeleteData::~CVgImageDeleteData()
+    {
+    if(iVgImages)
+        {
+        for(TInt count=iNumVgImages-1; count >= 0; --count)
+            {
+            vgDestroyImage(iVgImages[count]);
+            }
+        delete [] iVgImages;
+        }
+    }
+
+//data will be used to cleanup RSgImages if leaving occurs
+NONSHARABLE_CLASS(CSgImageDeleteData) : public CBase
+    {
+public:
+    CSgImageDeleteData(RSgImage*& aSgImages, TInt aNumSgImages) :
+        iSgImages(aSgImages),
+        iNumSgImages(aNumSgImages)
+        {
+        }
+    ~CSgImageDeleteData();
+private:    
+    RSgImage*& iSgImages;//the ownership will be transferred and cleanup function will destroy this array
+    TInt iNumSgImages;
+    };
+
+CSgImageDeleteData::~CSgImageDeleteData()
+    {
+    if(iSgImages)
+        {
+        for(TInt count=iNumSgImages-1; count >= 0; --count)
+            {
+            iSgImages[count].Close();
+            }
+        delete [] iSgImages;
+        }
+    }
+
+//data will be used to cleanup EGLImages if leaving occurs
+NONSHARABLE_CLASS(CEglImageDeleteData) : public CBase
+    {
+public:
+    CEglImageDeleteData(CEglTestStep& aImageBaseStep, 
+            EGLImageKHR*& aEglImages, EGLDisplay& aDisplay, TInt aNumEglImages) : 
+        iImageBaseStep(aImageBaseStep), iEglImages(aEglImages), iDisplay(aDisplay), iNumEglImages(aNumEglImages)
+        {
+        }
+    ~CEglImageDeleteData();
+private:    
+	CEglTestStep& iImageBaseStep; //not owned by this object
+    EGLImageKHR*& iEglImages; //the ownership will be transferred and cleanup function will destroy this array
+    EGLDisplay iDisplay; //not owned by this object
+    TInt iNumEglImages;
+    };
+
+CEglImageDeleteData::~CEglImageDeleteData()
+    {
+    if(iEglImages)
+        {
+        CTestEglSession* eglSession = iImageBaseStep.GetEglSess(); 
+        for(TInt count=iNumEglImages-1; count >= 0; --count)
+            {    
+            eglSession->DestroyEGLImage( iDisplay, iEglImages[count]);
+            }
+        delete [] iEglImages;
+        }
+    }
+
+CEglTest_Benchmark_Base::~CEglTest_Benchmark_Base()
+    {
+    delete iProfiler;
+    }
+
+TVerdict CEglTest_Benchmark_Base::doTestStepPreambleL()
+    {
+    TVerdict verdict = CEglTestStep::doTestStepPreambleL();
+    iProfiler = CTProfiler::NewL(*this);
+    //read all parameters from config
+    CEglTestCommonIniSettings* iniParser = CEglTestCommonIniSettings::NewL();
+    CleanupStack::PushL(iniParser);
+    iNumIterations = iniParser->GetNumberOfIterations(KBenchmarkSection);
+    if(!iNumIterations)
+        {
+        ERR_PRINTF1(_L("The number iterations is not specified in INI file, the test will not be executed!"));
+        User::Leave(KErrArgument);      
+        }
+    
+    iImageSize = iniParser->GetImageSize(KBenchmarkSection);
+    if(iImageSize == TSize(0,0))
+        {
+        ERR_PRINTF1(_L("The image size whether is not specified in INI file or is TSize(0,0), the test will not be executed!"));
+        User::Leave(KErrArgument);      
+        }
+    iPixelFormat = iniParser->GetPixelFormat(KBenchmarkSection, 0);
+    if(iPixelFormat == EUidPixelFormatUnknown)
+        {
+        ERR_PRINTF1(_L("The image pixel format is not specified in INI file, the test will not be executed!"));
+        User::Leave(KErrArgument);      
+        }
+    CleanupStack::PopAndDestroy(iniParser);
+    INFO_PRINTF5(_L("**** The test will be run in following configuration: number of iterations %d, image size (%d, %d), image pixel format 0X%X"), iNumIterations, iImageSize.iWidth, iImageSize.iHeight, iPixelFormat);
+    return verdict;
+    }
+
+TVerdict CEglTest_Benchmark_Base::doTestStepPostambleL()
+    {
+    delete iProfiler; //we need to delete here to keep happy heap checking in the base class 
+    iProfiler = NULL;
+    return CEglTestStep::doTestStepPostambleL();
+    }
+
+//-------
+
+/**
+@SYMTestCaseID GRAPHICS-EGL-0434
+
+@SYMTestPriority 1
+
+@SYMPREQ 2637
+
+@SYMTestCaseDesc
+    Performance test - Creating and destroying VGImage
+@SYMTestActions
+Creating regular VGImage
+Init EGL, create context and surface
+For i = 0 to N
+    Start timer
+    Create VGImage[i] with size: 50x50 and format:  VG_sARGB_8888_PRE
+    Stop timer and record time
+End loop
+Record average time of creating VGImage
+
+Closing regular VGImage
+For i = N to 0
+    Start timer
+    Destroy VGImage[i]
+    Stop timer and record time
+End loop
+Record average time of destroying VGImage
+Destroy context, surface and terminate EGL
+
+Creating VGImage from uninitialized RSgImage
+Open RSgDriver
+Construct TSgImageInfo object with
+•   Size: 50x50
+•   PixelFormat: ESgPixelFormatARGB_8888_PRE
+•   Usage: ESgUsageBitOpenVgImage;
+
+For i = 0 to N
+    Start timer
+    Create RSgImage[i] with arguments TSgImageInfo but without initialized data
+    Stop timer and record time
+
+    Start timer
+    Create an EGLImage[i] from the RSgImage[i]
+    Stop timer and record time
+
+    Start timer
+    Create a VGImage[i] from the EGLImage[i]
+    Stop timer and record time
+
+    Record total time of  RSgImage[i], EGLImage[i] and VGImage[i] creation
+End loop
+Record average creation time of RSgImage, EGLImage, VGImage and the whole RSgImage-EGLImage-VGImage chain
+
+Destroying VGImage from RSgImage
+For i = N to 0
+    Start timer
+    Close VGImage[i]
+    Stop timer and record time
+
+    Start timer
+    Close EGLImage[i]
+    Stop timer and record time
+
+    Start timer
+    Close RSgImage[i]
+    Stop timer and record time
+
+    Record total time for closing VGImage[i], EGLImage[i] and RSgImage[i]
+End loop
+Record average closing time of RSgImage, EGLImage, VGImage, and the whole 
+VGImage-EGLImage-RSgImage chain
+
+Creating VGImage from initialized RSgImage
+For i = 0 to N
+    Start timer
+    Create RSgImage[i] with arguments TSgImageInfo a stride of 200 and a  pointer to a 
+    data array of size 10000 bytes
+    Stop timer and record time
+
+    Start timer
+    Create an EGLImage[i] from the RSgImage[i]
+    Stop timer and record time
+
+    Start timer
+    Create a VGImage[i] from the EGLImage[i]
+    Stop timer and record time
+
+    Record total time for RSgImage[i], EGLImage[i] and VGImage[i] creation
+End loop
+Record average creation time of RSgImage, EGLImage, VGImage and the whole 
+RSgImage-EGLImage-VGImage chain
+Close all VGImages, EGLImages and RSgImages
+Close RSgDriver
+
+@SYMTestExpectedResults
+The creation of RSgImage, EGLImage and VGImage must return no error. 
+The average time shall be made available in an easy-to-use format for further 
+analysis and comparison.
+*/
+TVerdict CEglTest_Benchmark_CreateCloseImage::doTestStepL()
+    {
+    SetTestStepID(_L("GRAPHICS-EGL-0434"));
+    INFO_PRINTF1(_L("CEglTest_Benchmark_CreateCloseImage::doTestStepL"));
+
+#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+	INFO_PRINTF1(_L("CEglTest_Benchmark_CreateCloseImage can only be run with SgImage-Lite"));
+	RecordTestResultL();
+	CloseTMSGraphicsStep();
+	return TestStepResult();
+#else
+    TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
+    if(!ret)
+        {
+        // The extension is not supported
+        RecordTestResultL();
+        CloseTMSGraphicsStep();
+        return TestStepResult();
+        }
+ 
+    ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
+    GetDisplayL();
+    CreateEglSessionL();
+    iEglSess->InitializeL();
+    iEglSess->OpenSgDriverL();
+ //----create pixmap and make context curent
+    TSgImageInfo imageInfo;
+    imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
+    imageInfo.iPixelFormat = iPixelFormat;
+    imageInfo.iSizeInPixels = iImageSize;
+    //create a dummy surface and context for the purpose of enabling use of VG
+    iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo, CTestEglSession::EResourceCloseSgImageLate);
+
+    //Creating regular VGImages
+    //Create an array of VGImages and push them into cleanup stack
+    //vgImageDeleteData takes ownership of the VGImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    VGImageFormat vgPixelFormat = EglTestConversion::PixelFormatToVgFormat(iPixelFormat);
+    VGImage* vgImages = NULL;
+    CVgImageDeleteData* vgImageDeleteData = new (ELeave) CVgImageDeleteData(vgImages, iNumIterations);
+    CleanupStack::PushL(vgImageDeleteData);    
+    vgImages = new (ELeave)VGImage[iNumIterations];
+    //-------   start profiling
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        //we will use VG_IMAGE_QUALITY_NONANTIALIASED flag to avoid OpenVG making the quality improvements
+        //at the expense of performance (for instance to create an extra buffer) 
+        vgImages[count] = vgCreateImage(vgPixelFormat, iImageSize.iWidth, iImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
+        //we will check the images later, to avoid interfering with the profiler
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Creating regular VGImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+    
+    //check that we created all VgImages
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        ASSERT_VG_TRUE(vgImages[count] !=  VG_INVALID_HANDLE);
+        }    
+    //Closing regular VGImage
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        vgDestroyImage(vgImages[count]);
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Closing regular VGImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+
+//---  Creating VGImage from uninitialized RSgImage  
+    //Create an array of SgImages and push them into cleanup stack
+    //sgImageData takes ownership of the SgImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    imageInfo.iUsage = ESgUsageBitOpenVgImage;
+    RSgImage* sgImages = NULL;
+    CSgImageDeleteData* sgImageData = new (ELeave)CSgImageDeleteData(sgImages, iNumIterations);
+    CleanupStack::PushL(sgImageData);    
+    sgImages = new (ELeave) RSgImage[iNumIterations];
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        const TInt res = sgImages[count].Create(imageInfo, NULL);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+        TESTL(res == KErrNone);
+#endif
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Creating uninitialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+    
+    //check that we created all sgImages successfully
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        TESTL(!sgImages[count].IsNull());
+        }    
+    
+    //Create an array of EglImages and push them into cleanup stack
+    //eglImageDeleteData takes ownership of the EglImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    EGLImageKHR* eglImages = NULL;
+    CEglImageDeleteData* eglImageDeleteData = new (ELeave)CEglImageDeleteData(*this, eglImages, iDisplay, iNumIterations); 
+    CleanupStack::PushL(eglImageDeleteData);    
+    eglImages = new (ELeave) EGLImageKHR[iNumIterations];
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {//we will use preserved flag as sgImage supposedly has some content
+        eglImages[count]= iEglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&sgImages[count],const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Creating EGLImage from uninitialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+
+    //check that we created all EglImages successfully
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        ASSERT_EGL_TRUE(eglImages[count] != EGL_NO_IMAGE_KHR)
+        }
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        vgImages[count] = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages[count]);
+        iProfiler->MarkResultSetL();
+        }   
+    iProfiler->ResultsAnalysis(_L("Creating VGImage from EGLImage, which in turn based on uninitialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+    
+    //check that we created all sgImages successfully
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        ASSERT_VG_TRUE(vgImages[count] != VG_INVALID_HANDLE);
+        }
+    
+    //Destroying VGImage/EGLImage/RSgImages
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        vgDestroyImage(vgImages[count]);
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Destroying VGImage which based on RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        const TBool res = iEglSess->DestroyEGLImage(iDisplay, eglImages[count]);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+        ASSERT_EGL_TRUE(res)
+#endif
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Destroying EGLImage which in turn based on RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        sgImages[count].Close();
+        iProfiler->MarkResultSetL();
+        }   
+    iProfiler->ResultsAnalysis(_L("Closing RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+    
+    //Creating initialized VGImage from initialized RSgImage
+    const TInt KDataStride = iImageSize.iWidth * EglTestConversion::BytePerPixel(iPixelFormat);
+    const TInt KDataSizeInByte = KDataStride *  iImageSize.iHeight;
+    TInt* data = new (ELeave) TInt[KDataSizeInByte];
+    User::LeaveIfNull(data);
+    CleanupStack::PushL(data);
+    
+    Mem::Fill(data, KDataSizeInByte / 2, 0xff);
+    Mem::FillZ(data + KDataSizeInByte / 2, KDataSizeInByte / 2);
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        const TInt res = sgImages[count].Create(imageInfo, data, KDataStride);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+        TESTL(res == KErrNone);
+#endif
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Creating initialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+    
+    //check that we created all sgImages successfully
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        TESTL(!sgImages[count].IsNull());
+        }
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {//we will use preserved flag as sgImage supposedly has some content
+        eglImages[count]= iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, 
+                &sgImages[count], const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Creating EGLImage from initialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+
+    //check that we created all EglImages successfully
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        ASSERT_EGL_TRUE(eglImages[count] != EGL_NO_IMAGE_KHR)
+        }
+    
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        vgImages[count] = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages[count]);
+        iProfiler->MarkResultSetL();
+        }   
+    iProfiler->ResultsAnalysis(_L("Creating VGImage from EGLImage which in turn based on initialized RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+
+    //check that we created all VgImages successfully
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        ASSERT_VG_TRUE(vgImages[count] != VG_INVALID_HANDLE);
+        }
+    
+    CleanupStack::PopAndDestroy(data);    
+    //Destroying VGImage/EGLImage/RSgImages
+    //no need to profile as we have already done this before
+    CleanupStack::PopAndDestroy(3, vgImageDeleteData);  // vgImageDeleteData, sgImageData, eglImageDeleteData  
+    
+    CleanAll();
+    RecordTestResultL();
+    CloseTMSGraphicsStep();
+    return TestStepResult();
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    }
+
+/**
+@SYMTestCaseID GRAPHICS-EGL-0435
+
+@SYMTestPriority 1
+
+@SYMPREQ 2637
+
+@SYMTestCaseDesc
+    Performance test – Creating and destroying VGImage from an RSgImage via Open
+@SYMTestActions
+Environmental settings:
+•   Image Size: w50 h50
+•   Simulated Load: 0%
+•   Pixel format ESgPixelFormatARGB_8888_PRE
+•   Number of benchmark iteration: N
+
+The method of creation of the RSgImage is similar to the case taken from GRAPHICS-EGL-RSGIMAGE_LITE-0406
+
+From Process A:
+Open the RSgDriver
+Create an RSgImage
+Spawn a client process B, passing in the drawable ID of the RSgImage
+Wait for process B to exit
+
+From process B:
+Open RSgDriver
+For i = 0 to N
+    Start timer
+    Open RSgImage[i]
+    Stop timer and record time
+
+    Start timer
+    Create an EGLImage[i] from the RSgImage[i]
+    Stop timer and record time
+
+    Start timer
+    Create a VGImage[i] from the EGLImage[i]
+    Stop timer and record time
+
+    Record total time of RSgImage[i] open and EGLImage[i] and VGImage[i] creation
+End loop
+Record average opening time of RSgImage, and average creation time of EGLImage, 
+VGImage and the whole RSgImage-EGLImage-VGImage chain
+For i = N to 0
+    Start timer
+    Close VGImage[i]
+    Stop timer and record time
+
+    Start timer
+    Close EGLImage[i]
+    Stop timer and record time
+
+    Start timer
+    Close RSgImage[i]
+    Stop timer and record time
+
+    Record total time for closing VGImage[i], EGLImage[i] and RSgImage[i]
+End loop
+Record average closing time of RSgImage, EGLImage, VGImage, and the whole VGImage-EGLImage-RSgImage chain
+
+Close RSgDriver
+Exit
+
+@SYMTestExpectedResults
+    The creation/opening of RSgImage, EGLImage and VGImage must return no error. 
+    The average time shall be made available in an easy-to-use format 
+    for further analysis and comparison. All allocated image memory should be freed
+*/
+TVerdict CEglTest_Benchmark_Multi_Process_CreateCloseImage::doTestStepL()
+    {
+    SetTestStepID(_L("GRAPHICS-EGL-0435"));
+    SetTestStepName(KBenchmark_Multi_Process_CreateCloseImage);
+    INFO_PRINTF1(_L("CEglTest_Benchmark_Multi_Process_CreateCloseImage::doTestStepL"));
+
+#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+	INFO_PRINTF1(_L("CEglTest_Benchmark_Multi_Process_CreateCloseImage can only be run with SgImage-Lite"));
+	RecordTestResultL();
+	CloseTMSGraphicsStep();
+	return TestStepResult();
+#else
+    TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
+    if(!ret)
+        {
+        // The extension is not supported
+        RecordTestResultL();
+        CloseTMSGraphicsStep();
+        return TestStepResult();
+        }
+
+    // launch 2 processes
+    Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
+    
+    RecordTestResultL();
+    CloseTMSGraphicsStep();
+    return TestStepResult();
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    }
+
+void CEglTest_Benchmark_Multi_Process_CreateCloseImage::doProcessFunctionL(TInt aIdx)
+    {
+    INFO_PRINTF2(_L("CEglTest_Benchmark_Multi_Process_CreateCloseImage::doProcessFunctionL, Process %d"),aIdx);
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    GetDisplayL();
+    CreateEglSessionL(aIdx);
+    iEglSess->InitializeL();    
+    iEglSess->OpenSgDriverL();
+
+    TSgImageInfo imageInfo;
+    imageInfo.iUsage = ESgUsageBitOpenVgImage;
+    imageInfo.iPixelFormat = iPixelFormat;
+    imageInfo.iSizeInPixels = iImageSize;
+    RArray<TSgDrawableId> sgIdImageList; 
+    
+    //Create an array of SgImages and push them into cleanup stack
+    //sgImageData takes ownership of the SgImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    RSgImage* sgImages = NULL;
+    CSgImageDeleteData* sgImageData = new (ELeave)CSgImageDeleteData(sgImages, iNumIterations);
+    CleanupStack::PushL(sgImageData);    
+    sgImages = new (ELeave) RSgImage[iNumIterations];
+    
+    RMsgQueue<TSgDrawableId> messageQueue;
+    User::LeaveIfError(messageQueue.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
+    CleanupClosePushL(messageQueue);
+
+    //create  iNumIterations number of SgImages in one process and send them over to the second process
+    INFO_PRINTF3(_L("Process %d, Start sending %d SgImage IDs to other process..."), aIdx, iNumIterations);
+    if(aIdx == 0)
+        {
+        for(TInt count=0; count < iNumIterations; ++count)
+            {
+            const TInt res = sgImages[count].Create(imageInfo, NULL);
+            TESTL(res == KErrNone);
+            messageQueue.SendBlocking(sgImages[count].Id());
+            }
+        }
+    else if(aIdx == 1)
+        {
+        for(TInt count=0; count < iNumIterations; ++count)
+            {
+            TSgDrawableId sgImageId;
+            messageQueue.ReceiveBlocking(sgImageId);
+            sgIdImageList.AppendL(sgImageId);
+            }
+        }
+    INFO_PRINTF3(_L("Process %d, Finish sending %d SgImage IDs to other process..."), aIdx, iNumIterations);
+    
+    CleanupStack::PopAndDestroy(&messageQueue); 
+    
+    // Wait for both processes to reach this point
+    // This is to be sure that there is no context 
+    //switching whilst the profiling occurs
+    Rendezvous(aIdx);
+    if(aIdx == 1)
+        {
+        imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
+        //create a dummy surface and context for the purpose of enabling use of VG
+        iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo, CTestEglSession::EResourceCloseSgImageLate);
+        
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            const TInt res = sgImages[count].Open(sgIdImageList[count]);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+            TESTL(res == KErrNone);
+#endif            
+            iProfiler->MarkResultSetL();
+            }
+        iProfiler->ResultsAnalysis(_L("Open RSgImage from another process"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+        
+        //check that we created all sgImages successfully
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            TESTL(!sgImages[count].IsNull());
+            }
+        
+        //Create an array of EglImages and push them into cleanup stack
+        //eglImageDeleteData takes ownership of EglImages array. 
+        //If leaving occurs or this object is destroyed from the cleanup stack 
+        //it will delete all images and then the array
+        EGLImageKHR* eglImages = NULL;
+        CEglImageDeleteData* eglImageDeleteData = new (ELeave)CEglImageDeleteData(*this, eglImages, iDisplay, iNumIterations); 
+        CleanupStack::PushL(eglImageDeleteData);    
+        eglImages = new (ELeave) EGLImageKHR[iNumIterations];
+        
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {//we will use preserved flag as sgImage supposedly has some content
+            eglImages[count]= iEglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&sgImages[count],const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
+            iProfiler->MarkResultSetL();
+            }
+        iProfiler->ResultsAnalysis(_L("Creating EGLImage from RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+        
+        //check that we created all EglImages successfully
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            ASSERT_EGL_TRUE(eglImages[count] != EGL_NO_IMAGE_KHR)
+            }
+        
+        //Create an array of VGImages and push them into cleanup stack
+        //vgImageDeleteData takes ownership of VgImages array. 
+        //If leaving occurs or this object is destroyed from the cleanup stack 
+        //it will delete all images and then the array
+        VGImage* vgImages = NULL;
+        CVgImageDeleteData* vgImageDeleteData = new (ELeave) CVgImageDeleteData(vgImages, iNumIterations);
+        CleanupStack::PushL(vgImageDeleteData);
+        vgImages = new (ELeave) VGImage[iNumIterations];
+        
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            vgImages[count] = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages[count]);
+            iProfiler->MarkResultSetL();
+            }   
+        iProfiler->ResultsAnalysis(_L("Creating VGImage from EGLImage, which in turn based on SgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+
+        //check that we created all VgImages successfully
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            ASSERT_VG_TRUE(vgImages[count] != VG_INVALID_HANDLE);
+            }   
+        
+        sgIdImageList.Reset();
+        
+        //Destroying VGImage/EglImage/RSgImages
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            vgDestroyImage(vgImages[count]);
+            iProfiler->MarkResultSetL();
+            }
+        iProfiler->ResultsAnalysis(_L("Destroying VGImage based on EGLImage which in turn based on RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+        
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            const TBool res = iEglSess->DestroyEGLImage(iDisplay, eglImages[count]);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+            ASSERT_EGL_TRUE(res);
+#endif            
+            iProfiler->MarkResultSetL();
+            }
+        iProfiler->ResultsAnalysis(_L("Destroying EGLImage which based on RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+        
+        iProfiler->InitResults();
+        for(TInt count=iNumIterations-1; count >= 0; --count)
+            {
+            sgImages[count].Close();
+            iProfiler->MarkResultSetL();
+            }   
+        iProfiler->ResultsAnalysis(_L("Closing RSgImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);    
+        CleanupStack::PopAndDestroy(2, eglImageDeleteData); //eglImageDeleteData, vgImageDeleteData     
+        }
+
+    // Wait for both processes to reach this point
+    Rendezvous(aIdx);
+    CleanupStack::PopAndDestroy(sgImageData);
+    CleanAll();
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    }
+
+
+/**
+@SYMTestCaseID GRAPHICS-EGL-0436
+
+@SYMTestPriority 1
+
+@SYMPREQ 2637
+
+@SYMTestCaseDesc
+    Performance test - Drawing VGImage
+@SYMTestActions
+Environmental settings:
+•   Image Size: w50 h50
+•   Simulated Load: 0%
+•   Pixel format ESgPixelFormatARGB_8888_PRE
+•   Number of benchmark iteration: N (may vary depending on hardware capacity)
+
+Creating regular VGImage
+Init EGL, create context and surface
+For i = 0 to N
+    Create VGImage[i] with size: 50x50 and format:  VG_sARGB_8888_PRE
+    SetSubData for VGImage[i] 
+End loop
+
+Draw VGImage
+For i = N to 0
+    Start timer
+    Draw VGImage[i]
+    Stop timer and record time
+End loop
+Record average time of drawing VGImage
+
+Closing regular VGImage
+For i = N to 0
+    Destroy VGImage[i]
+End loop
+
+Creating VGImage from initialized RSgImage
+Open RSgDriver
+Construct TSgImageInfo object with
+•   Size: 50x50
+•   PixelFormat: ESgPixelFormatARGB_8888_PRE
+•   Usage: ESgUsageBitOpenVgImage;
+
+For i = N to 0
+    Create RSgImage[i] with arguments TSgImageInfo with initialized data which were supplied to regular VGImage 
+    Create an EGLImage[i] from the RSgImage[i]
+    Create a VGImage[i] from the EGLImage[i]
+End loop
+
+Draw VGImage which is based on RSgImage
+For i = N to 0
+    Start timer
+    Draw VGImage[i]
+    Stop timer and record time
+End loop
+Record average time of drawing VGImage
+
+Close all VGImages, EGLImages and RSgImages
+Close RSgDriver
+
+@SYMTestExpectedResults
+The creation of RSgImage, EGLImage and VGImage must return no error. 
+The average drawing time of regular VGImage and VGImage with underlying RSgImage is 
+made available in an easy-to-use format for further analysis and comparison.
+*/
+TVerdict CEglTest_Benchmark_DrawImage::doTestStepL()
+    {
+    SetTestStepID(_L("GRAPHICS-EGL-0436"));
+    INFO_PRINTF1(_L("CEglTest_Benchmark_DrawImage::doTestStepL"));
+
+#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    INFO_PRINTF1(_L("CEglTest_Benchmark_DrawImage can only be run with SgImage-Lite"));
+    RecordTestResultL();
+    CloseTMSGraphicsStep();
+    return TestStepResult();
+#else
+    TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
+    if(!ret)
+        {
+        // The extension is not supported
+        RecordTestResultL();
+        CloseTMSGraphicsStep();
+        return TestStepResult();
+        }
+ 
+    ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
+    GetDisplayL();
+    CreateEglSessionL();
+    iEglSess->InitializeL();
+    iEglSess->OpenSgDriverL();
+ //----create pixmap and make context curent
+    TSgImageInfo imageInfo;
+    imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
+    imageInfo.iPixelFormat = iPixelFormat;
+    imageInfo.iSizeInPixels = iImageSize;
+    //create a dummy surface and context for the purpose of enabling use of VG
+    iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo, CTestEglSession::EResourceCloseSgImageLate);
+
+    const TInt KDataStride = iImageSize.iWidth * EglTestConversion::BytePerPixel(iPixelFormat);
+    const TInt KDataSizeInByte = KDataStride *  iImageSize.iHeight;
+    TInt* data = new (ELeave) TInt[KDataSizeInByte];
+    User::LeaveIfNull(data);
+    CleanupStack::PushL(data);
+    
+    Mem::Fill(data, KDataSizeInByte / 2, 0xff);
+    Mem::FillZ(data + KDataSizeInByte / 2, KDataSizeInByte / 2);
+
+    //Creating regular VGImages
+    //Create an array of VGImages and push them into cleanup stack
+    //vgImageDeleteData takes ownership of the VGImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    VGImageFormat vgPixelFormat = EglTestConversion::PixelFormatToVgFormat(iPixelFormat);
+    VGImage* vgImages = NULL;
+    CVgImageDeleteData* vgImageDeleteData = new (ELeave) CVgImageDeleteData(vgImages, iNumIterations);
+    CleanupStack::PushL(vgImageDeleteData);    
+    vgImages = new (ELeave)VGImage[iNumIterations];
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        //we will use VG_IMAGE_QUALITY_NONANTIALIASED flag to avoid OpenVG making the quality improvements
+        //at the expense of performance (for instance to create an extra buffer) 
+        vgImages[count] = vgCreateImage(vgPixelFormat, iImageSize.iWidth, iImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
+        ASSERT_VG_TRUE(vgImages[count] !=  VG_INVALID_HANDLE);
+        
+        vgImageSubData(vgImages[count],
+                data, KDataStride,
+                vgPixelFormat,
+                0, 0, iImageSize.iWidth, iImageSize.iHeight);
+        ASSERT_VG_ERROR(VG_NO_ERROR);
+        }
+    
+    //--------- start profiling
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        vgDrawImage(vgImages[count]);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+        ASSERT_VG_ERROR(VG_NO_ERROR);
+#endif            
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Drawing regular VGImage"), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+    //--------- stop profiling
+    
+    //destroy vgImages
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        vgDestroyImage(vgImages[count]);
+        ASSERT_VG_ERROR(VG_NO_ERROR);
+        vgImages[count]=VG_INVALID_HANDLE;
+        }
+    
+    //Create an array of SgImages and push them into cleanup stack
+    //sgImageData takes ownership of the SgImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    imageInfo.iUsage = ESgUsageBitOpenVgImage;
+    RSgImage* sgImages = NULL;
+    CSgImageDeleteData* sgImageData = new (ELeave)CSgImageDeleteData(sgImages, iNumIterations);
+    CleanupStack::PushL(sgImageData);    
+    sgImages = new (ELeave) RSgImage[iNumIterations];
+    
+    //Create an array of EglImages and push them into cleanup stack
+    //eglImageDeleteData takes ownership of the EglImages array. 
+    //If leaving occurs or this object is destroyed from the cleanup stack 
+    //it will delete all images and then the array
+    EGLImageKHR* eglImages = NULL;
+    CEglImageDeleteData* eglImageDeleteData = new (ELeave)CEglImageDeleteData(*this, eglImages, iDisplay, iNumIterations); 
+    CleanupStack::PushL(eglImageDeleteData);    
+    eglImages = new (ELeave) EGLImageKHR[iNumIterations];
+    
+    //Creating VGImage from initialized RSgImage
+    for(TInt count=iNumIterations-1; count >= 0; --count)
+        {
+        const TInt res = sgImages[count].Create(imageInfo, data, KDataStride);
+        TESTL(res == KErrNone);
+        TESTL(!sgImages[count].IsNull());
+
+        eglImages[count]= iEglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&sgImages[count],const_cast<EGLint *> (KEglImageAttribsPreservedTrue));
+        ASSERT_EGL_TRUE(eglImages[count] != EGL_NO_IMAGE_KHR)
+
+        vgImages[count] = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImages[count]);
+        ASSERT_VG_TRUE(vgImages[count] != VG_INVALID_HANDLE);
+        }
+    
+    //---------------start profiling
+    iProfiler->InitResults();
+    for(TInt count=iNumIterations - 1; count >= 0; --count)
+        {
+        vgDrawImage(vgImages[count]);
+#ifdef ENABLE_CHECKING_WHILST_PROFILING
+        ASSERT_VG_ERROR(VG_NO_ERROR);
+#endif            
+        iProfiler->MarkResultSetL();
+        }
+    iProfiler->ResultsAnalysis(_L("Drawing VGImage with underlying RSgImage "), 0, EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), EglTestConversion::PixelFormatToDisplayMode(iPixelFormat), iNumIterations);   
+    //----------------stop profiling
+    
+    //Destroying VGImage/EGLImage/RSgImages
+    //no need to profile as we have already done this before
+    CleanupStack::PopAndDestroy(4, data);  // data, vgImageDeleteData, sgImageData, eglImageDeleteData  
+    
+    CleanAll();
+    RecordTestResultL();
+    CloseTMSGraphicsStep();
+    return TestStepResult();
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    }