os/graphics/graphicsresourceservices/graphicsresourceimplementation/src/sgextension.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsresourceservices/graphicsresourceimplementation/src/sgextension.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,197 @@
1.4 +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Graphics Resource - kernel extension implementation
1.18 +//
1.19 +
1.20 +#include <kernel/kern_priv.h>
1.21 +#include "sgextensionimpl.h"
1.22 +
1.23 +DSgExtensionImpl* TheSgExtensionImpl = NULL;
1.24 +
1.25 +DECLARE_STANDARD_EXTENSION()
1.26 + {
1.27 + __KTRACE_OPT(KBOOT, Kern::Printf("Starting Graphics Extension"));
1.28 + TInt err;
1.29 + TheSgExtensionImpl = new DSgExtensionImpl;
1.30 + if (TheSgExtensionImpl)
1.31 + {
1.32 + err = TheSgExtensionImpl->Construct();
1.33 + if (err != KErrNone)
1.34 + {
1.35 + delete TheSgExtensionImpl;
1.36 + TheSgExtensionImpl = NULL;
1.37 + }
1.38 + }
1.39 + else
1.40 + {
1.41 + err = KErrNoMemory;
1.42 + }
1.43 + if (err != KErrNone)
1.44 + {
1.45 + __KTRACE_OPT(KBOOT, Kern::Printf("Error: Graphics Extension failed to start"));
1.46 + }
1.47 + return err;
1.48 + }
1.49 +
1.50 +EXPORT_C TVersion SgExtension::Version()
1.51 + {
1.52 + return TVersion(1, 1, 1);
1.53 + }
1.54 +
1.55 +EXPORT_C TInt SgExtension::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, DSgResource*& aResource)
1.56 + {
1.57 + if (!TheSgExtensionImpl)
1.58 + {
1.59 + __KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
1.60 + return KErrNotReady;
1.61 + }
1.62 + return TheSgExtensionImpl->CreateResource(aAttribs, aMetaData, aDataSize, aResource);
1.63 + }
1.64 +
1.65 +EXPORT_C TInt SgExtension::FindAndOpenResource(TUint64 aId, DSgResource*& aResource)
1.66 + {
1.67 + if (!TheSgExtensionImpl)
1.68 + {
1.69 + __KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
1.70 + return KErrNotReady;
1.71 + }
1.72 + return TheSgExtensionImpl->FindAndOpenResource(aId, aResource);
1.73 + }
1.74 +
1.75 +EXPORT_C TInt SgExtension::GlobalResourceCount()
1.76 + {
1.77 + if (!TheSgExtensionImpl)
1.78 + {
1.79 + __KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
1.80 + return KErrNotReady;
1.81 + }
1.82 + return TheSgExtensionImpl->GlobalResourceCount();
1.83 + }
1.84 +
1.85 +EXPORT_C TInt SgExtension::GlobalGraphicsMemoryUsed()
1.86 + {
1.87 + if (!TheSgExtensionImpl)
1.88 + {
1.89 + __KTRACE_OPT(KPANIC, Kern::Printf("Error: Graphics Extension not ready"));
1.90 + return KErrNotReady;
1.91 + }
1.92 + return TheSgExtensionImpl->GlobalGraphicsMemoryUsed();
1.93 + }
1.94 +
1.95 +TInt DSgExtensionImpl::Construct()
1.96 + {
1.97 + return Kern::MutexCreate(iMutex, KNullDesC8, KMutexOrdGeneral0);
1.98 + }
1.99 +
1.100 +TInt DSgExtensionImpl::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, DSgResource*& aResource)
1.101 + {
1.102 + if (aDataSize <= 0)
1.103 + {
1.104 + return KErrArgument;
1.105 + }
1.106 + DSgResourceImpl* resource = static_cast<DSgResourceImpl*>(Kern::Alloc(sizeof(DSgResourceImpl) + aMetaData.Size()));
1.107 + if (!resource)
1.108 + {
1.109 + return KErrNoMemory;
1.110 + }
1.111 + TChunkCreateInfo info;
1.112 + info.iType = TChunkCreateInfo::ESharedKernelMultiple;
1.113 + info.iMaxSize = aDataSize;
1.114 + info.iOwnsMemory = ETrue;
1.115 +#ifdef __WINS__
1.116 + info.iMapAttr = aAttribs, 0; // suppress compiler warning: cache attribute does not apply to WINS
1.117 +#else
1.118 + info.iMapAttr = aAttribs & ESgResourceAttrCpuCached ? EMapAttrCachedMax : EMapAttrL1Uncached;
1.119 +#endif
1.120 + DChunk* chunk;
1.121 + TLinAddr kernAddr;
1.122 + TUint32 mapAttr;
1.123 + TInt err = Kern::ChunkCreate(info, chunk, kernAddr, mapAttr);
1.124 + if (err != KErrNone)
1.125 + {
1.126 + Kern::Free(resource);
1.127 + return err;
1.128 + }
1.129 + err = Kern::ChunkCommit(chunk, 0, aDataSize);
1.130 + if (err != KErrNone)
1.131 + {
1.132 + Kern::ChunkClose(chunk);
1.133 + Kern::Free(resource);
1.134 + return err;
1.135 + }
1.136 + Kern::MutexWait(*iMutex);
1.137 + new(resource) DSgResourceImpl(*this, ++iLastResourceId, aAttribs, aMetaData, chunk, aDataSize);
1.138 + err = iResources.InsertInOrder(resource, DSgResource::Compare);
1.139 + Kern::MutexSignal(*iMutex);
1.140 + if (err != KErrNone)
1.141 + {
1.142 + resource->Close();
1.143 + }
1.144 + aResource = (err == KErrNone ? resource : NULL);
1.145 + return err;
1.146 + }
1.147 +
1.148 +TInt DSgExtensionImpl::FindAndOpenResource(TUint64 aId, DSgResource*& aResource)
1.149 + {
1.150 + if (aId == 0)
1.151 + {
1.152 + return KErrArgument;
1.153 + }
1.154 + Kern::MutexWait(*iMutex);
1.155 + TInt i = iResources.FindInOrder(aId, DSgResource::Compare);
1.156 + if (i < 0)
1.157 + {
1.158 + Kern::MutexSignal(*iMutex);
1.159 + return KErrNotFound;
1.160 + }
1.161 + DSgResource* resource = iResources[i];
1.162 + TInt err = resource->Open();
1.163 + Kern::MutexSignal(*iMutex);
1.164 + aResource = (err == KErrNone ? resource : NULL);
1.165 + return err;
1.166 + }
1.167 +
1.168 +void DSgExtensionImpl::DeleteResource(DSgResource* aResource)
1.169 + {
1.170 + Kern::MutexWait(*iMutex);
1.171 + TInt i = iResources.FindInOrder(aResource, DSgResource::Compare);
1.172 + if (i >= 0)
1.173 + {
1.174 + iResources.Remove(i);
1.175 + }
1.176 + else
1.177 + {
1.178 + __KTRACE_OPT(KPANIC, Kern::Printf("Error: internal state of Graphics Extension is inconsistent"));
1.179 + }
1.180 + Kern::MutexSignal(*iMutex);
1.181 + delete aResource;
1.182 + }
1.183 +
1.184 +TInt DSgExtensionImpl::GlobalResourceCount() const
1.185 + {
1.186 + return iResources.Count();
1.187 + }
1.188 +
1.189 +TInt DSgExtensionImpl::GlobalGraphicsMemoryUsed() const
1.190 + {
1.191 + TInt ret = 0;
1.192 + Kern::MutexWait(*iMutex);
1.193 + TInt n = iResources.Count();
1.194 + for (TInt i = 0; i < n; ++i)
1.195 + {
1.196 + ret += iResources[i]->DataChunk()->Size();
1.197 + }
1.198 + Kern::MutexSignal(*iMutex);
1.199 + return ret;
1.200 + }