os/graphics/graphicsresourceservices/graphicsresourceadaptation/src/sgdriverimpl.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsresourceservices/graphicsresourceadaptation/src/sgdriverimpl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,813 @@
1.4 +// Copyright (c) 2007-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 +//
1.18 +
1.19 +#include <e32math.h>
1.20 +#include "sgdriverimpl.h"
1.21 +#include "sgimageimpl.h"
1.22 +#include "sgimagecollectionimpl.h"
1.23 +
1.24 +
1.25 +TInt SgAlignedDataStride(TInt aWidthInPixels, TUidPixelFormat aPixelFormat)
1.26 + {
1.27 +#if defined(SYMBIAN_GRAPHICS_USE_MBX)
1.28 + // MBX requires 2^n stride.
1.29 + for (TInt width = 8; width & KMaxTInt; width <<= 1)
1.30 + {
1.31 + if (width >= aWidthInPixels)
1.32 + {
1.33 + aWidthInPixels = width;
1.34 + break;
1.35 + }
1.36 + }
1.37 +#elif defined(SYMBIAN_GRAPHICS_USE_SGX)
1.38 + // SGX requires a 32 pixel alignment.
1.39 + aWidthInPixels = (aWidthInPixels + 31) & ~31;
1.40 +#endif
1.41 + return Align4(SgMinDataStride(aWidthInPixels, aPixelFormat));
1.42 + }
1.43 +
1.44 +
1.45 +TInt SgOffsetToFirstBuffer(TInt aMetaDataSize)
1.46 + {
1.47 +#if defined(SYMBIAN_GRAPHICS_USE_MBX) || defined(SYMBIAN_GRAPHICS_USE_SGX)
1.48 + return (aMetaDataSize + 127) & ~127;
1.49 +#else
1.50 + return Align4(aMetaDataSize);
1.51 +#endif
1.52 + }
1.53 +
1.54 +
1.55 +TInt SgOffsetBetweenBuffers(TInt aDataStride, TInt aScanLineCount)
1.56 + {
1.57 +#if defined(SYMBIAN_GRAPHICS_USE_MBX)
1.58 + for (TInt count = 16; count & KMaxTInt; count <<= 1)
1.59 + {
1.60 + if (count >= aScanLineCount)
1.61 + {
1.62 + aScanLineCount = count;
1.63 + break;
1.64 + }
1.65 + }
1.66 +#endif
1.67 + return aDataStride * aScanLineCount;
1.68 + }
1.69 +
1.70 +
1.71 +TBool SgIsValidImageInfo(const TSgImageInfo& aInfo)
1.72 + {
1.73 + return aInfo.iSizeInPixels.iWidth > 0 && aInfo.iSizeInPixels.iHeight > 0
1.74 + && (aInfo.iUsage & ESgUsageScreenSource ? aInfo.iScreenId >= KSgScreenIdMain : aInfo.iScreenId >= KSgScreenIdAny)
1.75 + && (aInfo.iUserAttributes ? aInfo.iUserAttributeCount > 0 : aInfo.iUserAttributeCount == 0);
1.76 + }
1.77 +
1.78 +
1.79 +TBool SgIsMutableImage(const TSgImageInfo& aInfo)
1.80 + {
1.81 + return (aInfo.iCpuAccess & ESgCpuAccessWritable) || (aInfo.iUsage & KSgUsageAllTargets);
1.82 + }
1.83 +
1.84 +
1.85 +TBool SgIsCachedImage(const TSgImageInfo& aInfo)
1.86 + {
1.87 +#ifdef SYMBIAN_GRAPHICS_USE_GPU
1.88 +#ifdef SYMBIAN_GRAPHICS_USE_CACHE
1.89 + return aInfo.iCpuAccess != ESgCpuAccessNone;
1.90 +#else
1.91 + (void)aInfo;
1.92 + return EFalse;
1.93 +#endif
1.94 +#else
1.95 + (void)aInfo;
1.96 + return ETrue;
1.97 +#endif
1.98 + }
1.99 +
1.100 +
1.101 +// TSgPixelFormatTableEntry
1.102 +
1.103 +TBool TSgPixelFormatTableEntry::IsMatch(const TSgImageInfo& aInfo) const
1.104 + {
1.105 + return iPixelFormat == aInfo.iPixelFormat
1.106 + && !(~iUsage & aInfo.iUsage)
1.107 + && !(~iCpuAccess & aInfo.iCpuAccess)
1.108 + && (iScreenId == KSgScreenIdAny || iScreenId == aInfo.iScreenId);
1.109 + }
1.110 +
1.111 +
1.112 +TBool TSgPixelFormatTableEntry::IsMatchIgnoringPixelFormat(const TSgImageInfo& aInfo) const
1.113 + {
1.114 + return !(~iUsage & aInfo.iUsage)
1.115 + && !(~iCpuAccess & aInfo.iCpuAccess)
1.116 + && (iScreenId == KSgScreenIdAny || iScreenId == aInfo.iScreenId);
1.117 + }
1.118 +
1.119 +
1.120 +TBool TSgPixelFormatTableEntry::IsMatchIgnoringUsage(const TSgImageInfo& aInfo) const
1.121 + {
1.122 + return iPixelFormat == aInfo.iPixelFormat
1.123 + && !(~iCpuAccess & aInfo.iCpuAccess)
1.124 + && (iScreenId == KSgScreenIdAny || iScreenId == aInfo.iScreenId);
1.125 + }
1.126 +
1.127 +
1.128 +// XSgBase
1.129 +
1.130 +XSgBase::~XSgBase()
1.131 + {
1.132 + __ASSERT_DEBUG(iDriverImpl.IsMutexHeld(), Panic(ESgPanicMutexNotHeld));
1.133 + __ASSERT_DEBUG(iRefCount == 0, Panic(ESgPanicBadReferenceCount));
1.134 + }
1.135 +
1.136 +
1.137 +void XSgBase::Delete()
1.138 + {
1.139 + XSgDriverImpl& driverImpl = iDriverImpl;
1.140 + this->~XSgBase();
1.141 + driverImpl.Free(this);
1.142 + }
1.143 +
1.144 +
1.145 +// XSgDriverImpl
1.146 +
1.147 +TInt XSgDriverImpl::Construct()
1.148 + {
1.149 + TInt err = iMutex.CreateLocal();
1.150 + if (err != KErrNone)
1.151 + {
1.152 + return err;
1.153 + }
1.154 + err = iSurfaceManager.Open();
1.155 + if (err != KErrNone)
1.156 + {
1.157 + return err;
1.158 + }
1.159 + return ConstructPixelFormatTable();
1.160 + }
1.161 +
1.162 +
1.163 +XSgDriverImpl::~XSgDriverImpl()
1.164 + {
1.165 + __ASSERT_DEBUG(iImages.Count() == 0, Panic(ESgPanicUnclosedResources));
1.166 + __ASSERT_DEBUG(iImageCollections.Count() == 0, Panic(ESgPanicUnclosedResources));
1.167 + iMutex.Close();
1.168 + iSurfaceManager.Close();
1.169 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.170 + iPixelFormatTable.Close();
1.171 + iLastPixelFormats.Close();
1.172 + User::SwitchHeap(prevHeap);
1.173 + }
1.174 +
1.175 +
1.176 +void XSgDriverImpl::Delete()
1.177 + {
1.178 + RHeap* heap = iHeap;
1.179 + this->~XSgDriverImpl();
1.180 + heap->Free(this);
1.181 + __ASSERT_DEBUG(heap->Count() == 0, Panic(ESgPanicUnclosedResources));
1.182 + heap->Close();
1.183 + }
1.184 +
1.185 +
1.186 +TInt XSgDriverImpl::MapSurface(const TSurfaceId& aSurfaceId, RChunk& aChunk)
1.187 + {
1.188 + RChunk chunk;
1.189 + TInt err = iSurfaceManager.MapSurface(aSurfaceId, chunk);
1.190 + if (err != KErrNone)
1.191 + {
1.192 + return err;
1.193 + }
1.194 + aChunk = chunk;
1.195 + err = aChunk.Duplicate(RThread()); // Get a process-wide handle
1.196 + chunk.Close();
1.197 + return err;
1.198 + }
1.199 +
1.200 +
1.201 +TArray<TSgPixelFormatTableEntry> XSgDriverImpl::PixelFormatTable() const
1.202 + {
1.203 + return iPixelFormatTable.Array();
1.204 + }
1.205 +
1.206 +
1.207 +TInt XSgDriverImpl::CanCreateImage(const TSgImageInfo& aInfo) const
1.208 + {
1.209 + __ASSERT_DEBUG(SgIsValidImageInfo(aInfo), Panic(ESgPanicBadImageInfo));
1.210 + if (aInfo.iSizeInPixels.iWidth > KMaxTInt16 / 2 || aInfo.iSizeInPixels.iHeight > KMaxTInt16 / 2)
1.211 + {
1.212 + return KErrTooBig;
1.213 + }
1.214 + TArray<TSgPixelFormatTableEntry> pixelFormatTable = PixelFormatTable();
1.215 + TInt n = pixelFormatTable.Count();
1.216 + for (TInt i = 0; i < n; ++i)
1.217 + {
1.218 + if (pixelFormatTable[i].IsMatch(aInfo))
1.219 + {
1.220 + return SgMinDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat) > 0 ? KErrNone : KErrNotSupported;
1.221 + }
1.222 + }
1.223 + return KErrNotSupported;
1.224 + }
1.225 +
1.226 +
1.227 +TInt XSgDriverImpl::GetPixelFormats(const TSgImageInfo& aInfo, TUidPixelFormat* aPixelFormats, TInt& aCount)
1.228 + {
1.229 + if (!SgIsValidImageInfo(aInfo) || (aPixelFormats && aCount < 0))
1.230 + {
1.231 + return KErrArgument;
1.232 + }
1.233 + iMutex.Wait();
1.234 + if (aInfo.iSizeInPixels != iLastSizeInPixels
1.235 + || aInfo.iUsage != iLastUsage
1.236 + || aInfo.iCpuAccess != iLastCpuAccess
1.237 + || aInfo.iScreenId != iLastScreenId)
1.238 + {
1.239 + iLastSizeInPixels = aInfo.iSizeInPixels;
1.240 + iLastUsage = aInfo.iUsage;
1.241 + iLastCpuAccess = aInfo.iCpuAccess;
1.242 + iLastScreenId = aInfo.iScreenId;
1.243 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.244 + iLastPixelFormats.Reset();
1.245 + User::SwitchHeap(prevHeap);
1.246 + TArray<TSgPixelFormatTableEntry> pixelFormatTable = PixelFormatTable();
1.247 + TInt n = pixelFormatTable.Count();
1.248 + for (TInt i = 0; i < n; ++i)
1.249 + {
1.250 + const TSgPixelFormatTableEntry& entry = pixelFormatTable[i];
1.251 + if (entry.IsMatchIgnoringPixelFormat(aInfo) && iLastPixelFormats.Find(entry.iPixelFormat) == KErrNotFound)
1.252 + {
1.253 + User::SwitchHeap(iHeap);
1.254 + TInt err = iLastPixelFormats.Append(entry.iPixelFormat);
1.255 + User::SwitchHeap(prevHeap);
1.256 + if (err != KErrNone)
1.257 + {
1.258 + iLastSizeInPixels = TSize(0, 0);
1.259 + iLastUsage = ESgUsageNone;
1.260 + iLastCpuAccess = ESgCpuAccessNone;
1.261 + iLastScreenId = KSgScreenIdMain;
1.262 + User::SwitchHeap(iHeap);
1.263 + iLastPixelFormats.Reset();
1.264 + User::SwitchHeap(prevHeap);
1.265 + iMutex.Signal();
1.266 + return err;
1.267 + }
1.268 + }
1.269 + }
1.270 + }
1.271 + TInt err = KErrNone;
1.272 + if (aPixelFormats)
1.273 + {
1.274 + TInt n = Min(aCount, iLastPixelFormats.Count());
1.275 + for (TInt i = 0; i < n; ++i)
1.276 + {
1.277 + aPixelFormats[i] = iLastPixelFormats[i];
1.278 + }
1.279 + if (aCount < iLastPixelFormats.Count())
1.280 + {
1.281 + err = KErrOverflow;
1.282 + }
1.283 + }
1.284 + aCount = iLastPixelFormats.Count();
1.285 + iMutex.Signal();
1.286 + return err;
1.287 + }
1.288 +
1.289 +
1.290 +TInt XSgDriverImpl::CreateImage(const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride, MSgDrawableAdapter*& aResult)
1.291 + {
1.292 + if (!SgIsValidImageInfo(aInfo))
1.293 + {
1.294 + return KErrArgument;
1.295 + }
1.296 + if (aResult)
1.297 + {
1.298 + return KErrInUse;
1.299 + }
1.300 + if (!aDataAddress && !SgIsMutableImage(aInfo))
1.301 + {
1.302 + return KErrNoInitializationData;
1.303 + }
1.304 + TInt err = CanCreateImage(aInfo);
1.305 + if (err != KErrNone)
1.306 + {
1.307 + return err;
1.308 + }
1.309 +#if !defined(SYMBIAN_GRAPHICS_USE_GPU) && !defined(__WINS__)
1.310 + if (!aInfo.iShareable)
1.311 + {
1.312 + iMutex.Wait();
1.313 + union
1.314 + {
1.315 + TSgDrawableId id;
1.316 + TSgImageId_SwLocal id_SwLocal;
1.317 + };
1.318 + do
1.319 + {
1.320 + id_SwLocal.iProcessId = RProcess().Id();
1.321 + id_SwLocal.iRandom[0] = Math::Random();
1.322 + id_SwLocal.iRandom[1] = Math::Random();
1.323 + id_SwLocal.iMinusOne = KErrNotFound;
1.324 + id_SwLocal.iFlags = 0;
1.325 + }
1.326 + while (iImages.FindInOrder(id, XSgImageImplBase::Compare) != KErrNotFound);
1.327 + XSgImageImpl_SwLocal* impl;
1.328 + err = XSgImageImpl_SwLocal::New(impl, *this, id, aInfo, aDataAddress, aDataStride);
1.329 + if (err != KErrNone)
1.330 + {
1.331 + iMutex.Signal();
1.332 + return err;
1.333 + }
1.334 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.335 + err = iImages.InsertInOrder(impl, XSgImageImplBase::Compare);
1.336 + User::SwitchHeap(prevHeap);
1.337 + if (err != KErrNone)
1.338 + {
1.339 + impl->Delete();
1.340 + iMutex.Signal();
1.341 + return err;
1.342 + }
1.343 + impl->IncRefCount();
1.344 + aResult = impl;
1.345 + iMutex.Signal();
1.346 + return KErrNone;
1.347 + }
1.348 +#endif
1.349 + iMutex.Wait();
1.350 + XSgImageImpl_SurfaceManager* impl;
1.351 + err = XSgImageImpl_SurfaceManager::New(impl, *this, aInfo, SgIsCachedImage(aInfo), aDataAddress, aDataStride);
1.352 + if (err != KErrNone)
1.353 + {
1.354 + iMutex.Signal();
1.355 + return err;
1.356 + }
1.357 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.358 + err = iImages.InsertInOrder(impl, XSgImageImplBase::Compare);
1.359 + User::SwitchHeap(prevHeap);
1.360 + if (err != KErrNone)
1.361 + {
1.362 + impl->Delete();
1.363 + iMutex.Signal();
1.364 + return err;
1.365 + }
1.366 + impl->IncRefCount();
1.367 + aResult = impl;
1.368 + iMutex.Signal();
1.369 + return KErrNone;
1.370 + }
1.371 +
1.372 +
1.373 +TInt XSgDriverImpl::CreateImage(const TSgImageInfo& aInfo, MSgImageAdapter* aImage, MSgDrawableAdapter*& aResult)
1.374 + {
1.375 + if (!aImage)
1.376 + {
1.377 + return KErrArgument;
1.378 + }
1.379 + __ASSERT_DEBUG(CheckImage(*aImage), Panic(ESgPanicBadImageHandle));
1.380 + XSgImageImplBase& impl = static_cast<XSgImageImplBase&>(*aImage);
1.381 + if (aInfo.iSizeInPixels != impl.MetaData().iSizeInPixels
1.382 + || aInfo.iPixelFormat != impl.MetaData().iPixelFormat)
1.383 + {
1.384 + return KErrNotSupported;
1.385 + }
1.386 + TInt err = impl.BeginDataAccess(ESgCpuAccessReadOnly);
1.387 + if (err != KErrNone)
1.388 + {
1.389 + return err;
1.390 + }
1.391 + err = CreateImage(aInfo, impl.DataAddress(), impl.DataStride(), aResult);
1.392 + impl.EndDataAccess();
1.393 + return err;
1.394 + }
1.395 +
1.396 +
1.397 +TInt XSgDriverImpl::CreateImageCollection(const TSgImageInfo& aInfo, TInt aImageCount, MSgImageCollectionAdapter*& aResult)
1.398 + {
1.399 + if (!SgIsValidImageInfo(aInfo) || aImageCount <= 0)
1.400 + {
1.401 + return KErrArgument;
1.402 + }
1.403 + if (aResult)
1.404 + {
1.405 + return KErrInUse;
1.406 + }
1.407 + if (!SgIsMutableImage(aInfo))
1.408 + {
1.409 + return KErrNotSupported;
1.410 + }
1.411 + TInt err = CanCreateImage(aInfo);
1.412 + if (err != KErrNone)
1.413 + {
1.414 + return err;
1.415 + }
1.416 + iMutex.Wait();
1.417 + XSgImageCollectionImpl* impl;
1.418 + const TInt stride = SgAlignedDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
1.419 + const TInt offsetToFirst = SgOffsetToFirstBuffer(sizeof(TSgImageMetaData));
1.420 + const TInt offsetBetween = SgOffsetBetweenBuffers(stride, aInfo.iSizeInPixels.iHeight);
1.421 +
1.422 + err = XSgImageCollectionImpl::New(impl, *this, aInfo, aImageCount, SgIsCachedImage(aInfo), stride, offsetToFirst, offsetBetween);
1.423 + if (err != KErrNone)
1.424 + {
1.425 + iMutex.Signal();
1.426 + return err;
1.427 + }
1.428 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.429 + err = iImageCollections.InsertInAddressOrder(impl);
1.430 + User::SwitchHeap(prevHeap);
1.431 + if (err != KErrNone)
1.432 + {
1.433 + impl->Delete();
1.434 + iMutex.Signal();
1.435 + return err;
1.436 + }
1.437 + impl->IncRefCount();
1.438 + aResult = impl;
1.439 + iMutex.Signal();
1.440 + return KErrNone;
1.441 + }
1.442 +
1.443 +TInt XSgDriverImpl::GetBufferOffset(const TSurfaceId& aSurfaceID, TInt aBuffer, TInt &aOffset)
1.444 + {
1.445 + return iSurfaceManager.GetBufferOffset(aSurfaceID,aBuffer,aOffset);
1.446 + }
1.447 +
1.448 +TInt XSgDriverImpl::GetSurfaceManagerAttrib(RSurfaceManager::TSurfaceManagerAttrib aAttrib, TInt& aValue)
1.449 + {
1.450 + return iSurfaceManager.GetSurfaceManagerAttrib(aAttrib,aValue);
1.451 + }
1.452 +
1.453 +TInt XSgDriverImpl::CreateImageCollections(const TSgImageInfo aInfos[], TInt aImageCount,
1.454 + MSgImageCollectionAdapter* aCollections[], TInt aCollectionCount)
1.455 + {
1.456 + if (aImageCount <= 0 || aCollectionCount <= 0)
1.457 + {
1.458 + return KErrArgument;
1.459 + }
1.460 + TBool isCached = EFalse;
1.461 + TInt offsetToFirstBuffer = SgOffsetToFirstBuffer(aCollectionCount * sizeof(TSgImageMetaData));
1.462 + TInt maxOffsetBetweenBuffers = 0;
1.463 + for (TInt i = 0; i < aCollectionCount; ++i)
1.464 + {
1.465 + const TSgImageInfo& info = aInfos[i];
1.466 + if (!SgIsValidImageInfo(info))
1.467 + {
1.468 + return KErrArgument;
1.469 + }
1.470 + if (aCollections[i])
1.471 + {
1.472 + return KErrInUse;
1.473 + }
1.474 + if (!SgIsMutableImage(info))
1.475 + {
1.476 + return KErrNotSupported;
1.477 + }
1.478 + TInt err = CanCreateImage(info);
1.479 + if (err != KErrNone)
1.480 + {
1.481 + return err;
1.482 + }
1.483 + if (SgIsCachedImage(info))
1.484 + {
1.485 + isCached = ETrue;
1.486 + }
1.487 + TInt stride = SgAlignedDataStride(info.iSizeInPixels.iWidth, info.iPixelFormat);
1.488 + TInt offsetBetweenBuffers = SgOffsetBetweenBuffers(stride, info.iSizeInPixels.iHeight);
1.489 + if (offsetBetweenBuffers > maxOffsetBetweenBuffers)
1.490 + {
1.491 + maxOffsetBetweenBuffers = offsetBetweenBuffers;
1.492 + }
1.493 + }
1.494 + iMutex.Wait();
1.495 + XSgImageCollectionImpl* firstImpl = NULL;
1.496 + for (TInt i = 0; i < aCollectionCount; ++i)
1.497 + {
1.498 + const TInt stride = SgAlignedDataStride(aInfos[i].iSizeInPixels.iWidth, aInfos[i].iPixelFormat);
1.499 + XSgImageCollectionImpl* impl;
1.500 + TInt err = XSgImageCollectionImpl::New(impl, *this, aInfos[i], aImageCount, isCached,
1.501 + stride, offsetToFirstBuffer, maxOffsetBetweenBuffers, i, firstImpl);
1.502 + if (err == KErrNone)
1.503 + {
1.504 + if (i == 0)
1.505 + {
1.506 + firstImpl = impl;
1.507 + RSurfaceManager::TInfoBuf info;
1.508 + TSurfaceId surface=impl->SurfaceId();
1.509 + err = SurfaceInfo(surface, info);
1.510 + if (err == KErrNone)
1.511 + {
1.512 + // get the actual value used for offset to first buffer
1.513 + err = iSurfaceManager.GetBufferOffset(surface, 0, offsetToFirstBuffer);
1.514 + // get the actual value used for offset between buffers
1.515 + if (aImageCount>1)
1.516 + {
1.517 + TInt offsetToSecondBuffer;
1.518 + err = iSurfaceManager.GetBufferOffset(surface, 1, offsetToSecondBuffer);
1.519 + maxOffsetBetweenBuffers = offsetToSecondBuffer - offsetToFirstBuffer;
1.520 + }
1.521 + else
1.522 + {
1.523 + maxOffsetBetweenBuffers = 0;
1.524 + }
1.525 + }
1.526 + if (err != KErrNone)
1.527 + {
1.528 + impl->Delete();
1.529 + iMutex.Signal();
1.530 + return err;
1.531 + }
1.532 + }
1.533 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.534 + err = iImageCollections.InsertInAddressOrder(impl);
1.535 + User::SwitchHeap(prevHeap);
1.536 + if (err == KErrNone)
1.537 + {
1.538 + impl->IncRefCount();
1.539 + aCollections[i] = impl;
1.540 + }
1.541 + else
1.542 + {
1.543 + impl->Delete();
1.544 + }
1.545 + }
1.546 + if (err != KErrNone)
1.547 + {
1.548 + while (--i >= 0)
1.549 + {
1.550 + aCollections[i]->Close();
1.551 + aCollections[i] = NULL;
1.552 + }
1.553 + iMutex.Signal();
1.554 + return err;
1.555 + }
1.556 + }
1.557 + iMutex.Signal();
1.558 + return KErrNone;
1.559 + }
1.560 +
1.561 +
1.562 +TInt XSgDriverImpl::OpenDrawable(const TSgDrawableId& aId, TUint32 aMode, TUid aHandleType, MSgDrawableAdapter*& aResult)
1.563 + {
1.564 + if (aHandleType == KSgImageTypeUid || aHandleType == KSgDrawableTypeUid)
1.565 + {
1.566 + return OpenImage(aId, aMode, aResult);
1.567 + }
1.568 + return KErrNotSupported;
1.569 + }
1.570 +
1.571 +
1.572 +TInt XSgDriverImpl::OpenImage(const TSgDrawableId& aId, TUint32 aMode, MSgDrawableAdapter*& aResult)
1.573 + {
1.574 + if (aResult)
1.575 + {
1.576 + return KErrInUse;
1.577 + }
1.578 + iMutex.Wait();
1.579 + TSgDrawableId id = aId;
1.580 + id.iId[KSgImageIdFlagsIndex] |= aMode;
1.581 + TInt i = iImages.FindInOrder(id, XSgImageImplBase::CompareIgnoringFlags);
1.582 + if (i != KErrNotFound)
1.583 + {
1.584 + XSgImageImplBase* impl;
1.585 + TInt j = iImages.FindInOrder(id, XSgImageImplBase::Compare);
1.586 + if (j != KErrNotFound)
1.587 + {
1.588 + impl = iImages[j];
1.589 + }
1.590 + else
1.591 + {
1.592 + impl = iImages[i];
1.593 +#ifndef SYMBIAN_GRAPHICS_USE_GPU
1.594 + if (TSgImageId_SwLocal::IsMatch(id))
1.595 + {
1.596 + XSgImageImpl_SwLocal* impl2;
1.597 + TInt err = XSgImageImpl_SwLocal::New(impl2, *static_cast<XSgImageImpl_SwLocal*>(impl), id.iId[KSgImageIdFlagsIndex]);
1.598 + if (err != KErrNone)
1.599 + {
1.600 + iMutex.Signal();
1.601 + return err;
1.602 + }
1.603 + impl = impl2;
1.604 + }
1.605 + else
1.606 +#endif
1.607 + if (TSgImageId_SurfaceManager::IsMatch(id))
1.608 + {
1.609 + XSgImageImpl_SurfaceManager* impl2;
1.610 + TInt err = XSgImageImpl_SurfaceManager::New(impl2, *static_cast<XSgImageImpl_SurfaceManager*>(impl), id.iId[KSgImageIdFlagsIndex]);
1.611 + if (err != KErrNone)
1.612 + {
1.613 + iMutex.Signal();
1.614 + return err;
1.615 + }
1.616 + impl = impl2;
1.617 + }
1.618 + else
1.619 + {
1.620 + iMutex.Signal();
1.621 + return KErrNotFound;
1.622 + }
1.623 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.624 + TInt err = iImages.InsertInOrder(impl, XSgImageImplBase::Compare);
1.625 + User::SwitchHeap(prevHeap);
1.626 + if (err != KErrNone)
1.627 + {
1.628 + impl->Delete();
1.629 + iMutex.Signal();
1.630 + return err;
1.631 + }
1.632 + }
1.633 + impl->IncRefCount();
1.634 + aResult = impl;
1.635 + iMutex.Signal();
1.636 + return KErrNone;
1.637 + }
1.638 + TInt err = KErrNotFound;
1.639 + if (TSgImageId_SurfaceManager::IsMatch(id))
1.640 + {
1.641 + XSgImageImpl_SurfaceManager* impl;
1.642 + err = XSgImageImpl_SurfaceManager::New(impl, *this, id);
1.643 + if (err != KErrNone)
1.644 + {
1.645 + iMutex.Signal();
1.646 + return err;
1.647 + }
1.648 + if (!impl->MetaData().iShareable && impl->MetaData().iCreatorProcess != RProcess().Id())
1.649 + {
1.650 + impl->Delete();
1.651 + iMutex.Signal();
1.652 + return KErrPermissionDenied;
1.653 + }
1.654 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.655 + err = iImages.InsertInOrder(impl, XSgImageImplBase::Compare);
1.656 + User::SwitchHeap(prevHeap);
1.657 + if (err != KErrNone)
1.658 + {
1.659 + impl->Delete();
1.660 + iMutex.Signal();
1.661 + return err;
1.662 + }
1.663 + impl->IncRefCount();
1.664 + aResult = impl;
1.665 + }
1.666 + iMutex.Signal();
1.667 + return err;
1.668 + }
1.669 +
1.670 +
1.671 +void XSgDriverImpl::DeleteImage(XSgImageImplBase* aImage)
1.672 + {
1.673 + __ASSERT_DEBUG(iMutex.IsHeld(), Panic(ESgPanicMutexNotHeld));
1.674 + TInt i = iImages.FindInOrder(aImage, XSgImageImplBase::Compare);
1.675 + __ASSERT_DEBUG(i != KErrNotFound, Panic(ESgPanicBadImageHandle));
1.676 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.677 + iImages.Remove(i);
1.678 + iImages.GranularCompress();
1.679 + User::SwitchHeap(prevHeap);
1.680 + aImage->Delete();
1.681 + }
1.682 +
1.683 +
1.684 +void XSgDriverImpl::DeleteImageCollection(XSgImageCollectionImpl* aImageCollection)
1.685 + {
1.686 + __ASSERT_DEBUG(iMutex.IsHeld(), Panic(ESgPanicMutexNotHeld));
1.687 + TInt i = iImageCollections.FindInAddressOrder(aImageCollection);
1.688 + __ASSERT_DEBUG(i != KErrNotFound, Panic(ESgPanicBadImageCollectionHandle));
1.689 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.690 + iImageCollections.Remove(i);
1.691 + iImageCollections.GranularCompress();
1.692 + User::SwitchHeap(prevHeap);
1.693 + aImageCollection->Delete();
1.694 + }
1.695 +
1.696 +
1.697 +TBool XSgDriverImpl::CheckDrawable(const MSgResourceAdapter& aDrawable) const
1.698 + {
1.699 + iMutex.Wait();
1.700 + TInt i = iImages.Find(&static_cast<const XSgImageImplBase&>(aDrawable));
1.701 + iMutex.Signal();
1.702 + return i != KErrNotFound;
1.703 + }
1.704 +
1.705 +
1.706 +TBool XSgDriverImpl::CheckImage(const MSgResourceAdapter& aImage) const
1.707 + {
1.708 + iMutex.Wait();
1.709 + TInt i = iImages.Find(&static_cast<const XSgImageImplBase&>(aImage));
1.710 + iMutex.Signal();
1.711 + return i != KErrNotFound;
1.712 + }
1.713 +
1.714 +
1.715 +TBool XSgDriverImpl::CheckImageCollection(const MSgResourceAdapter& aImageCollection) const
1.716 + {
1.717 + iMutex.Wait();
1.718 + TInt i = iImageCollections.Find(&static_cast<const XSgImageCollectionImpl&>(aImageCollection));
1.719 + iMutex.Signal();
1.720 + return i != KErrNotFound;
1.721 + }
1.722 +
1.723 +
1.724 +TInt XSgDriverImpl::ResourceCount() const
1.725 + {
1.726 + iMutex.Wait();
1.727 + TInt count = 0;
1.728 + for (TInt i = 0; i < iImages.Count(); ++i)
1.729 + {
1.730 + count += iImages[i]->RefCount();
1.731 + }
1.732 + for (TInt i = 0; i < iImageCollections.Count(); ++i)
1.733 + {
1.734 + count += iImageCollections[i]->RefCount();
1.735 + }
1.736 + iMutex.Signal();
1.737 + return count;
1.738 + }
1.739 +
1.740 +
1.741 +#ifdef _DEBUG
1.742 +
1.743 +void XSgDriverImpl::AllocMarkStart()
1.744 + {
1.745 + iMutex.Wait();
1.746 + iHeap->__DbgMarkStart();
1.747 + iMutex.Signal();
1.748 + }
1.749 +
1.750 +
1.751 +void XSgDriverImpl::AllocMarkEnd(TInt aCount)
1.752 + {
1.753 + iMutex.Wait();
1.754 + TUint32 badCell = iHeap->__DbgMarkEnd(aCount);
1.755 + iMutex.Signal();
1.756 + if (badCell != 0)
1.757 + {
1.758 + _LIT(KPanicCategoryFormat, "SGALLOC:%08x");
1.759 + TBuf<0x10> category;
1.760 + category.Format(KPanicCategoryFormat, badCell);
1.761 + User::Panic(category, 0);
1.762 + }
1.763 + }
1.764 +
1.765 +
1.766 +void XSgDriverImpl::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate)
1.767 + {
1.768 + iMutex.Wait();
1.769 + iHeap->__DbgSetAllocFail(aType, aRate);
1.770 + iMutex.Signal();
1.771 + }
1.772 +
1.773 +#else
1.774 +
1.775 +void XSgDriverImpl::AllocMarkStart()
1.776 + {
1.777 + }
1.778 +
1.779 +
1.780 +void XSgDriverImpl::AllocMarkEnd(TInt /*aCount*/)
1.781 + {
1.782 + }
1.783 +
1.784 +
1.785 +void XSgDriverImpl::SetAllocFail(RAllocator::TAllocFail /*aType*/, TInt /*aRate*/)
1.786 + {
1.787 + }
1.788 +
1.789 +#endif
1.790 +
1.791 +
1.792 +// MSgDriverAdapter::New()
1.793 +
1.794 +EXPORT_C TInt MSgDriverAdapter::New(MSgDriverAdapter*& aPtr)
1.795 + {
1.796 + RHeap* heap = UserHeap::ChunkHeap(NULL, 0, KSgMaxLocalChunkSize);
1.797 + if (!heap)
1.798 + {
1.799 + return KErrNoMemory;
1.800 + }
1.801 + XSgDriverImpl* driverImpl = static_cast<XSgDriverImpl*>(heap->Alloc(sizeof(XSgDriverImpl)));
1.802 + if (!driverImpl)
1.803 + {
1.804 + heap->Close();
1.805 + return KErrNoMemory;
1.806 + }
1.807 + new(driverImpl) XSgDriverImpl(heap);
1.808 + TInt err = driverImpl->Construct();
1.809 + if (err != KErrNone)
1.810 + {
1.811 + driverImpl->Delete();
1.812 + return err;
1.813 + }
1.814 + aPtr = driverImpl;
1.815 + return KErrNone;
1.816 + }