uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10VGImageBinder.cpp
branchRCL_3
changeset 17 3ac8bf5c5014
parent 0 15bf7259bb7c
child 50 1801340c26a2
equal deleted inserted replaced
11:46927d61fef3 17:3ac8bf5c5014
     1 /*
     1 /*
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
     2  * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
     3 * All rights reserved.
     3  * All rights reserved.
     4 * This component and the accompanying materials are made available
     4  * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5  * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6  * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     8  *
     9 * Initial Contributors:
     9  * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10  * Nokia Corporation - initial contribution.
    11 *
    11  *
    12 * Contributors:
    12  * Contributors:
    13 *
    13  *
    14 * Description:   Class HuiVg10VGImageBinder
    14  * Description:   Class HuiVg10VGImageBinder
    15 *
    15  *
    16 */
    16  */
    17 
    17 
    18 #include "HuiVg10VgImageBinder.h"
    18 #include "HuiVg10VgImageBinder.h"
    19 #include "HuiVg10RenderPlugin.h"
    19 #include "HuiVg10RenderPlugin.h"
    20 #include "uiacceltk/HuiUtil.h"
    20 #include "uiacceltk/HuiUtil.h"
    21 
    21 
    22 CHuiVg10VgImageBinder::CHuiVg10VgImageBinder(CHuiVg10RenderPlugin* aRenderPlugin):
    22 CHuiVg10VgImageBinder::CHuiVg10VgImageBinder(CHuiVg10RenderPlugin* aRenderPlugin):
    23     iRenderPlugin(aRenderPlugin)
    23 iRenderPlugin(aRenderPlugin)
    24     {
    24         {
    25     }
    25         }
    26 
    26 
    27 void CHuiVg10VgImageBinder::ConstructL()
    27 void CHuiVg10VgImageBinder::ConstructL()
    28     {
    28     {
    29     }
    29     }
    30 
    30 
    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