os/graphics/egl/egltest/src/egltest_image_multiprocess.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @test
    19 */
    20 
    21 #include <test/tefunit.h> // for ASSERT macros
    22 #include <iniparser.h>
    23 #include <e32msgqueue.h>
    24 
    25 #include "egltest_image_multiprocess.h"
    26 
    27 #include <test/egltestcommonconversion.h>
    28 #include <test/egltestcommoninisettings.h>
    29 #include <test/egltestcommonsgimageinfo.h>
    30 #include <test/egltestcommonprocess.h>
    31 
    32 //
    33 // Constant definitions
    34 //
    35 const TInt KNumProcesses = 8;
    36 const TInt KNumImages = 4;
    37 #define KImageSize TSize(100,100)	// use #define to avoid global temporary constructors
    38 
    39 
    40 /**
    41 @SYMTestCaseID GRAPHICS-EGL-0160
    42 
    43 @SYMTestPriority 1
    44 
    45 @SYMPREQ 39
    46 
    47 @SYMREQ See SGL.GT0386.401 document
    48 
    49 @SYMTestCaseDesc
    50 Check if EGL Implementation allows two processes to work in parallel.
    51 A process can create an EGLImage from the same RSgImage that already has been linked to an EGLImage by another process.
    52 
    53 @SYMTestActions
    54 Main Process: creates an RsgImage and starts Process and Process.
    55 Process1: Creates an EGLImage from the RsgImage previous mentioned
    56 --------
    57 Process2: Creates an EGLImage from the RsgImage previous mentioned and check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR
    58 --------
    59 Process1: Closes the EGLImage
    60 Process2: Closes the EGLImage
    61 Main Process: Closes the RsgImage
    62 
    63 @SYMTestExpectedResults
    64 No errors within both processes.
    65 No memory or handle leaks
    66 */
    67 TVerdict CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doTestStepL()
    68 	{
    69 	SetTestStepID(_L("GRAPHICS-EGL-0160"));
    70 	SetTestStepName(KEGL_Image_Multi_Process_Sibling_Basic);
    71 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doTestStepL"));
    72 
    73 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
    74 	if(!ret)
    75 		{
    76 		// The extension is not supported
    77 		RecordTestResultL();
    78 		CloseTMSGraphicsStep();
    79 		return TestStepResult();
    80 		}
    81 
    82 	// Create display object
    83 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
    84     GetDisplayL();
    85     CreateEglSessionL();
    86 	iEglSess->InitializeL();
    87 	iEglSess->OpenSgDriverL();
    88 
    89 	// create a reference bitmap (we give index 0, as there's only 1 image in this test case)
    90 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
    91 	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
    92 	CleanupStack::PushL(bitmap);
    93 
    94     // Create an RSgImage
    95 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KImageSize);
    96 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
    97 	imageInfo.iShareable = ETrue;
    98 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
    99     RSgImage sgImage;
   100 	CleanupClosePushL(sgImage);
   101 	ASSERT_EQUALS(sgImage.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
   102 
   103 	// launch 2 processes
   104 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName(), sgImage.Id());
   105 
   106 	// destroy sgImage
   107 	CleanupStack::PopAndDestroy(2, bitmap);
   108 
   109 	// clean everything
   110 	CleanAll();
   111 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doTestStepL"));
   112 	RecordTestResultL();
   113 	CloseTMSGraphicsStep();
   114 	return TestStepResult();
   115 	}
   116 
   117 void CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId)
   118 	{
   119 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL, Process %d"),aIdx);
   120 	GetDisplayL();
   121 	CreateEglSessionL(aIdx);
   122 	iEglSess->InitializeL();
   123 	iEglSess->OpenSgDriverL();
   124 
   125 	RSgImage sgImageFromId;
   126 	CleanupClosePushL(sgImageFromId);
   127 	ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone);
   128 
   129 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   130 	EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue);
   131 	ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR);
   132 	CleanupStack::PopAndDestroy(&sgImageFromId);
   133 
   134 	INFO_PRINTF2(_L("Process %d, EGLImage successfully created, now destroying it"),aIdx);
   135 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage));
   136 
   137 	// cleanup
   138 	CleanAll();
   139 	}
   140 
   141 
   142 /**
   143 @SYMTestCaseID GRAPHICS-EGL-0161
   144 
   145 @SYMTestPriority 1
   146 
   147 @SYMPREQ 39
   148 
   149 @SYMREQ See SGL.GT0386.401 document
   150 
   151 @SYMTestCaseDesc
   152 Check if EGL Implementation allows two processes to work in parallel.
   153 
   154 @SYMTestActions
   155 Run two processes that independently perform the same actions detailed below.
   156 This test will check for the “VG_KHR_EGL_image” extension, if it is not
   157 supported on this platform then the test will return immediately without failure.
   158 Create and fully construct an RSgImage object
   159 •	Set the iUsage bits to ESgUsageBitOpenVgImage
   160 Pass the RSgImage object into eglCreateImageKHR() with
   161 •	The target parameter set to EGL_NATIVE_PIXMAP_KHR
   162 •	Use the current display and EGL_NO_CONTEXT
   163 •	Use a NULL attr_list
   164 Check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR
   165 Use vgCreateEGLImageTargetKHR() to construct a VGImage object from the EGLImage.
   166 •	Check for errors (VGInvalidHandle is not returned)
   167 Create a second RSgImage, and use it to create a pixmap surface that is
   168 compatible as a target for the VGImage to be drawn to.
   169 •	Set the iUsage bit to ESgUsageBitOpenVgSurface
   170 •	Use the same pixel format as the RSgImage above.
   171 Now that a eglContext and an OpenVG context have been created, use the
   172 OpenVG API vgClearImage to clear to a chosen colour the VGImage previously
   173 returned by eglCreateImageKHR.
   174 Use OpenVG to draw the just drawn VGImage to the pixmap surface currently
   175 linked to the context.
   176 Call eglWaitClient() to finish the above drawing instructions synchronously.
   177 Destroy the original image data
   178 •	Pass the VGImage into vgDestroyImage()
   179 •	Pass the EGLImage into eglDestroyImageKHR()
   180 •	Close the first RSgImage
   181 •	Check that the pixmap surface contains expected pixel values using
   182 OpenVG APIs, vgReadPixels.
   183 Close the second RSgImage and destroy the pixmap surface
   184 Check for memory and handle leaks
   185 
   186 @SYMTestExpectedResults
   187 Pixmap surface has the expected contents in both processes (within tolerance)
   188 No memory or handle leaks
   189 */
   190 TVerdict CEglTest_EGL_Image_Multi_Process_Parallel::doTestStepL()
   191 	{
   192 	SetTestStepID(_L("GRAPHICS-EGL-0161"));
   193 	SetTestStepName(KEGL_Image_Multi_Process_Parallel);
   194 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_Parallel::doTestStepL"));
   195 
   196 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
   197 	if(!ret)
   198 		{
   199 		// The extension is not supported
   200 		RecordTestResultL();
   201 		CloseTMSGraphicsStep();
   202 		return TestStepResult();
   203 		}
   204 
   205 	// launch 2 processes
   206 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
   207 
   208 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Parallel::doTestStepL"));
   209 	RecordTestResultL();
   210 	CloseTMSGraphicsStep();
   211 	return TestStepResult();
   212 	}
   213 
   214 void CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL(TInt aIdx)
   215 	{
   216 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL, Process %d"),aIdx);
   217 	GetDisplayL();
   218 	CreateEglSessionL(aIdx);
   219 	iEglSess->InitializeL();
   220 	iEglSess->OpenSgDriverL();
   221 
   222 	// create a reference bitmap (we give index 3 for example, as there's only 1 image in this test case)
   223 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   224 	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 3);
   225 	CleanupStack::PushL(bitmap);
   226 
   227 	// Create an RSgImage
   228 	INFO_PRINTF2(_L("Process %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
   229 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KImageSize);
   230     RSgImage rSgImageLocal;
   231 	CleanupClosePushL(rSgImageLocal);
   232 	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
   233 
   234 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   235 	EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
   236 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
   237 	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
   238 	CleanupStack::PopAndDestroy(bitmap);
   239 
   240 	INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
   241 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
   242 	TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
   243 	// Create a pixmap surface matching the native image pixel format
   244 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly);
   245 
   246 	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
   247 	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
   248 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
   249 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
   250 
   251 	// Copy the source VGImage to the surface
   252 	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   253 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   254 	eglWaitClient();
   255 
   256 	// destroy VGImage
   257 	vgDestroyImage(vgImageLocal);
   258 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   259 
   260 	// we can now compare the VgImage to the one we would expect for this particular process
   261 	CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 3);
   262 	CleanupStack::PushL(refBitmap);
   263 	iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   264 	CleanupStack::PopAndDestroy(refBitmap);
   265 	INFO_PRINTF2(_L("Drawing successful, Process %d"),aIdx);
   266 
   267 	// cleanup
   268 	CleanAll();
   269 	}
   270 
   271 /**
   272 @SYMTestCaseID GRAPHICS-EGL-0162
   273 
   274 @SYMTestPriority 1
   275 
   276 @SYMPREQ 39
   277 
   278 @SYMREQ See SGL.GT0386.401 document
   279 
   280 @SYMTestCaseDesc
   281 Check if EGL Implementation allows two processes to work in parallel.
   282 A process can create an EGLImage from the same RSgImage that already has been linked to an EGLImage by another process.
   283 Both process can create a VGImage from it.
   284 Another process uses the VGImage as a target
   285 One process uses the VGImage as a source being able to see the drawing done by the other process
   286 
   287 @SYMTestActions
   288 Main Process: creates an RsgImage and starts Process and Process.
   289 Process1: Creates an egl context and a pizmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   290 Process2: Creates an egl context and a pizmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   291 Process1: Changes the contents of the VGImage
   292 --------
   293 Process1: Closes the VGImage and the EGLImage
   294 Process2: Draws the VGImage to the surface and checks if the contets match the reference bitmap plus the chages made by the first process.
   295 Process2: Closes the VGImage and the EGLImage
   296 Main Process: Closes the RsgImage
   297 
   298 @SYMTestExpectedResults
   299 No errors within both processes.
   300 The content of the pixmap surface will match the one of the reference bitmap changed by the first process.
   301 No memory or handle leaks.
   302 */
   303 TVerdict CEglTest_EGL_Image_Multi_Process_Sibling_CheckContents::doTestStepL()
   304 	{
   305 	SetTestStepID(_L("GRAPHICS-EGL-0162"));
   306 	SetTestStepName(KEGL_Image_Multi_Process_Sibling_CheckContents);
   307 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_Sibling_CheckContents::doTestStepL"));
   308 
   309 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
   310 	if(!ret)
   311 		{
   312 		// The extension is not supported
   313 		RecordTestResultL();
   314 		CloseTMSGraphicsStep();
   315 		return TestStepResult();
   316 		}
   317 
   318 	// Create display object
   319 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
   320     GetDisplayL();
   321     CreateEglSessionL();
   322 	iEglSess->InitializeL();
   323 	iEglSess->OpenSgDriverL();
   324 
   325 	// create a reference bitmap (we give index 0, as there's only 1 image in this test case)
   326 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   327 	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
   328 	CleanupStack::PushL(bitmap);
   329 
   330     // Create an RSgImage
   331 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KImageSize);
   332 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   333 	imageInfo.iShareable = ETrue;
   334 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   335     RSgImage sgImage;
   336 	CleanupClosePushL(sgImage);
   337 	ASSERT_EQUALS(sgImage.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
   338 
   339 	// launch 2 processes
   340 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName(), sgImage.Id());
   341 
   342 	// destroy sgImage
   343 	CleanupStack::PopAndDestroy(&sgImage);
   344 	CleanupStack::PopAndDestroy(bitmap);
   345 
   346 	// clean everything
   347 	CleanAll();
   348 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Sibling_CheckContents::doTestStepL"));
   349     RecordTestResultL();
   350 	CloseTMSGraphicsStep();
   351 	return TestStepResult();
   352 	}
   353 
   354 void CEglTest_EGL_Image_Multi_Process_Sibling_CheckContents::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId)
   355 	{
   356 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Sibling_CheckContents::doProcessFunctionL, Process %d"),aIdx);
   357 	GetDisplayL();
   358 	CreateEglSessionL(aIdx);
   359 	iEglSess->InitializeL();
   360 	iEglSess->OpenSgDriverL();
   361 
   362 	RSgImage sgImageFromId;
   363 	CleanupClosePushL(sgImageFromId);
   364 	ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone);
   365 
   366 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   367 	EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue);
   368 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
   369 	CleanupStack::PopAndDestroy(&sgImageFromId);
   370 
   371 	INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
   372 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
   373 	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
   374 	// Create a pixmap surface matching the native image pixel format
   375 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
   376 
   377 	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
   378 	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
   379 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
   380 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
   381 
   382 	if(aIdx == 0)
   383 		{
   384 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   385 		CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4);
   386     	// Add pixel data to the VGImage reference from the bitmap reference.
   387         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
   388 		TSize bitmapSize = bitmap->SizeInPixels();
   389     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
   390     	TInt stride = bitmap->DataStride();
   391     	address += (bitmapSize.iHeight - 1) * stride;
   392         vgImageSubData(vgImageLocal, address, -stride, KDefaultSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
   393 		delete bitmap;
   394 		bitmap = NULL;
   395 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   396 		eglWaitClient();
   397 		}
   398 
   399 	// Wait for both processes to reach this point (process 0 will have updated the VGImage)
   400 	Rendezvous(aIdx);
   401 
   402 	if(aIdx == 1)
   403 		{
   404 		INFO_PRINTF2(_L("Process %d, Drawing the VGImage to the current surface"),aIdx);
   405 		// Copy the source VGImage to the surface
   406     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   407 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   408 		eglWaitClient();
   409 
   410 		// we can now compare the VgImage to the one we expect after changing it in the other process
   411 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   412 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4);
   413 		CleanupStack::PushL(refBitmap);
   414 		iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   415 		CleanupStack::PopAndDestroy(refBitmap);
   416 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
   417 		}
   418 
   419 	// destroy VGImage
   420 	vgDestroyImage(vgImageLocal);
   421 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   422 
   423 	// cleanup
   424 	CleanAll();
   425 	}
   426 
   427 /**
   428 @SYMTestCaseID GRAPHICS-EGL-0350
   429 
   430 @SYMTestPriority 1
   431 
   432 @SYMPREQ 2637
   433 
   434 @SYMTestCaseDesc
   435 Check sharing SgImage between 2 processes where a writer process populates SgImage through VgImage and a reader process draws SgImage to window surface.
   436 
   437 @SYMTestActions
   438 Main Process: starts Process1 and Process2.
   439 Process1: Creates an RsgImage and passes RsgImage ID to process2. Creates an egl context and a pixmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   440 Process2: Creates an RsgImage using RsgImage ID passed into it. Creates an egl context and a pixmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   441 --------
   442 Process2: Draws the VGImage to the surface before Process1 changes the contents of the VGImage.
   443 --------
   444 Process1: Changes the contents of the VGImage
   445 --------
   446 Process2: Draws the VGImage to the surface after Process1 changes the contents of the VGImage and checks if the contets match the reference bitmap plus the chages made by the process1.
   447 Process1: Closes the VGImage, the EGLImage, the RsgImage.
   448 Process2: Closes the VGImage, the EGLImage, the RsgImage.
   449 
   450 @SYMTestExpectedResults
   451 No errors within both processes.
   452 The content of the pixmap surface will match the one of the reference bitmap changed by the first process.
   453 No memory or handle leaks.
   454 */
   455 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_Source::doTestStepL()
   456     {
   457     SetTestStepID(_L("GRAPHICS-EGL-0350"));
   458 	SetTestStepName(KEGL_Image_Multi_Process_VgImage_Source);
   459 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_Source::doTestStepL"));
   460 
   461 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
   462 	if(!ret)
   463 		{
   464 		// The extension is not supported
   465 		RecordTestResultL();
   466 		CloseTMSGraphicsStep();
   467 		return TestStepResult();
   468 		}
   469 
   470 	// launch 2 processes
   471 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
   472 
   473     INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_VgImage_Source::doTestStepL"));
   474     RecordTestResultL();
   475     CloseTMSGraphicsStep();
   476     return TestStepResult();
   477     }
   478 
   479 void CEglTest_EGL_Image_Multi_Process_VgImage_Source::doProcessFunctionL(TInt aIdx)
   480     {
   481     INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_VgImage_Source::doProcessFunctionL, Process %d"),aIdx);
   482 	GetDisplayL();
   483 	CreateEglSessionL(aIdx);
   484 	iEglSess->InitializeL();
   485 	iEglSess->OpenSgDriverL();
   486 
   487     RMsgQueue<TSgDrawableId> messageQueue;
   488     User::LeaveIfError(messageQueue.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
   489     CleanupClosePushL(messageQueue);
   490 
   491     RSgImage rSgImageLocal;
   492 	if(aIdx == 0)
   493         {
   494     	// create a reference bitmap (we give index 0, as there's only 1 image in this test case)
   495     	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   496     	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
   497     	CleanupStack::PushL(bitmap);
   498 
   499     	// Create an RSgImage
   500     	INFO_PRINTF2(_L("Process %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
   501     	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KImageSize);
   502 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   503     	imageInfo.iShareable = ETrue;
   504 #endif
   505     	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
   506         CleanupStack::PopAndDestroy(bitmap);
   507 
   508         INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx);
   509         messageQueue.SendBlocking(rSgImageLocal.Id());
   510         }
   511     else if(aIdx == 1)
   512         {
   513         INFO_PRINTF2(_L("Process %d, Receiving SgImage ID from other process..."), aIdx);
   514         TSgDrawableId sgImageId;
   515         messageQueue.ReceiveBlocking(sgImageId);
   516         ASSERT_EQUALS(rSgImageLocal.Open(sgImageId), KErrNone);
   517         }
   518 
   519 	// Wait for both processes to reach this point
   520     Rendezvous(aIdx);
   521     
   522     INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   523 	CleanupClosePushL(rSgImageLocal);
   524 	EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
   525 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
   526 	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
   527 
   528 	INFO_PRINTF2(_L("Creating a Surface and a Context bound to OpenVG, Process %d"),aIdx);
   529 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
   530 	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
   531 	// Create a pixmap surface matching the native image pixel format
   532 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
   533 
   534 	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
   535 	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
   536 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
   537 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
   538 
   539     if(aIdx == 1)
   540         {
   541         INFO_PRINTF2(_L("Process %d, Drawing the VGImage to the current surface before changing contents of the VGImage"),aIdx);
   542     	// Copy the source VGImage to the surface
   543     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   544     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   545     	eglWaitClient();
   546 
   547     	// we can now compare the VgImage to the one we expect before we apply any change to it
   548 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   549 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
   550 		CleanupStack::PushL(refBitmap);
   551 		iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   552 		CleanupStack::PopAndDestroy(refBitmap);
   553 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
   554         }
   555 
   556 	// Wait for both processes to reach this point
   557     Rendezvous(aIdx);
   558 
   559     if(aIdx == 0)
   560         {
   561         INFO_PRINTF2(_L("Process %d, Changing contents of the VGImage"),aIdx);
   562         TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   563         CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4);
   564         // Add pixel data to the VGImage reference from the bitmap reference.
   565         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
   566         TSize bitmapSize = bitmap->SizeInPixels();
   567     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
   568     	TInt stride = bitmap->DataStride();
   569     	address += (bitmapSize.iHeight - 1) * stride;
   570         vgImageSubData(vgImageLocal, address, -stride, KDefaultSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
   571         delete bitmap;
   572         bitmap = NULL;
   573     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   574     	eglWaitClient();
   575         }
   576 
   577 	// Wait for both processes to reach this point (process 0 will have updated the VGImage)
   578 	Rendezvous(aIdx);
   579 
   580 	if(aIdx == 1)
   581 		{
   582         INFO_PRINTF2(_L("Drawing the VGImage to the current surface after changing contents of the VGImage, Process %d"),aIdx);
   583         // Copy the source VGImage to the surface
   584     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   585 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   586 		eglWaitClient();
   587 
   588 		// we can now compare the VgImage to the one we expect after changing it in the other process
   589 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   590 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4);
   591 		CleanupStack::PushL(refBitmap);
   592 		iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   593 		CleanupStack::PopAndDestroy(refBitmap);
   594 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
   595         }
   596 
   597 	vgDestroyImage(vgImageLocal);
   598 	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
   599 
   600 	CleanupStack::PopAndDestroy(&messageQueue);
   601     CleanAll();
   602     }
   603 
   604 /**
   605 @SYMTestCaseID GRAPHICS-EGL-0351
   606 
   607 @SYMTestPriority 1
   608 
   609 @SYMPREQ 2637
   610 
   611 @SYMTestCaseDesc
   612 Check when sharing SgImage between 2 processes where a writer process populates SgImage through VgImage and a reader process draws SgImage to window surface,
   613 process2 has reference to SgImage even after process1 loses all references to SgImage
   614 
   615 @SYMTestActions
   616 Main Process: starts Process1 and Process2.
   617 Process1: Creates an RsgImage and passes RsgImage ID to process2. Creates an egl context and a pixmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   618 Process2: Creates an RsgImage using RsgImage ID passed into it. Creates an egl context and a pixmap surface linked to it. Creates an EGLImage from the RsgImage previous mentioned. Creates a VGImage from the EGLImage.
   619 Process2: Drawss the VGImage to the surface before Process1 changes the contents of the VGImage.
   620 --------
   621 Process1: Changes the contents of the VGImage
   622 Process1: Closes the VGImage, the EGLImage, the RsgImage.
   623 --------
   624 Process2: Draws the VGImage to the surface after Process1 changes the contents of the VGImage and checks if the contents match the reference bitmap plus the changes made by the process1.
   625 Process2: Closes the VGImage, the EGLImage, the RsgImage.
   626 
   627 @SYMTestExpectedResults
   628 No errors within both processes.
   629 The content of the pixmap surface will match the one of the reference bitmap changed by the process1.
   630 No memory or handle leaks.
   631 */
   632 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_DrawAfterTerminate::doTestStepL()
   633     {
   634     SetTestStepID(_L("GRAPHICS-EGL-0351"));
   635 	SetTestStepName(KEGL_Image_Multi_Process_VgImage_DrawAfterTerminate);
   636     INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_DrawAfterTerminate::doTestStepL"));
   637 
   638 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
   639 	if(!ret)
   640 		{
   641 		// The extension is not supported
   642 		RecordTestResultL();
   643 		CloseTMSGraphicsStep();
   644 		return TestStepResult();
   645 		}
   646 
   647 	// This test is performed for default pixel format
   648 	PrintUsedPixelConfiguration();
   649 
   650 	// launch 2 processes
   651  	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
   652 
   653 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_VgImage_DrawAfterTerminate::doTestStepL"));
   654     RecordTestResultL();
   655     CloseTMSGraphicsStep();
   656     return TestStepResult();
   657     }
   658 
   659 void CEglTest_EGL_Image_Multi_Process_VgImage_DrawAfterTerminate::doProcessFunctionL(TInt aIdx)
   660     {
   661     INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_VgImage_DrawAfterTerminate::doProcessFunctionL, Process %d"),aIdx);
   662     GetDisplayL();
   663     CreateEglSessionL(aIdx);
   664     iEglSess->InitializeL();
   665     iEglSess->OpenSgDriverL();
   666 
   667     RMsgQueue<TSgDrawableId> messageQueue;
   668     User::LeaveIfError(messageQueue.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
   669     CleanupClosePushL(messageQueue);
   670 
   671     RSgImage rSgImageLocal;
   672     if(aIdx == 0)
   673         {
   674     	// create a reference bitmap (we give index 0, as there's only 1 image in this test case)
   675     	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   676     	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
   677     	CleanupStack::PushL(bitmap);
   678 
   679     	// Create an RSgImage
   680     	INFO_PRINTF2(_L("Process %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
   681     	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KImageSize);
   682 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   683     	imageInfo.iShareable = ETrue;
   684 #endif
   685     	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
   686         CleanupStack::PopAndDestroy(bitmap);
   687 
   688         INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx);
   689         messageQueue.SendBlocking(rSgImageLocal.Id());
   690         }
   691     else if(aIdx == 1)
   692         {
   693         INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx);
   694         TSgDrawableId sgImageId;
   695         messageQueue.ReceiveBlocking(sgImageId);
   696         ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone);
   697         }
   698 
   699 	// Wait for both processes to reach this point
   700     Rendezvous(aIdx);
   701 
   702 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   703 	CleanupClosePushL(rSgImageLocal);
   704 	EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
   705 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
   706 	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
   707 
   708 	INFO_PRINTF2(_L("Creating a Surface and a Context bound to OpenVG, Process %d"),aIdx);
   709 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
   710 	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
   711 	// Create a pixmap surface matching the native image pixel format
   712 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
   713 
   714 	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
   715 	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
   716 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
   717 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
   718 
   719     if(aIdx == 1)
   720         {
   721         INFO_PRINTF2(_L("Process %d, Drawing the VGImage to the current surface before changing contents of the VGImage"),aIdx);
   722         // Copy the source VGImage to the surface
   723     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   724     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   725     	eglWaitClient();
   726 
   727 
   728     	// we can now compare the VgImage to the one we expect before we apply any change to it
   729 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   730 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0);
   731 		CleanupStack::PushL(refBitmap);
   732 		iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   733 		CleanupStack::PopAndDestroy(refBitmap);
   734 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
   735         }
   736 
   737 	// Wait for both processes to reach this point
   738     Rendezvous(aIdx);
   739 
   740     if(aIdx == 0)
   741         {
   742         INFO_PRINTF2(_L("Process %d, Changing contents of the VGImage"),aIdx);
   743         TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   744         CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 2);
   745     	// Add pixel data to the VGImage reference from the bitmap reference.
   746         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
   747 		TSize bitmapSize = bitmap->SizeInPixels();
   748     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
   749     	TInt stride = bitmap->DataStride();
   750     	address += (bitmapSize.iHeight - 1) * stride;
   751         vgImageSubData(vgImageLocal, address, -stride, KDefaultSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
   752         delete bitmap;
   753         bitmap = NULL;
   754     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   755     	eglWaitClient();
   756 
   757     	vgDestroyImage(vgImageLocal);
   758     	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
   759     	CleanupStack::PopAndDestroy(&messageQueue);
   760         CleanAll();
   761         }
   762 
   763 	// Wait for both processes to reach this point
   764     Rendezvous(aIdx);
   765 
   766     if(aIdx == 1)
   767         {
   768         INFO_PRINTF2(_L("Drawing the VGImage to the current surface after changing contents of the VGImage, Process %d"),aIdx);
   769  		// Copy the source VGImage to the surface
   770     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   771 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   772 		eglWaitClient();
   773 
   774 		// we can now compare the VgImage to the one we expect after changing it in the other process
   775 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
   776 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 2);
   777 		CleanupStack::PushL(refBitmap);
   778 		iEglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
   779 		CleanupStack::PopAndDestroy(refBitmap);
   780 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
   781 
   782 		vgDestroyImage(vgImageLocal);
   783 		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
   784 
   785 		CleanupStack::PopAndDestroy(&messageQueue);
   786     	CleanAll();
   787         }
   788     }
   789 
   790 /**
   791 @SYMTestCaseID GRAPHICS-EGL-0406
   792 
   793 @SYMTestPriority 1
   794 
   795 @SYMPREQ PREQ2637
   796 
   797 @SYMTestCaseDesc
   798 To ensure that RSgImage with uploaded data can be shared across processes.
   799 To ensure that reference counting of RSgImage works correctly.
   800 
   801 @SYMTestActions
   802 From the main process:
   803 - Create M SgImage(s) with the flag ESgUsageBitOpenVgImage. The size are all the same.
   804   We are running through all the possible configurations, with the values assumed being:
   805 •	EUidPixelFormatRGB_565
   806 •	EUidPixelFormatXRGB_8888
   807 •	EUidPixelFormatARGB_8888 (source only)
   808 •	EUidPixelFormatARGB_8888_PRE
   809 •	EUidPixelFormatA_8  (source only)
   810 - Note that when using EUidPixelFormatA_8 as a source, the reference bitmap display mode used is EGray256,
   811   This is to enable using the reference bitmap as an alpha mask.
   812 - Spawn N client processes. During the process launching, pass to each process single drawable ID from the SgImages.
   813   In order to define which SgImage needs to be passed to the particular process, there will be following
   814   formula applied: J = P Mod (M), where J is the sequence number of the image, P is the particular process number.
   815 From processes 1 to N:
   816 - Open SgImage by using TSgDrawableId, obtained from the SgImage which was passed from the process A.
   817 - Using EGL extension, create EGLImage specifying as EGLClientBuffer SgImage which was created on
   818   previous step,  EGL_NATIVE_PIXMAP_KHR as a target and EGL_IMAGE_PRESERVED_KHR as an attribute
   819 - Using VG extension, create VG image based on EGLImage from the previous step.
   820 - Close Sg and EGL images
   821 - Create second SgImage with the same size and pixel format as first SgImage and usage flag is set to ESgUsageBitOpenVgSurface.
   822 - Create off-screen pixmap surface with underlining second SgImage and make it current for the drawing context.
   823 - Draw VGImage to the off-screen surface (note that when using EUidPixelFormatA_8 as a source, the
   824   reference bitmap is used as an alpha mask).
   825 - Draw VGImage to the off-screen surface.
   826 - Retrieve surface data (see vgReadPixels() API)
   827 
   828 @SYMTestExpectedResults
   829 Creation of all drawable  resources have been completed without errors.
   830 Image data obtained in client processes 1-N matches to the data which have been uploaded to the SgImages buffer from
   831 process A. Reference counting works correctly and keeps VG image alive although bound Sg and EGL images have been destroyed.
   832 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes.
   833 */
   834 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestStepL()
   835 	{
   836 	SetTestStepID(_L("GRAPHICS-EGL-0406"));
   837 	SetTestStepName(KEGL_Image_Multi_Process_FontServer_Upfront);
   838 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestStepL"));
   839 
   840 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
   841 	if(!ret)
   842 		{
   843 		// The extension is not supported
   844 		RecordTestResultL();
   845 		CloseTMSGraphicsStep();
   846 		return TestStepResult();
   847 		}
   848 
   849 	CEglTestCommonIniSettings* iniParser = CEglTestCommonIniSettings::NewL();
   850 	CleanupStack::PushL(iniParser);
   851 
   852 	TInt numPixmapSgSurfaceFormats = iniParser->GetNumberOfFormats(KSectionPixmapSgSurfaceFormats);
   853 	TInt numImageSourceFormats = iniParser->GetNumberOfFormats(KSectionImageSourceFormats);
   854 	if(!numImageSourceFormats && !numPixmapSgSurfaceFormats)
   855 		{
   856 		ERR_PRINTF1(_L("No formats to iterate through"));
   857 		User::Leave(KErrArgument);
   858 		}
   859 	for(TUint j=0; j < numPixmapSgSurfaceFormats; j++)
   860 		{
   861 		iSurfaceFormat = iniParser->GetVgFormat(KSectionPixmapSgSurfaceFormats,j);
   862 		for(TUint i=0; i < numImageSourceFormats; i++)
   863 			{
   864 			iSourceFormat = iniParser->GetPixelFormat(KSectionImageSourceFormats,i);
   865 			if (iSourceFormat == EUidPixelFormatARGB_8888 && (iSurfaceFormat == VG_sARGB_8888_PRE || iSurfaceFormat == VG_sARGB_8888))
   866 				{
   867 				// Don't perform the test for this particular format combination
   868 				//  Causes issues converting pixel values from non-pre to pre
   869 				continue;
   870 				}
   871 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   872 			// A_8 related tests are only performed for SgImage-Lite
   873 			if (iSourceFormat == EUidPixelFormatA_8)
   874 				continue;
   875 #endif
   876 			doTestPartialStepL();
   877 			}
   878 		}
   879 
   880 	CleanupStack::PopAndDestroy(iniParser);
   881 	RecordTestResultL();
   882 	CloseTMSGraphicsStep();
   883 	return TestStepResult();
   884 	}
   885 
   886 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestPartialStepL()
   887 	{
   888 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestPartialStepL"));
   889 	PrintUsedPixelConfiguration();
   890 
   891 	// Create display object
   892 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
   893 	GetDisplayL();
   894 	CreateEglSessionL();
   895 	iEglSess->InitializeL();
   896 	iEglSess->OpenSgDriverL();
   897 
   898 	// list to maintain TSgDrawableId
   899 	RArray<TSgDrawableId> sgIdList;
   900 	CleanupClosePushL(sgIdList);
   901     RSgImage sgImages[KNumImages];
   902 
   903 	INFO_PRINTF2(_L("MAIN PROCESS: Creating %d RSgImage(s)..."), KNumImages);
   904 	for (TInt i=0; i<KNumImages; i++)
   905 		{
   906 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
   907 		CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, i);
   908 		CleanupStack::PushL(bitmap);
   909 
   910 		TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(iSourceFormat, KImageSize);
   911 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   912     	imageInfo.iShareable = ETrue;
   913 #endif
   914 		ASSERT_EQUALS(sgImages[i].Create(imageInfo, bitmap->DataAddress(), bitmap->DataStride()), KErrNone);
   915         CleanupClosePushL(sgImages[i]);
   916 		ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone);
   917 		}
   918 
   919 	INFO_PRINTF2(_L("MAIN PROCESS: About to launch %d processes..."), KNumProcesses);
   920 	Test_MultiProcessL(KEglTestStepDllName, KNumProcesses, TestStepName(), sgIdList); //the function will guarantee that all images will be opened before it returns
   921     CleanupStack::PopAndDestroy(2 * KNumImages + 1, &sgIdList); // KNumImages SgImages, KNumImages bitmaps, sgIdList
   922 	INFO_PRINTF2(_L("MAIN PROCESS: All %d launched processes have completed!"), KNumProcesses);
   923 
   924 	CleanAll();
   925 	INFO_PRINTF1(_L("End of CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestPartialStepL"));
   926 	return TestStepResult();
   927 	}
   928 
   929 void CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId)
   930 	{
   931 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doProcessFunctionL, Process %d"),aIdx);
   932 	GetDisplayL();
   933 	CreateEglSessionL(aIdx);
   934 	iEglSess->InitializeL();
   935 	iEglSess->OpenSgDriverL();
   936 
   937 	//Retrieve source formats for the launched process from the process parameters.
   938 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
   939 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
   940 
   941 	RSgImage sgImageFromId;
   942 	CleanupClosePushL(sgImageFromId);
   943 	ASSERT_EQUALS(sgImageFromId.Open(aSgId), KErrNone);
   944 
   945 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
   946 	EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue);
   947 	ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR);
   948 	CleanupStack::PopAndDestroy(&sgImageFromId);
   949 
   950 	INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
   951     TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
   952     TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
   953 	// Create a pixmap surface matching the native image pixel format
   954     iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
   955 
   956     INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
   957     VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
   958 	ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE);
   959 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage));
   960 
   961 	// At this point we draw the VGImage created from the SgImage to the current surface.
   962 	//	# if the source is a A_8, the VGImage acts as a mask and the target surface must contain
   963 	//		as a result the pen colour set above blended with the mask
   964 	//	# otherwise, drawing the VGImage is just a simple copy via vgSetPixels (no blending required)
   965 	INFO_PRINTF1(_L("Copying the VGImage to the surface"));
   966 	if (iSourceFormat == EUidPixelFormatA_8)
   967 		{
   968 		// clear surface background
   969 		VGfloat bgColor[] = {0.0, 0.0, 0.0, 1.0}; // opaque black
   970 		vgSetfv(VG_CLEAR_COLOR, 4, bgColor);
   971 		vgClear(0, 0, KImageSize.iWidth, KImageSize.iHeight);
   972 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
   973 
   974 		// fill paint
   975 		VGPaint fillPaint = vgCreatePaint();
   976 		vgSetPaint(fillPaint, VG_FILL_PATH);
   977 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
   978 		vgSetParameteri(fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
   979 		VGuint fillColor = 0x008000ff; // opaque dark green
   980 		vgSetColor(fillPaint, fillColor);
   981 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
   982 
   983 		vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
   984 		vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
   985 		vgDrawImage(vgImage);
   986 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
   987 		eglWaitClient();
   988 	    vgDestroyPaint(fillPaint);
   989 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
   990 		}
   991 	else
   992 		{
   993 		vgSetPixels(0, 0, vgImage, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
   994 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
   995 		eglWaitClient();
   996 		}
   997 
   998 	// Check that the surface contains the expected pixels
   999 	//  # if the source is a A_8, to compare the surface with a reference bitmap, the following is needed:
  1000 	//    a) a reference bitmap needs to be cleared to black (same colour as the surface was cleared to)
  1001 	//    b) a Pen bitmap, that we clear to dark green (same colour as the fillPaint used to draw to the surface)
  1002 	//    c) a mask bitmap, which is the reference bitmap used to create the SgImage
  1003 	//  # otherwise, the surface must contain the same pixels as the bitmap used to create the SgImage
  1004 	if (iSourceFormat == EUidPixelFormatA_8)
  1005 		{
  1006 		TDisplayMode maskMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1007 		CFbsBitmap* mask = iEglSess->CreateReferenceBitmapL(maskMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1008 		CleanupStack::PushL(mask);
  1009 
  1010 		// we need a reference bitmap with the same pixel format as the target surface
  1011 		TUidPixelFormat format = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1012 		TDisplayMode refbitmapMode = EglTestConversion::PixelFormatToDisplayMode(format);
  1013 
  1014 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceMaskedBitmapL(refbitmapMode, KRgbDarkGreen, mask);
  1015 		CleanupStack::PushL(refBitmap);
  1016 
  1017 		// compare the obtained reference bitmap with the surface drawn
  1018 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1019 		CleanupStack::PopAndDestroy(2, mask); //mask, refBitmap
  1020 		}
  1021 	else
  1022 		{
  1023 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1024 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1025 		CleanupStack::PushL(refBitmap);
  1026 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1027 		CleanupStack::PopAndDestroy(refBitmap);
  1028 		}
  1029 	INFO_PRINTF2(_L("Process %d, VG drawing successfully completed and checked"),aIdx);
  1030 
  1031 	// destroy VGImage
  1032 	vgDestroyImage(vgImage);
  1033 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1034 
  1035 	// cleanup
  1036 	CleanAll();
  1037 	}
  1038 
  1039 
  1040 /**
  1041 @SYMTestCaseID GRAPHICS-EGL-0410
  1042 
  1043 @SYMTestPriority 1
  1044 
  1045 @SYMPREQ PREQ2637
  1046 
  1047 @SYMTestCaseDesc
  1048 To ensure that RSgImage with uploaded data can be shared across processes.
  1049 To ensure that reference counting of RSgImage works correctly
  1050 
  1051 @SYMTestActions
  1052 From the main process:
  1053 - Create M SgImage(s) with the flag ESgUsageBitOpenVgImage. The size are all the same.
  1054   We are running through all the possible target configurations, with the values assumed being:
  1055 •	EUidPixelFormatRGB_565
  1056 •	EUidPixelFormatXRGB_8888
  1057 •	EUidPixelFormatARGB_8888_PRE
  1058 - Using EGL extension, create M EGLImage(s), specifying as EGLClientBuffer SgImage(s) which were created on
  1059   first step and EGL_NATIVE_PIXMAP_KHR as a target
  1060 - Using VG extension, create VG images based on EGLImage(s) from the previous step
  1061 - Close Sg and EGL Images
  1062 - Populate data in VGImages (see vgImageSubData(..) API), there will be different data uploaded for each VGImage
  1063 - Spawn N client processes. During the process launching, pass to each process single drawable ID from the SgImages.
  1064   In order to define which SgImage(s) needs to be passed to the particular processes, there will be following
  1065   formula applied: J = P Mod (M), where J is the sequence number of the image, P is the particular process number.
  1066 From processes 1 to N:
  1067 - Open SgImage by using TSgDrawableId, obtained from the SgImage which was passed from the process A.
  1068 - Using EGL extension, create EGLImage specifying as EGLClientBuffer SgImage which was created on previous step,
  1069   EGL_NATIVE_PIXMAP_KHR as a target and EGL_IMAGE_PRESERVED_KHR as an attribute
  1070 - Using VG extension, create VG image based on EGLImage from the previous step.
  1071 - Close Sg and EGL images
  1072 - Create second SgImage with the same size and pixel format as first SgImage and usage flag is set to ESgUsageBitOpenVgSurface.
  1073 - Create off-screen pixmap surface with underlining second SgImage and make it current for the drawing context.
  1074 - Draw VGImage to the off-screen surface.
  1075 - Retrieve surface data (see vgReadPixels() API)
  1076 
  1077 @SYMTestExpectedResults
  1078 Creation of all drawable  resources have been completed without errors.
  1079 Image data obtained in client processes 1-N matches to the data which have been uploaded to the SgImages buffer from
  1080 process A. Reference counting works correctly and keep VG image alive although bound Sg and EGL images have been closed.
  1081 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes.
  1082 */
  1083 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestStepL()
  1084 	{
  1085 	SetTestStepID(_L("GRAPHICS-EGL-0410"));
  1086 	SetTestStepName(KEGL_Image_Multi_Process_FontServer_Deferred);
  1087 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestStepL"));
  1088 
  1089 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
  1090 	if(!ret)
  1091 		{
  1092 		// The extension is not supported
  1093 		RecordTestResultL();
  1094 		CloseTMSGraphicsStep();
  1095 		return TestStepResult();
  1096 		}
  1097 
  1098 	CEglTestCommonIniSettings* iniParser = CEglTestCommonIniSettings::NewL();
  1099 	CleanupStack::PushL(iniParser);
  1100 
  1101 	TInt numPixmapSgSurfaceFormats = iniParser->GetNumberOfFormats(KSectionPixmapSgSurfaceFormats);
  1102 	if(!numPixmapSgSurfaceFormats)
  1103 		{
  1104 		ERR_PRINTF1(_L("No formats to iterate through"));
  1105 		User::Leave(KErrArgument);
  1106 		}
  1107 	for(TUint j=0; j < numPixmapSgSurfaceFormats; j++)
  1108 		{
  1109 		iSurfaceFormat = iniParser->GetVgFormat(KSectionPixmapSgSurfaceFormats,j);
  1110 		iSourceFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1111 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1112 		// A_8 related tests are only performed for SgImage-Lite
  1113 		if (iSourceFormat == EUidPixelFormatA_8)
  1114 			continue;
  1115 #endif
  1116 		doTestPartialStepL();
  1117 		}
  1118 
  1119 	CleanupStack::PopAndDestroy(iniParser);
  1120 	RecordTestResultL();
  1121 	CloseTMSGraphicsStep();
  1122 	return TestStepResult();
  1123 	}
  1124 
  1125 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestPartialStepL()
  1126 	{
  1127 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestPartialStepL"));
  1128 	PrintUsedPixelConfiguration();
  1129 
  1130 	// Create display object
  1131 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
  1132 	GetDisplayL();
  1133 	CreateEglSessionL();
  1134 	iEglSess->InitializeL();
  1135 	iEglSess->OpenSgDriverL();
  1136 
  1137 	// Create RSgImage's attributes
  1138 	TSgImageInfoTest imageInfo = TSgImageInfoTest(iSourceFormat, KImageSize);
  1139 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1140 	imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
  1141 #else
  1142     imageInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
  1143    	imageInfo.iShareable = ETrue;
  1144 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1145 	// Create a pixmap surface matching the given pixel format
  1146 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
  1147 
  1148 	// list to maintain TSgDrawableId
  1149 	RArray<TSgDrawableId> sgIdList;
  1150 	CleanupClosePushL(sgIdList);
  1151     RSgImage sgImages[KNumImages];
  1152 
  1153 	INFO_PRINTF2(_L("MAIN PROCESS: Creating %d RSgImage(s)..."), KNumImages);
  1154 	for (TInt i=0; i<KNumImages; i++)
  1155 		{
  1156 		ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone);
  1157         CleanupClosePushL(sgImages[i]);
  1158 		ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone);
  1159 
  1160 		EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImages[i], KEglImageAttribsPreservedTrue);
  1161 		ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR);
  1162 
  1163 		VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
  1164 		ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE);
  1165 		ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage));
  1166 
  1167 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1168         CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, i);
  1169     	// Add pixel data to the VGImage reference from the bitmap reference.
  1170         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
  1171 		TSize bitmapSize = bitmap->SizeInPixels();
  1172     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
  1173     	TInt stride = bitmap->DataStride();
  1174     	address += (bitmapSize.iHeight - 1) * stride;
  1175         vgImageSubData(vgImage, address, -stride, iSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
  1176         delete bitmap;
  1177         bitmap = NULL;
  1178     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1179         eglWaitClient();
  1180    		}
  1181 
  1182 	INFO_PRINTF2(_L("MAIN PROCESS: About to launch %d processes..."), KNumProcesses);
  1183 	Test_MultiProcessL(KEglTestStepDllName, KNumProcesses, TestStepName(), sgIdList);
  1184 	CleanupStack::PopAndDestroy(KNumImages + 1, &sgIdList); //KNumImages SgImages, sgIdList
  1185 	INFO_PRINTF2(_L("MAIN PROCESS: All %d launched processes have completed!"), KNumProcesses);
  1186 
  1187 	CleanAll();
  1188 	INFO_PRINTF1(_L("End of CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestPartialStepL"));
  1189 	return TestStepResult();
  1190 	}
  1191 
  1192 void CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId)
  1193 	{
  1194 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doProcessFunctionL, Process %d"),aIdx);
  1195 	GetDisplayL();
  1196 	CreateEglSessionL(aIdx);
  1197 	iEglSess->InitializeL();
  1198 	iEglSess->OpenSgDriverL();
  1199 
  1200 	//Retrieve source formats for the launched process from the process parameters.
  1201 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
  1202 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
  1203 
  1204 	RSgImage sgImageFromId;
  1205 	CleanupClosePushL(sgImageFromId);
  1206 	ASSERT_EQUALS(sgImageFromId.Open(aSgId), KErrNone);
  1207 
  1208 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
  1209 	EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue);
  1210 	ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR);
  1211 	CleanupStack::PopAndDestroy(&sgImageFromId);
  1212 
  1213 	INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
  1214     TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1215     TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
  1216 	// Create a pixmap surface matching the native image pixel format
  1217     iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
  1218 
  1219     INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
  1220     VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
  1221 	ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE);
  1222 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage));
  1223 
  1224 	// At this point we draw the VGImage created from the SgImage to the current surface.
  1225 	//	# if the source is a A_8, the VGImage acts as a mask and the target surface must contain
  1226 	//		as a result the pen colour set above blended with the mask
  1227 	//	# otherwise, drawing the VGImage is just a simple copy via vgSetPixels (no blending required)
  1228 	INFO_PRINTF1(_L("Copying the VGImage to the surface"));
  1229 	if (iSourceFormat == EUidPixelFormatA_8)
  1230 		{
  1231 		// clear surface background
  1232 		VGfloat bgColor[] = {0.0, 0.0, 0.0, 1.0}; // opaque black
  1233 		vgSetfv(VG_CLEAR_COLOR, 4, bgColor);
  1234 		vgClear(0, 0, KImageSize.iWidth, KImageSize.iHeight);
  1235 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1236 
  1237 		// fill paint
  1238 		VGPaint fillPaint = vgCreatePaint();
  1239 		vgSetPaint(fillPaint, VG_FILL_PATH);
  1240 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1241 		vgSetParameteri(fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
  1242 		VGuint fillColor = 0x008000ff; // opaque dark green
  1243 		vgSetColor(fillPaint, fillColor);
  1244 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1245 
  1246 		vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
  1247 		vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
  1248 		vgDrawImage(vgImage);
  1249 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1250 		eglWaitClient();
  1251 	    vgDestroyPaint(fillPaint);
  1252 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1253 		}
  1254 	else
  1255 		{
  1256 		vgSetPixels(0, 0, vgImage, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
  1257 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1258 		eglWaitClient();
  1259 		}
  1260 
  1261 	// Check that the surface contains the expected pixels
  1262 	//  # if the source is a A_8, to compare the surface with a reference bitmap, the following is needed:
  1263 	//    a) a reference bitmap needs to be cleared to black (same colour as the surface was cleared to)
  1264 	//    b) a Pen bitmap, that we clear to dark green (same colour as the fillPaint used to draw to the surface)
  1265 	//    c) a mask bitmap, which is the reference bitmap used to create the SgImage
  1266 	//  # otherwise, the surface must contain the same pixels as the bitmap used to create the SgImage
  1267 	if (iSourceFormat == EUidPixelFormatA_8)
  1268 		{
  1269 		TDisplayMode maskMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1270 		CFbsBitmap* mask = iEglSess->CreateReferenceBitmapL(maskMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1271 		CleanupStack::PushL(mask);
  1272 
  1273 		// we need a reference bitmap with the same pixel format as the target surface
  1274 		TUidPixelFormat format = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1275 		TDisplayMode refbitmapMode = EglTestConversion::PixelFormatToDisplayMode(format);
  1276 
  1277 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceMaskedBitmapL(refbitmapMode, KRgbDarkGreen, mask);
  1278 		CleanupStack::PushL(refBitmap);
  1279 
  1280 		// compare the obtained reference bitmap with the surface drawn
  1281 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1282 		CleanupStack::PopAndDestroy(2, mask); //mask, refBitmap
  1283 		}
  1284 	else
  1285 		{
  1286 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1287 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1288 		CleanupStack::PushL(refBitmap);
  1289 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1290 		CleanupStack::PopAndDestroy(refBitmap);
  1291 		}
  1292 	INFO_PRINTF2(_L("Process %d, VG drawing successfully completed and checked"),aIdx);
  1293 
  1294 	// destroy VGImage
  1295 	vgDestroyImage(vgImage);
  1296 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1297 
  1298 	// cleanup
  1299 	CleanAll();
  1300 	}
  1301 
  1302 
  1303 /**
  1304 @SYMTestCaseID GRAPHICS-EGL-0415
  1305 
  1306 @SYMTestPriority 1
  1307 
  1308 @SYMPREQ PREQ2637
  1309 
  1310 @SYMTestCaseDesc
  1311 To ensure that SgImage with the data rendered as Pixmap surface can be shared across processes.
  1312 To ensure that reference counting of SgImage works correctly
  1313 
  1314 @SYMTestActions
  1315 From the main process:
  1316 - Create M SgImages with the flags ESgUsageBitOpenVgImage & ESgUsageBitOpenVgSurface. The size are all the same.
  1317   We are running through all the possible target configurations, with the values assumed being:
  1318 •	EUidPixelFormatRGB_565
  1319 •	EUidPixelFormatXRGB_8888
  1320 •	EUidPixelFormatARGB_8888_PRE
  1321 - Choose egl config, supplying as a native pixmap type in attribute (flag EGL_MATCH_NATIVE_PIXMAP) the SgImages which
  1322   were created on the previous step. The EGL_RENDERABLE_TYPE of the config attributes must include EGL_OPENVG_BIT.
  1323 - Create M pixmap surfaces based on SgImages from the first step. The surface is created with EGL_ALPHA_FORMAT_PRE
  1324   flag supplied in attribute list if the underlining SgImage was of type ESgPixelFormatARGB_8888_PRE.
  1325 - In iteration from 1 to M perform three following steps:
  1326 	1. Make the pixmap surface current (see eglMakeCurrent(.) API)
  1327 	2. Draw something to the current surface, for instance, clear the whole area with color and then draw a
  1328 	   few graphics primitives. The drawing needs to be unique for each surface and complicated enough to
  1329 	   ensure that bit comparison will reveal any mismatch
  1330 	3. Make no surface current
  1331 - Close all pixmap surfaces
  1332 - Spawn N client processes. During the process launching, pass to each process single drawable ID from the SgImages.
  1333   In order to define which SgImage(s) needs to be passed to the particular processes, there will be following
  1334   formula applied: J = P Mod (M), where J is the sequence number of the image, P is the particular process number.
  1335 From processes 1 to N:
  1336 - Open SgImage by TSgDrawableId obtained from the SgImage which was passed from the process A.
  1337 - Using EGL extension, create EGLImage specifying as EGLClientBuffer SgImage which was opened on the previous
  1338   step,  EGL_NATIVE_PIXMAP_KHR as a target and EGL_IMAGE_PRESERVED_KHR as an attribute
  1339 - Using VG extension, create VG image based on EGLImage from the previous step.
  1340 - Close both Sg and EGL images
  1341 - Create second SgImage with the same size and pixel format as first SgImage and usage flag is set to ESgUsageBitOpenVgSurface.
  1342 - Create off-screen pixmap surface with underlining second SgImage and make it current for the drawing context.
  1343 - Draw VGImage to the off-screen surface.
  1344 - Retrieve surface data (see vgReadPixels() API)
  1345 
  1346 @SYMTestExpectedResults
  1347 Creation of all drawable resources has been completed without errors.
  1348 On return eglChooseConfig() must return EGL_OPENVG_BIT in config attribute list (actual attributes should
  1349 be retrieved via call to eglGetConfigAttrib()).
  1350 Image data obtained in client processes 1 - N matches to the pixmap surface which was drawn in the process A.
  1351 Reference counting works correctly and keep VG image alive although bound Sg and EGL images have been closed.
  1352 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes.
  1353 */
  1354 TVerdict CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestStepL()
  1355 	{
  1356 	SetTestStepID(_L("GRAPHICS-EGL-0415"));
  1357 	SetTestStepName(KEGL_Image_Multi_Process_ThemeServer);
  1358 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestStepL"));
  1359 
  1360 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
  1361 	if(!ret)
  1362 		{
  1363 		// The extension is not supported
  1364 		RecordTestResultL();
  1365 		CloseTMSGraphicsStep();
  1366 		return TestStepResult();
  1367 		}
  1368 
  1369 	CEglTestCommonIniSettings* iniParser = CEglTestCommonIniSettings::NewL();
  1370 	CleanupStack::PushL(iniParser);
  1371 
  1372 	TInt numPixmapSgSurfaceFormats = iniParser->GetNumberOfFormats(KSectionPixmapSgSurfaceFormats);
  1373 	if(!numPixmapSgSurfaceFormats)
  1374 		{
  1375 		ERR_PRINTF1(_L("No formats to iterate through"));
  1376 		User::Leave(KErrArgument);
  1377 		}
  1378 	for(TUint j=0; j < numPixmapSgSurfaceFormats; j++)
  1379 		{
  1380 		iSurfaceFormat = iniParser->GetVgFormat(KSectionPixmapSgSurfaceFormats,j);
  1381 		iSourceFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1382 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1383 		// A_8 related tests are only performed for SgImage-Lite
  1384 		if (iSourceFormat == EUidPixelFormatA_8)
  1385 			continue;
  1386 #endif
  1387 		doTestPartialStepL();
  1388 		}
  1389 
  1390 	CleanupStack::PopAndDestroy(iniParser);
  1391 	RecordTestResultL();
  1392 	CloseTMSGraphicsStep();
  1393 	return TestStepResult();
  1394 	}
  1395 
  1396 TVerdict CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestPartialStepL()
  1397 	{
  1398 	INFO_PRINTF1(_L("CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestPartialStepL"));
  1399 	PrintUsedPixelConfiguration();
  1400 
  1401 	// Create display object
  1402 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
  1403 	GetDisplayL();
  1404 	CreateEglSessionL();
  1405 	iEglSess->InitializeL();
  1406 	iEglSess->OpenSgDriverL();
  1407 
  1408 	// list to maintain TSgDrawableId
  1409 	RArray<TSgDrawableId> sgIdList;
  1410 	CleanupClosePushL(sgIdList);
  1411     RSgImage sgImages[KNumImages];
  1412 
  1413 	INFO_PRINTF2(_L("MAIN PROCESS: Creating %d RSgImage(s)..."), KNumImages);
  1414 	for (TInt i=0; i<KNumImages; i++)
  1415 		{
  1416 		// Create RSgImage's attributes
  1417 		TSgImageInfoTest imageInfo = TSgImageInfoTest(iSourceFormat, KImageSize);
  1418 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1419 		imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
  1420 #else
  1421 		imageInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
  1422     	imageInfo.iShareable = ETrue;
  1423 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1424 
  1425 		ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone);
  1426 	    CleanupClosePushL(sgImages[i]);
  1427 		ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone);
  1428 
  1429 		INFO_PRINTF1(_L("Calling sequence - eglBindAPI(EGL_OPENVG_API) - eglCreatePixmapSurface - eglCreateContext - eglMakeCurrent"));
  1430 	    ASSERT_EGL_TRUE(eglBindAPI(EGL_OPENVG_API));
  1431 
  1432     	const EGLint KAttrib_list_image_pre[] = {   EGL_MATCH_NATIVE_PIXMAP,	reinterpret_cast<EGLint>(&sgImages[i]),
  1433 													EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
  1434 													EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT,
  1435 													EGL_NONE };
  1436     	const EGLint KAttrib_list_image_nonpre[] = {EGL_MATCH_NATIVE_PIXMAP,	reinterpret_cast<EGLint>(&sgImages[i]),
  1437 													EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
  1438 													EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,
  1439 													EGL_NONE };
  1440 		EGLConfig currentConfig;
  1441 		EGLint numconfigs =0;
  1442 		EGLSurface surface = EGL_NO_SURFACE;
  1443 	    if (iSourceFormat == EUidPixelFormatARGB_8888_PRE)
  1444 	    	{
  1445 			ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib_list_image_pre,&currentConfig,1,&numconfigs))
  1446 			ASSERT_EGL_TRUE(numconfigs==1);
  1447 	    	surface = eglCreatePixmapSurface(iDisplay, currentConfig,&sgImages[i], KPixmapAttribsVgAlphaFormatPre);
  1448 	    	}
  1449 	    else
  1450 	    	{
  1451 			ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,KAttrib_list_image_nonpre,&currentConfig,1,&numconfigs))
  1452 			ASSERT_EGL_TRUE(numconfigs==1);
  1453 	    	surface = eglCreatePixmapSurface(iDisplay, currentConfig,&sgImages[i], KPixmapAttribsVgAlphaFormatNonPre);
  1454 	    	}
  1455     	ASSERT_EGL_TRUE(surface != EGL_NO_SURFACE);
  1456 	    EGLContext context = eglCreateContext(iDisplay, currentConfig, EGL_NO_CONTEXT, NULL);
  1457 	    ASSERT_EGL_TRUE(context != EGL_NO_CONTEXT);
  1458 	    ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, surface, surface, context));
  1459 
  1460     	//Drawing to the current surface (and hence to the RSgImage) to test that the contents are preserved
  1461 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1462 		CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, i);
  1463         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
  1464 		TSize bitmapSize = bitmap->SizeInPixels();
  1465     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
  1466     	TInt stride = bitmap->DataStride();
  1467     	address += (bitmapSize.iHeight - 1) * stride;
  1468     	vgWritePixels(address, -stride, iSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
  1469    	    eglWaitClient();   // wait for writing to finish
  1470 		delete bitmap;
  1471 		bitmap = NULL;
  1472 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1473 
  1474     	// Make no surface current and destroy surface
  1475        	ASSERT_EGL_TRUE(eglDestroySurface(iDisplay, surface));
  1476     	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
  1477 		}
  1478 
  1479 	INFO_PRINTF2(_L("MAIN PROCESS: About to launch %d processes..."), KNumProcesses);
  1480 	Test_MultiProcessL(KEglTestStepDllName, KNumProcesses, TestStepName(), sgIdList);
  1481 	CleanupStack::PopAndDestroy(KNumImages + 1, &sgIdList); //KNumImages SgImages, sgIdList
  1482 	INFO_PRINTF2(_L("MAIN PROCESS: All %d launched processes have completed!"), KNumProcesses);
  1483 
  1484 	CleanAll();
  1485 	INFO_PRINTF1(_L("End of CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestPartialStepL"));
  1486 	return TestStepResult();
  1487 	}
  1488 
  1489 void CEglTest_EGL_Image_Multi_Process_ThemeServer::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId)
  1490 	{
  1491 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_ThemeServer::doProcessFunctionL, Process %d"),aIdx);
  1492 	GetDisplayL();
  1493 	CreateEglSessionL(aIdx);
  1494 	iEglSess->InitializeL();
  1495 	iEglSess->OpenSgDriverL();
  1496 
  1497 	//Retrieve source formats for the launched process from the process parameters.
  1498 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
  1499 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
  1500 
  1501 	RSgImage sgImageFromId;
  1502 	CleanupClosePushL(sgImageFromId);
  1503 	ASSERT_EQUALS(sgImageFromId.Open(aSgId), KErrNone);
  1504 
  1505 	INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
  1506 	EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue);
  1507 	ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR);
  1508 	CleanupStack::PopAndDestroy(&sgImageFromId);
  1509 
  1510 	INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
  1511     TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
  1512     TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
  1513 	// Create a pixmap surface matching the native image pixel format
  1514     iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
  1515 
  1516     INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
  1517     VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage);
  1518 	ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE);
  1519 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage));
  1520 
  1521 	// At this point we draw the VGImage created from the SgImage to the current surface.
  1522 	//	# if the source is a A_8, the VGImage acts as a mask and the target surface must contain
  1523 	//		as a result the pen colour set above blended with the mask
  1524 	//	# otherwise, drawing the VGImage is just a simple copy via vgSetPixels (no blending required)
  1525 	INFO_PRINTF1(_L("Copying the VGImage to the surface"));
  1526 	if (iSourceFormat == EUidPixelFormatA_8)
  1527 		{
  1528 		// clear surface background
  1529 		VGfloat bgColor[] = {0.0, 0.0, 0.0, 1.0}; // opaque black
  1530 		vgSetfv(VG_CLEAR_COLOR, 4, bgColor);
  1531 		vgClear(0, 0, KImageSize.iWidth, KImageSize.iHeight);
  1532 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1533 
  1534 		// fill paint
  1535 		VGPaint fillPaint = vgCreatePaint();
  1536 		vgSetPaint(fillPaint, VG_FILL_PATH);
  1537 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1538 		vgSetParameteri(fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
  1539 		VGuint fillColor = 0x008000ff; // opaque dark green
  1540 		vgSetColor(fillPaint, fillColor);
  1541 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1542 
  1543 		vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
  1544 		vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
  1545 		vgDrawImage(vgImage);
  1546 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1547 		eglWaitClient();
  1548 	    vgDestroyPaint(fillPaint);
  1549 		ASSERT_EGL_TRUE(vgGetError() == VG_NO_ERROR);
  1550 		}
  1551 	else
  1552 		{
  1553 		vgSetPixels(0, 0, vgImage, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
  1554 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1555 		eglWaitClient();
  1556 		}
  1557 
  1558 	// Check that the surface contains the expected pixels
  1559 	//  # if the source is a A_8, to compare the surface with a reference bitmap, the following is needed:
  1560 	//    a) a reference bitmap needs to be cleared to black (same colour as the surface was cleared to)
  1561 	//    b) a Pen bitmap, that we clear to dark green (same colour as the fillPaint used to draw to the surface)
  1562 	//    c) a mask bitmap, which is the reference bitmap used to create the SgImage
  1563 	//  # otherwise, the surface must contain the same pixels as the bitmap used to create the SgImage
  1564 	if (iSourceFormat == EUidPixelFormatA_8)
  1565 		{
  1566 		TDisplayMode maskMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1567 		CFbsBitmap* mask = iEglSess->CreateReferenceBitmapL(maskMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1568 		CleanupStack::PushL(mask);
  1569 
  1570 		// we need a reference bitmap with the same pixel format as the target surface
  1571 		TUidPixelFormat format = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1572 		TDisplayMode refbitmapMode = EglTestConversion::PixelFormatToDisplayMode(format);
  1573 
  1574 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceMaskedBitmapL(refbitmapMode, KRgbDarkGreen, mask);
  1575 		CleanupStack::PushL(refBitmap);
  1576 
  1577 		// compare the obtained reference bitmap with the surface drawn
  1578 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1579 		CleanupStack::PopAndDestroy(2, mask); //mask, refBitmap
  1580 		}
  1581 	else
  1582 		{
  1583 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1584 		CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, ImageIndexFromProcessId(aIdx, KNumImages));
  1585 		CleanupStack::PushL(refBitmap);
  1586 		iEglSess->CheckVgDrawingL(iSurfaceFormat, refBitmap);
  1587 		CleanupStack::PopAndDestroy(refBitmap);
  1588 		}
  1589 	INFO_PRINTF2(_L("Process %d, VG drawing successfully completed and checked"),aIdx);
  1590 
  1591 	// destroy VGImage
  1592 	vgDestroyImage(vgImage);
  1593 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1594 
  1595 	// cleanup
  1596 	CleanAll();
  1597 	}
  1598 
  1599 
  1600 /**
  1601 @SYMTestCaseID GRAPHICS-EGL-0430
  1602 
  1603 @SYMTestPriority 1
  1604 
  1605 @SYMPREQ 2637
  1606 
  1607 @SYMTestCaseDesc
  1608 Functional test - Killing the RSgImage creating process
  1609 
  1610 @SYMTestPurpose
  1611 To verify correct operation of RSgImage sharing across processes when the creating process is killed
  1612 
  1613 @SYMTestActions
  1614 Run two processes that independently perform the actions detailed below.
  1615 * From Process A
  1616 	Open the RSgDriver
  1617 	Create an RSgImage passing an initialised bitmap
  1618 	Signal (by semaphore or otherwise) to process B, passing the drawable ID to it
  1619 
  1620 * From Process B:
  1621 	Open the RSgDriver
  1622 	Using the drawable ID, open the RSgImage
  1623 	Close the RSgImage
  1624 	Re-open the RSgImage
  1625 
  1626 * From Process A:
  1627 	Unexpectedly terminate process A without performing any explicit clean-up
  1628 
  1629 * From Process B:
  1630 	Wait for Process A to be killed:
  1631 	Create an EGLImage from the RSgImage
  1632 	Create a VGImage from the EGLImage
  1633 	Close the RSgImage
  1634 	Close the EGLImage
  1635 	Create an off-screen surface
  1636 	Draw VGImage to the off-screen surface
  1637 	Read the pixel data and verify that it matches the data populated by process A
  1638 	Destroy the off-screen surface
  1639 	Close the VGImage
  1640 	Close the RSgDriver
  1641 	Exit
  1642 
  1643 @SYMTestExpectedResults
  1644 Process B should be able to populate the VGImage with data and copy it to the off-screen surface
  1645 All allocated image memory should be freed
  1646 */
  1647 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL()
  1648     {
  1649     SetTestStepID(_L("GRAPHICS-EGL-0430"));
  1650 	SetTestStepName(KEGL_Image_Multi_Process_VgImage_ProcessTerminate);
  1651     INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL"));
  1652 
  1653 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
  1654 	if(!ret)
  1655 		{
  1656 		// The extension is not supported
  1657 		RecordTestResultL();
  1658 		CloseTMSGraphicsStep();
  1659 		return TestStepResult();
  1660 		}
  1661 
  1662 	// This test is performed for default pixel format
  1663 	PrintUsedPixelConfiguration();
  1664 
  1665 	// launch 2 processes
  1666  	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
  1667 
  1668 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL"));
  1669     RecordTestResultL();
  1670     CloseTMSGraphicsStep();
  1671     return TestStepResult();
  1672     }
  1673 
  1674 void CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doProcessFunctionL(TInt aIdx)
  1675     {
  1676     INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doProcessFunctionL, Process %d"),aIdx);
  1677     GetDisplayL();
  1678     CreateEglSessionL(aIdx);
  1679     iEglSess->InitializeL();
  1680     iEglSess->OpenSgDriverL();
  1681 
  1682 	//Retrieve source formats for the launched process from the process parameters.
  1683 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
  1684 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
  1685 
  1686 	//create the queue to send/receive SgImage ID between processes
  1687 	RMsgQueue<TSgDrawableId> messageQueueSgId;
  1688     User::LeaveIfError(messageQueueSgId.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
  1689     CleanupClosePushL(messageQueueSgId);
  1690 
  1691 	//create the queue to send/receive Process ID between processes
  1692     RMsgQueue<TProcessId> messageQueueProcId;
  1693     User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess));
  1694     CleanupClosePushL(messageQueueProcId);
  1695 
  1696     RProcess process;
  1697     CleanupClosePushL(process);
  1698 	TRequestStatus status;
  1699 
  1700 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
  1701 	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 6);
  1702 	CleanupStack::PushL(bitmap);
  1703 
  1704 	RSgImage rSgImageLocal;
  1705     if(aIdx == 0)
  1706         {
  1707     	// Create an RSgImage
  1708     	INFO_PRINTF2(_L("Process %d, Creating a RSgImage"),aIdx);
  1709     	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(iSourceFormat, KImageSize);
  1710 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1711     	imageInfo.iShareable = ETrue;
  1712     	imageInfo.iCpuAccess = ESgCpuAccessReadWrite;
  1713 #endif
  1714     	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo, bitmap->DataAddress(), bitmap->DataStride()), KErrNone);
  1715 
  1716         INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx);
  1717         messageQueueSgId.SendBlocking(rSgImageLocal.Id());
  1718 
  1719         // Sending Process ID to other process... so that the other process can identify when this one dies.
  1720         messageQueueProcId.SendBlocking(RProcess().Id());
  1721         }
  1722     else if(aIdx == 1)
  1723         {
  1724         INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx);
  1725         TSgDrawableId sgImageId;
  1726         messageQueueSgId.ReceiveBlocking(sgImageId);
  1727     	ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone);
  1728 
  1729         // Also receiving RProcess ID from other process to be able to identify when it dies
  1730         TProcessId procId;
  1731         messageQueueProcId.ReceiveBlocking(procId);
  1732         process.Open(procId);
  1733         process.Logon(status);
  1734 
  1735         INFO_PRINTF2(_L("Process %d: Closing and Opening SgImage again..."), aIdx);
  1736     	rSgImageLocal.Close();
  1737     	ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone);
  1738         }
  1739 
  1740 	// Wait for both processes to reach this point
  1741     Rendezvous(aIdx);
  1742 
  1743     if(aIdx == 0)
  1744     	{
  1745     	// simulate this process being killed
  1746     	// note that we terminate with reason=0 (otherwise the egl test framework would think it's an error)
  1747        	INFO_PRINTF2(_L("Process %d, Simulate the process is being killed!"),aIdx);
  1748     	RProcess().Terminate(KErrNone);
  1749 
  1750     	// this line is unreachable
  1751     	ASSERT(0);
  1752     	}
  1753     else if(aIdx == 1)
  1754         {
  1755         // first wait for the other process to finish
  1756         User::WaitForRequest(status);
  1757         ASSERT_EQUALS(status.Int(), KErrNone);
  1758 
  1759         INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
  1760     	CleanupClosePushL(rSgImageLocal);
  1761         EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
  1762     	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
  1763     	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
  1764 
  1765     	INFO_PRINTF2(_L("Creating a Surface and a Context bound to OpenVG, Process %d"),aIdx);
  1766     	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat);
  1767     	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize);
  1768     	// Create a pixmap surface matching the native image pixel format
  1769     	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
  1770 
  1771     	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
  1772     	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
  1773     	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
  1774     	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
  1775 
  1776         INFO_PRINTF2(_L("Process %d, Drawing the VGImage to the current surface before changing contents of the VGImage"),aIdx);
  1777         // Copy the source VGImage to the surface
  1778     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight);
  1779     	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
  1780     	eglWaitClient();
  1781 
  1782     	// we can now compare the VgImage to the one we expect
  1783 		iEglSess->CheckVgDrawingL(iSurfaceFormat, bitmap);
  1784 		INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx);
  1785 
  1786 		// cleanup
  1787 		vgDestroyImage(vgImageLocal);
  1788     	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
  1789         }
  1790 
  1791     //cleanup and finish
  1792 	CleanupStack::PopAndDestroy(4, &messageQueueSgId); //messageQueueSgId, messageQueueProcId, process, bitmap
  1793 	CleanAll();
  1794     }
  1795 
  1796 
  1797 /**
  1798 @SYMTestCaseID GRAPHICS-EGL-0429
  1799 
  1800 @SYMTestPriority 1
  1801 
  1802 @SYMPREQ 2637
  1803 
  1804 @SYMTestCaseDesc
  1805 Functional test - Killing the RSgImage creating process
  1806 
  1807 @SYMTestPurpose
  1808 To verify correct operation of RSgImage sharing across processes when the creating process is killed
  1809 
  1810 @SYMTestActions
  1811 Run two processes that independently perform the actions detailed below.
  1812 * From Process A:
  1813 	Open the RSgDriver
  1814 	Create an RSgImage
  1815 	Signal (by semaphore or otherwise) to process B, passing the drawable ID to it
  1816 
  1817 * From Process B:
  1818 	Open the RSgDriver
  1819 
  1820 * From Process A:
  1821 	Unexpectedly terminate process A without performing any explicit clean-up
  1822 
  1823 * From Process B:
  1824 	Wait for Process A to be killed:
  1825 	Using the drawable ID, attempt to open the RSgImage
  1826 	Close the RSgDriver
  1827 	Exit
  1828 
  1829 @SYMTestExpectedResults
  1830 Process B should be unable to open the RSgImage and the call to Open() should return error code KErrNotFound.
  1831 All allocated image memory should be freed
  1832 */
  1833 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminateNegative::doTestStepL()
  1834     {
  1835     SetTestStepID(_L("GRAPHICS-EGL-0429"));
  1836 	SetTestStepName(KEGL_Image_Multi_Process_VgImage_ProcessTerminateNegative);
  1837     INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminateNegative::doTestStepL"));
  1838 
  1839 	TBool ret = CheckForExtensionL(KEGL_RSgimage);
  1840 	if(!ret)
  1841 		{
  1842 		// The extension is not supported
  1843 		RecordTestResultL();
  1844 		CloseTMSGraphicsStep();
  1845 		return TestStepResult();
  1846 		}
  1847 
  1848 	// This test is performed for default pixel format
  1849 	PrintUsedPixelConfiguration();
  1850 
  1851 	// launch 2 processes
  1852 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
  1853 
  1854 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminateNegative::doTestStepL"));
  1855     RecordTestResultL();
  1856     CloseTMSGraphicsStep();
  1857     return TestStepResult();
  1858     }
  1859 
  1860 void CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminateNegative::doProcessFunctionL(TInt aIdx)
  1861     {
  1862     INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminateNegative::doProcessFunctionL, Process %d"),aIdx);
  1863     GetDisplayL();
  1864     CreateEglSessionL(aIdx);
  1865     iEglSess->InitializeL();
  1866     iEglSess->OpenSgDriverL();
  1867 
  1868 	//Retrieve source formats for the launched process from the process parameters.
  1869 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
  1870 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
  1871 
  1872 	//create the queue to send/receive SgImage ID between processes
  1873 	RMsgQueue<TSgDrawableId> messageQueueSgId;
  1874     User::LeaveIfError(messageQueueSgId.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
  1875     CleanupClosePushL(messageQueueSgId);
  1876 
  1877 	//create the queue to send/receive Process ID between processes
  1878     RMsgQueue<TProcessId> messageQueueProcId;
  1879     User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess));
  1880     CleanupClosePushL(messageQueueProcId);
  1881 
  1882     RProcess process;
  1883     CleanupClosePushL(process);
  1884 	TRequestStatus status;
  1885 
  1886     RSgImage rSgImageLocal;
  1887     TSgDrawableId sgImageId;
  1888 	if(aIdx == 0)
  1889         {
  1890     	// Create an RSgImage
  1891     	INFO_PRINTF2(_L("Process %d, Creating a RSgImage"),aIdx);
  1892     	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(iSourceFormat, KImageSize);
  1893 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1894     	imageInfo.iShareable = ETrue;
  1895     	imageInfo.iCpuAccess = ESgCpuAccessReadWrite;
  1896 #endif
  1897     	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,NULL, NULL), KErrNone);
  1898 
  1899         INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx);
  1900         messageQueueSgId.SendBlocking(rSgImageLocal.Id());
  1901 
  1902         // Sending Process ID to other process... so that the other process can identify when this one dies.
  1903         messageQueueProcId.SendBlocking(RProcess().Id());
  1904         }
  1905     else if(aIdx == 1)
  1906         {
  1907         INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx);
  1908         //unlike the other cases, do not open it (yet)
  1909         messageQueueSgId.ReceiveBlocking(sgImageId);
  1910 
  1911         // Also receiving RProcess ID from other process to be able to identify when it dies
  1912         TProcessId procId;
  1913         messageQueueProcId.ReceiveBlocking(procId);
  1914         process.Open(procId);
  1915         process.Logon(status);
  1916         }
  1917 
  1918 	// Wait for both processes to reach this point
  1919     Rendezvous(aIdx);
  1920 
  1921     if(aIdx == 0)
  1922     	{
  1923     	// simulate this process being killed
  1924     	// note that we terminate with reason=0 (otherwise the egl test framework would think it's an error)
  1925        	INFO_PRINTF2(_L("Process %d, Simulate the process is being killed!"),aIdx);
  1926     	RProcess().Terminate(KErrNone);
  1927 
  1928     	// this line is unreachable
  1929     	ASSERT(0);
  1930     	}
  1931     else if(aIdx == 1)
  1932         {
  1933         // first wait for the other process to finish
  1934         User::WaitForRequest(status);
  1935         ASSERT_EQUALS(status.Int(), KErrNone);
  1936 
  1937         // NOTE: We can't guarante when the kernel will have completed the cleanup. This process
  1938         //	could have been notified that the other process has terminated but this does not guarantee
  1939         //	that all handles to the process have been released.
  1940         //	This is not generally a problem in single processor hardware, but can be a problem in dual
  1941         //	processor hardware (ie, NaviEngine) where one processor could be cleaning up the terminated
  1942         //	process, the other processor could already be issuing the notification to the waiting process
  1943         //	Not much we can do other than adding a small delay to ensure this...
  1944         User::After(1*1000*1000); // 1 second
  1945 
  1946         // we're expecting it to fail with the appropriate error
  1947         TInt ret = rSgImageLocal.Open(sgImageId);
  1948 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  1949         INFO_PRINTF4(_L("Process %d: Opening SgImage resulted in %d (expected was %d)."), aIdx, ret, KErrNotFound);
  1950         ASSERT_EQUALS(ret, KErrNotFound);
  1951 #else
  1952         INFO_PRINTF4(_L("Process %d: Opening SgImage resulted in %d (expected was %d)."), aIdx, ret, KErrArgument);
  1953         ASSERT_EQUALS(ret, KErrArgument);
  1954 #endif
  1955         }
  1956 
  1957     //cleanup and finish
  1958 	CleanupStack::PopAndDestroy(3, &messageQueueSgId); //messageQueueSgId, messageQueueProcId, process
  1959 	CleanAll();
  1960     }
  1961 
  1962 
  1963 /**
  1964 @SYMTestCaseID GRAPHICS-EGL-0431
  1965 
  1966 @SYMTestPriority 1
  1967 
  1968 @SYMPREQ 2637
  1969 
  1970 @SYMTestCaseDesc
  1971 Functional test - Simultaneous reading and writing of simulated glyphs.
  1972 The rectangular area of RSgImage will be divided into the following section:
  1973 	 -----------
  1974     ¦ 0 ¦ 1 ¦ 2 ¦
  1975     ¦-----------
  1976     ¦ 3 ¦ 4 ¦ 5 ¦
  1977     ¦-----------
  1978     ¦ 6 ¦ 7 ¦ 8 ¦
  1979 	 -----------
  1980 The image size is taken to be 90x90 so that it is easily split between 9 sub-sections
  1981 It is obvoious that each sub-section will therefore be of 30x30:
  1982 
  1983 @SYMTestPurpose
  1984 To determine that the system can cope with simultaneous
  1985 reading and writing from/to area within RSgImage without corrupting each other.
  1986 
  1987 @SYMTestActions
  1988 Run two processes that independently perform the actions detailed below.
  1989 * From Process A:
  1990 	Open the RSgDriver
  1991 	Create an RSgImages with no content
  1992 	For each RSgImage, create an EGLImage and from that create a VGImage
  1993 	Close the RSgImage and the EGLImage
  1994 * From Process B:
  1995 	Open the RSgDriver
  1996 	Open the RSgImage using the drawable ID passed from process A
  1997 	Create an EGLImage and then a VGImage
  1998 	Close the RSgImage and the EGLImage
  1999 	Wait for signal from process A
  2000 
  2001 * Concurrently from Process A and the client process:
  2002 	Process A:
  2003 		For i = 1 to 9
  2004 			Shade section[i] to colour[i]
  2005 			Signal client process that section[i] can be read
  2006 			Repeat until client process signal read complete
  2007 				Shade sections surrounding section[i] to other colors e.g. when i=1, 
  2008 				surrounding sections are section 0, 2 and 4 
  2009 				End loop
  2010 			End loop
  2011 
  2012 	Process B:
  2013 		For i = 1 to 9
  2014 			Wait for signal that section[i] is ready
  2015 			Create child VGImage for section[i]
  2016 			Read the value of child VGImage and compare it with colour[i]
  2017 			Signal process A to indicate read is complete
  2018 			Destroy child VGImage
  2019 			End loop
  2020 
  2021 * Processes A and B:
  2022 Close the VGImage and RSgImage driver
  2023 
  2024 @SYMTestExpectedResults
  2025 The content of each section read by client process should match the content written by Process A.
  2026 All image memory should be freed
  2027 */
  2028 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_ReadWrite::doTestStepL()
  2029     {
  2030     SetTestStepID(_L("GRAPHICS-EGL-0431"));
  2031 	SetTestStepName(KEGL_Image_Multi_Process_VgImage_ReadWrite);
  2032     INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_ReadWrite::doTestStepL"));
  2033 
  2034 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
  2035 	if(!ret)
  2036 		{
  2037 		// The extension is not supported
  2038 		RecordTestResultL();
  2039 		CloseTMSGraphicsStep();
  2040 		return TestStepResult();
  2041 		}
  2042 
  2043 	// This test is performed for ARGB_8888 non pre-multiplied
  2044 	// as we compare pixels manually, we avoid having to do the pre-multiply in the test itself
  2045     iSourceFormat = EUidPixelFormatARGB_8888;
  2046     iSurfaceFormat = VG_sARGB_8888;
  2047 	PrintUsedPixelConfiguration();
  2048 
  2049 	// launch 2 processes
  2050 	Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName());
  2051 
  2052 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_VgImage_ReadWrite::doTestStepL"));
  2053     RecordTestResultL();
  2054     CloseTMSGraphicsStep();
  2055     return TestStepResult();
  2056     }
  2057 
  2058 void CEglTest_EGL_Image_Multi_Process_VgImage_ReadWrite::doProcessFunctionL(TInt aIdx)
  2059     {
  2060     INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_VgImage_ReadWrite::doProcessFunctionL, Process %d"),aIdx);
  2061     GetDisplayL();
  2062     CreateEglSessionL(aIdx);
  2063     iEglSess->InitializeL();
  2064     iEglSess->OpenSgDriverL();
  2065 
  2066 	const TSize KTestReadWriteImageSize(90,90);
  2067 	const TInt KTestReadWriteSubImageLength = KTestReadWriteImageSize.iHeight / 3;
  2068 	const TInt KTestNumColors = 9;
  2069 	const VGfloat KTestClearColors[KTestNumColors][4] =
  2070 		{
  2071 		{0.11f, 0.13f, 0.15f, 0.17f},	// arbitrary colour 1
  2072 		{0.21f, 0.23f, 0.25f, 0.27f},	// arbitrary colour 2
  2073 		{0.31f, 0.33f, 0.35f, 0.37f},	// arbitrary colour 3
  2074 		{0.41f, 0.43f, 0.45f, 0.47f},	// arbitrary colour 4
  2075 		{0.51f, 0.53f, 0.55f, 0.57f},	// arbitrary colour 5
  2076 		{0.61f, 0.63f, 0.65f, 0.67f},	// arbitrary colour 6
  2077 		{0.71f, 0.73f, 0.75f, 0.77f},	// arbitrary colour 7
  2078 		{0.81f, 0.83f, 0.85f, 0.87f},	// arbitrary colour 8
  2079 		{0.91f, 0.93f, 0.95f, 0.97f}	// arbitrary colour 9
  2080 		};
  2081 
  2082 	//Retrieve source formats for the launched process from the process parameters.
  2083 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat)));
  2084 	User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat)));
  2085 
  2086 	//create the queue to send/receive SgImage ID between processes
  2087 	RMsgQueue<TSgDrawableId> messageQueueSgId;
  2088     User::LeaveIfError(messageQueueSgId.Open(EProcSlotMsgQueueSgId, EOwnerProcess));
  2089     CleanupClosePushL(messageQueueSgId);
  2090 
  2091     RSgImage rSgImageLocal;
  2092     if(aIdx == 0)
  2093         {
  2094     	// Create an RSgImage
  2095     	INFO_PRINTF2(_L("Process %d, Creating a RSgImage"),aIdx);
  2096     	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(iSourceFormat, KImageSize);
  2097 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
  2098     	imageInfo.iShareable = ETrue;
  2099     	imageInfo.iCpuAccess = ESgCpuAccessReadWrite;
  2100 #endif
  2101     	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,NULL, NULL), KErrNone);
  2102 
  2103         INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx);
  2104         messageQueueSgId.SendBlocking(rSgImageLocal.Id());
  2105         }
  2106     else if(aIdx == 1)
  2107         {
  2108         INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx);
  2109         TSgDrawableId sgImageId;
  2110         messageQueueSgId.ReceiveBlocking(sgImageId);
  2111     	ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone);
  2112         }
  2113 
  2114 	// Wait for both processes to reach this point
  2115     Rendezvous(aIdx);
  2116     
  2117     INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx);
  2118 	CleanupClosePushL(rSgImageLocal);
  2119 	EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
  2120 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
  2121 	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
  2122 
  2123 	// OpenVG needs a current VG context before it will allow the call vgCreateEGLImageTargetKHR
  2124 	// The created surface will remain un-used, hence we create it with the default pixel format, as we don't care
  2125 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
  2126 	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KTestReadWriteImageSize);
  2127 	iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
  2128 
  2129 	INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx);
  2130 	VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);
  2131 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
  2132 	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal));
  2133 
  2134 	// Wait for both processes to reach this point
  2135     Rendezvous(aIdx);
  2136 
  2137     for (TInt section=0; section<9; section++)
  2138     	{
  2139     	INFO_PRINTF3(_L("Process %d, Starting loop for section[%d]"),aIdx, section);
  2140     	if (aIdx==0)
  2141     		{
  2142         	INFO_PRINTF3(_L("Process %d, Shading section[%d]"),aIdx, section);
  2143     		//Shade section[i] to color[i]
  2144     	    vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[section]);
  2145             vgClearImage(vgImageLocal, (section%3)*KTestReadWriteSubImageLength, (section/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength);        
  2146     		vgFinish();
  2147     		}
  2148 
  2149     	// Wait for both processes to reach this point
  2150         Rendezvous(aIdx);
  2151 
  2152         VGImage childImage = VG_INVALID_HANDLE;
  2153         if (aIdx==1)
  2154     		{
  2155         	INFO_PRINTF3(_L("Process %d, Creating child vgimage for section[%d]"),aIdx, section);
  2156 			//Create child VGImage for section[i]
  2157     		childImage = vgChildImage(vgImageLocal, (section%3)*KTestReadWriteSubImageLength, (section/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength);
  2158     		//Read the value of child VGImage and compare it with colour[i]
  2159 			TUint32* vgPixel = new(ELeave) TUint32[KTestReadWriteSubImageLength];
  2160 			CleanupArrayDeletePushL(vgPixel);
  2161     		for (TInt i=0; i<KTestReadWriteSubImageLength; i++)
  2162     			{
  2163     			// Read childImage, a line at a time
  2164     			vgGetImageSubData(childImage, vgPixel, 1, iSurfaceFormat, 0, i, KTestReadWriteSubImageLength, 1);
  2165     			for (TInt j=0; j<KTestReadWriteSubImageLength; j++)
  2166     				{
  2167 					// Should be exact, but give a tolerance of 1 because VG rounds to nearer integer, whereas TInt rounds down 
  2168     				ASSERT_TRUE(Abs(((vgPixel[j] & 0xff000000) >> 24) - (255 * KTestClearColors[section][3])) <= 1);	//alpha
  2169     				ASSERT_TRUE(Abs(((vgPixel[j] & 0x00ff0000) >> 16) - (255 * KTestClearColors[section][0])) <= 1);	//red
  2170     				ASSERT_TRUE(Abs(((vgPixel[j] & 0x0000ff00) >> 8) - (255 * KTestClearColors[section][1])) <= 1); 	//green
  2171     				ASSERT_TRUE(Abs(((vgPixel[j] & 0x000000ff) >> 0) - (255 * KTestClearColors[section][2])) <= 1); 	//blue
  2172 					}
  2173     			}
  2174     		CleanupStack::PopAndDestroy(vgPixel);
  2175     		}
  2176     	if (aIdx==0)
  2177     		{
  2178         	INFO_PRINTF3(_L("Process %d, Shading surrounding sections to section[%d]"),aIdx, section);
  2179         	for (TInt k=-3; k<=3; k=k+2)
  2180         		{
  2181             	TInt surroundingSection = (KTestNumColors + section + k) % KTestNumColors;
  2182         	    vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[surroundingSection]);
  2183         	    vgClearImage(vgImageLocal, (surroundingSection%3)*KTestReadWriteSubImageLength, (surroundingSection/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength);        
  2184         		}
  2185     		vgFinish(); 
  2186     		}
  2187 
  2188     	// Wait for both processes to reach this point
  2189         Rendezvous(aIdx);
  2190 
  2191         if (aIdx==1)
  2192         	{
  2193     		INFO_PRINTF3(_L("Process %d, destroying child vgimage for section[%d]"),aIdx, section);
  2194         	//Destroy child VGImage
  2195     		vgDestroyImage(childImage);
  2196     		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
  2197         	}
  2198     	}
  2199 
  2200 	// cleanup
  2201 	vgDestroyImage(vgImageLocal);
  2202 	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
  2203 	CleanupStack::PopAndDestroy(&messageQueueSgId);
  2204 	CleanAll();
  2205     }
  2206