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