egl/egltest/src/egltest_image_multithread.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 
       
     2 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 // All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 //
       
     9 // Initial Contributors:
       
    10 // Nokia Corporation - initial contribution.
       
    11 //
       
    12 // Contributors:
       
    13 //
       
    14 // Description:
       
    15 //
       
    16 
       
    17 /**
       
    18  @file
       
    19  @test
       
    20 */
       
    21 
       
    22 #include <test/tefunit.h> // for ASSERT macros
       
    23 #include "egltest_image_multithread.h"
       
    24 
       
    25 #include <test/egltestcommonconversion.h>
       
    26 #include <test/egltestcommonsgimageinfo.h>
       
    27 
       
    28 
       
    29 CEglTest_MThread_Image_Base::CEglTest_MThread_Image_Base()
       
    30 	{
       
    31 	}
       
    32 
       
    33 CEglTest_MThread_Image_Base::~CEglTest_MThread_Image_Base()
       
    34 	{
       
    35 	iSgImageShared.Close();
       
    36 	}
       
    37 
       
    38 /**
       
    39 @SYMTestCaseID GRAPHICS-EGL-0155
       
    40 
       
    41 @SYMTestPriority 1
       
    42 
       
    43 @SYMPREQ 39
       
    44 
       
    45 @SYMREQ See SGL.GT0386.401 document
       
    46 
       
    47 @SYMTestCaseDesc
       
    48 Check if EGL Implementation allows two threads to work in parallel.
       
    49 
       
    50 @SYMTestActions
       
    51 Run two threads that independently perform the same actions detailed below.
       
    52 This test will check for the “VG_KHR_EGL_image” extension, if it is not 
       
    53 supported on this platform then the test will return immediately without failure.
       
    54 Create and fully construct an RSgImage object
       
    55 •	Set the iUsage bits to ESgUsageBitOpenVgImage
       
    56 Pass the RSgImage object into eglCreateImageKHR() with
       
    57 •	The target parameter set to EGL_NATIVE_PIXMAP_KHR
       
    58 •	Use the current display and EGL_NO_CONTEXT
       
    59 •	Use a NULL attr_list
       
    60 Check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR
       
    61 Use vgCreateEGLImageTargetKHR() to construct a VGImage object from the EGLImage.
       
    62 •	Check for errors (VGInvalidHandle is not returned)
       
    63 Create a second RSgImage, and use it to create a pixmap surface that is 
       
    64 compatible as a target for the VGImage to be drawn to.
       
    65 •	Set the iUsage bit to ESgUsageBitOpenVgSurface
       
    66 •	Use the same pixel format as the RSgImage above.
       
    67 Now that a eglContext and an OpenVG context have been created, use the 
       
    68 OpenVG API vgClearImage to clear to a chosen colour the VGImage previously 
       
    69 returned by eglCreateImageKHR.
       
    70 Use OpenVG to draw the just drawn VGImage to the pixmap surface currently 
       
    71 linked to the context.
       
    72 Call eglWaitClient() to finish the above drawing instructions synchronously.
       
    73 Destroy the original image data
       
    74 •	Pass the VGImage into vgDestroyImage()
       
    75 •	Pass the EGLImage into eglDestroyImageKHR()
       
    76 •	Close the first RSgImage
       
    77 •	Check that the pixmap surface contains expected pixel values using 
       
    78 OpenVG APIs, vgReadPixels.
       
    79 Close the second RSgImage and destroy the pixmap surface
       
    80 Check for memory and handle leaks
       
    81 
       
    82 @SYMTestExpectedResults
       
    83 Pixmap surface has the expected contents in both threads (within tolerance).
       
    84 No memory or handle leaks.
       
    85 */
       
    86 TVerdict CEglTest_EGL_Image_Multi_Thread_Parallel::doTestStepL()
       
    87 	{
       
    88 	SetTestStepID(_L("GRAPHICS-EGL-0155"));
       
    89 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_Parallel::doTestStepL"));
       
    90 
       
    91 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
       
    92 	if(!ret)
       
    93 		{
       
    94 		// The extension is not supported
       
    95 		RecordTestResultL();
       
    96 		CloseTMSGraphicsStep();
       
    97 		return TestStepResult();
       
    98 		}
       
    99 
       
   100 	Test_MultiThreadL(2, ETrue);
       
   101 	TerminateDisplayL();
       
   102 
       
   103 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_Parallel::doTestStepL"));
       
   104 	RecordTestResultL();	
       
   105 	CloseTMSGraphicsStep();
       
   106 	return TestStepResult();
       
   107 	}
       
   108 
       
   109 void CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL(TInt aIdx)
       
   110 	{
       
   111 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL, Thread %d"),aIdx);
       
   112 	GetDisplayL();
       
   113 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   114 	eglSess->InitializeL();	
       
   115 	eglSess->OpenSgDriverL();
       
   116 	
       
   117 	// create a reference bitmap (we give index 7, as there's only 1 image in this test case)
       
   118 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   119 	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7);
       
   120 	CleanupStack::PushL(bitmap);
       
   121 
       
   122 	// Create an RSgImage
       
   123 	INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
       
   124 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   125     RSgImage rSgImageLocal;
       
   126 	CleanupClosePushL(rSgImageLocal);
       
   127 	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   128 
       
   129 	INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
       
   130 	EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
       
   131 	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
       
   132 	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
       
   133 	CleanupStack::PopAndDestroy(bitmap);
       
   134 
       
   135 	INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
       
   136 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
       
   137 	TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
       
   138 	// Create a pixmap surface matching the native image pixel format
       
   139 	eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly);
       
   140 	
       
   141 	INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx);
       
   142 	VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);	
       
   143 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
       
   144 	ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal));
       
   145 		
       
   146 	// Copy the source VGImage to the surface
       
   147 	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
       
   148 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   149 	eglWaitClient();
       
   150 
       
   151 	// destroy VGImage
       
   152 	vgDestroyImage(vgImageLocal);
       
   153 	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   154 
       
   155 	// we can now compare the VgImage to the one we would expect for this particular thread
       
   156 	CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7);
       
   157 	CleanupStack::PushL(refBitmap);
       
   158 	eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
       
   159 	CleanupStack::PopAndDestroy(refBitmap);
       
   160 	INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx);
       
   161 
       
   162 	// cleanup
       
   163 	eglSess->CloseSgDriver();
       
   164   	CleanupStack::PopAndDestroy(eglSess);	
       
   165 	}
       
   166 
       
   167 /**
       
   168 @SYMTestCaseID GRAPHICS-EGL-0156
       
   169 
       
   170 @SYMTestPriority 1
       
   171 
       
   172 @SYMPREQ 39
       
   173 
       
   174 @SYMREQ See SGL.GT0386.401 document
       
   175 
       
   176 @SYMTestCaseDesc
       
   177 Check if EGL Implementation allows two threads to work in parallel.
       
   178 EGLImage can’t be created from an RSgImage that already has been linked to an EGLImage by another thread.
       
   179 
       
   180 @SYMTestActions
       
   181 Main Thread: creates an RSgImage and starts thread1 and thread2.
       
   182 Thread1: Creates an EGLImage from the RSgImage previous mentioned
       
   183 --------
       
   184 Thread2: Creates an EGLImage from the RSgImage previous mentioned and check that eglCreateImageKHR() does return EGL_NO_IMAGE_KHR
       
   185 --------
       
   186 Thread1: Closes the EGLImage
       
   187 Main Thread: Closes the RSgImage.
       
   188 
       
   189 @SYMTestExpectedResults
       
   190 eglCreateImageKHR() does return EGL_NO_IMAGE_KHR in the 2nd thread and EGL_BAD_ACCESS error is generated.
       
   191 No memory or handle leaks
       
   192 */
       
   193 TVerdict CEglTest_EGL_Image_Multi_Thread_Sibling_Basic::doTestStepL()
       
   194 	{
       
   195 	SetTestStepID(_L("GRAPHICS-EGL-0156"));
       
   196 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_Sibling_Basic::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 	// Create display object
       
   208 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
       
   209     GetDisplayL();
       
   210     CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, 0);
       
   211 	eglSess->InitializeL();
       
   212 
       
   213 	// Make sure the driver is ready
       
   214 	eglSess->OpenSgDriverL();
       
   215 
       
   216 	// create a reference bitmap (we give index 0, as there's only 1 image in this test case)
       
   217 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   218 	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 0);
       
   219 	CleanupStack::PushL(bitmap);
       
   220 	
       
   221 	// Create an RSgImage (member variable as it is 'shared' in the thread funtion...) 
       
   222 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   223 	ASSERT_EQUALS(iSgImageShared.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   224 	CleanupStack::PopAndDestroy(bitmap);
       
   225 
       
   226 	// launch 2 threads
       
   227 	Test_MultiThreadL(2, ETrue);
       
   228 	
       
   229 	// clean everything
       
   230 	iSgImageShared.Close();
       
   231 	CleanupStack::PopAndDestroy(eglSess);
       
   232 	TerminateDisplayL();
       
   233 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_Sibling_Basic::doTestStepL"));
       
   234 	RecordTestResultL();
       
   235 	CloseTMSGraphicsStep();
       
   236 	return TestStepResult();
       
   237 	}
       
   238 
       
   239 void CEglTest_EGL_Image_Multi_Thread_Sibling_Basic::doThreadFunctionL(TInt aIdx)
       
   240 	{
       
   241 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Sibling_Basic::doThreadFunctionL, Thread %d"),aIdx);
       
   242 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   243 	eglSess->InitializeL();
       
   244 	eglSess->OpenSgDriverL();
       
   245 			
       
   246 	EGLImageKHR eglImageLocal = EGL_NO_IMAGE_KHR;
       
   247 	if(aIdx == 0)
       
   248 		{
       
   249 		INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
       
   250 		eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
       
   251 		ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
       
   252 		}
       
   253 	
       
   254 	Rendezvous(aIdx);
       
   255 	
       
   256 	if(aIdx == 1)
       
   257 		{
       
   258 		INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
       
   259 		eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
       
   260 		ASSERT_EGL_TRUE(eglImageLocal == EGL_NO_IMAGE_KHR);
       
   261 		ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
       
   262 		}
       
   263 	
       
   264 	Rendezvous(aIdx);
       
   265 	
       
   266 	// cleanup
       
   267 	if(aIdx == 0)
       
   268 		{
       
   269 		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal));
       
   270 		}
       
   271 	eglSess->CloseSgDriver();
       
   272 	CleanupStack::PopAndDestroy(eglSess);
       
   273 	}
       
   274 
       
   275 /**
       
   276 @SYMTestCaseID GRAPHICS-EGL-0157
       
   277 
       
   278 @SYMTestPriority 1
       
   279 
       
   280 @SYMPREQ 39
       
   281 
       
   282 @SYMREQ See SGL.GT0386.401 document
       
   283 
       
   284 @SYMTestCaseDesc
       
   285 Check if EGL Implementation allows two threads to work in parallel.
       
   286 Each thread is allowed to create a VGImage from the same EGLImage
       
   287 
       
   288 @SYMTestActions
       
   289 Main Thread: creates an RSgImage with the same content as the reference bitmap and creates an EGLImage from it; starts thread1 and thread2.
       
   290 Thread1: Creates an egl context and a pixmap surface linked to it. Creates an VGImage from the EGLImage previous mentioned
       
   291 Thread2: Creates an egl context and a pixmap surface linked to it. Creates an VGImage from the EGLImage previous mentioned
       
   292 --------
       
   293 Thread 1: Changes the content of the RSgImage by using the VGImage that has a reference to it.
       
   294 --------
       
   295 Thread1: Passes the VGImage into vgDestroyImage()
       
   296 Thread2: Copies the VGImage to the pixmap surface and checks the contents
       
   297 Thread2: Passes the VGImage into vgDestroyImage()
       
   298 Main Thread: Closes the EGLImage
       
   299 Main Thread: Closes the RSgImage
       
   300 
       
   301 @SYMTestExpectedResults
       
   302 No error is generated within both threads. The changes apported by the first thread affects the second thread. The content the pixmap surface will matches the one of the reference bitmap changed by the first thread.
       
   303 No memory or handle leaks
       
   304 */
       
   305 TVerdict CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doTestStepL()
       
   306 	{
       
   307 	SetTestStepID(_L("GRAPHICS-EGL-0157"));
       
   308 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doTestStepL"));
       
   309 
       
   310 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
       
   311 	if(!ret)
       
   312 		{
       
   313 		// The extension is not supported
       
   314 		RecordTestResultL();
       
   315 		CloseTMSGraphicsStep();
       
   316 		return TestStepResult();
       
   317 		}
       
   318 
       
   319 	// Create display object
       
   320 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
       
   321     GetDisplayL();
       
   322     CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, 0);
       
   323 	eglSess->InitializeL();
       
   324 
       
   325 	// Make sure the driver is ready
       
   326 	eglSess->OpenSgDriverL();
       
   327 
       
   328 	// create a reference bitmap (we give index 3, as there's only 1 image in this test case)
       
   329 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   330 	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 3);
       
   331 	CleanupStack::PushL(bitmap);
       
   332 	
       
   333 	// Create an RSgImage (member variable as it is 'shared' in the thread funtion...) 
       
   334 	INFO_PRINTF1(_L("Parent Thread, Creating the shared RSgImage"));
       
   335 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   336 	ASSERT_EQUALS(iSgImageShared.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   337 	CleanupStack::PopAndDestroy(bitmap);
       
   338 	
       
   339 	// Create an EGLImage from the RSgImage (member variable as it is 'shared' in the thread funtion...) 
       
   340 	INFO_PRINTF1(_L("Parent Thread, Creating the shared EGLImage"));
       
   341 	iEGLImageShared = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
       
   342 	ASSERT_EGL_TRUE(iEGLImageShared != EGL_NO_IMAGE_KHR);
       
   343 	iSgImageShared.Close();
       
   344 
       
   345 	// launch 2 threads
       
   346 	Test_MultiThreadL(2, ETrue);
       
   347 	
       
   348 	// cleanup
       
   349 	ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, iEGLImageShared));
       
   350 	CleanupStack::PopAndDestroy(eglSess);
       
   351 	TerminateDisplayL();	
       
   352 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doTestStepL"));	
       
   353 	RecordTestResultL();
       
   354 	CloseTMSGraphicsStep();
       
   355 	return TestStepResult();
       
   356 	}
       
   357 
       
   358 void CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doThreadFunctionL(TInt aIdx)
       
   359 	{	
       
   360 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doThreadFunctionL, Thread %d"),aIdx);
       
   361 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   362 	eglSess->InitializeL();
       
   363 	eglSess->OpenSgDriverL();
       
   364 
       
   365 	INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
       
   366 	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
       
   367 	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
       
   368 	// Create a pixmap surface matching the native image pixel format
       
   369 	eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
       
   370 	
       
   371 	// Create a VGImage from the EGLImage
       
   372 	INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
       
   373 	VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
       
   374 	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
       
   375 	
       
   376 	Rendezvous(aIdx);
       
   377 		
       
   378 	if(aIdx == 0)
       
   379 		{
       
   380 		INFO_PRINTF2(_L("Thread %d, Updating contents of the VGImage from the shared EGLImage"),aIdx);
       
   381 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   382 		CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 8);
       
   383     	// Add pixel data to the VGImage reference from the bitmap reference. 
       
   384         // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
       
   385 		TSize bitmapSize = bitmap->SizeInPixels();
       
   386     	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
       
   387     	TInt stride = bitmap->DataStride();
       
   388     	address += (bitmapSize.iHeight - 1) * stride;
       
   389         vgImageSubData(vgImageLocal, address, -stride, KDefaultSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
       
   390 		delete bitmap;
       
   391         bitmap = NULL;
       
   392 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   393 		eglWaitClient();
       
   394 		}
       
   395 
       
   396 	Rendezvous(aIdx);
       
   397 	
       
   398 	if(aIdx == 1)
       
   399 		{
       
   400 		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
       
   401 		// Copy the source VGImage to the surface
       
   402     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
       
   403 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   404 		eglWaitClient();
       
   405 
       
   406 		// we can now compare the VgImage to the one we expect after changing it in the other thread
       
   407 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   408 		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 8);
       
   409 		CleanupStack::PushL(refBitmap);
       
   410 		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
       
   411 		CleanupStack::PopAndDestroy(refBitmap);
       
   412 		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);
       
   413 		}		
       
   414 	
       
   415 	// cleanup
       
   416 	vgDestroyImage(vgImageLocal);
       
   417 	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
       
   418 	eglSess->CloseSgDriver();
       
   419 	CleanupStack::PopAndDestroy(eglSess);
       
   420 	}
       
   421 
       
   422 /**
       
   423 @SYMTestCaseID GRAPHICS-EGL-0158
       
   424 
       
   425 @SYMTestPriority 1
       
   426 
       
   427 @SYMPREQ 39
       
   428 
       
   429 @SYMREQ See SGL.GT0386.401 document
       
   430 
       
   431 @SYMTestCaseDesc
       
   432 Check if EGL Implementation allows two threads to work in parallel.
       
   433 Each thread is allowed to create a VGImage from an EGLImage created by another thread.
       
   434 
       
   435 @SYMTestActions
       
   436 Main Thread: creates an RSgImage ; starts thread1 and thread2.
       
   437 Thread1: Creates an EGLImage from the previous mentioned RSgImage
       
   438 --------
       
   439 Thread2: Creates an VGImage from the EGLImage created by the other thread
       
   440 --------
       
   441 Thread1: Passes the EGLImage into eglDestroyImageKHR ()
       
   442 Thread2: Passes the VGImage into vgDestroyImage()
       
   443 Main Thread: Closes the RSgImage
       
   444 
       
   445 @SYMTestExpectedResults
       
   446 No error is generated within both threads
       
   447 No memory or handle leaks
       
   448 */
       
   449 TVerdict CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doTestStepL()
       
   450 	{
       
   451 	SetTestStepID(_L("GRAPHICS-EGL-0158"));
       
   452 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doTestStepL"));
       
   453 
       
   454 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
       
   455 	if(!ret)
       
   456 		{
       
   457 		// The extension is not supported
       
   458 		RecordTestResultL();
       
   459 		CloseTMSGraphicsStep();
       
   460 		return TestStepResult();
       
   461 		}
       
   462 
       
   463 	// Create display object
       
   464 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
       
   465     GetDisplayL();
       
   466     CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, 0);
       
   467 	eglSess->InitializeL();
       
   468 
       
   469 	// Make sure the driver is ready
       
   470 	eglSess->OpenSgDriverL();
       
   471 
       
   472 	// create a reference bitmap (we give index 5, as there's only 1 image in this test case)
       
   473 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   474 	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 5);
       
   475 	CleanupStack::PushL(bitmap);
       
   476 	
       
   477 	// Create an RSgImage (member variable as it is 'shared' in the thread funtion...) 
       
   478 	INFO_PRINTF1(_L("Parent Thread, Creating the shared RSgImage"));
       
   479 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   480 	ASSERT_EQUALS(iSgImageShared.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   481 	CleanupStack::PopAndDestroy(bitmap);
       
   482 	
       
   483 	// launch 2 threads
       
   484 	Test_MultiThreadL(2, ETrue);
       
   485 	
       
   486 	// cleanup
       
   487 	iSgImageShared.Close();
       
   488 	CleanupStack::PopAndDestroy(eglSess);
       
   489 	TerminateDisplayL();	
       
   490 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doTestStepL"));	
       
   491 	RecordTestResultL();
       
   492 	CloseTMSGraphicsStep();
       
   493 	return TestStepResult();
       
   494 	}
       
   495 
       
   496 void CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doThreadFunctionL(TInt aIdx)
       
   497 	{	
       
   498 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doThreadFunctionL, Thread %d"),aIdx);
       
   499 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   500 	eglSess->InitializeL();
       
   501 	eglSess->OpenSgDriverL();	
       
   502 
       
   503 	// check there is no eglImage at the start of either thread
       
   504 	ASSERT_EGL_TRUE(iEGLImageShared == EGL_NO_IMAGE_KHR);
       
   505 	
       
   506 	// Wait for both thread to reach this point
       
   507 	//	This is important for multicore platforms (i.e., naviengine) as the execution order is not known and it could
       
   508 	//	happen that the first thread has already created the image before the second checks there is no eglImage 
       
   509 	Rendezvous(aIdx);
       
   510 
       
   511 	if(aIdx == 0)
       
   512 		{
       
   513 		// Create an EGLImage from the RSgImage (member variable as it is 'shared' in the thread function...) 
       
   514 		INFO_PRINTF2(_L("Thread %d, Creating the shared EGLImage"),aIdx);
       
   515 		iEGLImageShared = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
       
   516 		ASSERT_EGL_TRUE(iEGLImageShared != EGL_NO_IMAGE_KHR);
       
   517 		iSgImageShared.Close();
       
   518 		}
       
   519 	
       
   520 	Rendezvous(aIdx);
       
   521 	
       
   522 	if(aIdx == 1)
       
   523 		{
       
   524 		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
       
   525 		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
       
   526 		TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
       
   527 		// Create a pixmap surface matching the native image pixel format
       
   528 		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
       
   529 
       
   530 		// Create a VGImage from the EGLImage
       
   531 		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
       
   532 		VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
       
   533 		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
       
   534 
       
   535 		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
       
   536 		// Copy the source VGImage to the surface
       
   537     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
       
   538 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   539 		eglWaitClient();
       
   540 
       
   541 		// we can now compare the VgImage to the one we expect from the main thread
       
   542 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   543 		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 5);
       
   544 		CleanupStack::PushL(refBitmap);
       
   545 		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
       
   546 		CleanupStack::PopAndDestroy(refBitmap);
       
   547 		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);
       
   548 
       
   549 		vgDestroyImage(vgImageLocal);
       
   550 		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
       
   551 		}
       
   552 	
       
   553 	Rendezvous(aIdx);
       
   554 	
       
   555 	if(aIdx == 0)
       
   556 		{
       
   557 		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, iEGLImageShared));
       
   558 		iEGLImageShared = EGL_NO_IMAGE_KHR;
       
   559 		}
       
   560 	
       
   561 	// cleanup
       
   562 	eglSess->CloseSgDriver();
       
   563 	CleanupStack::PopAndDestroy(eglSess);
       
   564 	}
       
   565 
       
   566 /**
       
   567 @SYMTestCaseID GRAPHICS-EGL-0159
       
   568 
       
   569 @SYMTestPriority 1
       
   570 
       
   571 @SYMPREQ 39
       
   572 
       
   573 @SYMREQ See SGL.GT0386.401 document
       
   574 
       
   575 @SYMTestCaseDesc
       
   576 Check if EGL Implementation allows two threads to work in parallel.
       
   577 If the thread that has created the EGLImage terminates without destroying it the other thread can still use it.
       
   578 
       
   579 @SYMTestActions
       
   580 Main Thread: Creates an RSgImage ; starts thread1 and thread2.
       
   581 Thread1: An EGLImage from the previous mentioned RSgImage
       
   582 --------
       
   583 Thread1: Calls eglReleaseThread()
       
   584 Thread1: Finishes gracefully
       
   585 Thread2: Creates an VGImage the EGLImage created by the other thread
       
   586 Thread2: Passes the VGImage into vgDestroyImage()
       
   587 Thread2: Passes the EGLImage into eglDestroyImageKHR ()
       
   588 Main Thread: Closes the RSgImage.
       
   589 
       
   590 @SYMTestExpectedResults
       
   591 No error is generated within both threads
       
   592 No memory or handle leaks
       
   593 */
       
   594 TVerdict CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doTestStepL()
       
   595 	{
       
   596 	SetTestStepID(_L("GRAPHICS-EGL-0159"));
       
   597 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doTestStepL"));
       
   598 
       
   599 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
       
   600 	if(!ret)
       
   601 		{
       
   602 		// The extension is not supported
       
   603 		RecordTestResultL();
       
   604 		CloseTMSGraphicsStep();
       
   605 		return TestStepResult();
       
   606 		}
       
   607 
       
   608 	// Create display object
       
   609 	ASSERT_TRUE(iDisplay == EGL_NO_DISPLAY);
       
   610     GetDisplayL();
       
   611     CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, 0);
       
   612 	eglSess->InitializeL();
       
   613 
       
   614 	// Make sure the driver is ready
       
   615 	eglSess->OpenSgDriverL();
       
   616 
       
   617 	// create a reference bitmap (we give index 2, as there's only 1 image in this test case)
       
   618 	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   619 	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 2);
       
   620 	CleanupStack::PushL(bitmap);
       
   621 	
       
   622 	// Create an RSgImage (member variable as it is 'shared' in the thread funtion...) 
       
   623 	INFO_PRINTF1(_L("Parent Thread, Creating the shared RSgImage"));
       
   624 	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   625 	ASSERT_EQUALS(iSgImageShared.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   626 	CleanupStack::PopAndDestroy(bitmap);
       
   627 	
       
   628 	// launch 2 threads
       
   629 	Test_MultiThreadL(2, ETrue);
       
   630 	
       
   631 	// cleanup
       
   632 	iSgImageShared.Close();
       
   633 	CleanupStack::PopAndDestroy(eglSess);	
       
   634 	TerminateDisplayL();
       
   635 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doTestStepL"));	
       
   636 	RecordTestResultL();
       
   637 	CloseTMSGraphicsStep();
       
   638 	return TestStepResult();
       
   639 	}
       
   640 
       
   641 void CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doThreadFunctionL(TInt aIdx)
       
   642 	{	
       
   643 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doThreadFunctionL, Thread %d"),aIdx);
       
   644 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   645 	eglSess->InitializeL();
       
   646 	eglSess->OpenSgDriverL();
       
   647 
       
   648 	// check there is no eglImage at the start of either thread
       
   649 	ASSERT_EGL_TRUE(iEGLImageShared == EGL_NO_IMAGE_KHR);
       
   650 
       
   651 	TRequestStatus statusThread0;
       
   652 	if(aIdx == 1)
       
   653 		{
       
   654 		INFO_PRINTF2(_L("Thread %d, Asking to be notified when thread 0 exits"),aIdx);
       
   655 		iThreadStatus[0].iThread.Logon(statusThread0);
       
   656 		}
       
   657 	
       
   658 	Rendezvous(aIdx);
       
   659 	
       
   660 	//Thread 0 creates the EGLImage and exit
       
   661 	if(aIdx == 0)	
       
   662 		{
       
   663 		// Create an EGLImage from the RSgImage (member variable as it is 'shared' in the thread function...) 
       
   664 		INFO_PRINTF2(_L("Thread %d, Creating the shared EGLImage"),aIdx);
       
   665 		iEGLImageShared = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
       
   666 		ASSERT_EGL_TRUE(iEGLImageShared != EGL_NO_IMAGE_KHR);
       
   667 		iSgImageShared.Close();
       
   668 		INFO_PRINTF2(_L("Thread %d -----  Exiting ---- EGLImage should be kept alive"),aIdx);
       
   669 		}
       
   670 	
       
   671 	//Thread1 waits for Thread0 to exit and then uses the EGLImage and performs some drawing
       
   672 	if(aIdx == 1)
       
   673 		{
       
   674 		INFO_PRINTF2(_L("Thread %d, Waiting for thread 0 to exit"),aIdx);
       
   675 		User::WaitForRequest(statusThread0);
       
   676 
       
   677 		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
       
   678 		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
       
   679 		TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
       
   680 		// Create a pixmap surface matching the native image pixel format
       
   681 		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
       
   682 
       
   683 		// Create a VGImage from the EGLImage
       
   684 		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
       
   685 		VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
       
   686 		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
       
   687 
       
   688 		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
       
   689 		// Copy the source VGImage to the surface
       
   690     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
       
   691 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   692 		eglWaitClient();
       
   693 
       
   694 		// we can now compare the VgImage to the one we expect after changing it in the other thread
       
   695 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   696 		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 2);
       
   697 		CleanupStack::PushL(refBitmap);
       
   698 		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
       
   699 		CleanupStack::PopAndDestroy(refBitmap);
       
   700 		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);
       
   701 
       
   702 		vgDestroyImage(vgImageLocal);
       
   703 		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
       
   704 		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, iEGLImageShared));
       
   705 		iEGLImageShared = EGL_NO_IMAGE_KHR;
       
   706 		}
       
   707 	
       
   708 	// cleanup
       
   709 	eglSess->CloseSgDriver();
       
   710 	CleanupStack::PopAndDestroy(eglSess);
       
   711 	}
       
   712 
       
   713 
       
   714 /**
       
   715 @SYMTestCaseID GRAPHICS-EGL-0163
       
   716 
       
   717 @SYMTestPriority 1
       
   718 
       
   719 @SYMPREQ 39
       
   720 
       
   721 @SYMREQ See SGL.GT0386.401 document
       
   722 
       
   723 @SYMTestCaseDesc
       
   724 All the EGL resources may be used implicitly by a thread even after another thread has terminated the display.
       
   725 
       
   726 @SYMTestActions
       
   727 Thread0: Asks to be notified when Thread1 exits
       
   728 Thread0: Creates a RSgImage having the reference bitmap as content
       
   729 Thread0: Creates a EGLImage from the RSgImage
       
   730 Thread0: Creates a surface
       
   731 Thread0: Creates a VGImage from the EGLImage
       
   732 --------
       
   733 Thread1: Calls eglTerminate
       
   734 --------
       
   735 Thread1: Exits
       
   736 Thread0: Resumes when Thread1 exits
       
   737 Thread0: Uses the VGImage and draw it to the surface
       
   738 Thread0: Checks the contents
       
   739 
       
   740 @SYMTestExpectedResults
       
   741 Thread0 is able to use successfully the VGmage and the surface's content are the ones expected.
       
   742 */
       
   743 TVerdict CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doTestStepL()
       
   744 	{
       
   745     SetTestStepID(_L("GRAPHICS-EGL-0163"));
       
   746 	INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doTestStepL"));
       
   747 
       
   748 	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
       
   749 	if(!ret)
       
   750 		{
       
   751 		// The extension is not supported
       
   752 		RecordTestResultL();
       
   753 		CloseTMSGraphicsStep();
       
   754 		return TestStepResult();
       
   755 		}
       
   756 
       
   757 	Test_MultiThreadL(2, ETrue);
       
   758 			
       
   759 	INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doTestStepL"));	
       
   760 	RecordTestResultL();
       
   761 	CloseTMSGraphicsStep();
       
   762 	return TestStepResult();
       
   763 	}
       
   764 
       
   765 void CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL(TInt aIdx)
       
   766 	{
       
   767 	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL, Thread %d"),aIdx);
       
   768 	GetDisplayL();
       
   769 	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
       
   770 	eglSess->InitializeL();
       
   771 	eglSess->OpenSgDriverL();
       
   772 
       
   773 	TRequestStatus statusThread1;
       
   774 	VGImage vgImageLocal = VG_INVALID_HANDLE;
       
   775 	EGLint surfaceWidth;
       
   776 	EGLint surfaceHeigth;
       
   777 	
       
   778 	//Thread0 asks to be notified when Thread1 exits
       
   779 	//Creates a RSgImage having the reference bitmap as content
       
   780 	//Creates a EGLImage from the RSgImage
       
   781 	//Creates a surface
       
   782 	//Creates a VGImage from the EGLImage
       
   783 	if(aIdx == 0)
       
   784 		{
       
   785 		// Thread0 asks to be notified when Thread1 exits
       
   786 		iThreadStatus[1].iThread.Logon(statusThread1);
       
   787 
       
   788 	    RSgImage rSgImageLocal;
       
   789 		CleanupClosePushL(rSgImageLocal);
       
   790 
       
   791 		// create a reference bitmap (we give index 9, as there's only 1 image in this test case)
       
   792 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   793 		CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9);
       
   794 		CleanupStack::PushL(bitmap);
       
   795 
       
   796 		// Create an RSgImage
       
   797 		INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
       
   798 		TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
       
   799 		ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
       
   800 		CleanupStack::PopAndDestroy(bitmap);
       
   801 
       
   802 		INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
       
   803 		EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
       
   804 		ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
       
   805 		CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
       
   806 
       
   807 		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
       
   808 		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
       
   809 		TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
       
   810 		// Create a pixmap surface matching the native image pixel format
       
   811 		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly);
       
   812 
       
   813 		//We now store the size of the surface because after eglTerminate is called on the display
       
   814 		//it will not be possible to use explicitly all the resources linked to it
       
   815 		//i.e. every call to an EGL API who takes a display as an argument will raise a EGL_BAD_DISPLAY error
       
   816 		eglQuerySurface(iDisplay, eglSess->Surface(), EGL_WIDTH, &surfaceWidth);
       
   817 		eglQuerySurface(iDisplay, eglSess->Surface(), EGL_HEIGHT, &surfaceHeigth);		
       
   818 		
       
   819 		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx);
       
   820 		vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);	
       
   821 		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
       
   822 		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal));
       
   823 		}
       
   824 	
       
   825 	Rendezvous(aIdx);
       
   826 	
       
   827 	//Thread1 calls eglTerminate and exit
       
   828 	if(aIdx == 1)
       
   829 		{
       
   830 		INFO_PRINTF2(_L(", Thread %d, Calling eglTerminate and exiting"),aIdx);
       
   831 		TerminateDisplayL();
       
   832 		}
       
   833 	
       
   834 	Rendezvous(aIdx);
       
   835 	
       
   836 	//Thread0 resumes when Thread1 exits
       
   837 	//and it uses the resources that are linked to the just destroyed display
       
   838 	if(aIdx == 0)
       
   839 		{
       
   840 		User::WaitForRequest(statusThread1);
       
   841 
       
   842 		// It's still possible to use the current context, surface and VGImage even though the display has been terminated
       
   843 		//Copy the source VGImage to the surface
       
   844     	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
       
   845 		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
       
   846 		eglWaitClient();
       
   847 
       
   848 		// we can now compare the VgImage to the one we would expect for this particular thread
       
   849 		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
       
   850 		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9);
       
   851 		CleanupStack::PushL(refBitmap);
       
   852 		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
       
   853 		CleanupStack::PopAndDestroy(refBitmap);
       
   854 		INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx);
       
   855 
       
   856 		vgDestroyImage(vgImageLocal);
       
   857 		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
       
   858 		eglReleaseThread();
       
   859 		}
       
   860 	
       
   861 	// cleanup
       
   862 	eglSess->CloseSgDriver();
       
   863 	CleanupStack::PopAndDestroy(eglSess);
       
   864 	}