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