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