os/graphics/graphicsresourceservices/graphicsresourceimplementation/src/sgdriver.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsresourceservices/graphicsresourceimplementation/src/sgdriver.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,569 @@
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 +// Graphics Resource - driver implementation
1.18 +//
1.19 +
1.20 +#include "sgdriver.h"
1.21 +
1.22 +const TInt KSgMaxLocalChunkSize = 0x100000;
1.23 +const TInt KSgLocalChunkAlignment = 0x40;
1.24 +
1.25 +EXPORT_C TInt RSgDriver::Open()
1.26 + {
1.27 + if (iImpl)
1.28 + {
1.29 + return KErrInUse;
1.30 + }
1.31 + if (gPls.iError != KErrNone)
1.32 + {
1.33 + return gPls.iError;
1.34 + }
1.35 + gPls.iMutex.Wait();
1.36 + if (gPls.iDriver)
1.37 + {
1.38 + ++gPls.iOpenCount;
1.39 + iImpl = gPls.iDriver;
1.40 + gPls.iMutex.Signal();
1.41 + return KErrNone;
1.42 + }
1.43 + RChunk chunk;
1.44 + TInt err = chunk.CreateLocal(KMinHeapGrowBy, KSgMaxLocalChunkSize, EOwnerProcess);
1.45 + if (err != KErrNone)
1.46 + {
1.47 + gPls.iMutex.Signal();
1.48 + return err;
1.49 + }
1.50 + RHeap* heap = UserHeap::ChunkHeap(chunk, 0, KMinHeapGrowBy, KSgMaxLocalChunkSize, KSgLocalChunkAlignment, ETrue);
1.51 + __ASSERT_DEBUG(heap, Panic(ESgPanicResourceImplGeneral));
1.52 + XSgDriver* driver = static_cast<XSgDriver*>(heap->Alloc(sizeof(XSgDriver)));
1.53 + __ASSERT_DEBUG(driver, Panic(ESgPanicResourceImplGeneral));
1.54 + new(driver) XSgDriver(heap);
1.55 + err = driver->Construct();
1.56 + if (err != KErrNone)
1.57 + {
1.58 + driver->Delete();
1.59 + gPls.iMutex.Signal();
1.60 + return err;
1.61 + }
1.62 + gPls.iOpenCount = 1;
1.63 + iImpl = gPls.iDriver = driver;
1.64 + gPls.iMutex.Signal();
1.65 + return KErrNone;
1.66 + }
1.67 +
1.68 +EXPORT_C void RSgDriver::Close()
1.69 + {
1.70 + if (iImpl)
1.71 + {
1.72 + __ASSERT_DEBUG(gPls.iError == KErrNone, Panic(ESgPanicResourceImplGeneral));
1.73 + gPls.iMutex.Wait();
1.74 + __ASSERT_DEBUG(gPls.iOpenCount > 0, Panic(ESgPanicResourceImplGeneral));
1.75 + if (--gPls.iOpenCount == 0)
1.76 + {
1.77 + gPls.iDriver->Delete();
1.78 + gPls.iDriver = NULL;
1.79 + }
1.80 + iImpl = NULL;
1.81 + gPls.iMutex.Signal();
1.82 + }
1.83 + }
1.84 +
1.85 +EXPORT_C TInt RSgDriver::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr) const
1.86 + {
1.87 + aInterfacePtr = NULL;
1.88 + if (!iImpl)
1.89 + {
1.90 + return KErrBadHandle;
1.91 + }
1.92 + return static_cast<XSgDriver*>(iImpl)->GetInterface(aInterfaceUid, aInterfacePtr);
1.93 + }
1.94 +
1.95 +EXPORT_C TVersion RSgDriver::Version()
1.96 + {
1.97 + return TVersion(1, 1, 1);
1.98 + }
1.99 +
1.100 +_LIT(KSgResourceImplPanicCategory, "SGRES-IMPL");
1.101 +
1.102 +void Panic(TSgResourceImplPanicReason aReason)
1.103 + {
1.104 + User::Panic(KSgResourceImplPanicCategory, aReason);
1.105 + }
1.106 +
1.107 +#ifdef SYMBIAN_GRAPHICS_USE_GPU
1.108 +const TUint32 KSgResourceAttributes = 0;
1.109 +#else
1.110 +const TUint32 KSgResourceAttributes = ESgResourceAttrCpuCached;
1.111 +#endif
1.112 +
1.113 +LOCAL_C TInt SgMinDataStride(TInt aWidthInPixels, TInt aPixelFormat)
1.114 + {
1.115 + switch (aPixelFormat)
1.116 + {
1.117 + case ESgPixelFormatA_8:
1.118 + return aWidthInPixels;
1.119 + case ESgPixelFormatRGB_565:
1.120 + return aWidthInPixels << 1;
1.121 + case ESgPixelFormatXRGB_8888:
1.122 + case ESgPixelFormatARGB_8888:
1.123 + case ESgPixelFormatARGB_8888_PRE:
1.124 + return aWidthInPixels << 2;
1.125 + default:
1.126 +#ifdef _DEBUG
1.127 + Panic(ESgPanicResourceImplGeneral);
1.128 +#endif
1.129 + return 0;
1.130 + }
1.131 + }
1.132 +
1.133 +LOCAL_C TInt SgAlignedDataStride(TInt aWidthInPixels, TInt aPixelFormat)
1.134 + {
1.135 +#if defined(SYMBIAN_GRAPHICS_USE_MBX)
1.136 + // MBX requires 2^n stride
1.137 + for (TInt width = 8; width & KMaxTInt; width <<= 1)
1.138 + {
1.139 + if (width >= aWidthInPixels)
1.140 + {
1.141 + aWidthInPixels = width;
1.142 + break;
1.143 + }
1.144 + }
1.145 +#elif defined(SYMBIAN_GRAPHICS_USE_SGX)
1.146 + // SGX requires 32-pixel alignment
1.147 + aWidthInPixels = (aWidthInPixels + 31) & ~31;
1.148 +#endif
1.149 + return Align4(SgMinDataStride(aWidthInPixels, aPixelFormat));
1.150 + }
1.151 +
1.152 +XSgDriverPls::XSgDriverPls()
1.153 + {
1.154 + iError = iMutex.CreateLocal();
1.155 + iOpenCount = 0;
1.156 + iDriver = NULL;
1.157 + }
1.158 +
1.159 +XSgDriver::XSgDriver(RHeap* aHeap)
1.160 + : iHeap(aHeap), iHasOpenVg(EFalse), iHasOpenGles(EFalse), iHasOpenGles2(EFalse)
1.161 + {
1.162 + }
1.163 +
1.164 +XSgDriver::~XSgDriver()
1.165 + {
1.166 + iMutex.Close();
1.167 + iDevice.Close();
1.168 + __ASSERT_DEBUG(iImagesByAddress.Count() == 0, Panic(ESgPanicUnclosedResources));
1.169 + __ASSERT_DEBUG(iImagesById.Count() == 0, Panic(ESgPanicUnclosedResources));
1.170 + }
1.171 +
1.172 +TInt XSgDriver::Construct()
1.173 + {
1.174 + TInt err = iMutex.CreateLocal();
1.175 + if (err != KErrNone)
1.176 + {
1.177 + return err;
1.178 + }
1.179 + err = User::LoadLogicalDevice(KSgDeviceName);
1.180 + if (err != KErrNone && err != KErrAlreadyExists)
1.181 + {
1.182 + return err;
1.183 + }
1.184 + err = iDevice.Connect();
1.185 + if (err != KErrNone)
1.186 + {
1.187 + return err;
1.188 + }
1.189 + _LIT(KLibOpenVg, "libOpenVG.dll");
1.190 + _LIT(KLibOpenGles, "libGLESv1_CM.dll");
1.191 + _LIT(KLibOpenGles2, "libGLESv2.dll");
1.192 + RLibrary lib;
1.193 + if (lib.Load(KLibOpenVg) == KErrNone)
1.194 + {
1.195 + lib.Close();
1.196 + iHasOpenVg = ETrue;
1.197 + }
1.198 + if (lib.Load(KLibOpenGles) == KErrNone)
1.199 + {
1.200 + lib.Close();
1.201 + iHasOpenGles = ETrue;
1.202 + }
1.203 + if (lib.Load(KLibOpenGles2) == KErrNone)
1.204 + {
1.205 + lib.Close();
1.206 + iHasOpenGles2 = ETrue;
1.207 + }
1.208 + return KErrNone;
1.209 + }
1.210 +
1.211 +void XSgDriver::Delete()
1.212 + {
1.213 + RHeap* heap = iHeap;
1.214 + this->~XSgDriver();
1.215 + heap->Free(this);
1.216 + __ASSERT_DEBUG(heap->Count() == 0, Panic(ESgPanicUnclosedResources));
1.217 + heap->Close();
1.218 + }
1.219 +
1.220 +TInt XSgDriver::CreateImage(const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
1.221 + {
1.222 + TInt err = CheckImageInfo(aInfo);
1.223 + if (err != KErrNone)
1.224 + {
1.225 + return err;
1.226 + }
1.227 + TInt minDataStride = SgMinDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
1.228 + if (aDataAddress && Abs(aDataStride) < minDataStride)
1.229 + {
1.230 + return KErrArgument;
1.231 + }
1.232 + if (aAttributes)
1.233 + {
1.234 + return KErrNotSupported;
1.235 + }
1.236 + TUint32 attribs = KSgResourceAttributes | MatchingEglConfigUsage(aInfo.iUsage);
1.237 + TPckgBuf<TSgImageMetaData> metaDataPckg;
1.238 + metaDataPckg().iSizeInPixels = aInfo.iSizeInPixels;
1.239 + metaDataPckg().iPixelFormat = aInfo.iPixelFormat;
1.240 + TInt dataStride = SgAlignedDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
1.241 + TInt dataSize = dataStride * aInfo.iSizeInPixels.iHeight;
1.242 + TSgDrawableId id;
1.243 + err = iDevice.CreateResource(attribs, metaDataPckg, dataSize, id.iId);
1.244 + if (err != KErrNone)
1.245 + {
1.246 + return err;
1.247 + }
1.248 + iMutex.Wait();
1.249 + XSgImage* imageImpl = static_cast<XSgImage*>(iHeap->Alloc(sizeof(XSgImage)));
1.250 + if (!imageImpl)
1.251 + {
1.252 + (void)iDevice.CloseResource(id.iId);
1.253 + iMutex.Signal();
1.254 + return KErrNoMemory;
1.255 + }
1.256 + new(imageImpl) XSgImage(id, attribs, metaDataPckg(), iDevice.ResourceDataAddress(id.iId), dataStride);
1.257 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.258 + err = iImagesByAddress.InsertInAddressOrder(imageImpl);
1.259 + if (err == KErrNone)
1.260 + {
1.261 + err = iImagesById.InsertInOrder(imageImpl, XSgImage::Compare);
1.262 + if (err != KErrNone)
1.263 + {
1.264 + iImagesByAddress.Remove(iImagesByAddress.FindInAddressOrder(imageImpl));
1.265 + iImagesByAddress.GranularCompress();
1.266 + }
1.267 + }
1.268 + User::SwitchHeap(prevHeap);
1.269 + if (err == KErrNone)
1.270 + {
1.271 + if (aDataAddress)
1.272 + {
1.273 + const TAny* src = aDataStride > 0 ? aDataAddress : PtrAdd(aDataAddress, -aDataStride * (aInfo.iSizeInPixels.iHeight - 1));
1.274 + TAny* trg = imageImpl->DataAddress();
1.275 + for (TInt y = 0; y < aInfo.iSizeInPixels.iHeight; ++y)
1.276 + {
1.277 + Mem::Copy(trg, src, minDataStride);
1.278 + src = PtrAdd(src, aDataStride);
1.279 + trg = PtrAdd(trg, dataStride);
1.280 + }
1.281 + }
1.282 + aResult = imageImpl;
1.283 + }
1.284 + else
1.285 + {
1.286 + (void)iDevice.CloseResource(id.iId);
1.287 + iHeap->Free(imageImpl);
1.288 + }
1.289 + iMutex.Signal();
1.290 + return err;
1.291 + }
1.292 +
1.293 +TInt XSgDriver::CreateImage(const TSgImageInfo& aInfo, const XSgImage* aImageImpl, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
1.294 + {
1.295 + if (!aImageImpl)
1.296 + {
1.297 + return KErrArgument;
1.298 + }
1.299 + __ASSERT_ALWAYS(CheckImage(aImageImpl), Panic(ESgPanicBadDrawableHandle));
1.300 + TSgImageInfo info;
1.301 + aImageImpl->GetInfo(info);
1.302 + if (aInfo.iSizeInPixels != info.iSizeInPixels || aInfo.iPixelFormat != info.iPixelFormat)
1.303 + {
1.304 + return KErrNotSupported;
1.305 + }
1.306 + return CreateImage(aInfo, aImageImpl->DataAddress(), aImageImpl->DataStride(), aAttributes, aResult);
1.307 + }
1.308 +
1.309 +TInt XSgDriver::FindAndOpenImage(TSgDrawableId aId, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
1.310 + {
1.311 + if (aId == KSgNullDrawableId)
1.312 + {
1.313 + return KErrArgument;
1.314 + }
1.315 + if (aAttributes)
1.316 + {
1.317 + return KErrNotSupported;
1.318 + }
1.319 + TInt err;
1.320 + iMutex.Wait();
1.321 + TInt indexById = iImagesById.FindInOrder(aId, XSgImage::Compare);
1.322 + if (indexById >= 0)
1.323 + {
1.324 + XSgImage* imageImpl = iImagesById[indexById];
1.325 + err = imageImpl->Open();
1.326 + if (err == KErrNone)
1.327 + {
1.328 + aResult = imageImpl;
1.329 + }
1.330 + }
1.331 + else
1.332 + {
1.333 + err = iDevice.OpenResource(aId.iId);
1.334 + if (err != KErrNone)
1.335 + {
1.336 + iMutex.Signal();
1.337 + return err;
1.338 + }
1.339 + TPckgBuf<TSgImageMetaData> metaDataPckg;
1.340 + err = iDevice.GetResourceMetaData(aId.iId, metaDataPckg);
1.341 + if (metaDataPckg.Size() != sizeof(TSgImageMetaData))
1.342 + {
1.343 + err = KErrGeneral;
1.344 + }
1.345 + TUint32 attribs;
1.346 + if (err == KErrNone)
1.347 + {
1.348 + attribs = iDevice.ResourceAttributes(aId.iId);
1.349 + TSgImageInfo info(metaDataPckg().iSizeInPixels, metaDataPckg().iPixelFormat, attribs & KSgUsageBitMask);
1.350 + if (CheckImageInfo(info) != KErrNone)
1.351 + {
1.352 + err = KErrGeneral;
1.353 + }
1.354 + }
1.355 + TInt dataStride;
1.356 + if (err == KErrNone)
1.357 + {
1.358 + dataStride = SgAlignedDataStride(metaDataPckg().iSizeInPixels.iWidth, metaDataPckg().iPixelFormat);
1.359 + if (iDevice.ResourceDataSize(aId.iId) != dataStride * metaDataPckg().iSizeInPixels.iHeight)
1.360 + {
1.361 + err = KErrGeneral;
1.362 + }
1.363 + }
1.364 + if (err != KErrNone)
1.365 + {
1.366 + (void)iDevice.CloseResource(aId.iId);
1.367 + iMutex.Signal();
1.368 + return err;
1.369 + }
1.370 + XSgImage* imageImpl = static_cast<XSgImage*>(iHeap->Alloc(sizeof(XSgImage)));
1.371 + if (!imageImpl)
1.372 + {
1.373 + (void)iDevice.CloseResource(aId.iId);
1.374 + iMutex.Signal();
1.375 + return KErrNoMemory;
1.376 + }
1.377 + new(imageImpl) XSgImage(aId, attribs, metaDataPckg(), iDevice.ResourceDataAddress(aId.iId), dataStride);
1.378 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.379 + err = iImagesByAddress.InsertInAddressOrder(imageImpl);
1.380 + if (err == KErrNone)
1.381 + {
1.382 + err = iImagesById.InsertInOrder(imageImpl, XSgImage::Compare);
1.383 + if (err != KErrNone)
1.384 + {
1.385 + iImagesByAddress.Remove(iImagesByAddress.FindInAddressOrder(imageImpl));
1.386 + iImagesByAddress.GranularCompress();
1.387 + }
1.388 + }
1.389 + User::SwitchHeap(prevHeap);
1.390 + if (err == KErrNone)
1.391 + {
1.392 + aResult = imageImpl;
1.393 + }
1.394 + else
1.395 + {
1.396 + (void)iDevice.CloseResource(aId.iId);
1.397 + iHeap->Free(imageImpl);
1.398 + }
1.399 + }
1.400 + iMutex.Signal();
1.401 + return err;
1.402 + }
1.403 +
1.404 +void XSgDriver::DeleteImage(XSgImage* aImageImpl)
1.405 + {
1.406 + iMutex.Wait();
1.407 + TInt indexByAddress = iImagesByAddress.FindInAddressOrder(aImageImpl);
1.408 + TInt indexById = iImagesById.FindInOrder(aImageImpl, XSgImage::Compare);
1.409 + __ASSERT_DEBUG(indexByAddress >= 0 && indexById >= 0, Panic(ESgPanicBadImagePointer));
1.410 + RHeap* prevHeap = User::SwitchHeap(iHeap);
1.411 + iImagesByAddress.Remove(indexByAddress);
1.412 + iImagesById.Remove(indexById);
1.413 + iImagesByAddress.GranularCompress();
1.414 + iImagesById.GranularCompress();
1.415 + User::SwitchHeap(prevHeap);
1.416 + (void)iDevice.CloseResource(aImageImpl->Id().iId);
1.417 + aImageImpl->~XSgImage();
1.418 + iHeap->Free(aImageImpl);
1.419 + iMutex.Signal();
1.420 + }
1.421 +
1.422 +TUint32 XSgDriver::MatchingEglConfigUsage(TUint32 aUsage) const
1.423 + {
1.424 + if (aUsage & KSgUsageAllSurfaceTypes)
1.425 + {
1.426 + if (iHasOpenVg)
1.427 + {
1.428 + aUsage |= ESgUsageBitOpenVgSurface;
1.429 + }
1.430 + if (iHasOpenGles)
1.431 + {
1.432 + aUsage |= ESgUsageBitOpenGlesSurface;
1.433 + }
1.434 + if (iHasOpenGles2)
1.435 + {
1.436 + aUsage |= ESgUsageBitOpenGles2Surface;
1.437 + }
1.438 + }
1.439 + return aUsage;
1.440 + }
1.441 +
1.442 +TInt XSgDriver::CheckImageInfo(const TSgImageInfo& aInfo) const
1.443 + {
1.444 + if (aInfo.iSizeInPixels.iWidth <= 0 || aInfo.iSizeInPixels.iHeight <= 0
1.445 + || aInfo.iPixelFormat == EUidPixelFormatUnknown || aInfo.iUsage == 0)
1.446 + {
1.447 + return KErrArgument;
1.448 + }
1.449 + if (aInfo.iSizeInPixels.iWidth > KMaxTInt16 / 2 || aInfo.iSizeInPixels.iHeight > KMaxTInt16 / 2)
1.450 + {
1.451 + return KErrTooBig;
1.452 + }
1.453 + if (aInfo.iUsage & ~KSgUsageAll)
1.454 + {
1.455 + return KErrNotSupported;
1.456 + }
1.457 + if ((aInfo.iUsage & (ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface)) && !iHasOpenVg
1.458 + || (aInfo.iUsage & (ESgUsageBitOpenGlesTexture2D | ESgUsageBitOpenGlesSurface)) && !iHasOpenGles
1.459 + || (aInfo.iUsage & (ESgUsageBitOpenGles2Texture2D | ESgUsageBitOpenGles2Surface)) && !iHasOpenGles2)
1.460 + {
1.461 + return KErrNotSupported;
1.462 + }
1.463 + switch (aInfo.iPixelFormat)
1.464 + {
1.465 + case ESgPixelFormatA_8:
1.466 + if (aInfo.iUsage & KSgUsageAllSurfaceTypes)
1.467 + {
1.468 + return KErrNotSupported;
1.469 + }
1.470 + // coverity[fallthrough]
1.471 + case ESgPixelFormatRGB_565:
1.472 + case ESgPixelFormatXRGB_8888:
1.473 + case ESgPixelFormatARGB_8888:
1.474 + case ESgPixelFormatARGB_8888_PRE:
1.475 + return KErrNone;
1.476 + default:
1.477 + return KErrNotSupported;
1.478 + }
1.479 + }
1.480 +
1.481 +TBool XSgDriver::CheckImage(const TAny* aImageImpl) const
1.482 + {
1.483 + iMutex.Wait();
1.484 + TInt indexByAddress = iImagesByAddress.FindInAddressOrder(static_cast<const XSgImage*>(aImageImpl));
1.485 + iMutex.Signal();
1.486 + return indexByAddress >= 0;
1.487 + }
1.488 +
1.489 +TInt XSgDriver::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
1.490 + {
1.491 + if (aInterfaceUid == KNullUid)
1.492 + {
1.493 + return KErrArgument;
1.494 + }
1.495 + if (aInterfaceUid.iUid == MSgDriver_Profiling::EInterfaceUid)
1.496 + {
1.497 + aInterfacePtr = static_cast<MSgDriver_Profiling*>(this);
1.498 + return KErrNone;
1.499 + }
1.500 +#ifdef _DEBUG
1.501 + if (aInterfaceUid.iUid == MSgDriver_Test::EInterfaceUid)
1.502 + {
1.503 + aInterfacePtr = static_cast<MSgDriver_Test*>(this);
1.504 + return KErrNone;
1.505 + }
1.506 +#endif
1.507 + return KErrExtensionNotSupported;
1.508 + }
1.509 +
1.510 +TInt XSgDriver::LocalResourceCount() const
1.511 + {
1.512 + TInt count = 0;
1.513 + iMutex.Wait();
1.514 + TInt n = iImagesByAddress.Count();
1.515 + for (TInt i = 0; i < n; ++i)
1.516 + {
1.517 + count += iImagesByAddress[i]->RefCount();
1.518 + }
1.519 + iMutex.Signal();
1.520 + return count;
1.521 + }
1.522 +
1.523 +TInt XSgDriver::GlobalResourceCount() const
1.524 + {
1.525 + return iDevice.GlobalResourceCount();
1.526 + }
1.527 +
1.528 +TInt XSgDriver::LocalGraphicsMemoryUsed() const
1.529 + {
1.530 + return iDevice.LocalGraphicsMemoryUsed();
1.531 + }
1.532 +
1.533 +TInt XSgDriver::GlobalGraphicsMemoryUsed() const
1.534 + {
1.535 + return iDevice.GlobalGraphicsMemoryUsed();
1.536 + }
1.537 +
1.538 +#ifdef _DEBUG
1.539 +
1.540 +void XSgDriver::AllocMarkStart()
1.541 + {
1.542 + iMutex.Wait();
1.543 + iHeap->__DbgMarkStart();
1.544 + iMutex.Signal();
1.545 + }
1.546 +
1.547 +void XSgDriver::AllocMarkEnd(TInt aCount)
1.548 + {
1.549 + iMutex.Wait();
1.550 + TUint32 badCell = iHeap->__DbgMarkEnd(aCount);
1.551 + iMutex.Signal();
1.552 + if (badCell != 0)
1.553 + {
1.554 + _LIT(KPanicCategoryFormat, "SGALLOC:%08x");
1.555 + TBuf<0x10> category;
1.556 + category.Format(KPanicCategoryFormat, badCell);
1.557 + User::Panic(category, 0);
1.558 + }
1.559 + }
1.560 +
1.561 +void XSgDriver::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate)
1.562 + {
1.563 + iMutex.Wait();
1.564 + iHeap->__DbgSetAllocFail(aType, aRate);
1.565 + iMutex.Signal();
1.566 + }
1.567 +
1.568 +#endif // _DEBUG
1.569 +
1.570 +#ifndef __WINS__
1.571 +XSgDriverPls gPls;
1.572 +#endif