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