diff -r 000000000000 -r 5d03bc08d59c graphicsresourceservices/graphicsresourceadaptation/src/sgimageimpl.cpp --- /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 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(aId), sizeof(TSgDrawableId), + reinterpret_cast(&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(aId), sizeof(TSgDrawableId) - sizeof(TUint32), + reinterpret_cast(&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(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(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(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(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(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(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(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(this); + return KErrNone; + } + return XSgImageImplBase::GetInterface(aInterfaceUid, aInterfacePtr); + } + + +const RChunk& XSgImageImpl_SurfaceManager::DataChunk() const + { + return static_cast(iState)->DataChunk(); + } + + +TInt XSgImageImpl_SurfaceManager::DataOffset() const + { + return static_cast(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(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(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(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(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