os/graphics/graphicsresourceservices/graphicsresourceadaptation/src/sgimageimpl.cpp
First public contribution.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "sgimageimpl.h"
17 #include "sgresourceinternal.h"
22 TSgImageMetaData::TSgImageMetaData(const TSgImageInfo& aInfo, TArray<TSgPixelFormatTableEntry> aPixelFormatTable, TBool aIsCached)
23 : iCreatorProcess(RProcess().Id()),
24 iSizeInPixels(aInfo.iSizeInPixels),
25 iPixelFormat(aInfo.iPixelFormat),
26 iRequestedUsage(aInfo.iUsage),
28 iShareable(aInfo.iShareable),
29 iCpuAccess(aInfo.iCpuAccess),
30 iScreenId(aInfo.iScreenId),
33 TUint32 usageMask = (aInfo.iUsage & KSgUsageAllSources ? KSgUsageAllSources : 0)
34 | (aInfo.iUsage & KSgUsageAllTargets ? KSgUsageAllTargets : 0);
35 TInt n = aPixelFormatTable.Count();
36 for (TInt i = 0; i < n; ++i)
38 const TSgPixelFormatTableEntry& entry = aPixelFormatTable[i];
39 if (entry.IsMatchIgnoringUsage(aInfo))
41 iPotentialUsage |= entry.iUsage & usageMask;
47 void TSgImageMetaData::GetInfo(TSgImageInfo& aInfo, TBool aGetPotentialUsage) const
49 aInfo.iSizeInPixels = iSizeInPixels;
50 aInfo.iPixelFormat = iPixelFormat;
51 aInfo.iUsage = aGetPotentialUsage ? iPotentialUsage : iRequestedUsage;
52 aInfo.iShareable = iShareable;
53 aInfo.iCpuAccess = iCpuAccess;
54 aInfo.iScreenId = iScreenId;
60 XSgImageImplBase::XSgImageImplBase(const XSgImageImplBase& aImage, TUint32 aFlags)
61 : XSgBase(aImage.iDriverImpl)
63 __ASSERT_DEBUG(iDriverImpl.IsMutexHeld(), Panic(ESgPanicMutexNotHeld));
65 iId.iId[KSgImageIdFlagsIndex] = aFlags;
66 aImage.iState->IncRefCount();
67 iState = aImage.iState;
71 XSgImageImplBase::~XSgImageImplBase()
73 __ASSERT_DEBUG(iDriverImpl.IsMutexHeld(), Panic(ESgPanicMutexNotHeld));
74 if (iState && iState->DecRefCount() == 0)
82 TInt XSgImageImplBase::Compare(const TSgDrawableId* aId, const XSgImageImplBase& aImage)
84 return Mem::Compare(reinterpret_cast<const TUint8*>(aId), sizeof(TSgDrawableId),
85 reinterpret_cast<const TUint8*>(&aImage.Id()), sizeof(TSgDrawableId));
89 TInt XSgImageImplBase::Compare(const XSgImageImplBase& aImage1, const XSgImageImplBase& aImage2)
91 return Compare(&aImage1.Id(), aImage2);
95 TInt XSgImageImplBase::CompareIgnoringFlags(const TSgDrawableId* aId, const XSgImageImplBase& aImage)
97 return Mem::Compare(reinterpret_cast<const TUint8*>(aId), sizeof(TSgDrawableId) - sizeof(TUint32),
98 reinterpret_cast<const TUint8*>(&aImage.Id()), sizeof(TSgDrawableId) - sizeof(TUint32));
102 void XSgImageImplBase::Close()
104 XSgDriverImpl& driverImpl = iDriverImpl;
106 if (DecRefCount() == 0)
108 driverImpl.DeleteImage(this);
114 const TSgDrawableId& XSgImageImplBase::Id() const
120 TUid XSgImageImplBase::DrawableType() const
122 return KSgImageTypeUid;
126 TInt XSgImageImplBase::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
128 if (aInterfaceUid.iUid == MSgImage_Sw::EInterfaceUid)
130 aInterfacePtr = static_cast<MSgImage_Sw*>(this);
133 return KErrExtensionNotSupported;
137 TInt XSgImageImplBase::GetInfo(TSgImageInfo& aInfo) const
139 iState->MetaData().GetInfo(aInfo, iId.iId[KSgImageIdFlagsIndex] & ESgDoNotRestrictUsage);
140 return iState->GetUserAttributes(aInfo.iUserAttributes, aInfo.iUserAttributeCount);
144 TInt XSgImageImplBase::MapReadOnly(const TAny*& aDataAddress, TInt& aDataStride)
146 TInt err = iState->BeginDataAccess(ESgCpuAccessReadOnly, ETrue);
151 aDataAddress = iState->DataAddress();
152 aDataStride = iState->DataStride();
157 TInt XSgImageImplBase::MapWriteOnly(TAny*& aDataAddress, TInt& aDataStride)
159 TInt err = iState->BeginDataAccess(ESgCpuAccessWriteOnly, ETrue);
164 aDataAddress = iState->DataAddress();
165 aDataStride = iState->DataStride();
170 TInt XSgImageImplBase::MapReadWrite(TAny*& aDataAddress, TInt& aDataStride)
172 TInt err = iState->BeginDataAccess(ESgCpuAccessReadWrite, ETrue);
177 aDataAddress = iState->DataAddress();
178 aDataStride = iState->DataStride();
183 TInt XSgImageImplBase::Unmap()
185 return iState->EndDataAccess(ETrue);
189 TAny* XSgImageImplBase::DataAddress() const
191 return iState->DataAddress();
195 TInt XSgImageImplBase::DataStride() const
197 return iState->DataStride();
201 TInt XSgImageImplBase::BeginDataAccess(TSgCpuAccess aCpuAccess)
203 return iState->BeginDataAccess(aCpuAccess, EFalse);
207 TInt XSgImageImplBase::EndDataAccess()
209 return iState->EndDataAccess(EFalse);
213 TInt XSgImageImplBase::SetData(const TAny* aDataAddress, TInt aDataStride)
217 TInt err = BeginDataAccess(ESgCpuAccessWriteOnly);
222 const TSgImageMetaData& metaData = iState->MetaData();
223 const TAny* src = aDataAddress;
224 TAny* trg = iState->DataAddress();
225 TInt dataStride = iState->DataStride();
226 TInt minDataStride = SgMinDataStride(metaData.iSizeInPixels.iWidth, metaData.iPixelFormat);
227 __ASSERT_DEBUG(minDataStride > 0, Panic(ESgPanicResourceAdapterGeneral));
228 for (TInt y = 0; y < metaData.iSizeInPixels.iHeight; ++y)
230 Mem::Copy(trg, src, minDataStride);
231 src = PtrAdd(src, aDataStride);
232 trg = PtrAdd(trg, dataStride);
240 TInt XSgImageStateBase::BeginDataAccess(TSgCpuAccess aCpuAccess, TBool aIsUserAccess)
242 if (aCpuAccess == ESgCpuAccessNone)
246 const TSgImageMetaData& metaData = MetaData();
247 if (aIsUserAccess && (~metaData.iCpuAccess & aCpuAccess))
249 return KErrAccessDenied;
251 if (aIsUserAccess && metaData.iCreatorProcess != RProcess().Id())
253 return KErrPermissionDenied;
256 if (iCpuAccess != ESgCpuAccessNone)
258 iDriverImpl.Signal();
261 iCpuAccess = aCpuAccess;
262 iIsUserAccess = aIsUserAccess;
263 iDriverImpl.Signal();
268 TInt XSgImageStateBase::EndDataAccess(TBool aIsUserAccess)
271 if (iCpuAccess == ESgCpuAccessNone || iIsUserAccess != aIsUserAccess)
273 iDriverImpl.Signal();
276 iCpuAccess = ESgCpuAccessNone;
277 iIsUserAccess = EFalse;
278 iDriverImpl.Signal();
283 #ifndef SYMBIAN_GRAPHICS_USE_GPU
285 // XSgImageImpl_SwLocal
287 TInt XSgImageImpl_SwLocal::New(XSgImageImpl_SwLocal*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId,
288 const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride)
290 aPtr = static_cast<XSgImageImpl_SwLocal*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SwLocal)));
295 new(aPtr) XSgImageImpl_SwLocal(aDriverImpl, aId);
296 TInt err = aPtr->Construct(aInfo, aDataAddress, aDataStride);
306 TInt XSgImageImpl_SwLocal::New(XSgImageImpl_SwLocal*& aPtr, const XSgImageImpl_SwLocal& aImage, TUint32 aFlags)
308 aPtr = static_cast<XSgImageImpl_SwLocal*>(aImage.iDriverImpl.Alloc(sizeof(XSgImageImpl_SwLocal)));
313 new(aPtr) XSgImageImpl_SwLocal(aImage, aFlags);
318 TInt XSgImageImpl_SwLocal::Construct(const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride)
320 XSgImageState_SwLocal* state;
321 TInt err = XSgImageState_SwLocal::New(state, iDriverImpl, aInfo);
326 state->IncRefCount();
328 return SetData(aDataAddress, aDataStride);
332 // XSgImageState_SwLocal
334 TInt XSgImageState_SwLocal::New(XSgImageState_SwLocal*& aPtr, XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo)
336 TInt dataStride = Align4(SgMinDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat));
337 TInt size = _FOFF(XSgImageState_SwLocal, iUserAttributes) + aInfo.iUserAttributeCount * sizeof(TSgUserAttribute) + dataStride * aInfo.iSizeInPixels.iHeight;
338 aPtr = static_cast<XSgImageState_SwLocal*>(aDriverImpl.Alloc(size));
343 new(aPtr) XSgImageState_SwLocal(aDriverImpl, aInfo, dataStride);
348 XSgImageState_SwLocal::XSgImageState_SwLocal(XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo, TInt aDataStride)
349 : XSgImageStateBase(aDriverImpl, aDataStride), iMetaData(aInfo, aDriverImpl.PixelFormatTable())
351 iUserAttributeCount = aInfo.iUserAttributeCount;
352 Mem::Copy(iUserAttributes, aInfo.iUserAttributes, aInfo.iUserAttributeCount * sizeof(TSgUserAttribute));
356 const TSgImageMetaData& XSgImageState_SwLocal::MetaData() const
362 TInt XSgImageState_SwLocal::GetUserAttributes(TSgUserAttribute* aUserAttributes, TInt aUserAttributeCount) const
364 for (TInt i = 0; i < aUserAttributeCount; ++i)
366 TBool found = EFalse;
367 for (TInt j = 0; j < iUserAttributeCount; ++j)
369 if (aUserAttributes[i].iUid == iUserAttributes[j].iUid)
371 aUserAttributes[i].iValue = iUserAttributes[j].iValue;
385 TAny* XSgImageState_SwLocal::DataAddress() const
387 //__ASSERT_DEBUG(iCpuAccess != ESgCpuAccessNone, ::Panic(ESgPanicNoCpuAccess));
388 return (TAny*)PtrAdd(iUserAttributes, iUserAttributeCount * sizeof(TSgUserAttribute));
394 // XSgImageImpl_SurfaceManager
397 TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl,
398 const TSgImageInfo& aInfo, TBool aIsCached, const TAny* aDataAddress, TInt aDataStride)
400 aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
405 new(aPtr) XSgImageImpl_SurfaceManager(aDriverImpl);
406 TInt err = aPtr->Construct(aInfo, aIsCached, aDataAddress, aDataStride);
416 TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId)
418 aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
423 new(aPtr) XSgImageImpl_SurfaceManager(aDriverImpl, aId);
424 TInt err = aPtr->Construct(aId);
434 TInt XSgImageImpl_SurfaceManager::New(XSgImageImpl_SurfaceManager*& aPtr, const XSgImageImpl_SurfaceManager& aImage, TUint32 aFlags)
436 aPtr = static_cast<XSgImageImpl_SurfaceManager*>(aImage.iDriverImpl.Alloc(sizeof(XSgImageImpl_SurfaceManager)));
441 new(aPtr) XSgImageImpl_SurfaceManager(aImage, aFlags);
446 TInt XSgImageImpl_SurfaceManager::Construct(const TSgImageInfo& aInfo, TBool aIsCached, const TAny* aDataAddress, TInt aDataStride)
448 XSgImageState_SurfaceManager* state;
449 TInt err = XSgImageState_SurfaceManager::New(state, iDriverImpl, aInfo, aIsCached);
454 Mem::Copy(&iId, &state->SurfaceId(), sizeof(TSurfaceId));
455 state->IncRefCount();
457 return SetData(aDataAddress, aDataStride);
461 TInt XSgImageImpl_SurfaceManager::Construct(const TSgDrawableId& aId)
463 XSgImageState_SurfaceManager* state;
464 TInt err = XSgImageState_SurfaceManager::New(state, iDriverImpl, aId);
469 state->IncRefCount();
475 TInt XSgImageImpl_SurfaceManager::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
477 if (aInterfaceUid.iUid == MSgImage_Chunk::EInterfaceUid)
479 aInterfacePtr = static_cast<MSgImage_Chunk*>(this);
482 return XSgImageImplBase::GetInterface(aInterfaceUid, aInterfacePtr);
486 const RChunk& XSgImageImpl_SurfaceManager::DataChunk() const
488 return static_cast<XSgImageState_SurfaceManager*>(iState)->DataChunk();
492 TInt XSgImageImpl_SurfaceManager::DataOffset() const
494 return static_cast<XSgImageState_SurfaceManager*>(iState)->DataOffset();
498 TInt XSgImageImpl_SurfaceManager::DataStride() const
500 return iState->DataStride();
504 // XSgImageState_SurfaceManager
506 TInt XSgImageState_SurfaceManager::New(XSgImageState_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgImageInfo& aInfo, TBool aIsCached)
508 aPtr = static_cast<XSgImageState_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageState_SurfaceManager)));
513 new(aPtr) XSgImageState_SurfaceManager(aDriverImpl);
514 TInt err = aPtr->Construct(aInfo, aIsCached);
524 TInt XSgImageState_SurfaceManager::New(XSgImageState_SurfaceManager*& aPtr, XSgDriverImpl& aDriverImpl, const TSgDrawableId& aId)
526 aPtr = static_cast<XSgImageState_SurfaceManager*>(aDriverImpl.Alloc(sizeof(XSgImageState_SurfaceManager)));
531 new(aPtr) XSgImageState_SurfaceManager(aDriverImpl);
532 TInt err = aPtr->Construct(aId);
542 TInt XSgImageState_SurfaceManager::Construct(const TSgImageInfo& aInfo, TBool aIsCached)
544 TInt maxNumberOfHints;
546 err=iDriverImpl.GetSurfaceManagerAttrib(RSurfaceManager::EMaxNumberOfHints,maxNumberOfHints);
552 if (aInfo.iUserAttributeCount > maxNumberOfHints)
556 RSurfaceManager::THintPair* hints = new RSurfaceManager::THintPair[aInfo.iUserAttributeCount];
561 RSurfaceManager::TSurfaceCreationAttributesBuf reqs;
562 reqs().iSurfaceHints = hints;
563 reqs().iHintCount = aInfo.iUserAttributeCount;
564 reqs().iSize = aInfo.iSizeInPixels;
566 reqs().iPixelFormat = aInfo.iPixelFormat;
567 reqs().iStride = SgAlignedDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
568 reqs().iOffsetToFirstBuffer = SgOffsetToFirstBuffer(sizeof(TSgImageMetaData));
569 reqs().iAlignment = 4;
570 reqs().iContiguous = EFalse;
571 reqs().iCacheAttrib = aIsCached ? RSurfaceManager::ECached : RSurfaceManager::ENotCached;
572 reqs().iOffsetBetweenBuffers = SgOffsetBetweenBuffers(reqs().iStride, aInfo.iSizeInPixels.iHeight);
573 reqs().iMappable = ETrue;
574 for (TInt i = 0; i < aInfo.iUserAttributeCount; ++i)
576 reqs().iSurfaceHints[i].iKey = aInfo.iUserAttributes[i].iUid;
577 reqs().iSurfaceHints[i].iValue = aInfo.iUserAttributes[i].iValue;
578 reqs().iSurfaceHints[i].iMutable = EFalse;
580 TSurfaceId surfaceId;
581 err = iDriverImpl.CreateSurface(reqs, surfaceId);
584 reqs().iSurfaceHints = NULL;
589 iSurfaceId = surfaceId;
590 RSurfaceManager::TInfoBuf info;
591 err = iDriverImpl.SurfaceInfo(surfaceId, info);
596 err=iDriverImpl.GetBufferOffset(surfaceId,0,iDataOffset);
601 iDataStride = info().iStride;
603 err = iDriverImpl.MapSurface(surfaceId, chunk);
609 new(chunk.Base()) TSgImageMetaData(aInfo, iDriverImpl.PixelFormatTable(), aIsCached);
614 TInt XSgImageState_SurfaceManager::Construct(const TSgDrawableId& aId)
616 const TSgImageId_SurfaceManager& id_SurfaceManager = reinterpret_cast<const TSgImageId_SurfaceManager&>(aId);
617 if (id_SurfaceManager.iBufferIndex < 0)
621 if (id_SurfaceManager.iMetaDataIndex < 0)
625 TInt err = iDriverImpl.OpenSurface(id_SurfaceManager.iSurfaceId);
630 iSurfaceId = id_SurfaceManager.iSurfaceId;
631 RSurfaceManager::TInfoBuf info;
632 err = iDriverImpl.SurfaceInfo(id_SurfaceManager.iSurfaceId, info);
637 iDataStride = info().iStride;
638 if (id_SurfaceManager.iBufferIndex >= info().iBuffers)
642 iBufferIndex = id_SurfaceManager.iBufferIndex;
643 TInt offsetToFirstBuffer;
644 err=iDriverImpl.GetBufferOffset(id_SurfaceManager.iSurfaceId,0,offsetToFirstBuffer);
649 if ((id_SurfaceManager.iMetaDataIndex + 1) * sizeof(TSgImageMetaData) > offsetToFirstBuffer)
653 iMetaDataOffset = id_SurfaceManager.iMetaDataIndex * sizeof(TSgImageMetaData);
655 err = iDriverImpl.MapSurface(id_SurfaceManager.iSurfaceId, chunk);
661 err=iDriverImpl.GetBufferOffset(id_SurfaceManager.iSurfaceId,id_SurfaceManager.iBufferIndex,iDataOffset);
666 XSgImageState_SurfaceManager::~XSgImageState_SurfaceManager()
668 if (!iSurfaceId.IsNull())
670 iDriverImpl.CloseSurface(iSurfaceId);
676 const TSgImageMetaData& XSgImageState_SurfaceManager::MetaData() const
678 return *reinterpret_cast<TSgImageMetaData*>(iDataChunk.Base() + iMetaDataOffset);
682 TInt XSgImageState_SurfaceManager::GetUserAttributes(TSgUserAttribute* aUserAttributes, TInt aUserAttributeCount) const
684 for (TInt i = 0; i < aUserAttributeCount; ++i)
686 RSurfaceManager::THintPair hint;
687 hint.iKey = aUserAttributes[i].iUid;
688 TInt err = iDriverImpl.GetSurfaceHint(iSurfaceId, hint);
693 aUserAttributes[i].iValue = hint.iValue;
699 TAny* XSgImageState_SurfaceManager::DataAddress() const
701 #ifdef SYMBIAN_GRAPHICS_AUTOFLUSH_CACHE
702 __ASSERT_DEBUG(iCpuAccess != ESgCpuAccessNone, ::Panic(ESgPanicNoCpuAccess));
704 return iDataChunk.Base() + iDataOffset;
708 #ifdef SYMBIAN_GRAPHICS_AUTOFLUSH_CACHE
710 TInt XSgImageState_SurfaceManager::BeginDataAccess(TSgCpuAccess aCpuAccess, TBool aIsUserAccess)
712 TInt err = XSgImageStateBase::BeginDataAccess(aCpuAccess, aIsUserAccess);
717 if (aCpuAccess != ESgCpuAccessWriteOnly && MetaData().iIsCached && (MetaData().iPotentialUsage & KSgUsageAllTargets))
719 // Cache::SyncMemoryAfterDmaRead() cannot fail so the following should not fail if the arguments are correct
720 err = iDriverImpl.SynchronizeCache(iSurfaceId, iBufferIndex, RSurfaceManager::ESyncAfterNonCPUWrite);
721 __ASSERT_DEBUG(err == KErrNone, Panic(ESgPanicResourceAdapterGeneral));
727 TInt XSgImageState_SurfaceManager::EndDataAccess(TBool aIsUserAccess)
729 TSgCpuAccess prevCpuAccess = iCpuAccess;
730 TInt err = XSgImageStateBase::EndDataAccess(aIsUserAccess);
735 if (prevCpuAccess != ESgCpuAccessReadOnly && MetaData().iIsCached)
737 // Cache::SyncMemoryBeforeDmaWrite() cannot fail so the following should not fail if the arguments are correct
738 err = iDriverImpl.SynchronizeCache(iSurfaceId, iBufferIndex, RSurfaceManager::ESyncBeforeNonCPURead);
739 __ASSERT_DEBUG(err == KErrNone, Panic(ESgPanicResourceAdapterGeneral));