46 return self; |
46 return self; |
47 } |
47 } |
48 |
48 |
49 TInt CHuiVg10VgImageBinder::BindClientBuffer(TUint aBuffer) |
49 TInt CHuiVg10VgImageBinder::BindClientBuffer(TUint aBuffer) |
50 { |
50 { |
51 // Check whether we should use the Alpha format bit |
51 |
52 VGImageFormat imageFormat = (VGImageFormat)vgGetParameteri(aBuffer, VG_IMAGE_FORMAT); |
52 // This returns the index of the corresponding aBuffer stored in the array. |
53 TInt maskBit = 0; |
53 // If KErrNotFound is returned,it indicates that this is the first BindClientBuffer |
54 if (imageFormat == VG_sRGBA_8888_PRE) |
54 // call for aBuffer and hence eglPbufferfromclient has to be created for this buffer |
|
55 TInt bufferIndex = iGroupOpacityImages.Find(aBuffer); |
|
56 |
|
57 |
|
58 // This check mandates that iSavedDraw/Read Surfaces are stored only for the first time |
|
59 // (i.e., before any pbufferfromclient surfaces are created).This is because when there are concurrent |
|
60 // BindToImageL calls,we would eventually be losing track of the base window surface on |
|
61 // top of which the vgImage has to be drawn. |
|
62 if(iGroupOpacityImages.Count() == 0) |
55 { |
63 { |
56 maskBit = EGL_VG_ALPHA_FORMAT_PRE_BIT; |
64 // Save current context and surfaces |
|
65 iSavedContext = eglGetCurrentContext(); |
|
66 iSavedDrawSurface = eglGetCurrentSurface(EGL_DRAW); |
|
67 iSavedReadSurface = eglGetCurrentSurface(EGL_READ); |
57 } |
68 } |
|
69 |
|
70 // Buffer Index would be KErrNotFound if this is the first BindClientBuffer call for aBuffer |
|
71 // (there would be multiple BindClientBuffer calls for an aBuffer) and hence corresponding |
|
72 // pbufferfromclient surface has to be created for that aBuffer. |
|
73 if(bufferIndex == KErrNotFound) |
|
74 { |
|
75 // Check whether we should use the Alpha format bit |
|
76 VGImageFormat imageFormat = (VGImageFormat)vgGetParameteri(aBuffer, VG_IMAGE_FORMAT); |
|
77 TInt maskBit = 0; |
|
78 if (imageFormat == VG_sRGBA_8888_PRE) |
|
79 { |
|
80 maskBit = EGL_VG_ALPHA_FORMAT_PRE_BIT; |
|
81 } |
|
82 |
|
83 const TInt BITS_PER_CHANNEL = 8; |
|
84 // Choose an EGL config |
|
85 const EGLint attrs[] = |
|
86 { |
|
87 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
|
88 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | maskBit, |
|
89 EGL_RED_SIZE, BITS_PER_CHANNEL, |
|
90 EGL_GREEN_SIZE, BITS_PER_CHANNEL, |
|
91 EGL_BLUE_SIZE, BITS_PER_CHANNEL, |
|
92 EGL_ALPHA_SIZE, BITS_PER_CHANNEL, |
|
93 EGL_NONE |
|
94 }; |
|
95 |
|
96 // Create a context |
|
97 TInt configCount = iRenderPlugin->EglChooseConfig(attrs); |
|
98 EGLConfig config = iRenderPlugin->EglConfig(0); |
|
99 |
|
100 // Create a pbuffer surface |
|
101 iEglPBufferSurface_Client = eglCreatePbufferFromClientBuffer(iRenderPlugin->EglDisplay(), |
|
102 EGL_OPENVG_IMAGE, |
|
103 static_cast<EGLClientBuffer>(aBuffer), // Use the param image as buffer |
|
104 config, NULL); |
|
105 if (iEglPBufferSurface_Client == EGL_NO_SURFACE) |
|
106 { |
|
107 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be created, eglErr: %04x"), eglGetError() ); |
|
108 return KErrGeneral; |
|
109 } |
|
110 iGroupOpacitySurfaces.Append(iEglPBufferSurface_Client); |
|
111 iGroupOpacityImages.Append(aBuffer); |
|
112 } |
|
113 // Control would go to else part indicating that this is not the first BindClientBuffer for aBuffer |
|
114 // and hence the corresponding eglPBufferfromClient surface could be retrieved with the bufferIndex |
|
115 else |
|
116 { |
|
117 iEglPBufferSurface_Client = iGroupOpacitySurfaces[bufferIndex]; |
|
118 } |
|
119 |
|
120 EGLContext context = iRenderPlugin->EglSharedContext(); |
58 |
121 |
59 const TInt BITS_PER_CHANNEL = 8; |
122 // eglMakeCurrent with EGL_NO_SURFACE de-couples vgImage from an old eglpbufferfromclient surface. |
60 // Choose an EGL config |
123 // Otherwise in a multiple BindClientBuffer scenario for the same vgImage, eglMakeCurrent |
61 const EGLint attrs[] = |
124 // fails with an EGL_BAD_ACCESS error (vgimage already inuse error) |
|
125 eglMakeCurrent(iRenderPlugin->EglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, context); |
|
126 |
|
127 // Bind our own PBuffer surface (from VGImage) |
|
128 if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client, iEglPBufferSurface_Client, context ) == EGL_FALSE ) |
62 { |
129 { |
63 EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, |
130 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError()); |
64 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | maskBit, |
131 TInt eglError = eglGetError(); |
65 EGL_RED_SIZE, BITS_PER_CHANNEL, |
|
66 EGL_GREEN_SIZE, BITS_PER_CHANNEL, |
|
67 EGL_BLUE_SIZE, BITS_PER_CHANNEL, |
|
68 EGL_ALPHA_SIZE, BITS_PER_CHANNEL, |
|
69 EGL_NONE |
|
70 }; |
|
71 |
|
72 // Create a context |
|
73 TInt configCount = iRenderPlugin->EglChooseConfig(attrs); |
|
74 EGLConfig config = iRenderPlugin->EglConfig(0); |
|
75 |
|
76 // Create a pbuffer surface |
|
77 iEglPBufferSurface_Client = eglCreatePbufferFromClientBuffer(iRenderPlugin->EglDisplay(), |
|
78 EGL_OPENVG_IMAGE, |
|
79 static_cast<EGLClientBuffer>(aBuffer), // Use the param image as buffer |
|
80 config, NULL); |
|
81 |
|
82 if (iEglPBufferSurface_Client == EGL_NO_SURFACE) |
|
83 { |
|
84 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be created, eglErr: %04x"), eglGetError() ); |
|
85 return KErrGeneral; |
132 return KErrGeneral; |
86 } |
133 } |
87 |
134 |
88 // Save current context and surfaces |
|
89 iSavedContext = eglGetCurrentContext(); |
|
90 iSavedDrawSurface = eglGetCurrentSurface(EGL_DRAW); |
|
91 iSavedReadSurface = eglGetCurrentSurface(EGL_READ); |
|
92 |
|
93 EGLContext context = iRenderPlugin->EglSharedContext(); |
|
94 |
|
95 // Bind our own PBuffer surface (from VGImage) |
|
96 if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client, iEglPBufferSurface_Client, context /*iSavedContext*/) == EGL_FALSE ) |
|
97 { |
|
98 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError()); |
|
99 return KErrGeneral; |
|
100 } |
|
101 |
|
102 // Alles in Ordnung! |
135 // Alles in Ordnung! |
103 return KErrNone; |
136 return KErrNone; |
104 } |
137 } |
105 |
138 |
106 TInt CHuiVg10VgImageBinder::UnBindClientBuffer() |
139 TInt CHuiVg10VgImageBinder::UnBindClientBuffer() |
107 { |
140 { |
108 if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iSavedDrawSurface, iSavedReadSurface, iSavedContext) == EGL_FALSE ) |
141 EGLContext context = iRenderPlugin->EglSharedContext(); |
|
142 |
|
143 // eglMakeCurrent with EGL_NO_SURFACE de-couples vgImage from an old eglpbufferfromclient surface. |
|
144 // Otherwise in a multiple BindClientBuffer scenario for the same vgImage, eglMakeCurrent |
|
145 // fails with an EGL_BAD_ACCESS error (vgimage already inuse error) |
|
146 eglMakeCurrent(iRenderPlugin->EglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, context); |
|
147 |
|
148 // iSavedDrawSurface and iSavedReadSurface would be the window surface on top of which the |
|
149 // group opacity vgImages(aBuffers) would have to be drawn. This is the reason why we store |
|
150 // iSavedDrawSurface only once at the start of BindClientBuffer routine. |
|
151 if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iSavedDrawSurface, iSavedReadSurface, context) == EGL_FALSE ) |
109 { |
152 { |
110 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError()); |
153 HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError()); |
111 return KErrGeneral; |
154 return KErrGeneral; |
112 } |
155 } |
113 |
156 |
114 iSavedDrawSurface = 0; |
157 // When the final UnBindClientBuffer is called and the vgimage has to be drawn on to the window surface. |
115 iSavedReadSurface = 0; |
158 // We would lose the handles if these iSaved surfaces are set to zero. |
116 iSavedContext = 0; |
159 // iSavedDrawSurface = 0; |
|
160 // iSavedReadSurface = 0; |
|
161 // iSavedContext = 0; |
117 |
162 |
118 if (iEglPBufferSurface_Client) |
163 if (iEglPBufferSurface_Client) |
119 { |
164 { |
|
165 TInt bufferIndex = iGroupOpacitySurfaces.Find(iEglPBufferSurface_Client); |
|
166 iGroupOpacitySurfaces.Remove(bufferIndex); |
|
167 iGroupOpacityImages.Remove(bufferIndex); |
120 eglDestroySurface( iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client ); |
168 eglDestroySurface( iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client ); |
121 iEglPBufferSurface_Client = EGL_NO_SURFACE; |
169 iEglPBufferSurface_Client = EGL_NO_SURFACE; |
122 } |
170 } |
123 |
171 |
124 // Everything went fine |
172 // Everything went fine |
125 return KErrNone; |
173 return KErrNone; |
126 } |
174 } |
127 |
175 |
128 // End of file |
176 // End of file |