--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/guestegl.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,2274 @@
+// Copyright (c) 2010 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:
+// Guest EGL implementation
+
+#include <graphics/surfacemanager.h>
+#include <graphics/surfaceconfiguration.h>
+#include <graphics/suerror.h>
+#include <graphics/surface_hints.h>
+#include <e32debug.h>
+#include <stdlib.h> // for malloc
+#include "eglapi.h"
+
+#include <graphics/guestvideodriverinterfaceconstants.h>
+
+
+// FAISALMEMON HOLE 0
+
+// -----------------------------------------------------------------------------
+// constructor
+// -----------------------------------------------------------------------------
+//
+
+// FAISALMEMON STUB CODE
+#define PITCH_OF_TWIPS_PIXELS(a, b) 1 /* This is incorrect; just a stub*/
+#define EGL_CHECK_ERROR(a, b, c) /* This does no checking; just a stub */
+void CGuestEGL::EglInternalFunction_DestroyWindowSurface(TSurfaceInfo&)
+ {
+ return; // stub code
+ }
+
+EGLBoolean CGuestEGL::EglInternalFunction_SurfaceResized(TEglThreadState&, TSurfaceInfo&, int, int)
+ {
+ return EFalse; // stub code
+ }
+
+TBool CGuestEGL::EglInternalFunction_SwapWindowSurface(TEglThreadState&, int, int)
+ {
+ return EFalse; // stub code
+ }
+TSymbianPixmapTypeId CGuestEGL::EglInternalFunction_GetNativePixmapType(void*)
+ {
+ return EPixmapTypeNone; // stub code
+ }
+TBool CGuestEGL::EglInternalFunction_IsValidNativePixmap(void*, TSymbianPixmapTypeId)
+ {
+ return EFalse; // stub code
+ }
+const char * CGuestEGL::EglInternalFunction_QueryExtensionList()
+ {
+ return NULL; // stub code
+ }
+ProcPointer CGuestEGL::eglGetProcAddress(const char*)
+ {
+ return NULL; // stub code
+ }
+
+EGLSurface CGuestEGL::eglCreateWindowSurface(TEglThreadState&, int, int, void*, const int*)
+ {
+ return 0; // stub code
+ }
+const char* CGuestEGL::eglQueryString(EGLDisplay aDisplay, EGLint aName)
+ {
+ return NULL; // stub code
+ }
+// FAISALMEMON END OF STUB CODE
+
+CGuestEGL::CGuestEGL() :
+ iEglSyncExtension(NULL)
+ {
+ }
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+void CGuestEGL::OpenSgResources()
+ {
+ // ToDo delay opening SgDriver until needed, as it force loads Open GL ES 1.1, GL ES 2 and Open VG DLLs if it finds them
+ TInt err = iSgDriver.Open();
+ EGL_TRACE(" CGuestEGL::Create SgDriver.Open err=%d", err);
+ EGLPANIC_ASSERT(err == KErrNone, EEglPanicSgDriverCreateLocalFailed);
+
+ TVersion sgImageVer = RSgDriver::Version();
+ EGL_TRACE(" CGuestEGL::Create sgImageVer=%d.%d", sgImageVer.iMajor, sgImageVer.iMinor);
+ EGLPANIC_ASSERT(sgImageVer.iMajor == 1, EEglPanicBadSgDriverVersion);
+
+ }
+void CGuestEGL::CloseSgResources()
+ {
+ iSgDriver.Close();
+ }
+#else
+void CGuestEGL::CloseSgResources()
+ {
+ }
+
+void CGuestEGL::OpenSgResources()
+ {
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+// destructor
+// -----------------------------------------------------------------------------
+//
+CGuestEGL::~CGuestEGL()
+ {
+ EGL_TRACE("CGuestEGL::~CGuestEGL");
+ // only expected to be called during process termination
+ if (iEglSyncExtension)
+ {
+ delete iEglSyncExtension;
+ iEglSyncExtension = NULL;
+ }
+ iDisplayMapLock.Close();
+ CloseSgResources();
+ iEglImageLock.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// 2nd phase constructor
+// -----------------------------------------------------------------------------
+//
+void CGuestEGL::Create()
+ {
+ EGL_TRACE(" CGuestEGL::Create -->");
+ OpenSgResources();
+ TInt err;
+ err = iDisplayMapLock.CreateLocal();
+ EGLPANIC_ASSERT(err == KErrNone, EEglPanicDisplayMapLockCreateLocalFailed);
+
+ err = iEglImageLock.CreateLocal();
+ EGLPANIC_ASSERT(err == KErrNone, EEglPanicEglImageLockCreateLocalFailed);
+
+ InitialiseExtensions();
+
+ const char* initExtensionList = EglInternalFunction_QueryExtensionList();
+ EGL_TRACE(" CGuestEGL::Create initExtensionList=0x%x (\"%s\") <--",
+ initExtensionList, initExtensionList ? initExtensionList : "");
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CGuestEGL* CGuestEGL::New()
+ {
+ EGL_TRACE("CGuestEGL::New start -->");
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ CGuestEGL* result = new CGuestEGL();
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ EGLPANIC_ASSERT(result, EEglPanicGuestGraphicsAllocFailed);
+ if (result)
+ {
+ result->Create();
+ }
+ EGL_TRACE("CGuestEGL::New end - result=0x%x <--", result);
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CGuestEGL::SetError(EGLint aError)
+ { // ToDo remove - everything except EGL Sync already uses threadState->SetEglError
+ EGL_TRACE( "CGuestEGL::SetError EGL error=0x%x", aError);
+ TEglThreadState* threadState = CVghwUtils::EglThreadState();
+ if (threadState)
+ {
+ threadState->SetEglError(aError);
+ }
+ }
+
+EGLint CGuestEGL::CheckColorAttributes(const EGLint* aAttribList, EGLint aColorBufferType, EGLint aLuminanceBits, EGLint aRedBits,
+ EGLint aGreenBits, EGLint aBlueBits, EGLint aAlphaBits)
+ {
+ const EGLint* pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_COLOR_BUFFER_TYPE);
+ if (pValue && (*pValue != aColorBufferType))
+ {
+ return EGL_BAD_MATCH;
+ }
+ EGLint colorBits = 0;
+ if (aColorBufferType == EGL_RGB_BUFFER)
+ {
+ colorBits = aRedBits + aGreenBits + aBlueBits + aAlphaBits;
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_RED_SIZE);
+ if (pValue && (*pValue < aRedBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_GREEN_SIZE);
+ if (pValue && (*pValue < aGreenBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_BLUE_SIZE);
+ if (pValue && (*pValue < aBlueBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_LUMINANCE_SIZE);
+ if (pValue && (*pValue != 0))
+ {
+ return EGL_BAD_MATCH;
+ }
+ }
+ else
+ { // EGL_LUMINANCE_BUFFER
+ colorBits = aLuminanceBits + aAlphaBits;
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_RED_SIZE);
+ if (pValue && (*pValue != 0))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_GREEN_SIZE);
+ if (pValue && (*pValue != 0))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_BLUE_SIZE);
+ if (pValue && (*pValue != 0))
+ {
+ return EGL_BAD_MATCH;
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_LUMINANCE_SIZE);
+ if (pValue && (*pValue < aLuminanceBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ }
+
+ if (aAlphaBits)
+ {
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_ALPHA_SIZE);
+ if (pValue && (*pValue < aAlphaBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ }
+
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_BUFFER_SIZE);
+ if (pValue && (*pValue < colorBits))
+ {
+ return EGL_BAD_MATCH;
+ }
+ return EGL_SUCCESS;
+ }
+
+void CGuestEGL::AppendColorAttributes(EGLint* aAttribList, EGLint aColorBufferType, EGLint aLuminanceBits, EGLint aRedBits,
+ EGLint aGreenBits, EGLint aBlueBits, EGLint aAlphaBits, TBool aSetVgPreMultAlpha)
+ {
+ const EGLint* pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_COLOR_BUFFER_TYPE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_COLOR_BUFFER_TYPE, aColorBufferType);
+ }
+
+ EGLint colorBits = 0;
+ if (aColorBufferType == EGL_RGB_BUFFER)
+ {
+ colorBits = aRedBits + aGreenBits + aBlueBits + aAlphaBits;
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_RED_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_RED_SIZE, aRedBits);
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_GREEN_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_GREEN_SIZE, aGreenBits);
+ }
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_BLUE_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_BLUE_SIZE, aBlueBits);
+ }
+ }
+ else
+ { // EGL_LUMINANCE_BUFFER
+ colorBits = aLuminanceBits + aAlphaBits;
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_LUMINANCE_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_LUMINANCE_SIZE, aLuminanceBits);
+ }
+ }
+
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_BUFFER_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_BUFFER_SIZE, colorBits);
+ }
+
+ if (aAlphaBits)
+ {
+ pValue = TAttribUtils::FindAttribValue(aAttribList, EGL_ALPHA_SIZE);
+ if (!pValue)
+ {
+ TAttribUtils::AppendAttribValue(aAttribList, EGL_ALPHA_SIZE, aAlphaBits);
+ }
+ }
+ if (aSetVgPreMultAlpha)
+ {
+ EGLint* pSurfaceType = TAttribUtils::FindAttribValue(aAttribList, EGL_SURFACE_TYPE);
+ if (pSurfaceType)
+ {
+ *pSurfaceType |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
+ }
+ }
+ }
+
+EGLBoolean CGuestEGL::ChooseConfigForPixmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint* aAttribList, EGLConfig* aConfigs, EGLint aConfigSize,
+ EGLint* aNumConfig, const void* aPixmap)
+ {
+ EGLint error = EGL_SUCCESS;
+ EGLint* newList = NULL;
+
+ switch ( EglInternalFunction_GetNativePixmapType((EGLNativePixmapType) (aPixmap)) )
+ {
+ case EPixmapTypeFbsBitmap:
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 1.a pixmap type is FbsBitmap (aPixmap=0x%x)", aPixmap);
+ error = ChooseConfigAttribsForFbsBitmap(aThreadState, aAttribList, reinterpret_cast<const CFbsBitmap*>(aPixmap), &newList);
+ break;
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+ case EPixmapTypeSgImage:
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 1.b pixmap type is SgImage (aPixmap=0x%x)", aPixmap);
+ error = ChooseConfigAttribsForSgImage(aThreadState, aAttribList, reinterpret_cast<const RSgImage*>(aPixmap), &newList);
+ break;
+#endif
+
+ case EPixmapTypeNone:
+ default:
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 1.c pixmap type is unknown (aPixmap=0x%x)", aPixmap);
+ error = EGL_BAD_NATIVE_PIXMAP;
+ break;
+ }
+
+ if (error != EGL_SUCCESS)
+ {
+ aThreadState.SetEglError(error);
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 2.a encountered error=0x%x", error);
+ if (newList)
+ {
+ CVghwUtils::Free(newList);
+ }
+ return EGL_FALSE;
+ }
+
+ EGLPANIC_ASSERT(newList, EEglPanicTemp);
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 2.b temp AttribList ... (*newList=0x%x)", *newList);
+ EGL_TRACE_ATTRIB_LIST(newList);
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglChooseConfig );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLintVector(newList, TAttribUtils::AttribListLength(newList) );
+ eglApiData.AppendEGLConfigVector(aConfigs, aConfigSize, RemoteFunctionCallData::EOut);
+ eglApiData.AppendEGLint(aConfigSize);
+ eglApiData.AppendEGLintVector(aNumConfig, 1, RemoteFunctionCallData::EOut);
+ EGLBoolean result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE("CGuestEGL::ChooseConfigForPixmapSurface 3. Host EGL success=%d", result);
+
+ CVghwUtils::Free(newList);
+ return result;
+ }
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+EGLBoolean CGuestEGL::ChooseConfigForNativeSgImagePixmapSurface( TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint* aAttribList, EGLConfig* aConfigs, EGLint aConfigSize,
+ EGLint* aNumConfig, const EGLint* aPixmap )
+ {
+ EGLConfig* sgConfigs;
+ EGLint sgConfigCnt;
+ TBool* sgConfigsMatchingAttributes;
+ TInt sgConfigsMatchingAttributesCnt=0;
+ EGLint* sgConfigAttribs;
+ EGLint sgConfigsAttribtCnt;
+ EGL_TRACE( "CGuestEGL::eglChooseConfig: ChooseConfigForNativePixmapSurface" );
+ EglInternalFunction_MetaGetConfigs( aThreadState, sgConfigs, sgConfigCnt, sgConfigAttribs, sgConfigsAttribtCnt );
+ EGL_TRACE( "EglInternalFunction_MetaGetConfigAttirb cnt = %d ", sgConfigsAttribtCnt );
+
+ sgConfigsMatchingAttributes = new TBool[sgConfigCnt];
+
+ TInt attribs_per_config = EglRFC::MetaGetConfigAttributeCnt();
+ TInt configcnt = (TInt) sgConfigsAttribtCnt / attribs_per_config;
+ EGL_TRACE( "EglInternalFunction_MetaGetConfigs cnt = %d ", configcnt );
+
+ //The attribute values of aAttribList, in the order of MetaGetConfigAttribute(i)
+ EGLint* specAttribVals = new EGLint[ attribs_per_config ];
+ for( TInt i=0;i<attribs_per_config;++i )
+ {
+ *( specAttribVals + i ) = -1;
+ }
+ int spec_attrib_kind;
+ int i_spec_attrib = 0;
+ //Go through all the given attributes
+ while( (spec_attrib_kind = *(aAttribList + i_spec_attrib )) != EGL_NONE )
+ {
+ //Check which type of attribute is specified, then set the value if types match
+ for( TInt i=0;i<attribs_per_config;++i )
+ {
+ if( spec_attrib_kind == EglRFC::MetaGetConfigAttribute( i ) )
+ *(specAttribVals + i) = *( aAttribList + i_spec_attrib );
+ }
+ i_spec_attrib += 2;
+ }
+
+ //Go through the configurations
+ for( TInt i_config = 0;i_config < configcnt; ++i_config )
+ {
+ TBool pass = ETrue;//true, unless we bump into an attribute that doesn't match
+ //Go throught the attributes of this configuration
+ for( TInt i_attr = 0; i_attr < attribs_per_config; ++i_attr )
+ {
+ EGL_TRACE( "cnf %d, attr %d = %d ", i_config, i_attr, *( sgConfigAttribs + i_config*attribs_per_config + i_attr ) );
+ //Match attribute values here, if the client-specified attribute value isn't empty
+ if( *( specAttribVals + i_attr ) != -1 )
+ {
+ switch( EglRFC::MetaGetConfigAttributeSelCriteria( i_attr ) )
+ {
+ case EExact:
+ {
+ if( *( specAttribVals + i_attr ) != *( sgConfigAttribs + i_config*attribs_per_config + i_attr ) )
+ {
+ pass = EFalse;
+ }
+ break;
+ }
+ case EAtLeast:
+ {
+ if( *( specAttribVals + i_attr ) > *( sgConfigAttribs + i_config*attribs_per_config + i_attr ) )
+ {
+ pass = EFalse;
+ }
+ break;
+ }
+ case EMask:
+ {
+ if( !(*( specAttribVals + i_attr ) & *( sgConfigAttribs + i_config*attribs_per_config + i_attr )) )
+ {
+ pass = EFalse;
+ }
+ break;
+ }
+ }//switch comparison method
+
+ }//if attribute value specified by client
+ }//for through the attributes of a configuration
+ if( pass )
+ {
+ *(sgConfigsMatchingAttributes + i_config) = ETrue;
+ }
+ else
+ {
+ *(sgConfigsMatchingAttributes + i_config) = EFalse;
+ }
+ }//end for through the configurations
+
+ //Now get the configs that match, and return those
+ TInt aConfigsIndex = 0;
+ for( TInt i_config = 0;i_config < configcnt; ++i_config )
+ {
+ if( *(sgConfigsMatchingAttributes + i_config) )
+ {
+ if( aConfigsIndex < aConfigSize )
+ {
+ *(aConfigs + (aConfigsIndex++)) = *(sgConfigs + i_config);
+ ++sgConfigsMatchingAttributesCnt;
+ }
+ }
+ }
+ //Ok, all done. Delete allocated memory
+ // ToDo use correct Heap!
+ delete[] sgConfigs;
+ delete[] sgConfigsMatchingAttributes;
+ delete[] sgConfigAttribs;
+ delete[] specAttribVals;
+ return EGL_TRUE;
+ }
+#endif
+
+EGLint CGuestEGL::ChooseConfigAttribsForFbsBitmap(TEglThreadState& aThreadState, const EGLint* aAttribList, const CFbsBitmap* aBitmap, EGLint** aNewList)
+ {
+ EGLPANIC_ASSERT_DEBUG(aNewList, EEglPanicTemp);
+ EGLint error = EGL_SUCCESS;
+ const TInt listLength = TAttribUtils::AttribListLength(aAttribList);
+ ASSERT(listLength);
+ TDisplayMode mode = ENone;
+ const EGLint* pRenderType = TAttribUtils::FindAttribValue(aAttribList, EGL_RENDERABLE_TYPE);
+
+ mode = aBitmap->DisplayMode();
+ EGL_TRACE("CGuestEGL::ChooseConfigAttribsForFbsBitmap bitmap addr=0x%x, Display Mode=%d", aBitmap, mode);
+ switch (mode)
+ {
+ case EColor64K:
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 5, 6, 5);
+ break;
+ case EColor16M:
+ case EColor16MU:
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 8, 8, 8);
+ break;
+ case EColor16MA:
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ break;
+ case EColor16MAP:
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ break;
+ default: // pixmap not supported
+ error = EGL_BAD_NATIVE_PIXMAP;
+ break;
+ }
+
+ if (error != EGL_SUCCESS)
+ {
+ return error;
+ }
+
+ const TInt KExpansionSpace = 10 * 2; // want enough space for 10 extra attribute/value pairs
+ *aNewList = (EGLint*) CVghwUtils::Alloc( (listLength + KExpansionSpace) * sizeof(EGLint) );
+ if (!*aNewList)
+ {
+ return EGL_BAD_ALLOC;
+ }
+ memcpy(*aNewList, aAttribList, listLength * sizeof(EGLint));
+
+ switch (mode)
+ {
+ case EColor64K:
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 5, 6, 5);
+ break;
+ case EColor16M:
+ case EColor16MU:
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8);
+ break;
+ case EColor16MA:
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ break;
+ case EColor16MAP:
+ if (pRenderType && ( (*pRenderType) & EGL_OPENVG_BIT) )
+ {
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8, ETrue);
+ }
+ else
+ {
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ }
+ break;
+ default:
+ EGLPANIC_ALWAYS(EEglPanicTemp);
+ }
+
+ return EGL_SUCCESS;
+ }
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+EGLint CGuestEGL::ChooseConfigAttribsForSgImage(TEglThreadState& aThreadState, const EGLint* aAttribList, const RSgImage* aSgImage, EGLint** aNewList)
+ {
+ ASSERT(aNewList);
+ EGLint error = EGL_SUCCESS;
+ const TInt listLength = TAttribUtils::AttribListLength(aAttribList);
+ ASSERT(listLength);
+ const EGLint* pRenderType = TAttribUtils::FindAttribValue(aAttribList, EGL_RENDERABLE_TYPE);
+
+ /*
+ if (!iSgConfigAttribs)
+ {
+ EGL_TRACE( "CGuestEGL::ChooseConfigAttribsForSgImage 1. EglInternalFunction_MetaGetConfigs" );
+ EGLConfig* config;
+ EGLint config_cnt;
+ EglInternalFunction_MetaGetConfigs(aThreadState, config, config_cnt, iSgConfigAttribs, iSgConfigsAttribtCnt);
+ EGL_TRACE( "EglInternalFunction_MetaGetConfigs cnt = %d ", iSgConfigsAttribtCnt );
+ }
+ if (!iSgConfigAttribs)
+ { // exit if EglInternalFunction_MetaGetConfigs still failed
+ return EGL_BAD_ALLOC;
+ }
+ */
+ // ToDo use iSgConfigAttribs
+
+ // temporarily open a handle to the SgImage
+ TSgDrawableId sgId = aSgImage->Id();
+ RSgDrawable sgHandle;
+ TSgImageInfo imgInfo;
+ EGL_TRACE("CGuestEGL::ChooseConfigAttribsForSgImage 1. SgImage Id=0x%lx", sgId);
+
+ // ToDo check SgImage usage bits
+ if ( (sgId != KSgNullDrawableId) && (KErrNone == sgHandle.Open(sgId)) && (KErrNone == aSgImage->GetInfo(imgInfo)) )
+ {
+ EGL_TRACE("CGuestEGL::ChooseConfigAttribsForSgImage 2. SgImage PixelFormat=0x%x; size=%d,%d; Usage=0x%x",
+ imgInfo.iPixelFormat, imgInfo.iSizeInPixels.iWidth, imgInfo.iSizeInPixels.iHeight, imgInfo.iUsage);
+
+ switch (imgInfo.iPixelFormat)
+ {
+ case ESgPixelFormatARGB_8888_PRE: // == EUidPixelFormatARGB_8888_PRE
+ case ESgPixelFormatARGB_8888: // == EUidPixelFormatARGB_8888,
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ break;
+ case ESgPixelFormatXRGB_8888: // == EUidPixelFormatXRGB_8888,
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 8, 8, 8);
+ break;
+ case ESgPixelFormatRGB_565: // == EUidPixelFormatRGB_565,
+ error = CheckColorAttributes(aAttribList, EGL_RGB_BUFFER, 0, 5, 6, 5);
+ break;
+ case ESgPixelFormatA_8: // == EUidPixelFormatA_8
+ error = CheckColorAttributes(aAttribList, EGL_LUMINANCE_BUFFER, 8, 0, 0, 0);
+ break;
+ default: // pixmap not supported
+ error = EGL_BAD_NATIVE_PIXMAP;
+ break;
+ }
+ }
+ else
+ {
+ error = EGL_BAD_PARAMETER;
+ }
+ sgHandle.Close();
+
+
+ if (error != EGL_SUCCESS)
+ {
+ return error;
+ }
+
+ const TInt KExpansionSpace = 10 * 2; // want enough space for 10 extra attribute/value pairs
+ *aNewList = (EGLint*) CVghwUtils::Alloc( (listLength + KExpansionSpace) * sizeof(EGLint) );
+ if (!*aNewList)
+ {
+ return EGL_BAD_ALLOC;
+ }
+ memcpy(*aNewList, aAttribList, listLength * sizeof(EGLint));
+
+ switch (imgInfo.iPixelFormat)
+ {
+ case ESgPixelFormatARGB_8888_PRE: // == EUidPixelFormatARGB_8888_PRE
+ if (pRenderType && ( (*pRenderType) & EGL_OPENVG_BIT) )
+ {
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8, ETrue);
+ }
+ else
+ {
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ }
+ break;
+ case ESgPixelFormatARGB_8888: // == EUidPixelFormatARGB_8888,
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8, 8);
+ break;
+ case ESgPixelFormatXRGB_8888: // == EUidPixelFormatXRGB_8888,
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 8, 8, 8);
+ break;
+ case ESgPixelFormatRGB_565: // == EUidPixelFormatRGB_565,
+ AppendColorAttributes(*aNewList, EGL_RGB_BUFFER, 0, 5, 6, 5);
+ break;
+ case ESgPixelFormatA_8: // == EUidPixelFormatA_8
+ AppendColorAttributes(*aNewList, EGL_LUMINANCE_BUFFER, 8, 0, 0, 0);
+ break;
+ default: // pixmap not supported - panic because this code should be in-sync with supported SgImage formats
+ EGLPANIC_ALWAYS(EEglPanicTemp);
+ break;
+ }
+
+ // change requested surface type from pixmap to Pbuffer
+ EGLint* pSurfaceType = TAttribUtils::FindAttribValue(*aNewList, EGL_SURFACE_TYPE);
+ EGLint surfaceType = *pSurfaceType;
+ *pSurfaceType = EGL_PBUFFER_BIT | (surfaceType & ~EGL_PIXMAP_BIT);
+
+ TAttribUtils::RemoveAttrib(*aNewList, EGL_MATCH_NATIVE_PIXMAP);
+ return EGL_SUCCESS;
+ }
+#endif
+
+/*
+ Create an information object for an opened Display.
+ */
+TBool CGuestEGL::CreateDisplayInfo(EGLDisplay aDisplay)
+ {
+ TBool result = EFalse;
+ EGL_TRACE("CGuestEGL::CreateDisplayInfo begin aDisplay=%d", aDisplay);
+ iDisplayMapLock.WriteLock();
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ if (NULL != iDisplayMap.Find( aDisplay))
+ {
+ result = ETrue;
+ }
+ else
+ {
+ TInt err = KErrNoMemory;
+ CEglDisplayInfo* dispInfo = new CEglDisplayInfo;
+
+ if (dispInfo)
+ {
+ err = iDisplayMap.Insert(aDisplay, dispInfo);
+ // EGL_TRACE("CreateDisplayInfo - DisplayMap insert error %d", err);
+ EGLPANIC_ASSERT_DEBUG(err == KErrNone, EEglPanicDisplayMapInsertFailed);
+
+ //added for egl sync extension benefit
+ if (iEglSyncExtension)
+ {
+ err = iEglSyncExtension->EglSyncDisplayCreate(aDisplay);
+ // EGL_TRACE("CreateDisplayInfo - EglSyncDisplayCreate error %d", err);
+ EGLPANIC_ASSERT_DEBUG(err == KErrNone, EEglPanicEglSyncDisplayCreateFailed);
+
+ if (err)
+ {
+ iDisplayMap.Remove(aDisplay);
+ }
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ result = ETrue;
+ }
+ }
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ iDisplayMapLock.Unlock();
+
+ EGL_TRACE("CreateDisplayInfo end, result=%d", result);
+ return result;
+ }
+
+/*
+ Mark information object for Display as Initialised
+ */
+TBool CGuestEGL::InitializeDisplayInfo(EGLDisplay aDisplay)
+ {
+ TBool result = EFalse;
+ EGL_TRACE("CGuestEGL::InitialiseDisplayInfo begin aDisplay=%d", aDisplay);
+ iDisplayMapLock.WriteLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (pDispInfo && *pDispInfo)
+ {
+ (*pDispInfo)->iInitialized = ETrue;
+ result = ETrue;
+ }
+ iDisplayMapLock.Unlock();
+
+ EGL_TRACE("InitialiseDisplayInfo end, result=%d", result);
+ return result;
+ }
+
+/*
+ Check whether Display exists and is Initialised
+ */
+TBool CGuestEGL::IsDisplayInitialized(EGLDisplay aDisplay)
+ {
+ TBool result = EFalse;
+ EGL_TRACE("CGuestEGL::IsDisplayInitialized begin aDisplay=%d", aDisplay);
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if ( pDispInfo && *pDispInfo && (*pDispInfo)->iInitialized)
+ {
+ result = ETrue;
+ }
+ iDisplayMapLock.Unlock();
+
+ EGL_TRACE("IsDisplayInitialized end, result=%d", result);
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CGuestEGL::EglInternalFunction_GetPitch(RWindow* aNativeWindow, TInt& aHorizontalPitch, TInt& aVerticalPitch)
+ {
+ RWsSession* ws = aNativeWindow->Session();
+ CWsScreenDevice* screenDevice = new CWsScreenDevice(*ws);
+ if ( !screenDevice )
+ {
+ return KErrNoMemory;
+ }
+ TInt err = screenDevice->Construct();
+
+ if ( KErrNone == err )
+ {
+ TSize pixelSize = screenDevice->SizeInPixels();
+ TSize twipSize = screenDevice->SizeInTwips();
+
+ aHorizontalPitch = PITCH_OF_TWIPS_PIXELS(twipSize.iWidth , pixelSize.iWidth);
+ aVerticalPitch = PITCH_OF_TWIPS_PIXELS(twipSize.iHeight, pixelSize.iHeight);
+ }
+ delete screenDevice;
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLBoolean CGuestEGL::eglSwapBuffers(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface)
+ {
+ EglInternalFunction_SwapWindowSurface(aThreadState, aDisplay, aSurface);
+
+ // ToDo when all surfaces are recorded in client validate BEFORE sending cmd to host
+ TSurfaceInfo* surfaceInfo = EglInternalFunction_GetPlatformSurface( aDisplay, aSurface );
+ EGL_CHECK_ERROR( surfaceInfo, EGL_BAD_SURFACE, EGL_FALSE );
+
+ //Check if surface size has changed
+ TSize size = surfaceInfo->iNativeWindow->Size();
+
+ if (size != surfaceInfo->iSize)
+ {
+ EGL_TRACE("CGuestEGL::eglSwapBuffers Surface Resized size=%d,%d, surfaceInfo->iSize=%d,%d",
+ size.iHeight, size.iWidth, surfaceInfo->iSize.iHeight, surfaceInfo->iSize.iWidth);
+ return EglInternalFunction_SurfaceResized(aThreadState, *surfaceInfo, aDisplay, aSurface);
+ }
+ return EGL_TRUE;
+ }
+
+EGLBoolean CGuestEGL::eglMakeCurrent(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aDraw, EGLSurface aRead, EGLContext aContext)
+ {
+ if (aContext == EGL_NO_CONTEXT)
+ {
+ if ( (aDraw != EGL_NO_SURFACE) || (aRead != EGL_NO_SURFACE) )
+ {
+ aThreadState.SetEglError(EGL_BAD_SURFACE);
+ return EGL_FALSE;
+ }
+ EGL_TRACE("CGuestEGL::eglMakeCurrent call host");
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglMakeCurrent );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(EGL_NO_SURFACE);
+ eglApiData.AppendEGLSurface(EGL_NO_SURFACE);
+ eglApiData.AppendEGLContext(EGL_NO_CONTEXT);
+
+ EGLBoolean ret = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE("CGuestEGL::eglMakeCurrent end success=%d", ret);
+ return (EGLBoolean)ret;
+ }
+ else
+ {
+ if ( (aDraw == EGL_NO_SURFACE) || (aRead == EGL_NO_SURFACE) )
+ {
+ aThreadState.SetEglError(EGL_BAD_SURFACE);
+ return EGL_FALSE;
+ }
+ // ToDo use new CEglContext code
+ const TInt KMaxSurfaces( 2 );
+ EGLSurface surfaces[KMaxSurfaces];
+ TSurfaceInfo* surfaceInfo[KMaxSurfaces] = {NULL, NULL};
+ surfaces[0] = aDraw;
+ if (aDraw != aRead)
+ {
+ surfaces[1] = aRead;
+ }
+ else
+ {
+ surfaces[1] = EGL_NO_SURFACE;
+ }
+
+ for ( TInt i = 0; i < KMaxSurfaces; i++ )
+ {
+ if ( EGL_NO_SURFACE != surfaces[i] )
+ {
+ EGL_TRACE("CGuestEGL::eglMakeCurrent check surface %d", surfaces[i] );
+ surfaceInfo[i] = EglInternalFunction_GetPlatformSurface( aDisplay, surfaces[i] );
+ //EGL_CHECK_ERROR( surfaceInfo, EGL_BAD_SURFACE , EGL_FALSE );
+ if ( surfaceInfo[i] )
+ {
+ TSize newSize;
+ switch (surfaceInfo[i]->iSurfaceType)
+ {
+ case ESurfaceTypePixmapFbsBitmap:
+ EGLPANIC_ASSERT_DEBUG(surfaceInfo[i]->iFbsBitmap, EEglPanicTemp);
+ newSize = surfaceInfo[i]->iFbsBitmap->SizeInPixels();
+ break;
+ case ESurfaceTypeWindow:
+ EGLPANIC_ASSERT_DEBUG(surfaceInfo[i]->iNativeWindow, EEglPanicTemp);
+ newSize = surfaceInfo[i]->iNativeWindow->Size();
+ break;
+ default:
+ // size cannot change for other surface types
+ newSize = surfaceInfo[i]->iSize;
+ break;
+ }
+ if (newSize != surfaceInfo[i]->iSize)
+ {
+ EGL_TRACE("CGuestEGL::eglMakeCurrent resize surface");
+ if ( !EglInternalFunction_SurfaceResized(aThreadState, *surfaceInfo[i], aDisplay, surfaces[i] ) )
+ {
+ return EGL_FALSE;
+ }
+ surfaceInfo[i]->iSize = newSize;
+ }
+ }
+ }
+ }
+
+ // adapt to only some surfaces having CEglSurfaceInfo objects so far
+ EGLSurface drawId = surfaceInfo[0] ? surfaceInfo[0]->iHostSurfaceId : aDraw;
+ EGLSurface readId = aRead;
+ if ((aRead == aDraw) && surfaceInfo[0])
+ {
+ readId = surfaceInfo[0]->iHostSurfaceId;
+ }
+ else if (surfaceInfo[1])
+ {
+ readId = surfaceInfo[1]->iHostSurfaceId;
+ }
+
+ EGL_TRACE(" eglMakeCurrent surfaces[0]=0x%x, surfaces[1]=0x%x", surfaces[0], surfaces[1]);
+ EGL_TRACE(" eglMakeCurrent surfacesInfo[0]=0x%x, surfacesInfo[0].iHostSurfaceId=0x%x",
+ surfaceInfo[0], surfaceInfo[0] ? surfaceInfo[0]->iHostSurfaceId : NULL);
+ EGL_TRACE(" eglMakeCurrent surfacesInfo[1]=0x%x, surfacesInfo[1].iHostSurfaceId=0x%x",
+ surfaceInfo[1], surfaceInfo[1] ? surfaceInfo[1]->iHostSurfaceId : NULL);
+
+ EGL_TRACE("CGuestEGL::eglMakeCurrent call host");
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglMakeCurrent );
+ eglApiData.AppendEGLDisplay(aDisplay);
+
+ EGL_TRACE(" eglApiData.AppendEGLSurface(drawId = 0x%x)", drawId);
+ eglApiData.AppendEGLSurface(drawId);
+ EGL_TRACE(" eglApiData.AppendEGLSurface(readId = 0x%x);", readId);
+ eglApiData.AppendEGLSurface(readId);
+
+ eglApiData.AppendEGLContext(aContext);
+ EGLBoolean ret = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE("CGuestEGL::eglMakeCurrent end success=%d", ret);
+ return (EGLBoolean)ret;
+ }
+ }
+
+// FAISALMEMON HOLE 0.1
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CGuestEGL::EglInternalFunction_CreateSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLConfig aConfig, RWindow* aNativeWindow,
+ TSurfaceInfo& aSurfaceInfo)
+ {
+ RSurfaceManager::TSurfaceCreationAttributesBuf attributes;
+ RSurfaceManager::TInfoBuf info;
+
+ aSurfaceInfo.iNativeWindow = aNativeWindow;
+ aSurfaceInfo.iSurfaceType = ESurfaceTypeWindow;
+ aSurfaceInfo.iSize = aNativeWindow->Size();
+ aSurfaceInfo.iConfigId = aConfig;
+ aSurfaceInfo.iHostSurfaceId = aSurface;
+
+ // ToDo have function variants that do not validate parameters
+ eglQuerySurface(aThreadState, aDisplay, aSurface, EGL_VG_ALPHA_FORMAT, &aSurfaceInfo.iAlphaFormat);
+ eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_BUFFER_SIZE, &aSurfaceInfo.iColorBits);
+ eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_RED_SIZE, &aSurfaceInfo.iRedBits);
+ eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_GREEN_SIZE, &aSurfaceInfo.iGreenBits);
+ eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_BLUE_SIZE, &aSurfaceInfo.iBlueBits);
+ eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_ALPHA_SIZE, &aSurfaceInfo.iAlphaBits);
+
+ /*
+ TInt err = LastError();
+ EGL_CHECK_ERROR( EGL_SUCCESS == err, err, EGL_FALSE );
+ */
+ EGL_TRACE(" Win surface details: width=%d height=%d colorbits=%d red=%d green=%d blue=%d alpha=%d alphaformat=0x%x",
+ aSurfaceInfo.iSize.iWidth, aSurfaceInfo.iSize.iHeight, aSurfaceInfo.iColorBits, aSurfaceInfo.iRedBits,
+ aSurfaceInfo.iGreenBits, aSurfaceInfo.iBlueBits, aSurfaceInfo.iAlphaBits, aSurfaceInfo.iAlphaFormat);
+
+ TSize size;
+
+ // FAISALMEMON HOLE 1
+
+ // FAISALMEMON STUB CODE
+ TUint8 offsetToFirstBuffer = 0; // This is wrong; just stub code
+ TUint8 offsetToSecondBuffer = 0; // This is wrong; just stub code
+ // FAISALMEMON END OF STUB CODE
+
+ TUint32 chunkHWBase = 0;
+ (void)CVghwUtils::MapToHWAddress(aSurfaceInfo.iChunk->Handle(), chunkHWBase);
+ // FAISALMEMON write code to handle errors in the above function
+ EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface AFTER VGHWUtils::MapToHWAddress");
+
+ /* Store the pointer to the pixel data */
+ aSurfaceInfo.iBuffer0 = aSurfaceInfo.iChunk->Base() + offsetToFirstBuffer;
+ aSurfaceInfo.iBuffer1 = aSurfaceInfo.iChunk->Base() + offsetToSecondBuffer;
+
+ aSurfaceInfo.iBuffer0Index = (chunkHWBase + offsetToFirstBuffer) - VVI_FRAMEBUFFER_BASE_ADDRESS;
+ aSurfaceInfo.iBuffer1Index = (chunkHWBase + offsetToSecondBuffer) - VVI_FRAMEBUFFER_BASE_ADDRESS;
+ EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface %u %x %x %x %x",chunkHWBase, offsetToFirstBuffer, offsetToSecondBuffer,
+ aSurfaceInfo.iBuffer0Index,
+ aSurfaceInfo.iBuffer1Index);
+
+ if ( !EglInternalFunction_CallSetSurfaceParams(aThreadState, aDisplay, aSurface, aSurfaceInfo) )
+ {
+ EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface end failure");
+
+ return EGL_FALSE;
+ }
+ EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface end success");
+
+ return EGL_TRUE;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLBoolean CGuestEGL::eglDestroySurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface)
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ EGLBoolean result = EGL_FALSE;
+
+ // do not destroy SgImage surfaces on the Host!
+ TSurfaceInfo* surfaceInfo = EglInternalFunction_GetPlatformSurface(aDisplay, aSurface);
+ if (!surfaceInfo)
+ { // Note: Pbuffer surfaces are not currently recorded in client
+ eglApiData.Init( EglRFC::EeglDestroySurface );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+ else
+ {
+ if (surfaceInfo->iSurfaceType != ESurfaceTypePixmapSgImage)
+ { // destroy surface allocated by Host EGL
+ eglApiData.Init( EglRFC::EeglDestroySurface );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(surfaceInfo->iHostSurfaceId);
+ result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+#ifdef FAISALMEMON_S4_SGIMAGE
+ else
+ { // release SgImage handle
+ surfaceInfo->iSgHandle.Close();
+ }
+#endif
+
+ DestroySurfaceInfo(aDisplay, aSurface);
+ }
+
+ return result;
+ }
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CGuestEGL::DestroySurfaceInfo(EGLDisplay aDisplay, EGLSurface aSurface)
+ {
+ EGL_TRACE("DestroySurfaceInfo begin");
+
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE("cannot find display %d", aDisplay);
+ }
+ else
+ {
+ TSurfaceInfo** pSurfaceInfo = (*pDispInfo)->iSurfaceMap.Find(aSurface);
+ if (!pSurfaceInfo)
+ {
+ EGL_TRACE("cannot find surface %d for display %d", aSurface, aDisplay);
+ }
+ else
+ {
+ TSurfaceInfo* surfaceInfo = *pSurfaceInfo;
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ if (surfaceInfo->iNativeWindow)
+ {
+ EglInternalFunction_DestroyWindowSurface(*surfaceInfo);
+ }
+ delete surfaceInfo;
+ (*pDispInfo)->iSurfaceMap.Remove( aSurface );
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ EGL_TRACE("DestroySurfaceInfo end");
+ }
+ }
+
+ iDisplayMapLock.Unlock();
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CGuestEGL::DestroyDisplayInfo (EGLDisplay aDisplay)
+ {
+ EGL_TRACE("DestroyDisplayInfo begin aDisplay=%d", aDisplay);
+ TBool success = EFalse;
+
+ iDisplayMapLock.WriteLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE("cannot find display %d", aDisplay);
+ }
+ else
+ {
+ success = ETrue;
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ RHashMap<TInt, TSurfaceInfo*>::TIter iter((*pDispInfo)->iSurfaceMap);
+ for (;;)
+ {
+ TSurfaceInfo** pSurfaceInfo = const_cast<TSurfaceInfo**>(iter.NextValue());
+ if (!pSurfaceInfo)
+ {
+ break;
+ }
+
+ EGL_TRACE("destroying surface %d", *iter.CurrentKey());
+
+ TSurfaceInfo* surfaceInfo = *pSurfaceInfo;
+ if (surfaceInfo->iNativeWindow)
+ {
+ EglInternalFunction_DestroyWindowSurface(*surfaceInfo);
+ }
+ delete surfaceInfo;
+ }
+ iDisplayMap.Remove(aDisplay);
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+
+ //added for egl sync extension benefit
+ if (iEglSyncExtension)
+ {
+ iEglSyncExtension->EglSyncDisplayDestroy(aDisplay);
+ }
+ }
+
+ iDisplayMapLock.Unlock();
+ EGL_TRACE("DestroyDisplayInfo end - ret=%d", success);
+ return success;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLBoolean CGuestEGL::EglInternalFunction_CallSetSurfaceParams(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, TSurfaceInfo& aSurfaceInfo)
+ {
+ EGL_TRACE("EglInternalFunction_CallSetSurfaceParams begin");
+
+ RemoteFunctionCallData rfcdata;
+ EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglSimulatorSetSurfaceParams);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface( aSurface );
+ EGLNativeWindowType win = (EGLNativeWindowType)aSurfaceInfo.iNativeWindow->ClientHandle();
+ eglApiData.AppendEGLNativeWindowType( win );
+ eglApiData.AppendEGLSize(aSurfaceInfo.iSize);
+ eglApiData.AppendEGLint(aSurfaceInfo.iStride);
+ eglApiData.AppendEGLint(aSurfaceInfo.iBuffer0Index);
+ eglApiData.AppendEGLint(aSurfaceInfo.iBuffer1Index);
+ aThreadState.ExecuteEglNeverErrorCmd(eglApiData);
+
+ EGL_TRACE("EglInternalFunction_CallSetSurfaceParams end");
+ return EGL_TRUE;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLint CGuestEGL::ConfigMatchesFbsBitmapPixmap(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const EGLint* aAttribList, TDisplayMode aMode)
+ {
+ // ToDo check EGL_VG_ALPHA_FORMAT ?
+ EGLint colorBits, redBits, greenBits, blueBits, alphaBits;
+ EGLint wantColorBits, wantRedBits, wantGreenBits, wantBlueBits;
+ EGLint wantAlphaBits = 0;
+ switch (aMode)
+ {
+ case EColor64K:
+ wantColorBits = 12;
+ wantRedBits = 5;
+ wantGreenBits = 6;
+ wantBlueBits = 5;
+ break;
+ case EColor16M:
+ case EColor16MU:
+ wantColorBits = 24;
+ wantRedBits = 8;
+ wantGreenBits = 8;
+ wantBlueBits = 8;
+ break;
+ case EColor16MA:
+ wantColorBits = 32;
+ wantRedBits = 8;
+ wantGreenBits = 8;
+ wantBlueBits = 8;
+ wantAlphaBits = 8;
+ break;
+ case EColor16MAP:
+ wantColorBits = 32;
+ wantRedBits = 8;
+ wantGreenBits = 8;
+ wantBlueBits = 8;
+ wantAlphaBits = 8;
+ break;
+ default: // pixmap format not supported
+ return EGL_BAD_NATIVE_PIXMAP;
+ }
+
+ // ToDo version of these functions lighter on parameter checking - maybe use cached values
+ if (!eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_BUFFER_SIZE, &colorBits) ||
+ !eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_RED_SIZE, &redBits) ||
+ !eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_GREEN_SIZE, &greenBits) ||
+ !eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_BLUE_SIZE, &blueBits) ||
+ !eglGetConfigAttrib(aThreadState, aDisplay, aConfig, EGL_ALPHA_SIZE, &alphaBits) )
+ { // fetch failed
+ return EGL_BAD_MATCH;
+ }
+
+ EGL_TRACE("CGuestEGL::ConfigMatchesFbsBitmapPixmap: want %d bpp, %d red, %d green, %d blue, %d alpha\n\tconfig has %d bpp, %d red, %d green, %d blue, %d alpha",
+ wantColorBits, wantRedBits, wantGreenBits, wantBlueBits, wantAlphaBits,
+ colorBits, redBits, greenBits, blueBits, alphaBits);
+
+ if ( (colorBits < wantColorBits) || (redBits < wantRedBits) || (greenBits < wantGreenBits) ||
+ (blueBits < wantBlueBits) || (alphaBits < wantAlphaBits) )
+ { // config does not match bitmap
+ return EGL_BAD_MATCH;
+ }
+
+ return EGL_SUCCESS;
+ }
+
+/*
+ Returns EGL_NO_SURFACE on failure. If the attributes of pixmap do not
+ correspond to config, then an EGL_BAD_MATCH error is generated. If config does
+ not support rendering to pixmaps (the EGL_SURFACE_TYPE attribute does not
+ contain EGL_PIXMAP_BIT), an EGL_BAD_MATCH error is generated. If config does
+ not support the colorspace or alpha format attributes specified in attrib list
+ (as defined for eglCreateWindowSurface), an EGL_BAD_MATCH error is generated.
+ If config is not a valid EGLConfig, an EGL_BAD_CONFIG error is generated. If
+ pixmap is not a valid native pixmap handle, then an EGL_BAD_NATIVE_PIXMAP
+ error should be generated. If there is already an EGLSurface associated with
+ pixmap (as a result of a previous eglCreatePixmapSurface call), then a
+ EGL_BAD_ALLOC error is generated. Finally, if the implementation cannotallocate
+ resources for the new EGL pixmap, an EGL_BAD_ALLOC error is generated.
+ */
+EGLSurface CGuestEGL::eglCreatePixmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, EGLNativePixmapType aNativePixmap, const EGLint *aAttribList)
+ {
+ EGL_TRACE( "CGuestEGL::eglCreatePixmapSurface");
+ EGL_TRACE_ATTRIB_LIST(aAttribList);
+
+ EGLSurface newSurfaceId = EGL_NO_SURFACE;
+ TSurfaceInfo* surfaceInfo = NULL;
+ EGLint error = EGL_BAD_DISPLAY;
+ TSymbianPixmapTypeId pixmapType = EPixmapTypeNone;
+
+ const EGLint* pixmapMatch = TAttribUtils::FindAttribValue(aAttribList, EGL_MATCH_NATIVE_PIXMAP);
+ if ( pixmapMatch && ( (*pixmapMatch) != (EGLint)(aNativePixmap) ) )
+ { // if EGL_MATCH_NATIVE_PIXMAP is in the attribute list it must be the same pixmap as aNativePixmap
+ error = EGL_BAD_MATCH;
+ }
+ else
+ {
+ iDisplayMapLock.WriteLock();
+ CEglDisplayInfo** pDispInfo;
+ pDispInfo = iDisplayMap.Find(aDisplay);
+
+ if (pDispInfo && *pDispInfo)
+ {
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+
+ surfaceInfo = new TSurfaceInfo();
+ if (surfaceInfo)
+ {
+ surfaceInfo->iConfigId = aConfig;
+ pixmapType = EglInternalFunction_GetNativePixmapType(aNativePixmap);
+ switch (pixmapType)
+ {
+ case EPixmapTypeFbsBitmap:
+ newSurfaceId = CreateFbsBitmapSurface(aThreadState, aDisplay, aConfig, reinterpret_cast<CFbsBitmap*>(aNativePixmap), aAttribList,
+ *surfaceInfo);
+ break;
+#ifdef FAISALMEMON_S4_SGIMAGE
+ case EPixmapTypeSgImage:
+ newSurfaceId = CreateSgImageSurface(aThreadState, aDisplay, aConfig, reinterpret_cast<const RSgImage*>(aNativePixmap), aAttribList,
+ *surfaceInfo);
+ break;
+#endif
+ default:
+ break;
+ }
+ if (newSurfaceId == EGL_NO_SURFACE)
+ {
+ error = EGL_BAD_NATIVE_PIXMAP;
+ }
+ else
+ {
+ error = EGL_SUCCESS;
+ EGL_TRACE( "CGuestEGL::eglCreatePixmapSurface inserting surface 0x%x to display %d", newSurfaceId, aDisplay);
+ if (KErrNone != (*pDispInfo)->iSurfaceMap.Insert(newSurfaceId, surfaceInfo))
+ {
+ error = EGL_BAD_ALLOC;
+ if (pixmapType == EPixmapTypeFbsBitmap)
+ {
+ (void) eglDestroySurface(aThreadState, aDisplay, newSurfaceId);
+ }
+ newSurfaceId = EGL_NO_SURFACE;
+ }
+ }
+ if (error != EGL_SUCCESS)
+ {
+ delete surfaceInfo;
+ surfaceInfo = NULL;
+ }
+ }
+ else
+ {
+ error = EGL_BAD_ALLOC;
+ }
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ } // dispInfo
+ iDisplayMapLock.Unlock();
+ }
+
+ aThreadState.SetEglError(error);
+
+ // parameter check failed
+ if (error != EGL_SUCCESS)
+ {
+ EGLPANIC_ASSERT_DEBUG(newSurfaceId == EGL_NO_SURFACE, EEglPanicTemp);
+ EGLPANIC_ASSERT_DEBUG(surfaceInfo == NULL, EEglPanicTemp);
+ return EGL_NO_SURFACE;
+ }
+
+ EGLPANIC_ASSERT_DEBUG(newSurfaceId != EGL_NO_SURFACE, EEglPanicTemp);
+ EGLPANIC_ASSERT_DEBUG(surfaceInfo != NULL, EEglPanicTemp);
+
+ return newSurfaceId;
+ }
+
+EGLSurface CGuestEGL::CreateFbsBitmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, CFbsBitmap* aBitmap,
+ const EGLint *aAttribList, TSurfaceInfo& aSurfaceInfo)
+ {
+ EGLSurface newSurfaceId = EGL_NO_SURFACE;
+ aSurfaceInfo.iSurfaceType = ESurfaceTypePixmapFbsBitmap;
+ aSurfaceInfo.iFbsBitmap = aBitmap;
+
+ TDisplayMode mode = ENone;
+ TInt stride;
+ aSurfaceInfo.iSize = aBitmap->SizeInPixels();
+ EGL_TRACE("CGuestEGL::CreateFbsBitmapSurface image width=%d, height=%d", aSurfaceInfo.iSize.iWidth, aSurfaceInfo.iSize.iHeight);
+
+ // check that a pixmap surface has not previously been created from this CFbsBitmap
+ if (!EglInternalFunction_PixmapSurfacePreviouslyCreated(aBitmap, EPixmapTypeFbsBitmap))
+ {
+ // error = EGL_BAD_ALLOC;
+ return EGL_NO_SURFACE;
+ }
+ else
+ {
+ mode = aBitmap->DisplayMode();
+ if (EGL_SUCCESS != ConfigMatchesFbsBitmapPixmap(aThreadState, aDisplay, aConfig, aAttribList, mode))
+ {
+ return EGL_NO_SURFACE;
+ }
+ }
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ stride = CFbsBitmap::ScanLineLength(aSurfaceInfo.iSize.iWidth, mode);
+ eglApiData.Init( EglRFC::EeglCreatePixmapSurface );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLConfig(aConfig);
+ eglApiData.AppendEGLNativePixmapType((EGLNativePixmapType) aBitmap);
+ eglApiData.AppendEGLint(mode);
+ eglApiData.AppendEGLSize(aSurfaceInfo.iSize);
+ eglApiData.AppendEGLint(stride);
+ eglApiData.AppendEGLint(EPixmapTypeFbsBitmap);
+ eglApiData.AppendEGLintVector(aAttribList, TAttribUtils::AttribListLength(aAttribList));
+ newSurfaceId = aThreadState.ExecEglSurfaceCmd(eglApiData);
+ EGL_TRACE( "EeglCreatePixmapSurface aDisplay=%d, config=%d, format=%d, width=%d, height=%d, stride=%d, pixmapType=%d, newSurface=%d",
+ aDisplay, aConfig, mode, aSurfaceInfo.iSize.iWidth, aSurfaceInfo.iSize.iHeight, stride, EPixmapTypeFbsBitmap, newSurfaceId);
+
+ aSurfaceInfo.iHostSurfaceId = newSurfaceId;
+ return newSurfaceId;
+ }
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+EGLSurface CGuestEGL::CreateSgImageSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const RSgImage* aSgImage,
+ const EGLint *aAttribList, TSurfaceInfo& aSurfaceInfo)
+ {
+ // ToDo check that the SgImage is not already being used for a surface or EglImage
+ aSurfaceInfo.iSurfaceType = ESurfaceTypePixmapSgImage;
+ aSurfaceInfo.iSgId = aSgImage->Id();
+
+ EGL_TRACE("CGuestEGL::CreateSgImageSurface sgImage id 0x%lx", aSurfaceInfo.iSgId);
+ TSgImageInfo imgInfo;
+ // ToDo ensure SgImage has correct suitable usage bits
+ if ( (aSurfaceInfo.iSgId != KSgNullDrawableId) && (KErrNone == aSurfaceInfo.iSgHandle.Open(aSurfaceInfo.iSgId)) &&
+ (KErrNone == aSgImage->GetInfo(imgInfo)) )
+ {
+ EGL_TRACE("CGuestEGL::CreateSgImageSurface 1. SgImage PixelFormat=%d; size=%d,%d; Usage=0x%x",
+ imgInfo.iPixelFormat, imgInfo.iSizeInPixels.iWidth, imgInfo.iSizeInPixels.iHeight, imgInfo.iUsage);
+ aSurfaceInfo.iSize = imgInfo.iSizeInPixels;
+
+ /* Package the handles to 64-bit value, since there's only one parameter available.
+ pbufferHandle is the lower 32 bits, VGImageHandle is the upper bits. */
+ TUint64 sgHandles;
+ EGLint hostResult = CVghwUtils::EglGetSgHandles(aSurfaceInfo.iSgId.iId, &sgHandles);
+ EGL_TRACE("CGuestEGL::CreateSgImageSurface 2. EglGetSgHandles result=%d, sgHandles=0x%lx", hostResult, sgHandles);
+ aSurfaceInfo.iHostSurfaceId = (EGLSurface)(sgHandles&0xFFFFFFFF);
+ return aSurfaceInfo.iHostSurfaceId;
+ }
+
+ aSurfaceInfo.iSgHandle.Close();
+ return EGL_NO_SURFACE;
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TSurfaceInfo* CGuestEGL::EglInternalFunction_GetPlatformSurface( EGLDisplay display, EGLSurface surface )
+ {
+ EGL_TRACE( "CGuestEGL::EglInternalFunction_GetPlatformSurface");
+ TSurfaceInfo* result = NULL;
+
+ iDisplayMapLock.ReadLock();
+
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find( display );
+ if (pDispInfo && *pDispInfo)
+ {
+ TSurfaceInfo** pSurfaceInfo = (*pDispInfo)->iSurfaceMap.Find( surface );
+ if (pSurfaceInfo)
+ {
+ result = *pSurfaceInfo;
+ }
+ }
+
+ // TODO on success should probably Unlock() the surface in the caller
+ iDisplayMapLock.Unlock();
+
+ /* TODO review calling code, to see if this suggestion makes sense
+ if (result == NULL)
+ {
+ EGL_RAISE_ERROR( EGL_BAD_SURFACE, NULL); //Enable this when all surfaces are in surface map
+ }
+ */
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLBoolean CGuestEGL::eglWaitClient(TEglThreadState& aThreadState)
+ {
+ EGL_TRACE( "CGuestEGL::eglWaitClient");
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglWaitClient);
+ EGLBoolean result = aThreadState.ExecEglBooleanCmd(eglApiData);
+
+ if (result)
+ {
+ // ToDo cache in client, check results are not EGL_NO_DISPLAY / EGL_NO_SURFACE
+ EGLDisplay display = eglGetCurrentDisplay(aThreadState);
+ EGLSurface surface = eglGetCurrentSurface(aThreadState, EGL_DRAW);
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find( display );
+ TSurfaceInfo* surfaceInfo = NULL;
+
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE( "cannot find display %d", display );
+ }
+ else
+ {
+ TSurfaceInfo** pSurfaceInfo = (*pDispInfo)->iSurfaceMap.Find( surface );
+ if (!pSurfaceInfo)
+ {
+ EGL_TRACE( "cannot find surface %d for display %d", surface, display );
+ }
+ else
+ {
+ surfaceInfo = *pSurfaceInfo;
+ }
+ }
+ iDisplayMapLock.Unlock();
+ if (surfaceInfo == NULL)
+ {
+ return EGL_FALSE;
+ }
+ if (surfaceInfo->iSurfaceType == ESurfaceTypePixmapFbsBitmap)
+ {
+ EGLPANIC_ASSERT_DEBUG(surfaceInfo->iFbsBitmap, EEglPanicTemp);
+ surfaceInfo->iFbsBitmap->BeginDataAccess();
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglSimulatorCopyImageData );
+ const TSize sizePixels( surfaceInfo->iFbsBitmap->Header().iSizeInPixels );
+ eglApiData.AppendVector( (void*)surfaceInfo->iFbsBitmap->DataAddress(),
+ CFbsBitmap::ScanLineLength( sizePixels.iWidth, surfaceInfo->iFbsBitmap->DisplayMode() )*sizePixels.iHeight,
+ RemoteFunctionCallData::EOut );
+ aThreadState.ExecuteEglNeverErrorCmd(eglApiData);
+
+ surfaceInfo->iFbsBitmap->EndDataAccess();
+ }
+ }
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLSurface CGuestEGL::eglGetCurrentSurface(TEglThreadState& aThreadState, EGLint aReadDraw)
+ {
+ // ToDo cache in client
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglGetCurrentSurface);
+ eglApiData.AppendEGLint(aReadDraw);
+ return ExecEglSurfaceNoErrorCmd(aThreadState, eglApiData);
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLDisplay CGuestEGL::eglGetCurrentDisplay(TEglThreadState& aThreadState)
+ {
+ // ToDo cache in client
+ EGL_TRACE("CGuestEGL::eglGetCurrentDisplay");
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglGetCurrentDisplay);
+ return ExecEglDisplayNoErrorCmd(aThreadState, eglApiData);
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLBoolean CGuestEGL::eglCopyBuffers(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLNativePixmapType aTarget)
+ {
+ TSize pixmapSize;
+
+ EGL_TRACE("CGuestEGL::eglCopyBuffers");
+ EGLBoolean hostResult = EGL_FALSE;
+ TSymbianPixmapTypeId targetPixmapType = EglInternalFunction_GetNativePixmapType(aTarget);
+
+ // Only CFbsBitmap native pixmaps are supported by this API. (SgImages are not supported, as per the SgImsge Lite spec.)
+ if ( (targetPixmapType == EPixmapTypeFbsBitmap) && EglInternalFunction_IsValidNativePixmap(aTarget, targetPixmapType) )
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData(rfcdata);
+ CFbsBitmap* bitmap = (CFbsBitmap*)aTarget;
+ TSize pixmapSize = bitmap->SizeInPixels();
+ bitmap->BeginDataAccess();
+
+ TDisplayMode mode = bitmap->DisplayMode();
+ EGLint stride = CFbsBitmap::ScanLineLength(bitmap->Header().iSizeInPixels.iWidth, mode);
+ void* data = bitmap->DataAddress();
+
+#ifdef _DEBUG
+ char* modeName = NULL;
+ switch (mode)
+ {
+ case ENone: modeName = "ENone"; break;
+ case EGray2: modeName = "EGray2"; break;
+ case EGray4: modeName = "EGray4"; break;
+ case EGray16: modeName = "EGray16"; break;
+ case EGray256: modeName = "EGray256"; break;
+ case EColor16: modeName = "EColor16"; break;
+ case EColor256: modeName = "EColor256"; break;
+ case EColor64K: modeName = "EColor64K"; break;
+ case EColor16M: modeName = "EColor16M"; break;
+ case ERgb: modeName = "ERgb"; break;
+ case EColor4K: modeName = "EColor4K"; break;
+ case EColor16MU: modeName = "EColor16MU"; break;
+ case EColor16MA: modeName = "EColor16MA"; break;
+ case EColor16MAP: modeName = "EColor16MAP"; break;
+ case EColorLast: modeName = "EColorLast"; break;
+ default: modeName = "unknown"; break;
+ }
+ EGL_TRACE("EglInternalFunction_GetNativePixmapInfo (0x%x) -> CFbsBitmap: DisplayMode=%d (\"%s\"), ScanLineLength=%d, data addr=0x%x",
+ bitmap, mode, modeName, stride, data);
+#endif
+
+ eglApiData.Init(EglRFC::EeglCopyBuffers);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ const TSize sizePixels( bitmap->Header().iSizeInPixels );
+ eglApiData.AppendVector((void*)bitmap->DataAddress(),
+ stride*pixmapSize.iHeight,
+ RemoteFunctionCallData::EOut);
+
+ eglApiData.AppendEGLint((EGLint) mode);
+ eglApiData.AppendEGLSize(pixmapSize);
+ eglApiData.AppendEGLint(stride);
+ eglApiData.AppendEGLint(targetPixmapType);
+
+ hostResult = aThreadState.ExecEglBooleanCmd(eglApiData);
+ bitmap->EndDataAccess();
+ }
+ else
+ {
+ aThreadState.SetEglError(EGL_BAD_NATIVE_PIXMAP);
+ }
+
+ return hostResult;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+// Beware odd logic: EFalse if surface is found, otherwise ETrue
+TBool CGuestEGL::EglInternalFunction_PixmapSurfacePreviouslyCreated(EGLNativePixmapType pixmap, TSymbianPixmapTypeId pixmapType)
+ {
+ // ToDo keep a hashmap of pixmap addresses currently used for surfaces
+ TBool result = ETrue;
+ if(pixmapType == EPixmapTypeFbsBitmap)
+ {
+ iDisplayMapLock.ReadLock();
+ RHashMap<TInt, CEglDisplayInfo*>::TIter iter( iDisplayMap );
+ for (;;)
+ {
+ CEglDisplayInfo** pDispInfo = const_cast<CEglDisplayInfo**>(iter.NextValue());
+ if (!pDispInfo || !*pDispInfo)
+ {
+ break;
+ }
+
+ RHashMap<TInt, TSurfaceInfo*>::TIter iter2((*pDispInfo)->iSurfaceMap);
+ for (;;)
+ {
+ TSurfaceInfo** pSurfaceInfo = const_cast<TSurfaceInfo**>(iter2.NextValue());
+ if (!pSurfaceInfo)
+ {
+ break;
+ }
+
+ TSurfaceInfo* surfaceInfo = *pSurfaceInfo;
+ if ( (surfaceInfo->iSurfaceType == ESurfaceTypePixmapFbsBitmap) && (surfaceInfo->iFbsBitmap == pixmap) )
+ {
+ result = EFalse;
+ }
+ }
+ }
+ iDisplayMapLock.Unlock();
+ }
+
+ EGL_TRACE("CGuestEGL::EglInternalFunction_PixmapSurfacePreviouslyCreated %d", result);
+ return result;
+ }
+
+// FAISALMEMON HOLE 2
+
+EGLDisplay CGuestEGL::eglGetDisplay(TEglThreadState& aThreadState, EGLNativeDisplayType aDisplayId)
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData(rfcdata);
+ eglApiData.Init(EglRFC::EeglGetDisplay);
+ eglApiData.AppendEGLNativeDisplayType(aDisplayId);
+ EGLDisplay display = ExecEglDisplayNoErrorCmd(aThreadState, eglApiData);
+
+ if (display != EGL_NO_DISPLAY)
+ {
+ if (!CreateDisplayInfo(display))
+ { // alloc failed
+ display = EGL_NO_DISPLAY;
+ }
+ }
+ return display;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+EGLint CGuestEGL::InitialiseExtensions()
+ {
+ iEglSyncExtension = CEglSyncExtension::Create(*this);
+ return EGL_SUCCESS;
+ }
+
+
+// API supporting EGL sync extension
+// lock the display once found
+EGLint CGuestEGL::FindAndLockDisplay(EGLDisplay aDisplay)
+ {
+ EGLint result = EGL_BAD_DISPLAY;
+ EGL_TRACE("CGuestEGL::FindAndLockDisplay aDisplay=%d", aDisplay);
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDisp = iDisplayMap.Find(aDisplay);
+ if (pDisp && *pDisp)
+ {
+ CEglDisplayInfo* disp = *pDisp;
+ if (disp->iInitialized)
+ {
+ EGL_TRACE("CGuestEGL::FindAndLockDisplay display found");
+ result = EGL_SUCCESS;
+ }
+ else
+ {
+ EGL_TRACE("CGuestEGL::FindAndLockDisplay display not initialized");
+ result = EGL_NOT_INITIALIZED;
+ }
+ }
+ else
+ {
+ EGL_TRACE("CGuestEGL::FindAndLockDisplay cannot find display");
+ }
+ if (result != EGL_SUCCESS)
+ {
+ iDisplayMapLock.Unlock();
+ }
+ return result;
+ }
+
+// release the lock
+void CGuestEGL::ReleaseDisplayLock(EGLDisplay aDisplay)
+ {
+ EGL_TRACE("CGuestEGL::ReleaseDisplayLock aDisplay=%d", aDisplay);
+ iDisplayMapLock.Unlock();
+ }
+
+
+CEglSyncExtension* CGuestEGL::EGLSyncExtension()
+ {
+ return iEglSyncExtension;
+ }
+
+
+/*
+ EGL_FALSE is returned on failure and major and minor are not updated. An
+ EGL_BAD_DISPLAY error is generated if the dpy argument does not refer to a valid
+ EGLDisplay. An EGL_NOT_INITIALIZED error is generated if EGL cannot be
+ initialized for an otherwise valid dpy.
+ */
+EGLBoolean CGuestEGL::eglInitialize(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLint *aMajor, EGLint *aMinor)
+ {
+ if ((aDisplay == EGL_NO_DISPLAY) || !InitializeDisplayInfo(aDisplay))
+ {
+ aThreadState.SetEglError(EGL_BAD_DISPLAY);
+ return EGL_FALSE;
+ }
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData(rfcdata);
+ eglApiData.Init(EglRFC::EeglInitialize);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ EGLBoolean ret = aThreadState.ExecEglBooleanCmd(eglApiData);
+
+ if(ret)
+ {
+ if(aMajor)
+ *aMajor = EGL_VERSION_MAJOR;
+ if(aMinor)
+ *aMinor = EGL_VERSION_MINOR;
+ }
+ EGL_TRACE("eglInitialize <-" );
+ return ret;
+ }
+
+/*
+ Returns EGL_FALSE on failure and value is not updated. If attribute is not a
+ valid EGL surface attribute, then an EGL_BAD_ATTRIBUTE error is generated. If
+ surface is not a valid EGLSurface then an EGL_BAD_SURFACE error is generated.
+ */
+EGLBoolean CGuestEGL::eglQuerySurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aAttribute, EGLint *aValue)
+ {
+ // ToDo more parameter validation, and possibly use cached values
+ if ( (aValue == NULL) || (3 & (TUint32)aValue) )
+ {
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_FALSE;
+ }
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglQuerySurface);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ eglApiData.AppendEGLint(aAttribute);
+ eglApiData.AppendEGLintVector(aValue, 1, RemoteFunctionCallData::EOut);
+
+ EGLBoolean result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE_GET_ATTRIB("eglQuerySurface", "surface", aDisplay, aSurface, aAttribute, aValue, result);
+ return result;
+ }
+
+/*
+ On failure eglCreatePbufferFromClientBuffer returns EGL_NO_SURFACE. In
+ addition to the errors described eglCreatePbufferSurface,
+ eglCreatePbufferFromClientBuffer may fail and generate errors for the
+ following reasons:
+ * If buftype is not a recognized client API resource type (e.g. is not
+ EGL_OPENVG_IMAGE), an EGL_BAD_PARAMETER error is generated.
+ * If buffer is not a valid handle or name of a client API resource of the
+ specified buftype in the currently bound context corresponding to that
+ type, an EGL_BAD_PARAMETER error is generated.
+ * If the buffers contained in buffer do not correspond to a proper subset
+ of the buffers described by config, and match the bit depths for those
+ buffers specified in config, then an EGL_BAD_MATCH error is generated.
+ For example, a VGImage with pixel format VG_lRGBA_8888 corresponds to an
+ EGLConfig with EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, and
+ EGL_ALPHA_SIZE values of 8.
+ * If no context corresponding to the specified buftype is current, an
+ EGL_BAD_ACCESS error is generated.
+ * There may be additional constraints on which types of buffers may be
+ bound to EGL surfaces, as described in client API specifications. If
+ those constraints are violated, then an EGL_BAD_MATCH error is generated.
+ * If buffer is already bound to another pbuffer, or is in use by a client
+ API an EGL_BAD_ACCESS error is generated.
+ */
+EGLSurface CGuestEGL::eglCreatePbufferFromClientBuffer(TEglThreadState& aThreadState,
+ EGLDisplay aDisplay, EGLenum aBufType, EGLClientBuffer aBuffer, EGLConfig aConfig, const EGLint *aAttribList)
+ {
+ // ToDo validate parameters
+ // ToDo SgImage Design Spec 5.12 - eglCreatePbufferFromClientBuffer should fail with EGL_BAD_ACCESS for VgImages derived from SgImages
+ EGL_TRACE("eglCreatePbufferFromClientBuffer %d %d %d", aDisplay, aBufType, aConfig);
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglCreatePbufferFromClientBuffer);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLenum(aBufType);
+ eglApiData.AppendEGLClientBuffer(aBuffer);
+ eglApiData.AppendEGLConfig(aConfig);
+ eglApiData.AppendEGLintVector(aAttribList, TAttribUtils::AttribListLength(aAttribList) );
+
+ return aThreadState.ExecEglSurfaceCmd(eglApiData);
+ }
+
+/*
+ If the dpy argument does not refer to a valid EGLDisplay, EGL_FALSE is
+ returned, and an EGL_BAD_DISPLAY error is generated.
+ */
+EGLBoolean CGuestEGL::eglTerminate(TEglThreadState& aThreadState, EGLDisplay aDisplay)
+ {
+ EGLBoolean success = EGL_FALSE;
+ if (DestroyDisplayInfo(aDisplay))
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglTerminate);
+ eglApiData.AppendEGLDisplay(aDisplay);
+
+ success = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE("eglTerminate display=%d ret=%d", aDisplay, success);
+ }
+ else
+ {
+ aThreadState.SetEglError(EGL_BAD_DISPLAY);
+ }
+
+ return success;
+ }
+
+/*
+ On failure, EGL_FALSE is returned. An EGL_NOT_INITIALIZED error is generated
+ if EGL is not initialized on dpy. An EGL_BAD_PARAMETER error is generated
+ if num config is NULL.
+ */
+EGLBoolean CGuestEGL::eglGetConfigs(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig *aConfigs,
+ EGLint aConfigSize, EGLint *aNumConfig)
+ {
+ EGLint error = EGL_SUCCESS;
+
+ if (aNumConfig == NULL)
+ {
+ error = EGL_BAD_PARAMETER;
+ }
+
+ // ToDo check display is valid
+ if (error != EGL_SUCCESS)
+ {
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_FALSE;
+ }
+ if (aConfigs && !aConfigSize)
+ aConfigSize = 1;
+ else if (!aConfigs)
+ aConfigSize = 0;
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglGetConfigs);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLConfigVector(aConfigs, aConfigSize, RemoteFunctionCallData::EOut);
+ eglApiData.AppendEGLint(aConfigSize);
+ eglApiData.AppendEGLintVector(aNumConfig, 1, RemoteFunctionCallData::EOut);
+
+ // ToDo cache successful result for next time
+ EGLBoolean result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ return result;
+ }
+
+EGLBoolean CGuestEGL::eglChooseConfig(TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint *aAttribList,
+ EGLConfig *aConfigs, EGLint aConfigSize, EGLint *aNumConfig)
+ {
+ if (aConfigs && !aConfigSize)
+ {
+ aConfigSize = 1;
+ }
+ else if (!aConfigs)
+ {
+ aConfigSize = 0;
+ }
+
+ const EGLint* surfaceType = TAttribUtils::FindAttribValue(aAttribList, EGL_SURFACE_TYPE);
+ if (surfaceType && (*surfaceType & EGL_PIXMAP_BIT))
+ {
+ EGL_TRACE("CGuestEGL::eglChooseConfig for Pixmap Surface");
+ const EGLint* pixmapMatch = TAttribUtils::FindAttribValue(aAttribList, EGL_MATCH_NATIVE_PIXMAP);
+ if (pixmapMatch && *pixmapMatch)
+ {
+ EGL_TRACE("CGuestEGL::eglChooseConfig attributes include EGL_MATCH_NATIVE_PIXMAP, value is 0x%x", *pixmapMatch);
+ // check/copy color & alpha sizes from pixmap
+ return ChooseConfigForPixmapSurface(aThreadState, aDisplay, aAttribList, aConfigs, aConfigSize, aNumConfig, (const void*)*pixmapMatch);
+ }
+ else
+ { // Pixmap to match is missing
+ EGL_TRACE("CGuestEGL::eglChooseConfig EGL_MATCH_NATIVE_PIXMAP attribute is missing or NULL");
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_FALSE;
+ }
+ }
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglChooseConfig );
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLintVector(aAttribList, TAttribUtils::AttribListLength(aAttribList));
+ eglApiData.AppendEGLConfigVector(aConfigs, aConfigSize, RemoteFunctionCallData::EOut );
+ eglApiData.AppendEGLint(aConfigSize);
+ eglApiData.AppendEGLintVector(aNumConfig, 1, RemoteFunctionCallData::EOut);
+
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ On failure returns EGL_FALSE. If attribute
+ is not a valid attribute then EGL_BAD_ATTRIBUTE is generated.
+ */
+EGLBoolean CGuestEGL::eglGetConfigAttrib(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLint aAttribute, EGLint *aValue)
+ {
+ // ToDo validate display & aAttribute, and maybe get result from local cache
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglGetConfigAttrib);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLConfig(aConfig);
+ eglApiData.AppendEGLint(aAttribute);
+ eglApiData.AppendEGLintVector(aValue, 1, RemoteFunctionCallData::EOut);
+
+ EGLBoolean result = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGL_TRACE_GET_ATTRIB("eglGetConfigAttrib", "config", aDisplay, aConfig, aAttribute, aValue, result);
+ return result;
+ }
+
+/*
+ Returns EGL_FALSE on failure and value is not updated. If attribute is not a
+ valid EGL surface attribute, then an EGL_BAD_ATTRIBUTE error is generated. If
+ surface is not a valid EGLSurface then an EGL_BAD_SURFACE error is generated.
+ */
+EGLBoolean CGuestEGL::eglSurfaceAttrib(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface,
+ EGLint aAttribute, EGLint aValue)
+ {
+ EGL_TRACE_SET_ATTRIB("eglSurfaceAttrib", "surface", aDisplay, aSurface, aAttribute, aValue);
+
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglSurfaceAttrib);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ eglApiData.AppendEGLint(aAttribute);
+ eglApiData.AppendEGLint(aValue);
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ If eglBindTexImage is called and the surface attribute EGL_TEXTURE_FORMAT is set
+ to EGL_NO_TEXTURE, then an EGL_BAD_MATCH error is returned. If buffer is already
+ bound to a texture then an EGL_BAD_ACCESS error is returned. If buffer is not a
+ valid buffer, then an EGL_BAD_PARAMETER error is generated. If surface is not a
+ valid EGLSurface, or is not a pbuffer surface supporting texture
+ binding, then an EGL_BAD_SURFACE error is generated.
+ */
+EGLBoolean CGuestEGL::eglBindTexImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer)
+ {
+ // ToDo validate parameters
+ if ( (aBuffer == NULL) || (3 & (TUint)aBuffer))
+ {
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_FALSE;
+ }
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglBindTexImage);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ eglApiData.AppendEGLint(aBuffer);
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ If the value of surface attribute EGL_TEXTURE_FORMAT is EGL_NO_TEXTURE,
+ then an EGL_BAD_MATCH error is returned. If buffer is not a valid buffer
+ (currently only EGL_BACK_BUFFER may be specified), then an
+ EGL_BAD_PARAMETER error is generated. If surface is not a valid EGLSurface,
+ or is not a bound pbuffer surface, then an EGL_BAD_SURFACE error is
+ returned.
+ */
+EGLBoolean CGuestEGL::eglReleaseTexImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer)
+ {
+ // ToDo validate parameters
+ if ( (aBuffer == NULL) || (3 & (TUint)aBuffer))
+ {
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_FALSE;
+ }
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglReleaseTexImage);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLSurface(aSurface);
+ eglApiData.AppendEGLint(aBuffer);
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ Returns EGL_FALSE on failure. If there is no current context on the calling
+ thread, a EGL_BAD_CONTEXT error is generated. If there is no surface bound
+ to the current context, a EGL_BAD_SURFACE error is generated.
+ */
+EGLBoolean CGuestEGL::eglSwapInterval(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLint aInterval)
+ {
+ // ToDo validate parameters
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglSwapInterval);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLint(aInterval);
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ On failure returns EGL_NO_CONTEXT. If the current rendering api is EGL_NONE,
+ then an EGL_BAD_MATCH error is generated (this situation can only arise in
+ an implementation which does not support OpenGL ES, and prior to the first
+ call to eglBindAPI). If share context is neither zero nor a valid context
+ of the same client API type as the newly created context, then an EGL_-
+ BAD_CONTEXT error is generated.
+
+ ...
+ */
+EGLContext CGuestEGL::eglCreateContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLContext aShareContext, const EGLint *aAttribList)
+ {
+ EGLContext result = EGL_NO_CONTEXT;
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE("cannot find display %d", aDisplay);
+ }
+ else
+ {
+ CEglContext* shareContext = NULL;
+ if (aShareContext)
+ {
+ CEglContext** pContext = (*pDispInfo)->iContextMap.Find(aShareContext);
+ if (!pContext || (*pContext)->IsDestroyed())
+ {
+ EGL_TRACE("cannot find share context %d for display %d, or it is destroyed", aShareContext, aDisplay);
+ aThreadState.SetEglError(EGL_BAD_CONTEXT);
+ iDisplayMapLock.Unlock();
+ return EGL_NO_CONTEXT;
+ }
+ }
+
+ CEglContext* newContext = CEglContext::Create(aThreadState, aDisplay, aConfig, shareContext, aAttribList);
+ if (newContext)
+ {
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ TInt err = (*pDispInfo)->iContextMap.Insert(newContext->ClientContext(), newContext);
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ if (err != KErrNone)
+ {
+ newContext->Destroy(aThreadState);
+ aThreadState.SetEglError(EGL_BAD_ALLOC);
+ }
+ else
+ {
+ result = newContext->ClientContext();
+ }
+ }
+ }
+
+ iDisplayMapLock.Unlock();
+ return result;
+ }
+
+/*
+ Returns EGL_FALSE on failure. An EGL_BAD_CONTEXT error is generated if ctx is
+ not a valid context.
+ */
+EGLBoolean CGuestEGL::eglDestroyContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext)
+ {
+ EGLBoolean success = EGL_FALSE;
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE("cannot find display %d", aDisplay);
+ aThreadState.SetEglError(EGL_BAD_DISPLAY);
+ }
+ else
+ {
+ CEglContext** pContext = (*pDispInfo)->iContextMap.Find(aContext);
+ if (!pContext || (*pContext)->IsDestroyed())
+ {
+ EGL_TRACE("cannot find context %d for display %d, or it is destroyed", aContext, aDisplay);
+ aThreadState.SetEglError(EGL_BAD_CONTEXT);
+ }
+ else
+ {
+ success = EGL_TRUE;
+ if ((*pContext)->Destroy(aThreadState))
+ {
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ (*pDispInfo)->iContextMap.Remove(aContext);
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ }
+ EGL_TRACE("eglDestroyContext end");
+ }
+ }
+
+ iDisplayMapLock.Unlock();
+ return success;
+ }
+
+/*
+ Returns EGL_FALSE on failure and value is not updated. If attribute is not
+ a valid EGL context attribute, then an EGL_BAD_ATTRIBUTE error is generated.
+ If ctx is invalid, an EGL_BAD_CONTEXT error is generated.
+ */
+EGLBoolean CGuestEGL::eglQueryContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext, EGLint aAttribute, EGLint *aValue)
+ {
+ EGLBoolean success = EGL_FALSE;
+ iDisplayMapLock.ReadLock();
+ CEglDisplayInfo** pDispInfo = iDisplayMap.Find(aDisplay);
+ if (!pDispInfo || !*pDispInfo)
+ {
+ EGL_TRACE("cannot find display %d", aDisplay);
+ aThreadState.SetEglError(EGL_BAD_DISPLAY);
+ }
+ else
+ {
+ CEglContext** pContext = (*pDispInfo)->iContextMap.Find(aContext);
+ if (!pContext || (*pContext)->IsDestroyed())
+ {
+ EGL_TRACE("cannot find context %d for display %d, or it is destroyed", aContext, aDisplay);
+ aThreadState.SetEglError(EGL_BAD_CONTEXT);
+ }
+ else
+ {
+ success = (*pContext)->QueryAttribute(aThreadState, aAttribute, aValue);
+ }
+ }
+
+ iDisplayMapLock.Unlock();
+ return success;
+ }
+
+/*
+ On failure returns EGL_NO_SURFACE. If the pbuffer could not be created due
+ to insufficient resources, then an EGL_BAD_ALLOC error is generated. If
+ config is not a valid EGLConfig, an EGL_BAD_CONFIG error is generated. If
+ the value specified for either EGL_WIDTH or EGL_HEIGHT is less than zero,
+ an EGL_BAD_PARAMETER error is generated. If config does not support
+ pbuffers, an EGL_BAD_MATCH error is generated.
+
+ ... see also comment on exported API
+ */
+EGLSurface CGuestEGL::eglCreatePbufferSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const EGLint *aAttribList)
+ {
+ // ToDo validate parameters
+ // ToDo store info about surface
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglCreatePbufferSurface);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLConfig(aConfig);
+ eglApiData.AppendEGLintVector(aAttribList, TAttribUtils::AttribListLength(aAttribList) );
+ return aThreadState.ExecEglBooleanCmd(eglApiData);
+ }
+
+/*
+ If there is no current context for the current rendering API, or if the
+ current rendering API is EGL_NONE, then EGL_NO_CONTEXT is returned (this
+ is not an error).
+ */
+EGLContext CGuestEGL::eglGetCurrentContext(TEglThreadState& aThreadState)
+ {
+ // ToDo should have this information cached
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglGetCurrentContext);
+ return ExecEglContextNoErrorCmd(aThreadState, eglApiData);
+ }
+
+/**
+ *
+ *
+ * @param aConfigs handle to an EGLConfig pointer, where the new configuration data will be. Ownership is transferred to the client.
+ * @param aConfigsCnt number of configs that will be in aConfigs upon returning
+ *
+ * @param aConfigAttribs handle to a pointer, where the memory will be allocated, and data copied. This will contain a list of
+ * config attribute _values_, in the order set out in eglrfc::MetaGetConfigAttribute().
+ * Format: c1attrval1, c1attrval2, ..., c2attrval1, c2attrval2, ... cNattrvalM
+ * (the number of attribute values per config is eglrfc::MetaGetConfigAttributeCnt()
+ * Ownership is transferred to the client.
+ * @param aConfigAttribsLen handle to an integer value, where the size of the above vector will be stored.
+ * @param aFetchMode: which configs to fetch, default = EMetaGetConfigsSg (get configs that support sgImage), possible values are
+ * EMetaGetConfigsAll, //get all the configs available
+ * EMetaGetConfigsSg, //get configs supporting sg images
+ * EMetaGetConfigsNonSg, //get configs not supporting sg images
+ * (only sgImage implemented!)
+ *
+ */
+TBool CGuestEGL::EglInternalFunction_MetaGetConfigs(TEglThreadState& aThreadState, EGLConfig*& aConfigs, EGLint& aConfigCnt, EGLint*& aConfigAttribs, EGLint& aConfigAttribsLen, TMetaGetConfigsMode aFetchMode )
+ {
+ aConfigCnt = KConfigsMaxCnt;
+ //TODO: optimize this so that the length is the number of returned items
+ aConfigs = (EGLConfig*) CVghwUtils::Alloc( sizeof(EGLConfig) * aConfigCnt );
+ aConfigAttribsLen = KConfigsMaxCnt * 29;
+ //TODO: optimize this so that the length is the number of returned items
+ aConfigAttribs = (EGLint*) CVghwUtils::Alloc( sizeof(EGLint) * aConfigAttribsLen );
+
+ RemoteFunctionCallData rfcdata; EglRFC call( rfcdata );
+ call.Init( EglRFC::EeglMetaGetConfigs );
+ call.AppendEGLintVector( aConfigs, aConfigCnt, RemoteFunctionCallData::EInOut );
+ call.AppendEGLintVector( aConfigAttribs, aConfigAttribsLen, RemoteFunctionCallData::EInOut );
+
+ call.AppendEGLint( (EGLint)aFetchMode );
+
+ return aThreadState.ExecEglBooleanCmd( call );
+ }
+
+
+// Private interfaces for EGL to call into Open VG & Open GL ES
+// class MVgApiForEgl - redirects via CVghwUtils to exported functions from Open VG
+ExtensionProcPointer CGuestEGL::guestGetVgProcAddress (const char *aProcName)
+ {
+ if (!iVgApiForEgl)
+ {
+ iVgApiForEgl = CVghwUtils::VgApiForEgl();
+ }
+ if (iVgApiForEgl)
+ {
+ return iVgApiForEgl->guestGetVgProcAddress(aProcName);
+ }
+ return NULL;
+ }
+
+
+// class MGles11ApiForEgl - redirects via CVghwUtils to exported functions from Open GL ES 1.1
+ExtensionProcPointer CGuestEGL::guestGetGles11ProcAddress (const char *aProcName)
+ {
+ if (!iGles11ApiForEgl)
+ {
+ iGles11ApiForEgl = CVghwUtils::Gles11ApiForEgl();
+ }
+ if (iGles11ApiForEgl)
+ {
+ return iGles11ApiForEgl->guestGetGles11ProcAddress(aProcName);
+ }
+ return NULL;
+ }
+
+
+// class MGles2ApiForEgl - redirects via CVghwUtils to exported functions from Open GL ES 2
+ExtensionProcPointer CGuestEGL::guestGetGles2ProcAddress (const char *aProcName)
+ {
+ if (!iGles2ApiForEgl)
+ {
+ iGles2ApiForEgl = CVghwUtils::Gles2ApiForEgl();
+ }
+ if (iGles2ApiForEgl)
+ {
+ return iGles2ApiForEgl->guestGetGles2ProcAddress(aProcName);
+ }
+ return NULL;
+ }