sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Graphics Resource - logical channel implementation sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include "sgdeviceimpl.h" sl@0: sl@0: TInt DSgChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVersion) sl@0: { sl@0: TVersion version = SgExtension::Version(); sl@0: if (aVersion.iMajor != version.iMajor || aVersion.iMinor > version.iMinor) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: return Kern::MutexCreate(iMutex, KNullDesC, KMutexOrdGeneral7); sl@0: } sl@0: sl@0: DSgChannel::~DSgChannel() sl@0: { sl@0: if (iMutex) sl@0: { sl@0: iMutex->Close(NULL); sl@0: } sl@0: for (TInt i = 0; i < iResources.Count(); ++i) sl@0: { sl@0: iResources[i].iResource->Close(); sl@0: } sl@0: iResources.Close(); sl@0: } sl@0: sl@0: TInt DSgChannel::Request(TInt aFunction, TAny* a1, TAny* a2) sl@0: { sl@0: switch (aFunction) sl@0: { sl@0: case RSgDevice::EControlCreateResource: sl@0: { sl@0: RSgDevice::TCreateResourceArgs args; sl@0: kumemget32(&args, a1, sizeof(RSgDevice::TCreateResourceArgs)); sl@0: TInt metaDataSize, maxMetaDataSize; sl@0: Kern::KUDesInfo(*args.iMetaData, metaDataSize, maxMetaDataSize); sl@0: __ASSERT_ALWAYS(metaDataSize <= KSgMaxMetaDataSize, Panic(ESgPanicMetaDataSizeTooBig)); sl@0: __ASSERT_ALWAYS(args.iDataSize >= 0, Panic(ESgPanicDataSizeNegative)); sl@0: TBuf8 metaData; sl@0: Kern::KUDesGet(metaData, *args.iMetaData); sl@0: TUint64 id; sl@0: TInt err = CreateResource(args.iAttributes, metaData, args.iDataSize, id); sl@0: kumemput32(a2, &id, sizeof(TUint64)); sl@0: return err; sl@0: } sl@0: case RSgDevice::EControlOpenResource: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: return OpenResource(id); sl@0: } sl@0: case RSgDevice::EControlCloseResource: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: return CloseResource(id); sl@0: } sl@0: case RSgDevice::EControlResourceAttributes: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: return static_cast(ResourceAttributes(id)); sl@0: } sl@0: case RSgDevice::EControlGetResourceMetaData: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: TBuf8 metaData; sl@0: TInt err = GetResourceMetaData(id, metaData); sl@0: if (err == KErrNone) sl@0: { sl@0: Kern::InfoCopy(*static_cast(a2), metaData); sl@0: } sl@0: return err; sl@0: } sl@0: case RSgDevice::EControlResourceDataAddress: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: return reinterpret_cast(ResourceDataAddress(id)); sl@0: } sl@0: case RSgDevice::EControlResourceDataSize: sl@0: { sl@0: TUint64 id; sl@0: kumemget32(&id, a1, sizeof(TUint64)); sl@0: return ResourceDataSize(id); sl@0: } sl@0: case RSgDevice::EControlGlobalResourceCount: sl@0: return GlobalResourceCount(); sl@0: case RSgDevice::EControlLocalGraphicsMemoryUsed: sl@0: return LocalGraphicsMemoryUsed(); sl@0: case RSgDevice::EControlGlobalGraphicsMemoryUsed: sl@0: return GlobalGraphicsMemoryUsed(); sl@0: default: sl@0: return KErrNotSupported; sl@0: } sl@0: } sl@0: sl@0: TInt DSgChannel::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, TUint64& aId) sl@0: { sl@0: aId = 0; sl@0: NKern::ThreadEnterCS(); sl@0: DSgResource* resource; sl@0: TInt err = SgExtension::CreateResource(aAttribs, aMetaData, aDataSize, resource); sl@0: if (err != KErrNone) sl@0: { sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: TInt handle = Kern::MakeHandleAndOpen(NULL, resource->DataChunk(), EOwnerProcess); sl@0: if (handle < 0) sl@0: { sl@0: resource->Close(); sl@0: NKern::ThreadLeaveCS(); sl@0: return handle; sl@0: } sl@0: Kern::MutexWait(*iMutex); sl@0: err = iResources.InsertInOrder(TResourceListItem(resource, handle), Compare); sl@0: Kern::MutexSignal(*iMutex); sl@0: if (err != KErrNone) sl@0: { sl@0: (void)Kern::CloseHandle(NULL, handle); sl@0: resource->Close(); sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: NKern::ThreadLeaveCS(); sl@0: aId = resource->Id(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DSgChannel::OpenResource(TUint64 aId) sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return KErrAlreadyExists; sl@0: } sl@0: DSgResource* resource; sl@0: TInt err = SgExtension::FindAndOpenResource(aId, resource); sl@0: if (err != KErrNone) sl@0: { sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: TInt handle = Kern::MakeHandleAndOpen(NULL, resource->DataChunk(), EOwnerProcess); sl@0: if (handle < 0) sl@0: { sl@0: resource->Close(); sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return handle; sl@0: } sl@0: err = iResources.InsertInOrder(TResourceListItem(resource, handle), Compare); sl@0: if (err != KErrNone) sl@0: { sl@0: (void)Kern::CloseHandle(NULL, handle); sl@0: resource->Close(); sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DSgChannel::CloseResource(TUint64 aId) sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: TInt err = KErrNotFound; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: (void)Kern::CloseHandle(NULL, iResources[i].iChunkHandle); sl@0: iResources[i].iResource->Close(); sl@0: iResources.Remove(i); sl@0: err = KErrNone; sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: sl@0: TUint32 DSgChannel::ResourceAttributes(TUint64 aId) const sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return 0; sl@0: } sl@0: TUint32 attribs = 0; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: attribs = iResources[i].iResource->Attributes(); sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return attribs; sl@0: } sl@0: sl@0: TInt DSgChannel::GetResourceMetaData(TUint64 aId, TDes8& aMetaData) const sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: TInt err = KErrNotFound; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: err = iResources[i].iResource->GetMetaData(aMetaData); sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return err; sl@0: } sl@0: sl@0: TAny* DSgChannel::ResourceDataAddress(TUint64 aId) const sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return NULL; sl@0: } sl@0: TAny* addr = NULL; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: addr = Kern::ChunkUserBase(iResources[i].iResource->DataChunk(), &Kern::CurrentThread()); sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return addr; sl@0: } sl@0: sl@0: TInt DSgChannel::ResourceDataSize(TUint64 aId) const sl@0: { sl@0: if (aId == 0) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: TInt ret = KErrNotFound; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt i = iResources.FindInOrder(aId, Compare); sl@0: if (i >= 0) sl@0: { sl@0: ret = iResources[i].iResource->DataSize(); sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return ret; sl@0: } sl@0: sl@0: TInt DSgChannel::GlobalResourceCount() const sl@0: { sl@0: NKern::ThreadEnterCS(); sl@0: TInt ret = SgExtension::GlobalResourceCount(); sl@0: NKern::ThreadLeaveCS(); sl@0: return ret; sl@0: } sl@0: sl@0: TInt DSgChannel::LocalGraphicsMemoryUsed() const sl@0: { sl@0: TInt ret = 0; sl@0: NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iMutex); sl@0: TInt n = iResources.Count(); sl@0: for (TInt i = 0; i < n; ++i) sl@0: { sl@0: ret += iResources[i].iResource->DataChunk()->Size(); sl@0: } sl@0: Kern::MutexSignal(*iMutex); sl@0: NKern::ThreadLeaveCS(); sl@0: return ret; sl@0: } sl@0: sl@0: TInt DSgChannel::GlobalGraphicsMemoryUsed() const sl@0: { sl@0: NKern::ThreadEnterCS(); sl@0: TInt ret = SgExtension::GlobalGraphicsMemoryUsed(); sl@0: NKern::ThreadLeaveCS(); sl@0: return ret; sl@0: } sl@0: sl@0: DSgChannel::TResourceListItem::TResourceListItem(DSgResource* aResource, TInt aChunkHandle) sl@0: : iResource(aResource), iChunkHandle(aChunkHandle) sl@0: { sl@0: } sl@0: sl@0: TInt DSgChannel::Compare(const TUint64* aId, const TResourceListItem& aResourceListItem) sl@0: { sl@0: return DSgResource::Compare(aId, *aResourceListItem.iResource); sl@0: } sl@0: sl@0: TInt DSgChannel::Compare(const TResourceListItem& aResourceListItem1, const TResourceListItem& aResourceListItem2) sl@0: { sl@0: return DSgResource::Compare(*aResourceListItem1.iResource, *aResourceListItem2.iResource); sl@0: }