egl/egltest/src/egltestcommonsession.cpp
changeset 0 5d03bc08d59c
child 18 5e30ef2e26cb
child 36 01a6848ebfd7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/egltest/src/egltestcommonsession.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,2093 @@
+// Copyright (c) 2007-2009 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:
+//
+
+/**
+ @file
+ @test 
+*/
+
+#include "egltestcommonsession.h"
+#include "egltestcommonutils.h"
+#include "egltestcommonsgimageinfo.h"
+
+#include <test/tefunit.h>
+#include <e32cmn.h>
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+#include <sgresource/sgresource.h>
+#else
+#include <graphics/sgresourceinternal.h>
+#include <graphics/sgresource.h>
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+#include <VG/openvg.h>
+#include <GLES/gl.h>
+
+
+#define	CHECK_EXPECTED_ERROR(aFunctionReturnValue) \
+	if(!(CheckExpectedError(aFunctionReturnValue))) \
+		{ \
+		ERR_PRINTF2(_L("thread %d: Unexpected EGL error information"), iThreadIdx); \
+		User::Leave(KErrTEFUnitFail); \
+		}
+
+const TMapEglConfigToPixelFormat KMapEglConfigToPixelFormat[] =
+	{
+	{16, 0, 5,6,5, 0, 							EGL_RGB_BUFFER, EUidPixelFormatRGB_565, EColor64K},
+	{32, 0, 8,8,8, 0,							EGL_RGB_BUFFER, EUidPixelFormatXRGB_8888, EColor16MU},
+    {32, 8, 8,8,8, EGL_VG_ALPHA_FORMAT_NONPRE, 	EGL_RGB_BUFFER, EUidPixelFormatARGB_8888, EColor16MA},
+	{32, 8, 8,8,8, EGL_VG_ALPHA_FORMAT_PRE, 	EGL_RGB_BUFFER, EUidPixelFormatARGB_8888_PRE, EColor16MAP}
+	};
+
+EXPORT_C CTestEglSession::CTestEglSession(CTestExecuteLogger& aLogger, EGLDisplay& aDisplay, TInt aThreadIdx)
+	: iLogger(aLogger), iThreadIdx(aThreadIdx), iExtensionGroupCached(EIsUndefined), iDisplay(aDisplay), iExpectedErrorCode(EGL_SUCCESS)
+	{}
+
+EXPORT_C CTestEglSession* CTestEglSession::NewLC(CTestExecuteLogger& aLogger, EGLDisplay& aDisplay, TInt aThreadIdx)
+	{
+	CTestEglSession* self = new (ELeave) CTestEglSession(aLogger, aDisplay, aThreadIdx);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+EXPORT_C CTestEglSession* CTestEglSession::NewL(CTestExecuteLogger& aLogger, EGLDisplay& aDisplay, TInt aThreadIdx)
+	{
+	CTestEglSession* self = CTestEglSession::NewLC(aLogger, aDisplay, aThreadIdx);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CTestEglSession::~CTestEglSession()
+	{
+	iExtensionStrings.Reset();
+	EGLBoolean ret;
+	if (iDisplay != EGL_NO_DISPLAY)
+		{
+		// Unbind and destroy context only if we successfuly created it
+		if (iContext != EGL_NO_CONTEXT)
+		    {
+            INFO_PRINTF2(_L("thread %d: Calling eglMakeCurrent(NULL values) from ~CTestEglSession..."), iThreadIdx);
+            ret = eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+            if(ret == EGL_FALSE)
+                {
+                WARN_PRINTF3(_L("thread %d: eglMakeCurrent returned error = %x ~CTestEglSession..."), iThreadIdx, eglGetError());
+                }
+            
+            // Warn because this should be done by the test, rather than relying on the d'tor
+            // which may not leave if there is an error (so no CHECK_EXPECTED_ERROR)
+            WARN_PRINTF2(_L("thread %d: Calling eglDestroyContext() from ~CTestEglSession..."), iThreadIdx);
+            ret = eglDestroyContext(iDisplay, iContext);
+            if(ret == EGL_FALSE)
+                {
+                WARN_PRINTF3(_L("thread %d: eglDestroyContext returned error = %x ~CTestEglSession..."), iThreadIdx, eglGetError());
+                }   
+		    }
+
+		if (iSurface != EGL_NO_SURFACE)
+			{
+			// Warn because this should be done by the test, rather than relying on the d'tor
+			// which may not leave if there is an error (so no CHECK_EXPECTED_ERROR)
+			WARN_PRINTF2(_L("thread %d: Calling eglDestroySurface() from ~CTestEglSession..."), iThreadIdx);
+			ret = eglDestroySurface(iDisplay, iSurface);
+			if(ret == EGL_FALSE)
+				{
+				WARN_PRINTF3(_L("thread %d: eglDestroySurface returned error = %x ~CTestEglSession..."), iThreadIdx, eglGetError());
+				}	
+			}
+		
+		if (iTerminateDisplay)
+			{
+			INFO_PRINTF1(_L("Calling eglTerminate..."));
+			ret = eglTerminate(iDisplay);
+			iDisplay = EGL_NO_DISPLAY;
+			if(ret == EGL_FALSE)
+				{
+				WARN_PRINTF3(_L("thread %d: eglTerminate returned error = %x ~CTestEglSession..."), iThreadIdx, eglGetError());
+				}	
+			}
+		}
+
+	// Only destroy native resource after the surface and context that wraps it has been destroyed.
+	delete iFbsBitmap;
+	CloseFbsSession();
+	
+	iSgImage.Close();
+	CloseSgDriver();
+	}
+
+EXPORT_C void CTestEglSession::SetExpectedError(EGLint aExpectedErrorCode)
+	{
+	VERBOSE_INFO_PRINTF3(_L("thread %d: Setting the expected error code for the next EGL call to %x"), iThreadIdx, aExpectedErrorCode);
+		{
+		iExpectedErrorCode = aExpectedErrorCode; 
+		}
+	}
+
+EXPORT_C void CTestEglSession::ResetExpectedError()
+	{
+	iExpectedErrorCode = EGL_SUCCESS;
+	}
+
+/**
+Checks whether the call to an EGL method returned the correct error information.
+The method checks whether eglGetError() returns the expected error value as specified by calling SetExpectedError()
+It also checks that the value returned by the EGL method was appropriate for the expected error value.
+@param aFunctionReturnValue Pass in the value retured from the EGL method
+@return Whether the expected error information was returned from a call to an EGL method.
+*/
+EXPORT_C TBool CTestEglSession::CheckExpectedError(EGLint aFunctionReturnValue)
+	{
+	TBool isExpectedError = ETrue;
+	EGLint eglErr = eglGetError();
+	
+	// First check that we got the correct return value
+	if ((iExpectedErrorCode == EGL_SUCCESS) && !aFunctionReturnValue)
+		{
+		ERR_PRINTF3(_L("thread %d: Wrong function return value: %d"), iThreadIdx, aFunctionReturnValue);
+		isExpectedError = EFalse;
+		}
+	// Also check that we got the 
+	if (eglErr != iExpectedErrorCode) 
+		{
+		ERR_PRINTF4(_L("thread %d: eglGetError() returned %x, but expected %x"), iThreadIdx, eglErr, iExpectedErrorCode);
+		isExpectedError = EFalse;
+		}
+	else if (eglErr != EGL_SUCCESS)
+		{
+		VERBOSE_INFO_PRINTF3(_L("thread %d: eglGetError() returned %x, as expected"), iThreadIdx, eglErr);
+		}
+	
+	// Reset the expected error
+	ResetExpectedError();
+	
+	return isExpectedError;
+	}
+
+EXPORT_C void CTestEglSession::CheckExpectedErrorL(EGLint aExpectedErrorCode)
+	{
+	EGLint eglErr = eglGetError();	
+	// check that we got the expected error
+	if (eglErr != aExpectedErrorCode) 
+		{
+		ERR_PRINTF4(_L("thread %d: eglGetError() returned %x, but expected %x"), iThreadIdx, eglErr, aExpectedErrorCode);
+		User::Leave(KErrTEFUnitFail);
+		}
+	}
+
+void CTestEglSession::QueryExtensionsL(TExtensionsGroups aExtensionBelongsTo)
+	{
+	// reset the cached extensions
+	iExtensionStrings.Reset();
+	
+	const char* extensionsString = NULL;
+	if(aExtensionBelongsTo == EIsEGL)
+		{
+		INFO_PRINTF2(_L("thread %d: Calling eglQueryString for EGL_EXTENSIONS)"), iThreadIdx);
+		extensionsString = eglQueryString(iDisplay, EGL_EXTENSIONS);
+		}
+	else if(aExtensionBelongsTo == EIsVG)
+		{	
+		INFO_PRINTF2(_L("thread %d: Calling vgGetString for VG_EXTENSIONS)"), iThreadIdx);
+
+		// OpenVG needs a current VG context before it will allow the call to vgGetString
+		TSgImageInfoOpenVgTarget imageInfo;
+		imageInfo.iSizeInPixels = KPixmapSize;
+		imageInfo.iPixelFormat = EUidPixelFormatXRGB_8888;
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+		imageInfo.iUsage = ESgUsageBitOpenVgSurface;
+#else
+        imageInfo.iUsage = ESgUsageOpenVgTarget;
+#endif		
+		CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
+
+		extensionsString = (const char*) vgGetString(VG_EXTENSIONS);
+
+		//cleanup the context & surface
+		CleanupSurfaceSgImageL();
+		}
+	else
+		{
+		ERR_PRINTF2(_L("CTestEglSession::QueryExtensionsL() - Unknown extension group provided (%d)."), aExtensionBelongsTo);
+		User::Leave(KErrArgument);
+		}
+	CHECK_EXPECTED_ERROR(extensionsString!=NULL);	
+	
+	TPtrC8 ptrExtensions((const TUint8 *) extensionsString );
+	TBuf16<128> bufExtensions;
+	bufExtensions.Copy(ptrExtensions.Left(128));
+	INFO_PRINTF3(_L("thread %d: QueryExtensionsL: \"%S\""), iThreadIdx, &bufExtensions);
+	
+	TInt posSpace=1;
+	while (posSpace > 0 && ptrExtensions.Length() > 0)
+		{
+		posSpace = ptrExtensions.Locate(' '); // strictly looking for a single space
+		ASSERT_FALSE(posSpace==0); // Would imply extension starting with a space or with 2 spaces in a row
+		if (posSpace > 0)
+			{
+			iExtensionStrings.Append(ptrExtensions.Left(posSpace));
+			if (posSpace <= ptrExtensions.Length())
+				{
+				ptrExtensions.Set(ptrExtensions.Mid(posSpace+1));
+				}
+			}
+		else
+			{
+			iExtensionStrings.Append(ptrExtensions);
+			}
+		} 
+	}
+
+TBool CTestEglSession::FindExtensionStringL(TExtensionsGroups aExtensionBelongsTo, const TDesC8& aExtensionString)
+	{
+	//Load the extensions for this group if not already cached
+	if (iExtensionGroupCached != aExtensionBelongsTo)
+		{
+		QueryExtensionsL(aExtensionBelongsTo); // Load extension info
+		iExtensionGroupCached = aExtensionBelongsTo;
+		}
+	
+	TInt countExtensionStrings = iExtensionStrings.Count();
+	for(TUint i=0; i<countExtensionStrings; i++)
+		{
+		if (iExtensionStrings[i].Compare(aExtensionString)==0)
+			{
+			// We have a match!
+			return ETrue;
+			}
+		}
+
+	// No match: copy the extension string into a 16 bit buffer for logging
+	const TInt KBufLenMissingExtension=128;
+	TBuf16<KBufLenMissingExtension> bufMissingExtension16;
+	bufMissingExtension16.Copy(aExtensionString.Left(KBufLenMissingExtension));
+	
+	WARN_PRINTF2(_L("EGL extension missing: [%S]"), &bufMissingExtension16);
+	return EFalse;
+	}
+
+/**
+ Converts from TRgb space to Vg floating point colour
+ */
+EXPORT_C void CTestEglSession::ConvertColor(const TRgb& aSource, VGfloat* aTarget)
+//static
+	{
+	aTarget[0] = (VGfloat)aSource.Red() / 255.f;
+	aTarget[1] = (VGfloat)aSource.Green() / 255.f;
+	aTarget[2] = (VGfloat)aSource.Blue() / 255.f;
+	aTarget[3] = (VGfloat)aSource.Alpha() / 255.f;
+	}
+
+/** Breakpoint to manually view available configs while debugging */
+EXPORT_C void CTestEglSession::ViewConfigsL()
+	{
+	EGLConfig configs[KMaxEglConfigs];
+	EGLint numConfigs=0;
+
+	// Query number of configs available
+	INFO_PRINTF1(_L("Calling eglGetConfigs to get the number of configs available..."));
+	CHECK_EXPECTED_ERROR(eglGetConfigs(iDisplay, NULL, KMaxTInt, &numConfigs));
+
+	INFO_PRINTF1(_L("Checking number of configs..."));
+	ASSERT_TRUE(numConfigs >= 1);
+	INFO_PRINTF2(_L("Found %d configs"), numConfigs);
+	
+	// Get the configs
+	INFO_PRINTF1(_L("Calling eglGetConfigs to get configs..."));
+	CHECK_EXPECTED_ERROR(eglGetConfigs(iDisplay, configs, KMaxEglConfigs, &numConfigs));
+	
+	for(TUint index = 0; index < numConfigs; index++)
+		{
+		EGLint EGL_BUFFER_SIZE_value;
+		EGLint EGL_ALPHA_SIZE_value;
+		EGLint EGL_BLUE_SIZE_value;
+		EGLint EGL_GREEN_SIZE_value;
+		EGLint EGL_RED_SIZE_value;
+#ifdef PRINT_ALL_CONFIGS_DETAILS
+		EGLint EGL_DEPTH_SIZE_value;
+		EGLint EGL_STENCIL_SIZE_value;
+		EGLint EGL_CONFIG_CAVEAT_value;
+		EGLint EGL_CONFIG_ID_value;
+		EGLint EGL_LEVEL_value;
+		EGLint EGL_MAX_PBUFFER_HEIGHT_value;
+		EGLint EGL_MAX_PBUFFER_PIXELS_value;
+		EGLint EGL_MAX_PBUFFER_WIDTH_value;
+		EGLint EGL_NATIVE_RENDERABLE_value;
+		EGLint EGL_NATIVE_VISUAL_ID_value;
+		EGLint EGL_NATIVE_VISUAL_TYPE_value;
+		EGLint EGL_SAMPLES_value;
+		EGLint EGL_SAMPLE_BUFFERS_value;
+#endif
+		EGLint EGL_SURFACE_TYPE_value;
+#ifdef PRINT_ALL_CONFIGS_DETAILS
+		EGLint EGL_TRANSPARENT_TYPE_value;
+		EGLint EGL_TRANSPARENT_BLUE_VALUE_value;
+		EGLint EGL_TRANSPARENT_GREEN_VALUE_value;
+		EGLint EGL_TRANSPARENT_RED_VALUE_value;
+		EGLint EGL_BIND_TO_TEXTURE_RGB_value;
+		EGLint EGL_BIND_TO_TEXTURE_RGBA_value;
+		EGLint EGL_MIN_SWAP_INTERVAL_value;
+		EGLint EGL_MAX_SWAP_INTERVAL_value;
+		EGLint EGL_LUMINANCE_SIZE_value;
+		EGLint EGL_ALPHA_MASK_SIZE_value;
+		EGLint EGL_COLOR_BUFFER_TYPE_value;
+#endif
+		EGLint EGL_RENDERABLE_TYPE_value;
+
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_BUFFER_SIZE, &EGL_BUFFER_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_ALPHA_SIZE, &EGL_ALPHA_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_BLUE_SIZE, &EGL_BLUE_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_GREEN_SIZE, &EGL_GREEN_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_RED_SIZE, &EGL_RED_SIZE_value);
+#ifdef PRINT_ALL_CONFIGS_DETAILS
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_DEPTH_SIZE, &EGL_DEPTH_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_STENCIL_SIZE, &EGL_STENCIL_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_CONFIG_CAVEAT, &EGL_CONFIG_CAVEAT_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_CONFIG_ID, &EGL_CONFIG_ID_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_LEVEL, &EGL_LEVEL_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_MAX_PBUFFER_HEIGHT, &EGL_MAX_PBUFFER_HEIGHT_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_MAX_PBUFFER_PIXELS, &EGL_MAX_PBUFFER_PIXELS_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_MAX_PBUFFER_WIDTH, &EGL_MAX_PBUFFER_WIDTH_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_NATIVE_RENDERABLE, &EGL_NATIVE_RENDERABLE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_NATIVE_VISUAL_ID, &EGL_NATIVE_VISUAL_ID_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_NATIVE_VISUAL_TYPE, &EGL_NATIVE_VISUAL_TYPE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_SAMPLES, &EGL_SAMPLES_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_SAMPLE_BUFFERS, &EGL_SAMPLE_BUFFERS_value);
+#endif
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_SURFACE_TYPE, &EGL_SURFACE_TYPE_value);
+#ifdef PRINT_ALL_CONFIGS_DETAILS
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_TRANSPARENT_TYPE, &EGL_TRANSPARENT_TYPE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_TRANSPARENT_BLUE_VALUE, &EGL_TRANSPARENT_BLUE_VALUE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_TRANSPARENT_GREEN_VALUE, &EGL_TRANSPARENT_GREEN_VALUE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_TRANSPARENT_RED_VALUE, &EGL_TRANSPARENT_RED_VALUE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_BIND_TO_TEXTURE_RGB, &EGL_BIND_TO_TEXTURE_RGB_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_BIND_TO_TEXTURE_RGBA, &EGL_BIND_TO_TEXTURE_RGBA_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_MIN_SWAP_INTERVAL, &EGL_MIN_SWAP_INTERVAL_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_MAX_SWAP_INTERVAL, &EGL_MAX_SWAP_INTERVAL_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_LUMINANCE_SIZE, &EGL_LUMINANCE_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_ALPHA_MASK_SIZE, &EGL_ALPHA_MASK_SIZE_value);
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_COLOR_BUFFER_TYPE, &EGL_COLOR_BUFFER_TYPE_value);
+#endif
+		eglGetConfigAttrib(iDisplay, configs[index], EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value);
+
+		TBool good = ETrue;
+
+		INFO_PRINTF7(_L("(idx: %3d) RGBA=(%2d) %2d,%2d,%2d,%2d"), index, EGL_BUFFER_SIZE_value, 
+				EGL_RED_SIZE_value, EGL_GREEN_SIZE_value, EGL_BLUE_SIZE_value, 
+				EGL_ALPHA_SIZE_value);
+		if (!(EGL_RED_SIZE_value == 8 && EGL_GREEN_SIZE_value == 8 && EGL_BLUE_SIZE_value == 8 && EGL_ALPHA_SIZE_value == 0))
+			{
+			continue;
+			}
+		
+		INFO_PRINTF2(_L("\n\n^^^^^^ CONFIG [%d] VALUES ******"), index);
+		if (EGL_SURFACE_TYPE_value & EGL_PIXMAP_BIT)
+			{
+			INFO_PRINTF2(_L("EGL_SURFACE_TYPE=%d. <<< Has EGL_PIXMAP_BIT"), EGL_SURFACE_TYPE_value);
+			}
+		else
+			{
+			INFO_PRINTF2(_L("EGL_SURFACE_TYPE=%d. <<< BAD (not pixmap)"), EGL_SURFACE_TYPE_value);
+			good = EFalse;
+			}
+		
+		if (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)
+			{
+			INFO_PRINTF2(_L("EGL_RENDERABLE_TYPE=%d. <<< Has EGL_OPENVG_BIT"), EGL_RENDERABLE_TYPE_value);
+			}
+		else
+			{
+			INFO_PRINTF2(_L("EGL_RENDERABLE_TYPE=%d. <<< BAD (not open vg)"), EGL_RENDERABLE_TYPE_value);
+			good = EFalse;
+			}
+		
+		if (good)
+			{
+			INFO_PRINTF1(_L("^^^^^^^ GOOD ^^^^^^^"));
+			}
+
+#ifdef PRINT_ALL_CONFIGS_DETAILS
+		INFO_PRINTF2(_L("\n\n***** CONFIG [%d] VALUES ******"), index);
+		INFO_PRINTF2(_L("EGL_BUFFER_SIZE=%d."), EGL_BUFFER_SIZE_value);
+		INFO_PRINTF2(_L("EGL_ALPHA_SIZE=%d."), EGL_ALPHA_SIZE_value);
+		INFO_PRINTF2(_L("EGL_BLUE_SIZE=%d."), EGL_BLUE_SIZE_value);
+		INFO_PRINTF2(_L("EGL_GREEN_SIZE=%d."), EGL_GREEN_SIZE_value);
+		INFO_PRINTF2(_L("EGL_RED_SIZE=%d."), EGL_RED_SIZE_value);
+		INFO_PRINTF2(_L("EGL_DEPTH_SIZE=%d."), EGL_DEPTH_SIZE_value);
+		INFO_PRINTF2(_L("EGL_STENCIL_SIZE=%d."), EGL_STENCIL_SIZE_value);
+		INFO_PRINTF2(_L("EGL_CONFIG_CAVEAT=%d."), EGL_CONFIG_CAVEAT_value);
+		INFO_PRINTF2(_L("EGL_CONFIG_ID=%d."), EGL_CONFIG_ID_value);
+		INFO_PRINTF2(_L("EGL_LEVEL=%d."), EGL_LEVEL_value);
+		INFO_PRINTF2(_L("EGL_MAX_PBUFFER_HEIGHT=%d."), EGL_MAX_PBUFFER_HEIGHT_value);
+		INFO_PRINTF2(_L("EGL_MAX_PBUFFER_PIXELS=%d."), EGL_MAX_PBUFFER_PIXELS_value);
+		INFO_PRINTF2(_L("EGL_MAX_PBUFFER_WIDTH=%d."), EGL_MAX_PBUFFER_WIDTH_value);
+		INFO_PRINTF2(_L("EGL_NATIVE_RENDERABLE=%d."), EGL_NATIVE_RENDERABLE_value);
+		INFO_PRINTF2(_L("EGL_NATIVE_VISUAL_ID=%d."), EGL_NATIVE_VISUAL_ID_value);
+		INFO_PRINTF2(_L("EGL_NATIVE_VISUAL_TYPE=%d."), EGL_NATIVE_VISUAL_TYPE_value);
+		INFO_PRINTF2(_L("EGL_SAMPLES=%d."), EGL_SAMPLES_value);
+		INFO_PRINTF2(_L("EGL_SAMPLE_BUFFERS=%d."), EGL_SAMPLE_BUFFERS_value);
+		INFO_PRINTF2(_L("EGL_SURFACE_TYPE=%d."), EGL_SURFACE_TYPE_value);
+		INFO_PRINTF2(_L("EGL_TRANSPARENT_TYPE=%d."), EGL_TRANSPARENT_TYPE_value);
+		INFO_PRINTF2(_L("EGL_TRANSPARENT_BLUE_VALUE=%d."), EGL_TRANSPARENT_BLUE_VALUE_value);
+		INFO_PRINTF2(_L("EGL_TRANSPARENT_GREEN_VALUE=%d."), EGL_TRANSPARENT_GREEN_VALUE_value);
+		INFO_PRINTF2(_L("EGL_TRANSPARENT_RED_VALUE=%d."), EGL_TRANSPARENT_RED_VALUE_value);
+		INFO_PRINTF2(_L("EGL_BIND_TO_TEXTURE_RGB=%d."), EGL_BIND_TO_TEXTURE_RGB_value);
+		INFO_PRINTF2(_L("EGL_BIND_TO_TEXTURE_RGBA=%d."), EGL_BIND_TO_TEXTURE_RGBA_value);
+		INFO_PRINTF2(_L("EGL_MIN_SWAP_INTERVAL=%d."), EGL_MIN_SWAP_INTERVAL_value);
+		INFO_PRINTF2(_L("EGL_MAX_SWAP_INTERVAL=%d."), EGL_MAX_SWAP_INTERVAL_value);
+		INFO_PRINTF2(_L("EGL_LUMINANCE_SIZE=%d."), EGL_LUMINANCE_SIZE_value);
+		INFO_PRINTF2(_L("EGL_ALPHA_MASK_SIZE=%d."), EGL_ALPHA_MASK_SIZE_value);
+		INFO_PRINTF2(_L("EGL_COLOR_BUFFER_TYPE=%d."), EGL_COLOR_BUFFER_TYPE_value);
+		INFO_PRINTF2(_L("EGL_RENDERABLE_TYPE=%d."), EGL_RENDERABLE_TYPE_value);
+		INFO_PRINTF2(_L("\n*********************************\n\n"), index);
+#endif
+		}
+	}
+
+EXPORT_C static TEglConfigMatchType GetMatchType(EGLint aAttrib, TEglConfigMatchRule aMatchRule)
+	{
+	const TConfigMatchRuleItem* curMatchRuleItem = KConfigMatchRules[aMatchRule];
+			
+	while(curMatchRuleItem->iAttrib != EGL_NONE)
+		{
+		if (aAttrib == curMatchRuleItem->iAttrib)
+			{
+			return curMatchRuleItem->iMatchType;
+			}
+		curMatchRuleItem++;
+		}
+
+	RDebug::Printf("Unknown attrib %x", aAttrib);
+	return eMatchUnknown;
+	}
+
+/**
+ Returns the first index of a config that matches the requested config extactly
+ */
+TInt CTestEglSession::GetFullMatchConfigIndex(EGLDisplay aDisplay, EGLConfig *aConfigs, TInt aNumConfigs, 
+											  const EGLint aWantedAttribs[], TEglConfigMatchRule aMatchRule)
+	{
+	EGLint value=0;
+	for(TUint idxConfig=0; idxConfig<aNumConfigs; idxConfig++)
+		{
+		const EGLint *curAttrib = aWantedAttribs;
+		TBool match = ETrue;
+		
+		while(*curAttrib != EGL_NONE && match)
+			{
+			ASSERT_EGL_TRUE(eglGetConfigAttrib(aDisplay, aConfigs[idxConfig], *curAttrib, &value));
+
+			switch(GetMatchType(*curAttrib, aMatchRule))
+				{
+				case eMatchEqual:
+					if (value != curAttrib[1])
+						{
+						match = EFalse;
+						}		
+					break;
+				case eMatchAtLeast:
+					if (value < curAttrib[1])   // Note, we detect "failure to match", hence "<" not ">="!
+						{
+						match = EFalse;
+						}
+					break;
+				case eMatchBitMask:
+					if ((value & curAttrib[1]) != curAttrib[1])
+						{
+						match = EFalse;
+						}
+					break;
+				case eMatchAlways:
+				    break;
+				    
+				default:
+					// We should not get here.
+				    ASSERT(FALSE); 
+				    break;
+				}
+			curAttrib += 2;
+			}
+		
+		// If we get here with match set, we have matched all attributes, and have found a match. 
+		if (match) 
+			{
+			return idxConfig;
+			}
+		}
+	return KErrNotFound;
+	}
+
+TInt CTestEglSession::ConfigToPixelFormatTableLength() const
+	{
+	return sizeof(KMapEglConfigToPixelFormat) / sizeof(TMapEglConfigToPixelFormat);
+	}
+
+const TMapEglConfigToPixelFormat& CTestEglSession::ConfigToPixelFormatTable(TInt aIndex) const
+	{
+	return KMapEglConfigToPixelFormat[aIndex];
+	}
+
+/**
+ Returns pixel format inforamtion for a given EGL config.
+ @param aConfig The EGL config for which pixel format information will be returned.
+ @return A pointer to the pixel format information for the given EGL config.  
+         Tf the config cannot be mapped, then NULL is returned.
+ */
+EXPORT_C const TMapEglConfigToPixelFormat* CTestEglSession::GetPixelFormatFromEglConfigL(EGLConfig aConfig)
+	{
+	EGLint bufferSize=0;
+	EGLint alphaSize=0;
+	EGLint redSize=0;
+	EGLint greenSize=0;
+	EGLint blueSize=0;
+	EGLint colorBufferType=0;
+	EGLint surfaceType = 0;
+
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_BUFFER_SIZE, &bufferSize));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_ALPHA_SIZE, &alphaSize));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_RED_SIZE, &redSize));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_GREEN_SIZE, &greenSize));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_BLUE_SIZE, &blueSize));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_COLOR_BUFFER_TYPE, &colorBufferType));
+	CHECK_EXPECTED_ERROR(eglGetConfigAttrib(iDisplay, aConfig, EGL_SURFACE_TYPE, &surfaceType));
+
+	INFO_PRINTF7(_L(">>>>> Config info: %d, %d, %d,%d,%d, 0x%x"), bufferSize, alphaSize, redSize, greenSize, blueSize, colorBufferType);
+	
+	for(TUint i=0; i<ConfigToPixelFormatTableLength(); i++)
+		{
+		if ((ConfigToPixelFormatTable(i).iBufferSize == bufferSize)
+				&& (ConfigToPixelFormatTable(i).iAlphaSize == alphaSize)
+				&& (ConfigToPixelFormatTable(i).iRedSize == redSize)
+				&& (ConfigToPixelFormatTable(i).iGreenSize == greenSize)
+				&& (ConfigToPixelFormatTable(i).iBlueSize == blueSize)
+				&& (ConfigToPixelFormatTable(i).iColorBufferType == colorBufferType)
+				&& ((ConfigToPixelFormatTable(i).iSurfaceTypeFlags & surfaceType) == ConfigToPixelFormatTable(i).iSurfaceTypeFlags))
+			{
+			return &ConfigToPixelFormatTable(i);
+			}
+		}
+
+	return NULL;
+	}
+
+EXPORT_C void CTestEglSession::CleanupSurfaceFbsBitmapL()
+	{
+	CleanupSurfaceAndContextL();
+
+	delete iFbsBitmap;
+	iFbsBitmap = NULL;
+	}
+
+EXPORT_C void CTestEglSession::CleanupSurfaceAndContextL()
+	{
+	ASSERT_TRUE(iSurface != EGL_NO_SURFACE);
+	ASSERT_TRUE(iContext != EGL_NO_CONTEXT);
+
+	// Clean up
+	INFO_PRINTF1(_L("Calling eglMakeCurrent(NULL values)..."));
+	CHECK_EXPECTED_ERROR(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+	INFO_PRINTF1(_L("Calling eglDestroyContext()..."));
+	CHECK_EXPECTED_ERROR(eglDestroyContext(iDisplay, iContext));
+	iContext = EGL_NO_CONTEXT;
+
+	INFO_PRINTF1(_L("Calling eglDestroySurface()..."));
+	CHECK_EXPECTED_ERROR(eglDestroySurface(iDisplay, iSurface));
+	iSurface = EGL_NO_SURFACE;
+	}
+
+EXPORT_C CFbsBitmap* CTestEglSession::NativeFbsBitmap()
+	{
+	return iFbsBitmap;
+	}
+
+EXPORT_C RSgImage& CTestEglSession::NativeSgImage()
+	{
+	return iSgImage;
+	}
+
+EXPORT_C EGLSurface CTestEglSession::Surface() const
+	{
+	return iSurface;
+	}
+
+EXPORT_C EGLContext CTestEglSession::Context() const
+	{
+	return iContext;
+	}
+
+EXPORT_C EGLConfig CTestEglSession::GetConfigExactMatchL(TEglTestConfig aConfigAttribIndex, TEglConfigMatchRule aMatchRule)
+	{
+	if(aConfigAttribIndex >= EEglTestConfigMax )
+		{
+		ERR_PRINTF1(_L("Attribute index out of range, please check the INI file"));
+		User::Leave(KErrArgument);
+		}
+	
+	EGLConfig configs[KMaxEglConfigs];
+	EGLint numConfigs=0;
+	ASSERT_EGL_TRUE(eglChooseConfig(iDisplay, KConfigAttribs[aConfigAttribIndex], configs, KMaxEglConfigs, &numConfigs));
+	if (numConfigs <= 0)
+		{
+		// we just WARN, as we don't know if this is expected yet (if it is, then catch the leaving error)
+		WARN_PRINTF1(_L("GetConfigExactMatchL - Could not find a matching config, eglChooseConfig returned 0 configs!"));
+		User::Leave(KTestNoMatchingConfig);
+		}
+	
+	// Check that any of the configs returned matches the desired attributes
+	TInt match = GetFullMatchConfigIndex(iDisplay, configs, numConfigs, KConfigAttribs[aConfigAttribIndex], aMatchRule);
+	if (match == KErrNotFound)
+		{
+		// we just WARN, as we don't know if this is expected yet (if it is, then catch the leaving error)
+		WARN_PRINTF1(_L("GetConfigExactMatchL - Could not find a matching config amongst those returned by eglChooseConfig!"));
+		User::Leave(KTestNoMatchingConfig);
+		}
+	return configs[match];
+	}
+
+/**
+Creates a pixmap surface from a CFbsBitmap, draws to it and checks that the drawing operation succeeded.
+*/
+EXPORT_C void CTestEglSession::TryUsePixmapCFbsBitmapL()
+	{
+	INFO_PRINTF2(_L("thread %d: TryUsePixmapCFbsBitmapL"), iThreadIdx);
+	EGLConfig currentConfig = GetConfigExactMatchL(EPixmapAttribsColor64K);
+	TryUsePixmapCFbsBitmapOpenVgL(currentConfig, KPixmapSize, EColor64K);
+	}
+
+/**
+Creates a pixmap surface from a CFbsBitmap, draws to it and checks that the drawing operation succeeded.
+*/
+EXPORT_C void CTestEglSession::TryUsePixmapCFbsBitmapOpenVgL(EGLConfig aConfig, const TSize& aSize, TDisplayMode aDisplayMode)
+	{
+	CreatePixmapSurfaceAndMakeCurrentL(aConfig, aSize, aDisplayMode);
+	DrawOpenVgL();
+	
+	// Wait for the drawing to complete
+	eglWaitClient();
+	
+	CheckImageDataL(iFbsBitmap);
+	CheckImageDataVgL(VG_sRGB_565);
+	CleanupSurfaceFbsBitmapL();
+	CloseFbsSession();
+	}
+
+/**
+Creates a pixmap surface from a CFbsBitmap, draws to it and checks that the drawing operation succeeded.
+*/
+EXPORT_C void CTestEglSession::TryUsePixmapCFbsBitmapOpenGlesL(EGLConfig aConfig, const TSize& aSize, TDisplayMode aDisplayMode, TInt aRenderVersion)
+	{
+	CreatePixmapSurfaceAndMakeCurrentL(aConfig, aSize, aDisplayMode,EGL_OPENGL_ES_API, aRenderVersion);
+	DrawOpenGLesL();
+	
+	// Wait for the drawing to complete
+	eglWaitClient();
+	
+	CheckImageDataFullRedishL(iFbsBitmap);
+	CleanupSurfaceFbsBitmapL();
+	CloseFbsSession();
+	}
+
+/**
+ Creates a pixmap surface from a RSgImage, draws to it and checks that the drawing operation succeeded.
+ */
+EXPORT_C void CTestEglSession::TryUsePixmapRSgImageL()
+	{
+	INFO_PRINTF2(_L("thread %d: TryUsePixmapRSgImageL"), iThreadIdx);
+	TSgImageInfo imageInfo;
+	imageInfo.iSizeInPixels = KPixmapSize;
+	imageInfo.iPixelFormat = EUidPixelFormatXRGB_8888;
+	// will draw to and read from the image using OpenVg
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE	
+	imageInfo.iUsage = ESgUsageBitOpenVgSurface | ESgUsageBitOpenVgImage;
+#else
+    // will also read from the image using DirectGdi
+    imageInfo.iUsage = ESgUsageOpenVgTarget | ESgUsageDirectGdiSource;
+    imageInfo.iShareable = EFalse;
+    imageInfo.iCpuAccess = ESgCpuAccessNone;
+    imageInfo.iScreenId = KSgScreenIdMain;
+    imageInfo.iUserAttributes = NULL;
+    imageInfo.iUserAttributeCount=0;
+#endif
+	CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo, EResourceCloseSgImageLate);
+	DrawOpenVgL();
+	            
+	// Wait for the drawing to complete
+	 eglWaitClient();
+	    
+	//we can't retrieve data directly from the SgImage as 
+	//non-unified architecture doesn't allow readback from the GPU
+	CheckImageDataVgL(VG_sXRGB_8888);
+	CleanupSurfaceSgImageL();
+	CloseSgDriver();
+	}
+
+EXPORT_C TBool CTestEglSession::TryUsePixmapRSgImageOpenGlesL(EGLConfig aConfig, const TSgImageInfo& aImageInfo, TResourceCloseRule aResourceCloseRule, TInt aRenderVersion)
+	{
+	CreatePixmapSurfaceAndMakeCurrentL(aConfig, aImageInfo, aResourceCloseRule ,EGL_OPENGL_ES_API, aRenderVersion);
+		
+	DrawOpenGLesL();
+			
+	// Wait for the drawing to complete
+	eglWaitClient();
+
+	//we can't retrieve data directly from SgImage as non-unified 
+	//architecture doesn't allow readback from the GPU
+	
+	if (aImageInfo.iPixelFormat == EUidPixelFormatXRGB_8888  || 
+		aImageInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE)
+		{	
+		CheckImageDataGLesL();
+		}
+
+	CleanupSurfaceSgImageL();
+	CloseSgDriver();
+	return ETrue;
+	}
+
+/**
+Compound operation that constructs an RSgImage and uses it to create a pixmap suface.
+It then draws to the surface using OpenVG and checks whether the drawing succeeded.
+It cleans up the pixmap surface it destroyed.
+@param aConfig The EGL config to be used when creating the pixmap surface
+@param aImageInfo Used to create the RSgImage pixmap
+@param aCloseNativeImageEarly When ETrue, the RSgImage is closed as soon as the pixmap surface has been
+		created.  Otherwise, the RSgImage is closed during cleanup, when the pixmap surface is destroyed.
+@return Whether it was possible to create an iSgImage for the given aImageInfo
+*/
+EXPORT_C TBool CTestEglSession::TryUsePixmapRSgImageOpenVgL(EGLConfig aConfig, const TSgImageInfo& aImageInfo, TResourceCloseRule aResourceCloseRule)
+	{
+	CreatePixmapSurfaceAndMakeCurrentL(aConfig, aImageInfo, aResourceCloseRule);
+		
+	DrawOpenVgL();
+			
+	// Wait for the drawing to complete
+	eglWaitClient();
+	
+	//we can't retrieve data directly from the SgImage as 
+	//non-unified architecture doesn't allow readback from the GPU
+	CheckImageDataVgL(VG_sXRGB_8888);
+	CleanupSurfaceSgImageL();
+	CloseSgDriver();
+	return ETrue;
+	}
+
+EXPORT_C void CTestEglSession::CreateWindowSurfaceAndMakeCurrentL(EGLConfig aConfig, RWindow& aWindow, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+		
+	// Create a Window surface from the native image
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, aConfig, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	const EGLint* pixmapAttribs = ((aWindow.DisplayMode() == EColor16MAP) && (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)) ? KPixmapAttribsVgAlphaFormatPre : KPixmapAttribsNone;
+	iSurface = eglCreateWindowSurface(iDisplay, aConfig, &aWindow, pixmapAttribs);
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	const EGLint KAttribsListCtxNone[] = { EGL_NONE };;
+	const EGLint KAttribsListCtxGles2[] = { EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE };
+	const EGLint* attrib_list_ctx = (aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber == 2) ? KAttribsListCtxGles2 : KAttribsListCtxNone; 
+	iContext = eglCreateContext(iDisplay, aConfig, EGL_NO_CONTEXT, attrib_list_ctx);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+
+EXPORT_C TBool CTestEglSession::CongfigSupportsOpenVgL(EGLConfig aConfig)
+	{
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, aConfig, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	return (EGL_RENDERABLE_TYPE_value&EGL_OPENVG_BIT)>0;
+	}
+
+EXPORT_C void CTestEglSession::CreatePixmapSurfaceAndMakeCurrentAndMatchL(const TSgImageInfo& aImageInfo, TResourceCloseRule aResourceCloseRule, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+    OpenSgDriverL();
+    ASSERT_EQUALS(iSgImage.Create(aImageInfo, NULL, 0), KErrNone);
+
+	EGLint renderableType = 0;
+	if(aBindAPI == EGL_OPENVG_API)
+		{
+		renderableType = EGL_OPENVG_BIT;
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber==1)
+		{
+		renderableType = EGL_OPENGL_ES_BIT;
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber==2)
+		{
+		renderableType = EGL_OPENGL_ES2_BIT;
+		}
+	else
+		{
+		ERR_PRINTF1(_L("CreatePixmapSurfaceAndMakeCurrentAndMatchL - Unkown API requested!"));
+		User::Leave(KErrArgument);
+		}
+	EGLint attrib_list[] = { 
+			  EGL_MATCH_NATIVE_PIXMAP,(TInt)&iSgImage,
+			  EGL_RENDERABLE_TYPE,renderableType,
+			  EGL_SURFACE_TYPE,EGL_PIXMAP_BIT,
+			  EGL_NONE};
+
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+
+	EGLConfig config;
+	EGLint numConfigs;
+	ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,attrib_list,&config,1,&numConfigs));
+	if (numConfigs <= 0)
+		{
+		// we just WARN, as we don't know if this is expected yet (if it is, then catch the leaving error)
+		WARN_PRINTF1(_L("CreatePixmapSurfaceAndMakeCurrentAndMatchL - Could not find a matching config!"));
+		iSgImage.Close();
+		CloseSgDriver();
+		// Leave with a unique knonwn error code - useful to catch this error in negative tests
+		User::Leave(KTestNoMatchingConfig);
+		}
+
+	// Create a pixmap surface from the native image
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, config, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	const EGLint* pixmapAttribs = ((aImageInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE) && (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)) ? KPixmapAttribsVgAlphaFormatPre : KPixmapAttribsNone;
+	iSurface = eglCreatePixmapSurface(iDisplay, config, &iSgImage, pixmapAttribs);
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+	
+	if (aResourceCloseRule == EResourceCloseSgImageEarly)
+		{
+		// EGL should have taken its own reference to the SgImage, so it should be able to continue
+		// to use the underlying data after this local image has been closed.
+		iSgImage.Close();
+		}
+	
+	if (aResourceCloseRule == EResourceCloseSgDriverAndImageEarly)
+		{
+		// EGL should have taken its own reference to the SgDriver, so it should be able to continue
+		// to use its reference to the image resource after this local reference to the driver has 
+		// been closed.
+		iSgImage.Close();
+		CloseSgDriver();		
+		}
+
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	const EGLint KAttribsListCtxNone[] = { EGL_NONE };;
+	const EGLint KAttribsListCtxGles2[] = { EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE };
+	const EGLint* attrib_list_ctx = (aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber == 2) ? KAttribsListCtxGles2 : KAttribsListCtxNone; 
+	iContext = eglCreateContext(iDisplay, config, EGL_NO_CONTEXT, attrib_list_ctx);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+/**
+Compound operation that constructs an RSgImage and uses it to create a pixmap suface. 
+It then makes it current to the thread.
+@param aConfig The EGL config to be used when creating the pixmap surface
+@param aImageInfo Used to create the RSgImage pixmap
+@param aCloseNativeImageEarly When ETrue, the RSgImage is closed as soon as the pixmap surface has been
+		created.  Otherwise, the RSgImage is left to be destroyed later by some other method 
+		- e.g at the same time as destroying the surface.
+@return Whether it was possible to create an iSgImage for the given aImageInfo
+*/
+EXPORT_C void CTestEglSession::CreatePixmapSurfaceAndMakeCurrentL(EGLConfig aConfig, const TSgImageInfo& aImageInfo, TResourceCloseRule aResourceCloseRule, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+	OpenSgDriverL();
+    ASSERT_EQUALS(iSgImage.Create(aImageInfo, NULL, 0), KErrNone);
+		
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+
+	// Create a pixmap surface from the native image
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, aConfig, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	const EGLint* pixmapAttribs = ((aImageInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE) && (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)) ? KPixmapAttribsVgAlphaFormatPre : KPixmapAttribsNone;
+	iSurface = eglCreatePixmapSurface(iDisplay, aConfig, &iSgImage, pixmapAttribs);
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+	
+	if (aResourceCloseRule == EResourceCloseSgImageEarly)
+		{
+		// EGL should have taken its own reference to the SgImage, so it should be able to continue
+		// to use the underlying data after this local image has been closed.
+		iSgImage.Close();
+		}
+	if (aResourceCloseRule == EResourceCloseSgDriverAndImageEarly)
+		{
+		// EGL should have taken its own reference to the SgDriver, so it should be able to continue
+		// to use its reference to the image resource after this local reference to the driver has 
+		// been closed.
+		iSgImage.Close();
+		CloseSgDriver();		
+		}
+	
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	const EGLint KAttribsListCtxNone[] = { EGL_NONE };;
+	const EGLint KAttribsListCtxGles2[] = { EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE };
+	const EGLint* attrib_list_ctx = (aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber == 2) ? KAttribsListCtxGles2 : KAttribsListCtxNone; 
+	iContext = eglCreateContext(iDisplay, aConfig, EGL_NO_CONTEXT, attrib_list_ctx);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+EXPORT_C TInt CTestEglSession::CreateBitmap(CFbsBitmap* aFbsBitmap, const TSize& aSize, TDisplayMode aDisplayMode)
+	{
+	//Fist try with CreateHardwareBitmap to check whether we are on hardware
+	TInt result = aFbsBitmap->CreateHardwareBitmap(aSize, aDisplayMode, KUidEglTestServer);
+	
+	if(result == KErrNotSupported)
+		{
+		//we are not on hardware
+		result = aFbsBitmap->Create(aSize, aDisplayMode);
+		}
+	return result;
+	}
+
+EXPORT_C void CTestEglSession::CreatePixmapSurfaceAndMakeCurrentL(EGLConfig aConfig, const TSize& aSize, TDisplayMode displayMode, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+	// Create an empty native CFbsBitmap
+	OpenFbsSessionL();
+	iFbsBitmap = new(ELeave)CFbsBitmap;
+	ASSERT_EQUALS(CreateBitmap(iFbsBitmap, aSize, displayMode), KErrNone);
+	
+    const EGLint* attrib_list = NULL;
+	if(aBindAPI == EGL_OPENVG_API)
+		{
+		// no attribs to modify
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API)
+		{
+		// no attribs to modify
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber==2)
+		{
+	    const EGLint KAttribGLES2[] = {EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE};
+		attrib_list=KAttribGLES2;
+		}
+	else
+		{
+		ERR_PRINTF1(_L("CreatePixmapSurfaceAndMakeCurrentL - Unkown API requested!"));
+		User::Leave(KErrArgument);
+		}
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+	
+	// Create a pixmap surface from the native image
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, aConfig, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	const EGLint* pixmapAttribs = ((displayMode == EColor16MAP) && (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)) ? KPixmapAttribsVgAlphaFormatPre : KPixmapAttribsNone;
+	iSurface = eglCreatePixmapSurface(iDisplay, aConfig, iFbsBitmap, pixmapAttribs);
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+	
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	iContext = eglCreateContext(iDisplay, aConfig, EGL_NO_CONTEXT, attrib_list);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+EXPORT_C void CTestEglSession::CreatePixmapSurfaceAndMakeCurrentAndMatchL(const TSize& aSize, TDisplayMode displayMode, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+	OpenFbsSessionL();
+	iFbsBitmap = new(ELeave)CFbsBitmap;
+	ASSERT_EQUALS(CreateBitmap(iFbsBitmap, aSize, displayMode), KErrNone);
+
+	EGLint renderableType = 0;
+	if(aBindAPI == EGL_OPENVG_API)
+		{
+		renderableType = EGL_OPENVG_BIT;
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber==1)
+		{
+		renderableType = EGL_OPENGL_ES_BIT;
+		}
+	else if(aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber==2)
+		{
+		renderableType = EGL_OPENGL_ES2_BIT;
+		}
+	else
+		{
+		ERR_PRINTF1(_L("CreatePixmapSurfaceAndMakeCurrentAndMatchL - Unkown API requested!"));
+		User::Leave(KErrArgument);
+		}
+	EGLint attrib_list[] = { 
+			  EGL_MATCH_NATIVE_PIXMAP,(TInt)iFbsBitmap,
+			  EGL_RENDERABLE_TYPE,renderableType,
+			  EGL_SURFACE_TYPE,EGL_PIXMAP_BIT,
+			  EGL_NONE};
+
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+
+	EGLConfig config;
+	EGLint numConfigs;
+	ASSERT_EGL_TRUE(eglChooseConfig(iDisplay,attrib_list,&config,1,&numConfigs));
+	if (numConfigs <= 0)
+		{
+		// we just WARN, as we don't know if this is expected yet (if it is, then catch the leaving error)
+		WARN_PRINTF1(_L("CreatePixmapSurfaceAndMakeCurrentAndMatchL - Could not find a matching config!"));
+		iSgImage.Close();
+		CloseSgDriver();
+		// Leave with a unique knonwn error code - useful to catch this error in negative tests
+		User::Leave(KTestNoMatchingConfig);
+		}
+
+	// Create a pixmap surface from the native image
+	EGLint EGL_RENDERABLE_TYPE_value = 0;
+	ASSERT_EGL_TRUE(eglGetConfigAttrib(iDisplay, config, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value));
+	const EGLint* pixmapAttribs = ((displayMode == EColor16MAP) && (EGL_RENDERABLE_TYPE_value & EGL_OPENVG_BIT)) ? KPixmapAttribsVgAlphaFormatPre : KPixmapAttribsNone;
+	iSurface = eglCreatePixmapSurface(iDisplay, config, iFbsBitmap, pixmapAttribs);
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+	
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	const EGLint KAttribsListCtxNone[] = { EGL_NONE };;
+	const EGLint KAttribsListCtxGles2[] = { EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE };
+	const EGLint* attrib_list_ctx = (aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber == 2) ? KAttribsListCtxGles2 : KAttribsListCtxNone; 
+	iContext = eglCreateContext(iDisplay, config, EGL_NO_CONTEXT, attrib_list_ctx);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+EXPORT_C void CTestEglSession::CreatePbufferSurfaceAndMakeCurrentL(EGLConfig aConfig, const TSize& aSize, EGLenum aBindAPI, TInt aRenderVersionNumber)
+	{
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+
+	ASSERT_EQUALS(iSurface, EGL_NO_SURFACE);
+	ASSERT_EQUALS(iContext, EGL_NO_CONTEXT);
+	
+	ASSERT_EGL_TRUE(eglBindAPI(aBindAPI));
+	
+	//	PBuffer attribs options are:
+	//		EGL_WIDTH, EGL_HEIGHT, EGL_LARGEST_PBUFFER,
+	//		EGL_TEXTURE_FORMAT, EGL_TEXTURE_TARGET, EGL_MIPMAP_TEXTURE,
+	//		EGL_VG_COLORSPACE, and EGL_VG_ALPHA_FORMAT
+	// Create a pbuffer surface of the given size
+	const EGLint KPbufferAttribs[] = { 
+			EGL_WIDTH,	aSize.iWidth,
+			EGL_HEIGHT,	aSize.iHeight,
+			EGL_NONE };
+	iSurface = eglCreatePbufferSurface(iDisplay, aConfig, KPbufferAttribs);	
+	ASSERT_EGL_TRUE(iSurface != EGL_NO_SURFACE);
+
+	// Create a context for drawing to/reading from the pixmap surface and make it current
+	const EGLint KAttribsListCtxNone[] = { EGL_NONE };;
+	const EGLint KAttribsListCtxGles2[] = { EGL_CONTEXT_CLIENT_VERSION, aRenderVersionNumber, EGL_NONE };
+	const EGLint* attrib_list_ctx = (aBindAPI == EGL_OPENGL_ES_API && aRenderVersionNumber == 2) ? KAttribsListCtxGles2 : KAttribsListCtxNone; 
+	iContext = eglCreateContext(iDisplay, aConfig, EGL_NO_CONTEXT, attrib_list_ctx);
+	ASSERT_EGL_TRUE(iContext != EGL_NO_CONTEXT);	
+	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
+	}
+
+EXPORT_C void CTestEglSession::DrawOpenVgL()
+	{
+	ASSERT_TRUE(iSurface != EGL_NO_SURFACE);
+	ASSERT_TRUE(iContext != EGL_NO_CONTEXT);
+	
+	// Draw to the pixmap surface 
+	// Clear it: redish
+	VGfloat colorBackground[4];
+	ConvertColor(KRgbReddish, colorBackground);
+	vgSetfv(VG_CLEAR_COLOR, 4, colorBackground);
+	vgClear(0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
+	
+	// And add a square: greenish
+	VGfloat colorSquare[4];
+	ConvertColor(KRgbGreenish, colorSquare);
+	vgSetfv(VG_CLEAR_COLOR, 4, colorSquare);
+	vgClear(KPixmapSquare.iTl.iX, KPixmapSquare.iTl.iX, KPixmapSquare.Width(), KPixmapSquare.Height());
+	}
+
+EXPORT_C void CTestEglSession::DrawOpenGLesL()
+	{
+	ASSERT_TRUE(iSurface != EGL_NO_SURFACE);
+	ASSERT_TRUE(iContext != EGL_NO_CONTEXT);
+	//GreenishRGB 0x46, 0xDC, 0x78
+	const GLfloat glRed = KRgbReddish.Red();
+	const GLfloat glGreen = KRgbReddish.Green();
+	const GLfloat glBlue  = KRgbReddish.Blue();
+	const GLfloat glAlpha = KRgbReddish.Alpha();
+	const GLfloat glRedBits = 255.f;
+	const GLfloat glGreenBits = 255.f;
+	const GLfloat glBlueBits  = 255.f;
+	const GLfloat glAlphaBits = 255.f;
+	
+	// Disable  cdither - when using exact comparison to reference bitmap
+	// because reference bitmap cannot be created to match dither exactly
+	glDisable(GL_DITHER);	
+	// Clear the surface to the colour specified
+	glClearColor((glRed)/glRedBits, (glGreen)/glGreenBits, (glBlue)/glBlueBits, glAlpha/glAlphaBits);
+	
+	//glColor3f(KRgbGreenish.Red(),KRgbGreenish.Green(),KRgbGreenish.Blue());
+	//glRectf(KPixmapSquare.iTl.iX, KPixmapSquare.iTl.iY,KPixmapSquare.iTl.iX + KPixmapSquare.Width(),KPixmapSquare.iTl.iY + KPixmapSquare.Height());
+	
+	glClear(GL_COLOR_BUFFER_BIT);
+	}
+
+EXPORT_C void CTestEglSession::CheckImageDataL(CFbsBitmap* aFbsBitmap)
+	{
+	// Use native API's to check pixel values in the surface - note that this is not an OpenVG test, so no boundary pixels are tested
+	TRgb rgbPixelSample;
+	// Outside the square
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(10,10));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(90,90));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	
+	// Inside the square
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(30,30));
+	ASSERT_TRUE(PixelsMatch(KRgbGreenish, rgbPixelSample, EFalse));
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(70,70));
+	ASSERT_TRUE(PixelsMatch(KRgbGreenish, rgbPixelSample, EFalse));
+	}
+
+EXPORT_C void CTestEglSession::CheckImageDataFullRedishL(CFbsBitmap* aFbsBitmap)
+	{
+	// Use native API's to check pixel values in the surface - note that this is not an OpenVG test, so no boundary pixels are tested
+	TRgb rgbPixelSample;
+	// Outside the square
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(10,10));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(90,90));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	
+	// Inside the square
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(30,30));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	aFbsBitmap->GetPixel(rgbPixelSample, TPoint(70,70));
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, rgbPixelSample, EFalse));
+	}
+
+/**
+Use OpenVG to check pixel values
+@param aDataFormat The VG image data format of the current surface
+*/
+EXPORT_C void CTestEglSession::CheckImageDataVgL(VGImageFormat aDataFormat)
+	{
+	switch(aDataFormat)
+		{
+		case VG_sRGB_565:
+			{
+			TUint16 intPixelSample=0;
+			
+			// Outside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 10,10, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color64K(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 90,90, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color64K(intPixelSample), EFalse));
+			
+			// Inside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 30,30, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color64K(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 70,70, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color64K(intPixelSample), EFalse));
+			break;
+			}
+		case VG_sXRGB_8888:		
+			{
+			TUint32 intPixelSample=0;
+	
+			// Outside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 10,10, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 90,90, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));
+			
+			// Inside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 30,30, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color16MU(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 70,70, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color16MU(intPixelSample), EFalse));
+			break;
+			}
+		case VG_sARGB_8888:
+			{
+			TUint32 intPixelSample=0;
+	
+			// Outside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 10,10, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MA(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 90,90, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MA(intPixelSample), EFalse));
+			
+			// Inside the square
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 30,30, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color16MA(intPixelSample), EFalse));
+			vgReadPixels(&intPixelSample, 1, aDataFormat, 70,70, 1,1);
+			ASSERT_TRUE(PixelsMatch(KRgbGreenish, TRgb::Color16MA(intPixelSample), EFalse));
+			break;
+			}
+		default:
+			WARN_PRINTF2(_L("Unexpected image data format %d in CTestEglSession::CheckImageDataVgL"), aDataFormat);
+			ASSERT_TRUE(EFalse);
+		}
+	}
+
+/**
+Use OpenGLes to check pixel values
+@param aDataFormat The VG image data format of the current surface
+*/
+EXPORT_C void CTestEglSession::CheckImageDataGLesL()
+	{
+	TUint32 intPixelSample;
+	glReadPixels(10,10,1,1,GL_RGBA,GL_UNSIGNED_BYTE ,&intPixelSample);
+	SwapChannels(intPixelSample);
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));	
+	
+	glReadPixels(45,45,1,1,GL_RGBA,GL_UNSIGNED_BYTE ,&intPixelSample);
+	SwapChannels(intPixelSample);
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));
+
+	glReadPixels(55,55,1,1,GL_RGBA,GL_UNSIGNED_BYTE ,&intPixelSample);
+	SwapChannels(intPixelSample);
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));
+
+	glReadPixels(99,99,1,1,GL_RGBA,GL_UNSIGNED_BYTE ,&intPixelSample);
+	SwapChannels(intPixelSample);
+	ASSERT_TRUE(PixelsMatch(KRgbReddish, TRgb::Color16MU(intPixelSample), EFalse));
+
+	}
+
+EXPORT_C void CTestEglSession::SwapChannels(TUint32 &aSwapMe)
+	{
+	TUint32 buff = aSwapMe;
+	
+	aSwapMe = 0;
+	aSwapMe |= (buff & 0x000000FF) << 16;
+	aSwapMe |= (buff & 0x0000FF00);
+	aSwapMe |= (buff & 0x00FF0000) >> 16;
+	aSwapMe |= (buff & 0xFF000000);
+	}
+
+/**
+Destroys the surface and underlying RSgImage object.
+Nulls the current context.
+*/
+EXPORT_C void CTestEglSession::CleanupSurfaceSgImageL()
+	{
+	CleanupSurfaceAndContextL();
+
+	iSgImage.Close();
+	}
+
+/**
+Resets the internal surface and context handles without destroying them.
+Also closes the internal RSgImage handled that is associated to the surface.
+
+EGL destroys all surface and context handles associated with a display when
+eglTerminate() is called. 
+*/
+EXPORT_C void CTestEglSession::ResetSurfaceAndContextSgImageL()
+	{
+	INFO_PRINTF1(_L("CTestEglSession::ResetSurfaceAndContextSgImageL()"));
+	
+	iContext = EGL_NO_CONTEXT;
+	iSurface = EGL_NO_SURFACE;
+	iSgImage.Close();
+	}
+
+/**
+ Check that the pixel values match within a predefined tolerance
+ @param aExpected the expected pixel colour vaule
+ @param aActual the actual pixel colour value 
+ @param aCheckAlpha Whether to check the alpha channel value
+ @return Whether the pixel values match - within the allowed tolerance
+ */
+EXPORT_C TBool CTestEglSession::PixelsMatch(const TRgb& aExpected, const TRgb& aActual, TBool aCheckAlpha)
+	{
+	// This value has been carefully selected. If it is too high it could be hidding genuine pixel value
+	//	differences, while too low will be too strict to allow for pixel conversions, i.e. from 16bpp to 32bpp
+	const TInt KPixelTolerance = 8;
+
+	if (aCheckAlpha && aExpected.Alpha()== 0 && 
+		aActual.Red() == 0 && 
+		aActual.Green() == 0 && 
+		aActual.Blue() == 0 && 
+		aActual.Alpha() == 0)
+		{
+		// if the expected value for alpha is 0, all actual values should be 0
+		return ETrue;
+		}
+	else if (Abs(aExpected.Red() - aActual.Red()) > KPixelTolerance ||
+			 Abs(aExpected.Green() - aActual.Green()) > KPixelTolerance ||
+			 Abs(aExpected.Blue() - aActual.Blue()) > KPixelTolerance ||
+			 aCheckAlpha && Abs(aExpected.Alpha() - aActual.Alpha()) > KPixelTolerance)
+		{
+		// one or more of the actual values differ by more than the allowed tolerance
+		ERR_PRINTF6(_L("thread %d: Expected r:%d g:%d b:%d a:%d"), iThreadIdx, aExpected.Red(), aExpected.Green(), aExpected.Blue(), aExpected.Alpha());
+		ERR_PRINTF6(_L("thread %d: Actual r:%d g:%d b:%d a:%d"), iThreadIdx, aActual.Red(), aActual.Green(), aActual.Blue(), aActual.Alpha());
+		ERR_PRINTF6(_L("thread %d: diff r:%d g:%d b:%d a:%d"), iThreadIdx, Abs(aExpected.Red() - aActual.Red()), Abs(aExpected.Green() - aActual.Green()), Abs(aExpected.Blue() - aActual.Blue()), Abs(aExpected.Alpha() - aActual.Alpha()));
+		return EFalse;
+		}
+	return ETrue;
+	}
+
+EXPORT_C void CTestEglSession::InitializeL(TBool aTerminateDisplay)
+	{
+	// Initialize display object
+	INFO_PRINTF2(_L("thread %d: Calling eglInitialize..."), iThreadIdx);
+	EGLint major=0;
+	EGLint minor=0;
+	CHECK_EXPECTED_ERROR(eglInitialize(iDisplay, &major, &minor));
+	// Remember if the user wants us to terminate the display.
+	iTerminateDisplay = aTerminateDisplay;
+	
+	INFO_PRINTF4(_L("thread %d: Initialised: EGL Version %d.%d"), iThreadIdx, major, minor);
+	}
+
+
+EXPORT_C void CTestEglSession::TerminateDisplayL()
+	{
+	if (iSurface != EGL_NO_SURFACE)
+		{
+		WARN_PRINTF2(_L("thread %d: iSurface has not been destoroyed in TerminateDisplayL..."), iThreadIdx);
+		}
+	if (iContext != EGL_NO_CONTEXT)
+		{
+		WARN_PRINTF2(_L("thread %d: iContext has not been destoroyed in TerminateDisplayL..."), iThreadIdx);
+		}
+	if (iDisplay != EGL_NO_DISPLAY)
+		{
+		INFO_PRINTF2(_L("thread %d: Calling eglMakeCurrent(NULL values) from TerminateDisplayL..."), iThreadIdx);
+
+		ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+		INFO_PRINTF1(_L("Calling eglTerminate..."));
+		ASSERT_EGL_TRUE(eglTerminate(iDisplay));
+		iDisplay = EGL_NO_DISPLAY;
+		}
+	iTerminateDisplay = EFalse;
+	}
+
+EXPORT_C void CTestEglSession::OpenSgDriverL()
+	{
+	if (!iSgDriverOpen)
+		{
+		VERBOSE_INFO_PRINTF2(_L("CTestEglSession<0x%08x> Opening SgDriver"), this);
+#ifdef  SYMBIAN_GRAPHICS_EGL_SGIMAGELITE 		
+		TInt ret=iSgDriver.Open();
+#else
+		TInt ret=SgDriver::Open();
+#endif	//SYMBIAN_GRAPHICS_EGL_SGIMAGELITE	
+		ASSERT_EQUALS(ret, KErrNone);
+		iSgDriverOpen = ETrue;
+		}
+	}
+
+EXPORT_C void CTestEglSession::CloseSgDriver()
+	{
+	if (iSgDriverOpen)
+		{
+		VERBOSE_INFO_PRINTF2(_L("CTestEglSession<0x%08x> Closing SgDriver"), this);
+#ifdef  SYMBIAN_GRAPHICS_EGL_SGIMAGELITE        
+        iSgDriver.Close();
+#else
+        SgDriver::Close(); 
+#endif  //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+		iSgDriverOpen = EFalse;
+		}
+	}
+
+EXPORT_C void CTestEglSession::OpenFbsSessionL()
+	{
+	if (!iFbsSessionOpen)
+		{
+		INFO_PRINTF2(_L("CTestEglSession<0x%08x> Opening FbsSession"), this);
+		TInt ret=RFbsSession::Connect();
+		ASSERT_EQUALS(ret, KErrNone);
+		iFbsSessionOpen = ETrue;
+		}
+	}
+
+EXPORT_C void CTestEglSession::CloseFbsSession()
+	{
+	if (iFbsSessionOpen)
+		{
+		INFO_PRINTF2(_L("CTestEglSession<0x%08x> Closing FbsSession"), this);
+		RFbsSession::Disconnect();
+		iFbsSessionOpen = EFalse;
+		}
+	}
+
+EXPORT_C TBool CTestEglSession::FetchProcEglCreateImageKhr()
+	{
+	if (!ipfnEglCreateImageKHR)
+		{
+		INFO_PRINTF2(_L("thread %d: Calling eglGetProcAddress(\"eglCreateImageKHR\")"), iThreadIdx);
+		ipfnEglCreateImageKHR = reinterpret_cast<TFPtrEglCreateImageKhr>(eglGetProcAddress("eglCreateImageKHR"));
+		if (ipfnEglCreateImageKHR==NULL)
+			{
+			EGLint eglError = eglGetError();
+			WARN_PRINTF2(_L("eglCreateImageKHR() not found - EGL Error: 0x%x"), eglError);
+			}
+		}
+	return (ipfnEglCreateImageKHR!=NULL);
+	}
+
+EXPORT_C EGLImageKHR CTestEglSession::eglCreateImageKhrL(EGLDisplay aDisplay,EGLContext aContext,EGLenum aTarget,RSgImage* aSgImage,const EGLint *aAttr_List)
+	{
+	TBool bSuccess = FetchProcEglCreateImageKhr();
+	ASSERT_TRUE(bSuccess);
+	VERBOSE_INFO_PRINTF2(_L("thread %d: Calling eglCreateImageKHR"), iThreadIdx);
+	EGLImageKHR eglImage = ipfnEglCreateImageKHR(aDisplay,aContext,aTarget,reinterpret_cast<EGLClientBuffer>(aSgImage),const_cast<EGLint *>(aAttr_List));	
+	return eglImage;
+	}
+
+EXPORT_C EGLImageKHR CTestEglSession::eglCreateImageKhrL(EGLDisplay aDisplay,EGLContext aContext,EGLenum aTarget,CFbsBitmap &aCFbsBitmap, const EGLint *aAttr_List)
+	{
+	TBool bSuccess = FetchProcEglCreateImageKhr();
+	ASSERT_TRUE(bSuccess);
+	INFO_PRINTF2(_L("thread %d: Calling eglCreateImageKHR, with CFBsBitmap)"), iThreadIdx);
+	//the following call to eglCreateImageKHR MUST fail, error handling is made outside
+	EGLImageKHR eglImage = ipfnEglCreateImageKHR(aDisplay,aContext,aTarget,reinterpret_cast<EGLClientBuffer>(&aCFbsBitmap),const_cast<EGLint *>(aAttr_List));	
+	return eglImage;
+	}
+
+EXPORT_C TBool CTestEglSession::FetchProcEglDestroyImageKhr()
+	{
+	if (!ipfnEglDestroyImageKHR)
+		{
+		INFO_PRINTF2(_L("thread %d: Calling eglGetProcAddress(\"eglDestroyImageKHR\")"), iThreadIdx);
+		ipfnEglDestroyImageKHR = reinterpret_cast<TFPtrEglDestroyImageKhr>(eglGetProcAddress("eglDestroyImageKHR"));
+		if (ipfnEglDestroyImageKHR==NULL)
+			{
+			EGLint eglError = eglGetError();
+			WARN_PRINTF2(_L("eglDestroyImageKHR() not found - EGL Error: 0x%x"), eglError);
+			}
+		}
+	return (ipfnEglDestroyImageKHR!=NULL);
+	}
+
+EXPORT_C TBool CTestEglSession::DestroyEGLImage(EGLDisplay aDisplay, EGLImageKHR aEGLImageKHR)
+	{
+	TBool bSuccess = FetchProcEglDestroyImageKhr();
+	ASSERT_TRUE(bSuccess);
+	VERBOSE_INFO_PRINTF2(_L("thread %d: Calling eglDestroyImageKHR"), iThreadIdx);
+	return ipfnEglDestroyImageKHR(aDisplay,aEGLImageKHR);
+	}
+
+EXPORT_C TBool CTestEglSession::FetchProcvgCreateImageTargetKhr()
+	{
+	if (!ipfnvgCreateImageTargetKHR)
+		{
+		INFO_PRINTF2(_L("thread %d: Calling eglGetProcAddress (\"vgCreateEGLImageTargetKHR\")"), iThreadIdx);
+		ipfnvgCreateImageTargetKHR = reinterpret_cast<TFPtrVgCreateEglImageTargetKhr>(eglGetProcAddress("vgCreateEGLImageTargetKHR"));		
+		if (ipfnvgCreateImageTargetKHR==NULL)
+			{
+			EGLint eglError = eglGetError();
+			WARN_PRINTF2(_L("vgCreateImageTargetKHR() not found - EGL Error: 0x%x"), eglError);
+			}
+		}
+	return (ipfnvgCreateImageTargetKHR!=NULL);
+	}
+
+EXPORT_C VGImage CTestEglSession::vgCreateImageTargetKHR(VGeglImageKHR aImage)
+	{
+	TBool bSuccess = FetchProcvgCreateImageTargetKhr();
+	ASSERT_TRUE(bSuccess);
+	VERBOSE_INFO_PRINTF2(_L("thread %d: Calling vgCreateEGLImageTargetKHR"), iThreadIdx);
+	return ipfnvgCreateImageTargetKHR(aImage);
+	}
+
+EXPORT_C TBool CTestEglSession::IsACompatibleConfig(EGLConfig aConfig,RSgImage& aImage,TBool aLog)
+	{
+	EGLint EGL_BUFFER_SIZE_value;
+	EGLint EGL_ALPHA_SIZE_value;
+	EGLint EGL_BLUE_SIZE_value;
+	EGLint EGL_GREEN_SIZE_value;
+	EGLint EGL_RED_SIZE_value;
+	EGLint EGL_SURFACE_TYPE_value;
+	EGLint EGL_RENDERABLE_TYPE_value;
+	EGLint EGL_CONFIG_ID_value;
+	
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_CONFIG_ID, &EGL_CONFIG_ID_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_BUFFER_SIZE, &EGL_BUFFER_SIZE_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_ALPHA_SIZE, &EGL_ALPHA_SIZE_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_BLUE_SIZE, &EGL_BLUE_SIZE_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_GREEN_SIZE, &EGL_GREEN_SIZE_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_RED_SIZE, &EGL_RED_SIZE_value);
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_SURFACE_TYPE, &EGL_SURFACE_TYPE_value);	
+	eglGetConfigAttrib(iDisplay, aConfig, EGL_RENDERABLE_TYPE, &EGL_RENDERABLE_TYPE_value);
+#ifdef PRINTG_CONFIGS_LOG
+	INFO_PRINTF7(_L("(Config: %3d) RGBA=(%2d) %2d,%2d,%2d,%2d"), EGL_CONFIG_ID_value, EGL_BUFFER_SIZE_value, 
+					EGL_RED_SIZE_value, EGL_GREEN_SIZE_value, EGL_BLUE_SIZE_value, 
+					EGL_ALPHA_SIZE_value);
+	INFO_PRINTF2(_L("RENDERABLE_TYPE %d"),EGL_RENDERABLE_TYPE_value);
+#endif
+	
+	if(!(EGL_SURFACE_TYPE_value & EGL_PIXMAP_BIT))
+		{
+		return EFalse;
+		}
+	
+	TBool good = ETrue;
+	//requested usage bits
+	TSgImageInfo requestedImageInfo;
+	aImage.GetInfo(requestedImageInfo);
+	
+#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+	//potential usage bits
+    RSgImage potential;
+    potential.Open(aImage.Id(),ESgDoNotRestrictUsage);
+    TSgImageInfo potentialImageInfo;
+    potential.GetInfo(potentialImageInfo);
+    potential.Close();
+#endif    
+	
+	switch(requestedImageInfo.iPixelFormat)
+		{			
+		case EUidPixelFormatRGB_565:
+			if (!(EGL_RED_SIZE_value == 5 && EGL_GREEN_SIZE_value == 6 && EGL_BLUE_SIZE_value == 5 && EGL_ALPHA_SIZE_value == 0))
+				{
+				good = EFalse;
+				}
+			break;			
+		case EUidPixelFormatXRGB_8888:
+			if (!(EGL_RED_SIZE_value == 8 && EGL_GREEN_SIZE_value == 8 && EGL_BLUE_SIZE_value == 8 && EGL_ALPHA_SIZE_value == 0))
+				{
+				good = EFalse;
+				}				
+			break;			
+		case EUidPixelFormatARGB_8888_PRE:
+			if (!(EGL_RED_SIZE_value == 8 && EGL_GREEN_SIZE_value == 8 && EGL_BLUE_SIZE_value == 8 && EGL_ALPHA_SIZE_value == 8))
+				{
+				good = EFalse;
+				}
+			//just OVG cares about the premultiplied alpha
+			if(EGL_RENDERABLE_TYPE_value& EGL_OPENVG_BIT)
+			//if(requestedImageInfo.iUsage & ESgUsageBitOpenVgSurface)
+				{
+				if(!(EGL_SURFACE_TYPE_value & EGL_VG_ALPHA_FORMAT_PRE_BIT))
+					{
+					if(aLog)
+						{
+						WARN_PRINTF2(_L("This Config can't be used with Pre-multipliedAlpha becasue EGL_SURFACE_TYPE has the wrong bits = %x"), EGL_SURFACE_TYPE_value);
+						}
+					good = EFalse;
+					}
+				}
+			break;
+		default:
+			if(aLog)
+				{
+				ERR_PRINTF2(_L("Wrong PixelFormat for a target, %x"), requestedImageInfo.iPixelFormat);
+				}
+			good = EFalse;
+		}
+	if(!good)
+		{
+		return EFalse;
+		}
+
+#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+	// 
+	//Check if strict matching requirements are met:
+	//- All the supported APIs included in the EGL_RENDERABLE_TYPE of the 
+	// EGLConfig must be matched by the corresponding iUsage of RSgImage
+	//- The following usages included in the iUsage of the RSgImage must be 
+	// matched by the corresponding API in EGL_RENDERABLE_TYPE of the EGLConfig: 
+	//         ESgUsageBitOpenGlSurface-> EGL_OPENGL_BIT
+	//         ESgUsageBitOpenGlesSurface-> EGL_OPENGL_ES_BIT
+	//         ESgUsageBitOpenGles2Surface-> EGL_OPENGL_ES2_BIT
+	//         ESgUsageBitOpenVgSurface->EGL_OPENVG_BIT
+	
+	EGLint usageBitsMask = 0;
+	if(requestedImageInfo.iUsage & ESgUsageBitOpenVgSurface)
+		{
+		usageBitsMask |= EGL_OPENVG_BIT;
+		}
+	if(requestedImageInfo.iUsage & ESgUsageBitOpenGles2Surface)
+		{
+		usageBitsMask |= EGL_OPENGL_ES2_BIT;
+		}
+    if(requestedImageInfo.iUsage & ESgUsageBitOpenGlesSurface)
+        {
+        usageBitsMask |= EGL_OPENGL_ES_BIT;
+        }
+    if(requestedImageInfo.iUsage & ESgUsageBitOpenGlSurface)
+        {
+        usageBitsMask |= EGL_OPENGL_BIT;
+        }
+
+	if(usageBitsMask  != EGL_RENDERABLE_TYPE_value)
+		{
+		return EFalse;
+		}
+#else
+    // requested usage & RENDERABLE_TYPE > 0
+    EGLint usageBitsMask = 0;
+    if(requestedImageInfo.iUsage & ESgUsageOpenVgTarget)
+        {
+        usageBitsMask |= EGL_OPENVG_BIT;
+        }
+    if(requestedImageInfo.iUsage & ESgUsageOpenGlesTarget)
+        {
+        usageBitsMask |= EGL_OPENGL_ES_BIT;
+        }
+    if(requestedImageInfo.iUsage & ESgUsageOpenGles2Target)
+        {
+        usageBitsMask |= EGL_OPENGL_ES2_BIT;
+        }
+    if(!(usageBitsMask & EGL_RENDERABLE_TYPE_value))
+        {
+        return EFalse;
+        }
+    
+    // potential usage >= RENDERABLE_TYPE
+    
+    EGLint potentialUsageBitsMask = 0;
+    if(potentialImageInfo.iUsage & ESgUsageOpenVgTarget)
+        {
+        potentialUsageBitsMask |= EGL_OPENVG_BIT;
+        }
+    if(potentialImageInfo.iUsage & ESgUsageOpenGlesTarget)
+        {
+        potentialUsageBitsMask |= EGL_OPENGL_ES_BIT;
+        }
+    if(potentialImageInfo.iUsage & ESgUsageOpenGles2Target)
+        {
+        potentialUsageBitsMask |= EGL_OPENGL_ES2_BIT;
+        }
+    
+    potentialUsageBitsMask = EGL_RENDERABLE_TYPE_value &~ potentialUsageBitsMask;
+    if(potentialUsageBitsMask)
+        {
+        return EFalse;
+        }
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE	
+	return good;
+	}
+
+EXPORT_C TBool  CTestEglSession::CheckNeededExtensionL(TInt aExtension, const TDesC& aExtensionName)
+	{
+	TBuf8<128> extensionName;
+	extensionName.Copy(aExtensionName);
+	if(aExtension & KEGL_RSgimage || extensionName.Compare(KEglRSgImage)==0)
+		{
+		TBool bFoundExtensionEGL_NOK_pixmap_type_rsgimage = FindExtensionStringL(EIsEGL,KEglRSgImage);
+		if (!bFoundExtensionEGL_NOK_pixmap_type_rsgimage)
+			{
+			// The extension is not supported
+			return EFalse;
+			}
+		}
+	if(aExtension & KEGL_KHR_image_base || extensionName.Compare(KEglKhrImageBase)==0)
+		{
+		TBool bFoundExtensionEGL_KHR_image = FindExtensionStringL(EIsEGL,KEglKhrImageBase);
+		if (!bFoundExtensionEGL_KHR_image)
+			{
+			// The extension is not supported
+			return EFalse;
+			}
+		}
+	if(aExtension & KEGL_KHR_image_pixmap || extensionName.Compare(KEglKhrImagePixmap)==0)
+		{
+		TBool bFoundExtensionEGL_KHR_image = FindExtensionStringL(EIsEGL,KEglKhrImagePixmap);
+		if (!bFoundExtensionEGL_KHR_image)
+			{
+			// The extension is not supported
+			return EFalse;
+			}
+		}
+	if(aExtension & KVG_KHR_EGL_image || extensionName.Compare(KVgKhrEglImage)==0)
+		{
+		TBool bFoundExtensionVG_KHR_EGL_image = FindExtensionStringL(EIsVG,KVgKhrEglImage);
+		if (!bFoundExtensionVG_KHR_EGL_image)
+			{
+			// The extension is not supported
+			return EFalse;
+			}
+		}
+	if(aExtension & KEGL_KHR_reusable_sync || extensionName.Compare(KEglKhrReusableSync)==0)
+		{
+		TBool bFoundExtensionEGL_KHR_reusable_sync = FindExtensionStringL(EIsEGL,KEglKhrReusableSync);
+		if (!bFoundExtensionEGL_KHR_reusable_sync)
+			{
+			// The extension is not supported
+			return EFalse;
+			}
+		}
+    if(aExtension & KEGL_NOK__private__signal_sync)
+        {
+        TBool bFoundExtensionEGL_NOK__private__signal_sync = FindExtensionStringL(EIsEGL,KEglNokPrivateSignalSync);
+        if (!bFoundExtensionEGL_NOK__private__signal_sync)
+            {
+            // The extension is not supported
+            return EFalse;
+            }
+        }
+    if(aExtension & KEGL_NOKIA_swap_buffers)
+        {
+        TBool bFoundExtensionEGL_NOKIA_swap_buffer = FindExtensionStringL(EIsEGL,KEglNokiaSwapBuffers);
+        if (!bFoundExtensionEGL_NOKIA_swap_buffer)
+            {
+            // The extension is not supported
+            return EFalse;
+            }
+        }
+#ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    if(aExtension & KEGL_SYMBIAN_image_preserved)
+        {
+        TBool bFoundExtensionEGL_SYMBIAN_image_preserved = FindExtensionStringL(EIsEGL,KEglSymbianImagePreserved);
+        if (!bFoundExtensionEGL_SYMBIAN_image_preserved)
+            {
+            // The extension is not supported
+            return EFalse;
+            }
+        }
+#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
+    
+	return ETrue;	
+	}
+
+EXPORT_C CFbsBitmap* CTestEglSession::CreateReferenceBitmapL(TDisplayMode aMode)
+	{
+	if(aMode == ENone )
+		{
+		ERR_PRINTF1(_L("Queried Reference Bitmap dispaly mode equal to ENone"));
+		User::Leave(KErrTEFUnitFail);
+		}
+	return CreateReferenceBitmapL(aMode,KRgbGreenish);
+	}
+
+EXPORT_C CFbsBitmap* CTestEglSession::CreateReferenceBitmapL(TDisplayMode aMode,const TRgb& aColour)
+	{
+	OpenFbsSessionL();
+	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
+	CleanupStack::PushL(bitmap);
+	if(bitmap->Create(KPixmapSize,aMode) != KErrNone)
+		{
+		return NULL;
+		}
+	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
+	CleanupStack::PushL(bitmapDevice);
+	CFbsBitGc* fbsBitGc = CFbsBitGc::NewL();
+	CleanupStack::PushL(fbsBitGc);
+	fbsBitGc->Activate(bitmapDevice);
+	fbsBitGc->SetBrushColor(aColour);
+	fbsBitGc->Clear();
+	CleanupStack::PopAndDestroy(2,bitmapDevice);
+	CleanupStack::Pop(bitmap);
+	return bitmap;
+	}
+
+EXPORT_C CFbsBitmap* CTestEglSession::CreateReferenceMaskedBitmapL(TDisplayMode aRefBitmapMode, const TRgb& aPenBitmapColor, const CFbsBitmap* aMaskBitmap)
+	{
+	OpenFbsSessionL();
+
+	// create the refBitmat (same size as the mask bitmap)
+	// Note that we clear it to 'opaque black' as we assume the target surface has been cleared to 'opaque black' too
+	// If either the surface or the refBitmap are cleared to another colour, update the other accordingly
+	CFbsBitmap* refBitmap = new(ELeave) CFbsBitmap();
+	CleanupStack::PushL(refBitmap);
+	User::LeaveIfError(refBitmap->Create(aMaskBitmap->SizeInPixels(), aRefBitmapMode));
+	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(refBitmap);
+	CleanupStack::PushL(bitmapDevice);
+	CFbsBitGc* fbsBitGc = CFbsBitGc::NewL();
+	CleanupStack::PushL(fbsBitGc);
+	fbsBitGc->Activate(bitmapDevice);
+	fbsBitGc->SetBrushColor(KRgbBlack);
+	fbsBitGc->Clear();
+	
+	// create the penBitmap (same size as the mask bitmap)	
+	CFbsBitmap* penBitmap = new(ELeave) CFbsBitmap();
+	CleanupStack::PushL(penBitmap);
+	User::LeaveIfError(penBitmap->Create(aMaskBitmap->SizeInPixels(), aRefBitmapMode));
+	CFbsBitmapDevice* penbitmapDevice = CFbsBitmapDevice::NewL(penBitmap);
+	CleanupStack::PushL(penbitmapDevice);
+	CFbsBitGc* penBitGc = CFbsBitGc::NewL();
+	CleanupStack::PushL(penBitGc);
+	penBitGc->Activate(penbitmapDevice);
+	penBitGc->SetBrushColor(aPenBitmapColor);
+	penBitGc->Clear();
+
+	// perform a masked bitmap transfer to the active refBitmap
+	TRect bmpRect(TPoint(0, 0), refBitmap->SizeInPixels()); 
+	fbsBitGc->Activate(bitmapDevice);
+	fbsBitGc->BitBltMasked(TPoint(0, 0), penBitmap, bmpRect, aMaskBitmap, EFalse);	
+
+	CleanupStack::PopAndDestroy(5, bitmapDevice);
+	CleanupStack::Pop(refBitmap);
+	return refBitmap;
+	}
+
+
+EXPORT_C CFbsBitmap* CTestEglSession::CreateReferenceBitmapL(TDisplayMode aMode, const TSize &aSize, const TInt aIndex)
+	{
+	OpenFbsSessionL();
+	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
+	CleanupStack::PushL(bitmap);
+	User::LeaveIfError(bitmap->Create(aSize,aMode));
+
+	TInt height = bitmap->SizeInPixels().iHeight;
+	TInt width  = bitmap->SizeInPixels().iWidth;
+
+	// Initialise colour values to a random value (guarantees pixel uniqueness if update is done accordingly)  
+	TInt red=0;
+	TInt green=127;
+	TInt blue=127;
+	TInt alpha=255;
+
+	TBitmapUtil bmpUtil(bitmap);
+	bmpUtil.Begin(TPoint(0,0));
+	for (TInt colIndex = 0; colIndex < width; ++colIndex)
+
+		{
+		bmpUtil.SetPos(TPoint(colIndex, 0));
+		for (TInt rowIndex =0; rowIndex < height; ++rowIndex)
+			{
+			TRgb rgb(red, green, blue, alpha);
+			switch(bitmap->DisplayMode())
+				{
+				case EColor64K:
+					{
+					bmpUtil.SetPixel(rgb.Color64K());
+					break;
+					}
+				case EColor16MU:
+					{
+					bmpUtil.SetPixel(rgb.Color16MU());
+					break;
+					}
+				case EColor16MA:
+					{
+					bmpUtil.SetPixel(rgb.Color16MA());
+					break;
+					}
+				case EColor16MAP:
+					{
+					bmpUtil.SetPixel(rgb.Color16MAP());
+					break;
+					}
+				case EGray256:
+					{
+					bmpUtil.SetPixel(rgb.Gray256());
+					break;
+					}
+				default:
+					{
+					// We should not get here - colour mode not supported by these tests
+					ERR_PRINTF1(_L("CTestEglSession::CreateReferenceBitmapL - Colour mode not supported!"));
+				    ASSERT(FALSE); 
+					}
+				}
+			bmpUtil.IncYPos();
+
+			// Update red bit 
+			red = ++red + aIndex; 
+			if (red>255) 
+				red = red - 256;
+			
+			// Update green bit
+			green = --green - aIndex; 
+			if (green<0) 
+				green = green + 256;
+			
+			// Update blue bit
+			blue = ++blue + aIndex; 
+			if (blue>255) 
+				blue = blue - 256;
+			
+			// Update alpha bit
+			alpha = --alpha - aIndex; 
+			if (alpha<0) 
+				alpha = alpha + 256;
+			}
+		}
+	bmpUtil.End();
+	CleanupStack::Pop(bitmap);
+	return bitmap;
+	}
+
+EXPORT_C void CTestEglSession::CheckVgDrawingL(VGImageFormat aDataFormat, const CFbsBitmap* aReferenceBitmap)
+	{
+	TRgb refPixel;
+	TInt height = aReferenceBitmap->SizeInPixels().iHeight;
+	TInt width  = aReferenceBitmap->SizeInPixels().iWidth;
+
+	switch(aDataFormat)
+		{
+		case VG_sRGB_565:
+			{			
+			TUint16* vgPixel = new(ELeave) TUint16[width];
+			CleanupArrayDeletePushL(vgPixel);
+			for (TInt y=0; y < height; y++)
+				{
+                // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
+                vgReadPixels(vgPixel, 1, aDataFormat, 0,height-y-1, width,1);
+				
+				for (TInt x=0; x < width; x++)
+					{
+					aReferenceBitmap->GetPixel(refPixel, TPoint(x,y));
+					if(!PixelsMatch(refPixel, TRgb::Color64K(vgPixel[x]), EFalse))
+						{
+						User::Leave(KErrTEFUnitFail);
+						}
+					}		
+				}
+			CleanupStack::PopAndDestroy(vgPixel);
+			break;
+			}
+
+		case VG_sXRGB_8888:		
+			{			
+			TUint32* vgPixel = new(ELeave) TUint32[width];
+			CleanupArrayDeletePushL(vgPixel);
+			for (TInt y=0; y < height; y++)
+				{
+                // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
+                vgReadPixels(vgPixel, 1, aDataFormat, 0,height-y-1, width,1);
+			
+				for (TInt x=0; x < width; x++)
+					{
+					aReferenceBitmap->GetPixel(refPixel, TPoint(x,y));
+					if(!PixelsMatch(refPixel, TRgb::Color16MU(vgPixel[x]), EFalse))
+						{
+						User::Leave(KErrTEFUnitFail);
+						}
+					}		
+				}
+			CleanupStack::PopAndDestroy(vgPixel);
+			break;
+			}
+			
+		case VG_sARGB_8888:		
+			{			
+			TUint32* vgPixel = new(ELeave) TUint32[width];
+			CleanupArrayDeletePushL(vgPixel);
+			for (TInt y=0; y < height; y++)
+				{
+                // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
+                vgReadPixels(vgPixel, 1, aDataFormat, 0,height-y-1, width,1);
+			
+				for (TInt x=0; x < width; x++)
+					{
+					aReferenceBitmap->GetPixel(refPixel, TPoint(x,y));
+					if(!PixelsMatch(refPixel, TRgb::Color16MA(vgPixel[x]), ETrue))
+						{
+						User::Leave(KErrTEFUnitFail);
+						}
+					}		
+				}
+			CleanupStack::PopAndDestroy(vgPixel);
+			break;
+			}
+			
+		case VG_sARGB_8888_PRE:		
+			{			
+			TUint32* vgPixel = new(ELeave) TUint32[width];
+			CleanupArrayDeletePushL(vgPixel);
+			for (TInt y=0; y < height; y++)
+				{
+                // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
+                vgReadPixels(vgPixel, 1, aDataFormat, 0,height-y-1, width,1);
+                
+				for (TInt x=0; x < width; x++)
+					{
+					aReferenceBitmap->GetPixel(refPixel, TPoint(x,y));
+					if(!PixelsMatch(refPixel, TRgb::Color16MAP(vgPixel[x]), ETrue))
+						{
+						User::Leave(KErrTEFUnitFail);
+						}
+					}		
+				}
+			CleanupStack::PopAndDestroy(vgPixel);
+			break;
+			}
+
+		default:
+			// We should not get here - colour mode not supported by these tests
+			ERR_PRINTF1(_L("CTestEglSession::CheckVgDrawingL - Colour mode not supported!"));
+		    ASSERT(FALSE); 
+			break;
+		}
+	}
+
+EXPORT_C TBool CTestEglSession::IsOpenGLESSupported() 
+    { 
+    if(!iIsSupportedRenderInitialized)
+        {
+        CheckAllAvailableRenders();
+        }
+    return iIsOpenGLESSupported;
+    } 
+
+EXPORT_C TBool CTestEglSession::IsOpenGLES2Supported() 
+    {
+    if(!iIsSupportedRenderInitialized)
+        {
+        CheckAllAvailableRenders();
+        }
+    return iIsOpenGLES2Supported;
+    }
+EXPORT_C TBool CTestEglSession::IsOpenVGSupported() 
+    {
+    if(!iIsSupportedRenderInitialized)
+        {
+        CheckAllAvailableRenders();
+        }
+    return iIsOpenVGSupported;
+    }
+
+void CTestEglSession::CheckAllAvailableRenders()
+    {
+    ASSERT_EGL_TRUE(iDisplay != EGL_NO_DISPLAY);
+    TPtrC8 ptrEglClientApis((const TText8 *)eglQueryString(iDisplay, EGL_CLIENT_APIS));
+    _LIT8(KOpenGLES, "OpenGL_ES");
+    EGLint numConfigs= 0;       
+    EGLConfig config;
+    if(ptrEglClientApis.Find(KOpenGLES) != KErrNotFound)
+        {
+        //check GLES2
+        const EGLint KAttrib_list_gles2[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                                              EGL_NONE };
+        EGLBoolean eglRes = eglChooseConfig(iDisplay, KAttrib_list_gles2, &config,1, &numConfigs);
+        ASSERT_EGL_TRUE(eglRes == EGL_TRUE);
+        if(numConfigs > 0)
+            {
+            iIsOpenGLES2Supported = ETrue;
+            }
+        //check GLES
+        numConfigs = 0;
+        const EGLint KAttrib_list_gles[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+                                             EGL_NONE };
+        eglRes = eglChooseConfig(iDisplay, KAttrib_list_gles, &config,1, &numConfigs);
+        ASSERT_EGL_TRUE(eglRes == EGL_TRUE);
+        if(numConfigs > 0)
+            {
+            iIsOpenGLESSupported = ETrue;
+            }
+        }
+    _LIT8(KOpenVG, "OpenVG");
+    if(ptrEglClientApis.Find(KOpenVG) != KErrNotFound)
+        {
+        numConfigs= 0;       
+        //check VG
+        const EGLint KAttrib_list_vg[] = { EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+                                           EGL_NONE };
+        EGLBoolean eglRes = eglChooseConfig(iDisplay, KAttrib_list_vg, &config,1, &numConfigs);
+        ASSERT_EGL_TRUE(eglRes == EGL_TRUE);
+        if(numConfigs > 0)
+            {
+            iIsOpenVGSupported = ETrue;
+            }
+        }
+    iIsSupportedRenderInitialized = ETrue;
+    }
+
+