vghwinterface/vghwutils/inc/vghwutils.h
branchbug235_bringup_0
changeset 51 4f400a6ea71f
parent 30 f204b762818d
child 59 d9b81aebba7b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vghwinterface/vghwutils/inc/vghwutils.h	Wed Oct 06 15:43:10 2010 +0100
@@ -0,0 +1,342 @@
+// 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:
+
+
+#ifndef __VGHWUTILS_H__
+#define __VGHWUTILS_H__
+
+//  Include Files
+#include <e32base.h>	// CBase
+#include <EGL/egl.h>
+#include <VG/openvg.h>
+#include <GLES/gl.h>
+#include "eglrfc.h"
+
+
+class RGuestVideoDriver;
+
+// Virtual Graphics Hardware per thread data: TEglThreadState is concrete, MVgContext & MGlesContext are per API interfaces
+class TEglThreadState;
+class MGlesContext;
+class MVgContext;
+
+// data serialisation packages
+class OpenVgRFC;
+class EglRFC;
+class RemoteFunctionCall;
+class RemoteFunctionCallData;
+
+// tracing
+#ifdef _DEBUG
+	#include <e32debug.h>
+    #define UTIL_TRACE(fmt, args...) RDebug::Printf(fmt, ##args)
+	#define VGHWPANIC_ASSERT(condition, panic) if (!(condition)) { VghwPanic(panic, #panic, #condition, __FILE__, __LINE__); }
+	#define VGHWPANIC_ASSERT_DEBUG(condition, panic) if (!(condition)) { VghwPanic(panic, #panic, #condition, __FILE__, __LINE__); }
+#else
+    #define UTIL_TRACE(fmt, args...)
+	#define VGHWPANIC_ASSERT(condition, panic) if (!(condition)) { VghwPanic(panic, NULL, NULL, NULL, __LINE__); }
+	#define VGHWPANIC_ASSERT_DEBUG(condition, panic)
+#endif
+
+
+// Simulator Virtual Graphics Hardware panic codes
+typedef enum
+	{
+	EVghwPanicNoVideoChannel = 1,
+	EVghwPanicOperationDataTooBig,
+	EVghwPanicDriverOpenError,
+	EVghwPanicVghwHeapDoesNotExist,
+	EVghwPanicInitializeFailed,
+	EVghwPanicGraphicsDriverNotOpen,
+	EVghwPanicSwitchToVghwHeapOldHeapIsVghwHeap,
+	EVghwPanicSwitchFromVghwHeapParamIsNull,
+	EVghwPanicSwitchFromVghwHeapOldHeapIsNotVghwHeap,
+	EVghwPanicSwitchFromVghwHeapParamIsVghwHeap, // 10
+	EVghwPanicGraphicsCreationLockDoesNotExist,
+	EVghwPanicExecuteCommandFailed,
+	EVghwPanicBadVgErrorValue,
+	EVghwPanicBadGlesErrorValue,
+	EVghwPanicBadEglErrorValue,
+	EVghwPanicBadEglBoundApi,
+	} TVghwPanic;
+
+// This panic function is exported to allow inline functions to use it
+IMPORT_C void VghwPanic(TVghwPanic aPanicCode, char* aPanicName, char* aCondition, char* aFile, TInt aLine);
+
+
+// Mix-in class: EGL support functions, including SgImage support, expected to be called by Open VG and Open GL ES
+class MEglManagementApi
+	{
+public:
+	virtual TBool EglImageOpenForVgImage(EGLImageKHR aImage, TSize& aSize, VGHandle& aVgHandle, TUint64& aSgImageId) = 0;
+	virtual void EglImageClose(EGLImageKHR aImage) = 0;
+	// ToDo add an API so that Open VG can query the size of the current Context's surface
+	};
+
+
+typedef void (*ExtensionProcPointer)(...);
+
+
+// Private interfaces for EGL to call into Open VG 
+class MVgApiForEgl
+	{
+public:
+	virtual ExtensionProcPointer guestGetVgProcAddress (const char *aProcName) = 0;
+	};
+
+
+// Private interfaces for EGL to call into Open GL ES 1.1 
+class MGles11ApiForEgl
+	{
+public:
+	virtual ExtensionProcPointer guestGetGles11ProcAddress (const char *aProcName) = 0;
+	};
+
+
+// Private interfaces for EGL to call into Open GL ES 2 
+class MGles2ApiForEgl
+	{
+public:
+	virtual ExtensionProcPointer guestGetGles2ProcAddress (const char *aProcName) = 0;
+	};
+
+
+/*
+ VGHWUtils APIs are static for ease of use by the other Simulator Graphics DLLs.
+
+ One (singleton) instance is created as Writeable Static Data when the DLL is loaded.
+ After initialization this will hold process-wide data - e.g. a memory heap for Graphics DLLs
+ to store local Symbian client state information.
+
+ ToDo maybe make this a Symbian X class because it owns resources, but only as static data.
+ */
+NONSHARABLE_CLASS(CVghwUtils): public CBase
+    {
+	friend class TEglThreadState; // to limit visibility of DriverExecuteCommand
+public:
+	// open Driver connection, create Memory Heap, etc...
+	IMPORT_C static void InitStatics();
+	IMPORT_C static void DestroyStatics();
+
+	IMPORT_C static TInt MapToHWAddress(const TInt aChunkHandle, TUint32& aHWAddress);
+	IMPORT_C static TInt GetSurfaceBufferBaseAddress(TUint32& aHWAddress);
+	IMPORT_C static TInt EglGetSgHandles(const TUint64 aId, TUint64 *aSgHandles);
+
+	// VG Memory Pool APIs (One heap is created for the process, for use by all Simulator Graphics DLLs)
+	IMPORT_C static TAny* Alloc(TInt aSize); 
+	IMPORT_C static void Free(TAny* aPtr);
+	IMPORT_C static RHeap* GetHeap();
+	IMPORT_C static RHeap* SwitchToVghwHeap();
+	IMPORT_C static void SwitchFromVghwHeap(RHeap* aOldHeapPtr);
+	// handy function for Debug Asserts
+	static inline TBool UsingVghwHeap() { return &User::Heap() == GetHeap(); }
+
+	// if this thread does not have a state object try to alloc a new one
+	IMPORT_C static TEglThreadState* CreateThreadState();
+	// current state object, if any, for this thread (for EGL)
+	IMPORT_C static TEglThreadState* EglThreadState();
+	// current state object, if Open VG, for this thread (as tracked by EGL DLL)
+	IMPORT_C static MVgContext* VgContext();
+	// current state object for Open GL ES 1.1, for this thread (as tracked by EGL DLL)
+	IMPORT_C static MGlesContext* GlesContext();
+	// free current state object, if any, for this thread
+	IMPORT_C static void ReleaseThreadState();
+
+	IMPORT_C static void SetEglManagementApi(MEglManagementApi* aEglManagementApi);
+	IMPORT_C static MEglManagementApi* EglManagementApi();
+
+	// Private interfaces for EGL to call into Open GL ES and Open VG (avoids breaking DEF file compatibility) 
+	IMPORT_C static void SetVgApiForEgl(MVgApiForEgl* aVgApiForEgl);
+	IMPORT_C static MVgApiForEgl* VgApiForEgl();
+
+	IMPORT_C static void SetGles11ApiForEgl(MGles11ApiForEgl* aGles11ApiForEgl);
+	IMPORT_C static MGles11ApiForEgl* Gles11ApiForEgl();
+
+	IMPORT_C static void SetGles2ApiForEgl(MGles2ApiForEgl* aGles2ApiForEgl);
+	IMPORT_C static MGles2ApiForEgl* Gles2ApiForEgl();
+
+protected:
+	IMPORT_C static void DriverExecuteCommand(RemoteFunctionCallData& aRequestData);
+
+private:
+	inline static RGuestVideoDriver& Driver();
+
+private:
+	// everything is zeroed on construction, call Initialize() to prepare
+	volatile static TBool iInitialized;    // NB "volatile" used for thread safety in InitStaticse()
+	static TInt           iVghwInitMutex;  // required for thread safety in Initialize()
+
+	// static member objects
+	static RGuestVideoDriver*   iDriver;
+	static RHeap*               iHeap;
+	static MEglManagementApi*   iEglManagementApi;
+	static MVgApiForEgl*        iVgApiForEgl;
+	static MGles11ApiForEgl*    iGles11ApiForEgl;
+	static MGles2ApiForEgl*     iGles2ApiForEgl;
+	static TBool                iLoadedOpenVgDll;
+	static TBool                iLoadedOpenGles11Dll;
+	static TBool                iLoadedOpenGles2Dll;	
+	};
+
+
+// Basic interface for sending GL ES 1.1 commands down to Host Open GL ES implementation - can be expanded later
+class MGlesContext
+	{
+public:
+	// Execute Open GL ES 1.1 commands
+	virtual void ExecuteGlesCommand(RemoteFunctionCall& aGlesRequestData) = 0;
+	virtual void ExecuteGlesFlushCommand() = 0;
+	virtual void ExecuteGlesFinishCommand() = 0;
+	// GLES state
+	virtual void SetGlesError(GLenum aGlesErrorCode) = 0;
+	virtual GLenum GlesError() = 0;
+	// ToDo make context tracking work for VG & GL ES
+	virtual EGLContext GlesEglContext() = 0;
+	};
+
+
+// Basic interface for sending VG commands down to Host Open VG implementation - can be expanded later
+class MVgContext
+	{
+public:
+	// Execute Open VG commands
+	virtual void ExecuteVgCommand(OpenVgRFC& aVgApiData) = 0;
+	virtual void ExecuteVgFlushCommand() = 0;
+	virtual void ExecuteVgFinishCommand() = 0;
+	// VG state
+	virtual void SetVgError(VGErrorCode aVgErrorCode) = 0;
+	virtual VGErrorCode VgError() = 0;
+	virtual EGLContext VgEglContext() = 0;
+	};
+
+
+NONSHARABLE_CLASS(TEglThreadState) : public MGlesContext, public MVgContext
+	{
+	friend class CVghwUtils; // to manage creation / delete of per thread state
+public:
+	// Execute EGL commands, and analyse for success
+	IMPORT_C EGLBoolean ExecEglBooleanCmd(EglRFC& aEglApiData);
+	IMPORT_C EGLContext ExecEglContextCmd(EglRFC& aEglApiData);
+	IMPORT_C EGLSurface ExecEglSurfaceCmd(EglRFC& aEglApiData);
+	// ToDo add static export for eglTerminate
+
+	// Execute EGL commands whose return value cannot be tested for fail/success
+	inline void ExecuteEglNeverErrorCmd(EglRFC& aEglApiData);
+	// EGL thread state
+	inline void ClearEglError();
+	inline void SetEglError(EGLint aEglError);
+	IMPORT_C EGLint EglError();
+	inline void SetEglBoundApi(EGLenum aEglBoundApi);
+	inline EGLenum EglBoundApi();
+	inline EGLint PeekEglError(); // reads DLL set error code (only)
+
+	// MGlesContext: Execute Open GL ES 1.1 commands & manage Open GL ES state
+	virtual void ExecuteGlesCommand(RemoteFunctionCall& aGlesRequestData);
+	virtual void ExecuteGlesFlushCommand();
+	virtual void ExecuteGlesFinishCommand();
+	virtual void SetGlesError(GLenum aGlesErrorCode);
+	virtual GLenum GlesError();
+	virtual EGLContext GlesEglContext();
+
+	// MVgContext: Execute Open VG commands & manage Open VG state
+	virtual void ExecuteVgCommand(OpenVgRFC& aVgApiData);
+	virtual void ExecuteVgFlushCommand();
+	virtual void ExecuteVgFinishCommand();
+	virtual void SetVgError(VGErrorCode aVgErrorCode);
+	virtual VGErrorCode VgError();
+	virtual EGLContext VgEglContext();
+
+protected:
+	static TEglThreadState* New();
+	void Destroy();
+	TEglThreadState();
+	~TEglThreadState();
+
+private:
+	GLenum GetHostGlesError();
+	VGErrorCode GetHostVgError();
+
+private:
+	// EGL thread state
+	EGLint       iEglError;
+	TBool        iEglHostHasRecentError;
+	// currently bound graphics API
+	EGLenum      iEglBoundApi;
+
+	// Open VG context for thread
+	VGErrorCode  iVgError;
+	EGLContext  iVgEglContext;
+	TBool        iVgCommandsSinceGetError;
+	TBool        iVgCommandsSinceFlush;
+	TBool        iVgCommandsSinceFinish;
+
+	// Open GL ES 1.1 context for thread
+	GLenum       iGlesError;
+	EGLContext  iGlesEglContext;
+	TBool        iGlesCommandsSinceGetError;
+	TBool        iGlesCommandsSinceFlush;
+	TBool        iGlesCommandsSinceFinish;
+	};
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// TVghwThreadState inline functions
+
+void TEglThreadState::ClearEglError()
+	{
+	UTIL_TRACE("  TVghwThreadState::ClearEglError");
+	iEglError = EGL_SUCCESS;
+	iEglHostHasRecentError = EFalse;
+	}
+
+
+void TEglThreadState::SetEglError(EGLint aEglError)
+	{
+	UTIL_TRACE("  TVghwThreadState::SetEglError error=0x%x", aEglError);
+	VGHWPANIC_ASSERT_DEBUG((aEglError >= EGL_SUCCESS) && (aEglError <= 0x301F), EVghwPanicBadEglErrorValue);
+	iEglError = aEglError;
+	iEglHostHasRecentError = EFalse;
+	}
+
+
+EGLint TEglThreadState::PeekEglError() // reads DLL set error code
+	{
+	return iEglError;
+	}
+
+
+void TEglThreadState::SetEglBoundApi(EGLenum aEglBoundApi)
+	{
+	VGHWPANIC_ASSERT_DEBUG((aEglBoundApi == EGL_OPENGL_ES_API) || (aEglBoundApi == EGL_OPENVG_API), EVghwPanicBadEglBoundApi);
+	iEglBoundApi = aEglBoundApi;
+	}
+
+
+EGLenum TEglThreadState::EglBoundApi()
+	{
+	return iEglBoundApi;
+	}
+
+// Execute EGL Command simple variants
+
+void TEglThreadState::ExecuteEglNeverErrorCmd(EglRFC& aEglApiData)
+	{ // for EGL commands which cannot have a host error
+	CVghwUtils::DriverExecuteCommand(aEglApiData.Data());
+	iEglHostHasRecentError = EFalse;
+	iEglError = EGL_SUCCESS;
+	}
+
+#endif  // __VGHWUTILS_H__