--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsresourceservices/graphicsresourceadaptation/src/sgimageimpl.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,744 @@
+// Copyright (c) 2007-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 "sgimageimpl.h"
+#include "sgresourceinternal.h"
+
+
+// TSgImageMetaData
+
+TSgImageMetaData::TSgImageMetaData(const TSgImageInfo& aInfo, TArray<TSgPixelFormatTableEntry> aPixelFormatTable, TBool aIsCached)
+ : iCreatorProcess(RProcess().Id()),
+ iSizeInPixels(aInfo.iSizeInPixels),
+ iPixelFormat(aInfo.iPixelFormat),
+ iRequestedUsage(aInfo.iUsage),
+ iPotentialUsage(0),
+ iShareable(aInfo.iShareable),
+ iCpuAccess(aInfo.iCpuAccess),
+ iScreenId(aInfo.iScreenId),
+ iIsCached(aIsCached)
+ {
+ TUint32 usageMask = (aInfo.iUsage & KSgUsageAllSources ? KSgUsageAllSources : 0)
+ | (aInfo.iUsage & KSgUsageAllTargets ? KSgUsageAllTargets : 0);
+ TInt n = aPixelFormatTable.Count();
+ for (TInt i = 0; i < n; ++i)
+ {
+ const TSgPixelFormatTableEntry& entry = aPixelFormatTable[i];
+ if (entry.IsMatchIgnoringUsage(aInfo))
+ {
+ iPotentialUsage |= entry.iUsage & usageMask;
+ }
+ }
+ }
+
+
+void TSgImageMetaData::GetInfo(TSgImageInfo& aInfo, TBool aGetPotentialUsage) const
+ {
+ aInfo.iSizeInPixels = iSizeInPixels;
+ aInfo.iPixelFormat = iPixelFormat;
+ aInfo.iUsage = aGetPotentialUsage ? iPotentialUsage : iRequestedUsage;
+ aInfo.iShareable = iShareable;
+ aInfo.iCpuAccess = iCpuAccess;
+ aInfo.iScreenId = iScreenId;
+ }
+
+
+// XSgImageImplBase
+
+XSgImageImplBase::XSgImageImplBase(const XSgImageImplBase& aImage, TUint32 aFlags)
+ : XSgBase(aImage.iDriverImpl)
+ {
+ __ASSERT_DEBUG(iDriverImpl.IsMutexHeld(), Panic(ESgPanicMutexNotHeld));
+ iId = aImage.iId;
+ iId.iId[KSgImageIdFlagsIndex] = aFlags;
+ aImage.iState->IncRefCount();
+ iState = aImage.iState;
+ }
+
+
+XSgImageImplBase::~XSgImageImplBase()
+ {
+ __ASSERT_DEBUG(iDriverImpl.IsMutexHeld(), Panic(ESgPanicMutexNotHeld));
+ if (iState && iState->DecRefCount() == 0)
+ {
+ Unmap();
+ iState->Delete();
+ }
+ }
+
+
+TInt XSgImageImplBase::Compare(const TSgDrawableId* aId, const XSgImageImplBase& aImage)
+ {
+ return Mem::Compare(reinterpret_cast<const TUint8*>(aId), sizeof(TSgDrawableId),
+ reinterpret_cast<const TUint8*>(&aImage.Id()), sizeof(TSgDrawableId));
+ }
+
+
+TInt XSgImageImplBase::Compare(const XSgImageImplBase& aImage1, const XSgImageImplBase& aImage2)
+ {
+ return Compare(&aImage1.Id(), aImage2);
+ }
+
+
+TInt XSgImageImplBase::CompareIgnoringFlags(const TSgDrawableId* aId, const XSgImageImplBase& aImage)
+ {
+ return Mem::Compare(reinterpret_cast<const TUint8*>(aId), sizeof(TSgDrawableId) - sizeof(TUint32),
+ reinterpret_cast<const TUint8*>(&aImage.Id()), sizeof(TSgDrawableId) - sizeof(TUint32));
+ }
+
+
+void XSgImageImplBase::Close()
+ {
+ XSgDriverImpl& driverImpl = iDriverImpl;
+ driverImpl.Wait();
+ if (DecRefCount() == 0)
+ {
+ driverImpl.DeleteImage(this);
+ }
+ driverImpl.Signal();
+ }
+
+
+const TSgDrawableId& XSgImageImplBase::Id() const
+ {
+ return iId;
+ }
+
+
+TUid XSgImageImplBase::DrawableType() const
+ {
+ return KSgImageTypeUid;
+ }
+
+
+TInt XSgImageImplBase::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
+ {
+ if (aInterfaceUid.iUid == MSgImage_Sw::EInterfaceUid)
+ {
+ aInterfacePtr = static_cast<MSgImage_Sw*>(this);
+ return KErrNone;
+ }
+ return KErrExtensionNotSupported;
+ }
+
+
+TInt XSgImageImplBase::GetInfo(TSgImageInfo& aInfo) const
+ {
+ iState->MetaData().GetInfo(aInfo, iId.iId[KSgImageIdFlagsIndex] & ESgDoNotRestrictUsage);
+ return iState->GetUserAttributes(aInfo.iUserAttributes, aInfo.iUserAttributeCount);
+ }
+
+
+TInt XSgImageImplBase::MapReadOnly(const TAny*& aDataAddress, TInt& aDataStride)
+ {
+ TInt err = iState->BeginDataAccess(ESgCpuAccessReadOnly, ETrue);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ aDataAddress = iState->DataAddress();
+ aDataStride = iState->DataStride();
+ return KErrNone;
+ }
+
+
+TInt XSgImageImplBase::MapWriteOnly(TAny*& aDataAddress, TInt& aDataStride)
+ {
+ TInt err = iState->BeginDataAccess(ESgCpuAccessWriteOnly, ETrue);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ aDataAddress = iState->DataAddress();
+ aDataStride = iState->DataStride();
+ return KErrNone;
+ }
+
+
+TInt XSgImageImplBase::MapReadWrite(TAny*& aDataAddress, TInt& aDataStride)
+ {
+ TInt err = iState->BeginDataAccess(ESgCpuAccessReadWrite, ETrue);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ aDataAddress = iState->DataAddress();
+ aDataStride = iState->DataStride();
+ return KErrNone;
+ }
+
+
+TInt XSgImageImplBase::Unmap()
+ {
+ return iState->EndDataAccess(ETrue);
+ }
+
+
+TAny* XSgImageImplBase::DataAddress() const
+ {
+ return iState->DataAddress();
+ }
+
+
+TInt XSgImageImplBase::DataStride() const
+ {
+ return iState->DataStride();
+ }
+
+
+TInt XSgImageImplBase::BeginDataAccess(TSgCpuAccess aCpuAccess)
+ {
+ return iState->BeginDataAccess(aCpuAccess, EFalse);
+ }
+
+
+TInt XSgImageImplBase::EndDataAccess()
+ {
+ return iState->EndDataAccess(EFalse);
+ }
+
+
+TInt XSgImageImplBase::SetData(const TAny* aDataAddress, TInt aDataStride)
+ {
+ if (aDataAddress)
+ {
+ TInt err = BeginDataAccess(ESgCpuAccessWriteOnly);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ const TSgImageMetaData& metaData = iState->MetaData();
+ const TAny* src = aDataAddress;
+ TAny* trg = iState->DataAddress();
+ TInt dataStride = iState->DataStride();
+ TInt minDataStride = SgMinDataStride(metaData.iSizeInPixels.iWidth, metaData.iPixelFormat);
+ __ASSERT_DEBUG(minDataStride > 0, Panic(ESgPanicResourceAdapterGeneral));
+ for (TInt y = 0; y < metaData.iSizeInPixels.iHeight; ++y)
+ {
+ Mem::Copy(trg, src, minDataStride);
+ src = PtrAdd(src, aDataStride);
+ trg = PtrAdd(trg, dataStride);
+ }
+ EndDataAccess();
+ }
+ return KErrNone;
+ }
+
+
+TInt XSgImageStateBase::BeginDataAccess(TSgCpuAccess aCpuAccess, TBool aIsUserAccess)
+ {
+ if (aCpuAccess == ESgCpuAccessNone)
+ {
+ return KErrArgument;
+ }
+ const TSgImageMetaData& metaData = MetaData();
+ if (aIsUserAccess && (~metaData.iCpuAccess & aCpuAccess))
+ {
+ return KErrAccessDenied;
+ }
+ if (aIsUserAccess && metaData.iCreatorProcess != RProcess().Id())
+ {
+ return KErrPermissionDenied;
+ }
+ iDriverImpl.Wait();
+ if (iCpuAccess != ESgCpuAccessNone)
+ {
+ iDriverImpl.Signal();
+ return KErrInUse;
+ }
+ iCpuAccess = aCpuAccess;
+ iIsUserAccess = aIsUserAccess;
+ iDriverImpl.Signal();
+ return KErrNone;
+ }
+
+
+TInt XSgImageStateBase::EndDataAccess(TBool aIsUserAccess)
+ {
+ iDriverImpl.Wait();
+ if (iCpuAccess == ESgCpuAccessNone || iIsUserAccess != aIsUserAccess)
+ {
+ iDriverImpl.Signal();
+ return KErrGeneral;
+ }
+ iCpuAccess = ESgCpuAccessNone;
+ iIsUserAccess = EFalse;
+ iDriverImpl.Signal();
+ return KErrNone;
+ }
+
+
+#ifndef SYMBIAN_GRAPHICS_USE_GPU
+
+// XSgImageImpl_SwLocal
+
+TInt XSgImageImpl_SwLocal::New(XSgImageImpl_SwLocal*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId,
+ const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride)
+ {
+ aPtr = static_cast<XSgImageImpl_SwLocal*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SwLocal)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageImpl_SwLocal(aDriverImpl, aId);
+ TInt err = aPtr->Construct(aInfo, aDataAddress, aDataStride);
+ if (err != KErrNone)
+ {
+ aPtr->Delete();
+ aPtr = NULL;
+ }
+ return err;
+ }
+
+
+TInt XSgImageImpl_SwLocal::New(XSgImageImpl_SwLocal*& aPtr, const XSgImageImpl_SwLocal& aImage, TUint32 aFlags)
+ {
+ aPtr = static_cast<XSgImageImpl_SwLocal*>(aImage.iDriverImpl.Alloc(sizeof(XSgImageImpl_SwLocal)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageImpl_SwLocal(aImage, aFlags);
+ return KErrNone;
+ }
+
+
+TInt XSgImageImpl_SwLocal::Construct(const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride)
+ {
+ XSgImageState_SwLocal* state;
+ TInt err = XSgImageState_SwLocal::New(state, iDriverImpl, aInfo);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ state->IncRefCount();
+ iState = state;
+ return SetData(aDataAddress, aDataStride);
+ }
+
+
+// XSgImageState_SwLocal
+
+TInt XSgImageState_SwLocal::New(XSgImageState_SwLocal*& aPtr, XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo)
+ {
+ TInt dataStride = Align4(SgMinDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat));
+ TInt size = _FOFF(XSgImageState_SwLocal, iUserAttributes) + aInfo.iUserAttributeCount * sizeof(TSgUserAttribute) + dataStride * aInfo.iSizeInPixels.iHeight;
+ aPtr = static_cast<XSgImageState_SwLocal*>(aDriverImpl.Alloc(size));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageState_SwLocal(aDriverImpl, aInfo, dataStride);
+ return KErrNone;
+ }
+
+
+XSgImageState_SwLocal::XSgImageState_SwLocal(XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo, TInt aDataStride)
+ : XSgImageStateBase(aDriverImpl, aDataStride), iMetaData(aInfo, aDriverImpl.PixelFormatTable())
+ {
+ iUserAttributeCount = aInfo.iUserAttributeCount;
+ Mem::Copy(iUserAttributes, aInfo.iUserAttributes, aInfo.iUserAttributeCount * sizeof(TSgUserAttribute));
+ }
+
+
+const TSgImageMetaData& XSgImageState_SwLocal::MetaData() const
+ {
+ return iMetaData;
+ }
+
+
+TInt XSgImageState_SwLocal::GetUserAttributes(TSgUserAttribute* aUserAttributes, TInt aUserAttributeCount) const
+ {
+ for (TInt i = 0; i < aUserAttributeCount; ++i)
+ {
+ TBool found = EFalse;
+ for (TInt j = 0; j < iUserAttributeCount; ++j)
+ {
+ if (aUserAttributes[i].iUid == iUserAttributes[j].iUid)
+ {
+ aUserAttributes[i].iValue = iUserAttributes[j].iValue;
+ found = ETrue;
+ break;
+ }
+ }
+ if (!found)
+ {
+ return KErrNotFound;
+ }
+ }
+ return KErrNone;
+ }
+
+
+TAny* XSgImageState_SwLocal::DataAddress() const
+ {
+ //__ASSERT_DEBUG(iCpuAccess != ESgCpuAccessNone, ::Panic(ESgPanicNoCpuAccess));
+ return (TAny*)PtrAdd(iUserAttributes, iUserAttributeCount * sizeof(TSgUserAttribute));
+ }
+
+#endif
+
+
+// XSgImageImpl_SurfaceManager
+
+
+TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl,
+ const TSgImageInfo& aInfo, TBool aIsCached, const TAny* aDataAddress, TInt aDataStride)
+ {
+ aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageImpl_SurfaceManager(aDriverImpl);
+ TInt err = aPtr->Construct(aInfo, aIsCached, aDataAddress, aDataStride);
+ if (err != KErrNone)
+ {
+ aPtr->Delete();
+ aPtr = NULL;
+ }
+ return err;
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId)
+ {
+ aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageImpl_SurfaceManager(aDriverImpl, aId);
+ TInt err = aPtr->Construct(aId);
+ if (err != KErrNone)
+ {
+ aPtr->Delete();
+ aPtr = NULL;
+ }
+ return err;
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, const XSgImageImpl_SurfaceManager& aImage, TUint32 aFlags)
+ {
+ aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aImage.iDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageImpl_SurfaceManager(aImage, aFlags);
+ return KErrNone;
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::Construct(const TSgImageInfo& aInfo, TBool aIsCached, const TAny* aDataAddress, TInt aDataStride)
+ {
+ XSgImageState_SurfaceManager* state;
+ TInt err = XSgImageState_SurfaceManager::New(state, iDriverImpl, aInfo, aIsCached);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ Mem::Copy(&iId, &state->SurfaceId(), sizeof(TSurfaceId));
+ state->IncRefCount();
+ iState = state;
+ return SetData(aDataAddress, aDataStride);
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::Construct(const TSgDrawableId& aId)
+ {
+ XSgImageState_SurfaceManager* state;
+ TInt err = XSgImageState_SurfaceManager::New(state, iDriverImpl, aId);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ state->IncRefCount();
+ iState = state;
+ return KErrNone;
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
+ {
+ if (aInterfaceUid.iUid == MSgImage_Chunk::EInterfaceUid)
+ {
+ aInterfacePtr = static_cast<MSgImage_Chunk*>(this);
+ return KErrNone;
+ }
+ return XSgImageImplBase::GetInterface(aInterfaceUid, aInterfacePtr);
+ }
+
+
+const RChunk& XSgImageImpl_SurfaceManager::DataChunk() const
+ {
+ return static_cast<XSgImageState_SurfaceManager*>(iState)->DataChunk();
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::DataOffset() const
+ {
+ return static_cast<XSgImageState_SurfaceManager*>(iState)->DataOffset();
+ }
+
+
+TInt XSgImageImpl_SurfaceManager::DataStride() const
+ {
+ return iState->DataStride();
+ }
+
+
+// XSgImageState_SurfaceManager
+
+TInt XSgImageState_SurfaceManager::New(XSgImageState_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo, TBool aIsCached)
+ {
+ aPtr = static_cast<XSgImageState_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageState_SurfaceManager)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageState_SurfaceManager(aDriverImpl);
+ TInt err = aPtr->Construct(aInfo, aIsCached);
+ if (err != KErrNone)
+ {
+ aPtr->Delete();
+ aPtr = NULL;
+ }
+ return err;
+ }
+
+
+TInt XSgImageState_SurfaceManager::New(XSgImageState_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId)
+ {
+ aPtr = static_cast<XSgImageState_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageState_SurfaceManager)));
+ if (!aPtr)
+ {
+ return KErrNoMemory;
+ }
+ new(aPtr) XSgImageState_SurfaceManager(aDriverImpl);
+ TInt err = aPtr->Construct(aId);
+ if (err != KErrNone)
+ {
+ aPtr->Delete();
+ aPtr = NULL;
+ }
+ return err;
+ }
+
+
+TInt XSgImageState_SurfaceManager::Construct(const TSgImageInfo& aInfo, TBool aIsCached)
+ {
+ TInt maxNumberOfHints;
+ TInt err;
+ err=iDriverImpl.GetSurfaceManagerAttrib(RSurfaceManager::EMaxNumberOfHints,maxNumberOfHints);
+ if (err!=KErrNone)
+ {
+ return err;
+ }
+
+ if (aInfo.iUserAttributeCount > maxNumberOfHints)
+ {
+ return KErrOverflow;
+ }
+ RSurfaceManager::THintPair* hints = new RSurfaceManager::THintPair[aInfo.iUserAttributeCount];
+ if(!hints)
+ {
+ return KErrNoMemory;
+ }
+ RSurfaceManager::TSurfaceCreationAttributesBuf reqs;
+ reqs().iSurfaceHints = hints;
+ reqs().iHintCount = aInfo.iUserAttributeCount;
+ reqs().iSize = aInfo.iSizeInPixels;
+ reqs().iBuffers = 1;
+ reqs().iPixelFormat = aInfo.iPixelFormat;
+ reqs().iStride = SgAlignedDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
+ reqs().iOffsetToFirstBuffer = SgOffsetToFirstBuffer(sizeof(TSgImageMetaData));
+ reqs().iAlignment = 4;
+ reqs().iContiguous = EFalse;
+ reqs().iCacheAttrib = aIsCached ? RSurfaceManager::ECached : RSurfaceManager::ENotCached;
+ reqs().iOffsetBetweenBuffers = SgOffsetBetweenBuffers(reqs().iStride, aInfo.iSizeInPixels.iHeight);
+ reqs().iMappable = ETrue;
+ for (TInt i = 0; i < aInfo.iUserAttributeCount; ++i)
+ {
+ reqs().iSurfaceHints[i].iKey = aInfo.iUserAttributes[i].iUid;
+ reqs().iSurfaceHints[i].iValue = aInfo.iUserAttributes[i].iValue;
+ reqs().iSurfaceHints[i].iMutable = EFalse;
+ }
+ TSurfaceId surfaceId;
+ err = iDriverImpl.CreateSurface(reqs, surfaceId);
+ delete[] hints;
+ hints = NULL;
+ reqs().iSurfaceHints = NULL;
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iSurfaceId = surfaceId;
+ RSurfaceManager::TInfoBuf info;
+ err = iDriverImpl.SurfaceInfo(surfaceId, info);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ err=iDriverImpl.GetBufferOffset(surfaceId,0,iDataOffset);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iDataStride = info().iStride;
+ RChunk chunk;
+ err = iDriverImpl.MapSurface(surfaceId, chunk);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iDataChunk = chunk;
+ new(chunk.Base()) TSgImageMetaData(aInfo, iDriverImpl.PixelFormatTable(), aIsCached);
+ return err;
+ }
+
+
+TInt XSgImageState_SurfaceManager::Construct(const TSgDrawableId& aId)
+ {
+ const TSgImageId_SurfaceManager& id_SurfaceManager = reinterpret_cast<const TSgImageId_SurfaceManager&>(aId);
+ if (id_SurfaceManager.iBufferIndex < 0)
+ {
+ return KErrNotFound;
+ }
+ if (id_SurfaceManager.iMetaDataIndex < 0)
+ {
+ return KErrNotFound;
+ }
+ TInt err = iDriverImpl.OpenSurface(id_SurfaceManager.iSurfaceId);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iSurfaceId = id_SurfaceManager.iSurfaceId;
+ RSurfaceManager::TInfoBuf info;
+ err = iDriverImpl.SurfaceInfo(id_SurfaceManager.iSurfaceId, info);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iDataStride = info().iStride;
+ if (id_SurfaceManager.iBufferIndex >= info().iBuffers)
+ {
+ return KErrNotFound;
+ }
+ iBufferIndex = id_SurfaceManager.iBufferIndex;
+ TInt offsetToFirstBuffer;
+ err=iDriverImpl.GetBufferOffset(id_SurfaceManager.iSurfaceId,0,offsetToFirstBuffer);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ if ((id_SurfaceManager.iMetaDataIndex + 1) * sizeof(TSgImageMetaData) > offsetToFirstBuffer)
+ {
+ return KErrNotFound;
+ }
+ iMetaDataOffset = id_SurfaceManager.iMetaDataIndex * sizeof(TSgImageMetaData);
+ RChunk chunk;
+ err = iDriverImpl.MapSurface(id_SurfaceManager.iSurfaceId, chunk);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ iDataChunk = chunk;
+ err=iDriverImpl.GetBufferOffset(id_SurfaceManager.iSurfaceId,id_SurfaceManager.iBufferIndex,iDataOffset);
+ return err;
+ }
+
+
+XSgImageState_SurfaceManager::~XSgImageState_SurfaceManager()
+ {
+ if (!iSurfaceId.IsNull())
+ {
+ iDriverImpl.CloseSurface(iSurfaceId);
+ iDataChunk.Close();
+ }
+ }
+
+
+const TSgImageMetaData& XSgImageState_SurfaceManager::MetaData() const
+ {
+ return *reinterpret_cast<TSgImageMetaData*>(iDataChunk.Base() + iMetaDataOffset);
+ }
+
+
+TInt XSgImageState_SurfaceManager::GetUserAttributes(TSgUserAttribute* aUserAttributes, TInt aUserAttributeCount) const
+ {
+ for (TInt i = 0; i < aUserAttributeCount; ++i)
+ {
+ RSurfaceManager::THintPair hint;
+ hint.iKey = aUserAttributes[i].iUid;
+ TInt err = iDriverImpl.GetSurfaceHint(iSurfaceId, hint);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ aUserAttributes[i].iValue = hint.iValue;
+ }
+ return KErrNone;
+ }
+
+
+TAny* XSgImageState_SurfaceManager::DataAddress() const
+ {
+#ifdef SYMBIAN_GRAPHICS_AUTOFLUSH_CACHE
+ __ASSERT_DEBUG(iCpuAccess != ESgCpuAccessNone, ::Panic(ESgPanicNoCpuAccess));
+#endif
+ return iDataChunk.Base() + iDataOffset;
+ }
+
+
+#ifdef SYMBIAN_GRAPHICS_AUTOFLUSH_CACHE
+
+TInt XSgImageState_SurfaceManager::BeginDataAccess(TSgCpuAccess aCpuAccess, TBool aIsUserAccess)
+ {
+ TInt err = XSgImageStateBase::BeginDataAccess(aCpuAccess, aIsUserAccess);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ if (aCpuAccess != ESgCpuAccessWriteOnly && MetaData().iIsCached && (MetaData().iPotentialUsage & KSgUsageAllTargets))
+ {
+ // Cache::SyncMemoryAfterDmaRead() cannot fail so the following should not fail if the arguments are correct
+ err = iDriverImpl.SynchronizeCache(iSurfaceId, iBufferIndex, RSurfaceManager::ESyncAfterNonCPUWrite);
+ __ASSERT_DEBUG(err == KErrNone, Panic(ESgPanicResourceAdapterGeneral));
+ }
+ return KErrNone;
+ }
+
+
+TInt XSgImageState_SurfaceManager::EndDataAccess(TBool aIsUserAccess)
+ {
+ TSgCpuAccess prevCpuAccess = iCpuAccess;
+ TInt err = XSgImageStateBase::EndDataAccess(aIsUserAccess);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ if (prevCpuAccess != ESgCpuAccessReadOnly && MetaData().iIsCached)
+ {
+ // Cache::SyncMemoryBeforeDmaWrite() cannot fail so the following should not fail if the arguments are correct
+ err = iDriverImpl.SynchronizeCache(iSurfaceId, iBufferIndex, RSurfaceManager::ESyncBeforeNonCPURead);
+ __ASSERT_DEBUG(err == KErrNone, Panic(ESgPanicResourceAdapterGeneral));
+ }
+ return KErrNone;
+ }
+
+#endif