105 // launch 2 processes |
105 // launch 2 processes |
106 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName(), sgImage.Id()); |
106 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName(), sgImage.Id()); |
107 |
107 |
108 // destroy sgImage |
108 // destroy sgImage |
109 CleanupStack::PopAndDestroy(2, bitmap); |
109 CleanupStack::PopAndDestroy(2, bitmap); |
110 |
110 |
111 // clean everything |
111 // clean everything |
112 CleanAll(); |
112 CleanAll(); |
113 INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doTestStepL")); |
113 INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doTestStepL")); |
114 RecordTestResultL(); |
114 RecordTestResultL(); |
115 CloseTMSGraphicsStep(); |
115 CloseTMSGraphicsStep(); |
116 return TestStepResult(); |
116 return TestStepResult(); |
117 } |
117 } |
118 |
118 |
119 void CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId) |
119 void CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL(TInt aIdx,const TSgDrawableId& aSgId) |
120 { |
120 { |
121 INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL, Process %d"),aIdx); |
121 INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Sibling_Basic::doProcessFunctionL, Process %d"),aIdx); |
122 GetDisplayL(); |
122 GetDisplayL(); |
123 CreateEglSessionL(aIdx); |
123 CreateEglSessionL(aIdx); |
124 iEglSess->InitializeL(); |
124 iEglSess->InitializeL(); |
125 iEglSess->OpenSgDriverL(); |
125 iEglSess->OpenSgDriverL(); |
126 |
126 |
127 RSgImage sgImageFromId; |
127 RSgImage sgImageFromId; |
128 CleanupClosePushL(sgImageFromId); |
128 CleanupClosePushL(sgImageFromId); |
129 ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone); |
129 ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone); |
130 |
130 |
131 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
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); |
132 EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue); |
133 ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR); |
133 ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR); |
134 CleanupStack::PopAndDestroy(&sgImageFromId); |
134 CleanupStack::PopAndDestroy(&sgImageFromId); |
135 |
135 |
136 INFO_PRINTF2(_L("Process %d, EGLImage successfully created, now destroying it"),aIdx); |
136 INFO_PRINTF2(_L("Process %d, EGLImage successfully created, now destroying it"),aIdx); |
137 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage)); |
137 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage)); |
138 |
138 |
139 // cleanup |
139 // cleanup |
140 CleanAll(); |
140 CleanAll(); |
153 @SYMTestCaseDesc |
153 @SYMTestCaseDesc |
154 Check if EGL Implementation allows two processes to work in parallel. |
154 Check if EGL Implementation allows two processes to work in parallel. |
155 |
155 |
156 @SYMTestActions |
156 @SYMTestActions |
157 Run two processes that independently perform the same actions detailed below. |
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 |
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. |
159 supported on this platform then the test will return immediately without failure. |
160 Create and fully construct an RSgImage object |
160 Create and fully construct an RSgImage object |
161 • Set the iUsage bits to ESgUsageBitOpenVgImage |
161 • Set the iUsage bits to ESgUsageBitOpenVgImage |
162 Pass the RSgImage object into eglCreateImageKHR() with |
162 Pass the RSgImage object into eglCreateImageKHR() with |
163 • The target parameter set to EGL_NATIVE_PIXMAP_KHR |
163 • The target parameter set to EGL_NATIVE_PIXMAP_KHR |
164 • Use the current display and EGL_NO_CONTEXT |
164 • Use the current display and EGL_NO_CONTEXT |
165 • Use a NULL attr_list |
165 • Use a NULL attr_list |
166 Check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR |
166 Check that eglCreateImageKHR() does NOT return EGL_NO_IMAGE_KHR |
167 Use vgCreateEGLImageTargetKHR() to construct a VGImage object from the EGLImage. |
167 Use vgCreateEGLImageTargetKHR() to construct a VGImage object from the EGLImage. |
168 • Check for errors (VGInvalidHandle is not returned) |
168 • Check for errors (VGInvalidHandle is not returned) |
169 Create a second RSgImage, and use it to create a pixmap surface that is |
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. |
170 compatible as a target for the VGImage to be drawn to. |
171 • Set the iUsage bit to ESgUsageBitOpenVgSurface |
171 • Set the iUsage bit to ESgUsageBitOpenVgSurface |
172 • Use the same pixel format as the RSgImage above. |
172 • Use the same pixel format as the RSgImage above. |
173 Now that a eglContext and an OpenVG context have been created, use the |
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 |
174 OpenVG API vgClearImage to clear to a chosen colour the VGImage previously |
175 returned by eglCreateImageKHR. |
175 returned by eglCreateImageKHR. |
176 Use OpenVG to draw the just drawn VGImage to the pixmap surface currently |
176 Use OpenVG to draw the just drawn VGImage to the pixmap surface currently |
177 linked to the context. |
177 linked to the context. |
178 Call eglWaitClient() to finish the above drawing instructions synchronously. |
178 Call eglWaitClient() to finish the above drawing instructions synchronously. |
179 Destroy the original image data |
179 Destroy the original image data |
180 • Pass the VGImage into vgDestroyImage() |
180 • Pass the VGImage into vgDestroyImage() |
181 • Pass the EGLImage into eglDestroyImageKHR() |
181 • Pass the EGLImage into eglDestroyImageKHR() |
182 • Close the first RSgImage |
182 • Close the first RSgImage |
183 • Check that the pixmap surface contains expected pixel values using |
183 • Check that the pixmap surface contains expected pixel values using |
184 OpenVG APIs, vgReadPixels. |
184 OpenVG APIs, vgReadPixels. |
185 Close the second RSgImage and destroy the pixmap surface |
185 Close the second RSgImage and destroy the pixmap surface |
186 Check for memory and handle leaks |
186 Check for memory and handle leaks |
187 |
187 |
188 @SYMTestExpectedResults |
188 @SYMTestExpectedResults |
204 return TestStepResult(); |
204 return TestStepResult(); |
205 } |
205 } |
206 |
206 |
207 // launch 2 processes |
207 // launch 2 processes |
208 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName()); |
208 Test_MultiProcessL(KEglTestStepDllName, 2, TestStepName()); |
209 |
209 |
210 INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Parallel::doTestStepL")); |
210 INFO_PRINTF1(_L("Exit: CEglTest_EGL_Image_Multi_Process_Parallel::doTestStepL")); |
211 RecordTestResultL(); |
211 RecordTestResultL(); |
212 CloseTMSGraphicsStep(); |
212 CloseTMSGraphicsStep(); |
213 return TestStepResult(); |
213 return TestStepResult(); |
214 } |
214 } |
215 |
215 |
216 void CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL(TInt aIdx) |
216 void CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL(TInt aIdx) |
217 { |
217 { |
218 INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL, Process %d"),aIdx); |
218 INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Process_Parallel::doProcessFunctionL, Process %d"),aIdx); |
219 GetDisplayL(); |
219 GetDisplayL(); |
220 CreateEglSessionL(aIdx); |
220 CreateEglSessionL(aIdx); |
221 iEglSess->InitializeL(); |
221 iEglSess->InitializeL(); |
222 iEglSess->OpenSgDriverL(); |
222 iEglSess->OpenSgDriverL(); |
223 |
223 |
224 // create a reference bitmap (we give index 3 for example, as there's only 1 image in this test case) |
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); |
225 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); |
226 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 3); |
226 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 3); |
362 iEglSess->OpenSgDriverL(); |
362 iEglSess->OpenSgDriverL(); |
363 |
363 |
364 RSgImage sgImageFromId; |
364 RSgImage sgImageFromId; |
365 CleanupClosePushL(sgImageFromId); |
365 CleanupClosePushL(sgImageFromId); |
366 ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone); |
366 ASSERT_EQUALS(sgImageFromId.Open(aSgId),KErrNone); |
367 |
367 |
368 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
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); |
369 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImageFromId, KEglImageAttribsPreservedTrue); |
370 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
370 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
371 CleanupStack::PopAndDestroy(&sgImageFromId); |
371 CleanupStack::PopAndDestroy(&sgImageFromId); |
372 |
372 |
373 INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx); |
373 INFO_PRINTF2(_L("Process %d, Creating a Surface and a Context bound to OpenVG"),aIdx); |
374 TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat); |
374 TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat); |
375 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize); |
375 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize); |
376 // Create a pixmap surface matching the native image pixel format |
376 // Create a pixmap surface matching the native image pixel format |
377 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
377 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
378 |
378 |
379 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
379 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
380 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
380 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
381 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
381 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
382 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
382 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
383 |
383 |
384 if(aIdx == 0) |
384 if(aIdx == 0) |
385 { |
385 { |
386 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); |
386 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); |
387 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4); |
387 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 4); |
388 // Add pixel data to the VGImage reference from the bitmap reference. |
388 // Add pixel data to the VGImage reference from the bitmap reference. |
389 // Mind the fact that CFbsBitmap and VGImages use different coordinates origin! |
389 // Mind the fact that CFbsBitmap and VGImages use different coordinates origin! |
390 TSize bitmapSize = bitmap->SizeInPixels(); |
390 TSize bitmapSize = bitmap->SizeInPixels(); |
391 TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress()); |
391 TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress()); |
392 TInt stride = bitmap->DataStride(); |
392 TInt stride = bitmap->DataStride(); |
393 address += (bitmapSize.iHeight - 1) * stride; |
393 address += (bitmapSize.iHeight - 1) * stride; |
681 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
681 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
682 imageInfo.iShareable = ETrue; |
682 imageInfo.iShareable = ETrue; |
683 #endif |
683 #endif |
684 ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone); |
684 ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone); |
685 CleanupStack::PopAndDestroy(bitmap); |
685 CleanupStack::PopAndDestroy(bitmap); |
686 |
686 |
687 INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx); |
687 INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx); |
688 messageQueue.SendBlocking(rSgImageLocal.Id()); |
688 messageQueue.SendBlocking(rSgImageLocal.Id()); |
689 } |
689 } |
690 else if(aIdx == 1) |
690 else if(aIdx == 1) |
691 { |
691 { |
692 INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx); |
692 INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx); |
693 TSgDrawableId sgImageId; |
693 TSgDrawableId sgImageId; |
694 messageQueue.ReceiveBlocking(sgImageId); |
694 messageQueue.ReceiveBlocking(sgImageId); |
695 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
695 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
696 } |
696 } |
697 |
697 |
698 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
698 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
699 CleanupClosePushL(rSgImageLocal); |
699 CleanupClosePushL(rSgImageLocal); |
700 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
700 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
701 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
701 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
702 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
702 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
709 |
709 |
710 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
710 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
711 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
711 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
712 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
712 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
713 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
713 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
714 |
714 |
715 if(aIdx == 1) |
715 if(aIdx == 1) |
716 { |
716 { |
717 INFO_PRINTF2(_L("Process %d, Drawing the VGImage to the current surface before changing contents of the VGImage"),aIdx); |
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 |
718 // Copy the source VGImage to the surface |
719 vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight); |
719 vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight); |
720 ASSERT_TRUE(vgGetError()==VG_NO_ERROR); |
720 ASSERT_TRUE(vgGetError()==VG_NO_ERROR); |
721 eglWaitClient(); |
721 eglWaitClient(); |
722 |
722 |
723 |
723 |
724 // we can now compare the VgImage to the one we expect before we apply any change to it |
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); |
725 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat); |
726 CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0); |
726 CFbsBitmap* refBitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 0); |
727 CleanupStack::PushL(refBitmap); |
727 CleanupStack::PushL(refBitmap); |
803 • EUidPixelFormatARGB_8888 (source only) |
803 • EUidPixelFormatARGB_8888 (source only) |
804 • EUidPixelFormatARGB_8888_PRE |
804 • EUidPixelFormatARGB_8888_PRE |
805 • EUidPixelFormatA_8 (source only) |
805 • EUidPixelFormatA_8 (source only) |
806 - Note that when using EUidPixelFormatA_8 as a source, the reference bitmap display mode used is EGray256, |
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. |
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. |
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 |
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. |
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: |
811 From processes 1 to N: |
812 - Open SgImage by using TSgDrawableId, obtained from the SgImage which was passed from the process A. |
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 |
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 |
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. |
815 - Using VG extension, create VG image based on EGLImage from the previous step. |
816 - Close Sg and EGL images |
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. |
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. |
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 |
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). |
820 reference bitmap is used as an alpha mask). |
821 - Draw VGImage to the off-screen surface. |
821 - Draw VGImage to the off-screen surface. |
822 - Retrieve surface data (see vgReadPixels() API) |
822 - Retrieve surface data (see vgReadPixels() API) |
823 |
823 |
824 @SYMTestExpectedResults |
824 @SYMTestExpectedResults |
825 Creation of all drawable resources have been completed without errors. |
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 |
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. |
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. |
828 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes. |
829 */ |
829 */ |
830 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestStepL() |
830 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Upfront::doTestStepL() |
831 { |
831 { |
832 SetTestStepID(_L("GRAPHICS-EGL-0406")); |
832 SetTestStepID(_L("GRAPHICS-EGL-0406")); |
1049 - Create M SgImage(s) with the flag ESgUsageBitOpenVgImage. The size are all the same. |
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: |
1050 We are running through all the possible target configurations, with the values assumed being: |
1051 • EUidPixelFormatRGB_565 |
1051 • EUidPixelFormatRGB_565 |
1052 • EUidPixelFormatXRGB_8888 |
1052 • EUidPixelFormatXRGB_8888 |
1053 • EUidPixelFormatARGB_8888_PRE |
1053 • EUidPixelFormatARGB_8888_PRE |
1054 - Using EGL extension, create M EGLImage(s), specifying as EGLClientBuffer SgImage(s) which were created on |
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 |
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 |
1056 - Using VG extension, create VG images based on EGLImage(s) from the previous step |
1057 - Close Sg and EGL Images |
1057 - Close Sg and EGL Images |
1058 - Populate data in VGImages (see vgImageSubData(..) API), there will be different data uploaded for each VGImage |
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. |
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 |
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. |
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: |
1062 From processes 1 to N: |
1063 - Open SgImage by using TSgDrawableId, obtained from the SgImage which was passed from the process A. |
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, |
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 |
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. |
1066 - Using VG extension, create VG image based on EGLImage from the previous step. |
1067 - Close Sg and EGL images |
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. |
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. |
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. |
1070 - Draw VGImage to the off-screen surface. |
1071 - Retrieve surface data (see vgReadPixels() API) |
1071 - Retrieve surface data (see vgReadPixels() API) |
1072 |
1072 |
1073 @SYMTestExpectedResults |
1073 @SYMTestExpectedResults |
1074 Creation of all drawable resources have been completed without errors. |
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 |
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. |
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. |
1077 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes. |
1078 */ |
1078 */ |
1079 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestStepL() |
1079 TVerdict CEglTest_EGL_Image_Multi_Process_FontServer_Deferred::doTestStepL() |
1080 { |
1080 { |
1081 SetTestStepID(_L("GRAPHICS-EGL-0410")); |
1081 SetTestStepID(_L("GRAPHICS-EGL-0410")); |
1151 { |
1151 { |
1152 ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone); |
1152 ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone); |
1153 CleanupClosePushL(sgImages[i]); |
1153 CleanupClosePushL(sgImages[i]); |
1154 ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone); |
1154 ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone); |
1155 |
1155 |
1156 EGLImageKHR eglImage = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImages[i], KEglImageAttribsPreservedTrue); |
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); |
1157 ASSERT_EGL_TRUE(eglImage != EGL_NO_IMAGE_KHR); |
1158 |
1158 |
1159 VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage); |
1159 VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImage); |
1160 ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE); |
1160 ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE); |
1161 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage)); |
1161 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImage)); |
1162 |
1162 |
1163 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat); |
1163 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat); |
1164 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, i); |
1164 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, i); |
1165 // Add pixel data to the VGImage reference from the bitmap reference. |
1165 // Add pixel data to the VGImage reference from the bitmap reference. |
1166 // Mind the fact that CFbsBitmap and VGImages use different coordinates origin! |
1166 // Mind the fact that CFbsBitmap and VGImages use different coordinates origin! |
1167 TSize bitmapSize = bitmap->SizeInPixels(); |
1167 TSize bitmapSize = bitmap->SizeInPixels(); |
1168 TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress()); |
1168 TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress()); |
1169 TInt stride = bitmap->DataStride(); |
1169 TInt stride = bitmap->DataStride(); |
1170 address += (bitmapSize.iHeight - 1) * stride; |
1170 address += (bitmapSize.iHeight - 1) * stride; |
1312 - Create M SgImages with the flags ESgUsageBitOpenVgImage & ESgUsageBitOpenVgSurface. The size are all the same. |
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: |
1313 We are running through all the possible target configurations, with the values assumed being: |
1314 • EUidPixelFormatRGB_565 |
1314 • EUidPixelFormatRGB_565 |
1315 • EUidPixelFormatXRGB_8888 |
1315 • EUidPixelFormatXRGB_8888 |
1316 • EUidPixelFormatARGB_8888_PRE |
1316 • EUidPixelFormatARGB_8888_PRE |
1317 - Choose egl config, supplying as a native pixmap type in attribute (flag EGL_MATCH_NATIVE_PIXMAP) the SgImages which |
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. |
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 |
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. |
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: |
1321 - In iteration from 1 to M perform three following steps: |
1322 1. Make the pixmap surface current (see eglMakeCurrent(.) API) |
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 |
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 |
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 |
1325 ensure that bit comparison will reveal any mismatch |
1326 3. Make no surface current |
1326 3. Make no surface current |
1327 - Close all pixmap surfaces |
1327 - Close all pixmap surfaces |
1328 - Spawn N client processes. During the process launching, pass to each process single drawable ID from the SgImages. |
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 |
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. |
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: |
1331 From processes 1 to N: |
1332 - Open SgImage by TSgDrawableId obtained from the SgImage which was passed from the process A. |
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 |
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 |
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. |
1335 - Using VG extension, create VG image based on EGLImage from the previous step. |
1336 - Close both Sg and EGL images |
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. |
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. |
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. |
1339 - Draw VGImage to the off-screen surface. |
1340 - Retrieve surface data (see vgReadPixels() API) |
1340 - Retrieve surface data (see vgReadPixels() API) |
1341 |
1341 |
1342 @SYMTestExpectedResults |
1342 @SYMTestExpectedResults |
1343 Creation of all drawable resources has been completed without errors. |
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 |
1344 On return eglChooseConfig() must return EGL_OPENVG_BIT in config attribute list (actual attributes should |
1345 be retrieved via call to eglGetConfigAttrib()). |
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. |
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. |
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. |
1348 When all resources are closed, resource count maintained by RSgDriver extension is zero in all processes. |
1349 */ |
1349 */ |
1350 TVerdict CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestStepL() |
1350 TVerdict CEglTest_EGL_Image_Multi_Process_ThemeServer::doTestStepL() |
1351 { |
1351 { |
1352 SetTestStepID(_L("GRAPHICS-EGL-0415")); |
1352 SetTestStepID(_L("GRAPHICS-EGL-0415")); |
1414 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
1414 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
1415 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface; |
1415 imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface; |
1416 #else |
1416 #else |
1417 imageInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; |
1417 imageInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; |
1418 imageInfo.iShareable = ETrue; |
1418 imageInfo.iShareable = ETrue; |
1419 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
1419 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
1420 |
1420 |
1421 ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone); |
1421 ASSERT_EQUALS(sgImages[i].Create(imageInfo, NULL, NULL), KErrNone); |
1422 CleanupClosePushL(sgImages[i]); |
1422 CleanupClosePushL(sgImages[i]); |
1423 ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone); |
1423 ASSERT_EQUALS(sgIdList.Insert(sgImages[i].Id(),i), KErrNone); |
1424 |
1424 |
1425 INFO_PRINTF1(_L("Calling sequence - eglBindAPI(EGL_OPENVG_API) - eglCreatePixmapSurface - eglCreateContext - eglMakeCurrent")); |
1425 INFO_PRINTF1(_L("Calling sequence - eglBindAPI(EGL_OPENVG_API) - eglCreatePixmapSurface - eglCreateContext - eglMakeCurrent")); |
1426 ASSERT_EGL_TRUE(eglBindAPI(EGL_OPENVG_API)); |
1426 ASSERT_EGL_TRUE(eglBindAPI(EGL_OPENVG_API)); |
1427 |
1427 |
1428 const EGLint KAttrib_list_image_pre[] = { EGL_MATCH_NATIVE_PIXMAP, reinterpret_cast<EGLint>(&sgImages[i]), |
1428 const EGLint KAttrib_list_image_pre[] = { EGL_MATCH_NATIVE_PIXMAP, reinterpret_cast<EGLint>(&sgImages[i]), |
1429 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
1429 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
1430 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT, |
1430 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT, |
1431 EGL_NONE }; |
1431 EGL_NONE }; |
1432 const EGLint KAttrib_list_image_nonpre[] = {EGL_MATCH_NATIVE_PIXMAP, reinterpret_cast<EGLint>(&sgImages[i]), |
1432 const EGLint KAttrib_list_image_nonpre[] = {EGL_MATCH_NATIVE_PIXMAP, reinterpret_cast<EGLint>(&sgImages[i]), |
1433 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
1433 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
1434 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, |
1434 EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, |
1435 EGL_NONE }; |
1435 EGL_NONE }; |
1436 EGLConfig currentConfig; |
1436 EGLConfig currentConfig; |
1437 EGLint numconfigs =0; |
1437 EGLint numconfigs =0; |
1438 EGLSurface surface = EGL_NO_SURFACE; |
1438 EGLSurface surface = EGL_NO_SURFACE; |
1439 if (iSourceFormat == EUidPixelFormatARGB_8888_PRE) |
1439 if (iSourceFormat == EUidPixelFormatARGB_8888_PRE) |
1607 |
1607 |
1608 @SYMTestActions |
1608 @SYMTestActions |
1609 Run two processes that independently perform the actions detailed below. |
1609 Run two processes that independently perform the actions detailed below. |
1610 * From Process A |
1610 * From Process A |
1611 Open the RSgDriver |
1611 Open the RSgDriver |
1612 Create an RSgImage |
1612 Create an RSgImage passing an initialised bitmap |
1613 Signal (by semaphore or otherwise) to process A, passing the drawable ID to it |
1613 Signal (by semaphore or otherwise) to process B, passing the drawable ID to it |
1614 |
1614 |
1615 * From Process B: |
1615 * From Process B: |
1616 Open the RSgDriver |
1616 Open the RSgDriver |
1617 Using the drawable ID, open the RSgImage |
1617 Using the drawable ID, open the RSgImage |
|
1618 Close the RSgImage |
|
1619 Re-open the RSgImage |
|
1620 |
|
1621 * From Process A: |
|
1622 Unexpectedly terminate process A without performing any explicit clean-up |
|
1623 |
|
1624 * From Process B: |
|
1625 Wait for Process A to be killed: |
1618 Create an EGLImage from the RSgImage |
1626 Create an EGLImage from the RSgImage |
1619 Create a VGImage from the EGLImage |
1627 Create a VGImage from the EGLImage |
1620 Close the RSgImage |
1628 Close the RSgImage |
1621 Close the EGLImage |
1629 Close the EGLImage |
1622 Create an off-screen surface |
1630 Create an off-screen surface |
1623 |
1631 Draw VGImage to the off-screen surface |
1624 * From Process A: |
1632 Read the pixel data and verify that it matches the data populated by process A |
1625 Unexpectedly terminate process A without performing any explicit clean-up |
1633 Destroy the off-screen surface |
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 |
1634 Close the VGImage |
1633 Close the RSgDriver |
1635 Close the RSgDriver |
|
1636 Exit |
1634 |
1637 |
1635 @SYMTestExpectedResults |
1638 @SYMTestExpectedResults |
1636 Process B should be able to populate the VGImage with data and copy it to the off-screen surface. |
1639 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 |
1640 All allocated image memory should be freed |
1638 */ |
1641 */ |
1639 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL() |
1642 TVerdict CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL() |
1640 { |
1643 { |
1641 SetTestStepID(_L("GRAPHICS-EGL-0428")); |
1644 SetTestStepID(_L("GRAPHICS-EGL-0430")); |
1642 SetTestStepName(KEGL_Image_Multi_Process_VgImage_ProcessTerminate); |
1645 SetTestStepName(KEGL_Image_Multi_Process_VgImage_ProcessTerminate); |
1643 INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL")); |
1646 INFO_PRINTF1(_L("Enter: CEglTest_EGL_Image_Multi_Process_VgImage_ProcessTerminate::doTestStepL")); |
1644 |
1647 |
1645 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image); |
1648 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image); |
1646 if(!ret) |
1649 if(!ret) |
1682 |
1685 |
1683 //create the queue to send/receive Process ID between processes |
1686 //create the queue to send/receive Process ID between processes |
1684 RMsgQueue<TProcessId> messageQueueProcId; |
1687 RMsgQueue<TProcessId> messageQueueProcId; |
1685 User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess)); |
1688 User::LeaveIfError(messageQueueProcId.Open(EProcSlotMsgQueueProcId, EOwnerProcess)); |
1686 CleanupClosePushL(messageQueueProcId); |
1689 CleanupClosePushL(messageQueueProcId); |
1687 |
1690 |
1688 RProcess process; |
1691 RProcess process; |
1689 CleanupClosePushL(process); |
1692 CleanupClosePushL(process); |
1690 TRequestStatus status; |
1693 TRequestStatus status; |
1691 |
1694 |
1692 RSgImage rSgImageLocal; |
1695 TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat); |
1693 EGLImageKHR eglImageLocal = EGL_NO_IMAGE_KHR; |
1696 CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KImageSize, 6); |
1694 VGImage vgImageLocal = VG_INVALID_HANDLE; |
1697 CleanupStack::PushL(bitmap); |
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 |
1698 |
1898 RSgImage rSgImageLocal; |
1699 RSgImage rSgImageLocal; |
1899 if(aIdx == 0) |
1700 if(aIdx == 0) |
1900 { |
1701 { |
1901 // Create an RSgImage |
1702 // Create an RSgImage |
1928 |
1729 |
1929 INFO_PRINTF2(_L("Process %d: Closing and Opening SgImage again..."), aIdx); |
1730 INFO_PRINTF2(_L("Process %d: Closing and Opening SgImage again..."), aIdx); |
1930 rSgImageLocal.Close(); |
1731 rSgImageLocal.Close(); |
1931 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
1732 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
1932 } |
1733 } |
1933 |
1734 |
1934 // Wait for both processes to reach this point |
1735 // Wait for both processes to reach this point |
1935 Rendezvous(aIdx); |
1736 Rendezvous(aIdx); |
1936 |
1737 |
1937 if(aIdx == 0) |
1738 if(aIdx == 0) |
1938 { |
1739 { |
1939 // simulate this process being killed |
1740 // simulate this process being killed |
1940 // note that we terminate with reason=0 (otherwise the egl test framework would think it's an error) |
1741 // 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); |
1742 INFO_PRINTF2(_L("Process %d, Simulate the process is being killed!"),aIdx); |
1942 RProcess().Terminate(KErrNone); |
1743 RProcess().Terminate(KErrNone); |
1943 |
1744 |
1944 // this line is unreachable |
1745 // this line is unreachable |
1945 ASSERT(0); |
1746 ASSERT(0); |
1946 } |
1747 } |
1947 else if(aIdx == 1) |
1748 else if(aIdx == 1) |
1948 { |
1749 { |
1949 // first wait for the other process to finish |
1750 // first wait for the other process to finish |
1950 User::WaitForRequest(status); |
1751 User::WaitForRequest(status); |
1951 ASSERT_EQUALS(status.Int(), KErrNone); |
1752 ASSERT_EQUALS(status.Int(), KErrNone); |
1952 |
1753 |
1953 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
1754 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
1954 CleanupClosePushL(rSgImageLocal); |
1755 CleanupClosePushL(rSgImageLocal); |
1955 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
1756 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
1956 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
1757 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
1957 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
1758 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
1958 |
1759 |
1959 INFO_PRINTF2(_L("Creating a Surface and a Context bound to OpenVG, Process %d"),aIdx); |
1760 INFO_PRINTF2(_L("Creating a Surface and a Context bound to OpenVG, Process %d"),aIdx); |
1960 TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat); |
1761 TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(iSurfaceFormat); |
1961 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize); |
1762 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KImageSize); |
1962 // Create a pixmap surface matching the native image pixel format |
1763 // Create a pixmap surface matching the native image pixel format |
1963 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
1764 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
1965 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
1766 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
1966 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
1767 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
1967 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
1768 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
1968 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
1769 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
1969 |
1770 |
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); |
1771 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 |
1772 // Copy the source VGImage to the surface |
1986 vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight); |
1773 vgSetPixels(0, 0, vgImageLocal, 0, 0, KImageSize.iWidth, KImageSize.iHeight); |
1987 ASSERT_TRUE(vgGetError()==VG_NO_ERROR); |
1774 ASSERT_TRUE(vgGetError()==VG_NO_ERROR); |
1988 eglWaitClient(); |
1775 eglWaitClient(); |
1989 |
1776 |
1990 // we can now compare the VgImage to the one we expect |
1777 // we can now compare the VgImage to the one we expect |
1991 iEglSess->CheckVgDrawingL(iSurfaceFormat, bitmap); |
1778 iEglSess->CheckVgDrawingL(iSurfaceFormat, bitmap); |
1992 CleanupStack::PopAndDestroy(bitmap); |
|
1993 INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx); |
1779 INFO_PRINTF2(_L("Process %d, Drawing successful"),aIdx); |
1994 |
1780 |
1995 // cleanup |
1781 // cleanup |
1996 vgDestroyImage(vgImageLocal); |
1782 vgDestroyImage(vgImageLocal); |
1997 ASSERT_TRUE(vgGetError() == VG_NO_ERROR); |
1783 ASSERT_TRUE(vgGetError() == VG_NO_ERROR); |
1998 } |
1784 } |
1999 |
1785 |
2000 //cleanup and finish |
1786 //cleanup and finish |
2001 CleanupStack::PopAndDestroy(3, &messageQueueSgId); //messageQueueSgId, messageQueueProcId, process |
1787 CleanupStack::PopAndDestroy(4, &messageQueueSgId); //messageQueueSgId, messageQueueProcId, process, bitmap |
2002 CleanAll(); |
1788 CleanAll(); |
2003 } |
1789 } |
2004 |
1790 |
2005 |
1791 |
2006 /** |
1792 /** |
2143 User::WaitForRequest(status); |
1929 User::WaitForRequest(status); |
2144 ASSERT_EQUALS(status.Int(), KErrNone); |
1930 ASSERT_EQUALS(status.Int(), KErrNone); |
2145 |
1931 |
2146 // NOTE: We can't guarante when the kernel will have completed the cleanup. This process |
1932 // 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 |
1933 // 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. |
1934 // 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 |
1935 // 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 |
1936 // 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 |
1937 // 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... |
1938 // Not much we can do other than adding a small delay to ensure this... |
2153 User::After(1*1000*1000); // 1 second |
1939 User::After(1*1000*1000); // 1 second |
2154 |
1940 |
2155 // we're expecting it to fail with the appropriate error |
1941 // we're expecting it to fail with the appropriate error |
2156 TInt ret = rSgImageLocal.Open(sgImageId); |
1942 TInt ret = rSgImageLocal.Open(sgImageId); |
2157 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
1943 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
2158 INFO_PRINTF4(_L("Process %d: Opening SgImage resulted in %d (expected was %d)."), aIdx, ret, KErrNotFound); |
1944 INFO_PRINTF4(_L("Process %d: Opening SgImage resulted in %d (expected was %d)."), aIdx, ret, KErrNotFound); |
2159 ASSERT_EQUALS(ret, KErrNotFound); |
1945 ASSERT_EQUALS(ret, KErrNotFound); |
2273 iEglSess->OpenSgDriverL(); |
2059 iEglSess->OpenSgDriverL(); |
2274 |
2060 |
2275 const TSize KTestReadWriteImageSize(90,90); |
2061 const TSize KTestReadWriteImageSize(90,90); |
2276 const TInt KTestReadWriteSubImageLength = KTestReadWriteImageSize.iHeight / 3; |
2062 const TInt KTestReadWriteSubImageLength = KTestReadWriteImageSize.iHeight / 3; |
2277 const TInt KTestNumColors = 9; |
2063 const TInt KTestNumColors = 9; |
2278 const VGfloat KTestClearColors[KTestNumColors][4] = |
2064 const VGfloat KTestClearColors[KTestNumColors][4] = |
2279 { |
2065 { |
2280 {0.11f, 0.13f, 0.15f, 0.17f}, // arbitrary colour 1 |
2066 {0.11f, 0.13f, 0.15f, 0.17f}, // arbitrary colour 1 |
2281 {0.21f, 0.23f, 0.25f, 0.27f}, // arbitrary colour 2 |
2067 {0.21f, 0.23f, 0.25f, 0.27f}, // arbitrary colour 2 |
2282 {0.31f, 0.33f, 0.35f, 0.37f}, // arbitrary colour 3 |
2068 {0.31f, 0.33f, 0.35f, 0.37f}, // arbitrary colour 3 |
2283 {0.41f, 0.43f, 0.45f, 0.47f}, // arbitrary colour 4 |
2069 {0.41f, 0.43f, 0.45f, 0.47f}, // arbitrary colour 4 |
2284 {0.51f, 0.53f, 0.55f, 0.57f}, // arbitrary colour 5 |
2070 {0.51f, 0.53f, 0.55f, 0.57f}, // arbitrary colour 5 |
2285 {0.61f, 0.63f, 0.65f, 0.67f}, // arbitrary colour 6 |
2071 {0.61f, 0.63f, 0.65f, 0.67f}, // arbitrary colour 6 |
2286 {0.71f, 0.73f, 0.75f, 0.77f}, // arbitrary colour 7 |
2072 {0.71f, 0.73f, 0.75f, 0.77f}, // arbitrary colour 7 |
2287 {0.81f, 0.83f, 0.85f, 0.87f}, // arbitrary colour 8 |
2073 {0.81f, 0.83f, 0.85f, 0.87f}, // arbitrary colour 8 |
2288 {0.91f, 0.93f, 0.95f, 0.97f} // arbitrary colour 9 |
2074 {0.91f, 0.93f, 0.95f, 0.97f} // arbitrary colour 9 |
2289 }; |
2075 }; |
2290 |
2076 |
2291 //Retrieve source formats for the launched process from the process parameters. |
2077 //Retrieve source formats for the launched process from the process parameters. |
2292 User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat))); |
2078 User::LeaveIfError(User::GetTIntParameter(EProcSlotSourceFormat, reinterpret_cast<TInt&>(iSourceFormat))); |
2293 User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat))); |
2079 User::LeaveIfError(User::GetTIntParameter(EProcSlotSurfaceFormat, reinterpret_cast<TInt&>(iSurfaceFormat))); |
2306 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
2092 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE |
2307 imageInfo.iShareable = ETrue; |
2093 imageInfo.iShareable = ETrue; |
2308 imageInfo.iCpuAccess = ESgCpuAccessReadWrite; |
2094 imageInfo.iCpuAccess = ESgCpuAccessReadWrite; |
2309 #endif |
2095 #endif |
2310 ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,NULL, NULL), KErrNone); |
2096 ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,NULL, NULL), KErrNone); |
2311 |
2097 |
2312 INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx); |
2098 INFO_PRINTF2(_L("Process %d, Sending SgImage ID to other process..."), aIdx); |
2313 messageQueueSgId.SendBlocking(rSgImageLocal.Id()); |
2099 messageQueueSgId.SendBlocking(rSgImageLocal.Id()); |
2314 } |
2100 } |
2315 else if(aIdx == 1) |
2101 else if(aIdx == 1) |
2316 { |
2102 { |
2317 INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx); |
2103 INFO_PRINTF2(_L("Process %d: Receiving SgImage ID from other process..."), aIdx); |
2318 TSgDrawableId sgImageId; |
2104 TSgDrawableId sgImageId; |
2319 messageQueueSgId.ReceiveBlocking(sgImageId); |
2105 messageQueueSgId.ReceiveBlocking(sgImageId); |
2320 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
2106 ASSERT_EQUALS(rSgImageLocal.Open(sgImageId),KErrNone); |
2321 } |
2107 } |
2322 |
2108 |
2323 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
2109 INFO_PRINTF2(_L("Process %d, Creating an EGLImage from the shared RSgImage"),aIdx); |
2324 CleanupClosePushL(rSgImageLocal); |
2110 CleanupClosePushL(rSgImageLocal); |
2325 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
2111 EGLImageKHR eglImageLocal = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue); |
2326 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
2112 ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR); |
2327 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
2113 CleanupStack::PopAndDestroy(&rSgImageLocal); //transferring ownership of the buffer to the EGLImage |
2328 |
2114 |
2329 // OpenVG needs a current VG context before it will allow the call vgCreateEGLImageTargetKHR |
2115 // 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 |
2116 // 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); |
2117 TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat); |
2332 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KTestReadWriteImageSize); |
2118 TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KTestReadWriteImageSize); |
2333 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
2119 iEglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly); |
2334 |
2120 |
2335 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
2121 INFO_PRINTF2(_L("Process %d, Creating one VGImage from the EGLImage"),aIdx); |
2336 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
2122 VGImage vgImageLocal = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal); |
2337 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
2123 ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE); |
2338 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
2124 ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, eglImageLocal)); |
2339 |
2125 |
2340 // Wait for both processes to reach this point |
2126 // Wait for both processes to reach this point |
2341 Rendezvous(aIdx); |
2127 Rendezvous(aIdx); |
2342 |
2128 |
2343 for (TInt section=0; section<9; section++) |
2129 for (TInt section=0; section<9; section++) |
2344 { |
2130 { |
2346 if (aIdx==0) |
2132 if (aIdx==0) |
2347 { |
2133 { |
2348 INFO_PRINTF3(_L("Process %d, Shading section[%d]"),aIdx, section); |
2134 INFO_PRINTF3(_L("Process %d, Shading section[%d]"),aIdx, section); |
2349 //Shade section[i] to color[i] |
2135 //Shade section[i] to color[i] |
2350 vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[section]); |
2136 vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[section]); |
2351 vgClearImage(vgImageLocal, section%3, section/3, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
2137 vgClearImage(vgImageLocal, (section%3)*KTestReadWriteSubImageLength, (section/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
|
2138 vgFinish(); |
2352 } |
2139 } |
2353 |
2140 |
2354 // Wait for both processes to reach this point |
2141 // Wait for both processes to reach this point |
2355 Rendezvous(aIdx); |
2142 Rendezvous(aIdx); |
2356 |
2143 |
2357 VGImage childImage = VG_INVALID_HANDLE; |
2144 VGImage childImage = VG_INVALID_HANDLE; |
2358 if (aIdx==1) |
2145 if (aIdx==1) |
2359 { |
2146 { |
2360 INFO_PRINTF3(_L("Process %d, Creating child vgimage for section[%d]"),aIdx, section); |
2147 INFO_PRINTF3(_L("Process %d, Creating child vgimage for section[%d]"),aIdx, section); |
2361 //Create child VGImage for section[i] |
2148 //Create child VGImage for section[i] |
2362 childImage = vgChildImage(vgImageLocal, section%3, section/3, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
2149 childImage = vgChildImage(vgImageLocal, (section%3)*KTestReadWriteSubImageLength, (section/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
2363 //Read the value of child VGImage and compare it with colour[i] |
2150 //Read the value of child VGImage and compare it with colour[i] |
2364 TUint32 vgPixel=0; |
2151 TUint32* vgPixel = new(ELeave) TUint32[KTestReadWriteSubImageLength]; |
|
2152 CleanupArrayDeletePushL(vgPixel); |
2365 for (TInt i=0; i<KTestReadWriteSubImageLength; i++) |
2153 for (TInt i=0; i<KTestReadWriteSubImageLength; i++) |
2366 { |
2154 { |
|
2155 // Read childImage, a line at a time |
|
2156 vgGetImageSubData(childImage, vgPixel, 1, iSurfaceFormat, 0, i, KTestReadWriteSubImageLength, 1); |
2367 for (TInt j=0; j<KTestReadWriteSubImageLength; j++) |
2157 for (TInt j=0; j<KTestReadWriteSubImageLength; j++) |
2368 { |
2158 { |
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 |
2159 // 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 |
2160 ASSERT_TRUE(Abs(((vgPixel[j] & 0xff000000) >> 24) - (255 * KTestClearColors[section][3])) <= 1); //alpha |
2372 ASSERT_TRUE(Abs(((vgPixel & 0x00ff0000) >> 16) - (255 * KTestClearColors[section][0])) <= 1); //red |
2161 ASSERT_TRUE(Abs(((vgPixel[j] & 0x00ff0000) >> 16) - (255 * KTestClearColors[section][0])) <= 1); //red |
2373 ASSERT_TRUE(Abs(((vgPixel & 0x0000ff00) >> 8) - (255 * KTestClearColors[section][1])) <= 1); //green |
2162 ASSERT_TRUE(Abs(((vgPixel[j] & 0x0000ff00) >> 8) - (255 * KTestClearColors[section][1])) <= 1); //green |
2374 ASSERT_TRUE(Abs(((vgPixel & 0x000000ff) >> 0) - (255 * KTestClearColors[section][2])) <= 1); //blue |
2163 ASSERT_TRUE(Abs(((vgPixel[j] & 0x000000ff) >> 0) - (255 * KTestClearColors[section][2])) <= 1); //blue |
2375 } |
2164 } |
2376 } |
2165 } |
|
2166 CleanupStack::PopAndDestroy(vgPixel); |
2377 } |
2167 } |
2378 if (aIdx==0) |
2168 if (aIdx==0) |
2379 { |
2169 { |
2380 INFO_PRINTF3(_L("Process %d, Shading surrounding sections to section[%d]"),aIdx, section); |
2170 INFO_PRINTF3(_L("Process %d, Shading surrounding sections to section[%d]"),aIdx, section); |
2381 for (TInt k=-3; k<=3; k=k+2) |
2171 for (TInt k=-3; k<=3; k=k+2) |
2382 { |
2172 { |
2383 TInt surroundingSection = (KTestNumColors + section + k) % KTestNumColors; |
2173 TInt surroundingSection = (KTestNumColors + section + k) % KTestNumColors; |
2384 vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[surroundingSection]); |
2174 vgSetfv(VG_CLEAR_COLOR, 4, KTestClearColors[surroundingSection]); |
2385 vgClearImage(vgImageLocal, surroundingSection*KTestReadWriteSubImageLength, section*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
2175 vgClearImage(vgImageLocal, (surroundingSection%3)*KTestReadWriteSubImageLength, (surroundingSection/3)*KTestReadWriteSubImageLength, KTestReadWriteSubImageLength, KTestReadWriteSubImageLength); |
2386 } |
2176 } |
|
2177 vgFinish(); |
2387 } |
2178 } |
2388 |
2179 |
2389 // Wait for both processes to reach this point |
2180 // Wait for both processes to reach this point |
2390 Rendezvous(aIdx); |
2181 Rendezvous(aIdx); |
2391 |
2182 |