graphicshwdrivers/surfacemgr/src/extension.cpp
branchbug235_bringup_0
changeset 147 af143508cc47
parent 146 4d1fe4a7ce83
child 148 706129140cfc
--- a/graphicshwdrivers/surfacemgr/src/extension.cpp	Fri Aug 13 15:11:40 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1699 +0,0 @@
-// 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/surface.h>
-#include <graphics/surfacetypes.h>
-#include <graphics/surfacemanager.h>
-#include "surfacemanager_dev.h"
-#include <kernel/cache.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
-
-	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;
-	if (attribs.iContiguous)
-		{
-		r = Kern::ChunkCommitContiguous(chunk, 0, chunkSize, paddr);
-		}
-	else
-		{
-		r = Kern::ChunkCommit(chunk, 0, chunkSize);
-		}
-
-	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)
-		{
-		//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;
-	}