--- a/uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10VGImageBinder.cpp Wed Apr 14 16:53:50 2010 +0300
+++ b/uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10VGImageBinder.cpp Tue Apr 27 17:34:42 2010 +0300
@@ -1,28 +1,28 @@
/*
-* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Class HuiVg10VGImageBinder
-*
-*/
+ * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: Class HuiVg10VGImageBinder
+ *
+ */
#include "HuiVg10VgImageBinder.h"
#include "HuiVg10RenderPlugin.h"
#include "uiacceltk/HuiUtil.h"
CHuiVg10VgImageBinder::CHuiVg10VgImageBinder(CHuiVg10RenderPlugin* aRenderPlugin):
- iRenderPlugin(aRenderPlugin)
- {
- }
+iRenderPlugin(aRenderPlugin)
+ {
+ }
void CHuiVg10VgImageBinder::ConstructL()
{
@@ -48,79 +48,127 @@
TInt CHuiVg10VgImageBinder::BindClientBuffer(TUint aBuffer)
{
- // Check whether we should use the Alpha format bit
- VGImageFormat imageFormat = (VGImageFormat)vgGetParameteri(aBuffer, VG_IMAGE_FORMAT);
- TInt maskBit = 0;
- if (imageFormat == VG_sRGBA_8888_PRE)
+
+ // This returns the index of the corresponding aBuffer stored in the array.
+ // If KErrNotFound is returned,it indicates that this is the first BindClientBuffer
+ // call for aBuffer and hence eglPbufferfromclient has to be created for this buffer
+ TInt bufferIndex = iGroupOpacityImages.Find(aBuffer);
+
+
+ // This check mandates that iSavedDraw/Read Surfaces are stored only for the first time
+ // (i.e., before any pbufferfromclient surfaces are created).This is because when there are concurrent
+ // BindToImageL calls,we would eventually be losing track of the base window surface on
+ // top of which the vgImage has to be drawn.
+ if(iGroupOpacityImages.Count() == 0)
{
- maskBit = EGL_VG_ALPHA_FORMAT_PRE_BIT;
+ // Save current context and surfaces
+ iSavedContext = eglGetCurrentContext();
+ iSavedDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+ iSavedReadSurface = eglGetCurrentSurface(EGL_READ);
}
-
- const TInt BITS_PER_CHANNEL = 8;
- // Choose an EGL config
- const EGLint attrs[] =
+
+ // Buffer Index would be KErrNotFound if this is the first BindClientBuffer call for aBuffer
+ // (there would be multiple BindClientBuffer calls for an aBuffer) and hence corresponding
+ // pbufferfromclient surface has to be created for that aBuffer.
+ if(bufferIndex == KErrNotFound)
{
- EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | maskBit,
- EGL_RED_SIZE, BITS_PER_CHANNEL,
- EGL_GREEN_SIZE, BITS_PER_CHANNEL,
- EGL_BLUE_SIZE, BITS_PER_CHANNEL,
- EGL_ALPHA_SIZE, BITS_PER_CHANNEL,
- EGL_NONE
- };
+ // Check whether we should use the Alpha format bit
+ VGImageFormat imageFormat = (VGImageFormat)vgGetParameteri(aBuffer, VG_IMAGE_FORMAT);
+ TInt maskBit = 0;
+ if (imageFormat == VG_sRGBA_8888_PRE)
+ {
+ maskBit = EGL_VG_ALPHA_FORMAT_PRE_BIT;
+ }
+
+ const TInt BITS_PER_CHANNEL = 8;
+ // Choose an EGL config
+ const EGLint attrs[] =
+ {
+ EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | maskBit,
+ EGL_RED_SIZE, BITS_PER_CHANNEL,
+ EGL_GREEN_SIZE, BITS_PER_CHANNEL,
+ EGL_BLUE_SIZE, BITS_PER_CHANNEL,
+ EGL_ALPHA_SIZE, BITS_PER_CHANNEL,
+ EGL_NONE
+ };
+
+ // Create a context
+ TInt configCount = iRenderPlugin->EglChooseConfig(attrs);
+ EGLConfig config = iRenderPlugin->EglConfig(0);
+
+ // Create a pbuffer surface
+ iEglPBufferSurface_Client = eglCreatePbufferFromClientBuffer(iRenderPlugin->EglDisplay(),
+ EGL_OPENVG_IMAGE,
+ static_cast<EGLClientBuffer>(aBuffer), // Use the param image as buffer
+ config, NULL);
+ if (iEglPBufferSurface_Client == EGL_NO_SURFACE)
+ {
+ HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be created, eglErr: %04x"), eglGetError() );
+ return KErrGeneral;
+ }
+ iGroupOpacitySurfaces.Append(iEglPBufferSurface_Client);
+ iGroupOpacityImages.Append(aBuffer);
+ }
+ // Control would go to else part indicating that this is not the first BindClientBuffer for aBuffer
+ // and hence the corresponding eglPBufferfromClient surface could be retrieved with the bufferIndex
+ else
+ {
+ iEglPBufferSurface_Client = iGroupOpacitySurfaces[bufferIndex];
+ }
+
+ EGLContext context = iRenderPlugin->EglSharedContext();
- // Create a context
- TInt configCount = iRenderPlugin->EglChooseConfig(attrs);
- EGLConfig config = iRenderPlugin->EglConfig(0);
+ // eglMakeCurrent with EGL_NO_SURFACE de-couples vgImage from an old eglpbufferfromclient surface.
+ // Otherwise in a multiple BindClientBuffer scenario for the same vgImage, eglMakeCurrent
+ // fails with an EGL_BAD_ACCESS error (vgimage already inuse error)
+ eglMakeCurrent(iRenderPlugin->EglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, context);
- // Create a pbuffer surface
- iEglPBufferSurface_Client = eglCreatePbufferFromClientBuffer(iRenderPlugin->EglDisplay(),
- EGL_OPENVG_IMAGE,
- static_cast<EGLClientBuffer>(aBuffer), // Use the param image as buffer
- config, NULL);
-
- if (iEglPBufferSurface_Client == EGL_NO_SURFACE)
+ // Bind our own PBuffer surface (from VGImage)
+ if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client, iEglPBufferSurface_Client, context ) == EGL_FALSE )
{
- HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be created, eglErr: %04x"), eglGetError() );
+ HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError());
+ TInt eglError = eglGetError();
return KErrGeneral;
}
- // Save current context and surfaces
- iSavedContext = eglGetCurrentContext();
- iSavedDrawSurface = eglGetCurrentSurface(EGL_DRAW);
- iSavedReadSurface = eglGetCurrentSurface(EGL_READ);
-
- EGLContext context = iRenderPlugin->EglSharedContext();
-
- // Bind our own PBuffer surface (from VGImage)
- if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client, iEglPBufferSurface_Client, context /*iSavedContext*/) == EGL_FALSE )
- {
- HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError());
- return KErrGeneral;
- }
-
// Alles in Ordnung!
return KErrNone;
}
TInt CHuiVg10VgImageBinder::UnBindClientBuffer()
{
- if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iSavedDrawSurface, iSavedReadSurface, iSavedContext) == EGL_FALSE )
+ EGLContext context = iRenderPlugin->EglSharedContext();
+
+ // eglMakeCurrent with EGL_NO_SURFACE de-couples vgImage from an old eglpbufferfromclient surface.
+ // Otherwise in a multiple BindClientBuffer scenario for the same vgImage, eglMakeCurrent
+ // fails with an EGL_BAD_ACCESS error (vgimage already inuse error)
+ eglMakeCurrent(iRenderPlugin->EglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, context);
+
+ // iSavedDrawSurface and iSavedReadSurface would be the window surface on top of which the
+ // group opacity vgImages(aBuffers) would have to be drawn. This is the reason why we store
+ // iSavedDrawSurface only once at the start of BindClientBuffer routine.
+ if ( eglMakeCurrent(iRenderPlugin->EglDisplay(), iSavedDrawSurface, iSavedReadSurface, context) == EGL_FALSE )
{
HUI_DEBUG1(_L("CHuiVg10VgImageBinder::BindClientBuffer() - EGL Surface could not be made current, eglErr: %04x"), eglGetError());
return KErrGeneral;
}
-
- iSavedDrawSurface = 0;
- iSavedReadSurface = 0;
- iSavedContext = 0;
+
+ // When the final UnBindClientBuffer is called and the vgimage has to be drawn on to the window surface.
+ // We would lose the handles if these iSaved surfaces are set to zero.
+// iSavedDrawSurface = 0;
+// iSavedReadSurface = 0;
+// iSavedContext = 0;
if (iEglPBufferSurface_Client)
{
+ TInt bufferIndex = iGroupOpacitySurfaces.Find(iEglPBufferSurface_Client);
+ iGroupOpacitySurfaces.Remove(bufferIndex);
+ iGroupOpacityImages.Remove(bufferIndex);
eglDestroySurface( iRenderPlugin->EglDisplay(), iEglPBufferSurface_Client );
iEglPBufferSurface_Client = EGL_NO_SURFACE;
}
-
+
// Everything went fine
return KErrNone;
}