--- /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 dont 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
+ }