os/graphics/egl/egltest/src/egltest_image_multithread.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}