Provide code to deliver both syborg and reference implementations of surface manager. default
authorFaisal Memon <faisal.memon@nokia.com>
Mon, 16 Aug 2010 10:28:15 +0100
changeset 0 91fe342bd9c4
child 1 44a5686bb629
Provide code to deliver both syborg and reference implementations of surface manager.
bug235.pkgdef.xml
graphicscompositionref/openwfc_ri_displaychannel/group/bld.inf
graphicscompositionref/openwfc_ri_displayupdater/group/bld.inf
graphicscompositionref/openwfcompositionengine/group/bld.inf
graphicscompositionref/surfacemgrcommon/inc/surfacemanager_dev.h
graphicscompositionref/surfacemgrcommon/inc/surfacemanagerdriver.h
graphicscompositionref/surfacemgrcommon/inc/surfacemanagerdriver.inl
graphicscompositionref/surfacemgrcommon/inc/syborgvirtualhwmemory.h
graphicscompositionref/surfacemgrcommon/src/extension.cpp
graphicscompositionref/surfacemgrcommon/src/surfacemanager.cpp
graphicscompositionref/surfacemgrcommon/src/surfacemanagerdriver.cpp
graphicscompositionref/surfacemgrcommon/src/syborgvirtualhwmemory.cpp
graphicscompositionref/surfacemgrplatsim/group/bld.inf
graphicscompositionref/surfacemgrref/group/bld.inf
graphicscompositionref/surfacemgrref/group/surfacemanager.mmp
graphicscompositionref/surfacemgrref/group/surfacemanager_ref.iby
graphicscompositionref/surfacemgrref/group/surfacemanagerdriver.mmp
graphicscompositionref/surfacemgrsyborg/group/bld.inf
graphicscompositionref/surfacemgrsyborg/group/surfacemanager_syborg.iby
graphicscompositionref/surfacemgrsyborg/group/syborgsurfacemanagerdriver.mmp
graphicscompositionref/surfaceupdateref/group/bld.inf
graphicscompositionref/symbianstreamref/group/bld.inf
graphicsrenderingref/directgdiadaptation/group/bld.inf
graphicsrenderingref/eglrefimpl/group/bld.inf
graphicsrenderingref/graphicsresourceimplementation/group/bld.inf
graphicsrenderingref/opengles_stub/group/bld.inf
graphicsrenderingref/sfopenvg/group/bld.inf
package_definition.xml
package_map.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bug235.pkgdef.xml	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE SystemDefinition [
+<!ELEMENT SystemDefinition ( systemModel )>
+<!ATTLIST SystemDefinition
+  name CDATA #REQUIRED
+  schema CDATA #REQUIRED
+>
+<!-- all paths are relative to the environment variable specified by the root attribute, or SOURCEROOT if not.  -->
+
+<!-- System Model Section of DTD -->
+<!ELEMENT systemModel (layer+)>
+
+<!ELEMENT layer (block* | collection*)*>
+<!-- Kernel Services, Base Services, OS Services, Etc -->
+<!ATTLIST layer
+  name CDATA #REQUIRED
+  long-name CDATA #IMPLIED
+  levels NMTOKENS #IMPLIED
+  span CDATA #IMPLIED
+>
+
+<!ELEMENT block (subblock* | collection*)*>
+ <!-- Generic OS services, Comms Services, etc -->
+<!ATTLIST block
+  levels NMTOKENS #IMPLIED
+  span CDATA #IMPLIED
+  level NMTOKEN #IMPLIED
+  name CDATA #REQUIRED
+  long-name CDATA #IMPLIED
+>
+
+<!ELEMENT subblock (collection)*>
+<!-- Cellular Baseband Services, Networking Services, etc -->
+<!ATTLIST subblock
+  name CDATA #REQUIRED
+  long-name CDATA #IMPLIED
+>
+
+<!ELEMENT collection (component)*>
+<!-- Screen Driver, Content Handling, etc -->
+<!ATTLIST collection
+  name CDATA #REQUIRED
+  long-name CDATA #IMPLIED
+  level NMTOKEN #IMPLIED
+>
+
+<!ELEMENT component (unit)*>
+<!-- contains units or is a  package or prebuilt -->
+<!ATTLIST component
+  name CDATA #REQUIRED
+  long-name CDATA #IMPLIED
+  deprecated CDATA #IMPLIED
+  introduced CDATA #IMPLIED
+  contract CDATA #IMPLIED
+  plugin (Y|N) "N"
+  filter CDATA #IMPLIED
+  class NMTOKENS #IMPLIED
+  supports CDATA #IMPLIED
+  purpose ( optional | mandatory | development ) "optional"
+>
+
+<!ELEMENT unit EMPTY >
+<!-- must be buildable (bld.inf) -->
+<!-- bldFile  may someday be removed in favour of mrp -->
+<!ATTLIST unit
+  mrp CDATA #IMPLIED
+  filter CDATA #IMPLIED
+  bldFile CDATA #IMPLIED
+  root CDATA #IMPLIED
+  version NMTOKEN #IMPLIED
+  prebuilt NMTOKEN #IMPLIED
+  late (Y|N) #IMPLIED
+  priority CDATA #IMPLIED
+>
+]>
+<SystemDefinition schema="2.0.1" name="Nokia Graphics Adaptation">
+<systemModel>
+<layer name="anonymous">
+<block name="graphics.nokia" long-name="Nokia Graphics Adaptation" levels="rendering composition">
+<collection name="graphicscompositionref" long-name="Graphics Composition Reference" level="composition">
+<component name="openwfcompositionengine" long-name="OpenWF-C Reference" introduced="^3" purpose="development">
+<unit bldFile="graphics.nokia/graphicscompositionref/openwfcompositionengine/group"/>
+</component>
+<component name="openwfc_ri_displaychannel" long-name="OpenWF-C RI Display Channel Adapter" introduced="^4" purpose="development">
+<unit bldFile="graphics.nokia/graphicscompositionref/openwfc_ri_displaychannel/group"/>
+</component>
+<component name="openwfc_ri_displayupdater" long-name="OpenWF-C RI Display Updater Adapter" introduced="^4" purpose="development">
+<unit bldFile="graphics.nokia/graphicscompositionref/openwfc_ri_displayupdater/group"/>
+</component>
+<component name="symbianstreamref" long-name="Symbian Stream Reference" introduced="^4">
+<unit bldFile="graphics.nokia/graphicscompositionref/symbianstreamref/group"/>
+</component>
+<component name="surfacemgrplatsim" long-name="PlatSim Surface Manager" introduced="^4">
+<unit bldFile="graphics.nokia/graphicscompositionref/surfacemgrplatsim/group"/>
+</component>
+<component name="surfacemgrsyborg" long-name="Syborg Surface Manager" introduced="^4">
+<unit bldFile="graphics.nokia/graphicscompositionref/surfacemgrsyborg/group"/>
+</component>
+<component name="surfacemgrcommon" long-name="Surface Manager Common" introduced="^4"/>
+<component name="surfacemgrref" long-name="Surface Manager Reference" introduced="^4">
+<unit bldFile="graphics.nokia/graphicscompositionref/surfacemgrref/group"/>
+</component>
+<component name="surfaceupdateref" long-name="Surface Update Server Reference" introduced="^4">
+<unit bldFile="graphics.nokia/graphicscompositionref/surfaceupdateref/group"/>
+</component>
+</collection>
+<collection name="graphicsrenderingref" long-name="Graphics Rendering Reference" level="rendering">
+<component name="eglrefimpl" long-name="EGL Reference" purpose="development">
+<unit bldFile="graphics.nokia/graphicsrenderingref/eglrefimpl/group"/>
+</component>
+<component name="opengles_stub" long-name="OpenGL ES Stub Implementation" purpose="development" filter="sf_build">
+<unit bldFile="graphics.nokia/graphicsrenderingref/opengles_stub/group"/>
+</component>
+<component name="sfopenvg" long-name="SF OpenVG Reference Implementation" purpose="development" filter="sf_build">
+<unit bldFile="graphics.nokia/graphicsrenderingref/sfopenvg/group"/>
+</component>
+<component name="graphicsresourceimplementation" long-name="Graphics Resource Reference">
+<unit bldFile="graphics.nokia/graphicsrenderingref/graphicsresourceimplementation/group"/>
+</component>
+</collection>
+</block>
+</layer>
+</systemModel>
+</SystemDefinition>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/inc/surfacemanager_dev.h	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,178 @@
+// Copyright (c) 2006-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:
+//
+
+/**
+ @file
+ @publishedPartner
+ @prototype
+*/
+
+#ifndef __SURFACEMANAGER_DEV_H__
+#define __SURFACEMANAGER_DEV_H__
+
+#include <graphics/surface.h>
+#include "surfacemanagerdriver.h"
+
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+#include "syborgvirtualhwmemory.h"
+#endif
+
+#if 0
+#define TRACE(x) x
+#else
+#define TRACE(x)
+#endif
+
+/** Maximum number of HintPairs per surface */
+const TInt KMaxHintsPerSurface = 16;
+
+/** Maximum number of elements in the table. This value must be a power of 2 */
+#define KMaxLists 16
+
+/**
+  Logical Device (factory class) for Surface manager
+*/
+class DSurfaceManagerFactory : public DLogicalDevice
+	{
+public:
+	DSurfaceManagerFactory();
+	TInt Install();
+	void GetCaps(TDes8& aDes) const;
+	TInt Create(DLogicalChannelBase*& aChannel);
+	};
+
+
+/**
+  Logical Channel class for SurfaceManager
+*/
+class DSurfaceManagerChannel : public DLogicalChannelBase
+	{
+public:
+	DSurfaceManagerChannel();
+	~DSurfaceManagerChannel();
+
+	// Inherited from DLogicalChannelBase
+	TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+	TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+private:
+	// Implementation for the different kinds of messages sent through RBusLogicalChannel
+	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
+
+private:
+	DProcess* iOwner;
+	};
+
+
+/**
+Class to hold a reference count and process pointer. 
+Each surface has a linked list of these owning processes.
+The surface manager has a linked list of these to track connections.
+@internalTechnology
+*/
+class TProcessListItem
+	{
+public:
+	TProcessListItem* iNext;	//pointer to next one in list
+	DProcess* iOwningProcess;	//pointer to the process object which is being reference counted
+	TInt iCount;				//reference count
+	};
+	
+
+/**
+Class to hold the information about a surface.
+Each surface has a linked list of owners.  The surfaces are arranged in a linked list,
+with these objects being elements in the list.
+@internalTechnology
+*/
+class TSurface					//one of these per surface
+	{
+public:
+	TSurface* iNext;			//singly linked list, points to next surface
+	TSurfaceId	iId;			//the surface id
+	TSize iSize;				//pixel width/height
+	TInt iBuffers;				//number of buffers
+	TUidPixelFormat iPixelFormat;			//pixel format
+	TInt iStride;				//offset from start of one line to the next, in bytes
+	TInt iOffsetToFirstBuffer;	//offset between the start of the surface memory and the start of the first pixel buffer
+	TInt iOffsetBetweenBuffers;	//offset between pixel buffers
+	TInt  iAlignment;			//byte alignment of the pixel buffers
+	TBool iContiguous;			//if it is in contiguous physical memory
+	DChunk* iChunk;				//ptr to the shared chunk
+	RSurfaceManager::TCacheAttribute iCacheAttrib;			//Caching attribute to create chunks memory
+	RSurfaceManager::THintPair iSurfaceHints[KMaxHintsPerSurface];	//Arbitrary key-value pairs associated with a surface
+	TBool iMappable;			//Is the Surface Mappable
+	TProcessListItem* iOwners;	//owner list. Singly linked list, points to next surface owner
+
+public:	
+	TProcessListItem* ProcessOwnerInfo(const DProcess* aProcess);
+	};
+	
+/**
+Surface manager extension object.
+There is one static instance of this in the kernel extension.
+@internalTechnology
+*/
+class DSurfaceManager : public DBase
+	{
+public:
+	TInt CreateSurface(const TDesC8* aConfig, TSurfaceId* aId);
+	TInt SurfaceInfo(const TSurfaceId* aId, TDes8* aInfo);
+	TInt OpenSurface(const TSurfaceId* aId);
+	TInt CloseSurface(const TSurfaceId* aId);
+	TInt MapSurface(const TSurfaceId* aId);
+	TInt AddConnection(const DProcess* iProcess);
+	void RemoveConnection(const DProcess* iProcess);
+	TInt CreateSurface(RSurfaceManagerDriver::TDeviceParam* aParam, TInt aChunkHandle);
+	TInt SynchronizeCache(RSurfaceManagerDriver::TDeviceParam* aId, RSurfaceManager::TSyncOperation aOperation);
+	TInt GetSurfaceHint(const TSurfaceId* aSurfaceId, RSurfaceManager::THintPair* aHintPair);
+	TInt SetSurfaceHint(const TSurfaceId* aSurfaceId, const RSurfaceManager::THintPair* aHintPair);
+	TInt AddSurfaceHint(const TSurfaceId* aSurfaceId, const RSurfaceManager::THintPair* aHintPair);
+	TInt GetBufferOffset(RSurfaceManagerDriver::TDeviceParam* aParam,TUint* aOffset);
+	TInt GetSurfaceManagerAttrib(RSurfaceManager::TSurfaceManagerAttrib* aAttrib,TInt* aValue);
+private:
+	void GenerateSurfaceId(TSurfaceId& aId);
+	TInt  CreateSurfaceChunk(const RSurfaceManager::TSurfaceCreationAttributes& attribs);
+	TInt ValidateAndCalculateChunkSize(RSurfaceManager::TSurfaceCreationAttributes& aAttribs, TInt& aOffset, 
+			TUint& aActualBufferSize, const TBool aNewChunk = EFalse);
+	TInt ValidatePhysicalMemory(DChunk* aChunk, const RSurfaceManager::TSurfaceCreationAttributes& aAttribs, 
+			TUint aBuffersize, TUint32& aMapAttr, TBool &aIsContiguous); 
+	TSurface* FindSurfaceById(const TSurfaceId& aId);
+	void CloseSurfaceHandlesForProcess(const DProcess* iProcess);
+	TProcessListItem* FindConnectedProcess(const DProcess* aProcess);
+	TInt FindHintKey(const RSurfaceManager::THintPair* aHints, TUint32 aKey) const;
+	TBool SortHints(RSurfaceManager::THintPair* aHints, TInt aNumberOfHints) const;
+	TInt InsertHintKey(RSurfaceManager::THintPair* aHints, const RSurfaceManager::THintPair& aHintPair) const;
+
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+	TInt CreateMemory();
+#endif
+
+private:
+	TSurface* iSurfacesIndex[KMaxLists]; 			// A table with elements pointing to the head of each singly linked list
+	NFastMutex iMutex;						// Mutex to protect access to surface lists
+	TProcessListItem* iConnectedProcesses;	//reference counted list of processes connected to the driver
+
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+	DVirtualHWMemoryManager* iVHWMemoryManager;
+#endif
+	};
+
+
+#endif
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/inc/surfacemanagerdriver.h	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,100 @@
+// Copyright (c) 2006-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:
+// Surface Manager Implementation
+// 
+//
+
+/**
+@file
+@internalComponent
+@prototype
+*/
+
+#ifndef __SURFACEMANAGERDRIVER_H__
+#define __SURFACEMANAGERDRIVER_H__
+
+#include <graphics/surfacemanager.h>
+
+/**
+RSurface Manager driver. This is a simple user side interface class derived from RBusLogicalChannel
+with each surface manager function implemented with a call to DoControl
+*/
+class RSurfaceManagerDriver : public RBusLogicalChannel
+	{
+public:
+	
+	/** Package class to exchange data between the client interface of the driver (RSurfaceManagerDriver)
+	 * and the kernel extension which implement it (DSurfaceManger)*/
+	class TDeviceParam
+		{
+	public:
+		TDeviceParam(){}
+		TDeviceParam(TAny* aSurfaceId, TAny* aBuffer) : iSurfaceId(aSurfaceId), iBuffer(aBuffer) {}
+		/** Generic object used to pass as a parameter to device driver*/
+		TAny* iBuffer;
+		/** Generic object used to pass as a parameter to device driver*/
+		TAny* iSurfaceId;
+		};
+
+	class TCaps
+		{
+	public:
+		TVersion iVersion;
+		};
+
+public:
+#ifndef __KERNEL_MODE__
+	inline TInt CreateSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId);
+	inline TInt CreateSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId, const RChunk& aChunkHandle);
+	inline TInt OpenSurface(const TSurfaceId& aSurfaceId);
+	inline TInt CloseSurface(const TSurfaceId& aSurfaceId);
+	inline TInt MapSurface(const TSurfaceId& aSurfaceId, RChunk& aHandle);
+	inline TInt SurfaceInfo(const TSurfaceId& aSurfaceId, RSurfaceManager::TInfoBuf& aInfo);
+	inline TInt Open();
+	inline TInt SynchronizeCache(const TSurfaceId& aSurfaceId, TInt aBuffer, RSurfaceManager::TSyncOperation aOperation);
+	inline TInt GetSurfaceHint(const TSurfaceId& aSurfaceId, RSurfaceManager::THintPair& aHint);
+	inline TInt SetSurfaceHint(const TSurfaceId& aSurfaceId, const RSurfaceManager::THintPair& aHint);
+	inline TInt AddSurfaceHint(const TSurfaceId&aSurface, const RSurfaceManager::THintPair& aHint);
+	inline TInt GetBufferOffset(const TSurfaceId& aSurfaceId, TInt aBuffer, TInt& aOffset);
+	inline TInt GetSurfaceManagerAttrib(RSurfaceManager::TSurfaceManagerAttrib aAttrib, TInt& aValue);
+#endif	//__KERNEL_MODE__
+
+	inline static const TDesC& Name();
+	inline static TVersion VersionRequired();	
+
+private:
+	enum TSurfaceManagerControl
+		{
+		EControlCreateSurface,
+		EControlOpenSurface,
+		EControlCloseSurface,
+		EControlAccessSurfaceData,
+		EControlSurfaceInfo,
+		EControlCreateSurfaceEx,
+		EControlSynchronizeCache,
+		EControlGetSurfaceHint,
+		EControlSetSurfaceHint,
+		EControlAddSurfaceHint,
+		EControlGetBufferOffset,
+		EControlGetSurfaceManagerAttrib
+		};
+
+	friend class DSurfaceManagerChannel;
+
+	};
+
+
+#include "surfacemanagerdriver.inl"
+
+#endif	//__SURFACEMANAGERDRIVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/inc/surfacemanagerdriver.inl	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,301 @@
+// Copyright (c) 2006-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:
+// Surface Manager driver
+// 
+//
+
+/**
+@file
+@internalComponent
+@prototype
+*/
+
+
+/**
+The driver's name
+@return The name of the driver
+@internalComponent
+*/
+inline const TDesC& RSurfaceManagerDriver::Name()
+	{
+	_LIT(KSurfaceManagerName, "surfacemanagerdriver");
+	return KSurfaceManagerName;
+	}
+
+/**
+The driver's version
+@return The version number of the driver
+@internalComponent
+*/
+inline TVersion RSurfaceManagerDriver::VersionRequired()
+	{
+	const TInt KMajorVersionNumber=1;
+	const TInt KMinorVersionNumber=0;
+	const TInt KBuildVersionNumber=KE32BuildVersionNumber;
+	return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+	}
+
+
+#ifndef __KERNEL_MODE__
+
+
+inline TInt RSurfaceManagerDriver::GetSurfaceManagerAttrib(RSurfaceManager::TSurfaceManagerAttrib aAttrib, TInt& aValue)
+	{return DoControl(RSurfaceManagerDriver::EControlGetSurfaceManagerAttrib, (TAny*)&aAttrib, (TAny*)&aValue);}
+
+
+/**
+Opens a surface. If the surface is already open in this process, this call increments the reference count for the surface for this process.
+If the surface hasn't been opened in this process, it opens the surface in this process and sets the reference count to 1 for this process.
+A surface will be deleted when all its reference counts are 0.
+@param aSurfaceId  The surface id originally returned when the surface was created.
+@pre The surface id is for an existing surface.
+@post The surface is open in this process.
+@return KErrNone if successful otherwise a system wide error code.
+*/
+inline TInt RSurfaceManagerDriver::OpenSurface(const TSurfaceId& aSurfaceId)
+	{return DoControl(RSurfaceManagerDriver::EControlOpenSurface, (TAny*)&aSurfaceId);}
+	
+
+
+/**
+Creates a surface and allocates the memory for the surface.
+It does not map the surface memory into this process.
+Sets the surface ID, aSurfaceId, to a globally unique identifier for the surface.
+The most significant byte of the 4th TUint in the TSurfaceId will be set to a value to identify the surface type.
+The surface will be open with a reference count of 1 in this process after a successful call to CreateSurface.
+
+The creation attributes are validated as follows:
+		The alignment is 1,2,4, 8,16,32,64 or TPageAlignment::EPageAligned.
+		The offset to first buffer is correctly aligned.
+		The width and height are both greater than zero.
+		There is at least one buffer.
+		The calculated chunk size isn't so big that it will exceed a signed int.
+		The caching attribute is valid
+		If the offset between the start of one buffer and the next is specified, it must be correctly aligned and at least as big as the buffer size calculated from the height and stride.
+		A surface hint key of zero is allowed when creating a surface, it is ignored
+
+If offset to first buffer or offset between buffers is not aligned properly, then surface manager will do the alignment, based on surface is CPU cached or not.
+	-	If surface is CPU cached it will be aligned with minimum of the specified alignment 32(for alignment 1, 2, 4, 8, 16, 32) or 64.
+	-	If surface is not CPU cached it will be aligned based on creation attribute's alignment.
+For page alignment it will be rounded to page size.
+
+@param aReqs  Input parameter, specifies attributes of the surface required.
+@param aSurfaceId  Output parameter, the surface ID, set if the call succeeds.
+@pre The device driver is loaded and a channel to it has been opened.
+@post The surface is created and opened in the creating process.
+@return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect,
+KErrNoMemory if the surface cannot be created due to out of memory,
+KErrOverflow if the chunk limit has been exceeded in the moving memory model, otherwise a standard Symbian error code.
+*/
+inline TInt RSurfaceManagerDriver::CreateSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId)
+	{return DoControl(RSurfaceManagerDriver::EControlCreateSurface, (TAny*)&aReqs, (TAny*)&aSurfaceId);}
+	
+
+
+/**
+Creates a surface in the shared chunk memory specified by the user.
+Sets a new surface ID aSurfaceId to a globally unique identifier for the surface.  
+The most significant byte of the 4th TUint in the TSurfaceId will be set to a value to identify 
+the surface type.  The surface will be open with a reference count of 1 in this process after a 
+successful call to CreateSurface.
+The creation attributes are validated as follows:
+		The alignment is 1,2,4, 8,16,32,64 or page alignment.
+		The offset to first buffer is correctly aligned.
+		The width and height are both greater than zero.
+		There is at least one buffer.
+		The chunk should be a valid shared chunk of the necessary size.
+		If the offset between the start of one buffer and the next is specified, it must be correctly 
+		aligned and at least as big as the buffer size calculated from the height and stride.
+		A surface hint key of zero is allowed when creating a surface, it is ignored
+
+The offset can be 0 and that means the surface manager will calculate the offset
+The TSurfaceCreationAttributes members iContiguous and iCacheAttribute will not be used for already existing chunks
+Also, note that surface manager will not do any rounding for offset to first buffer and offset between buffer. 
+Surface manager will expect exact aligned values for this buffer attributes, otherwise surface creation will fail.
+
+@param aReqs  Input parameter, specifies attributes of the surface required.
+@param aSurfaceId  Output parameter, the surface ID, set if the call succeeds.
+@param aChunkHandle  Handle of the existing shared chunk.
+
+Preconditions:
+@pre The device driver is loaded and a channel has been opened. A valid shared chunk should be created and 
+big enough for the requested size. The shared chunk type should be Shared  Kernel multiple and should be right the size,
+ie., the size should be calculated as Offset to first buffer + (the number of buffers * ((stride * height * pixel depth in bytes) rounded up to the specified alignment) all rounded to a page size
+@post The surface manager opens the chunk.
+@return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect. 
+KErrBadHandle If the handle is of an invalid shared chunk memory
+*/ 
+inline TInt RSurfaceManagerDriver::CreateSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId, const RChunk& aChunkHandle)
+	{
+	TDeviceParam create((TAny*)&aSurfaceId, (TAny*)&aReqs);
+	return DoControl(RSurfaceManagerDriver::EControlCreateSurfaceEx, (TAny*)&create, (TAny*)aChunkHandle.Handle());
+	}
+
+
+/**
+Closes the surface. Decrements the reference count for the surface for the calling process.
+If the surface has other owners, it will not be deleted from memory.
+If this is the last process to close the surface, the surface will be deleted and the surface ID will become invalid.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@pre The surface is open.
+@post The surface is closed.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+*/
+inline TInt RSurfaceManagerDriver::CloseSurface(const TSurfaceId& aSurfaceId)
+	{return DoControl(RSurfaceManagerDriver::EControlCloseSurface, (TAny*)&aSurfaceId);}
+
+
+
+/**
+Maps the surface into the current client process address space.
+The actual memory will remain mapped into the calling process for as long as the RChunk handle aHandle is open.
+The RChunk handle is owned by the calling thread, so will need to be duplicated if passed to other threads in the process.
+
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHandle  Output parameter, handle to the implementation specific Shared Chunk.
+@pre The surface is open.
+@post The surface memory will be mapped into the calling porcesses address space.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a
+surface, KErrAccessDenied if the surface is not open in the current process,
+KErrNotSupported if the surface is not mappable, KErrOverflow if the chunk limit has been
+exceeded in the moving memory model, otherwise a system wide error code.
+@see RChunk
+@see RHandleBase::Duplicate
+*/
+inline TInt RSurfaceManagerDriver::MapSurface(const TSurfaceId& aSurfaceId, RChunk& aHandle)
+	{return aHandle.SetReturnedHandle(DoControl(RSurfaceManagerDriver::EControlAccessSurfaceData, (TAny*)&aSurfaceId));}
+
+
+
+/**
+Returns information about a particular surface identified by its surface ID.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aInfo  TInfoBuf to receive the information about the surface.
+@pre The surface is open in the calling process.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+*/
+inline TInt RSurfaceManagerDriver::SurfaceInfo(const TSurfaceId& aSurfaceId, RSurfaceManager::TInfoBuf& aInfo)
+	{return DoControl(RSurfaceManagerDriver::EControlSurfaceInfo, (TAny*)&aSurfaceId, (TAny*)&aInfo);}
+
+
+
+/**
+Opens a channel to the surface manager logical device driver. 
+@pre The logical device driver has been loaded
+@return Returns KErrNone if successful, KErrNotFound if the driver hasn't been loaded, otherwise a system wide error code.
+@see User::LoadLogicalDevice
+*/
+inline TInt RSurfaceManagerDriver::Open()
+	{return DoCreate(Name(),VersionRequired(),KNullUnit,NULL,NULL,EOwnerProcess);}
+
+
+
+/**
+This function ensures the memory is updated consistently before and/or after triggering non CPU hardware access. 
+Also ensures the CPU cache and the physical memory are in a consistent state before and after non CPU hardware or DMA access
+to the physical memory.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aBuffer  The buffer number indexed from 0 within the surface whose memory region is to be flushed. 
+@param aOperation  Specifies the sync operation as before non CPU hardware reads or before non CPU hardware writes or after non CPU hardware
+writes between physical memory of the surface and the cache contents.
+@pre The surface is open in the calling process.
+@post The surface buffer memory will be synchronized properly with cache contents.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+buffer number is invalid, KErrAccessDenied if the surface is not open in this
+process, otherwise a system wide error code.
+*/ 
+inline TInt RSurfaceManagerDriver::SynchronizeCache(const TSurfaceId& aSurfaceId, TInt aBuffer, RSurfaceManager::TSyncOperation aOperation)
+	{
+	TDeviceParam buff((TAny*)&aSurfaceId, (TAny*)aBuffer);
+	return DoControl(RSurfaceManagerDriver::EControlSynchronizeCache, (TAny*)&buff, (TAny*)aOperation);
+	}
+
+/**
+Get the surface hint value for the given surface ID and hint pair key.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHint  The hint value for the requested hint pair key.
+@pre The surface is open in the calling process.
+@pre Hint key should be a key for a hint set for this surface.
+@post The hint value will be updated in the hint pair.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+invalid hint pair key used, KErrAccessDenied if the surface is not open in the
+current process, otherwise a system wide error code.
+*/ 
+inline TInt RSurfaceManagerDriver::GetSurfaceHint(const TSurfaceId& aSurfaceId, RSurfaceManager::THintPair& aHint)
+	{return DoControl(RSurfaceManagerDriver::EControlGetSurfaceHint, (TAny*)&aSurfaceId, (TAny*)&aHint);}
+
+
+/**
+Set the surface hint value for the surface Id.
+Parameters:
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHint  The value of the hint pair to set.
+@pre The surface is open in the calling process.
+@pre The Hint key should be a key for a hint set for this surface.
+@pre Only mutable hints can be updated.
+@post The hint value will be updated in the surface hint pair.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or if invalid
+hint key used, KErrAccessDenied if the hint pair is immutable or the surface is not open
+in the current process, otherwise a system wide error code.
+*/
+inline TInt RSurfaceManagerDriver::SetSurfaceHint(const TSurfaceId& aSurfaceId, const RSurfaceManager::THintPair& aHint)
+	{return DoControl(RSurfaceManagerDriver::EControlSetSurfaceHint, (TAny*)&aSurfaceId, (TAny*)&aHint);}
+
+
+/**
+Adds a new surface hint to the surface. This function will fail if the surface already has its maximum number of hints 
+or if the hint key is a duplicate or invalid.
+Parameters:
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHint  The value of the hint pair to add.
+@pre The surface is open in the calling process.
+@pre Atleast one free space to add a hint pair.
+@pre The new hint key should be unique.
+@post New hint pair will be added in the surface.
+@return Returns KErrNone if successful, KErrArgument if the surface ID is invalid or the
+hint pair has invalid key UID, KErrAccessDenied if the surface is not open in the current
+process, KErrAlreadyExists if duplicate hint key used, KErrOverflow if no space to add new
+pair, otherwise a system wide error code.
+*/
+inline TInt RSurfaceManagerDriver::AddSurfaceHint(const TSurfaceId& aSurfaceId, const RSurfaceManager::THintPair& aHint)
+	{return DoControl(RSurfaceManagerDriver::EControlAddSurfaceHint, (TAny*)&aSurfaceId, (TAny*)&aHint);}
+
+/**
+Get the offset of the specified buffer from the base address of the underlying
+chunk.
+
+To obtain the address of the buffer, the offset returned must be added onto the
+base address of the RChunk returned in a call to MapSurface(). Note that
+buffer offsets are immutable during the lifetime of the surface.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aBuffer The buffer for which the offset is requested. Indexed from 0.
+@param aOffset Output parameter set to the offset within the chunk.
+@pre The surface is open in the calling process.
+@return KErrNone if successful, KErrArgument if aSurfaceId or aBuffer are invalid,
+KErrAccessDenied if the surface is not open in the current process, KErrNotSupported if
+the surface is not mappable, otherwise a system wide error code.
+*/
+inline TInt RSurfaceManagerDriver::GetBufferOffset(const TSurfaceId& aSurfaceId, TInt aBuffer, TInt& aOffset)
+	{
+	TDeviceParam buff((TAny*)&aSurfaceId, (TAny*)aBuffer);
+	return DoControl(RSurfaceManagerDriver::EControlGetBufferOffset, (TAny*)&buff, (TAny*)&aOffset);
+	}
+
+#endif //__KERNEL_MODE__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/inc/syborgvirtualhwmemory.h	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,64 @@
+// Copyright (c) 2006-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:
+// Syborg Virtual Hardware Memory implementation
+
+/**
+ @file
+ @internalTechnology
+ @prototype
+*/
+
+#ifndef __SYBORGVIRTUALHWMEMORY_H__
+#define __SYBORGVIRTUALHWMEMORY_H__
+
+#include <klib.h>
+#include <graphics/virtualvideohwinterface.h>
+#include <graphics/guestvideodriverinterfaceconstants.h>
+
+/**
+
+Very simple memory manager for platsim virtual HW memory
+
+*/
+class DVirtualHWMemoryManager: public DBase
+    {
+    struct TAllocatedCell
+        {
+        TAllocatedCell( TInt aSize, TUint32 aBase ):
+            iSize( aSize ),
+            iBase( aBase ),
+            iNext( NULL )
+            {
+            }
+        
+        TInt iSize;
+        TUint32 iBase;
+        TAllocatedCell* iNext;
+        };
+    
+public:
+    DVirtualHWMemoryManager(TUint32 aBase, TInt aMaxSize);
+    
+    TUint32 Allocate(TInt aSize);
+    
+    void Deallocate(const TUint32 aPhysicalAddress);
+
+    ~DVirtualHWMemoryManager();
+
+private:
+    TAllocatedCell iRoot;
+    TAllocatedCell iLast;
+    };
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/src/extension.cpp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,1759 @@
+// Copyright (c) 2006-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:
+//
+
+
+#include <kernel/kern_priv.h>
+#include <kernel/cache.h>
+#include <graphics/surface.h>
+#include <graphics/surfacetypes.h>
+#include <graphics/surfacemanager.h>
+#include "surfacemanager_dev.h"
+
+/**
+Convert the surface Id to an index of the array 
+based on the least significant 4 bits of the first word of the ID
+@param	aSurfaceId  Const reference to the surface Id
+@internalTechnology
+*/
+static TInt SurfaceIdToIndex(const TSurfaceId& aSurfaceId)
+	{
+	return static_cast<TInt>(aSurfaceId.iInternal[0]&(KMaxLists-1));
+	}
+
+/**
+Removes an item from a linked list
+@param	aList  Pointer to the head of a linked list of type T
+@param	aOwner  Pointer to the object to be removed
+@internalTechnology
+*/
+template<class T>
+static void UnlinkListItem(T** aList, const T* aItem)
+	{
+	TRACE(Kern::Printf("SM UnlinkListItem list %08x  object %08x \n", aList, aItem);)
+	
+	__ASSERT_DEBUG(aItem != NULL, Kern::Fault("Surface Manager", __LINE__));
+	__ASSERT_DEBUG(*aList != NULL, Kern::Fault("Surface Manager", __LINE__));
+
+	if (*aList == aItem)	//one we want is at the head of the list
+		{
+		*aList = aItem->iNext;
+		return;
+		}
+	
+	T* p = *aList;
+	T* q = (*aList)->iNext;
+	while (q)
+		{
+		if (q == aItem)
+			{
+			p->iNext = q->iNext;
+			return;
+			}
+		p = q;
+		q = q->iNext;
+		}
+	}
+
+
+
+
+/**
+Returns a pointer to the surface owner object for the specified process, for this surface.
+@param	aProcess  Pointer to the process object
+@return pointer to the surface owner object if found, else NULL
+@internalTechnology
+*/
+
+TProcessListItem* TSurface::ProcessOwnerInfo(const DProcess* aProcess)
+	{
+	TProcessListItem* so = iOwners;
+	while(so)
+		{
+		if (aProcess == so->iOwningProcess)
+			{
+			break;
+			}
+		so = so->iNext;
+		}
+	return so;
+	}
+
+/**
+Creates a shared chunk surface.
+@param aParams  Package buffer containing the surface creation parameters.  
+@param aId  Will be set to the surface id of the newly created surface.
+@return KErrNone if successful, KErrArgument if the creation attributes were incorrect,
+otherwise one of the other system wide error codes.
+@see RSurfaceManager::TSurfaceCreationAttributes
+@internalTechnology
+*/
+
+TInt DSurfaceManager::CreateSurface(const TDesC8* aParams, TSurfaceId* aId)
+	{
+
+	RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attribs = buf();
+	
+	Kern::KUDesGet(buf, *aParams);		//fetch input parameters
+	if( (attribs.iHintCount > KMaxHintsPerSurface) || (attribs.iHintCount<0) )
+		{
+		return KErrArgument;
+		}	
+	
+	RSurfaceManager::THintPair tempSurfaceHints[KMaxHintsPerSurface];
+	if( (attribs.iHintCount>0) && attribs.iSurfaceHints)
+		{
+		kumemget(tempSurfaceHints, attribs.iSurfaceHints, attribs.iHintCount*sizeof(RSurfaceManager::THintPair));		
+		attribs.iSurfaceHints = tempSurfaceHints;
+		}
+	else
+		{
+		attribs.iSurfaceHints=NULL;
+		}
+
+	//validate input parameters and calculate chunk size
+	TInt roundedBufferSize = attribs.iOffsetBetweenBuffers;
+	TUint dummyActualSize = 0;	
+	
+	TInt chunkSize = ValidateAndCalculateChunkSize(attribs, roundedBufferSize, dummyActualSize, ETrue);
+	if (chunkSize == 0)
+		{
+		return KErrArgument;
+		}	
+
+	TSurfaceId sid;
+	TInt r = KErrNone;
+	TSurface* surface = NULL;
+	do		//in the unlikely event that we generate a duplicate surface id, try again.
+		{
+		GenerateSurfaceId(sid);
+
+		NKern::FMWait(&iMutex);
+		surface = FindSurfaceById(sid);
+		NKern::FMSignal(&iMutex);
+		}
+	while (surface);
+	
+	//create a shared chunk for the surface memory
+	TChunkCreateInfo info;
+	info.iType = TChunkCreateInfo::ESharedKernelMultiple;	//multi process mappable
+	info.iMaxSize = chunkSize;
+	info.iOwnsMemory = ETrue;
+
+//iMapAttr is valid only for hardware devices and will not make any effect in wins	
+#ifndef __WINS__
+	info.iMapAttr = (attribs.iCacheAttrib == RSurfaceManager::ECached) ? EMapAttrCachedMax : EMapAttrL1Uncached;
+#else
+	info.iMapAttr = 0;
+#endif
+
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+	// ChunkCommitPhysical method may only be used if the chunk was
+	// created with TChunkCreateInfo::iOwnsMemory set to false.
+    info.iMapAttr = EMapAttrFullyBlocking;
+    info.iOwnsMemory = EFalse;
+#endif
+
+	TLinAddr kernAddr;
+	TUint32 mapAttr;	
+	
+	NKern::ThreadEnterCS();
+	DChunk* chunk;
+	r = Kern::ChunkCreate(info, chunk, kernAddr, mapAttr);
+	if (KErrNone != r)
+		{
+		NKern::ThreadLeaveCS();
+		return r;
+		}
+
+	//commit the memory
+	TUint32 paddr;
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG 
+    Kern::Printf("DSurfaceManager::CreateSurface: Allocate ");
+    if( iVHWMemoryManager != NULL )
+		{
+	    paddr = iVHWMemoryManager->Allocate(chunkSize);
+		}
+	else
+		{
+		CreateMemory();
+	    paddr = iVHWMemoryManager->Allocate(chunkSize);
+		}
+
+    
+    if ( paddr )
+        {
+        r = Kern::ChunkCommitPhysical( chunk, 0, chunkSize, paddr );
+	    Kern::Printf("DSurfaceManager::CreateSurface: Commit %d from: 0x%08x success: %d",chunkSize, paddr, r );
+        }
+    else
+        {
+        r = KErrNoMemory;
+        }
+#else // GRAPHICS_SURFACEMANAGER_SYBORG
+	if (attribs.iContiguous)
+		{
+		r = Kern::ChunkCommitContiguous(chunk, 0, chunkSize, paddr);
+		}
+	else
+		{
+		r = Kern::ChunkCommit(chunk, 0, chunkSize);
+		}
+#endif // GRAPHICS_SURFACEMANAGER_SYBORG
+
+	if (KErrNone != r)
+		{
+		//problem committing the memory,
+		//destroy the chunk and cleanup
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return r;
+		}
+
+	//create a surface structure for the new surface
+	surface = new TSurface;
+	TRACE(Kern::Printf("SM A %08x TSurface CreateSurface",surface);)
+	if (!surface)
+		{
+		//destroy the chunk and cleanup, out of memory
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+
+	surface->iId = sid;
+	surface->iSize = attribs.iSize;
+	surface->iBuffers = attribs.iBuffers;
+	surface->iPixelFormat = attribs.iPixelFormat;
+	surface->iStride = attribs.iStride;
+	surface->iOffsetToFirstBuffer = attribs.iOffsetToFirstBuffer;
+	surface->iAlignment = attribs.iAlignment;
+	surface->iContiguous = attribs.iContiguous;
+	surface->iChunk = chunk;
+	surface->iOffsetBetweenBuffers = roundedBufferSize;
+	surface->iCacheAttrib = attribs.iCacheAttrib;
+	surface->iMappable = attribs.iMappable;
+	if(attribs.iHintCount>0)
+		{
+		memcpy(surface->iSurfaceHints,tempSurfaceHints,attribs.iHintCount*sizeof(RSurfaceManager::THintPair));
+		}
+	memclr(surface->iSurfaceHints+attribs.iHintCount, (KMaxHintsPerSurface-attribs.iHintCount)*sizeof(RSurfaceManager::THintPair));
+	
+	//create a surface owner for this surface
+	TProcessListItem* owner = new TProcessListItem;
+	TRACE(Kern::Printf("SM A %08x TProcessListItem CreateSurface",owner);)
+
+	if (!owner)
+		{
+		//destroy the chunk and cleanup, out of memory
+		Kern::ChunkClose(chunk);
+		delete(surface);
+		TRACE(Kern::Printf("SM D %08x TSurface CreateSurface",surface);)
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+	
+	owner->iCount = 1;		//mark it as open in this process
+	owner->iOwningProcess =  &Kern::CurrentProcess();
+	owner->iNext = NULL;
+		
+	surface->iOwners = owner;	//only 1 owner at creation time
+
+	//at this point we have a fully constructed TSurface
+
+	//add surface to head of surfaces list
+	NKern::FMWait(&iMutex);
+	//Mask off the bottom log2(KMaxLists) bits of the first word of the surfaceID as an index
+	//add the new surface to the beginning of the list 
+	TInt index = SurfaceIdToIndex(sid);
+	surface->iNext = iSurfacesIndex[index];
+	iSurfacesIndex[index] = surface;
+
+	NKern::FMSignal(&iMutex);		
+	NKern::ThreadLeaveCS();
+	
+	//write surface id back to user side
+	kumemput(aId, &sid, sizeof (TSurfaceId));
+	return KErrNone;
+	}
+
+
+/**
+Validate that a chunk contains physical memory for the used areas.
+
+This function should be called in Critical Section in order to be completed even if the thread 
+or process is killed and so be able to free the memory allocated  (TUint32[pageList])
+
+@param aChunk  Chunk that the user supplied.   
+@param aAttribs  Surface Creation Attributes.
+@param aBuffersize  Calculated size of each buffer.
+@param aMapAttr  Filled in with the mapping attributes of the memory.
+@param aIsContiguous  Lets the caller know if the surface is physically contiguous or not. 
+@return KErrNone if successful, KErrArgument if the creation attributes were incorrect,
+KErrBadHandle if aChunkHandle is of an invalid shared chunk memory,
+otherwise one of the other system wide error codes.
+@see RSurfaceManager::TSurfaceCreationAttributes
+@internalTechnology
+*/
+TInt DSurfaceManager::ValidatePhysicalMemory(DChunk* aChunk, const RSurfaceManager::TSurfaceCreationAttributes& aAttribs, 
+								   TUint aBuffersize, TUint32& aMapAttr, TBool &aIsContiguous) 
+	{
+	TLinAddr kernAddr;
+	TUint32 physAddr;
+
+	//Get the physical address for a region in a shared chunk
+	TInt pageSize = Kern::RoundToPageSize(1);
+	TInt pageList = 1 + (aChunk->iSize + pageSize - 2) / pageSize;
+	TUint32* physAddr2 = new TUint32[pageList];
+	if(!physAddr2)
+		{
+		return KErrNoMemory;
+		}
+	
+	// Unless proven otherwise, the memory is not contiguous. 
+	aIsContiguous = EFalse;
+	TInt r = Kern::ChunkPhysicalAddress(aChunk, 0, aChunk->iSize, kernAddr, aMapAttr, physAddr, physAddr2);
+	if (KErrNone == r)
+		{
+		aIsContiguous = ETrue;
+		}
+	
+	
+	TRACE(Kern::Printf("SM CreateSurface ChunkPhysicalAddress r %d chunk %08x chunk size %d", r, aChunk, aChunk->iSize);)
+	TRACE(Kern::Printf("SM CreateSurface kernAddr %08x", kernAddr);)
+	TRACE(Kern::Printf("SM CreateSurface mapAttr %08x", aMapAttr);)
+	TRACE(Kern::Printf("SM CreateSurface physAddr %08x", physAddr);)
+	TRACE(Kern::Printf("SM CreateSurface physAddr2 %08x", physAddr2);)
+	
+	if(r < KErrNone)
+		{
+		// Error means that there isn't memory in the whole chunk - so check the
+		// relevant areas - it is allowed to have gaps between the buffers, but not 
+		// within the actual regions that are used for buffers. 
+		
+		// So, we first check the area before first buffer up to "offsettofirstbuffer", which all should be valid
+		if (aAttribs.iOffsetToFirstBuffer != 0)
+			{
+			r = Kern::ChunkPhysicalAddress(aChunk, 0, aAttribs.iOffsetToFirstBuffer, 
+					kernAddr, aMapAttr, physAddr, physAddr2);
+			}
+		else
+			{
+			r = KErrNone;
+			}
+		
+		// If that's a pass, loop through and check the actual buffers (leave loop if it fails).
+		for(TInt i = 0; i < aAttribs.iBuffers && KErrNone <= r; i++)
+			{
+			r = Kern::ChunkPhysicalAddress(aChunk, 
+					aAttribs.iOffsetToFirstBuffer + aAttribs.iOffsetBetweenBuffers * i, 
+					aBuffersize, kernAddr, aMapAttr, physAddr, physAddr2);
+			}
+		}
+
+	// Fix up weird ChunkPhysicalAddress behaviour - it returns 1 to indicate that memory is non-contiguous. 
+	if (1 == r)
+		{
+		r = KErrNone;
+		}
+
+	delete[] physAddr2;
+	return r;
+	}
+
+
+/**
+Creates a surface in an existing shared chunk.
+@param aParam  Package buf containing the surface creation parameters and id to be set to the surface id of the newly created surface.  
+@param aChunkHandle  Existing valid shared chunk handle.
+@return KErrNone if successful, KErrArgument if the creation attributes were incorrect,
+KErrBadHandle if aChunkHandle is of an invalid shared chunk memory,
+otherwise one of the other system wide error codes.
+@see RSurfaceManager::TSurfaceCreationAttributes
+@internalTechnology
+*/
+TInt DSurfaceManager::CreateSurface(RSurfaceManagerDriver::TDeviceParam* aParam, TInt aChunkHandle)
+	{
+	RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attribs = buf();
+
+	//Get the input parameters
+	RSurfaceManagerDriver::TDeviceParam param;
+	kumemget(&param, aParam, sizeof(RSurfaceManagerDriver::TDeviceParam));
+	Kern::KUDesGet(buf, *(reinterpret_cast<const TDesC8*>(param.iBuffer)));
+	if( (attribs.iHintCount > KMaxHintsPerSurface) || (attribs.iHintCount<0) )
+		{
+		return KErrArgument;
+		}	
+	
+	RSurfaceManager::THintPair tempSurfaceHints[KMaxHintsPerSurface];
+	if( (attribs.iHintCount>0) && attribs.iSurfaceHints)
+		{
+		kumemget(tempSurfaceHints, attribs.iSurfaceHints, attribs.iHintCount*sizeof(RSurfaceManager::THintPair));		
+		attribs.iSurfaceHints = tempSurfaceHints;
+		}
+	else
+		{
+		attribs.iSurfaceHints=NULL;
+		}
+		
+	//validate input parameters and calc size
+	TInt roundedBufferSize = attribs.iOffsetBetweenBuffers;
+	TUint actualBufferSize = 0;
+	TInt chunkSize = ValidateAndCalculateChunkSize(attribs, roundedBufferSize, actualBufferSize);
+	if (chunkSize == 0)
+		{
+		return KErrArgument;
+		}
+	
+	NKern::ThreadEnterCS();
+	
+	//Open an existing shared chunk
+	DChunk* chunk = Kern::OpenSharedChunk(NULL, aChunkHandle, EFalse);
+	if(chunk == NULL)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrBadHandle;
+		}
+	
+	//Check for chunk type as kernel multiple
+	if(chunk->iChunkType != ESharedKernelMultiple)
+		{
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return KErrBadHandle;
+		}
+	
+	//Check for enough chunk size to create surface for requested attributes
+	if (chunk->iSize < attribs.iOffsetToFirstBuffer + attribs.iBuffers * actualBufferSize)
+		{
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+
+	TSurfaceId sid;
+	TSurface* surface = NULL;
+	do		//in the unlikely event that we generate a duplicate surface id, try again.
+		{
+		GenerateSurfaceId(sid);
+
+		NKern::FMWait(&iMutex);
+		surface = FindSurfaceById(sid);
+		NKern::FMSignal(&iMutex);
+		}
+	while (surface);
+
+	//create a surface structure for the new surface
+	surface = new TSurface;
+	TRACE(Kern::Printf("SM A %08x TSurface CreateSurface",surface);)
+	if (!surface)
+		{
+		//destroy the chunk and cleanup, out of memory
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+
+	TUint32 mapAttr = 0;
+	TBool isContiguous;
+	TInt r = ValidatePhysicalMemory(chunk, attribs, actualBufferSize, mapAttr, isContiguous);
+	if (r != KErrNone)
+		{
+		//destroy the surface and close the chunk
+		delete(surface);
+		Kern::ChunkClose(chunk);
+		NKern::ThreadLeaveCS();
+		if (r != KErrNoMemory)
+			{
+			r = KErrArgument;
+			}
+		return r;
+		}
+	
+	surface->iId = sid;
+	surface->iSize = attribs.iSize;
+	surface->iBuffers = attribs.iBuffers;
+	surface->iPixelFormat = attribs.iPixelFormat;
+	surface->iStride = attribs.iStride;
+	surface->iOffsetToFirstBuffer = attribs.iOffsetToFirstBuffer;
+	surface->iAlignment = attribs.iAlignment;
+	surface->iContiguous = isContiguous;
+	surface->iChunk = chunk;
+	surface->iOffsetBetweenBuffers = (attribs.iOffsetBetweenBuffers) ? attribs.iOffsetBetweenBuffers : roundedBufferSize;
+	surface->iMappable = attribs.iMappable;
+#ifndef __WINS__	//Creation attribute field will not considered for iCacheAttrib
+	TUint32 level1Info = mapAttr & EMapAttrL1CacheMask;
+	TUint32 level2Info = mapAttr & EMapAttrL2CacheMask;
+	TBool chunkIsNotcached =  ((level2Info == EMapAttrL2Uncached) && 
+	    ((level1Info == EMapAttrFullyBlocking) || (level1Info == EMapAttrBufferedNC) ||
+	     (level1Info == EMapAttrBufferedC) || (level1Info == EMapAttrL1Uncached)));
+	surface->iCacheAttrib = (chunkIsNotcached) ? RSurfaceManager::ENotCached : RSurfaceManager::ECached;
+#else
+	surface->iCacheAttrib = RSurfaceManager::ENotCached;	
+#endif
+	
+	if(attribs.iHintCount>0)
+		{
+		memcpy(surface->iSurfaceHints,tempSurfaceHints,attribs.iHintCount*sizeof(RSurfaceManager::THintPair));
+		}
+	memclr(surface->iSurfaceHints+attribs.iHintCount, (KMaxHintsPerSurface-attribs.iHintCount)*sizeof(RSurfaceManager::THintPair));
+
+	//create a surface owner for this surface
+	TProcessListItem* owner = new TProcessListItem;
+	TRACE(Kern::Printf("SM A %08x TProcessListItem CreateSurface",owner);)
+
+	if (!owner)
+		{
+		//destroy the chunk and cleanup, out of memory
+		Kern::ChunkClose(chunk);
+		delete(surface);
+		TRACE(Kern::Printf("SM D %08x TSurface CreateSurface",surface);)
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+	
+	owner->iCount = 1;		//mark it as open in this process
+	owner->iOwningProcess =  &Kern::CurrentProcess();
+	owner->iNext = NULL;
+		
+	surface->iOwners = owner;	//only 1 owner at creation time
+
+	NKern::FMWait(&iMutex);
+	//at this point we have a fully constructed TSurface
+	//add surface to head of surfaces list
+
+	//Mask off the bottom log2(KMaxLists) bits of the first word of the surfaceID as an index
+	//add the new surface to the beginning of the list 
+	TInt index = SurfaceIdToIndex(sid);
+	surface->iNext = iSurfacesIndex[index];
+	iSurfacesIndex[index] = surface;
+	NKern::FMSignal(&iMutex);		
+	NKern::ThreadLeaveCS();
+	
+	//write surface id back to user side
+	kumemput(reinterpret_cast<TSurfaceId*>(param.iSurfaceId), &sid, sizeof (TSurfaceId));
+	return KErrNone;
+	}
+
+
+/**
+Opens a surface.  If the current process already is in the owners list, its usage count is
+incremented.  If this is an open from a different process, a new surface owner object is added
+to the surface's list of owners and its usage count is set to 1.
+@param aId  The surface id of the surface to be opened.
+@return KErrNone if successful, otherwise a system error code
+@internalTechnology
+*/
+TInt DSurfaceManager::OpenSurface(const TSurfaceId* aId)
+	{
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, aId, sizeof (TSurfaceId));
+	NKern::ThreadEnterCS();
+	TProcessListItem* owner = new TProcessListItem;  //speculative creation
+	TRACE(Kern::Printf("SM A %08x TProcessListItem OpenSurface", owner);)
+	
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		delete owner;		//free the memory just allocated
+		TRACE(Kern::Printf("SM D %08x TProcessListItem OpenSurface", owner);)
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (so)
+		{
+		//already an owner so inc the ref count
+		++so->iCount;
+		}
+	else
+		{
+		//new process trying to open it
+		if (!owner)
+			{
+			//the creation of the owner information object failed, out of memory
+			NKern::FMSignal(&iMutex);
+			NKern::ThreadLeaveCS();
+			return KErrNoMemory;
+			}
+			
+		owner->iCount = 1;		//mark it open in this process
+		owner->iOwningProcess =  &Kern::CurrentProcess();
+		
+		//add the owner to the list of owners
+		owner->iNext = surface->iOwners;
+		surface->iOwners = owner;
+		owner = NULL;
+		}
+	NKern::FMSignal(&iMutex);
+	delete owner;		//free if not used.
+	TRACE(Kern::Printf("SM D %08x TProcessListItem OpenSurface", owner);)
+	NKern::ThreadLeaveCS();
+	return KErrNone;
+	}
+
+
+
+/**
+Closes a surface.  Decrements the usage count in the surface owner object
+if the usage count is then zero, removes this surface owner from the surface.
+If this results in a surface with no owners, the surface is deleted and the 
+surface shared chunk is closed.
+@param aId  The id of the surface to be closed
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+@internalTechnology
+*/
+TInt DSurfaceManager::CloseSurface(const TSurfaceId* aId)
+	{
+
+	TSurfaceId sid;
+	kumemget(&sid, aId, sizeof (TSurfaceId));	//fetch surface id from user memory
+	//look it up
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;
+		}
+
+	//current process is a surface owner so decrement the open count
+	TSurface* surfaceToDelete = NULL;
+	TProcessListItem* ownerToDelete = NULL;
+	DChunk* chunkToClose = NULL;
+	if (--so->iCount == 0)
+		{
+		//if count is now zero remove the owner
+		//surface->RemoveOwner(so);
+		UnlinkListItem(&surface->iOwners, so);
+		ownerToDelete = so;
+
+		//check to see if the surface has any owners
+		if (!surface->iOwners)
+			{
+			//no more owners of the surface
+			chunkToClose = surface->iChunk;
+
+			//remove the surface from the list
+			UnlinkListItem(&(iSurfacesIndex[SurfaceIdToIndex(surface->iId)]), surface);
+			surfaceToDelete = surface;
+			}
+		}
+	
+	NKern::FMSignal(&iMutex);
+
+	if (chunkToClose)
+		{
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+        TLinAddr kernelAddress;
+        TUint32 mapAttr;
+        TUint32 physicalAddress(0);
+        if (KErrNone == Kern::ChunkPhysicalAddress(chunkToClose, 0, chunkToClose->Size(), kernelAddress, mapAttr, physicalAddress))
+            {
+            Kern::Printf("Closing chunk: deallocate %u",physicalAddress);
+            iVHWMemoryManager->Deallocate(physicalAddress);
+            }
+#endif // GRAPHICS_SURFACEMANAGER_SYBORG
+		//surface has no more owners so close the chunk
+		Kern::ChunkClose(chunkToClose);
+		}
+
+	delete surfaceToDelete;
+	TRACE(Kern::Printf("SM D %08x TSurface CloseSurface",surfaceToDelete);)
+	delete ownerToDelete;
+	TRACE(Kern::Printf("SM D %08x TProcessListItem CloseSurface",ownerToDelete);)
+	NKern::ThreadLeaveCS();
+
+	return KErrNone;
+	}
+
+
+/**
+Maps the surface memory into the process of the calling thread. This will fail if
+the surface is not open in this process, or if the handle to the chunk cannot be created.
+@param aId  The id of the surface to be mapped in.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a
+surface, KErrAccessDenied if the surface is not open in the current process,
+KErrNotSupported if the surface is not mappable, KErrOverflow if the chunk limit has been
+exceeded in the moving memory model, otherwise a system wide error code.
+@internalTechnology
+*/
+TInt DSurfaceManager::MapSurface(const TSurfaceId* aId)
+	{
+	TSurfaceId sid;
+	kumemget(&sid, aId, sizeof (TSurfaceId));	//fetch surface id from user memory
+
+	//look it up
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;	//surface id is not valid or in the list of surfaces
+		}
+	if(!surface->iMappable)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();		
+		return KErrNotSupported;
+		}
+
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;	//can't map it in, it's not open in this process
+		}
+
+	DChunk* chunk = surface->iChunk;
+	TInt r = chunk->Open();
+	NKern::FMSignal(&iMutex);
+	TRACE(Kern::Printf("SM MapSurface chunk open r %d\n",r);)
+
+	if (r == KErrGeneral)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;
+		}
+
+	//if we are here, got the surface and we are the owner.
+	//if we are the owner we must have it open at least once
+
+	r = Kern::MakeHandleAndOpen(NULL, chunk);
+	chunk->Close(NULL);
+	TRACE(Kern::Printf("SM MapSurface handle open r: %d\n",r);)
+
+	NKern::ThreadLeaveCS();
+
+	return r;
+	}
+
+
+/**
+Record a new connection to the driver.
+Adds an element to the reference counted list of connected processes if the connection
+is from a new process, otherwise it increments the reference count.
+@param aProcess  The process which has opened a driver channel.
+@internalTechnology
+*/
+TInt DSurfaceManager::AddConnection(const DProcess* aProcess)
+	{
+	TRACE(Kern::Printf("SM AddConnection process %08x\n", aProcess);)
+	NKern::ThreadEnterCS();
+	TProcessListItem* connectedProcess = new TProcessListItem;  //speculative creation
+	TRACE(Kern::Printf("SM A %08x TProcessListItem AddConnection", connectedProcess);)
+	NKern::FMWait(&iMutex);
+	TProcessListItem* p = FindConnectedProcess(aProcess);
+	if (p)	//already connected, found the process
+		{
+		++p->iCount;
+		}
+	else
+		{
+		//add a new connected process
+		if (!connectedProcess)
+			{
+			//the creation of the owner information object failed, out of memory
+			NKern::FMSignal(&iMutex);
+			NKern::ThreadLeaveCS();
+			return KErrNoMemory;
+			}
+		connectedProcess->iOwningProcess = (DProcess*)aProcess;
+		connectedProcess->iCount=1;
+		
+		connectedProcess->iNext = iConnectedProcesses;
+		iConnectedProcesses = connectedProcess;
+		connectedProcess = NULL;
+		}
+	NKern::FMSignal(&iMutex);
+	delete connectedProcess;
+	TRACE(Kern::Printf("SM D %08x TProcessListItem AddConnection", connectedProcess);)
+	NKern::ThreadLeaveCS();
+	return KErrNone;
+	}
+	
+	
+	
+/**
+Called when the driver channel is closed.
+Decrements the reference count for the connected process, if the last connection
+for this process is closed (reference count reaches 0) it removes the process from the list.
+@param aProcess  The process which has closed the driver channel.
+@internalTechnology
+*/
+void DSurfaceManager::RemoveConnection(const DProcess* aProcess)
+	{
+	TRACE(Kern::Printf("SM RemoveConnection process %08x\n", aProcess);)
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	TProcessListItem* p =FindConnectedProcess(aProcess);
+	TProcessListItem* toDelete = NULL;
+	if (p)	//already connected, found the process
+		{
+		if (--p->iCount == 0) //last connection in process has disconnected
+			{
+			//remove the process from the list and cleanup
+			UnlinkListItem(&iConnectedProcesses, p);
+			toDelete = p;
+			}
+		}
+	NKern::FMSignal(&iMutex);
+	delete toDelete;
+	TRACE(Kern::Printf("SM D %08x TProcessListItem RemoveConnection ", toDelete);)
+	
+	
+	if (toDelete)	// if a process has closed its last channel, remove process from the surface owners.
+		{
+		CloseSurfaceHandlesForProcess(aProcess);
+		}
+
+	NKern::ThreadLeaveCS();
+	}
+	
+
+
+
+/**
+Closes all the surfaces belonging to the process which has just terminated.
+If this is the only owner of a surface, delete the surface.
+@param aProcess  The process which has terminated.
+@pre must be called in critical section
+@internalTechnology
+*/
+void DSurfaceManager::CloseSurfaceHandlesForProcess(const DProcess* aProcess)
+	{
+
+	NKern::FMWait(&iMutex);
+
+	TSurface* p = NULL;
+	TSurface* surfacesTodelete = NULL;
+	TProcessListItem* ownersTodelete = NULL;
+	TProcessListItem* so;
+	// There are 16 doubly linked lists managed by Surface Manager
+	for (TInt index = 0; index < KMaxLists; index++)
+		{
+		p = iSurfacesIndex[index];
+		while(p)
+			{
+			//see if the process which has just died is an owner of any surfaces
+			TSurface* surface = p;
+			p=p->iNext;
+			so = surface->ProcessOwnerInfo(aProcess);
+			if (so)
+				{
+				UnlinkListItem(&surface->iOwners, so);
+				so->iNext = ownersTodelete;	//add the owner to the list of owner objects to remove
+				ownersTodelete = so;
+
+				if (!surface->iOwners)	//if the surface hasn't any owners
+					{
+					//remove the surface from the list
+					UnlinkListItem(&iSurfacesIndex[index], surface);
+					surface->iNext = surfacesTodelete;	//add the surface to the list of surfaces to remove
+					surfacesTodelete = surface;
+					}
+				}
+			}
+		}
+	NKern::FMSignal(&iMutex);
+
+	while(surfacesTodelete)
+		{
+		p = surfacesTodelete->iNext;
+		Kern::ChunkClose(surfacesTodelete->iChunk);
+		TRACE(Kern::Printf("SM Close chunk %08x CloseSurfaceHandlesForProcess",surfacesTodelete->iChunk);)
+		delete surfacesTodelete;
+		TRACE(Kern::Printf("SM D %08x TSurface CloseSurfaceHandlesForProcess",surfacesTodelete);)
+		surfacesTodelete = p;
+		}
+
+	while(ownersTodelete)
+		{
+		so = ownersTodelete->iNext;
+		delete ownersTodelete;
+		TRACE(Kern::Printf("SM D %08x TProcessListItem CloseSurfaceHandlesForProcess",ownersTodelete);)
+		ownersTodelete = so;
+		}
+	}
+
+	
+/**
+Returns the metadata information about the specified surface.
+@param aId  The id of the surface.
+@param aInfo  Pointer to user side descriptor to receive the information.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+@internalTechnology
+*/	
+TInt DSurfaceManager::SurfaceInfo(const TSurfaceId* aId, TDes8* aInfo)
+	{
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, aId, sizeof (TSurfaceId));
+
+	RSurfaceManager::TInfoBuf buf;
+	RSurfaceManager::TSurfaceInfoV01& info = buf();
+
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrArgument;
+		}
+	
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrAccessDenied;	//can do this, not open
+		}
+	
+	//at this point, we have a surface, we are the owner and it's mapped in
+	info.iSize = surface->iSize; 									// Visible width/height in pixels
+	info.iBuffers = surface->iBuffers;								// Number of Buffers
+	info.iPixelFormat = surface->iPixelFormat;	      				// pixel format
+	info.iStride = surface->iStride;								// Number of bytes between start of one line and start of next
+	info.iContiguous = surface->iContiguous;						// is it physically contiguous
+	info.iCacheAttrib = surface->iCacheAttrib;						// Underlying chunk is CPU cached or not
+	info.iMappable = surface->iMappable;							// Is the surface Mappable
+	NKern::FMSignal(&iMutex);
+	
+	//copy it back to user side
+	Kern::InfoCopy(*aInfo, buf);
+	return KErrNone;
+	}
+
+
+
+/**
+Generates a unique surface id
+@param aId  Surface id reference to receive the generated id.
+@internalTechnology
+*/	
+void DSurfaceManager::GenerateSurfaceId(TSurfaceId& aId)
+	{
+	TSurfaceId id;
+	
+	for (TInt x = 0; x < 4; ++x)
+		{
+		id.iInternal[x] = Kern::Random();
+		};
+	
+	//package up the handle,
+	//set the type identifier
+	id.iInternal[3] &= 0x00FFFFFF;
+	id.iInternal[3] |= TSurfaceTypes::ESurfaceManagerSurface << 24;
+	aId = id;
+	TRACE(Kern::Printf("SM GenerateSurfaceId id = %u %u %u %u\n",id.iInternal[0],id.iInternal[1],id.iInternal[2],id.iInternal[3]);)
+	};
+	
+
+
+/**
+Validates the surface creation attributes and calculates the size of the chunk required.
+@param aAttribs  The surface creation attributes used to specify the surface requirements.
+@param aOffset  Set to the offset between buffers on successfull return.
+@param aNewChunk  If this is true, surface is created in a new chunk otherwise the surface is created in an existing chunk
+@return The size of chunk required.  A size of 0 indicates a problem.
+*/	
+TInt DSurfaceManager::ValidateAndCalculateChunkSize(RSurfaceManager::TSurfaceCreationAttributes& aAttribs, 
+			TInt& aOffset, TUint &aActualBufferSize, const TBool aNewChunk)
+	{
+/*	
+	TRACE(Kern::Printf("SM width = %d  height = %d\n", aAttribs.iSize.iWidth, aAttribs.iSize.iHeight);)
+	TRACE(Kern::Printf("SM buffers = %d\n", aAttribs.iBuffers);)
+	TRACE(Kern::Printf("SM format = %d\n", aAttribs.iPixelFormat);)
+	TRACE(Kern::Printf("SM stride = %d\n", aAttribs.iStride);)
+	TRACE(Kern::Printf("SM offset to first buffer = %d\n", aAttribs.iOffsetToFirstBuffer);)
+	TRACE(Kern::Printf("SM offset between buffer = %d\n", aOffset);)
+	TRACE(Kern::Printf("SM alignment = %d\n", aAttribs.iAlignment);)
+	TRACE(Kern::Printf("SM contiguous = %d\n\n", aAttribs.iContiguous);)
+	TRACE(Kern::Printf("SM cacheAttrib = %d\n\n", aAttribs.iCacheAttrib);)
+*/
+	//check for negative values
+	if(aAttribs.iOffsetToFirstBuffer < 0 || aOffset < 0 )
+		{
+		TRACE(Kern::Printf("SM Validate offset for negative value");)
+		return 0;
+		}
+
+	//check aligment is sensible
+	TInt alignmentMask = 0;
+	switch(aAttribs.iAlignment)
+		{
+		case 1:	
+		case 2:	
+		case 4: 
+		case 8: 
+		case 16: 
+		case 32: 
+			alignmentMask = 31; 
+			break;
+		case 64: 
+			alignmentMask = 63; 
+			break;
+		case RSurfaceManager::EPageAligned:
+			break;
+		default:
+			TRACE(Kern::Printf("SM Validate alignment");)
+			return 0;
+		}
+	
+	//check alignment issues.
+	if(aAttribs.iAlignment != RSurfaceManager::EPageAligned)
+		{
+		if(aNewChunk)	
+			{
+			if(aAttribs.iCacheAttrib == RSurfaceManager::ECached)	// Surface is CPU cached, so the alignment will be based on either 32 or 64 byte 
+				{
+				//offset to first buffer needs to fit alignment
+				aAttribs.iOffsetToFirstBuffer = aAttribs.iOffsetToFirstBuffer + alignmentMask & ~alignmentMask;
+				//alignment with respect to offsetbetweenbuffers
+				aOffset = aOffset + alignmentMask & ~alignmentMask;
+				}
+			else	// Surface is NOT CPU cached, so the alignment will be based on surface attribute alignment
+				{
+				TUint alignMask = aAttribs.iAlignment-1;
+				//offset to first buffer needs to fit alignment
+				aAttribs.iOffsetToFirstBuffer = aAttribs.iOffsetToFirstBuffer + alignMask & ~alignMask;
+				//alignment with respect to offsetbetweenbuffers
+				aOffset = aOffset + alignMask & ~alignMask;
+				}
+			}
+		else	// existing chunk
+			{
+			TUint alignMask = aAttribs.iAlignment-1;
+			//check alignment issues.  offset to first buffer needs to fit alignment
+			if (aAttribs.iOffsetToFirstBuffer & alignMask)
+				{
+				TRACE(Kern::Printf("SM Validate offset to first pixel misaligned");)
+				return 0;
+				}
+
+			//check alignment for offsetbetweenbuffers.  offset between buffer needs to fit alignment for existing chunks
+			if (aOffset & alignMask)
+				{
+				TRACE(Kern::Printf("SM Validate offset between buffers misaligned");)
+				return 0;
+				}
+			}
+		}
+	else	//page aligned
+		{
+		if(aNewChunk)// if its a new chunks and doesn't match exact alignment then do the rounding
+			{
+			TUint32 pageSize = Kern::RoundToPageSize(1);
+			//offset to first buffer needs to fit alignment
+			aAttribs.iOffsetToFirstBuffer = (aAttribs.iOffsetToFirstBuffer + (pageSize - 1)) & ~(pageSize - 1);
+			//alignment with respect to offsetbetweenbuffers
+			aOffset = (aOffset + (pageSize - 1)) & ~((pageSize - 1));
+			}
+		else	// for existing chunks don't do any rounding operation
+			{
+			TUint32 pageSize = Kern::RoundToPageSize(1);
+			TUint alignmask = aAttribs.iOffsetToFirstBuffer & (pageSize - 1);
+			if (alignmask)
+				{
+				TRACE(Kern::Printf("SM Validate offset to first pixel misaligned");)
+				return 0;
+				}
+			
+			alignmask = aOffset & (pageSize - 1);
+			if (alignmask)
+				{
+				TRACE(Kern::Printf("SM Validate offset between buffers misaligned");)
+				return 0;
+				}
+			}
+		}
+
+	//check width and height
+	if(aAttribs.iSize.iWidth <= 0 || aAttribs.iSize.iHeight <= 0)
+		{
+		TRACE(Kern::Printf("SM Validate width/height");)
+		return 0;
+		}
+	
+	
+	//check there is at least 1 buffer
+	if (aAttribs.iBuffers <= 0)
+		{
+		TRACE(Kern::Printf("SM Validate buffers");)
+		return 0;
+		}
+
+	//Sort the array and also check for duplication
+	if (!SortHints(aAttribs.iSurfaceHints,aAttribs.iHintCount)) 
+		{
+		TRACE(Kern::Printf("SM Validate Duplicate hint key");)
+		return 0;
+		}
+
+	TUint size = 0;
+	//calculate buffer size and round it to alignment or to page size
+	TInt64 bufferSize = aAttribs.iStride;
+	bufferSize  *= aAttribs.iSize.iHeight;
+
+	if (I64HIGH(bufferSize) > 0) //too big
+		{
+		TRACE(Kern::Printf("SM Validate chunk buffer size is out of range");)
+		return 0;
+		}
+	
+	TUint bsize = I64LOW(bufferSize);
+	if (bsize > KMaxTInt)
+		{
+		TRACE(Kern::Printf("SM Validate buffer size is out of range for TInt");)
+		return 0;
+		}
+
+	if(aAttribs.iAlignment == RSurfaceManager::EPageAligned)
+		{
+		bsize = Kern::RoundToPageSize(bsize);	//page alignment
+		}
+	else if(aAttribs.iCacheAttrib == RSurfaceManager::ECached)
+		{
+		bsize = bsize + alignmentMask & ~alignmentMask;	//CPU cached byte alignment, for minimum of the specified alignment(32 or 64)
+		}
+	else
+		{
+		bsize = bsize + (aAttribs.iAlignment-1) & ~(aAttribs.iAlignment-1);	//NON CPU cached byte alignment for 1, 2, 4, 8, 16, 32 and 64
+		}
+	
+	bufferSize = bsize;
+	// Remember the actual size. 
+	aActualBufferSize = bsize;
+
+	//if offset between buffers is zero, then assign the calculated value as offset between buffers
+	if(aOffset == 0)
+		{
+		//buffer size rounded to alignment as offset between buffers
+		aOffset = I64INT(bufferSize);
+		}
+	else if(aOffset < I64INT(bufferSize))
+		{
+		TRACE(Kern::Printf("SM Offset between the buffer is less than the required size");)
+		return 0;
+		}
+	else
+		{
+		//use the buffer size specified
+		bufferSize = aOffset;
+		}
+	
+	
+	TInt64 totalSize = aAttribs.iOffsetToFirstBuffer + (aAttribs.iBuffers * bufferSize);
+	
+	if (I64HIGH(totalSize) > 0) //too big
+		{
+		TRACE(Kern::Printf("SM Validate chunk size is out of range for RoundToPageSize");)
+		return 0;
+		}
+		
+	size = I64LOW(totalSize);
+	if (size > KMaxTInt)
+		{
+		TRACE(Kern::Printf("SM Validate size is out of range for TInt");)
+		return 0;
+		}
+
+	size = Kern::RoundToPageSize(size);
+
+	//check the size isn't greater than will fit in a TInt
+	if (size > KMaxTInt)
+		{
+		TRACE(Kern::Printf("SM Rounded size is out of range for TInt");)
+		return 0;
+		}
+	
+	TRACE(Kern::Printf("SM After validate - offset to first buffer = %d\n", aAttribs.iOffsetToFirstBuffer);)
+	TRACE(Kern::Printf("SM After validate - offset between buffer = %d\n", aOffset);)
+	TRACE(Kern::Printf("SM CalculateChunkSize size = %d\n", size);)
+	return size;
+	}
+
+
+/**
+Find the surface in the list.   
+@param aId  The surface id of the surface to find in the surface list
+@return pointer to the surface object
+@internalTechnology
+*/
+TSurface* DSurfaceManager::FindSurfaceById(const TSurfaceId& aId)
+	{
+	TSurface *p = iSurfacesIndex[SurfaceIdToIndex(aId)];
+	while (p)
+		{
+		if (aId == p->iId)
+			{
+			//found it
+			return p;
+			}
+	
+		p = p->iNext;
+		}
+	return NULL;
+	}
+
+
+/**
+Find the index of the hint key from the surface list using binary search.   
+@param aHintsArray  Pointer to the first element in the array of surface hints
+@param aKey  The surface hint key uid value to search in the surface list
+@return index of the hint pair key in the surface list, KErrNotFound if key not found
+@internalTechnology
+*/
+TInt DSurfaceManager::FindHintKey(const RSurfaceManager::THintPair* aHintsArray, TUint32 aKey) const
+	{
+	__ASSERT_DEBUG(aHintsArray != NULL, Kern::Fault("Surface Manager", __LINE__));
+
+	TInt bottom = 0;
+	TInt top = KMaxHintsPerSurface - 1;
+	TInt mid;
+	while (bottom <= top)
+		{
+	    mid = (bottom + top) / 2;
+	    if((TUint) aHintsArray[mid].iKey.iUid == aKey)
+	    	{
+	    	return mid;
+	    	} 
+	    else if ((TUint)aHintsArray[mid].iKey.iUid < aKey) 
+	    	{
+	    	top = mid - 1;
+	    	}
+	    else
+	    	{
+	    	bottom = mid + 1;
+	    	}
+	  }
+	return KErrNotFound;	//Hint key not found
+    }
+
+TProcessListItem* DSurfaceManager::FindConnectedProcess(const DProcess* aProcess)
+	{
+	TProcessListItem * p = iConnectedProcesses;
+	while (p)
+		{
+		if (aProcess == p->iOwningProcess)
+			{
+			//found it
+			return p;
+			}
+		
+		p = p->iNext;
+		}
+	return NULL;
+	}
+
+/**
+Searches for a right place to insert the new hint pair in a sorted array.
+@param aHintsArray  Pointer to the first element in the sorted array
+@param aKey  The surface hint key uid value to search in the surface list
+@pre, there is at least one empty place in the array
+@return KErrNone if a new hint pair key inserted in the surface list, KErrAlreadyExists if duplicated
+@internalTechnology
+*/
+TInt DSurfaceManager::InsertHintKey(RSurfaceManager::THintPair* aHintsArray, const RSurfaceManager::THintPair& aHintPair) const
+	{
+	__ASSERT_DEBUG(aHintsArray != NULL, Kern::Fault("Surface Manager", __LINE__));
+	__ASSERT_DEBUG(aHintsArray[KMaxHintsPerSurface-1].iKey.iUid == NULL, Kern::Fault("Surface Manager", __LINE__));
+
+	TInt pos = 0;
+	if (aHintsArray[pos].iKey.iUid != 0)
+		{
+		while((TUint)aHintsArray[pos].iKey.iUid>(TUint)aHintPair.iKey.iUid && pos < KMaxHintsPerSurface-1)
+			{// find the right place to insert
+			++pos;
+			}
+	
+		if((TUint)aHintsArray[pos].iKey.iUid==(TUint)aHintPair.iKey.iUid)
+			{
+			//Duplicate key 
+			return KErrAlreadyExists;
+			}
+		else
+			{
+			// Shift right
+			memmove(aHintsArray+pos+1, aHintsArray+pos, (KMaxHintsPerSurface-pos-1)*sizeof(RSurfaceManager::THintPair));		
+			}	
+		}
+	aHintsArray[pos] = aHintPair;
+	return KErrNone;
+	}
+
+/**
+Sort the surface hint array in descending order.
+@param aHintsArray  The surface hintpair in the surface list
+@param aNumberOfHints The number of hints
+@return ETrue if sorting is finished or it is an empty array, EFalse if key duplicated
+@internalTechnology
+*/
+TBool DSurfaceManager::SortHints(RSurfaceManager::THintPair* aHintsArray, TInt aNumberOfHints) const
+	{
+	TInt in = 0;
+	TInt out = 0;
+	RSurfaceManager::THintPair temp;
+	if(!aHintsArray)
+		{
+		return ETrue;
+		}
+	for(out = 0; out < aNumberOfHints; ++out) 
+		{
+		if(aHintsArray[out].iKey.iUid != 0)
+			{
+			temp = aHintsArray[out];   
+			in = out;          // start shifting at out
+			while(in > 0 && (TUint)aHintsArray[in-1].iKey.iUid <= (TUint)temp.iKey.iUid)
+				{
+				if ((TUint)aHintsArray[in-1].iKey.iUid == (TUint)temp.iKey.iUid)
+					{
+					return EFalse;		//duplicate hint keys are not allowed
+					}
+				aHintsArray[in] = aHintsArray[in-1];     // shift item to the right
+				--in;          // go left one position
+				}
+			aHintsArray[in] = temp;        // insert marked item
+			}
+		}
+	return ETrue;
+	}
+
+
+/**
+Ensures the memory is updated consistently before/after triggering non CPU hardware access. 
+@param aParam  The suface id and buffer number (0 based).
+@param aOperation  The type of the synchronize operation. 
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+buffer number is invalid, KErrAccessDenied if the surface is not open in this
+process, otherwise a system wide error code.
+@see RSurfaceManager::TSyncOperation
+@internalTechnology
+*/	
+TInt DSurfaceManager::SynchronizeCache(RSurfaceManagerDriver::TDeviceParam* aParam, RSurfaceManager::TSyncOperation aOperation)
+	{
+	//Parse the parameters
+	RSurfaceManagerDriver::TDeviceParam param;
+	kumemget(&param, aParam, sizeof(RSurfaceManagerDriver::TDeviceParam));
+	TSurfaceId sid;
+	kumemget(&sid, param.iSurfaceId, sizeof(TSurfaceId));
+	TInt buffer = (TInt)param.iBuffer;
+	
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+	
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;
+		}
+
+	// surfaces have to have at least one buffer
+	__ASSERT_DEBUG(surface->iBuffers > 0, Kern::Fault("Surface Manager", __LINE__));
+	
+	//Validate the buffer number is within range
+	if((buffer >= surface->iBuffers) || (buffer < 0))
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+
+	DChunk* chunk = surface->iChunk;
+	TInt offsetBetweenBuffers = surface->iOffsetBetweenBuffers;
+	NKern::FMSignal(&iMutex);
+
+	TUint32 kernAddr;
+	TUint32 mapAttr;
+	TUint32 physAddr;
+	TInt pageList = chunk->iSize / Kern::RoundToPageSize(1) + 1;
+	TUint32* physAddr2 = new TUint32[pageList];
+	if(!physAddr2)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+	
+	TRACE(Kern::Printf("SM %08x DChunk SynchronizeCache", chunk);)
+	
+	//Retrieve the kernel address and mapping attribute from the chunk
+	TInt err = Kern::ChunkPhysicalAddress(chunk, surface->iOffsetToFirstBuffer + (buffer * offsetBetweenBuffers), offsetBetweenBuffers, kernAddr, mapAttr, physAddr, physAddr2);
+	delete[] physAddr2;
+	if(err >= KErrNone)
+		{
+		TRACE(Kern::Printf("SM %08x kernAddr SynchronizeCache", kernAddr);)
+		TRACE(Kern::Printf("SM %08x mapAttr SynchronizeCache", mapAttr);)
+		err = KErrNone;
+
+		// Do the sync operation
+		switch(aOperation)
+			{
+			case RSurfaceManager::ESyncBeforeNonCPURead:
+				Cache::SyncMemoryBeforeDmaWrite(kernAddr, offsetBetweenBuffers, mapAttr);
+				break;
+			case RSurfaceManager::ESyncBeforeNonCPUWrite:
+				Cache::SyncMemoryBeforeDmaRead(kernAddr, offsetBetweenBuffers, mapAttr);
+				break;
+			case RSurfaceManager::ESyncAfterNonCPUWrite:
+				Cache::SyncMemoryAfterDmaRead(kernAddr, offsetBetweenBuffers);
+				break;
+			default: 
+				err = KErrArgument;
+				break;
+			}			
+		}
+	NKern::ThreadLeaveCS();
+
+	return err;
+	}
+
+
+/**
+Get the surface hint value for the given surface ID and hint pair key.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHintPair  The hint value for the requested hint pair key.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+invalid hint pair key used, KErrAccessDenied if the surface is not open in the
+current process, otherwise a system wide error code.
+@internalTechnology
+*/ 
+TInt DSurfaceManager::GetSurfaceHint(const TSurfaceId* aSurfaceId, RSurfaceManager::THintPair* aHintPair)
+	{
+	RSurfaceManager::THintPair hintPair;
+	kumemget(&hintPair, aHintPair, sizeof(RSurfaceManager::THintPair));
+
+	if (hintPair.iKey.iUid == 0)
+		{
+		TRACE(Kern::Printf("SM GetSurfaceHint Hint key is invalid");)
+		return KErrArgument;	//Invalid Hint key
+		}
+	
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, aSurfaceId, sizeof (TSurfaceId));
+
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrArgument;
+		}
+	
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrAccessDenied;
+		}
+	
+	//at this point, we have a surface, we have to find the hint value based on the hint pair key
+	TInt index = FindHintKey(surface->iSurfaceHints, hintPair.iKey.iUid);
+
+	if (index == KErrNotFound)
+		{
+		TRACE(Kern::Printf("SM GetSurfaceHint Hint key not found");)
+		NKern::FMSignal(&iMutex);
+		return KErrArgument;	//Hint key not found
+		}
+
+	RSurfaceManager::THintPair hint = surface->iSurfaceHints[index];
+	NKern::FMSignal(&iMutex);
+		
+	TRACE(Kern::Printf("SM GetSurfaceHint Hint value %d", hint.iValue);)
+	//write it back to user side
+	kumemput(aHintPair, &hint, sizeof(RSurfaceManager::THintPair));
+	return KErrNone;
+	}
+
+
+/**
+Set the surface hint value for an existing surface hint key of the surface Id.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHintPair  The value of the hint pair to set.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or if invalid
+hint key used, KErrAccessDenied if the hint pair is immutable or the surface is not open
+in the current process, otherwise a system wide error code.
+@internalTechnology
+*/ 
+TInt DSurfaceManager::SetSurfaceHint(const TSurfaceId* aSurfaceId, const RSurfaceManager::THintPair* aHintPair)
+	{
+	RSurfaceManager::THintPair hintPair;
+	kumemget(&hintPair, aHintPair, sizeof(RSurfaceManager::THintPair));
+
+	//Check for valid hint key
+	if (!hintPair.iKey.iUid)
+		{
+		TRACE(Kern::Printf("SM SetSurfaceHint Hint key is invalid");)
+		return KErrArgument;	//Invalid Hint key
+		}
+	
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, aSurfaceId, sizeof (TSurfaceId));
+
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+	
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;
+		}
+	
+	//at this point, we have a surface, we have to find the hint value based on the hint pair key
+	TInt index = FindHintKey(surface->iSurfaceHints, hintPair.iKey.iUid);
+	if (index == KErrNotFound)
+		{
+		TRACE(Kern::Printf("SM SetSurfaceHint Hint key not found or invalid");)
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;	//Hint key not found or invalid
+		}
+	
+	//Check for mutability
+	if(!surface->iSurfaceHints[index].iMutable)
+		{
+		TRACE(Kern::Printf("SM SetSurfaceHint Hint is immutable");)
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;	//Hint pair is immutable
+		}
+	TRACE(Kern::Printf("SM SetSurfaceHint Hint key found and updated its value %d for the surface %08x \n", aHintPair->iValue, &sid);)
+	
+	//set the hint pair value now
+	memcpy(&surface->iSurfaceHints[index], &hintPair, sizeof(RSurfaceManager::THintPair));
+	NKern::FMSignal(&iMutex);
+	NKern::ThreadLeaveCS();
+
+	return KErrNone;
+	}
+
+/**
+Add a new surface hint value for the surface Id.
+@param aSurfaceId  The surface identifier originally returned when the surface was created.
+@param aHintPair  The value of the hint pair to Add.
+@return Returns KErrNone if successful, KErrArgument if the surface ID is invalid or the
+hint pair has invalid key UID, KErrAccessDenied if the surface is not open in the current
+process, KErrAlreadyExists if duplicate hint key used, KErrOverflow if no space to add new
+pair, otherwise a system wide error code.
+@internalTechnology
+*/ 
+TInt DSurfaceManager::AddSurfaceHint(const TSurfaceId* aSurfaceId, const RSurfaceManager::THintPair* aHintPair)
+	{
+	RSurfaceManager::THintPair hintPair;
+	kumemget(&hintPair, aHintPair, sizeof(RSurfaceManager::THintPair));
+
+	//Check for valid hint key
+	if (hintPair.iKey.iUid == 0)
+		{
+		TRACE(Kern::Printf("SM AddSurfaceHint Hint key is invalid");)
+		return KErrArgument;	//Invalid Hint key
+		}
+	
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, aSurfaceId, sizeof (TSurfaceId));
+
+	NKern::ThreadEnterCS();
+	NKern::FMWait(&iMutex);
+	//look it up
+	TSurface* surface = FindSurfaceById(sid);
+	if (!surface)	
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrArgument;
+		}
+	
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrAccessDenied;
+		}
+	
+
+	//Check for empty hint pair
+	if(surface->iSurfaceHints[KMaxHintsPerSurface - 1].iKey.iUid != 0)//at least end of sorted hint array should be 0 to add a new hint
+		{
+		TRACE(Kern::Printf("SM AddSurfaceHint there is no room to add the hint");)
+		NKern::FMSignal(&iMutex);
+		NKern::ThreadLeaveCS();
+		return KErrOverflow;	//No room for new hint
+		}
+	//We found room for a new hint pair, so insert it in the array
+	// Meanwhile, we check for duplication, if it is, return KErrAlreadyExists
+	TInt err = InsertHintKey(surface->iSurfaceHints,hintPair);
+	NKern::FMSignal(&iMutex);
+	TRACE(Kern::Printf("SM AddSurfaceHint Added new key ");)
+	NKern::ThreadLeaveCS();
+	return err;
+	}
+
+/**
+Get the offset of the specified buffer from the base address of the underlying
+chunk.
+
+To obtain the address of the buffer, the offset returned must be added onto the
+base address of the RChunk returned in a call to MapSurface(). Note that
+buffer offsets are immutable during the lifetime of the surface.
+@param aParam The input parameters including the surface ID and buffer index.
+@pre The surface is open in the calling process.
+@return KErrNone if successful, KErrArgument if aSurfaceId or aBuffer are invalid,
+KErrAccessDenied if the surface is not open in the current process, KErrNotSupported if
+the surface is not mappable, otherwise a system wide error code.
+*/
+TInt DSurfaceManager::GetBufferOffset(RSurfaceManagerDriver::TDeviceParam* aParam,TUint* aOffset)
+	{
+	//Get the input parameters
+	RSurfaceManagerDriver::TDeviceParam param;
+	kumemget(&param, aParam, sizeof(RSurfaceManagerDriver::TDeviceParam));
+	TSurfaceId sid;
+	//fetch surface id from user memory
+	kumemget(&sid, param.iSurfaceId, sizeof(TSurfaceId));
+	//(TAny*)iBuffer holds the buffer number in its value
+	TInt bufferNumber = (TInt) param.iBuffer;
+	
+	TSurface* surface = NULL;
+	NKern::FMWait(&iMutex);
+	surface = FindSurfaceById(sid);
+	if(NULL == surface || (bufferNumber >= surface->iBuffers))
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrArgument;
+		}
+	if(!surface->iMappable)
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrNotSupported;
+		}
+	//find the owner
+	TProcessListItem* so = surface->ProcessOwnerInfo(&Kern::CurrentProcess());
+	if (!so)
+		{
+		NKern::FMSignal(&iMutex);
+		return KErrAccessDenied;		
+		}
+	TInt bufferOffset = surface->iOffsetToFirstBuffer + bufferNumber*surface->iOffsetBetweenBuffers;
+	NKern::FMSignal(&iMutex);
+	
+	kumemput(aOffset, &bufferOffset, sizeof (TInt));
+	return KErrNone;
+	}
+
+/**
+Returns information specific to the Surface Manager implementation.
+@param aAttrib: Attribute to retrieve
+@param aValue : Output parameter where we write the value for the specified attribute
+@return KErrNone if successful or KErrArgument if the attribute UID is not recognized
+@internalTechnology
+*/
+TInt DSurfaceManager::GetSurfaceManagerAttrib(RSurfaceManager::TSurfaceManagerAttrib* aAttrib,TInt* aValue)
+	{
+	RSurfaceManager::TSurfaceManagerAttrib attrib;
+	kumemget(&attrib, aAttrib, sizeof(RSurfaceManager::TSurfaceManagerAttrib));
+	
+	TInt out=KErrNone;
+	TInt value;
+	switch (attrib)
+		{
+		case RSurfaceManager::EMaxNumberOfHints:
+			value=KMaxHintsPerSurface;
+			break;		
+		
+		default:
+			out=KErrArgument;
+			break;			
+		};
+	
+	if (out==KErrNone)
+		{
+		kumemput(aValue, &value, sizeof (TInt));
+		}	
+	return out;
+	}
+
+#ifdef GRAPHICS_SURFACEMANAGER_SYBORG
+TInt DSurfaceManager::CreateMemory()
+	{
+	Kern::Printf("DSurfaceManager::CreateMemory()>");
+	TUint32 physicalAddress = DVirtualVideoHwInterface::GetFrameBase();
+	Kern::Printf("DSurfaceManager::CreateMemory: 0x%08x",physicalAddress);
+	if( physicalAddress != 0 )
+		{
+		iVHWMemoryManager = new DVirtualHWMemoryManager( physicalAddress, VVI_FRAMEBUFFER_MEMORY_SIZE );
+		Kern::Printf("DSurfaceManager::CreateMemory: iVHWMemoryManager: 0x%08x",iVHWMemoryManager);
+		}
+	else
+		{
+		iVHWMemoryManager = NULL;
+		}
+	return 0;
+	}
+#endif // GRAPHICS_SURFACEMANAGER_SYBORG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/src/surfacemanager.cpp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,371 @@
+// Copyright (c) 2006-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
+@publishedPartner
+@prototype
+
+*/
+
+#include <e32base.h>
+#include <graphics/surfacemanager.h>
+#include "../inc/surfacemanagerdriver.h"
+
+/**
+Default constructor
+*/
+EXPORT_C RSurfaceManager::RSurfaceManager()
+	{
+	__ASSERT_COMPILE(sizeof(RSurfaceManagerDriver) <= sizeof(iDriverBuf));
+	new(iDriverBuf) RSurfaceManagerDriver();
+	}
+
+/**
+Opens a connection to the Surface Manager.
+
+The connection needs to be closed by calling Close() when it is no longer required.
+@return Returns KErrNone if successful, otherwise a system wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::Open()
+	{
+	TInt err = User::LoadLogicalDevice( RSurfaceManagerDriver::Name() );
+	if(! ((KErrNone == err) || (KErrAlreadyExists == err)))
+		{
+		return err;
+		}
+	return Driver().Open();
+	}
+
+/**
+Closes the connection to the Surface Manager.
+
+Cleanup is performed by the Surface Manager when a client process exits or
+closes its last connection. It is not guaranteed that the resources held by the
+Surface Manager are going to be released synchronously.
+*/
+EXPORT_C void RSurfaceManager::Close()
+	{
+	Driver().Close();
+	}
+
+/**
+Returns information specific to the Surface Manager implementation.
+@param aAttrib Attribute to retrieve
+@param aValue Output parameter set to the value for the specified attribute
+@return KErrNone if successful, KErrNotReady if the Surface Manager hasn't been
+opened, KErrArgument if the attribute UID is not recognized, otherwise a system
+wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::GetSurfaceManagerAttrib(TSurfaceManagerAttrib aAttrib, TInt& aValue)
+	{
+	return Driver().GetSurfaceManagerAttrib(aAttrib, aValue);
+	}
+
+/**
+Opens a surface.
+
+If the surface is already open in this process, this call increments the
+reference count for the surface for this process. If the surface hasn't been opened
+in this process, it opens the surface in this process and sets the reference count
+to 1 for this process.
+
+A surface will be deleted when all its reference counts are 0.
+@param aSurfaceId  The surface id originally returned when the surface was created.
+@pre The surface id is for an existing surface.
+@post The surface is open in this process.
+@return KErrNone if successful otherwise a system wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::OpenSurface(const TSurfaceId& aSurfaceId)
+	{
+	return Driver().OpenSurface(aSurfaceId);
+	}
+
+/**
+Creates a surface and returns its global unique identifier.
+
+Depending on the implementation, this method will allocate the surface in a new
+shared chunk or in external memory. Surfaces created in external memory cannot
+be mapped (see TSurfaceInfoV01::iMappable for more information). If the creation
+succeeds, the surface will be opened with a reference count of 1 in the calling
+process.
+
+The Surface Manager implementation should validate at least the following:
+	-	The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned.
+	-	The offset to first buffer is correctly aligned.
+	-	The width and height are both greater than zero.
+	-	There is at least one buffer.
+	-	The calculated chunk size isn't so big that it will exceed a signed int.
+	-	The caching attribute is valid
+	-	If the offset between the start of one buffer and the next is specified
+		(not zero), it must be correctly aligned and at least as big as the 
+		buffer size calculated from the height and stride.
+	-	A surface hint key of zero is allowed when creating a surface, it is ignored
+
+The Surface Manager implementation will treat iStride, iOffsetToFirstBuffer, and
+iOffsetBetweenBuffers as minimum values as opposed to required values. The caller
+of this method must not rely on the passed values as it is not guaranteed that
+they remain the same after surface creation (SurfaceInfo() and GetBufferOffset()
+should be used instead).
+
+If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout
+buffer at its own discretion. Although, a buffer's offset must remain constant
+during the surface's lifetime.
+
+If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface()
+will fail.
+
+@param aReqs Input parameter, specifies attributes of the surface required.
+@param aSurfaceId Output parameter, the surface ID, set if the call succeeds.
+@pre The Surface Manager has been successfully opened.
+@post The surface is created and opened in the creating process.
+@return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect,
+KErrNoMemory if the surface cannot be created due to out of memory, KErrOverflow if
+the chunk limit has been exceeded in the moving memory model, otherwise a standard
+Symbian error code.
+*/
+EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId)
+	{
+	return Driver().CreateSurface(aReqs,aSurfaceId);
+	}
+
+/**
+Creates a surface in an existing shared chunk specified by the caller and returns
+its global unique identifier.
+
+If the creation succeeds, the surface will be opened with a reference count of 1 in the calling
+process.
+
+The Surface Manager implementation should validate at least the following:
+	-	The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned.
+	-	The offset to first buffer is correctly aligned.
+	-	The width and height are both greater than zero.
+	-	There is at least one buffer.
+	-	The calculated chunk size isn't so big that it will exceed a signed int.
+	-	The caching attribute is valid
+	-	If the offset between the start of one buffer and the next is specified
+		(not zero), it must be correctly aligned and at least as big as the 
+		buffer size calculated from the height and stride.
+	-	A surface hint key of zero is allowed when creating a surface, it is ignored
+
+If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout
+buffer at its own discretion. Although, a buffer's offset must remain constant
+during the surface's lifetime.
+
+The attributes iContiguous and iCacheAttribute are ignored for existing chunks.
+
+Also, note that surface manager will not do any rounding for offset to first
+buffer and offset between buffers. It is up to the user, to give exact aligned
+values for this attributes, otherwise surface creation will fail.
+
+If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface()
+will fail.
+
+@param aReqs Input parameter, specifies attributes of the surface required.
+@param aSurfaceId Output parameter, the surface ID, set if the call succeeds.
+@param aChunkHandle Handle of the existing shared chunk.
+@pre The Surface Manager has been successfully opened.
+@pre A valid shared chunk exists. The shared chunk type should be Shared Kernel
+multiple and should be right the size, i.e. the size should be calculated as
+Offset to first buffer + (the number of buffers * ((stride * height *
+pixel depth in bytes) rounded up to the specified alignment) all rounded to a page size
+@post The Surface Manager has opened the chunk.
+@post The surface is created and opened in the creating process.
+@return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect. 
+KErrNotReady if the handle is of an invalid shared chunk memory
+*/ 
+EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId, const RChunk& aChunkHandle)
+	{
+	return Driver().CreateSurface(aReqs,aSurfaceId,aChunkHandle);
+	}
+
+/**
+Closes the surface. Decrements the reference count for the surface for the calling
+process.
+
+If the surface has other owners, it will not be deleted from memory. If this is
+the last process to close the surface, the surface will be deleted and the
+surface ID will become invalid. Resources associated with the surface are not
+guaranteed to be released synchronously.
+@param aSurfaceId The surface identifier originally returned when the surface was created.
+@pre The surface is open.
+@post The surface is closed.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+*/
+EXPORT_C TInt RSurfaceManager::CloseSurface(const TSurfaceId& aSurfaceId)
+	{
+	return Driver().CloseSurface(aSurfaceId);
+	}
+
+/**
+Maps the surface into the current client process address space.
+
+The actual memory will remain mapped into the calling process for as long as
+the RChunk handle aChunk is open.
+
+Whether or not a surface is mappable is determined at creation time, see 
+TSurfaceCreationAttributes::iMappable.
+
+The address of the pixel data in buffer N is chunk.Base() + GetBufferOffset(N).
+
+Surfaces created with existing shared chunks will get the same chunk handle.
+
+The RChunk handle is owned by the calling thread, so will need to be duplicated
+if passed to other threads in the process.
+@param aSurfaceId The surface identifier originally returned when the surface was created.
+@param aHandle Output parameter, handle to the implementation specific Shared Chunk.
+@pre The surface is open.
+@post The surface memory will be mapped into the calling process's address space.
+The surface is mapped.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a
+surface, KErrAccessDenied if the surface is not open in the current process,
+KErrNotSupported if the surface is not mappable, KErrOverflow if the chunk limit has been
+exceeded in the moving memory model, otherwise a system wide error code.
+@see RChunk
+@see RHandleBase::Duplicate
+@see TSurfaceCreationAttributes::iMappable
+*/
+EXPORT_C TInt RSurfaceManager::MapSurface(const TSurfaceId& aSurfaceId, RChunk& aHandle)
+	{
+	return Driver().MapSurface(aSurfaceId,aHandle);
+	}
+
+/**
+Returns information about a particular surface identified by its surface ID.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aInfo TInfoBuf to receive the information about the surface.
+@pre The surface is open in the calling process.
+@return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface,
+KErrAccessDenied if the surface is not open in the current process, otherwise a system wide
+error code.
+*/
+EXPORT_C TInt RSurfaceManager::SurfaceInfo(const TSurfaceId& aSurfaceId, TInfoBuf& aInfo)
+	{
+	return Driver().SurfaceInfo(aSurfaceId,aInfo);
+	}
+
+/**
+This function ensures the memory is updated consistently before and/or after
+triggering non CPU hardware access. Also ensures the CPU cache and the physical
+memory are in a consistent state before and after non CPU hardware or DMA access
+to the physical memory.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aBuffer The buffer number indexed from 0 within the surface whose memory
+region is to be flushed. 
+@param aOperation Specifies the sync operation as before non CPU hardware reads
+or before non CPU hardware writes or after non CPU hardware writes between
+physical memory of the surface and the cache contents.
+@pre The surface is open in the calling process.
+@post The surface buffer memory will be synchronized properly with cache contents.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+buffer number is invalid, KErrAccessDenied if the surface is not open in this
+process, otherwise a system wide error code.
+*/ 
+EXPORT_C TInt RSurfaceManager::SynchronizeCache(const TSurfaceId& aSurfaceId, TInt aBuffer, TSyncOperation aOperation)
+	{
+	return Driver().SynchronizeCache(aSurfaceId,aBuffer,aOperation);
+	}
+
+/**
+Get the surface hint value for the given surface ID and hint pair key.
+@param aSurfaceId  The surface identifier originally returned when the surface
+was created.
+@param aHint The hint value for the requested hint pair key.
+@pre The surface is open in the calling process.
+@pre Hint key should be a key for a hint set for this surface.
+@post The hint value will be updated in the hint pair.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or
+invalid hint pair key used, KErrAccessDenied if the surface is not open in the
+current process, otherwise a system wide error code.
+*/ 
+EXPORT_C TInt RSurfaceManager::GetSurfaceHint(const TSurfaceId& aSurfaceId, THintPair& aHint)
+	{
+	return Driver().GetSurfaceHint(aSurfaceId,aHint);
+	}
+
+/**
+Set the surface hint value for the surface ID.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aHint The value of the hint pair to set.
+@pre The surface is open in the calling process.
+@pre The hint key should be a key for a hint set for this surface.
+@pre Only mutable hints can be updated.
+@post The hint value will be updated in the surface hint pair.
+@return KErrNone if successful, KErrArgument if the surface ID is invalid or if invalid
+hint key used, KErrAccessDenied if the hint pair is immutable or the surface is not open
+in the current process, otherwise a system wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::SetSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint)
+	{
+	return Driver().SetSurfaceHint(aSurfaceId,aHint);
+	}
+
+/**
+Adds a new surface hint to the surface.
+
+This function will fail if the surface already has its maximum number of hints 
+or if the hint key is a duplicate or invalid.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aHint The value of the hint pair to add.
+@pre The surface is open in the calling process.
+@pre At least one free space to add a hint pair.
+@pre The new hint key should be non zero and unique for this surface.
+@post New hint pair will be added in the surface.
+@return Returns KErrNone if successful, KErrArgument if the surface ID is invalid or the
+hint pair has invalid key UID, KErrAccessDenied if the surface is not open in the current
+process, KErrAlreadyExists if duplicate hint key used, KErrOverflow if no space to add new
+pair, otherwise a system wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::AddSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint)
+	{
+	return Driver().AddSurfaceHint(aSurfaceId,aHint);
+	}
+
+/**
+Get the offset of the specified buffer from the base address of the underlying
+chunk.
+
+To obtain the address of the buffer, the offset returned must be added onto the
+base address of the RChunk returned in a call to MapSurface(). Note that
+buffer offsets are immutable during the lifetime of the surface.
+@param aSurfaceId The surface identifier originally returned when the surface
+was created.
+@param aBuffer The buffer for which the offset is requested. Indexed from 0.
+@param aOffset Output parameter set to the offset within the chunk.
+@pre The surface is open in the calling process.
+@return KErrNone if successful, KErrArgument if aSurfaceId or aBuffer are invalid,
+KErrAccessDenied if the surface is not open in the current process, KErrNotSupported if
+the surface is not mappable, otherwise a system wide error code.
+*/
+EXPORT_C TInt RSurfaceManager::GetBufferOffset(const TSurfaceId& aSurfaceId, TInt aBuffer, TInt& aOffset)
+	{
+	return Driver().GetBufferOffset(aSurfaceId, aBuffer, aOffset);
+	}
+
+/**
+Get a reference of the implementation of the surface manager.
+@return reference of the implementation of the surface manager
+*/
+inline RSurfaceManagerDriver& RSurfaceManager::Driver()
+	{
+	return reinterpret_cast<RSurfaceManagerDriver&>(*iDriverBuf);
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/src/surfacemanagerdriver.cpp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,226 @@
+// Copyright (c) 2006-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:
+//
+
+
+#include <kernel/kern_priv.h>
+#include <graphics/surfacemanager.h>
+#include "../inc/surfacemanager_dev.h"
+
+
+
+
+DECLARE_EXTENSION_LDD()
+	{
+	return new DSurfaceManagerFactory;
+	}
+
+static DSurfaceManager Manager;
+
+
+
+DSurfaceManagerFactory::DSurfaceManagerFactory()
+	{
+	// Set version number for this device
+	iVersion=RSurfaceManagerDriver::VersionRequired();
+
+	iParseMask=0;
+	}
+
+TInt DSurfaceManagerFactory::Install()
+	{
+	return SetName(&RSurfaceManagerDriver::Name());
+	}
+
+
+/**
+  Called by the kernel's device driver framework to create a Logical Channel.
+  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+  (E.g. through a call to RBusLogicalChannel::DoCreate)
+  The thread is in a critical section.
+
+  @param aChannel  Set to point to the created Logical Channel
+
+  @return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DSurfaceManagerFactory::Create(DLogicalChannelBase*& aChannel)
+	{
+	aChannel=new DSurfaceManagerChannel();
+	if(!aChannel)
+		return KErrNoMemory;
+	return KErrNone;
+	}
+
+
+
+/**
+  Return the drivers capabilities.
+  Called in the response to an RDevice::GetCaps() request.
+
+  @param aDes  User-side descriptor to write capabilities information into
+*/
+void DSurfaceManagerFactory::GetCaps(TDes8& aDes) const
+	{
+	// Create a capabilities object
+	RSurfaceManagerDriver::TCaps caps;
+	caps.iVersion = iVersion;
+	// Write it back to user memory
+	Kern::InfoCopy(aDes,reinterpret_cast<TUint8*>(&caps),sizeof(caps));
+	}
+
+
+
+DSurfaceManagerChannel::DSurfaceManagerChannel()
+	{
+	TRACE(Kern::Printf("SurfaceManagerChannel Creation");)
+	}
+
+
+/**
+Channel destructor.
+Called when the process owning the channel has died or closed the channel.
+Calls the manager object to indicate that the process has closed a session so it 
+can cleanup the surfaces which are only owned by that process if it has no further connections.
+*/
+DSurfaceManagerChannel::~DSurfaceManagerChannel()
+	{
+	Manager.RemoveConnection(iOwner);
+	}
+
+
+/**
+  Second stage constructor called by the kernel's device driver framework.
+  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+  (E.g. through a call to RBusLogicalChannel::DoCreate)
+  The thread is in a critical section.
+
+  @param aUnit  The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aInfo  The info argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aVer  The version argument supplied by the client to RBusLogicalChannel::DoCreate
+
+  @return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DSurfaceManagerChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
+	{
+	// Check version
+	if (!Kern::QueryVersionSupported(RSurfaceManagerDriver::VersionRequired(),aVer))
+		return KErrNotSupported;
+	
+	iOwner = &Kern::CurrentProcess();
+	TInt ret = Manager.AddConnection(iOwner);
+	if (ret != KErrNone)
+		iOwner = NULL;
+	
+	return ret;
+	}
+	
+
+
+/**
+  Process a request on this logical channel.
+
+  @param aReqNo Request number:
+  	            ==KMaxTInt, a 'DoCancel' message
+	            >=0, a 'DoControl' message with function number equal to iValue
+	            <0, a 'DoRequest' message with function number equal to ~iValue
+  @param a1     First argument. For DoRequest requests this is a pointer to the TRequestStatus.
+  @param a2     Second argument. For DoRequest this is a pointer to the 2 actual TAny* arguments.
+
+  @return       Result ignored by device driver framework for DoRequest requests.
+*/
+TInt DSurfaceManagerChannel::Request(TInt aReqNo, TAny* a1, TAny* a2)
+	{
+	// Decode the message type and dispatch it to the relevent handler function...
+	// only using synchronous control messages
+	if (static_cast<TUint>(aReqNo) < static_cast<TUint>(KMaxTInt))
+		{
+		return DoControl(aReqNo, a1, a2);
+		}
+
+	return KErrNotSupported;
+	}
+
+/**
+  Process synchronous 'control' requests
+*/
+TInt DSurfaceManagerChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
+	{
+	TRACE(Kern::Printf(">DSurfaceManagerChannel::DoControl fn=%d process = %u\n",aFunction, iOwner);)
+
+	TInt r;
+	switch(aFunction)
+		{
+		case RSurfaceManagerDriver::EControlCreateSurface:
+			r = Manager.CreateSurface(reinterpret_cast<const TDesC8*>(a1), reinterpret_cast<TSurfaceId*>(a2));
+			break;
+			
+		case RSurfaceManagerDriver::EControlOpenSurface:
+			r = Manager.OpenSurface(reinterpret_cast<TSurfaceId*>(a1));
+			break;
+			
+		case RSurfaceManagerDriver::EControlCloseSurface:
+			r = Manager.CloseSurface(reinterpret_cast<TSurfaceId*>(a1));
+			break;
+			
+		case RSurfaceManagerDriver::EControlAccessSurfaceData:
+			r = Manager.MapSurface(reinterpret_cast<TSurfaceId*>(a1));
+			break;
+			
+		case RSurfaceManagerDriver::EControlSurfaceInfo:
+			r = Manager.SurfaceInfo(reinterpret_cast<TSurfaceId*>(a1), reinterpret_cast<TDes8*>(a2));
+			break;
+
+		case RSurfaceManagerDriver::EControlCreateSurfaceEx:
+			r = Manager.CreateSurface(reinterpret_cast<RSurfaceManagerDriver::TDeviceParam*>(a1), (TInt)a2);
+			break;
+			
+		case RSurfaceManagerDriver::EControlSynchronizeCache:
+			r = Manager.SynchronizeCache(reinterpret_cast<RSurfaceManagerDriver::TDeviceParam*>(a1), (RSurfaceManager::TSyncOperation&)a2);
+			break;
+
+		case RSurfaceManagerDriver::EControlGetSurfaceHint:
+			r = Manager.GetSurfaceHint(reinterpret_cast<TSurfaceId*>(a1), reinterpret_cast<RSurfaceManager::THintPair*>(a2));
+			break;
+
+		case RSurfaceManagerDriver::EControlSetSurfaceHint:
+			r = Manager.SetSurfaceHint(reinterpret_cast<TSurfaceId*>(a1), reinterpret_cast<const RSurfaceManager::THintPair*>(a2));
+			break;
+
+		case RSurfaceManagerDriver::EControlAddSurfaceHint:
+			r = Manager.AddSurfaceHint(reinterpret_cast<TSurfaceId*>(a1), reinterpret_cast<const RSurfaceManager::THintPair*>(a2));
+			break;
+		case RSurfaceManagerDriver::EControlGetBufferOffset:
+			r = Manager.GetBufferOffset(reinterpret_cast<RSurfaceManagerDriver::TDeviceParam*>(a1),reinterpret_cast<TUint*>(a2));
+			break;
+		case RSurfaceManagerDriver::EControlGetSurfaceManagerAttrib:
+			r = Manager.GetSurfaceManagerAttrib(reinterpret_cast<RSurfaceManager::TSurfaceManagerAttrib*>(a1),reinterpret_cast<TInt*>(a2));
+			break;			
+		default:
+			r = KErrNotSupported;
+			break;
+		}
+	TRACE(Kern::Printf("<SurfaceManagerChannel::DoControl result=%d\n",r);)
+	return r;
+	}
+
+
+
+DECLARE_STANDARD_EXTENSION()
+	{
+	//called when kernel extension is loaded
+	//initialise the kernel extension
+	TRACE(Kern::Printf("<SurfaceManager Extension entry point\n");)
+	return KErrNone;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrcommon/src/syborgvirtualhwmemory.cpp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,93 @@
+// Copyright (c) 2006-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:
+// Syborg Virtual Hardware Memory implementation
+
+/**
+ @file
+ @internalTechnology
+ @prototype
+*/
+
+#include "syborgvirtualhwmemory.h"
+
+DVirtualHWMemoryManager::DVirtualHWMemoryManager(TUint32 aBase, TInt aMaxSize):
+        iRoot(0, aBase),
+        iLast(0, aBase + aMaxSize)
+        {
+        iRoot.iNext = &iLast;
+        }
+    
+TUint32 DVirtualHWMemoryManager::Allocate(TInt aSize)
+        {
+        TUint32 address(NULL);
+        TAllocatedCell* current(&iRoot);
+        TAllocatedCell* next(iRoot.iNext);
+        while (next)
+            {
+            const TInt freeBetweenCells = next->iBase - (current->iBase + current->iSize);
+            if (freeBetweenCells >= aSize )
+                {
+                //Mark area as allocated
+                address = current->iBase + current->iSize;
+                TAllocatedCell* newCell = new TAllocatedCell(aSize, address);
+                if (!newCell)
+                    {
+                    return NULL;
+                    }
+                newCell->iNext = next;
+                current->iNext = newCell;
+                break;
+                }
+            else
+                {
+                current = next;
+                next = next->iNext;
+                }
+            }
+        return address;
+        }
+    
+    void DVirtualHWMemoryManager::Deallocate(const TUint32 aPhysicalAddress)
+        {
+        TAllocatedCell* prev(&iRoot);
+        TAllocatedCell* next(iRoot.iNext);
+        while (next)
+            {
+            if (next->iBase == aPhysicalAddress)
+                {
+                prev->iNext = next->iNext;
+                delete next;
+                next = NULL;
+                }
+            else
+                {
+                prev = next;
+                next = next->iNext;
+                }
+            }
+        }
+
+    DVirtualHWMemoryManager::~DVirtualHWMemoryManager()
+        {
+        TAllocatedCell* next(iRoot.iNext);
+        while (next)
+            {
+            TAllocatedCell* deletethis = next;
+            next = next->iNext;
+            if (deletethis != &iLast)
+                {
+                delete deletethis;
+                }
+            }
+        }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrref/group/bld.inf	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,29 @@
+// 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:
+// Reference Surface Manager Driver
+
+/**
+ @file
+ @internalTechnology
+*/
+
+PRJ_PLATFORMS
+BASEDEFAULT
+
+PRJ_EXPORTS
+surfacemanager_ref.iby          /epoc32/rom/include/surfacemanager_ref.iby
+
+PRJ_MMPFILES
+surfacemanagerdriver.mmp
+surfacemanager.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrref/group/surfacemanager.mmp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,42 @@
+// Copyright (c) 2006-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:
+// Surface Manager user side library implementation
+
+
+target			surfacemanager.dll
+targettype		DLL
+
+OS_LAYER_SYSTEMINCLUDE
+
+sourcepath		../../surfacemgrcommon/src
+userinclude		../../surfacemgrcommon/inc
+
+source			surfacemanager.cpp
+
+
+#ifdef WINS
+DEFFILE       /epoc32/include/def/win32/surfacemanager.def
+#else
+DEFFILE       /epoc32/include/def/eabi/surfacemanager.def
+#endif
+
+library                 euser.lib
+
+//KUidSurfaceManager 	 0x10286A9D
+uid           0x1000008d 0x10286A9D
+VENDORID      0x70000011
+
+capability    all -tcb
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrref/group/surfacemanager_ref.iby	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,28 @@
+// Copyright (c) 2008-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:
+//
+
+#ifndef __SURFACEMANAGER_REF_IBY__
+#define __SURFACEMANAGER_REF_IBY__
+
+#ifndef __GRAPHICS_TEXTSHELL_IBY__
+file=ABI_DIR\BUILD_DIR\surfacemanager.dll 		System\Libs\surfacemanager.dll
+#endif
+
+ROM_IMAGE[0] {
+REM Surface Manager
+extension[VARID]=KERNEL_DIR\BUILD_DIR\surfacemanagerdriver.ldd		\Sys\Bin\surfacemanagerdriver.ldd
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrref/group/surfacemanagerdriver.mmp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,38 @@
+// Copyright (c) 2006-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:
+//
+
+
+OS_LAYER_SYSTEMINCLUDE
+
+#include <kernel/kern_ext.mmh>
+
+target			surfacemanagerdriver.ldd
+targettype		ldd
+sourcepath		../../surfacemgrcommon/src
+userinclude		../../surfacemgrcommon/inc
+source			surfacemanagerdriver.cpp
+source			extension.cpp
+
+epocallowdlldata
+
+start wins
+win32_headers
+end
+
+uid				0x100000af
+capability		all
+
+SMPSAFE
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrsyborg/group/bld.inf	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,28 @@
+// 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:
+// Syborg Surface Manager Driver
+
+/**
+ @file
+ @internalTechnology
+*/
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_EXPORTS
+surfacemanager_syborg.iby          /epoc32/rom/include/surfacemanager_syborg.iby
+
+PRJ_MMPFILES
+syborgsurfacemanagerdriver.mmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrsyborg/group/surfacemanager_syborg.iby	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,28 @@
+// 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 __SURFACEMANAGER_SYBORG_IBY__
+#define __SURFACEMANAGER_SYBORG_IBY__
+
+#ifndef __GRAPHICS_TEXTSHELL_IBY__
+file=ABI_DIR\BUILD_DIR\surfacemanager.dll 		System\Libs\surfacemanager.dll
+#endif
+
+ROM_IMAGE[0] {
+REM Surface Manager
+extension[VARID]=KERNEL_DIR\BUILD_DIR\syborgsurfacemanagerdriver.ldd		\Sys\Bin\surfacemanagerdriver.ldd
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscompositionref/surfacemgrsyborg/group/syborgsurfacemanagerdriver.mmp	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,42 @@
+// Copyright (c) 2006-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 to generate the syborg variant of the surface manager driver
+
+OS_LAYER_SYSTEMINCLUDE
+
+#include <kernel/kern_ext.mmh>
+
+target			syborgsurfacemanagerdriver.ldd
+targettype		ldd
+sourcepath              ../../surfacemgrcommon/src
+userinclude             ../../surfacemgrcommon/inc
+
+MACRO			GRAPHICS_SURFACEMANAGER_SYBORG
+
+source			surfacemanagerdriver.cpp
+source			syborgvirtualhwmemory.cpp
+source			extension.cpp
+
+epocallowdlldata
+
+library			guestvideohw.lib
+
+start wins
+win32_headers
+end
+
+uid				0x100000af // KLogicalDeviceDriverUidValue
+capability		all
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/package_definition.xml	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+  <package id="graphics.nokia" name="Nokia Graphics Adaptation" levels="rendering composition" version="4.0.0">
+    <meta rel="License">
+      <license type="EPL"><supplier>Nokia</supplier></license>
+    </meta>
+    <collection id="graphicscompositionref" name="Graphics Composition Reference" level="composition">
+      <component id="openwfcompositionengine" name="OpenWF-C Reference" introduced="^3" purpose="development">
+        <meta rel="License">
+          <license type="other">
+            <supplier>Khronos Group</supplier>
+            <description>Khronos Free Use License</description>
+            <notes>Distribution policy ID 1436</notes>
+          </license>
+        </meta>
+        <unit bldFile="graphicscompositionref/openwfcompositionengine/group"/>
+      </component>
+      <component id="openwfc_ri_displaychannel" name="OpenWF-C RI Display Channel Adapter" introduced="^4" purpose="development">
+        <meta rel="License">
+          <license type="other">
+            <supplier>Khronos Group</supplier>
+            <description>Khronos Free Use License</description>
+            <notes>Distribution policy ID 1436</notes>
+          </license>
+        </meta>
+        <unit bldFile="graphicscompositionref/openwfc_ri_displaychannel/group"/>
+      </component>
+      <component id="openwfc_ri_displayupdater" name="OpenWF-C RI Display Updater Adapter" introduced="^4" purpose="development">
+        <meta rel="License">
+          <license type="other">
+            <supplier>Khronos Group</supplier>
+            <description>Khronos Free Use License</description>
+            <notes>Distribution policy ID 1436</notes>
+          </license>
+        </meta>
+        <unit bldFile="graphicscompositionref/openwfc_ri_displayupdater/group"/>
+      </component>
+      <component id="symbianstreamref" name="Symbian Stream Reference" introduced="^4">
+        <unit bldFile="graphicscompositionref/symbianstreamref/group"/>
+      </component>
+      <component id="surfacemgrplatsim" name="PlatSim Surface Manager" introduced="^4">
+        <unit bldFile="graphicscompositionref/surfacemgrplatsim/group"/>
+      </component>
+      <component id="surfacemgrsyborg" name="Syborg Surface Manager" introduced="^4">
+        <unit bldFile="graphicscompositionref/surfacemgrsyborg/group"/>
+      </component>
+      <component id="surfacemgrcommon" name="Surface Manager Common" introduced="^4">
+        <unit base="graphicscompositionref/surfacemgrcommon"/>
+      </component>
+      <component id="surfacemgrref" name="Surface Manager Reference" introduced="^4">
+        <unit bldFile="graphicscompositionref/surfacemgrref/group"/>
+      </component>
+      <component id="surfaceupdateref" name="Surface Update Server Reference" introduced="^4">
+        <unit bldFile="graphicscompositionref/surfaceupdateref/group"/>
+      </component>
+    </collection>
+    <collection id="graphicsrenderingref" name="Graphics Rendering Reference" level="rendering">
+      <component id="eglrefimpl" name="EGL Reference" purpose="development">
+        <unit bldFile="graphicsrenderingref/eglrefimpl/group"/>
+      </component>
+      <component id="opengles_stub" name="OpenGL ES Stub Implementation" purpose="development" filter="sf_build">
+        <unit bldFile="graphicsrenderingref/opengles_stub/group"/>
+      </component>
+      <component id="sfopenvg" name="SF OpenVG Reference Implementation" purpose="development" filter="sf_build">
+        <unit bldFile="graphicsrenderingref/sfopenvg/group"/>
+      </component>
+      <component id="graphicsresourceimplementation" name="Graphics Resource Reference">
+        <unit bldFile="graphicsrenderingref/graphicsresourceimplementation/group"/>
+      </component>
+    </collection>
+  </package>
+</SystemDefinition>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/package_map.xml	Mon Aug 16 10:28:15 2010 +0100
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<PackageMap root="sf" layer="adapt" />