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