graphicsresourceservices/graphicsresourceimplementation/src/sgextension.cpp
changeset 36 01a6848ebfd7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsresourceservices/graphicsresourceimplementation/src/sgextension.cpp	Fri Apr 16 16:21:04 2010 +0300
@@ -0,0 +1,197 @@
+// Copyright (c) 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:
+// Graphics Resource - kernel extension implementation
+//
+
+#include <kernel/kern_priv.h>
+#include "sgextensionimpl.h"
+
+DSgExtensionImpl* TheSgExtensionImpl = NULL;
+
+DECLARE_STANDARD_EXTENSION()
+	{
+	__KTRACE_OPT(KBOOT, Kern::Printf("Starting Graphics Extension"));
+	TInt err;
+	TheSgExtensionImpl = new DSgExtensionImpl;
+	if (TheSgExtensionImpl)
+		{
+		err = TheSgExtensionImpl->Construct();
+		if (err != KErrNone)
+			{
+			delete TheSgExtensionImpl;
+			TheSgExtensionImpl = NULL;
+			}
+		}
+	else
+		{
+		err = KErrNoMemory;
+		}
+	if (err != KErrNone)
+		{
+		__KTRACE_OPT(KBOOT, Kern::Printf("Error: Graphics Extension failed to start"));
+		}
+	return err;
+	}
+
+EXPORT_C TVersion SgExtension::Version()
+	{
+	return TVersion(1, 1, 1);
+	}
+
+EXPORT_C TInt SgExtension::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, DSgResource*& aResource)
+	{
+	if (!TheSgExtensionImpl)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
+		return KErrNotReady;
+		}
+	return TheSgExtensionImpl->CreateResource(aAttribs, aMetaData, aDataSize, aResource);
+	}
+
+EXPORT_C TInt SgExtension::FindAndOpenResource(TUint64 aId, DSgResource*& aResource)
+	{
+	if (!TheSgExtensionImpl)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
+		return KErrNotReady;
+		}
+	return TheSgExtensionImpl->FindAndOpenResource(aId, aResource);
+	}
+
+EXPORT_C TInt SgExtension::GlobalResourceCount()
+	{
+	if (!TheSgExtensionImpl)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
+		return KErrNotReady;
+		}
+	return TheSgExtensionImpl->GlobalResourceCount();
+	}
+
+EXPORT_C TInt SgExtension::GlobalGraphicsMemoryUsed()
+	{
+	if (!TheSgExtensionImpl)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
+		return KErrNotReady;
+		}
+	return TheSgExtensionImpl->GlobalGraphicsMemoryUsed();
+	}
+
+TInt DSgExtensionImpl::Construct()
+	{
+	return Kern::MutexCreate(iMutex, KNullDesC8, KMutexOrdGeneral0);
+	}
+
+TInt DSgExtensionImpl::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, DSgResource*& aResource)
+	{
+	if (aDataSize <= 0)
+		{
+		return KErrArgument;
+		}
+	DSgResourceImpl* resource = static_cast<DSgResourceImpl*>(Kern::Alloc(sizeof(DSgResourceImpl) + aMetaData.Size()));
+	if (!resource)
+		{
+		return KErrNoMemory;
+		}
+    TChunkCreateInfo info;
+	info.iType = TChunkCreateInfo::ESharedKernelMultiple;
+	info.iMaxSize = aDataSize;
+	info.iOwnsMemory = ETrue;
+#ifdef __WINS__
+	info.iMapAttr = aAttribs, 0; // suppress compiler warning: cache attribute does not apply to WINS
+#else
+	info.iMapAttr = aAttribs & ESgResourceAttrCpuCached ? EMapAttrCachedMax : EMapAttrL1Uncached;
+#endif
+	DChunk* chunk;
+	TLinAddr kernAddr;
+	TUint32 mapAttr;
+	TInt err = Kern::ChunkCreate(info, chunk, kernAddr, mapAttr);
+	if (err != KErrNone)
+		{
+		Kern::Free(resource);
+		return err;
+		}
+	err = Kern::ChunkCommit(chunk, 0, aDataSize);
+	if (err != KErrNone)
+		{
+		Kern::ChunkClose(chunk);
+		Kern::Free(resource);
+		return err;
+		}
+	Kern::MutexWait(*iMutex);
+	new(resource) DSgResourceImpl(*this, ++iLastResourceId, aAttribs, aMetaData, chunk, aDataSize);
+	err = iResources.InsertInOrder(resource, DSgResource::Compare);
+	Kern::MutexSignal(*iMutex);
+	if (err != KErrNone)
+		{
+		resource->Close();
+		}
+	aResource = (err == KErrNone ? resource : NULL);
+	return err;
+	}
+
+TInt DSgExtensionImpl::FindAndOpenResource(TUint64 aId, DSgResource*& aResource)
+	{
+	if (aId == 0)
+		{
+		return KErrArgument;
+		}
+	Kern::MutexWait(*iMutex);
+	TInt i = iResources.FindInOrder(aId, DSgResource::Compare);
+	if (i < 0)
+		{
+		Kern::MutexSignal(*iMutex);
+		return KErrNotFound;
+		}
+	DSgResource* resource = iResources[i];
+	TInt err = resource->Open();
+	Kern::MutexSignal(*iMutex);
+	aResource = (err == KErrNone ? resource : NULL);
+	return err;
+	}
+
+void DSgExtensionImpl::DeleteResource(DSgResource* aResource)
+	{
+	Kern::MutexWait(*iMutex);
+	TInt i = iResources.FindInOrder(aResource, DSgResource::Compare);
+	if (i >= 0)
+		{
+		iResources.Remove(i);
+		}
+	else
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: internal state of Graphics Extension is inconsistent"));
+		}
+	Kern::MutexSignal(*iMutex);
+	delete aResource;
+	}
+
+TInt DSgExtensionImpl::GlobalResourceCount() const
+	{
+	return iResources.Count();
+	}
+
+TInt DSgExtensionImpl::GlobalGraphicsMemoryUsed() const
+	{
+	TInt ret = 0;
+	Kern::MutexWait(*iMutex);
+	TInt n = iResources.Count();
+	for (TInt i = 0; i < n; ++i)
+		{
+		ret += iResources[i]->DataChunk()->Size();
+		}
+	Kern::MutexSignal(*iMutex);
+	return ret;
+	}