--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/group/guestegl.mmp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,64 @@
+// 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:
+// Project file for guest egl implementation
+
+#include <platform_paths.hrh>
+#include <EGL/egluids.hrh> // For uids
+
+TARGET guestegl.dll
+TARGETTYPE dll
+LINKAS libegl.dll
+UID KUidSharedDllUidValue KUidEGLDllUidValue
+CAPABILITY CAP_GENERAL_DLL
+VENDORID VID_DEFAULT
+
+OS_LAYER_SYSTEMINCLUDE
+OS_LAYER_KERNEL_SYSTEMINCLUDE
+OS_LAYER_ESTLIB_SYSTEMINCLUDE
+
+USERINCLUDE ../inc
+USERINCLUDE ../../vghwutils/inc
+USERINCLUDE ../../vghwserialiser/inc
+USERINCLUDE ../../guestopenvg/inc
+USERINCLUDE ../../guestopengles11/inc
+
+SOURCEPATH ../../vghwserialiser/src
+SOURCE eglrfc.cpp
+
+SOURCEPATH ../src
+SOURCE guestegl.cpp
+SOURCE eglapi.cpp // exported C functions for EGL
+SOURCE egldebug.cpp // verbose debug trace
+SOURCE eglsync.cpp // EGL Sync extension
+SOURCE eglsgimage.cpp // EGL SgImage Lite extension
+SOURCE eglcontext.cpp // client side class for EGL Context
+SOURCE eglattribs.cpp // utilities for managing EGL AttribLists
+
+LIBRARY euser.lib // Mandatory
+LIBRARY fbscli.lib // For CFbsBitmap, etc
+LIBRARY ws32.lib // For RWindow, Direct Screen Access, etc
+LIBRARY surfacemanager.lib
+LIBRARY surfaceupdateclient.lib
+LIBRARY vghwutils.lib
+LIBRARY vghwserialiser.lib
+LIBRARY libc.lib // For strcmp, etc
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+LIBRARY sgresource.lib // For RSgImage
+#endif
+
+// standard ARM def file baseline for all implementions
+DEFFILE /epoc32/include/def/eabi/libegl14.def // ARM def file
+
+EPOCALLOWDLLDATA
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/inc/eglapi.h Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,136 @@
+// 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:
+// Header file for guest egl implementation
+
+#ifndef EGLAPI_H_
+#define EGLAPI_H_
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include <e32hashtab.h>
+#include <w32std.h>
+#include <graphics/surface.h>
+#include <graphics/surfaceupdateclient.h>
+#include <pixelformats.h>
+#include <e32cmn.h>
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+#include <sgresource/sgimage.h>
+#endif
+
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/egl.h>
+
+class CEglSyncExtension;
+#include "remotefunctioncall.h" // data serialisation data types
+#include "eglsync.h" // EGL Sync extension
+#include "eglrfc.h" // data serialisation stuff
+#include "vghwutils.h" // VGHW Utils DLL
+#include "guestegl.h" // CGuestEGL class
+
+
+extern CGuestEGL* guestEGL;
+
+/*
+ Change value to control how much tracing is generated in UDEB builds
+ 0 = API traces only
+ 1 = API traces and parameter validation diagnostics
+ 2 = API traces, param validation, extra diagnostics
+ */
+#define EGL_TRACE_LEVEL 0
+
+/*
+EGL version info
+*/
+#define EGL_VERSION_MAJOR 1
+#define EGL_VERSION_MINOR 4
+#define MAKE_VERSION_STRING(major, minor) #major "." #minor
+
+// tracing
+#include <e32debug.h>
+#ifdef _DEBUG
+ #define EGL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args)
+ #define EGL_TRACE_DETAIL(level, fmt, args...) if (level <= EGL_TRACE_LEVEL) RDebug::Printf(fmt, ##args)
+ #define EGLPANIC_ASSERT(condition, panic) if (!(condition)) { EglPanic(panic, #panic, #condition, __FILE__, __LINE__); }
+ #define EGLPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { EglPanic(panic, #panic, #condition, __FILE__, __LINE__); }
+ #define EGLPANIC_ALWAYS(panic) { EglPanic(panic, #panic, NULL, __FILE__, __LINE__); }
+ #define EGLPANIC_DEBUG(panic) { EglPanic(panic, #panic, NULL, __FILE__, __LINE__); }
+ #define EGL_TRACE_ATTRIB_LIST(aAttribList) TAttribUtils::TraceAttribList(aAttribList)
+ #define EGL_TRACE_GET_ATTRIB(N, T, D, O, A, V, R) TAttribUtils::TraceGetAttrib(N, T, D, O, A, V, R)
+ #define EGL_TRACE_SET_ATTRIB(N, T, D, O, A, V) TAttribUtils::TraceSetAttrib(N, T, D, O, A, V)
+#else
+ #define EGL_TRACE(fmt, args...)
+ #define EGL_TRACE_DETAIL(level, fmt, args...)
+ #define EGLPANIC_ASSERT(condition, panic) if (!(condition)) { EglPanic(panic, NULL, NULL, NULL, __LINE__); }
+ #define EGLPANIC_ASSERT_DEBUG(condition, panic)
+ #define EGLPANIC_ALWAYS(panic) { EglPanic(panic, NULL, NULL, NULL, __LINE__); }
+ #define EGLPANIC_DEBUG(panic)
+ #define EGL_TRACE_ATTRIB_LIST(aAttribList)
+ #define EGL_TRACE_GET_ATTRIB(N, T, D, O, A, V, R)
+ #define EGL_TRACE_SET_ATTRIB(N, T, D, O, A, V)
+#endif
+
+
+// Guest EGL panic codes
+typedef enum
+ {
+ EEglPanicCGuestEGLAllocFailed=1,
+ EEglPanicDisplayMapLockCreateLocalFailed,
+ EEglPanicGuestGraphicsAllocFailed,
+ EEglPanicSgImageHandleInvalid,
+ EEglPanicExtensionListAllocFailed,
+ EEglPanicExtensionListCreationError,
+ EEglPanicHostAndClientBoundApiOutOfSync,
+ EEglPanicUnexpectedBoundApi,
+ EEglPanicSymbianPixmapNotSetInSurface,
+ EEglPanicSymbianWindowNotSetInSurface, // 10
+ EEglPanicHostAndClientEglInitOutOfSync,
+ EEglPanicHostAndClientEglTerminateOutOfSync,
+ EEglPanicErrorNotSet,
+ EEglPanicThreadStateNotValidInInternalFunction,
+ EEglPanicNotReplyOpcode,
+ EEglPanicDisplayMapInsertFailed,
+ EEglPanicEglSyncDisplayCreateFailed,
+ EEglPanicReleaseInvalidDisplay,
+ EEglPanicNullDisplayPointerInMap,
+ EEglPanicLockedDisplayNotFound, // 20
+ EEglPanicStrayDisplayUnlock,
+ EEglPanicDisplayNotLockedForWriting,
+ EEglPanicDisplayAlreadyLocked,
+ EEglPanicReadLockExpected,
+ EEglPanicReadFromUnlockedDisplay,
+ EEglPanicDisplayAlreadyInMap,
+ EEglPanicDisplayNotFound,
+ EEglPanicSgDriverCreateLocalFailed,
+ EEglPanicInvalidNativePixmap,
+ EEglPanicEglImageLockCreateLocalFailed, // 30
+ EEglPanicBadSgDriverVersion,
+ EEglPanicEglImageRefCountNonZero,
+ EEglPanicEglImageIsDestroyed,
+ EEglPanicAtribListLengthTooLong,
+ EEglPanicTemp, // temporary panic in development code
+ } TEglPanic;
+
+void EglPanic(TEglPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine);
+
+
+inline CGuestEGL& Instance()
+ {
+ CGuestEGL* result = (CGuestEGL*)guestEGL; // read value and cast away volatile attribute
+ EGLPANIC_ASSERT(result, EEglPanicTemp);
+ return *result;
+ }
+
+#endif /* EGLAPI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/inc/eglsync.h Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,410 @@
+// 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:
+// The API provides functionality which allows waiting on the aSync object
+// to become signaled and to change status from signaled to unsignaled or vice
+// versa.
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef __GUEST_EGL_SYNC_H_
+#define __GUEST_EGL_SYNC_H_
+
+
+NONSHARABLE_CLASS(CEglSync): public CBase
+{
+public:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Factory function used to create a CEglSync instance
+ * \ingroup eglSync
+ * \param aFrontLock Reference to the lock protecting the sync map
+ * aHeap Reference to the Heap to be used by EGL Sync extension
+ * \param aSync the sync id for the new sync to be created
+ * \param aDisplay the display id of the associated display
+ * \param aType the sync type
+ * \return a pointer to the extension instance if successful or NULL otherwise
+ *//*-------------------------------------------------------------------*/
+ static CEglSync* Create(RFastLock& aFrontLock,
+ EGLSyncKHR aSync,
+ EGLDisplay aDisplay,
+ EGLenum aType);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Public destructor
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ ~CEglSync();
+
+private:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private constructor
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ CEglSync(RFastLock& aFrontLock,
+ EGLSyncKHR aSync,
+ EGLDisplay aDisplay,
+ EGLenum aType);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private initialisation method to be used by the factory method
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ TInt Initialize();
+
+public:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Blocks the calling thread until the specified aSync object
+ * is signaled, or until <aTimeout> nanoseconds have passed.
+ * It is supposed that the lock protecting
+ * the sync map is already acquired. The call will release this lock.
+ * \ingroup eglSync
+ * \param aFlags If the EGL_FLUSH_COMMANDS_BIT_KHR bit is set in <aFlags>
+ * and <aSync> is unsignaled when the function is called, then the equivalent
+ * of Flush() will be performed for the current API context.
+ * \param aTimeout The thread will be unblocked when <aTimeout> is expired.
+ * If the <aTimeout> is to zero, the function just test the current status
+ * of the aSync object. If the <aTimeout> is set to EGL_FOREVER_KHR, then the
+ * function does not time out. For all other values, <aTimeout> is adjusted to
+ * the closest aValue which may be substantially longer than one nanosecond.
+ * \return EGL_CONDITION_SATISFIED if <aSync> was signaled before
+ * the timeout expired, which includes the case when <aSync> was already
+ * signaled when eglClientWaitSyncKHR was called; EGL_TIMEOUT_EXPIRED_KHR if the
+ * specified timeout period expired before <aSync> was signaled;
+ * EGL_FALSE if an error occurs.
+ * \error EGL_BAD_PARAMETER if <aFlags> does not equal
+ * to 0 or EGL_SYNC_FLUSH_COMMAND_BIT_KHR
+ *//*-------------------------------------------------------------------*/
+ EGLint ClientWaitSync(EGLint aFlags, EGLTimeKHR aTimeout);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Signals or unsignals the reusable aSync object.
+ * \ingroup eglSync
+ * \param aMode Status of the aSync object. There are two possible states:
+ * EGL_SIGNALED_KHR and EGL_UNSIGNALED_KHR.
+ * \return EGL_SUCCESS if an operation was successful;
+ * EGL_BAD_MATCH if the type of <aSync> is not EGL_SYNC_REUSABLE_KHR
+ *//*-------------------------------------------------------------------*/
+ EGLint SignalSync(EGLenum aMode);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Preapares the sync object for destruction.
+ * \ingroup eglSync
+ * \return EGL_TRUE if the object can be destroyed immediately (the sync lock is not released)
+ * EGL_FALSE if the object cannot be deleted (the sync lock is released)
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean DestroySyncReady();
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Query an aAttribute of the aSync object
+ * \ingroup eglSync
+ * \param aDisplay Identifier of the display which owns the aSync object
+ * \param aValue Pointer to the aValue for the
+ * requested aAttribute which will be filled on function return.
+ * \return EGL_TRUE if an operation was successful and EGL_FALSE otherwise
+ * \error EGL_BAD_ATTRIBUTE if <aAttribute> does not lie within expected range;
+ * EGL_BAD_MATCH if <aAttribute> is not supported
+ * for the type of aSync object passed in <aSync>
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean GetSyncAttrib(EGLint aAttribute, EGLint *aValue);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Returns the associated display Id
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLDisplay Display() const { return iDisplay; }
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Returns the sync type
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLenum Type() const { return iSyncType; }
+private:
+ const EGLSyncKHR iEglSync;
+ const EGLDisplay iDisplay;
+ const EGLenum iSyncType;
+ EGLenum iSyncState;
+ EGLBoolean iDestroyed;
+ EGLint iWaiters;
+ RMutex iSyncMutex;
+ RCondVar iSyncCondVar;
+ RFastLock& iFrontLock;
+
+ static const EGLint KSupportedFlags;
+};
+
+class CGuestEGL;
+NONSHARABLE_CLASS(CEglSyncExtension): public CBase
+ {
+public:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Factory function used to create a CEglSyncExtension instance
+ * \ingroup eglSync
+ * \param aEglInstance Reference to the Egl Instance implementation object
+ * \return a pointer to the extension instance if successful or NUL otherwise
+ *//*-------------------------------------------------------------------*/
+ static CEglSyncExtension* Create(CGuestEGL& aEglInstance);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Public destructor
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ ~CEglSyncExtension();
+private:
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private initialisation method to be used by the factory method
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean Construct();
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private constructor
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ CEglSyncExtension(CGuestEGL& aEglInstance);
+
+public:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Create a aSync object for the specified display.
+ * \ingroup api
+ * \param aDisplay Identifier of the display which will own the aSync object
+ * \param type Type of the aSync object. EGL_SYNC_REUSABLE_KHR is only supported
+ * \param attrib_list Attribute-aValue list specifying attributes of the aSync
+ * object, terminated by an aAttribute entry EGL_NONE
+ * \return Handle for the created aSync object if successful, EGL_NO_SYNC_KHR otherwise
+ * \error EGL_BAD_DISPLAY if <aDisplay> is not a name of a valid EGLDisplay;
+ * EGL_NOT_INITIALIZED if the display object associated
+ * with the <aDisplay> has not been initialized;
+ * EGL_BAD_ATTRIBUTE if <attrib_list> is neither NULL nor empty (containing only EGL_NONE) or
+ * if <type> is not a supported type of aSync object;
+ * EGL_BAD_ALLOC if the memory allocation related to aSync object is not successful
+ * \note If <type> is EGL_SYNC_REUSABLE_KHR, a reusable aSync object is created.
+ * In this case <attrib_list> must be NULL or empty (containing only EGL_NONE).
+ * *//*-------------------------------------------------------------------*/
+ static EGLSyncKHR eglCreateSyncKHR(EGLDisplay aDisplay,
+ EGLenum aType,
+ const EGLint* aAttribList);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Destroy a aSync object and free memory associated with it
+ * \ingroup api
+ * \param aDisplay Identifier of the display which owns the aSync object
+ * \param aSync Sync object handle.
+ * \return EGL_TRUE if deletion was successful and EGL_FALSE otherwise
+ * \error EGL_BAD_DISPLAY if <aDisplay> is not a name of a valid EGLDisplay;
+ * EGL_NOT_INITIALIZED if the display object associated
+ * with the <aDisplay> has not been initialized;
+ * EGL_BAD_PARAMETER if <aSync> is not a valid aSync object for <aDisplay>
+ * \note If any eglClientWaitSyncKHR commands are blocking on <aSync> when
+ * eglDestroySyncKHR is called, they will be woken up, as if <aSync> were signaled.
+ * If no errors are generated, <aSync> will no longer be the handle of a valid aSync object.
+ *//*-------------------------------------------------------------------*/
+ static EGLBoolean eglDestroySyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Blocks the calling thread until the specified aSync object
+ * is signaled, or until <aTimeout> nanoseconds have passed.
+ * \ingroup api
+ * \param aDisplay Identifier of the display which owns the aSync object.
+ * \param aSync Sync object handle.
+ * \param aFlags If the EGL_FLUSH_COMMANDS_BIT_KHR bit is set in <aFlags>
+ * and <aSync> is unsignaled when the function is called, then the equivalent
+ * of Flush() will be performed for the current API context.
+ * \param aTimeout The thread will be unblocked when <aTimeout> is expired.
+ * If the <aTimeout> is to zero, the function just test the current status
+ * of the aSync object. If the <aTimeout> is set to EGL_FOREVER_KHR, then the
+ * function does not time out. For all other values, <aTimeout> is adjusted to
+ * the closest aValue which may be substantially longer than one nanosecond.
+ * \return EGL_CONDITION_SATISFIED if <aSync> was signaled before
+ * the timeout expired, which includes the case when <aSync> was already
+ * signaled when eglClientWaitSyncKHR was called; EGL_TIMEOUT_EXPIRED_KHR if the
+ * specified timeout period expired before <aSync> was signaled;
+ * EGL_FALSE if an error occurs.
+ * \error EGL_BAD_DISPLAY if <aDisplay> is not a name of a valid EGLDisplay;
+ * EGL_NOT_INITIALIZED if the display object associated w
+ * ith the <aDisplay> has not been initialized;
+ * EGL_BAD_PARAMETER if <aSync> is not a valid aSync object for <aDisplay> or
+ * if <aFlags> does not equal to 0 or EGL_SYNC_FLUSH_COMMAND_BIT_KHR
+ * Note\ More than one eglClientWaitSyncKHR may
+ * be outstanding on the same <aSync> at any given time.
+ * When there are multiple threads blocked on the same <aSync> and the aSync object is signaled,
+ * all such threads are released, but the order in which they are released is not defined.
+ * If a aSync object is destroyed while an eglClientWaitSyncKHR is blocking on that object,
+ * eglClientWaitSyncKHR will unblock and return immediately, just as if the aSync object
+ * had been signaled prior to being destroyed.
+ *//*-------------------------------------------------------------------*/
+ static EGLint eglClientWaitSyncKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLint aFlags,
+ EGLTimeKHR aTimeout);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Signals or unsignals the reusable aSync object.
+ * \ingroup api
+ * \param aDisplay Identifier of the display which owns the aSync object.
+ * \param aSync Sync object handle.
+ * \param aMode Status of the aSync object. There are two possible states:
+ * EGL_SIGNALED_KHR and EGL_UNSIGNALED_KHR.
+ * \return EGL_TRUE if an operation was successful and EGL_FALSE otherwise.
+ *//*-------------------------------------------------------------------*/
+ static EGLBoolean eglSignalSyncKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLenum aMode);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Query an aAttribute of the aSync object
+ * \ingroup api
+ * \param aDisplay Identifier of the display which owns the aSync object
+ * \param aSync Sync object handle.
+ * \param aAttribute An aAttribute to be retrieved.
+ * \param aValue Pointer to the aValue for the requested aAttribute
+ * which will be filled on function return.
+ * \return EGL_TRUE if an operation was successful and EGL_FALSE otherwise
+ * \error EGL_BAD_DISPLAY if <aDisplay> is not a name of a valid EGLDisplay;
+ * EGL_NOT_INITIALIZED if the display object associated
+ * with the <aDisplay> has not been initialized;
+ * EGL_BAD_PARAMETER if <aSync> is not a valid aSync object for <aDisplay> or if <aValue> is not
+ * a valid pointer; EGL_BAD_ATTRIBUTE if <aAttribute> does not lie within expected range;
+ * EGL_BAD_MATCH if <aAttribute> is not supported for the type of aSync object passed in <aSync>
+ *//*-------------------------------------------------------------------*/
+ static EGLBoolean eglGetSyncAttribKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLint aAttribute,
+ EGLint* aValue);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Signals or unsignals the reusable aSync object.
+ * \ingroup api
+ * \param aDisplay Identifier of the display which owns the aSync object.
+ * \param aSync Sync object handle.
+ * \param aSync Status of the aSync object. There are two possible states:
+ * EGL_SIGNALED_KHR and EGL_UNSIGNALED_KHR.
+ * \return EGL_SUCCESS if an operation was successful;
+ * EGL_BAD_DISPLAY if <aDisplay> is not a name of a valid EGLDisplay;
+ * EGL_NOT_INITIALIZED if the display object associated with the <aDisplay> has not
+ * been initialized; EGL_BAD_PARAMETER if <aSync> is not a valid aSync object for <aDisplay>
+ * or if <aSync> does not lie within expected range;
+ * EGL_BAD_MATCH if the type of <aSync> is not EGL_SYNC_REUSABLE_KHR
+ * \note This function does not generate an error.
+ *//*-------------------------------------------------------------------*/
+ static EGLint egl_Private_SignalSyncNOK(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode);
+
+public:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Initialisation request when a new display is created
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ * \return EGL_SUCCESS if successful;
+ *//*-------------------------------------------------------------------*/
+ TInt EglSyncDisplayCreate(EGLDisplay aDisplay);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Request to destroy all syncs associated with a display as preamble
+ * of destroying the specified display
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ *//*-------------------------------------------------------------------*/
+ void EglSyncDisplayDestroy(EGLDisplay aDisplay);
+
+private:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Query and request to lock a specified display
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ * \return EGL_SUCCESS if successful;
+ * EGL_BAD_DISPLAY is not a name of a valid EGLDisplay
+ * EGL_NOT_INITIALIZED if the display object associated
+ * with the <aEglDisplay> has not been initialized
+ *//*-------------------------------------------------------------------*/
+ EGLint FindAndLockDisplay(EGLDisplay aDisplay);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Releases the lock associated with a valid EGLDisplay
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ *//*-------------------------------------------------------------------*/
+ void ReleaseDisplayLock(EGLDisplay aDisplay);
+
+private:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <eglCreateSyncKHR> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLSyncKHR EglCreateSyncKHR(EGLDisplay aDisplay, EGLenum aType, const EGLint* aAttribList);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <eglDestroySyncKHR> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean EglDestroySyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <eglClientWaitSyncKHR> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLint EglClientWaitSyncKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLint aFlags,
+ EGLTimeKHR aTimeout);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <eglSignalSyncKHR> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean EglSignalSyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <eglGetSyncAttribKHR> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLBoolean EglGetSyncAttribKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLint aAttribute,
+ EGLint* aValue);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Private implementation for <egl_Private_SignalSyncNOK> public static interface
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ EGLint Egl_Private_SignalSyncNOK(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode);
+
+private:
+ /*-------------------------------------------------------------------*//*!
+ * \brief Creates a sync and inserts it in the sync map
+ * \ingroup eglSync
+ * \param aEglDisplay the id of the associated display
+ * \param aType The sync type
+ * \return the id of the sync created
+ *//*-------------------------------------------------------------------*/
+ EGLSyncKHR CreateSync(EGLDisplay aDisplay, EGLenum aType);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Destroy a sync associated with a display
+ * \ingroup eglSync
+ * \param aEglDisplay the id of the associated display
+ *//*-------------------------------------------------------------------*/
+ void EglDestroySync(EGLDisplay aDisplay);
+
+private:
+ typedef RHashMap<EGLint,CEglSync*> REglSyncHashMap;
+
+ REglSyncHashMap iEglSyncMap;
+ RFastLock iEglSyncMapLock;
+ EGLint iEglSyncId;
+ CGuestEGL& iEglInstance;
+ };
+
+#endif /* __GUEST_EGL_SYNC_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/inc/guestegl.h Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,410 @@
+// 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 Header file
+
+#ifndef __GUEST__EGL_H
+#define __GUEST__EGL_H
+
+
+// CLASS DECLARATION
+typedef enum
+ {
+ EPixmapTypeNone,
+ EPixmapTypeFbsBitmap,
+ EPixmapTypeSgImage,
+ } TSymbianPixmapTypeId;
+
+
+typedef enum
+ {
+ ESurfaceTypeWindow = 0,
+ ESurfaceTypePbuffer = 1,
+ ESurfaceTypePixmapFbsBitmap = 2,
+ ESurfaceTypePixmapSgImage = 3,
+ } TEglSurfaceType;
+
+
+class RSurfaceManager;
+class CEglContext;
+
+// client side info about a surface
+struct TSurfaceInfo
+ {
+ TSize iSize;
+ TEglSurfaceType iSurfaceType; //Surface type
+ EGLConfig iConfigId;
+ CFbsBitmap* iFbsBitmap; // Handle for CFbsBitmap
+#ifdef FAISALMEMON_S4_SGIMAGE
+ RSgDrawable iSgHandle; // Handle for RSgImge - keeps image open
+ TSgDrawableId iSgId; // SgImage Id - to detect 2nd attempted surface using the same SgImage
+#endif
+ EGLSurface iHostSurfaceId;
+ // Note: most member data is only used by Window surfaces
+ TSurfaceId iSurfaceId; /*<! Target system surface allocated by EGL. */
+ // FAISALMEMON HOLE 0
+ void* iBuffer0; /*<! Pointer to the first buffer pixels */
+ void* iBuffer1; /*<! Pointer to the second buffer pixels */
+ TInt iBuffer0Index; /*<! Pointer to the first buffer pixels */
+ TInt iBuffer1Index; /*<! Pointer to the second buffer pixels */
+ RChunk* iChunk; /*<! chunk of the backbuffer surface memory */
+ // FAISALMEMON HOLE 1
+ RWindow* iNativeWindow;
+ EGLint iRedBits;
+ EGLint iGreenBits;
+ EGLint iBlueBits;
+ EGLint iAlphaBits;
+ EGLenum iAlphaFormat;
+ EGLint iColorBits;
+ EGLint iStride;
+ // FAISALMEMON HOLE 2
+ };
+
+
+// Container for Symbian client side information about an EGL Display
+NONSHARABLE_CLASS(CEglDisplayInfo) : public CBase
+ {
+public:
+ TBool iInitialized;
+// RMutex iSurfaceMapLock;
+ RHashMap<TInt, TSurfaceInfo*> iSurfaceMap;
+//private:
+// RMutex iContextMapLock;
+ RHashMap<EGLContext, CEglContext*> iContextMap;
+ };
+
+
+// prototype to help eglGetProcAddress() API
+typedef void (*ProcPointer)(...);
+
+
+// Collection of static functions for processing EGL Attribute Lists
+class TAttribUtils
+ {
+public: // definitions in eglattribs.cpp
+ static TInt AttribListLength(const EGLint* aAttribList);
+ static const EGLint* FindAttribValue(const EGLint* aAttribList, EGLint aAttrib);
+ // NB only use these on AttribLists with adequate space for editing
+ static EGLint* FindAttribValue(EGLint* aAttribList, EGLint aAttrib);
+ static void AppendAttribValue(EGLint* aAttribList, EGLint aAttrib, EGLint aValue);
+ static void RemoveAttrib(EGLint* aAttribList, EGLint aAttrib);
+#ifdef _DEBUG
+ // definitions in egldebug.cpp
+ static void TraceAttribList(const EGLint* aAttribList);
+ static void TraceAttribNames(EGLint aAttrib, EGLint aValue, char** aAttrName, char** aValueName);
+ static void TraceGetAttrib(char* aApiName, char* aObjType, EGLDisplay aDisplay, EGLint aObject, EGLint aAttribute, EGLint *aValue, EGLBoolean aResult);
+ static void TraceSetAttrib(char* aApiName, char* aObjType, EGLDisplay aDisplay, EGLint aObject, EGLint aAttribute, EGLint aValue);
+#endif
+ };
+
+
+// CEglContext represents an EGLContext on Host EGL
+NONSHARABLE_CLASS(CEglContext) : public CBase
+ {
+public:
+ // factory function
+ static CEglContext* Create(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, CEglContext* aShareContext, const EGLint* aAttribList);
+ EGLBoolean MakeCurrent(TEglThreadState& aThreadState, EGLSurface aDraw, EGLSurface aRead);
+ EGLBoolean QueryAttribute(TEglThreadState& aThreadState, EGLint aAttribute, EGLint* aValue);
+ // These functions return ETrue if they delete themselves
+ TBool Destroy(TEglThreadState& aThreadState);
+ TBool MakeNotCurrent(TEglThreadState& aThreadState);
+ EGLContext ShareContextFamily();
+ inline EGLContext HostContext() { return iHostContext; }
+ inline EGLContext ClientContext() { return iHostContext; }
+ inline TBool IsDestroyed() { return iIsDestroyed; }
+
+private:
+ CEglContext(EGLDisplay aDisplay, EGLConfig aConfig, EGLContext aShareContextFamily, EGLenum aRenderingApi, EGLint aGlesClientVersion);
+ void Delete(TEglThreadState& aThreadState);
+ ~CEglContext();
+private:
+ RMutex iCtxMutex;
+ TBool iFirstUse; // for eglMakeCurrent
+ EGLContext iHostContext; // corresponding Host EGL Context
+ // info from eglCreateContext & eglMakeCurrent
+ EGLDisplay iDisplay;
+ EGLContext iShareContextFamily;
+ EGLConfig iConfigId; // Config id used to create context
+ EGLenum iRenderingApi; // set by current bound API at creation
+ EGLSurface iDrawSurface; // currently bound draw surface, if any
+ // for GL ES Contexts
+ EGLSurface iReadSurface; // currently bound read surface, if any
+ EGLint iGlesClientVersion; // set by EGL_CONTEXT_CLIENT_VERSION attribute at creation (default is 1)
+ // object lifetime management
+ TBool iIsDestroyed;
+ };
+
+
+NONSHARABLE_CLASS(CEglImage) : public CBase
+ {
+public:
+ CEglImage();
+ ~CEglImage();
+#ifdef FAISALMEMON_S4_SGIMAGE
+ inline void Create(TSgDrawableId aSgImageId, EGLDisplay aDisplay, TSgImageInfo& aSgImageInfo, TInt aPbufferHandle, VGHandle aVgHandle);
+ TSgDrawableId SgImageId() const;
+#endif
+ inline void Duplicate();
+ inline TBool OpenForVgImage(TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId);
+ inline TBool Close();
+ inline TBool Destroy();
+ inline TBool IsDestroyed() const;
+ inline TInt RefCount();
+ inline EGLDisplay Display() const;
+
+private:
+#ifdef FAISALMEMON_S4_SGIMAGE
+ RSgDrawable iSgHandle; // Client Handle
+ TSgImageInfo iSgImageInfo;
+#endif
+ EGLDisplay iDisplay;
+ TInt iPbufferHandle; // Handle of the underlying Pbuffer, if any
+ VGHandle iVgHandle; // Handle of the underlying Host VgImage, if any
+ TInt iCreateCount;
+ TInt iOpenCount;
+ TBool iIsDestroyed;
+ };
+
+const TInt KEglConfigSize = 29;
+
+
+class XGuestEglInitialiser
+ {
+public:
+ XGuestEglInitialiser();
+ ~XGuestEglInitialiser();
+ };
+
+
+/**
+ * CCGuestEGL
+ *
+ */
+NONSHARABLE_CLASS(CGuestEGL) : public CBase, public MEglManagementApi,
+ public MVgApiForEgl, public MGles11ApiForEgl, public MGles2ApiForEgl
+ {
+public:
+ // Constructors and destructor
+
+ /**
+ * Destructor.
+ */
+ ~CGuestEGL();
+
+ /**
+ * Public constructor.
+ */
+ static CGuestEGL* New();
+
+ // class MEglManagementApi - exported as a vtable via CVghwUtils for Open VG and Open GL ES to access EGL info
+ virtual TBool EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId);
+ virtual void EglImageClose(EGLImageKHR aImage);
+
+
+ // Private interfaces for EGL to call into Open VG & Open GL ES
+ // class MVgApiForEgl - redirects via CVghwUtils to exported functions from Open VG
+ virtual ExtensionProcPointer guestGetVgProcAddress (const char *aProcName);
+ // class MGles11ApiForEgl - redirects via CVghwUtils to exported functions from Open GL ES 1.1
+ virtual ExtensionProcPointer guestGetGles11ProcAddress (const char *aProcName);
+ // class MGles2ApiForEgl - redirects via CVghwUtils to exported functions from Open GL ES 2
+ virtual ExtensionProcPointer guestGetGles2ProcAddress (const char *aProcName);
+
+
+ // public support functions for EGL C API
+ static EGLint CheckColorAttributes(const EGLint* aAttribList, EGLint aColorBufferType, EGLint aLuminanceBits,
+ EGLint aRedBits, EGLint aGreenBits, EGLint aBlueBits, EGLint aAlphaBits=0);
+ static void AppendColorAttributes(EGLint* aAttribList, EGLint aColorBufferType, EGLint aLuminanceBits, EGLint aRedBits,
+ EGLint aGreenBits, EGLint aBlueBits, EGLint aAlphaBits=0, TBool aSetVgPreMultAlpha=EFalse);
+
+ const char *QueryExtensionList();
+
+ // ToDo probably remove this after EGL Sync refactoring
+ void SetError( EGLint aError );
+ void DestroySurfaceInfo(EGLDisplay aDisplay, EGLSurface aSurface);
+
+ // static functions directly implementing an EGL API
+ ProcPointer eglGetProcAddress(const char *aProcName);
+
+ // functions directly implementing an EGL API
+ EGLBoolean eglBindTexImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer);
+ EGLBoolean eglChooseConfig(TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint *aAttribList,
+ EGLConfig *aConfigs, EGLint aConfigSize, EGLint *aNumConfig);
+ EGLBoolean eglCopyBuffers(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLNativePixmapType aTarget);
+ EGLContext eglCreateContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLContext aShareContext, const EGLint *aAttribList);
+ EGLImageKHR eglCreateImageKHR(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext, EGLenum aTarget,
+ EGLClientBuffer aBuffer, const EGLint *aAttribList);
+ EGLSurface eglCreatePbufferFromClientBuffer(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLenum aBufType,
+ EGLClientBuffer aBuffer, EGLConfig aConfig, const EGLint *aAttribList);
+ EGLSurface eglCreatePbufferSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const EGLint *aAttribList);
+ EGLSurface eglCreatePixmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLNativePixmapType aNativePixmap, const EGLint *aAttribList);
+ EGLSurface eglCreateWindowSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLNativeWindowType aNativeWindow, const EGLint *aAttribList);
+ EGLBoolean eglDestroyContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext);
+ EGLBoolean eglDestroyImageKHR(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLImageKHR aImage);
+ EGLBoolean eglDestroySurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface);
+ EGLBoolean eglGetConfigAttrib(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLint aAttribute, EGLint *aValue);
+ EGLBoolean eglGetConfigs(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig *aConfigs,
+ EGLint aConfigSize, EGLint *aNumConfig);
+ EGLContext eglGetCurrentContext(TEglThreadState& aThreadState);
+ EGLDisplay eglGetCurrentDisplay(TEglThreadState& aThreadState);
+ EGLSurface eglGetCurrentSurface(TEglThreadState& aThreadState, EGLint aReadDraw);
+ EGLDisplay eglGetDisplay(TEglThreadState& aThreadState, EGLNativeDisplayType aDisplayId);
+ EGLBoolean eglInitialize(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLint *aMajor, EGLint *aMinor);
+ EGLBoolean eglMakeCurrent(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aDraw, EGLSurface aRead,
+ EGLContext aContext);
+ EGLBoolean eglQueryContext(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext, EGLint aAttribute, EGLint *aValue);
+ const char* eglQueryString(EGLDisplay aDisplay, EGLint aName);
+ EGLBoolean eglQuerySurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aAttribute,
+ EGLint *aValue);
+ EGLBoolean eglReleaseTexImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer);
+ EGLBoolean eglSurfaceAttrib(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface,
+ EGLint aAttribute, EGLint aValue);
+ EGLBoolean eglSwapBuffers(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface);
+ EGLBoolean eglSwapInterval(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLint aInterval);
+ EGLBoolean eglTerminate(TEglThreadState& aThreadState, EGLDisplay aDisplay);
+ EGLBoolean eglWaitClient(TEglThreadState& aThreadState);
+
+public:
+ // API supporting EGL sync extension
+ /*-------------------------------------------------------------------*//*!
+ * \brief Query and request to lock a specified display
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ * \return EGL_SUCCESS if successful;
+ * EGL_BAD_DISPLAY is not a name of a valid EGLDisplay
+ * EGL_NOT_INITIALIZED if the display object associated
+ * with the <aEglDisplay> has not been initialized
+ *//*-------------------------------------------------------------------*/
+ EGLint FindAndLockDisplay(EGLDisplay aDisplay);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Releases the lock associated with a valid EGLDisplay
+ * \ingroup eglSync
+ * \param aEglDisplay a display identifier
+ *//*-------------------------------------------------------------------*/
+ void ReleaseDisplayLock(EGLDisplay aDisplay);
+
+ /*-------------------------------------------------------------------*//*!
+ * \brief Returns pointer to the EGL sync instance
+ * \ingroup eglSync
+ *//*-------------------------------------------------------------------*/
+ CEglSyncExtension* EGLSyncExtension();
+
+private:
+ /**
+ * private constructor, 2nd phase constructor
+ */
+ CGuestEGL();
+ void Create();
+ void CloseSgResources();
+ void OpenSgResources();
+
+ // private function with "EglInternalFunction_" prefix
+ TBool EglInternalFunction_CreateSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, EGLConfig aConfig, RWindow* aNativeWindow, TSurfaceInfo& aSurfaceInfo);
+ void EglInternalFunction_DestroyWindowSurface(TSurfaceInfo& aSurfaceInfo);
+ TUidPixelFormat EglInternalFunction_GetSymbianPixelFormat(const TSurfaceInfo& aSurfaceInfo);
+ EGLBoolean EglInternalFunction_CallSetSurfaceParams(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, TSurfaceInfo& aSurfaceInfo);
+ TBool EglInternalFunction_PixmapSurfacePreviouslyCreated(EGLNativePixmapType pixmap, TSymbianPixmapTypeId pixmapType);
+ static TSymbianPixmapTypeId EglInternalFunction_GetNativePixmapType(EGLNativePixmapType pixmap);
+ const char* EglInternalFunction_QueryExtensionList();
+ TBool EglInternalFunction_IsValidNativePixmap(EGLNativePixmapType pixmap, TSymbianPixmapTypeId pixmapType);
+ EGLBoolean EglInternalFunction_SurfaceResized(TEglThreadState& aThreadState, TSurfaceInfo& aSurfaceInfo, EGLDisplay aDisplay, EGLSurface aSurface);
+ TSurfaceInfo* EglInternalFunction_GetPlatformSurface( EGLDisplay display, EGLSurface surface );
+ void EglInternalFunction_AbortWindowInit(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface, TSurfaceInfo* ps, RWindow* window, CWsScreenDevice* screenDevice);
+ TBool EglInternalFunction_SwapWindowSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLSurface aSurface);
+ TInt EglInternalFunction_GetPitch( RWindow* aNativeWindow, TInt& aHorizontalPitch, TInt& aVerticalPitch );
+ TBool EglInternalFunction_MetaGetConfigs( TEglThreadState& aThreadState, EGLConfig*& aConfigs, EGLint& aConfigCnt, EGLint*& aConfigAttribs, EGLint& aConfigAttribsLen, TMetaGetConfigsMode aFetchMode = EMetaGetConfigsSg );
+
+ // more private functions
+
+ EGLint ConfigMatchesFbsBitmapPixmap(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const EGLint* aAttribList, TDisplayMode aMode);
+ EGLBoolean ChooseConfigForPixmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint* aAttribList, EGLConfig* aConfigs, EGLint aConfigSize,
+ EGLint* aNumConfig, const void* aPixmap);
+ EGLSurface CreateFbsBitmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, CFbsBitmap* aBitmap, const EGLint *aAttribList, TSurfaceInfo& aSurfaceInfo);
+
+ EGLint ChooseConfigAttribsForFbsBitmap(TEglThreadState& aThreadState, const EGLint* aAttribList, const CFbsBitmap* aBitmap, EGLint** aNewList);
+
+ EGLint ValidateEglImageTarget(EGLDisplay aDisplay, EGLContext aContext, EGLenum aTarget,
+ EGLClientBuffer aBuffer, const EGLint *aAttribList, TSymbianPixmapTypeId aTargetPixmapType);
+
+
+ TBool CreateDisplayInfo(EGLDisplay aDisplay);
+ TBool InitializeDisplayInfo(EGLDisplay aDisplay);
+ TBool IsDisplayInitialized(EGLDisplay aDisplay);
+ TBool DestroyDisplayInfo(EGLDisplay aDisplay);
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+ EGLSurface CreateSgImageSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, const RSgImage* aSgImage, const EGLint *aAttribList,
+ TSurfaceInfo& aSurfaceInfo);
+ EGLImageKHR CreateNewEglImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, TSgDrawableId aSgId, TSgImageInfo aSgImageInfo);
+ EGLImageKHR DuplicateEglImageIfItExists(EGLDisplay aDisplay, TSgDrawableId aSgId);
+ EGLint ChooseConfigAttribsForSgImage(TEglThreadState& aThreadState, const EGLint* aAttribList, const RSgImage* aSgImage, EGLint** aNewList);
+ EGLBoolean ChooseConfigForNativeSgImagePixmapSurface(TEglThreadState& aThreadState, EGLDisplay aDisplay, const EGLint* aAttribList, EGLConfig* aConfigs, EGLint aConfigSize,
+ EGLint* aNumConfig, const EGLint* aPixmap);
+#endif
+private:
+ //new methods supporting EGL Sync extension
+ EGLint InitialiseExtensions();
+
+private:
+ RReadWriteLock iDisplayMapLock; // protects the iDisplayMap for multi-threaded clients
+ RHashMap<TInt, CEglDisplayInfo*> iDisplayMap;
+
+ RMutex iEglImageLock; // protects the iEglImageArray for multi-threaded clients
+ RPointerArray<CEglImage> iEglImageArray; // ToDo use a Unique Id for the index/handle, rather than the object address
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+ EGLint* iSgConfigAttribs;
+ EGLint iSgConfigsAttribtCnt;
+ // ToDo (SgImage Design Spec 3.5) ARM EGL should maintain its own lists of native window handles, pixmap handles etc
+
+ char* iEglExtnNameList; // supporting data for eglQueryString()
+ RSgDriver iSgDriver;
+#endif
+ //data members supporting EGL Sync extension
+ CEglSyncExtension* iEglSyncExtension;
+ // vtable pointers populated from CVghwUtils - to access Open VG & GL ES internals, e.g. to support eglGetProcAddress
+ MVgApiForEgl* iVgApiForEgl;
+ MGles11ApiForEgl* iGles11ApiForEgl;
+ MGles2ApiForEgl* iGles2ApiForEgl;
+ };
+
+
+/* Execute host EGL functions that cannot fail
+ These functions do not set the flag to say that an EGL command has been executed since the last host eglGetError.
+ */
+
+inline EGLContext ExecEglContextNoErrorCmd(TEglThreadState& aThreadState, EglRFC& aEglApiData)
+ {
+ aThreadState.ExecuteEglNeverErrorCmd(aEglApiData);
+ return (EGLContext) aEglApiData.ReturnValue();
+ }
+
+inline EGLSurface ExecEglSurfaceNoErrorCmd(TEglThreadState& aThreadState, EglRFC& aEglApiData)
+ {
+ aThreadState.ExecuteEglNeverErrorCmd(aEglApiData);
+ return (EGLSurface) aEglApiData.ReturnValue();
+ }
+
+inline EGLDisplay ExecEglDisplayNoErrorCmd(TEglThreadState& aThreadState, EglRFC& aEglApiData)
+ {
+ aThreadState.ExecuteEglNeverErrorCmd(aEglApiData);
+ return (EGLDisplay) aEglApiData.ReturnValue();
+ }
+
+
+#endif // __GUEST__EGL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/rom/guestegl.iby Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,21 @@
+// 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:
+// Rom configuration file for guest egl implementation
+
+#ifndef __GUEST_EGL_IBY__
+#define __GUEST_EGL_IBY__
+
+file=ABI_DIR\BUILD_DIR\guestegl.dll sys\bin\libegl.dll
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/eglapi.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,1165 @@
+// 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:
+// Implementation of guest egl stub functions
+
+#include "eglapi.h"
+#include <e32atomics.h>
+
+/*
+ Only having the pointer as "Writeable Static Data" makes it very easy to tell if
+ initialisation has been done: the pointer is not NULL!
+ */
+CGuestEGL* guestEGL;
+// Writeable Static Data - causes constructor to be called at load DLL time.
+XGuestEglInitialiser GuestEglInitialiser;
+
+
+
+XGuestEglInitialiser::XGuestEglInitialiser()
+ {
+ EGL_TRACE("XGuestEglInitialiser::XGuestEglInitialiser() - guestEGL=0x%x", guestEGL);
+ if (!guestEGL)
+ {
+ // ensure VGHW Memory heap is created & channel to LDD is opened
+ CVghwUtils::InitStatics();
+ // Multi-Threading safe creation of CGuestEGL instance
+ if (!guestEGL)
+ {
+ // guarantee that initialisation of the object is flushed to memory before the pointer is published
+ __e32_atomic_store_rel_ptr(&guestEGL, CGuestEGL::New());
+ }
+
+ // cast away volatile attribute
+ CGuestEGL* instance = (CGuestEGL*)guestEGL;
+ // cannot continue if alloc failed
+ EGLPANIC_ASSERT(guestEGL, EEglPanicCGuestEGLAllocFailed);
+ CVghwUtils::SetEglManagementApi(instance);
+
+ CVghwUtils::CreateThreadState();
+ }
+ }
+
+
+XGuestEglInitialiser::~XGuestEglInitialiser()
+ {
+ EGL_TRACE("XGuestEglInitialiser::~XGuestEglInitialiser() - guestEGL=0x%x", guestEGL);
+ if (guestEGL)
+ {
+ delete guestEGL;
+ guestEGL = NULL;
+ }
+ CVghwUtils::DestroyStatics();
+ }
+
+
+_LIT(KEglPanicCategory, "Guest EGL");
+
+void EglPanic(TEglPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine)
+ {
+ if (aPanicName && aCondition && aFile)
+ {
+ RDebug::Printf("Guest EGL DLL Panic %s for failed Assert (%s),\n\tat %s:%d", aPanicName, aCondition, aFile, aLine);
+ }
+ else if (aPanicName && aFile)
+ {
+ RDebug::Printf("Guest EGL DLL Panic %s at %s:%d", aPanicName, aFile, aLine);
+ }
+ else
+ {
+ RDebug::Printf("Guest EGL DLL Panic %d (line %d)", aPanicCode, aLine);
+ }
+
+ User::Panic(KEglPanicCategory, aPanicCode);
+ }
+
+
+extern "C" {
+/*
+ Note: Comments at the start of each EGL api are adapted from the Khronos EGL 1.4 specification.
+ The text has been chosen/adapted to give a helpful overview of the function, and the errors
+ that it may generate. For more details see the full Khronos EGL specification.
+ */
+
+
+/*
+ Get details of the last EGL api error in this thread.
+
+ Returns EGL_SUCCESS or an EGL_xxxx error constant.
+ */
+EXPORT_C EGLint eglGetError(void)
+ {
+ EGL_TRACE("eglGetError -->");
+
+ EGLint eglError = EGL_SUCCESS;
+ // threadState is non-null if an EGL api has been called in this thread
+ TEglThreadState* threadState = CVghwUtils::EglThreadState(); // do not create thread object for this API
+ if (threadState)
+ { // get error (may be from parameter checking in this DLL or from Host EGL) - fetching resets error to EGL_SUCCESS
+ eglError = threadState->EglError();
+ }
+ EGL_TRACE("eglGetError returning eglError=0x%x <--", eglError);
+ return eglError;
+ }
+
+/*
+ Get display handle for display with requested properties.
+
+ If display id is EGL_DEFAULT_DISPLAY, a default display is returned.
+ Multiple calls made to eglGetDisplay with the same display-id will
+ all return the same EGLDisplay handle.
+ If no display matching display id is available, EGL_NO_DISPLAY is
+ returned; no error condition is raised in this case.
+ */
+EXPORT_C EGLDisplay eglGetDisplay(EGLNativeDisplayType aDisplayId)
+ {
+ EGL_TRACE("eglGetDisplay Display Id=%d -->", aDisplayId);
+
+ EGLDisplay display = EGL_NO_DISPLAY;
+ // Most likely eglGetDisplay is the first API called, so try initialising EGL instance first
+ CGuestEGL& instance = Instance();
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ display = instance.eglGetDisplay(*threadState, aDisplayId);
+ }
+ EGL_TRACE("eglGetDisplay result Display=%d <--", display);
+ return display;
+ }
+
+/*
+ Initialize EGL on a display.
+
+ EGL_TRUE is returned on success, and major and minor are updated with the major
+ and minor version numbers of the EGL implementation (for example, in an EGL
+ 1.2 implementation, the values of *major and *minor would be 1 and 2, respectively).
+ major and minor are not updated if they are specified as NULL.
+ 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.
+ */
+EXPORT_C EGLBoolean eglInitialize(EGLDisplay aDisplay, EGLint *aMajor, EGLint *aMinor)
+ {
+ EGL_TRACE("eglInitialize Display=%d, Major 0x%x, Minor 0x%x", aDisplay, aMajor, aMinor );
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ EGLBoolean success = EGL_FALSE;
+ if (threadState)
+ {
+ success = Instance().eglInitialize(*threadState, aDisplay, aMajor, aMinor);
+ }
+ EGL_TRACE("eglInitialize <- result=%d", success);
+ return success;
+ }
+
+/*
+ Marks all EGL-specific resources associated with the specified display
+ for deletion.
+
+ If the dpy argument does not refer to a valid EGLDisplay, EGL_FALSE is
+ returned, and an EGL_BAD_DISPLAY error is generated.
+ */
+EXPORT_C EGLBoolean eglTerminate(EGLDisplay aDisplay)
+ {
+ EGL_TRACE("eglTerminate Display=%d", aDisplay);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglTerminate(*threadState, aDisplay);
+ }
+ return result;
+ }
+
+/*
+ Returns a pointer to a static, zero-terminated string describing some aspect
+ of the EGL implementation running on the specified display. name may be one
+ of EGL_CLIENT_APIS, EGL_EXTENSIONS, EGL_VENDOR, or EGL_VERSION.
+
+ The EGL_CLIENT_APIS string describes which client rendering APIs are
+ supported. It is zero-terminated and contains a space-separated list of API
+ names, which must include at least one of ‘‘OpenGL’’, ‘‘OpenGL_ES’’ or
+ ‘‘OpenVG’’.
+
+ The EGL_EXTENSIONS string describes which EGL extensions are supported
+ by the EGL implementation running on the specified display, and for the
+ current client API context. The string is zero terminated and contains a
+ space-separated list of extension names; extension names themselves do
+ not contain spaces. If there are no extensions to EGL, then the empty string
+ is returned.
+
+ The format and contents of the EGL_VENDOR string is implementation dependent.
+
+ The format of the EGL_VERSION string is:
+ <major version.minor version><space><vendor specific info>
+
+ On failure, NULL is returned. An EGL_NOT_INITIALIZED error is generated
+ if EGL is not initialized for dpy. An EGL_BAD_PARAMETER error is generated if
+ name is not one of the values described above.
+ */
+EXPORT_C const char* eglQueryString(EGLDisplay aDisplay, EGLint aName)
+ {
+ EGL_TRACE("eglQueryString Display=%d, Name=0x%x", aDisplay, aName);
+
+ return Instance().eglQueryString(aDisplay, aName);
+ }
+
+/*
+ Get the list of all EGLConfigs that are available on the specified display.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglGetConfigs(EGLDisplay aDisplay, EGLConfig *aConfigs,
+ EGLint aConfigSize, EGLint *aNumConfig)
+ {
+ EGL_TRACE("eglGetConfigs Display=%d, ConfigSize=%d , NumConfig=0x%x -->", aDisplay, aConfigSize, aNumConfig);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglGetConfigs(*threadState, aDisplay, aConfigs, aConfigSize, aNumConfig);
+ }
+ EGL_TRACE("eglGetConfigs hostResult=%d, NumConfig-%d <--", result, aNumConfig ? *aNumConfig : 0);
+ return result;
+ }
+
+/*
+ Get EGLConfigs that match a list of attributes. The return value and the meaning
+ of configs, config size, and num config are the same as for eglGetConfigs.
+ However, only configurations matching attrib list will be returned.
+
+ On failure, EGL_FALSE is returned. An EGL_BAD_ATTRIBUTE error is generated
+ if attrib list contains an undefined EGL attribute or an attribute value that is
+ unrecognized or out of range.
+ */
+EXPORT_C EGLBoolean eglChooseConfig(EGLDisplay aDisplay, const EGLint *aAttribList,
+ EGLConfig *aConfigs, EGLint aConfigSize, EGLint *aNumConfig)
+ {
+ EGL_TRACE("eglChooseConfig Display=%d, AttribList=0x%x, Configs=0x%x, ConfigSize=%d, NumConfig=0x%x -->",
+ aDisplay, aAttribList, aConfigs, aConfigSize, aNumConfig);
+ EGL_TRACE_ATTRIB_LIST(aAttribList);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglChooseConfig(*threadState, aDisplay, aAttribList, aConfigs, aConfigSize, aNumConfig);
+ }
+
+ EGL_TRACE("eglChooseConfig Result=%s, Num configs=%d, First config=%d <--",
+ result ? "success" : "fail",
+ aNumConfig ? *aNumConfig : 0,
+ (aConfigs && aNumConfig && (*aNumConfig > 0)) ? *aConfigs : -1);
+ return result;
+ }
+
+/*
+ Get the value of an EGLConfig attribute.
+
+ On failure returns EGL_FALSE. If attribute
+ is not a valid attribute then EGL_BAD_ATTRIBUTE is generated.
+ */
+EXPORT_C EGLBoolean eglGetConfigAttrib(EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLint aAttribute, EGLint *aValue)
+ {
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglGetConfigAttrib(*threadState, aDisplay, aConfig, aAttribute, aValue);
+ }
+ return result;
+ }
+
+/*
+ Creates an onscreen EGLSurface and returns a handle to it. Any EGL context created
+ with a compatible EGLConfig can be used to render into this surface.
+
+ On failure returns EGL_NO_SURFACE. If the attributes of win do not correspond to
+ config, then an EGL_BAD_MATCH error is generated. If config does not support
+ rendering to windows (the EGL_SURFACE_TYPE attribute does not contain
+ EGL_WINDOW_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 win is not a valid
+ native window handle, then an EGL_BAD_NATIVE_WINDOW error should be generated. If
+ there is already an EGLConfig associated with win (as a result of a previous
+ eglCreateWindowSurface call), then an EGL_BAD_ALLOC error is generated. Finally,
+ if the implementation cannot allocate resources for the new EGL window, an
+ EGL_BAD_ALLOC error is generated.
+ */
+EXPORT_C EGLSurface eglCreateWindowSurface(EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLNativeWindowType aWindow, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreateWindowSurface Display=%d, Config=%d, Window=0x%x -->", aDisplay, aConfig, aWindow);
+
+ EGLSurface newSurface = EGL_NO_SURFACE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ newSurface = Instance().eglCreateWindowSurface(*threadState, aDisplay, aConfig, aWindow, aAttribList);
+ }
+ EGL_TRACE("eglCreateWindowSurface new Surface=0x%x <--", newSurface);
+ return newSurface;
+ }
+
+/*
+ Creates a single off-screen pbuffer surface and returns a handle to it.
+
+ 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. In addition, an EGL_BAD_MATCH
+ error is generated if any of the following conditions are true:
+ * The EGL_TEXTURE_FORMAT attribute is not EGL_NO_TEXTURE, and EGL_WIDTH
+ and/or EGL_HEIGHT specify an invalid size (e.g., the texture size is
+ not a power of two, and the underlying OpenGL ES implementation does not
+ support non-power-of-two textures).
+ * The EGL_TEXTURE_FORMAT attribute is EGL_NO_TEXTURE, and EGL_TEXTURE_TARGET
+ is something other than EGL_NO_TEXTURE; or, EGL_TEXTURE_FORMAT is
+ something other than EGL_NO_TEXTURE, and EGL_TEXTURE_TARGET is
+ EGL_NO_TEXTURE.
+ Finally, an EGL_BAD_ATTRIBUTE error is generated if any of the EGL_-
+ TEXTURE_FORMAT, EGL_TEXTURE_TARGET, or EGL_MIPMAP_TEXTURE attributes
+ are specified, but config does not support OpenGL ES rendering (e.g.
+ the EGL_RENDERABLE_TYPE attribute does not include at least one of EGL_-
+ OPENGL_ES_BIT or EGL_OPENGL_ES2_BIT.
+ */
+EXPORT_C EGLSurface eglCreatePbufferSurface(EGLDisplay aDisplay, EGLConfig aConfig, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreatePbufferSurface Display=%d, Config=%d -->", aDisplay, aConfig);
+ EGL_TRACE_ATTRIB_LIST(aAttribList);
+
+ EGLSurface newSurface = EGL_NO_SURFACE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ newSurface = Instance().eglCreatePbufferSurface(*threadState, aDisplay, aConfig, aAttribList);
+ }
+ EGL_TRACE("eglCreatePbufferSurface new Surface=0x%x <--", newSurface);
+ return newSurface;
+ }
+
+/*
+ Creates an offscreen EGLSurface and returns a handle to it. Any EGL context
+ created with a compatible EGLConfig can be used to render into this surface.
+
+ To create a pixmap rendering surface, first create a native platform pixmap,
+ then select an EGLConfig matching the pixel format of that pixmap (calling
+ eglChooseConfig with an attribute list including EGL_MATCH_NATIVE_PIXMAP
+ returns only EGLConfigs matching the pixmap specified in the attribute list).
+
+ 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.
+ */
+EXPORT_C EGLSurface eglCreatePixmapSurface(EGLDisplay aDisplay, EGLConfig aConfig, EGLNativePixmapType aPixmap, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreatePixmapSurface Display=%d, Config=%d, Pixmap=0x%x -->", aDisplay, aConfig, aPixmap);
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ EGLSurface newSurface = EGL_NO_SURFACE;
+ if (threadState)
+ {
+ newSurface = Instance().eglCreatePixmapSurface(*threadState, aDisplay, aConfig, aPixmap, aAttribList);
+ }
+ EGL_TRACE("eglCreatePixmapSurface new Surface=0x%x <--", newSurface);
+ return newSurface;
+ }
+
+/*
+ Destroy an EGLSurface of any type (window, pbuffer, or pixmap).
+
+ All resources associated with surface which were allocated by EGL are marked
+ for deletion as soon as possible. Following eglDestroySurface, the surface
+ and the handle referring to it are treated in the same fashion as a surface
+ destroyed by eglTerminate.
+
+ Resources associated with surface but not allocated by EGL, such as native
+ windows, native pixmaps, or client API buffers, are not affected when the
+ surface is destroyed. Only storage actually allocated by EGL is marked for
+ deletion. Furthermore, resources associated with a pbuffer surface are not
+ released until all color buffers of that pbuffer bound to a OpenGL ES texture
+ object have been released.
+
+ Returns EGL_FALSE on failure. An EGL_BAD_SURFACE error is generated if surface
+ is not a valid rendering surface.
+ */
+EXPORT_C EGLBoolean eglDestroySurface(EGLDisplay aDisplay, EGLSurface aSurface)
+ {
+ EGL_TRACE("eglDestroySurface Display=%d, Surface=0x%x", aDisplay, aSurface);
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ EGLBoolean result = EGL_FALSE;
+ if (threadState)
+ {
+ result = Instance().eglDestroySurface(*threadState, aDisplay, aSurface);
+ }
+ return result;
+ }
+
+/*
+ Returns in value the value of attribute for surface. attribute must be set
+ to one of the attributes in table 3.5 of the EGL specification.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglQuerySurface(EGLDisplay aDisplay, EGLSurface aSurface, EGLint aAttribute, EGLint *aValue)
+ {
+ EGL_TRACE("eglQuerySurface display=%d, surface=%d, attribute=%d", aDisplay, aSurface, aAttribute);
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ return Instance().eglQuerySurface(*threadState, aDisplay, aSurface, aAttribute, aValue);
+ }
+ return EGL_FALSE;
+ }
+
+/*
+ Set the current rendering API, this is set on a per-thread basis.
+
+ api must specify one of the supported client APIs , either EGL_OPENVG_API
+ or EGL_OPENGL_ES_API. (EGL_OPENGL_API is not currently supported by Symbian.)
+
+ Returns EGL_FALSE on failure. If api is not one of the values specified
+ above, or if the client API specified by api is not supported by the
+ implementation, an EGL_BAD_PARAMETER error is generated.
+ */
+EXPORT_C EGLBoolean eglBindAPI(EGLenum aApi)
+ {
+ EGL_TRACE("eglBindAPI 0x%x (%s)", aApi, (aApi == EGL_OPENGL_ES_API) ? "EGL_OPENGL_ES_API" : (aApi == EGL_OPENVG_API) ? "EGL_OPENVG_API" : "???");
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ EGLBoolean result = EGL_FALSE;
+ if (threadState)
+ {
+ if ( (aApi == EGL_OPENGL_ES_API) || (aApi == EGL_OPENVG_API) )
+ {
+ threadState->SetEglBoundApi(aApi);
+ result = EGL_TRUE;
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData(rfcdata);
+ eglApiData.Init(EglRFC::EeglBindAPI);
+ eglApiData.AppendEGLenum(aApi);
+ EGLBoolean hostResult = threadState->ExecEglBooleanCmd(eglApiData);
+ // confirm Host EGL matches what we think about the parameter
+ EGLPANIC_ASSERT_DEBUG(hostResult == result, EEglPanicTemp);
+ }
+ else
+ {
+ threadState->SetEglError(EGL_BAD_PARAMETER);
+ }
+ }
+ return result;
+ }
+
+/*
+ Get the current rendering API, this is set on a per-thread basis.
+
+ The value returned will be one of the valid api parameters to eglBindAPI,
+ or EGL_NONE.
+
+ The initial value of the current rendering API is EGL_OPENGL_ES_API.
+ Applications using multiple client APIs are responsible for ensuring
+ the current rendering API is correct before calling the functions
+ eglCreateContext, eglGetCurrentContext, eglGetCurrentDisplay,
+ eglGetCurrentSurface, eglMakeCurrent (when its ctx parameter is
+ EGL_NO_CONTEXT), eglWaitClient, or eglWaitNative.
+ */
+EXPORT_C EGLenum eglQueryAPI(void)
+ {
+ EGL_TRACE("eglQueryAPI");
+
+ EGLenum result = EGL_OPENGL_ES_API;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ { // EGL threadState exists
+ result = threadState->EglBoundApi();
+ threadState->SetEglError(EGL_SUCCESS);
+#ifdef _DEBUG
+ // Debug build checks that local threadState is in sync with Host EGL state
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglQueryAPI);
+ threadState->ExecuteEglNeverErrorCmd(eglApiData);
+ EGLPANIC_ASSERT(result == (EGLenum)eglApiData.ReturnValue(), EEglPanicHostAndClientBoundApiOutOfSync);
+#endif
+ }
+ return result;
+ }
+
+/*
+ Wait for client (Open GL ES, VG, ...) rendering to complete, before
+ using Symbian native rendering.
+
+ Returns EGL_TRUE on success. If there is no current context for the current
+ rendering API, the function has no effect but still returns EGL_TRUE. If the
+ surface associated with the calling thread’s current context is no longer valid,
+ EGL_FALSE is returned and an EGL_BAD_CURRENT_SURFACE error is generated.
+ */
+EXPORT_C EGLBoolean eglWaitClient(void)
+ {
+ EGL_TRACE("eglWaitClient");
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglWaitClient(*threadState);
+ }
+ return result;
+ }
+
+/*
+ Return EGL to its state at thread initialization.
+
+ EGL_TRUE is returned on success, and the following actions are taken:
+ * For each client API supported by EGL, if there is a currently bound context,
+ that context is released. This is equivalent to calling eglMakeCurrent
+ with ctx set to EGL_NO_CONTEXT and both draw and read set to EGL_NO_SURFACE.
+ * The current rendering API is reset to its value at thread initialization.
+ * Any additional implementation-dependent per-thread state maintained by
+ EGL is marked for deletion as soon as possible.
+ Returns EGL_FALSE on failure, there are no defined conditions under which
+ failure will occur.
+ */
+EXPORT_C EGLBoolean eglReleaseThread(void)
+ {
+ EGL_TRACE("eglReleaseThread -->");
+
+ TEglThreadState* threadState = CVghwUtils::EglThreadState(); // fetching pre-existing thread state, if any
+ if (threadState)
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglReleaseThread);
+ threadState->ExecuteEglNeverErrorCmd(eglApiData);
+
+ // release client side memory
+ CVghwUtils::ReleaseThreadState();
+ }
+
+ EGL_TRACE("eglReleaseThread <--");
+ return EGL_TRUE;
+ }
+
+/*
+ Creates a single pbuffer surface bound to the specified buffer for part or
+ all of its buffer storage, and returns a handle to it. The width and height
+ of the pbuffer are determined by the width and height of buffer.
+
+ Currently, the only client API resources which may be bound in this fashion
+ are OpenVG VGImage objects.
+
+ 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.
+ */
+EXPORT_C EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay aDisplay, EGLenum aBufType, EGLClientBuffer aBuffer,
+ EGLConfig aConfig, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreatePbufferFromClientBuffer Display=%d, BufType=%d, Config=%d -->", aDisplay, aBufType, aConfig);
+ EGL_TRACE_ATTRIB_LIST(aAttribList);
+
+ EGLSurface newSurface = EGL_NO_SURFACE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ newSurface = Instance().eglCreatePbufferFromClientBuffer(*threadState, aDisplay, aBufType, aBuffer, aConfig, aAttribList);
+ }
+ EGL_TRACE("eglCreateWindowSurface new Surface=0x%x <--", newSurface);
+ return newSurface;
+ }
+
+/*
+ Set an attribute for an EGLSurface.
+
+ The specified attribute of surface is set to value. Attributes that can be
+ specified are EGL_MIPMAP_LEVEL, EGL_MULTISAMPLE_RESOLVE, and EGL_SWAP_BEHAVIOR.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglSurfaceAttrib(EGLDisplay aDisplay, EGLSurface aSurface,
+ EGLint aAttribute, EGLint aValue)
+ {
+ EGL_TRACE("eglSurfaceAttrib Display=%d, Surface=0x%x, Attribute=0x%x, Value=%d", aDisplay, aSurface, aAttribute, aValue);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglSurfaceAttrib(*threadState, aDisplay, aSurface, aAttribute, aValue);
+ }
+ return result;
+ }
+
+/*
+ Defines a two-dimensional texture image. The texture image consists of the image
+ data in buffer for the specified surface, and need not be copied. Currently the
+ only value accepted for buffer is EGL_BACK_BUFFER, which indicates the buffer into
+ which OpenGL ES rendering is taking place (this is true even when using a
+ singlebuffered surface, such as a pixmap). In future versions of EGL, additional buffer
+ values may be allowed to bind textures to other buffers in an EGLSurface.
+
+ eglBindTexImage is ignored if there is no current rendering context.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglBindTexImage(EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer)
+ {
+ EGL_TRACE("eglBindTexImage Display=%d, Surface=0x%x, Buffer=%d", aDisplay, aSurface, aBuffer);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglBindTexImage(*threadState, aDisplay, aSurface, aBuffer);
+ }
+ return result;
+ }
+
+/*
+ The specified color buffer is released back to the surface. The surface is
+ made available for reading and writing when it no longer has any color
+ buffers bound as textures.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglReleaseTexImage(EGLDisplay aDisplay, EGLSurface aSurface, EGLint aBuffer)
+ {
+ EGL_TRACE("eglReleaseTexImage Display=%d, Surface=0x%x, Buffer=%d", aDisplay, aSurface, aBuffer);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglReleaseTexImage(*threadState, aDisplay, aSurface, aBuffer);
+ }
+ return result;
+ }
+
+/*
+ Specifies the minimum number of video frame periods per buffer swap for
+ the window associated with the current context. The interval takes effect when
+ eglSwapBuffers is first called subsequent to the eglSwapInterval call.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglSwapInterval(EGLDisplay aDisplay, EGLint aInterval)
+ {
+ EGL_TRACE("eglSwapInterval Display=%d, Interval=%d frames", aDisplay, aInterval);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglSwapInterval(*threadState, aDisplay, aInterval);
+ }
+ return result;
+ }
+
+/*
+ Create a rendering context for the current rendering API.
+
+ If eglCreateContext succeeds, it initializes the context to the initial
+ state defined for the current rendering API, and returns a handle to it.
+ The context can be used to render to any compatible EGLSurface. Although
+ contexts are specific to a single client API , all contexts created in
+ EGL exist in a single namespace. This allows many EGL calls which manage
+ contexts to avoid use of the current rendering API.
+
+ 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.
+
+ If config is not a valid EGLConfig, or does not support the requested client
+ API , then an EGL_BAD_CONFIG error is generated (this includes requesting creation
+ of an OpenGL ES 1.x context when the EGL_RENDERABLE_TYPE attribute
+ of config does not contain EGL_OPENGL_ES_BIT, or creation of an OpenGL ES
+ 2.x context when the attribute does not contain EGL_OPENGL_ES2_BIT).
+
+ If the OpenGL or OpenGL ES server context state for share context exists in
+ an address space that cannot be shared with the newly created context, if share -
+ context was created on a different display than the one referenced by config, or if
+ the contexts are otherwise incompatible (for example, one context being associated
+ with a hardware device driver and the other with a software renderer), then an
+ EGL_BAD_MATCH error is generated. If the server does not have enough resources
+ to allocate the new context, then an EGL_BAD_ALLOC error is generated.
+ */
+EXPORT_C EGLContext eglCreateContext(EGLDisplay aDisplay, EGLConfig aConfig,
+ EGLContext aShareContext, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreateContext Display=%d, Config=%d, ShareContext=%d -->", aDisplay, aConfig, aShareContext);
+ EGL_TRACE_ATTRIB_LIST(aAttribList);
+
+ EGLContext result = EGL_NO_CONTEXT;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglCreateContext(*threadState, aDisplay, aConfig, aShareContext, aAttribList);
+ }
+ EGL_TRACE("eglCreateContext new context=%d <--", result);
+ return result;
+ }
+
+/*
+ Destroy a rendering context.
+
+ All resources associated with ctx are marked for deletion as soon as possible.
+ Following eglDestroyContext, the context and the handle referring to it are
+ treated in the same fashion as a context destroyed by eglTerminate.
+
+ Returns EGL_FALSE on failure. An EGL_BAD_CONTEXT error is generated if ctx is
+ not a valid context.
+ */
+EXPORT_C EGLBoolean eglDestroyContext(EGLDisplay aDisplay, EGLContext aContext)
+ {
+ EGL_TRACE("eglDestroyContext Display=%d, Context=%d", aDisplay, aContext);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglDestroyContext(*threadState, aDisplay, aContext);
+ }
+ return result;
+ }
+
+/*
+ Make a context current, binds ctx to the current rendering thread
+ and to the draw and read surfaces.
+
+ For an OpenVG context, the same EGLSurface must be specified for both
+ draw and read.
+
+ If the calling thread already has a current context of the same client
+ API type as ctx, then that context is flushed and marked as no longer
+ current. ctx is then made the current context for the calling thread.
+
+ To release the current context without assigning a new one, set ctx to
+ EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE. The currently
+ bound context for the client API specified by the current rendering API
+ is flushed and marked as no longer current, and there will be no current
+ context for that client API after eglMakeCurrent returns. This is the
+ only case in which eglMakeCurrent respects the current rendering API.
+ In all other cases, the client API affected is determined by ctx. This
+ is the only case where an uninitialized display may be passed to
+ eglMakeCurrent.
+
+ Returns EGL_FALSE on failure. Errors generated may include:
+ * If draw or read are not compatible with ctx, then an EGL_BAD_MATCH
+ error is generated.
+ * If ctx is current to some other thread, or if either draw or read are
+ bound to contexts in another thread, an EGL_BAD_ACCESS error is
+ generated.
+ * If binding ctx would exceed the number of current contexts of that
+ client API type supported by the implementation, an EGL_BAD_ACCESS
+ error is generated.
+ * If either draw or read are pbuffers created with eglCreatePbufferFrom-
+ ClientBuffer, and the underlying bound client API buffers are in use
+ by the client API that created them, an EGL_BAD_ACCESS error is
+ generated.
+ * If ctx is not a valid context, an EGL_BAD_CONTEXT error is generated.
+ * If either draw or read are not valid EGL surfaces, an EGL_BAD_SURFACE
+ error is generated.
+ * If a native window underlying either draw or read is no longer valid,
+ an EGL_BAD_NATIVE_WINDOW error is generated.
+ * If draw and read cannot fit into graphics memory simultaneously, an
+ EGL_BAD_MATCH error is generated.
+ * If the previous context of the calling thread has unflushed commands,
+ and the previous surface is no longer valid, an EGL_BAD_CURRENT_SURFACE
+ error is generated.
+ * If the ancillary buffers for draw and read cannot be allocated, an
+ EGL_BAD_ALLOC error is generated.
+ * If a power management event has occurred, an EGL_CONTEXT_LOST error
+ is generated.
+ * As with other commands taking EGLDisplay parameters, if dpy is not a
+ valid EGLDisplay handle, an EGL_BAD_DISPLAY error is generated.
+ Other errors may arise when the context state is inconsistent with the
+ surface state, as described in the EGL specification.
+ */
+EXPORT_C EGLBoolean eglMakeCurrent(EGLDisplay aDisplay, EGLSurface aDraw, EGLSurface aRead, EGLContext aContext)
+ {
+ EGL_TRACE("eglMakeCurrent Display=%d, DrawSurface=0x%x, ReadSurface=0x%x, Context=%d", aDisplay, aDraw, aRead, aContext);
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ return Instance().eglMakeCurrent(*threadState, aDisplay, aDraw, aRead, aContext);
+ }
+ return EGL_FALSE;
+ }
+
+/*
+ Get the current context for the current rendering API.
+
+ 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).
+ If the current context has been marked for deletion as a result of calling
+ eglTerminate or eglDestroyContext, the handle returned by eglGetCurrentContext
+ is not valid, and cannot be passed successfully to any other EGL function,
+ as discussed in section 3.2 of the EGL Specification.
+ */
+EXPORT_C EGLContext eglGetCurrentContext(void)
+ {
+ EGL_TRACE("eglGetCurrentContext -->");
+
+ EGLContext context = EGL_NO_SURFACE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ context = Instance().eglGetCurrentContext(*threadState);
+ }
+ EGL_TRACE("eglGetCurrentContext context=%d <--", context);
+ return context;
+ }
+
+/*
+ Get the surfaces used for rendering by a current context.
+
+ readdraw is either EGL_READ or EGL_DRAW, to return respectively the read or
+ draw surfaces bound to the current context in the calling thread, for the
+ current rendering API.
+
+ If there is no current context for the current rendering API, then
+ EGL_NO_SURFACE is returned (this is not an error). If readdraw is neither
+ EGL_READ nor EGL_DRAW, EGL_NO_SURFACE is returned and an EGL_BAD_PARAMETER
+ error is generated. If a current surface has been marked for deletion as
+ a result of calling eglTerminate or eglDestroySurface, the handle returned
+ by eglGetCurrentSurface is not valid, and cannot be passed successfully to
+ any other EGL function, as discussed in section 3.2 of the EGL Specification.
+ */
+EXPORT_C EGLSurface eglGetCurrentSurface(EGLint aReadDraw)
+ {
+ EGL_TRACE("eglGetCurrentSurface ReadDraw=%d -->", aReadDraw);
+
+ EGLSurface surface = EGL_NO_SURFACE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ surface = Instance().eglGetCurrentSurface(*threadState, aReadDraw);
+ }
+ EGL_TRACE("eglGetCurrentSurface surface=0x%x <--", surface);
+ return surface;
+ }
+
+/*
+ Get the display associated with a current context.
+
+ The display for the current context in the calling thread, for the current
+ rendering API, is returned. If there is no current context for the current
+ rendering API, EGL_NO_DISPLAY is returned (this is not an error).
+
+ Note that EGL_NO_DISPLAY is used solely to represent an error condition,
+ and is not a valid EGLDisplay handle. Passing EGL_NO_DISPLAY to any command
+ taking an EGLDisplay parameter will generate either an EGL_BAD_DISPLAY
+ error if the EGL implementation validates EGLDisplay handles, or undefined
+ behavior as described at the end of section 3.1 of the EGL Specification.
+ */
+EXPORT_C EGLDisplay eglGetCurrentDisplay(void)
+ {
+ EGL_TRACE("eglGetCurrentDisplay -->");
+
+ EGLDisplay display = EGL_NO_DISPLAY;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ display = Instance().eglGetCurrentDisplay(*threadState);
+ }
+ EGL_TRACE("eglGetCurrentDisplay Display=%d <--", display);
+ return display;
+ }
+
+/*
+ Obtain the value of context attributes.
+
+ Returns in value the value of attribute for ctx. attribute must be set to
+ EGL_CONFIG_ID, EGL_CONTEXT_CLIENT_TYPE, EGL_CONTEXT_CLIENT_VERSION, or
+ EGL_RENDER_BUFFER.
+
+ 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.
+ */
+EXPORT_C EGLBoolean eglQueryContext(EGLDisplay aDisplay, EGLContext aContext, EGLint aAttribute, EGLint *aValue)
+ {
+ EGL_TRACE("eglQueryContext Display=%d, Context=%d, Attribute=0x%x, aValue=0x%x", aDisplay, aContext, aAttribute, aValue);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglQueryContext(*threadState, aDisplay, aContext, aAttribute, aValue);
+ }
+ EGL_TRACE_GET_ATTRIB("eglQueryContext", "context", aDisplay, aContext, aAttribute, aValue, result);
+ return result;
+ }
+
+/*
+ EGL function is for backwards compatibility only.
+
+ Equivalent to:
+ EGLenum api = eglQueryAPI();
+ eglBindAPI(EGL_OPENGL_ES_API);
+ eglWaitClient();
+ eglBindAPI(api);
+ */
+EXPORT_C EGLBoolean eglWaitGL(void)
+ {
+ EGL_TRACE("eglWaitGL");
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglWaitGL);
+ result = threadState->ExecEglBooleanCmd(eglApiData);
+ }
+ return result;
+ }
+
+/*
+ Wait for Symbian native rendering to complete, before performing
+ client (Open GL ES, VG, ...) rendering.
+
+ Returns EGL_TRUE on success. If there is no current context,
+ the function has no effect but still returns EGL_TRUE. If the surface does not support
+ native rendering (e.g. pbuffer and in most cases window surfaces), the function
+ has no effect but still returns EGL_TRUE. If the surface associated with the
+ calling thread’s current context is no longer valid, EGL_FALSE is returned and an
+ EGL_BAD_CURRENT_SURFACE error is generated. If engine does not denote a recognized
+ marking engine, EGL_FALSE is returned and an EGL_BAD_PARAMETER
+ error is generated.
+ */
+EXPORT_C EGLBoolean eglWaitNative(EGLint aEngine)
+ {
+ EGL_TRACE("eglWaitNative %d", aEngine);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglWaitNative);
+ eglApiData.AppendEGLint(aEngine);
+ result = threadState->ExecEglBooleanCmd(eglApiData);
+
+ if ( EGL_CORE_NATIVE_ENGINE == aEngine )
+ {
+ //Do native draw api sync
+ }
+ }
+ return result;
+ }
+
+/*
+ Post the color buffer to a window.
+
+ If surface is a back-buffered window surface, then the color buffer is
+ copied to the native window associated with that surface. If surface is a
+ single-buffered window, pixmap, or pbuffer surface, eglSwapBuffers has no
+ effect.
+
+ The contents of the color buffer of surface may be affected by
+ eglSwapBuffers, depending on the value of the EGL_SWAP_BEHAVIOR attribute
+ of surface. See section 3.5.6 of the EGL Specification.
+
+ Returns EGL_FALSE on failure. If surface is not a valid EGL surface, an
+ EGL_BAD_SURFACE error is generated. If surface is not bound to the calling
+ thread’s current context, an EGL_BAD_SURFACE error is generated. If target is
+ not a valid native pixmap handle, an EGL_BAD_NATIVE_PIXMAP error should be
+ generated. If the format of target is not compatible with the color buffer,
+ or if the size of target is not the same as the size of the color buffer, and
+ there is no defined conversion between the source and target formats, an
+ EGL_BAD_MATCH error is generated. If called after a power management event
+ has occurred, a EGL_CONTEXT_LOST error is generated. If the native window
+ associated with surface is no longer valid, an EGL_ BAD_NATIVE_WINDOW error
+ is generated.
+ */
+EXPORT_C EGLBoolean eglSwapBuffers(EGLDisplay aDisplay, EGLSurface aSurface)
+ {
+ EGL_TRACE("eglSwapBuffers begin Display=%d, Surface=0x%x -->", aDisplay, aSurface);
+
+ EGLBoolean result = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ result = Instance().eglSwapBuffers(*threadState, aDisplay, aSurface);
+ }
+
+ EGL_TRACE("eglSwapBuffers success=%d <--", result);
+ return result;
+ }
+
+/*
+ Copy the color buffer to a native pixmap.
+
+ The mapping of pixels in the color buffer to pixels in the pixmap is platform
+ dependent, since the native platform pixel coordinate system may differ from
+ that of client APIs.
+
+ The color buffer of surface is left unchanged after calling eglCopyBuffers.
+ Returns EGL_FALSE on failure. If surface is not a valid EGL surface, an
+ EGL_BAD_SURFACE error is generated. If surface is not bound to the calling
+ thread’s current context, an EGL_BAD_SURFACE error is generated. If target is
+ not a valid native pixmap handle, an EGL_BAD_NATIVE_PIXMAP error should be
+ generated. If the format of target is not compatible with the color buffer,
+ or if the size of target is not the same as the size of the color buffer, and
+ there is no defined conversion between the source and target formats, an
+ EGL_BAD_MATCH error is generated. If called after a power management event
+ has occurred, a EGL_CONTEXT_LOST error is generated. If the egl
+ implementation does not support native pixmaps, an EGL_BAD_NATIVE_PIXMAP
+ error is generated.
+ */
+EXPORT_C EGLBoolean eglCopyBuffers(EGLDisplay aDisplay, EGLSurface aSurface, EGLNativePixmapType aTarget)
+ {
+ // Note: API supports CFbsBitmap native pixmap but not SgImage
+ EGL_TRACE("eglCopyBuffers Display=%d, Surface=0x%x, Target=0x%x", aDisplay, aSurface, aTarget);
+
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ { // EGL is initialized for thread
+ return Instance().eglCopyBuffers(*threadState, aDisplay, aSurface, aTarget);
+ }
+ return EGL_FALSE;
+ }
+
+/*
+ * eglCreateImageKHR supports Khronos EGL extension #8, "KHR_image_base"
+ *
+ * Supported values for target parameter:
+ * EGL_NATIVE_PIXMAP_KHR for Khronos EGL extension #9, "KHR_image_pixmap"
+ */
+EGLImageKHR eglCreateImageKHR(EGLDisplay aDisplay, EGLContext aContext, EGLenum aTarget, EGLClientBuffer aBuffer, const EGLint *aAttribList)
+ {
+ EGL_TRACE("eglCreateImageKHR Display=%d, Context=%d, Target=0x%x, Buffer=0x%x, AttribList=0x%x -->",
+ aDisplay, aContext, aTarget, aBuffer, aAttribList);
+
+ EGLImageKHR image = NULL;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ image = Instance().eglCreateImageKHR(*threadState, aDisplay, aContext, aTarget, aBuffer, aAttribList);
+ }
+ EGL_TRACE("eglCreateImageKHR image=0x%x <--", image);
+ return image;
+ }
+
+/*
+ * eglDestroyImageKHR supports Khronos EGL extension #8, "KHR_image_base"
+ */
+EGLBoolean eglDestroyImageKHR(EGLDisplay aDisplay, EGLImageKHR aImage)
+ {
+ EGL_TRACE("eglDestroyImageKHR Display=%d, Image=0x%x -->", aDisplay, aImage);
+
+ EGLBoolean success = EGL_FALSE;
+ TEglThreadState* threadState = CVghwUtils::CreateThreadState();
+ if (threadState)
+ {
+ success = Instance().eglDestroyImageKHR(*threadState, aDisplay, aImage);
+ }
+ EGL_TRACE("eglDestroyImageKHR success=%d <--", success);
+ return success;
+ }
+
+
+/*
+ Returns the address of the extension function named by procName. procName
+ must be a NULL-terminated string. The pointer returned should be cast to
+ a function pointer type matching the extension function’s definition in
+ that extension specification.
+
+ A return value of NULL indicates that the specified function does not exist
+ for the implementation.
+
+ A non-NULL return value for eglGetProcAddress does not guarantee that an
+ extension function is actually supported at runtime. The client must also make
+ a corresponding query, such as glGetString(GL_EXTENSIONS) for OpenGL and
+ OpenGL ES extensions; vgGetString(VG_EXTENSIONS) for OpenVG extensions;
+ or eglQueryString(dpy, EGL_EXTENSIONS) for EGL extensions, to determine if
+ an extension is supported by a particular client API context.
+
+ Function pointers returned by eglGetProcAddress are independent of the display
+ and the currently bound context, and may be used by any context which supports
+ the extension.
+
+ eglGetProcAddress may be queried for all of the following functions:
+ * All EGL and client API extension functions supported by the implementation
+ (whether those extensions are supported by the current context or not).
+ This includes any mandatory OpenGL ES extensions.
+ */
+EXPORT_C void (*eglGetProcAddress (const char *aProcname))(...)
+ {
+ EGL_TRACE("eglGetProcAddress");
+
+ if (aProcname)
+ {
+ return Instance().eglGetProcAddress(aProcname);
+ }
+ return NULL;
+ }
+
+} /* extern "C" */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/eglattribs.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,122 @@
+// 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 of attributes and attribute lists
+
+#include <e32debug.h>
+#include "eglapi.h"
+
+
+
+TInt TAttribUtils::AttribListLength(const EGLint* aAttribList)
+ {
+ int length = 0;
+ if (aAttribList)
+ {
+ while (aAttribList[length] != EGL_NONE)
+ {
+ length += 2;
+ EGLPANIC_ASSERT_DEBUG(length < 100, EEglPanicAtribListLengthTooLong);
+ }
+ ++length;
+ }
+ return length;
+ }
+
+const EGLint* TAttribUtils::FindAttribValue(const EGLint* aAttribList, EGLint aAttrib)
+ {
+ EGLPANIC_ASSERT_DEBUG(aAttrib != EGL_NONE, EEglPanicTemp);
+
+ if (aAttribList && (aAttrib != EGL_NONE) )
+ {
+ TInt idx = 0;
+ while (aAttribList[idx] != EGL_NONE)
+ {
+ if (aAttribList[idx] == aAttrib)
+ {
+ return aAttribList + idx + 1;
+ }
+ idx += 2;
+ EGLPANIC_ASSERT_DEBUG(idx < 100, EEglPanicAtribListLengthTooLong);
+ }
+ }
+ return NULL;
+ }
+
+EGLint* TAttribUtils::FindAttribValue(EGLint* aAttribList, EGLint aAttrib)
+ {
+ EGLPANIC_ASSERT_DEBUG(aAttrib != EGL_NONE, EEglPanicTemp);
+
+ if (aAttribList && (aAttrib != EGL_NONE) )
+ {
+ TInt idx = 0;
+ while (aAttribList[idx] != EGL_NONE)
+ {
+ if (aAttribList[idx] == aAttrib)
+ {
+ return aAttribList + idx + 1;
+ }
+ idx += 2;
+ EGLPANIC_ASSERT_DEBUG(idx < 100, EEglPanicAtribListLengthTooLong);
+ }
+ }
+ return NULL;
+ }
+
+void TAttribUtils::AppendAttribValue(EGLint* aAttribList, EGLint aAttrib, EGLint aValue)
+ {
+ EGLPANIC_ASSERT_DEBUG(aAttrib != EGL_NONE, EEglPanicTemp);
+
+ if (aAttribList && (aAttrib != EGL_NONE))
+ {
+ TInt idx = 0;
+ while (aAttribList[idx] != EGL_NONE)
+ {
+ idx += 2;
+ EGLPANIC_ASSERT_DEBUG(idx < 100, EEglPanicAtribListLengthTooLong);
+ }
+ aAttribList[idx++] = aAttrib;
+ aAttribList[idx++] = aValue;
+ aAttribList[idx++] = EGL_NONE;
+ }
+ }
+
+void TAttribUtils::RemoveAttrib(EGLint* aAttribList, EGLint aAttrib)
+ {
+ EGLPANIC_ASSERT_DEBUG(aAttrib != EGL_NONE, EEglPanicTemp);
+
+ if (aAttribList && (aAttrib != EGL_NONE) && (*aAttribList != EGL_NONE))
+ {
+ TInt dstIdx = 0;
+
+ while ( (aAttribList[dstIdx] != EGL_NONE) && (aAttribList[dstIdx] != aAttrib) )
+ {
+ dstIdx += 2;
+ EGLPANIC_ASSERT_DEBUG(dstIdx < 100, EEglPanicAtribListLengthTooLong);
+ }
+
+ if (aAttribList[dstIdx] == aAttrib)
+ { // attrib found
+ TInt srcIdx = dstIdx + 2;
+ while (aAttribList[srcIdx] != EGL_NONE)
+ { // copy up succeeding attrib / value pairs
+ aAttribList[dstIdx++] = aAttribList[srcIdx++];
+ aAttribList[dstIdx++] = aAttribList[srcIdx++];
+ EGLPANIC_ASSERT_DEBUG(dstIdx < 100, EEglPanicAtribListLengthTooLong);
+ }
+ aAttribList[dstIdx++] = EGL_NONE;
+ }
+ }
+ }
+
+// end of file eglattrib.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/eglcontext.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,293 @@
+// 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:
+// Implementation of guest egl context
+
+#include <e32debug.h>
+#include "eglapi.h"
+
+
+
+// factory function
+CEglContext* CEglContext::Create(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLConfig aConfig, CEglContext* aShareContext, const EGLint* aAttribList)
+ {
+ // ToDo validate aConfig
+ // ToDo validate aShareContext
+
+ // which Khronos Graphics API is the Context for: Open GL ES, Open VG, ...
+ EGLenum api = aThreadState.EglBoundApi();
+ // (in case supported APIs ever change) ensure the current API is valid
+ if (api == EGL_NONE)
+ {
+ aThreadState.SetEglError(EGL_BAD_MATCH);
+ return EGL_NO_CONTEXT;
+ }
+
+ EGLint glesClientVersion = 1;
+ // validate AttribList parameter
+ if ( aAttribList && (*aAttribList != EGL_NONE) )
+ {
+ TBool attribsOkay = EFalse;
+ // As of EGL 1.4 only Open GL ES api supports any attributes for eglCreateContext
+ if (api == EGL_OPENGL_ES_API)
+ {
+ // only supported attribute for Open GL ES is EGL_CONTEXT_CLIENT_VERSION
+ if ( (aAttribList[0] == EGL_CONTEXT_CLIENT_VERSION) && (aAttribList[2] == EGL_NONE) )
+ {
+ glesClientVersion = aAttribList[1];
+ // modify this code when GL ES 2 support is added
+ if (glesClientVersion == 1)
+ {
+ attribsOkay = ETrue;
+ }
+ }
+ }
+ if (!attribsOkay)
+ {
+ aThreadState.SetEglError(EGL_BAD_PARAMETER);
+ return EGL_NO_CONTEXT;
+ }
+ }
+
+ // ToDo validate that aConfig supports this API (inc GL ES v2 versus v1)
+ EGLContext shareContextFamily = EGL_NO_CONTEXT;
+ if (aShareContext)
+ {
+ shareContextFamily = aShareContext->ShareContextFamily();
+ }
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ CEglContext* self = new CEglContext(aDisplay, aConfig, shareContextFamily, api, glesClientVersion);
+ if (self == EGL_NO_CONTEXT)
+ {
+ aThreadState.SetEglError(EGL_BAD_ALLOC);
+ }
+ else
+ {
+ // call Host EGL, & set iHostContext
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglCreateContext);
+ eglApiData.AppendEGLDisplay(aDisplay);
+ eglApiData.AppendEGLConfig(aConfig);
+ eglApiData.AppendEGLContext(aShareContext ? aShareContext->HostContext() : EGL_NO_CONTEXT);
+ eglApiData.AppendEGLintVector(aAttribList, TAttribUtils::AttribListLength(aAttribList));
+ self->iHostContext = aThreadState.ExecEglContextCmd(eglApiData);
+ if (self->iHostContext == EGL_NO_CONTEXT)
+ { // Host EGL error
+ delete self;
+ self = EGL_NO_CONTEXT;
+ }
+ }
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ return self;
+ }
+
+
+CEglContext::CEglContext(EGLDisplay aDisplay, EGLConfig aConfig, EGLContext aShareContextFamily, EGLenum aRenderingApi,
+ EGLint aGlesClientVersion) :
+ iFirstUse(ETrue), iHostContext(EGL_NO_CONTEXT), iDisplay(aDisplay), iShareContextFamily(aShareContextFamily),
+ iConfigId(aConfig), iRenderingApi(aRenderingApi), iDrawSurface(EGL_NO_SURFACE), iReadSurface(EGL_NO_SURFACE),
+ iGlesClientVersion(aGlesClientVersion), iIsDestroyed(EFalse)
+ {
+ iCtxMutex.CreateLocal(EOwnerProcess);
+ }
+
+
+void CEglContext::Delete(TEglThreadState& aThreadState)
+ {
+ EGLPANIC_ASSERT_DEBUG(iCtxMutex.IsHeld(), EEglPanicTemp);
+
+ // tell Host EGL to destroy the Context now
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglDestroyContext);
+ eglApiData.AppendEGLDisplay(iDisplay);
+ eglApiData.AppendEGLContext(iHostContext);
+ EGLBoolean hostResult = aThreadState.ExecEglBooleanCmd(eglApiData);
+ EGLPANIC_ASSERT_DEBUG(hostResult, EEglPanicTemp);
+
+ // free
+ iCtxMutex.Close();
+ RHeap* threadHeap = CVghwUtils::SwitchToVghwHeap();
+ delete this;
+ CVghwUtils::SwitchFromVghwHeap(threadHeap);
+ }
+
+
+CEglContext::~CEglContext()
+ {
+ if (iCtxMutex.Handle())
+ {
+ iCtxMutex.Close();
+ }
+ }
+
+
+EGLBoolean CEglContext::MakeCurrent(TEglThreadState& aThreadState, EGLSurface aDraw, EGLSurface aRead)
+ {
+ // ToDo support different number spaces for Host & Client EGL Surfaces
+ EGLBoolean hostResult = EGL_FALSE;
+ EGLint error = EGL_SUCCESS;
+ iCtxMutex.Wait();
+ if (iIsDestroyed)
+ {
+ error = EGL_BAD_CONTEXT;
+ }
+ else
+ {
+ // ToDo validate aDraw & aRead are compatible with API
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init( EglRFC::EeglMakeCurrent );
+ eglApiData.AppendEGLDisplay(iDisplay);
+ eglApiData.AppendEGLSurface(aDraw);
+ eglApiData.AppendEGLSurface(aRead);
+ eglApiData.AppendEGLContext(iHostContext);
+ hostResult = aThreadState.ExecEglBooleanCmd(eglApiData);
+ if (hostResult)
+ {
+ iDrawSurface = aDraw;
+ iReadSurface = aRead;
+ }
+ }
+ iCtxMutex.Signal();
+ if (error != EGL_SUCCESS)
+ { // error in parameter checks
+ aThreadState.SetEglError(error);
+ }
+ return hostResult;
+ }
+
+
+TBool CEglContext::Destroy(TEglThreadState& aThreadState)
+ {
+ iCtxMutex.Wait();
+ iIsDestroyed = ETrue;
+ if ( (iDrawSurface == EGL_NO_SURFACE) && (iReadSurface == EGL_NO_SURFACE) )
+ { // Context not in use
+ Delete(aThreadState);
+ return ETrue;
+ }
+ iCtxMutex.Signal();
+ return EFalse;
+ }
+
+
+TBool CEglContext::MakeNotCurrent(TEglThreadState& aThreadState)
+ {
+ iCtxMutex.Wait();
+ iDrawSurface = EGL_NO_SURFACE;
+ iReadSurface = EGL_NO_SURFACE;
+
+ if (iIsDestroyed)
+ { // Destroyed & no longer in use
+ Delete(aThreadState);
+ return ETrue;
+ }
+ iCtxMutex.Signal();
+ return EFalse;
+ }
+
+
+EGLContext CEglContext::ShareContextFamily()
+ {
+ EGLContext result = EGL_NO_CONTEXT;
+ // ToDo review - maybe just check Mutex is held
+ iCtxMutex.Wait();
+ if (!iIsDestroyed)
+ {
+ if (iShareContextFamily)
+ {
+ result = iShareContextFamily;
+ }
+ else
+ {
+ result = iHostContext;
+ }
+ }
+ iCtxMutex.Signal();
+ return result;
+ }
+
+// Valid attributes are: EGL_CONFIG_ID, EGL_CONTEXT_CLIENT_TYPE, EGL_CONTEXT_CLIENT_VERSION, or EGL_RENDER_BUFFER
+EGLBoolean CEglContext::QueryAttribute(TEglThreadState& aThreadState, EGLint aAttribute, EGLint* aValue)
+ {
+ EGLint error = EGL_SUCCESS;
+ iCtxMutex.Wait();
+ if (iIsDestroyed)
+ {
+ error = EGL_BAD_CONTEXT;
+ }
+ else
+ {
+ switch (aAttribute)
+ {
+ case EGL_CONFIG_ID:
+ *aValue = iConfigId;
+ break;
+
+ case EGL_CONTEXT_CLIENT_TYPE:
+ *aValue = iRenderingApi;
+ break;
+
+ case EGL_CONTEXT_CLIENT_VERSION:
+ *aValue = iGlesClientVersion;
+ break;
+
+ case EGL_RENDER_BUFFER:
+ if (iDrawSurface == NULL)
+ { // context is not bound to any surface
+ *aValue = EGL_NONE;
+ }
+ else
+ // ToDo check the currently bound surface type to answer this
+ {
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglQueryContext);
+ eglApiData.AppendEGLDisplay(iDisplay);
+ eglApiData.AppendEGLContext(iHostContext);
+ eglApiData.AppendEGLint(aAttribute);
+ eglApiData.AppendEGLintVector(aValue, 1, RemoteFunctionCallData::EOut);
+ EGLBoolean hostResult = aThreadState.ExecEglBooleanCmd(eglApiData);
+ return hostResult;
+ }
+ break;
+
+ default:
+ error = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ // Debug compare with Host EGL result
+#ifdef _DEBUG
+ EGLint hostValue = 0;
+ RemoteFunctionCallData rfcdata; EglRFC eglApiData( rfcdata );
+ eglApiData.Init(EglRFC::EeglQueryContext);
+ eglApiData.AppendEGLDisplay(iDisplay);
+ eglApiData.AppendEGLContext(iHostContext);
+ eglApiData.AppendEGLint(aAttribute);
+ eglApiData.AppendEGLintVector(&hostValue, 1, RemoteFunctionCallData::EOut);
+ EGLBoolean hostResult = aThreadState.ExecEglBooleanCmd(eglApiData);
+ if (error == EGL_SUCCESS)
+ { // Host EGl result should match ours
+ EGLPANIC_ASSERT(hostResult, EEglPanicTemp);
+ EGLPANIC_ASSERT(hostValue == *aValue, EEglPanicTemp);
+ }
+ else
+ {
+ EGLPANIC_ASSERT(!hostResult, EEglPanicTemp);
+ }
+#endif
+ }
+ aThreadState.SetEglError(error);
+ iCtxMutex.Signal();
+ return (error == EGL_SUCCESS);
+ }
+
+// end of file eglcontext.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/egldebug.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,286 @@
+// 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 debugging support
+
+#include <e32debug.h>
+#include "eglapi.h"
+
+
+#ifdef _DEBUG
+
+// These functions help with verbose debug logging of EGL Attibutes
+
+// Try to get an attribute name string, and a description of the value - switch statements can be extended for later EGL versions
+void TAttribUtils::TraceAttribNames(EGLint aAttrib, EGLint aValue, char** aAttrName, char** aValueName)
+ {
+ char* attrName = NULL;
+ char* valueName = NULL;
+ switch (aAttrib)
+ {
+ case EGL_BUFFER_SIZE: attrName = "EGL_BUFFER_SIZE"; break;
+ case EGL_ALPHA_SIZE: attrName = "EGL_ALPHA_SIZE"; break;
+ case EGL_BLUE_SIZE: attrName = "EGL_BLUE_SIZE"; break;
+ case EGL_GREEN_SIZE: attrName = "EGL_GREEN_SIZE"; break;
+ case EGL_RED_SIZE: attrName = "EGL_RED_SIZE"; break;
+ case EGL_DEPTH_SIZE: attrName = "EGL_DEPTH_SIZE"; break;
+ case EGL_STENCIL_SIZE: attrName = "EGL_STENCIL_SIZE"; break;
+ case EGL_CONFIG_CAVEAT: attrName = "EGL_CONFIG_CAVEAT";
+ switch (aValue)
+ {
+ // Config attribute values
+ case EGL_SLOW_CONFIG: valueName = "EGL_SLOW_CONFIG"; break;
+ case EGL_NON_CONFORMANT_CONFIG: valueName = "EGL_NON_CONFORMANT_CONFIG"; break;
+ }
+ break;
+ case EGL_CONFIG_ID: attrName = "EGL_CONFIG_ID"; break;
+ case EGL_LEVEL: attrName = "EGL_LEVEL"; break;
+ case EGL_MAX_PBUFFER_HEIGHT: attrName = "EGL_MAX_PBUFFER_HEIGHT"; break;
+ case EGL_MAX_PBUFFER_PIXELS: attrName = "EGL_MAX_PBUFFER_PIXELS"; break;
+ case EGL_MAX_PBUFFER_WIDTH: attrName = "EGL_MAX_PBUFFER_WIDTH"; break;
+ case EGL_NATIVE_RENDERABLE: attrName = "EGL_NATIVE_RENDERABLE"; break;
+ case EGL_NATIVE_VISUAL_ID: attrName = "EGL_NATIVE_VISUAL_ID"; break;
+ case EGL_NATIVE_VISUAL_TYPE: attrName = "EGL_NATIVE_VISUAL_TYPE"; break;
+ case EGL_PRESERVED_RESOURCES: attrName = "EGL_PRESERVED_RESOURCES"; break;
+ case EGL_SAMPLES: attrName = "EGL_SAMPLES"; break;
+ case EGL_SAMPLE_BUFFERS: attrName = "EGL_SAMPLE_BUFFERS"; break;
+ case EGL_SURFACE_TYPE: attrName = "EGL_SURFACE_TYPE";
+ switch(aValue & 7)
+ {
+ case 0: valueName = "* | EGL_NONE"; break;
+ case 1: valueName = "* | PBUFFER"; break; // EGL_PBUFFER_BIT
+ case 2: valueName = "* | PIXMAP"; break; // EGL_PIXMAP_BIT
+ case 3: valueName = "* | PIXMAP | PBUFFER"; break;
+ case 4: valueName = "* | WINDOW"; break; // EGL_WINDOW_BIT
+ case 5: valueName = "* | WINDOW | PBUFFER"; break;
+ case 6: valueName = "* | WINDOW | PIXMAP"; break;
+ case 7: valueName = "* | WINDOW | PIXMAP | PBUFFER"; break;
+ }
+ break;
+ case EGL_TRANSPARENT_TYPE: attrName = "EGL_TRANSPARENT_TYPE";
+ if (aValue == EGL_TRANSPARENT_RGB)
+ valueName = "EGL_TRANSPARENT_RGB";
+ break;
+ case EGL_TRANSPARENT_BLUE_VALUE: attrName = "EGL_TRANSPARENT_BLUE_VALUE"; break;
+ case EGL_TRANSPARENT_GREEN_VALUE: attrName = "EGL_TRANSPARENT_GREEN_VALUE"; break;
+ case EGL_TRANSPARENT_RED_VALUE: attrName = "EGL_TRANSPARENT_RED_VALUE"; break;
+ case EGL_BIND_TO_TEXTURE_RGB: attrName = "EGL_BIND_TO_TEXTURE_RGB"; break;
+ case EGL_BIND_TO_TEXTURE_RGBA: attrName = "EGL_BIND_TO_TEXTURE_RGBA"; break;
+ case EGL_MIN_SWAP_INTERVAL: attrName = "EGL_MIN_SWAP_INTERVAL"; break;
+ case EGL_MAX_SWAP_INTERVAL: attrName = "EGL_MAX_SWAP_INTERVAL"; break;
+ case EGL_LUMINANCE_SIZE: attrName = "EGL_LUMINANCE_SIZE"; break;
+ case EGL_ALPHA_MASK_SIZE: attrName = "EGL_ALPHA_MASK_SIZE"; break;
+ case EGL_COLOR_BUFFER_TYPE: attrName = "EGL_COLOR_BUFFER_TYPE";
+ switch (aValue)
+ {
+ // EGL_COLOR_BUFFER_TYPE values
+ case EGL_RGB_BUFFER: valueName = "EGL_RGB_BUFFER"; break;
+ case EGL_LUMINANCE_BUFFER: valueName = "EGL_LUMINANCE_BUFFER"; break;
+ }
+ break;
+ case EGL_RENDERABLE_TYPE: attrName = "EGL_RENDERABLE_TYPE";
+ switch(aValue)
+ {
+ case 0: valueName = "EGL_NONE"; break;
+ case 1: valueName = "GL-ES"; break;
+ case 2: valueName = "VG"; break;
+ case 3: valueName = "VG | GL-ES"; break;
+ case 4: valueName = "GL-ES2"; break;
+ case 5: valueName = "GL-ES2 | GL-ES"; break;
+ case 6: valueName = "GL-ES2 | VG"; break;
+ case 7: valueName = "GL-ES2 | VG | GL-ES"; break;
+ case 8: valueName = "GL"; break;
+ case 9: valueName = "GL | GL-ES"; break;
+ case 10: valueName = "GL | VG"; break;
+ case 11: valueName = "GL | VG | GL-ES"; break;
+ case 12: valueName = "GL | GL-ES2"; break;
+ case 13: valueName = "GL | GL-ES2 | GL-ES"; break;
+ case 14: valueName = "GL | GL-ES2 | VG"; break;
+ case 15: valueName = "GL | GL-ES2 | VG | GL-ES"; break;
+ }
+ break;
+ case EGL_MATCH_NATIVE_PIXMAP: attrName = "EGL_MATCH_NATIVE_PIXMAP"; break; // Pseudo-attribute (not queryable)
+ case EGL_CONFORMANT: attrName = "EGL_CONFORMANT"; break;
+ case EGL_HEIGHT: attrName = "EGL_HEIGHT"; break;
+ case EGL_WIDTH: attrName = "EGL_WIDTH"; break;
+ case EGL_LARGEST_PBUFFER: attrName = "EGL_LARGEST_PBUFFER"; break;
+ case EGL_TEXTURE_FORMAT: attrName = "EGL_TEXTURE_FORMAT";
+ switch (aValue)
+ {
+ // config attribute values, for EGL_TEXTURE_FORMAT
+ case EGL_NO_TEXTURE: valueName = "EGL_NO_TEXTURE"; break;
+ case EGL_TEXTURE_RGB: valueName = "EGL_TEXTURE_RGB"; break;
+ case EGL_TEXTURE_RGBA: valueName = "EGL_TEXTURE_RGBA"; break;
+ case EGL_TEXTURE_2D: valueName = "EGL_TEXTURE_2D"; break;
+ }
+ break;
+ case EGL_TEXTURE_TARGET: attrName = "EGL_TEXTURE_TARGET"; break;
+ case EGL_MIPMAP_TEXTURE: attrName = "EGL_MIPMAP_TEXTURE"; break;
+ case EGL_MIPMAP_LEVEL: attrName = "EGL_MIPMAP_LEVEL"; break;
+ case EGL_RENDER_BUFFER: attrName = "EGL_RENDER_BUFFER";
+ switch (aValue)
+ {
+ // EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets
+ case EGL_BACK_BUFFER: valueName = "EGL_BACK_BUFFER"; break;
+ case EGL_SINGLE_BUFFER: valueName = "EGL_SINGLE_BUFFER"; break;
+ }
+ break;
+ case EGL_VG_COLORSPACE: attrName = "EGL_VG_COLORSPACE";
+ switch (aValue)
+ {
+ // OpenVG color spaces
+ case EGL_VG_COLORSPACE_sRGB: valueName = "EGL_VG_COLORSPACE_sRGB"; break;
+ case EGL_VG_COLORSPACE_LINEAR: valueName = "EGL_VG_COLORSPACE_LINEAR"; break;
+ }
+ break;
+ case EGL_VG_ALPHA_FORMAT: attrName = "EGL_VG_ALPHA_FORMAT";
+ switch (aValue)
+ {
+ // OpenVG alpha formats
+ case EGL_VG_ALPHA_FORMAT_NONPRE: valueName = "EGL_VG_ALPHA_FORMAT_NONPRE"; break;
+ case EGL_VG_ALPHA_FORMAT_PRE: valueName = "EGL_VG_ALPHA_FORMAT_PRE"; break;
+ }
+ break;
+ case EGL_HORIZONTAL_RESOLUTION: attrName = "EGL_HORIZONTAL_RESOLUTION"; break;
+ case EGL_VERTICAL_RESOLUTION: attrName = "EGL_VERTICAL_RESOLUTION"; break;
+ case EGL_PIXEL_ASPECT_RATIO: attrName = "EGL_PIXEL_ASPECT_RATIO"; break;
+ case EGL_SWAP_BEHAVIOR: attrName = "EGL_SWAP_BEHAVIOR"; break;
+ case EGL_MULTISAMPLE_RESOLVE: attrName = "EGL_MULTISAMPLE_RESOLVE"; break;
+ default: // unknown value - maybe buggy data or a later EGL version. Debug prints include the hex anyway.
+ break;
+ }
+
+ if (aValue == EGL_NONE)
+ valueName = "EGL_NONE";
+ if (aAttrib == EGL_NONE)
+ attrName = "EGL_NONE";
+
+ *aAttrName = attrName;
+ *aValueName = valueName;
+ }
+
+// verbose debug logging of EGL Attibute Lists
+void TAttribUtils::TraceAttribList(const EGLint* aAttribList)
+ {
+ int length = 0;
+ if (aAttribList)
+ {
+ while (aAttribList[length] != EGL_NONE)
+ {
+ char* attrName = NULL;
+ char* valueName = NULL;
+ // try to get an attribute name string, and a description of the value
+ TraceAttribNames(aAttribList[length], aAttribList[length+1], &attrName, &valueName);
+ // print attribute & value as numbers, and also print a string name/description if one could be determined
+ if (attrName)
+ {
+ if (valueName)
+ {
+ EGL_TRACE(" TraceAttribList aAttribList[%d]=0x%x (\"%s\"), aAttribList[%d]=0x%x (\"%s\")",
+ length, aAttribList[length], attrName, length+1, aAttribList[length+1], valueName);
+ }
+ else
+ {
+ EGL_TRACE(" TraceAttribList aAttribList[%d]=0x%x (\"%s\"), aAttribList[%d]=0x%x (%d)",
+ length, aAttribList[length], attrName, length+1, aAttribList[length+1], aAttribList[length+1]);
+ }
+ }
+ else
+ {
+ EGL_TRACE(" TraceAttribList aAttribList[%d]=0x%x, aAttribList[%d]=0x%x (%d)",
+ length, aAttribList[length], length+1, aAttribList[length+1], aAttribList[length+1]);
+ }
+ length += 2;
+ }
+ ++length;
+ }
+ }
+
+// verbose debug logging of EGL Get Attibute fn
+void TAttribUtils::TraceGetAttrib(char* aApiName, char* aObjType, EGLDisplay aDisplay, EGLint aObject, EGLint aAttribute, EGLint *aValue, EGLBoolean aResult)
+ {
+ char* attrName = NULL;
+ char* valueName = NULL;
+ if (aResult)
+ {
+ // try to get an attribute name string, and a description of the value
+ TraceAttribNames(aAttribute, *aValue, &attrName, &valueName);
+ // print attribute & value as numbers, and also print a string name/description if one could be determined
+ if (attrName)
+ {
+ if (valueName)
+ {
+ EGL_TRACE("%s succeeded: aDisplay=%d, %s=%d, aAttrib=0x%x (\"%s\"), aValue=0x%x (\"%s\")",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, attrName, *aValue, valueName);
+ }
+ else
+ {
+ EGL_TRACE("%s succeeded: aDisplay=%d, %s=%d, aAttrib=0x%x (\"%s\"), aValue=0x%x (%d)",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, attrName, *aValue, *aValue);
+ }
+ }
+ else
+ {
+ EGL_TRACE("%s succeeded: aDisplay=%d, %s=%d, aAttrib=0x%x, aValue=0x%x (%d)",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, *aValue, *aValue);
+ }
+ }
+ else
+ {
+ // try to get an attribute name string
+ TraceAttribNames(aAttribute, 0, &attrName, &valueName);
+ if (attrName)
+ {
+ EGL_TRACE("%s failed: aDisplay=%d, %s=%d, attribute=0x%x (\"%s\")",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, attrName);
+ }
+ else
+ {
+ EGL_TRACE("%s failed: aDisplay=%d, %s=%d, attribute=0x%x",
+ aApiName, aDisplay, aObjType, aObject, aAttribute);
+ }
+ }
+ }
+
+
+// verbose debug logging of EGL Get Attibute fn
+void TAttribUtils::TraceSetAttrib(char* aApiName, char* aObjType, EGLDisplay aDisplay, EGLint aObject, EGLint aAttribute, EGLint aValue)
+ {
+ char* attrName = NULL;
+ char* valueName = NULL;
+ // try to get an attribute name string, and a description of the value
+ TraceAttribNames(aAttribute, aValue, &attrName, &valueName);
+ // print attribute & value as numbers, and also print a string name/description if one could be determined
+ if (attrName)
+ {
+ if (valueName)
+ {
+ EGL_TRACE("%s: aDisplay=%d, %s=%d, aAttrib=0x%x (\"%s\"), aValue=0x%x (\"%s\")",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, attrName, aValue, valueName);
+ }
+ else
+ {
+ EGL_TRACE("%s: aDisplay=%d, %s=%d, aAttrib=0x%x (\"%s\"), aValue=0x%x (%d)",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, attrName, aValue, aValue);
+ }
+ }
+ else
+ {
+ EGL_TRACE("%s: aDisplay=%d, %s=%d, aAttrib=0x%x, aValue=0x%x (%d)",
+ aApiName, aDisplay, aObjType, aObject, aAttribute, aValue, aValue);
+ }
+ }
+
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/eglsgimage.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,369 @@
+// 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:
+// Implementation of SgImage functions exported through eglGetProcAddress
+
+
+#include "eglapi.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// CEgLImage
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+CEglImage::CEglImage() : iSgHandle(), iDisplay(0), iSgImageInfo(), iPbufferHandle(0), iVgHandle(VG_INVALID_HANDLE),
+ iCreateCount(1), iOpenCount(0), iIsDestroyed(EFalse)
+ {
+ EGL_TRACE("CEglImage::CEglImage(0x%x)", this);
+ }
+
+CEglImage::~CEglImage()
+ {
+ EGL_TRACE("CEglImage::~CEglImage(0x%x) iCreateCount=%d, iOpenCount=%d", this, iCreateCount, iOpenCount);
+ EGLPANIC_ASSERT_DEBUG( (iCreateCount == 0) && (iOpenCount == 0), EEglPanicEglImageRefCountNonZero);
+ iSgHandle.Close();
+ }
+
+// initialise member data
+void CEglImage::Create(TSgDrawableId aSgImageId, EGLDisplay aDisplay, TSgImageInfo& aSgImageInfo, TInt aPbufferHandle,
+ VGHandle aVgHandle)
+ {
+ EGL_TRACE("CEglImage::Create iCreateCount=%d, iOpenCount=%d", iCreateCount, iOpenCount);
+ EGLPANIC_ASSERT_DEBUG(iCreateCount == 0, EEglPanicEglImageRefCountNonZero);
+ EGLPANIC_ASSERT_DEBUG(!iIsDestroyed, EEglPanicEglImageIsDestroyed);
+ EGLPANIC_ASSERT_DEBUG(aSgImageId != KSgNullDrawableId, EEglPanicTemp);
+ ++iCreateCount;
+ TInt err = iSgHandle.Open(aSgImageId);
+ EGLPANIC_ASSERT_DEBUG(err == KErrNone, EEglPanicTemp);
+ iDisplay = aDisplay;
+ iSgImageInfo = aSgImageInfo;
+ iVgHandle = aVgHandle;
+ iPbufferHandle = aPbufferHandle;
+ }
+
+// Duplicate open
+void CEglImage::Duplicate()
+ {
+ EGL_TRACE("CEglImage::Duplicate iCreateCount=%d, iOpenCount=%d", iCreateCount, iOpenCount);
+ EGLPANIC_ASSERT_DEBUG( (iCreateCount > 0) && !iIsDestroyed, EEglPanicEglImageIsDestroyed);
+ ++iCreateCount;
+ }
+
+
+// If successful increments reference count & returns ETrue. (Ultimtately called from e.g. vgCreateEGLImageTargetKHR.)
+TBool CEglImage::OpenForVgImage(TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId)
+ {
+ EGL_TRACE("CEglImage::OpenForVgImage iCreateCount=%d, iOpenCount=%d", iCreateCount, iOpenCount);
+ if ( (iCreateCount > 0) && (iSgImageInfo.iUsage & ESgUsageBitOpenVgImage) )
+ {
+ ++iOpenCount;
+ aSize = iSgImageInfo.iSizeInPixels;
+ aVgHandle = iVgHandle;
+ aSgImageId = iSgHandle.Id().iId;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// If successful decrements reference count & returns ETrue. (Ultimtately called from e.g. vgDestroyImage.)
+TBool CEglImage::Close()
+ {
+ EGL_TRACE("CEglImage::Close iCreateCount=%d, iOpenCount=%d", iCreateCount, iOpenCount);
+ if (iOpenCount > 0)
+ {
+ --iOpenCount;
+ if ( RefCount() == 0 )
+ {
+ iSgHandle.Close();
+ }
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// If not already destroyed: mark EglImage as destroyed, dec reference count, return ETrue. (Called from eglDestroyImageKHR.)
+TBool CEglImage::Destroy()
+ {
+ EGL_TRACE("CEglImage::Destroy iCreateCount=%d, iOpenCount=%d", iCreateCount, iOpenCount);
+ if (!iIsDestroyed)
+ {
+ --iCreateCount;
+ if (iCreateCount == 0)
+ {
+ iIsDestroyed = ETrue;
+ if ( RefCount() == 0 )
+ {
+ iSgHandle.Close();
+ }
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// Reference Count: count of unbalanced Create() plus Open() calls.
+TInt CEglImage::RefCount()
+ {
+ return iOpenCount + iCreateCount;
+ }
+
+TSgDrawableId CEglImage::SgImageId() const
+ {
+ return iSgHandle.Id();
+ }
+
+EGLDisplay CEglImage::Display() const
+ {
+ return iDisplay;
+ }
+
+TBool CEglImage::IsDestroyed() const
+ {
+ return iIsDestroyed;
+ }
+#else
+void CEglImage::Duplicate() {}
+TBool CEglImage::OpenForVgImage(TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId) {}
+TBool CEglImage::Close() {}
+TBool CEglImage::Destroy() {}
+TBool CEglImage::IsDestroyed() const {}
+TInt CEglImage::RefCount() {}
+EGLDisplay CEglImage::Display() const {}
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SgImage stuff in CGuestEGL
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+EGLint CGuestEGL::ValidateEglImageTarget(EGLDisplay aDisplay, EGLContext aContext, EGLenum aTarget,
+ EGLClientBuffer aBuffer, const EGLint *aAttribList, TSymbianPixmapTypeId aTargetPixmapType)
+ {
+ if (!IsDisplayInitialized(aDisplay)) // ToDo just check display is valid, don't care if it is initialised
+ {
+ return EGL_BAD_DISPLAY;
+ }
+ if ( (aContext != EGL_NO_CONTEXT) || (aTarget != EGL_NATIVE_PIXMAP_KHR) )
+ {
+ return EGL_BAD_PARAMETER;
+ }
+ aTargetPixmapType = EglInternalFunction_GetNativePixmapType((EGLNativePixmapType) aBuffer);
+ if ( (aTargetPixmapType != EPixmapTypeSgImage) || !EglInternalFunction_IsValidNativePixmap((EGLNativePixmapType) aBuffer, aTargetPixmapType) )
+ {
+ return EGL_BAD_PARAMETER;
+ }
+ // ToDo check Attrib List is valid
+ return EGL_SUCCESS;
+ }
+
+#ifdef FAISALMEMON_S4_SGIMAGE
+EGLImageKHR CGuestEGL::DuplicateEglImageIfItExists(EGLDisplay aDisplay, TSgDrawableId aSgId)
+ { // ToDo something smarter with a Hash Map ?
+ TInt imageCount = iEglImageArray.Count();
+ for (TInt index = 0; index < imageCount; ++index)
+ {
+ CEglImage* imagePtr = iEglImageArray[index];
+ if ( !imagePtr->IsDestroyed() && (imagePtr->SgImageId() == aSgId) && (imagePtr->Display() == aDisplay) )
+ {
+ imagePtr->Duplicate();
+ EGL_TRACE("CGuestEGL::DuplicateEglImageIfItExists SgImage already used for eglImage=0x%x", imagePtr);
+ return (EGLImageKHR)imagePtr;
+ }
+ }
+ return EGL_NO_IMAGE_KHR;
+ }
+
+
+
+EGLImageKHR CGuestEGL::CreateNewEglImage(TEglThreadState& aThreadState, EGLDisplay aDisplay, TSgDrawableId aSgId, TSgImageInfo aSgImageInfo)
+ {
+ RHeap* oldHeap = CVghwUtils::SwitchToVghwHeap();
+ CEglImage* newImage = new CEglImage();
+ if (newImage)
+ {
+ if (KErrNone != iEglImageArray.InsertInAddressOrder(newImage))
+ {
+ delete newImage;
+ newImage = NULL;
+ }
+ }
+ CVghwUtils::SwitchFromVghwHeap(oldHeap);
+ if (newImage == NULL)
+ {
+ EGL_TRACE("CGuestEGL::CreateNewEglImage 1.a error creating new CEglImage");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ // success ...
+ EGL_TRACE("CGuestEGL::CreateNewEglImage 1.b Created new eglImage=0x%x", newImage);
+ TInt pbufferHandle;
+ TInt vgImageHandle;
+ TUint64 sgHandles;
+ EGLint hostResult = CVghwUtils::EglGetSgHandles(aSgId.iId, &sgHandles);
+ pbufferHandle = (TInt)(sgHandles&0xFFFFFFFF);
+ vgImageHandle = (TInt)((sgHandles>>32)&0xFFFFFFFF);
+ EGL_TRACE("CGuestEGL::CreateNewEglImage 2. CVghwUtils::EglGetSgHandles result=%d, pbufferHandle=0x%x, vgImageHandle=0x%x",
+ hostResult, pbufferHandle, vgImageHandle);
+ EGLPANIC_ASSERT(KErrNone == hostResult, EEglPanicTemp);
+
+ newImage->Create(aSgId, aDisplay, aSgImageInfo, pbufferHandle, vgImageHandle);
+
+ return (EGLImageKHR)newImage;
+ }
+
+#endif // FAISALMEMON_S4_SGIMAGE
+
+
+/*
+ * eglCreateImageKHR supports Khronos EGL extension #8, "KHR_image_base"
+ *
+ * Supported values for target parameter:
+ * EGL_NATIVE_PIXMAP_KHR for Khronos EGL extension #9, "KHR_image_pixmap"
+ */
+EGLImageKHR CGuestEGL::eglCreateImageKHR(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLContext aContext, EGLenum aTarget,
+ EGLClientBuffer aBuffer, const EGLint *aAttribList)
+ {
+ // ToDo lock aDisplay
+ EGLImageKHR eglImage = EGL_NO_IMAGE_KHR;
+ iEglImageLock.Wait();
+ TSymbianPixmapTypeId targetPixmapType = EPixmapTypeNone;
+ EGLint error = ValidateEglImageTarget(aDisplay, aContext, aTarget, aBuffer, aAttribList, targetPixmapType);
+ EGL_TRACE("CGuestEGL::eglCreateImageKHR 1. validate error=%d, targetPixmapType=%d", error, targetPixmapType);
+
+ if (error == EGL_SUCCESS)
+ {
+ switch(targetPixmapType)
+ {
+ case EPixmapTypeSgImage:
+ {
+#ifdef FAISALMEMON_S4_SGIMAGE
+ // try to lock SgImage from disappearing by opening a temporary handle
+ RSgImage* sgImagePtr = reinterpret_cast<RSgImage*>(aBuffer);
+ TSgDrawableId sgId = sgImagePtr->Id();
+ RSgDrawable sgHandle;
+ TSgImageInfo imgInfo;
+ // ToDo ensure SgImage has correct suitable usage bits
+ if ( (sgId != KSgNullDrawableId) && (KErrNone == sgHandle.Open(sgId)) && (KErrNone == sgImagePtr->GetInfo(imgInfo)) )
+ {
+ EGL_TRACE("CGuestEGL::eglCreateImageKHR 2. SgImage PixelFormat=%d; size=%d,%d; Usage=0x%x",
+ imgInfo.iPixelFormat, imgInfo.iSizeInPixels.iWidth, imgInfo.iSizeInPixels.iHeight, imgInfo.iUsage);
+
+ // find / create CEglImage
+ if (error == EGL_SUCCESS)
+ { // SgImage may already be used for an EglImage
+ eglImage = DuplicateEglImageIfItExists(aDisplay, sgId);
+ if (eglImage == EGL_NO_IMAGE_KHR)
+ { // first use
+ eglImage = CreateNewEglImage(aThreadState, aDisplay, sgId, imgInfo);
+ if (eglImage == EGL_NO_IMAGE_KHR)
+ {
+ error = EGL_BAD_ALLOC;
+ }
+ }
+ }
+ }
+ else
+ {
+ error = EGL_BAD_PARAMETER;
+ }
+ sgHandle.Close();
+#endif
+ }
+ break;
+
+ case EPixmapTypeFbsBitmap:
+ case EPixmapTypeNone:
+ default: // pixmap type not supported by this API
+ error = EGL_BAD_PARAMETER;
+ break;
+ }
+ }
+
+ iEglImageLock.Signal();
+ aThreadState.SetEglError(error);
+
+ // we either failed or should have a non-NULL handle
+ EGLPANIC_ASSERT_DEBUG( (error != EGL_SUCCESS) || (eglImage != EGL_NO_IMAGE_KHR), EEglPanicTemp);
+
+ return eglImage;
+ }
+
+/*
+ * eglDestroyImageKHR supports Khronos EGL extension #8, "KHR_image_base"
+ */
+EGLBoolean CGuestEGL::eglDestroyImageKHR(TEglThreadState& aThreadState, EGLDisplay aDisplay, EGLImageKHR aImage)
+ {
+ // ToDo lock aDisplay
+ EGLBoolean result = EGL_FALSE;
+ iEglImageLock.Wait();
+ TInt index = iEglImageArray.FindInAddressOrder((CEglImage*)aImage);
+ if (index >= 0)
+ {
+ CEglImage* eglImage = iEglImageArray[index];
+ if ( (eglImage->Display() && aDisplay) && eglImage->Destroy())
+ {
+ result = EGL_TRUE;
+ if (eglImage->RefCount() == 0)
+ {
+ iEglImageArray.Remove(index);
+ delete eglImage;
+ }
+ }
+ }
+ iEglImageLock.Signal();
+
+ // set EGL Error appropriately
+ aThreadState.SetEglError( result ? EGL_SUCCESS : EGL_BAD_PARAMETER);
+ return result;
+ }
+
+
+TBool CGuestEGL::EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId)
+ {
+ EGLBoolean result = EGL_FALSE;
+ iEglImageLock.Wait();
+ TInt index = iEglImageArray.FindInAddressOrder((CEglImage*)aImage);
+ if (index >= 0)
+ {
+ CEglImage* eglImage = iEglImageArray[index];
+ if (eglImage->OpenForVgImage(aSize, aVgHandle, aSgImageId))
+ {
+ result = EGL_TRUE;
+ }
+ }
+ iEglImageLock.Signal();
+ return result;
+ }
+
+void CGuestEGL::EglImageClose(EGLImageKHR aImage)
+ {
+ iEglImageLock.Wait();
+ TInt index = iEglImageArray.FindInAddressOrder((CEglImage*)aImage);
+ if (index >= 0)
+ {
+ CEglImage* eglImage = iEglImageArray[index];
+ if (eglImage->Close())
+ {
+ if (eglImage->RefCount() == 0)
+ {
+ iEglImageArray.Remove(index);
+ delete eglImage;
+ }
+ }
+ }
+ iEglImageLock.Signal();
+ }
+
+// end of file eglsgimage.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/guestrendering/guestegl/src/eglsync.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -0,0 +1,708 @@
+// 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:
+// EGL sync implementation
+
+#include "eglapi.h"
+
+const EGLint CEglSync::KSupportedFlags = EGL_SYNC_FLUSH_COMMANDS_BIT_KHR;
+
+// ToDo get rid of these macros
+#define EGL_SET_ERROR(e) { Instance().SetError(e); }
+#define TEST_AND_RET(c, r, t) { if (!(c)) { EGL_TRACE(t); return (r); } }
+#define TEST_CLEANUP_RET(c, r, clnp, t) { if (!(c)) { clnp; EGL_TRACE(t); return (r); } }
+#define CHECK_AND_RET(c, e, r, t) { if (!(c)) { EGL_SET_ERROR(e); EGL_TRACE(t); return (r); } }
+#define CHECK_CLEANUP_RET(c, e, r, clnp, t) { if (!(c)) { EGL_SET_ERROR(e); clnp; EGL_TRACE(t); return (r); } }
+#define RESET_EGL_ERROR() { EGL_SET_ERROR(EGL_SUCCESS); }
+
+// ToDo use EGL Panics & panic messages
+void SyncPanic(TInt aPanic)
+ {
+ _LIT(KPanic, "EGL SYNC");
+ User::Panic(KPanic, aPanic);
+ }
+
+CEglSync* CEglSync::Create(RFastLock& aFrontLock, EGLSyncKHR aSync, EGLDisplay aDisplay, EGLenum aType)
+ {
+ CEglSync* sync= new CEglSync(aFrontLock, aSync, aDisplay, aType);
+ TEST_AND_RET(sync != NULL, sync, "CEglSync::Create couldn't create the object");
+ if (KErrNone == sync->Initialize())
+ {
+ EGL_TRACE("CEglSync::Create OK aDisplay=%d aSync=%d aSyncType=0x%x", aDisplay, aSync, aType);
+ return sync;
+ }
+ else
+ {
+ EGL_TRACE("CEglSync::Create FAILED aDisplay=%d aSync=%d aSyncType=0x%x", aDisplay, aSync, aType);
+ delete sync;
+ return NULL;
+ }
+ }
+
+TInt CEglSync::Initialize()
+ {
+ TInt err = KErrNone;
+ err = iSyncMutex.CreateLocal();
+ TEST_AND_RET(err == KErrNone, err, "CEglSync::Initialize failed to create mutex");
+ err = iSyncCondVar.CreateLocal();
+ TEST_AND_RET(err == KErrNone, err, "CEglSync::Initialize failed to create cond var");
+ return err;
+ }
+
+
+CEglSync::CEglSync(RFastLock& aFrontLock, EGLSyncKHR aSync, EGLDisplay aDisplay, EGLenum aType):
+iEglSync(aSync),
+iDisplay(aDisplay),
+iSyncType(aType),
+iSyncState(EGL_UNSIGNALED_KHR),
+iDestroyed(EGL_FALSE),
+iWaiters(0),
+iFrontLock(aFrontLock)
+ {
+
+ }
+
+CEglSync::~CEglSync()
+ {
+ iSyncMutex.Close();
+ iSyncCondVar.Close();
+ EGL_TRACE("CEglSync::~CEglSync iDisplay=%d iEglSync=%d", iDisplay, iEglSync);
+ }
+
+EGLBoolean CEglSync::DestroySyncReady()
+ {
+ EGL_TRACE("CEglSync::DestroySync iDisplay=%d iEglSync=%d iWaiters=%d", iDisplay, iEglSync, iWaiters);
+ iSyncMutex.Wait();
+ if (iWaiters == 0)
+ {
+ EGL_TRACE("CEglSync::DestroySync READY TO DESTROY iDisplay=%d iEglSync=%d iWaiters=%d", iDisplay, iEglSync, iWaiters);
+ iDestroyed = EGL_TRUE;
+ return EGL_TRUE;
+ }
+ else if (!iDestroyed)
+ {
+ EGL_TRACE("CEglSync::DestroySync BROADCAST iDisplay=%d iEglSync=%d iWaiters=%d", iDisplay, iEglSync, iWaiters);
+ iSyncCondVar.Broadcast();
+ }
+ iDestroyed = EGL_TRUE;
+ iSyncMutex.Signal();
+ return EGL_FALSE;
+ }
+
+
+EGLint CEglSync::SignalSync(EGLenum aMode)
+ {
+ EGL_TRACE("CEglSync::SignalSync aMode=%d", aMode);
+
+ iSyncMutex.Wait();
+ if (aMode != iSyncState)
+ {
+ iSyncState = aMode;
+ if (aMode == EGL_SIGNALED_KHR)
+ {
+ iSyncCondVar.Broadcast();
+ }
+ }
+
+ iSyncMutex.Signal();
+ return EGL_SUCCESS;
+ }
+
+EGLint CEglSync::ClientWaitSync(EGLint aFlags, EGLTimeKHR aTimeout)
+ {
+ EGL_TRACE("CEglSync::ClientWaitSync aFlags=%d aTimeout=%d", aFlags, aTimeout);
+
+ CHECK_CLEANUP_RET(!(aFlags & (~KSupportedFlags)),
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iFrontLock.Signal();,
+ "CEglSync::ClientWaitSync bad flags parameter");
+
+ iSyncMutex.Wait();
+ iFrontLock.Signal();
+
+ CHECK_CLEANUP_RET(!iDestroyed ,
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iSyncMutex.Signal();,
+ "CEglSync::ClientWaitSync sync already destroyed");
+
+ EGLint ret = (EGLint) EGL_FALSE;
+ if (iSyncState == EGL_UNSIGNALED_KHR)
+ {
+ if (aTimeout && (aFlags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) && (eglGetCurrentContext() != EGL_NO_CONTEXT))
+ {
+ switch(eglQueryAPI())
+ {
+ case EGL_OPENGL_ES_API:
+ //ToDo: make sure these cases are covered
+ //glFlush();
+ break;
+ case EGL_OPENVG_API:
+ //ToDo: make sure these cases are covered
+ //vgFlush();
+ break;
+ default:
+ SyncPanic(__LINE__);
+ }
+ }
+
+ switch (aTimeout)
+ {
+ case 0:
+ ret = EGL_TIMEOUT_EXPIRED_KHR;
+ break;
+
+ case EGL_FOREVER_KHR:
+ {
+ EGLint res = KErrNone;
+ ++iWaiters;
+ EGL_TRACE("CEglSync::ClientWaitSync iSyncCondVar.Wait");
+ res = iSyncCondVar.Wait(iSyncMutex);
+ --iWaiters;
+ if (res == KErrNone)
+ {
+ ret = EGL_CONDITION_SATISFIED_KHR;
+ }
+ else
+ {
+ ret = EGL_FALSE;
+ }
+ break;
+ }
+
+ default:
+ {
+ /*
+ * Since the supported range of timeout at function RCondVar::TimedWait(mutex, timeout)
+ * is 0 to KMaxTInt, looping mechanism below is used to support 64bit timeout.
+ */
+ EGLint res = KErrTimedOut;
+ EGL_TRACE("CEglSync::ClientWaitSync iSyncCondVar.TimedWait");
+ for(TInt64 timeoutMicroseconds = aTimeout/1000; (res == KErrTimedOut) && (timeoutMicroseconds > 0); timeoutMicroseconds -= KMaxTInt)
+ {
+ ++iWaiters;
+ res = iSyncCondVar.TimedWait(iSyncMutex, (timeoutMicroseconds > KMaxTInt) ? KMaxTInt:timeoutMicroseconds);
+ --iWaiters;
+ }
+ switch (res)
+ {
+ case KErrNone:
+ ret = EGL_CONDITION_SATISFIED_KHR;
+ break;
+ case KErrTimedOut:
+ ret = EGL_TIMEOUT_EXPIRED_KHR;
+ break;
+ default:
+ ret = EGL_FALSE;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ ret = EGL_CONDITION_SATISFIED_KHR;
+ EGL_TRACE("CEglSync::ClientWaitSync sync in signalled state");
+ }
+ if (iDestroyed && (iWaiters == 0))
+ {
+ EGL_TRACE("CEglSync::ClientWaitSync sync autodestroyed");
+ delete this;
+ }
+ else
+ {
+ EGL_TRACE("CEglSync::ClientWaitSync release sync mutex");
+ iSyncMutex.Signal();
+ }
+ EGL_TRACE("CEglSync::ClientWaitSync sync exit ret=0x%x", ret);
+ return ret;
+ }
+
+EGLBoolean CEglSync::GetSyncAttrib(EGLint aAttribute, EGLint *aValue)
+ {
+ EGL_TRACE("CEglSync::GetSyncAttrib aAttribute=0x%x aValue", aValue);
+
+ CHECK_AND_RET(aValue,
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ "CEglSync::GetSyncAttrib undefined parameter aValue is NUL");
+
+ CHECK_AND_RET((aAttribute == EGL_SYNC_TYPE_KHR) || (aAttribute == EGL_SYNC_STATUS_KHR),
+ EGL_BAD_ATTRIBUTE,
+ EGL_FALSE,
+ "CEglSync::GetSyncAttrib unnexpected attribute parameter");
+
+
+ iSyncMutex.Wait();
+ EGLBoolean ret = EGL_FALSE;
+ switch(aAttribute)
+ {
+ case EGL_SYNC_TYPE_KHR:
+ {
+ *aValue = iSyncType;
+ ret = EGL_TRUE;
+ break;
+ }
+ case EGL_SYNC_STATUS_KHR:
+ {
+ *aValue = iSyncState;
+ ret = EGL_TRUE;
+ break;
+ }
+ default:
+ {
+ EGL_SET_ERROR(EGL_BAD_ATTRIBUTE);
+ }
+ }
+ iSyncMutex.Signal();
+ return ret;
+ }
+
+
+CEglSyncExtension* CEglSyncExtension::Create(CGuestEGL& aEglInstance)
+ {
+ EGL_TRACE("CEglSyncExtension::Create");
+ CEglSyncExtension* eglSyncExt= new CEglSyncExtension(aEglInstance);
+ if (eglSyncExt && eglSyncExt->Construct())
+ {
+ return eglSyncExt;
+ }
+
+ delete eglSyncExt;
+ return NULL;
+ }
+
+EGLBoolean CEglSyncExtension::Construct()
+ {
+ if (iEglSyncMapLock.CreateLocal() == KErrNone)
+ {
+ EGL_TRACE("CEglSyncExtension::Construct OK");
+ return EGL_TRUE;
+ }
+
+ EGL_TRACE("CEglSyncExtension::Construct FAILED");
+ return EGL_FALSE;
+ }
+
+CEglSyncExtension::CEglSyncExtension(CGuestEGL& aEglInstance):
+iEglSyncMap(),
+iEglSyncId(0),
+iEglInstance(aEglInstance)
+ {
+
+ }
+
+CEglSyncExtension::~CEglSyncExtension()
+ {
+ if (iEglSyncMapLock.Handle())
+ {
+ iEglSyncMapLock.Wait();
+ }
+
+ EglDestroySync(EGL_NO_DISPLAY);
+
+ iEglSyncMap.Close();
+ iEglSyncMapLock.Close();
+ }
+
+TInt CEglSyncExtension::EglSyncDisplayCreate(EGLDisplay aDisplay)
+ {
+ return KErrNone;
+ }
+
+void CEglSyncExtension::EglDestroySync(EGLDisplay aDisplay)
+ {
+ EGL_TRACE("CEglSyncExtension::EglDestroySync");
+ REglSyncHashMap::TIter iter(iEglSyncMap);
+
+ while (iter.NextKey())
+ {
+ CEglSync* const* syncpp = NULL;
+ syncpp = iter.CurrentValue();
+ if (syncpp && *syncpp && ((aDisplay == EGL_NO_DISPLAY) || (*syncpp)->Display() == aDisplay))
+ {
+ const EGLint* key = iter.CurrentKey();
+ EGLPANIC_ASSERT(key, EEglPanicTemp);
+ if (aDisplay != EGL_NO_DISPLAY)
+ {
+ // we expect that the map is to be closed after removing the elements
+ // therefore we can skip to remove the syncs from map
+ if (KErrNone != iEglSyncMap.Remove(*key))
+ {
+ SyncPanic(__LINE__);
+ }
+ }
+ if ((*syncpp)->DestroySyncReady())
+ {
+ delete *syncpp;
+ }
+ }
+ }
+ }
+
+void CEglSyncExtension::EglSyncDisplayDestroy(EGLDisplay aDisplay)
+ {
+ iEglSyncMapLock.Wait();
+ EglDestroySync(aDisplay);
+ iEglSyncMapLock.Signal();
+ }
+
+EGLSyncKHR CEglSyncExtension::EglCreateSyncKHR(EGLDisplay aDisplay, EGLenum aType, const EGLint* aAttribList)
+ {
+ EGL_TRACE("CEglSyncExtension::EglCreateSyncKHR aDisplay=%d, aType=%d", aDisplay, aType);
+ RESET_EGL_ERROR();
+
+ CHECK_AND_RET(aType == EGL_SYNC_REUSABLE_KHR,
+ EGL_BAD_ATTRIBUTE,
+ EGL_NO_SYNC_KHR,
+ "CEglSyncExtension::EglCreateSyncKHR unsupported sync type");
+
+ CHECK_AND_RET((aAttribList == NULL) || (*aAttribList == EGL_NONE),
+ EGL_BAD_ATTRIBUTE,
+ EGL_NO_SYNC_KHR,
+ "CEglSyncExtension::EglCreateSyncKHR invalid attribute list");
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ CHECK_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ EGL_NO_SYNC_KHR,
+ "CEglSyncExtension::EglCreateSyncKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ EGLSyncKHR dispRet = CreateSync(aDisplay, aType);
+
+ iEglSyncMapLock.Signal();
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+ EGL_TRACE("CEglSyncExtension::EglCreateSyncKHR EXIT aDisplay=%d, sync=%d", aDisplay, dispRet);
+ return dispRet;
+ }
+
+EGLBoolean CEglSyncExtension::EglDestroySyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync)
+ {
+ EGL_TRACE("CEglSyncExtension::EglDestroySyncKHR aDisplay=%d, aSync=%d", aDisplay, aSync);
+
+ RESET_EGL_ERROR();
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ CHECK_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ EGL_FALSE,
+ "CEglSyncExtension::EglDestroySyncKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ CEglSync** sync = iEglSyncMap.Find((EGLint)aSync);
+ CHECK_CLEANUP_RET(sync && (*sync) && ((*sync)->Display() == aDisplay),
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iEglSyncMapLock.Signal(),
+ "CEglSyncDisplayMap::EglDestroySyncKHR cannot find the sync");
+
+ if (KErrNone != iEglSyncMap.Remove((EGLint)aSync))
+ {
+ SyncPanic(__LINE__);
+ }
+
+ if ((*sync)->DestroySyncReady())
+ {
+ delete *sync;
+ }
+
+ iEglSyncMapLock.Signal();
+
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+ EGL_TRACE("CEglSyncExtension::EglDestroySyncKHR EXIT aDisplay=%d, aSync=%d ret=%s", aDisplay, aSync, "EGL_TRUE");
+ return EGL_TRUE;
+ }
+
+EGLBoolean CEglSyncExtension::EglSignalSyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode)
+ {
+ EGL_TRACE("CEglSyncExtension::EglSignalSyncKHR aDisplay=%d, aSync=%d aMode=%d", aDisplay, aSync, aMode);
+ EGLBoolean ret = EGL_FALSE;
+
+ RESET_EGL_ERROR();
+
+ CHECK_AND_RET((aMode == EGL_SIGNALED_KHR) || (aMode == EGL_UNSIGNALED_KHR),
+ EGL_BAD_PARAMETER,
+ ret,
+ "CEglSyncExtension::EglSignalSyncKHR unsupported sync mode");
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ CHECK_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ EGL_FALSE,
+ "CEglSyncExtension::EglSignalSyncKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ CEglSync** sync= iEglSyncMap.Find((EGLint)aSync);
+
+ CHECK_CLEANUP_RET(sync && (*sync) && ((*sync)->Display()==aDisplay),
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iEglSyncMapLock.Signal(); CVghwUtils::SwitchFromVghwHeap(callerHeap);,
+ "CEglSyncExtension::EglSignalSyncKHR cannot find the lock");
+
+ TEST_CLEANUP_RET((*sync)->Display() == EGL_SYNC_REUSABLE_KHR,
+ EGL_BAD_MATCH,
+ iEglSyncMapLock.Signal(); CVghwUtils::SwitchFromVghwHeap(callerHeap);,
+ "CEglSyncExtension::EglSignalSyncKHR bad sync type");
+
+ EGLint signalRet = (*sync)->SignalSync(aMode);
+
+ if (signalRet != EGL_SUCCESS)
+ {
+ EGL_SET_ERROR(ret);
+ EGL_TRACE("CEglSyncExtension::EglSignalSyncKHR failed (%d)", ret);
+ ret = EGL_FALSE;
+ }
+ else
+ {
+ ret = EGL_TRUE;
+ }
+
+ iEglSyncMapLock.Signal();
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+ EGL_TRACE("CEglSyncExtension::EglSignalSyncKHR EXIT aDisplay=%d, aSync=%d ret=%s", aDisplay, aSync, ret ? "EGL_TRUE":"EGL_FALSE");
+ return ret;
+ }
+
+EGLint CEglSyncExtension::Egl_Private_SignalSyncNOK(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode)
+ {
+ EGL_TRACE("CEglSyncExtension::EglPrivateSignalSyncKHR aDisplay=%d, aSync=%d aMode=%d", aDisplay, aSync, aMode);
+
+ TEST_AND_RET((aMode == EGL_SIGNALED_KHR) || (aMode == EGL_UNSIGNALED_KHR),
+ EGL_BAD_PARAMETER,
+ "CEglSyncExtension::EglPrivateSignalSyncKHR unsupported sync mode");
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ TEST_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ "CEglSyncExtension::EglPrivateSignalSyncKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ CEglSync** sync= iEglSyncMap.Find((EGLint)aSync);
+
+ TEST_CLEANUP_RET(sync && (*sync) && ((*sync)->Display()==aDisplay),
+ EGL_BAD_PARAMETER,
+ iEglSyncMapLock.Signal(); CVghwUtils::SwitchFromVghwHeap(callerHeap);,
+ "CEglSyncExtension::EglPrivateSignalSyncKHR cannot find the lock");
+
+ EGLint ret = (*sync)->SignalSync(aMode);
+
+ if (ret != EGL_SUCCESS)
+ {
+ EGL_TRACE("CEglSyncExtension::EglPrivateSignalSyncKHR failed (%d)", ret);
+ }
+
+ iEglSyncMapLock.Signal();
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+ EGL_TRACE("CEglSyncExtension::EglPrivateSignalSyncKHR EXIT aDisplay=%d, aSync=%d ret=%d", aDisplay, aSync, ret);
+ return ret;
+ }
+
+EGLint CEglSyncExtension::EglClientWaitSyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLint aFlags, EGLTimeKHR aTimeout)
+ {
+ EGL_TRACE("CEglSyncExtension::EglClientWaitSyncKHR aDisplay=%d, aSync=%d aFlags=0x%x, aTimeout=%ld", aDisplay, aSync, aFlags, aTimeout);
+
+ RESET_EGL_ERROR();
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ CHECK_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ EGL_FALSE,
+ "CEglSyncExtension::EglClientWaitSyncKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ CEglSync** sync= iEglSyncMap.Find((EGLint)aSync);
+
+ CHECK_CLEANUP_RET(sync && (*sync) && ((*sync)->Display()==aDisplay),
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iEglSyncMapLock.Signal(); CVghwUtils::SwitchFromVghwHeap(callerHeap);,
+ "CEglSyncExtension::EglClientWaitSyncKHR cannot find the sync");
+
+ EGLint ret = (*sync)->ClientWaitSync(aFlags, aTimeout);
+
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+ EGL_TRACE("CEglSyncExtension::EglClientWaitSyncKHR EXIT aDisplay=%d, aSync=%d ret=%d", aDisplay, aSync, ret);
+ return ret;
+ }
+
+EGLBoolean CEglSyncExtension::EglGetSyncAttribKHR(EGLDisplay aDisplay,
+ EGLSyncKHR aSync,
+ EGLint aAttribute,
+ EGLint* aValue)
+ {
+ EGL_TRACE("CEglSyncExtension::EglGetSyncAttribKHR aDisplay=%d, aSync=%d aAttribute=0x%x, aValue=0x%x", aDisplay,
+ aSync,
+ aAttribute,
+ aValue);
+ RESET_EGL_ERROR();
+
+ EGLint lockErr = FindAndLockDisplay(aDisplay);
+
+ CHECK_AND_RET(lockErr == EGL_SUCCESS,
+ lockErr,
+ EGL_FALSE,
+ "CEglSyncExtension::EglGetSyncAttribKHR couldn't find and lock display");
+
+ RHeap* callerHeap = CVghwUtils::SwitchToVghwHeap();
+
+ iEglSyncMapLock.Wait();
+ ReleaseDisplayLock(aDisplay);
+
+ CEglSync** sync= iEglSyncMap.Find((EGLint)aSync);
+
+ CHECK_CLEANUP_RET(sync && (*sync) && ((*sync)->Display()==aDisplay),
+ EGL_BAD_PARAMETER,
+ EGL_FALSE,
+ iEglSyncMapLock.Signal(); CVghwUtils::SwitchFromVghwHeap(callerHeap);,
+ "CEglSyncExtension::EglGetSyncAttribKHR cannot find the lock");
+
+
+ EGLint ret = (*sync)->GetSyncAttrib(aAttribute, aValue);
+
+ iEglSyncMapLock.Signal();
+
+ CVghwUtils::SwitchFromVghwHeap(callerHeap);
+
+ EGL_TRACE("CEglSyncExtension::EglGetSyncAttribKHR EXIT aDisplay=%d, aSync=%d ret=%s", aDisplay, aSync, ret ? "EGL_TRUE":"EGL_FALSE");
+ return ret;
+ }
+
+EGLint CEglSyncExtension::FindAndLockDisplay(EGLDisplay aDisplay)
+ {
+ return iEglInstance.FindAndLockDisplay(aDisplay);
+ }
+
+void CEglSyncExtension::ReleaseDisplayLock(EGLDisplay aDisplay)
+ {
+ iEglInstance.ReleaseDisplayLock(aDisplay);
+ }
+
+EGLSyncKHR CEglSyncExtension::CreateSync(EGLDisplay aDisplay, EGLenum aType)
+ {
+ CEglSync* sync = CEglSync::Create(iEglSyncMapLock,
+ (EGLSyncKHR)(++iEglSyncId),
+ aDisplay,
+ aType);
+
+ CHECK_AND_RET(sync != NULL,
+ EGL_BAD_ALLOC,
+ EGL_NO_SYNC_KHR,
+ "CEglSyncDisplayMap::CreateSync failed to create sync");
+
+ TInt err = KErrNone;
+ err = iEglSyncMap.Insert(iEglSyncId, sync);
+
+ CHECK_CLEANUP_RET(err == KErrNone,
+ EGL_BAD_ALLOC,
+ EGL_NO_SYNC_KHR,
+ delete sync,
+ "CEglSyncDisplayMap::CreateSync insert failed");
+
+ return (EGLSyncKHR)iEglSyncId;
+ }
+
+EGLSyncKHR CEglSyncExtension::eglCreateSyncKHR(EGLDisplay aDisplay, EGLenum aType, const EGLint* aAttribList)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_NO_SYNC_KHR,
+ "CEglSyncExtension::eglCreateSyncKHR extension instance not created");
+
+ return eglSyncInstance->EglCreateSyncKHR(aDisplay, aType, aAttribList);
+ }
+
+EGLBoolean CEglSyncExtension::eglDestroySyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_FALSE,
+ "CEglSyncExtension::eglDestroySyncKHR extension instance not created");
+
+ return eglSyncInstance->EglDestroySyncKHR(aDisplay, aSync);
+ }
+
+EGLint CEglSyncExtension::eglClientWaitSyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLint aFlags, EGLTimeKHR aTimeout)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_FALSE,
+ "CEglSyncExtension::eglGetSyncAttribKHR extension instance not created");
+
+ return eglSyncInstance->EglClientWaitSyncKHR(aDisplay, aSync, aFlags, aTimeout);
+ }
+
+EGLBoolean CEglSyncExtension::eglSignalSyncKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_FALSE,
+ "CEglSyncExtension::eglSignalSyncKHR extension instance not created");
+
+ return eglSyncInstance->EglSignalSyncKHR(aDisplay, aSync, aMode);
+ }
+
+
+EGLBoolean CEglSyncExtension::eglGetSyncAttribKHR(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLint aAttribute, EGLint* aValue)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_FALSE,
+ "CEglSyncExtension::eglGetSyncAttribKHR extension instance not created");
+
+ return eglSyncInstance->EglGetSyncAttribKHR(aDisplay, aSync, aAttribute, aValue);
+ }
+
+EGLint CEglSyncExtension::egl_Private_SignalSyncNOK(EGLDisplay aDisplay, EGLSyncKHR aSync, EGLenum aMode)
+ {
+ CEglSyncExtension* eglSyncInstance = Instance().EGLSyncExtension();
+ CHECK_AND_RET(eglSyncInstance,
+ EGL_NOT_INITIALIZED,
+ EGL_NOT_INITIALIZED,
+ "CEglSyncExtension::egl_Private_SignalSyncNOK extension instance not created");
+
+ return eglSyncInstance->Egl_Private_SignalSyncNOK(aDisplay, aSync, aMode);
+ }
--- /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;
+ }
--- a/guestrendering/guestvideodriver/ldd/src/virtualvideohwinterface.cpp Fri Sep 03 10:14:54 2010 +0100
+++ b/guestrendering/guestvideodriver/ldd/src/virtualvideohwinterface.cpp Wed Sep 08 15:45:18 2010 +0100
@@ -25,7 +25,9 @@
// CONSTANTS
+#ifdef PLATSIM_CONFIG
_LIT( KVirtualVideoHwInterfacePanic, "DVirtualVideoHwInterface" );
+#endif
// ============================ LOCAL DATA TYPES ===============================
--- a/guestrendering/vghwutils/inc/vghwutils.h Fri Sep 03 10:14:54 2010 +0100
+++ b/guestrendering/vghwutils/inc/vghwutils.h Wed Sep 08 15:45:18 2010 +0100
@@ -92,7 +92,7 @@
class MVgApiForEgl
{
public:
- virtual ExtensionProcPointer platsimGetVgProcAddress (const char *aProcName) = 0;
+ virtual ExtensionProcPointer guestGetVgProcAddress (const char *aProcName) = 0;
};
@@ -100,7 +100,7 @@
class MGles11ApiForEgl
{
public:
- virtual ExtensionProcPointer platsimGetGles11ProcAddress (const char *aProcName) = 0;
+ virtual ExtensionProcPointer guestGetGles11ProcAddress (const char *aProcName) = 0;
};
@@ -108,7 +108,7 @@
class MGles2ApiForEgl
{
public:
- virtual ExtensionProcPointer platsimGetGles2ProcAddress (const char *aProcName) = 0;
+ virtual ExtensionProcPointer guestGetGles2ProcAddress (const char *aProcName) = 0;
};