os/graphics/graphicsresourceservices/graphicsresourceimplementation/src/sgdriver.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Graphics Resource - driver implementation
sl@0
    15
//
sl@0
    16
sl@0
    17
#include "sgdriver.h"
sl@0
    18
sl@0
    19
const TInt KSgMaxLocalChunkSize = 0x100000;
sl@0
    20
const TInt KSgLocalChunkAlignment = 0x40;
sl@0
    21
sl@0
    22
EXPORT_C TInt RSgDriver::Open()
sl@0
    23
	{
sl@0
    24
	if (iImpl)
sl@0
    25
		{
sl@0
    26
		return KErrInUse;
sl@0
    27
		}
sl@0
    28
	if (gPls.iError != KErrNone)
sl@0
    29
		{
sl@0
    30
		return gPls.iError;
sl@0
    31
		}
sl@0
    32
	gPls.iMutex.Wait();
sl@0
    33
	if (gPls.iDriver)
sl@0
    34
		{
sl@0
    35
		++gPls.iOpenCount;
sl@0
    36
		iImpl = gPls.iDriver;
sl@0
    37
		gPls.iMutex.Signal();
sl@0
    38
		return KErrNone;
sl@0
    39
		}
sl@0
    40
	RChunk chunk;
sl@0
    41
	TInt err = chunk.CreateLocal(KMinHeapGrowBy, KSgMaxLocalChunkSize, EOwnerProcess);
sl@0
    42
	if (err != KErrNone)
sl@0
    43
		{
sl@0
    44
		gPls.iMutex.Signal();
sl@0
    45
		return err;
sl@0
    46
		}
sl@0
    47
	RHeap* heap = UserHeap::ChunkHeap(chunk, 0, KMinHeapGrowBy, KSgMaxLocalChunkSize, KSgLocalChunkAlignment, ETrue);
sl@0
    48
	__ASSERT_DEBUG(heap, Panic(ESgPanicResourceImplGeneral));
sl@0
    49
	XSgDriver* driver = static_cast<XSgDriver*>(heap->Alloc(sizeof(XSgDriver)));
sl@0
    50
	__ASSERT_DEBUG(driver, Panic(ESgPanicResourceImplGeneral));
sl@0
    51
	new(driver) XSgDriver(heap);
sl@0
    52
	err = driver->Construct();
sl@0
    53
	if (err != KErrNone)
sl@0
    54
		{
sl@0
    55
		driver->Delete();
sl@0
    56
		gPls.iMutex.Signal();
sl@0
    57
		return err;
sl@0
    58
		}
sl@0
    59
	gPls.iOpenCount = 1;
sl@0
    60
	iImpl = gPls.iDriver = driver;
sl@0
    61
	gPls.iMutex.Signal();
sl@0
    62
	return KErrNone;
sl@0
    63
	}
sl@0
    64
sl@0
    65
EXPORT_C void RSgDriver::Close()
sl@0
    66
	{
sl@0
    67
	if (iImpl)
sl@0
    68
		{
sl@0
    69
		__ASSERT_DEBUG(gPls.iError == KErrNone, Panic(ESgPanicResourceImplGeneral));
sl@0
    70
		gPls.iMutex.Wait();
sl@0
    71
		__ASSERT_DEBUG(gPls.iOpenCount > 0, Panic(ESgPanicResourceImplGeneral));
sl@0
    72
		if (--gPls.iOpenCount == 0)
sl@0
    73
			{
sl@0
    74
			gPls.iDriver->Delete();
sl@0
    75
			gPls.iDriver = NULL;
sl@0
    76
			}
sl@0
    77
		iImpl = NULL;
sl@0
    78
		gPls.iMutex.Signal();
sl@0
    79
		}
sl@0
    80
	}
sl@0
    81
sl@0
    82
EXPORT_C TInt RSgDriver::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr) const
sl@0
    83
	{
sl@0
    84
	aInterfacePtr = NULL;
sl@0
    85
	if (!iImpl)
sl@0
    86
		{
sl@0
    87
		return KErrBadHandle;
sl@0
    88
		}
sl@0
    89
	return static_cast<XSgDriver*>(iImpl)->GetInterface(aInterfaceUid, aInterfacePtr);
sl@0
    90
	}
sl@0
    91
sl@0
    92
EXPORT_C TVersion RSgDriver::Version()
sl@0
    93
	{
sl@0
    94
	return TVersion(1, 1, 1);
sl@0
    95
	}
sl@0
    96
sl@0
    97
_LIT(KSgResourceImplPanicCategory, "SGRES-IMPL");
sl@0
    98
sl@0
    99
void Panic(TSgResourceImplPanicReason aReason)
sl@0
   100
	{
sl@0
   101
	User::Panic(KSgResourceImplPanicCategory, aReason);
sl@0
   102
	}
sl@0
   103
sl@0
   104
#ifdef SYMBIAN_GRAPHICS_USE_GPU
sl@0
   105
const TUint32 KSgResourceAttributes = 0;
sl@0
   106
#else
sl@0
   107
const TUint32 KSgResourceAttributes = ESgResourceAttrCpuCached;
sl@0
   108
#endif
sl@0
   109
sl@0
   110
LOCAL_C TInt SgMinDataStride(TInt aWidthInPixels, TInt aPixelFormat)
sl@0
   111
	{
sl@0
   112
	switch (aPixelFormat)
sl@0
   113
		{
sl@0
   114
	case ESgPixelFormatA_8:
sl@0
   115
		return aWidthInPixels;
sl@0
   116
	case ESgPixelFormatRGB_565:
sl@0
   117
		return aWidthInPixels << 1;
sl@0
   118
	case ESgPixelFormatXRGB_8888:
sl@0
   119
	case ESgPixelFormatARGB_8888:
sl@0
   120
	case ESgPixelFormatARGB_8888_PRE:
sl@0
   121
		return aWidthInPixels << 2;
sl@0
   122
	default:
sl@0
   123
#ifdef _DEBUG
sl@0
   124
		Panic(ESgPanicResourceImplGeneral);
sl@0
   125
#endif
sl@0
   126
		return 0;
sl@0
   127
		}
sl@0
   128
	}
sl@0
   129
sl@0
   130
LOCAL_C TInt SgAlignedDataStride(TInt aWidthInPixels, TInt aPixelFormat)
sl@0
   131
	{
sl@0
   132
#if defined(SYMBIAN_GRAPHICS_USE_MBX)
sl@0
   133
	// MBX requires 2^n stride
sl@0
   134
	for (TInt width = 8; width & KMaxTInt; width <<= 1)
sl@0
   135
		{
sl@0
   136
		if (width >= aWidthInPixels)
sl@0
   137
			{
sl@0
   138
			aWidthInPixels = width;
sl@0
   139
			break;
sl@0
   140
			}
sl@0
   141
		}
sl@0
   142
#elif defined(SYMBIAN_GRAPHICS_USE_SGX)
sl@0
   143
	// SGX requires 32-pixel alignment
sl@0
   144
	aWidthInPixels = (aWidthInPixels + 31) & ~31;
sl@0
   145
#endif
sl@0
   146
	return Align4(SgMinDataStride(aWidthInPixels, aPixelFormat));
sl@0
   147
	}
sl@0
   148
sl@0
   149
XSgDriverPls::XSgDriverPls()
sl@0
   150
	{
sl@0
   151
	iError = iMutex.CreateLocal();
sl@0
   152
	iOpenCount = 0;
sl@0
   153
	iDriver = NULL;
sl@0
   154
	}
sl@0
   155
sl@0
   156
XSgDriver::XSgDriver(RHeap* aHeap)
sl@0
   157
	: iHeap(aHeap), iHasOpenVg(EFalse), iHasOpenGles(EFalse), iHasOpenGles2(EFalse)
sl@0
   158
	{
sl@0
   159
	}
sl@0
   160
sl@0
   161
XSgDriver::~XSgDriver()
sl@0
   162
	{
sl@0
   163
	iMutex.Close();
sl@0
   164
	iDevice.Close();
sl@0
   165
	__ASSERT_DEBUG(iImagesByAddress.Count() == 0, Panic(ESgPanicUnclosedResources));
sl@0
   166
	__ASSERT_DEBUG(iImagesById.Count() == 0, Panic(ESgPanicUnclosedResources));
sl@0
   167
	}
sl@0
   168
sl@0
   169
TInt XSgDriver::Construct()
sl@0
   170
	{
sl@0
   171
	TInt err = iMutex.CreateLocal();
sl@0
   172
	if (err != KErrNone)
sl@0
   173
		{
sl@0
   174
		return err;
sl@0
   175
		}
sl@0
   176
	err = User::LoadLogicalDevice(KSgDeviceName);
sl@0
   177
	if (err != KErrNone && err != KErrAlreadyExists)
sl@0
   178
		{
sl@0
   179
		return err;
sl@0
   180
		}
sl@0
   181
	err = iDevice.Connect();
sl@0
   182
	if (err != KErrNone)
sl@0
   183
		{
sl@0
   184
		return err;
sl@0
   185
		}
sl@0
   186
	_LIT(KLibOpenVg, "libOpenVG.dll");
sl@0
   187
	_LIT(KLibOpenGles, "libGLESv1_CM.dll");
sl@0
   188
	_LIT(KLibOpenGles2, "libGLESv2.dll");
sl@0
   189
	RLibrary lib;
sl@0
   190
	if (lib.Load(KLibOpenVg) == KErrNone)
sl@0
   191
		{
sl@0
   192
		lib.Close();
sl@0
   193
		iHasOpenVg = ETrue;
sl@0
   194
		}
sl@0
   195
	if (lib.Load(KLibOpenGles) == KErrNone)
sl@0
   196
		{
sl@0
   197
		lib.Close();
sl@0
   198
		iHasOpenGles = ETrue;
sl@0
   199
		}
sl@0
   200
	if (lib.Load(KLibOpenGles2) == KErrNone)
sl@0
   201
		{
sl@0
   202
		lib.Close();
sl@0
   203
		iHasOpenGles2 = ETrue;
sl@0
   204
		}
sl@0
   205
	return KErrNone;
sl@0
   206
	}
sl@0
   207
sl@0
   208
void XSgDriver::Delete()
sl@0
   209
	{
sl@0
   210
	RHeap* heap = iHeap;
sl@0
   211
	this->~XSgDriver();
sl@0
   212
	heap->Free(this);
sl@0
   213
	__ASSERT_DEBUG(heap->Count() == 0, Panic(ESgPanicUnclosedResources));
sl@0
   214
	heap->Close();
sl@0
   215
	}
sl@0
   216
sl@0
   217
TInt XSgDriver::CreateImage(const TSgImageInfo& aInfo, const TAny* aDataAddress, TInt aDataStride, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
sl@0
   218
	{
sl@0
   219
	TInt err = CheckImageInfo(aInfo);
sl@0
   220
	if (err != KErrNone)
sl@0
   221
		{
sl@0
   222
		return err;
sl@0
   223
		}
sl@0
   224
	TInt minDataStride = SgMinDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
sl@0
   225
	if (aDataAddress && Abs(aDataStride) < minDataStride)
sl@0
   226
		{
sl@0
   227
		return KErrArgument;
sl@0
   228
		}
sl@0
   229
	if (aAttributes)
sl@0
   230
		{
sl@0
   231
		return KErrNotSupported;
sl@0
   232
		}
sl@0
   233
	TUint32 attribs = KSgResourceAttributes | MatchingEglConfigUsage(aInfo.iUsage);
sl@0
   234
	TPckgBuf<TSgImageMetaData> metaDataPckg;
sl@0
   235
	metaDataPckg().iSizeInPixels = aInfo.iSizeInPixels;
sl@0
   236
	metaDataPckg().iPixelFormat = aInfo.iPixelFormat;
sl@0
   237
	TInt dataStride = SgAlignedDataStride(aInfo.iSizeInPixels.iWidth, aInfo.iPixelFormat);
sl@0
   238
	TInt dataSize = dataStride * aInfo.iSizeInPixels.iHeight;
sl@0
   239
	TSgDrawableId id;
sl@0
   240
	err = iDevice.CreateResource(attribs, metaDataPckg, dataSize, id.iId);
sl@0
   241
	if (err != KErrNone)
sl@0
   242
		{
sl@0
   243
		return err;
sl@0
   244
		}
sl@0
   245
	iMutex.Wait();
sl@0
   246
	XSgImage* imageImpl = static_cast<XSgImage*>(iHeap->Alloc(sizeof(XSgImage)));
sl@0
   247
	if (!imageImpl)
sl@0
   248
		{
sl@0
   249
		(void)iDevice.CloseResource(id.iId);
sl@0
   250
		iMutex.Signal();
sl@0
   251
		return KErrNoMemory;
sl@0
   252
		}
sl@0
   253
	new(imageImpl) XSgImage(id, attribs, metaDataPckg(), iDevice.ResourceDataAddress(id.iId), dataStride);
sl@0
   254
	RHeap* prevHeap = User::SwitchHeap(iHeap);
sl@0
   255
	err = iImagesByAddress.InsertInAddressOrder(imageImpl);
sl@0
   256
	if (err == KErrNone)
sl@0
   257
		{
sl@0
   258
		err = iImagesById.InsertInOrder(imageImpl, XSgImage::Compare);
sl@0
   259
		if (err != KErrNone)
sl@0
   260
			{
sl@0
   261
			iImagesByAddress.Remove(iImagesByAddress.FindInAddressOrder(imageImpl));
sl@0
   262
			iImagesByAddress.GranularCompress();
sl@0
   263
			}
sl@0
   264
		}
sl@0
   265
	User::SwitchHeap(prevHeap);
sl@0
   266
	if (err == KErrNone)
sl@0
   267
		{
sl@0
   268
		if (aDataAddress)
sl@0
   269
			{
sl@0
   270
			const TAny* src = aDataStride > 0 ? aDataAddress : PtrAdd(aDataAddress, -aDataStride * (aInfo.iSizeInPixels.iHeight - 1));
sl@0
   271
			TAny* trg = imageImpl->DataAddress();
sl@0
   272
			for (TInt y = 0; y < aInfo.iSizeInPixels.iHeight; ++y)
sl@0
   273
				{
sl@0
   274
				Mem::Copy(trg, src, minDataStride);
sl@0
   275
				src = PtrAdd(src, aDataStride);
sl@0
   276
				trg = PtrAdd(trg, dataStride);
sl@0
   277
				}
sl@0
   278
			}
sl@0
   279
		aResult = imageImpl;
sl@0
   280
		}
sl@0
   281
	else
sl@0
   282
		{
sl@0
   283
		(void)iDevice.CloseResource(id.iId);
sl@0
   284
		iHeap->Free(imageImpl);
sl@0
   285
		}
sl@0
   286
	iMutex.Signal();
sl@0
   287
	return err;
sl@0
   288
	}
sl@0
   289
sl@0
   290
TInt XSgDriver::CreateImage(const TSgImageInfo& aInfo, const XSgImage* aImageImpl, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
sl@0
   291
	{
sl@0
   292
	if (!aImageImpl)
sl@0
   293
		{
sl@0
   294
		return KErrArgument;
sl@0
   295
		}
sl@0
   296
	__ASSERT_ALWAYS(CheckImage(aImageImpl), Panic(ESgPanicBadDrawableHandle));
sl@0
   297
	TSgImageInfo info;
sl@0
   298
	aImageImpl->GetInfo(info);
sl@0
   299
	if (aInfo.iSizeInPixels != info.iSizeInPixels || aInfo.iPixelFormat != info.iPixelFormat)
sl@0
   300
		{
sl@0
   301
		return KErrNotSupported;
sl@0
   302
		}
sl@0
   303
	return CreateImage(aInfo, aImageImpl->DataAddress(), aImageImpl->DataStride(), aAttributes, aResult);
sl@0
   304
	}
sl@0
   305
sl@0
   306
TInt XSgDriver::FindAndOpenImage(TSgDrawableId aId, const TSgAttributeArrayBase* aAttributes, TAny*& aResult)
sl@0
   307
	{
sl@0
   308
	if (aId == KSgNullDrawableId)
sl@0
   309
		{
sl@0
   310
		return KErrArgument;
sl@0
   311
		}
sl@0
   312
	if (aAttributes)
sl@0
   313
		{
sl@0
   314
		return KErrNotSupported;
sl@0
   315
		}
sl@0
   316
	TInt err;
sl@0
   317
	iMutex.Wait();
sl@0
   318
	TInt indexById = iImagesById.FindInOrder(aId, XSgImage::Compare);
sl@0
   319
	if (indexById >= 0)
sl@0
   320
		{
sl@0
   321
		XSgImage* imageImpl = iImagesById[indexById];
sl@0
   322
		err = imageImpl->Open();
sl@0
   323
		if (err == KErrNone)
sl@0
   324
			{
sl@0
   325
			aResult = imageImpl;
sl@0
   326
			}
sl@0
   327
		}
sl@0
   328
	else
sl@0
   329
		{
sl@0
   330
		err = iDevice.OpenResource(aId.iId);
sl@0
   331
		if (err != KErrNone)
sl@0
   332
			{
sl@0
   333
			iMutex.Signal();
sl@0
   334
			return err;
sl@0
   335
			}
sl@0
   336
		TPckgBuf<TSgImageMetaData> metaDataPckg;
sl@0
   337
		err = iDevice.GetResourceMetaData(aId.iId, metaDataPckg);
sl@0
   338
		if (metaDataPckg.Size() != sizeof(TSgImageMetaData))
sl@0
   339
			{
sl@0
   340
			err = KErrGeneral;
sl@0
   341
			}
sl@0
   342
		TUint32 attribs;
sl@0
   343
		if (err == KErrNone)
sl@0
   344
			{
sl@0
   345
			attribs = iDevice.ResourceAttributes(aId.iId);
sl@0
   346
			TSgImageInfo info(metaDataPckg().iSizeInPixels, metaDataPckg().iPixelFormat, attribs & KSgUsageBitMask);
sl@0
   347
			if (CheckImageInfo(info) != KErrNone)
sl@0
   348
				{
sl@0
   349
				err = KErrGeneral;
sl@0
   350
				}
sl@0
   351
			}
sl@0
   352
		TInt dataStride;
sl@0
   353
		if (err == KErrNone)
sl@0
   354
			{
sl@0
   355
			dataStride = SgAlignedDataStride(metaDataPckg().iSizeInPixels.iWidth, metaDataPckg().iPixelFormat);
sl@0
   356
			if (iDevice.ResourceDataSize(aId.iId) != dataStride * metaDataPckg().iSizeInPixels.iHeight)
sl@0
   357
				{
sl@0
   358
				err = KErrGeneral;
sl@0
   359
				}
sl@0
   360
			}
sl@0
   361
		if (err != KErrNone)
sl@0
   362
			{
sl@0
   363
			(void)iDevice.CloseResource(aId.iId);
sl@0
   364
			iMutex.Signal();
sl@0
   365
			return err;
sl@0
   366
			}
sl@0
   367
		XSgImage* imageImpl = static_cast<XSgImage*>(iHeap->Alloc(sizeof(XSgImage)));
sl@0
   368
		if (!imageImpl)
sl@0
   369
			{
sl@0
   370
			(void)iDevice.CloseResource(aId.iId);
sl@0
   371
			iMutex.Signal();
sl@0
   372
			return KErrNoMemory;
sl@0
   373
			}
sl@0
   374
		new(imageImpl) XSgImage(aId, attribs, metaDataPckg(), iDevice.ResourceDataAddress(aId.iId), dataStride);
sl@0
   375
		RHeap* prevHeap = User::SwitchHeap(iHeap);
sl@0
   376
		err = iImagesByAddress.InsertInAddressOrder(imageImpl);
sl@0
   377
		if (err == KErrNone)
sl@0
   378
			{
sl@0
   379
			err = iImagesById.InsertInOrder(imageImpl, XSgImage::Compare);
sl@0
   380
			if (err != KErrNone)
sl@0
   381
				{
sl@0
   382
				iImagesByAddress.Remove(iImagesByAddress.FindInAddressOrder(imageImpl));
sl@0
   383
				iImagesByAddress.GranularCompress();
sl@0
   384
				}
sl@0
   385
			}
sl@0
   386
		User::SwitchHeap(prevHeap);
sl@0
   387
		if (err == KErrNone)
sl@0
   388
			{
sl@0
   389
			aResult = imageImpl;
sl@0
   390
			}
sl@0
   391
		else
sl@0
   392
			{
sl@0
   393
			(void)iDevice.CloseResource(aId.iId);
sl@0
   394
			iHeap->Free(imageImpl);
sl@0
   395
			}
sl@0
   396
		}
sl@0
   397
	iMutex.Signal();
sl@0
   398
	return err;
sl@0
   399
	}
sl@0
   400
sl@0
   401
void XSgDriver::DeleteImage(XSgImage* aImageImpl)
sl@0
   402
	{
sl@0
   403
	iMutex.Wait();
sl@0
   404
	TInt indexByAddress = iImagesByAddress.FindInAddressOrder(aImageImpl);
sl@0
   405
	TInt indexById = iImagesById.FindInOrder(aImageImpl, XSgImage::Compare);
sl@0
   406
	__ASSERT_DEBUG(indexByAddress >= 0 && indexById >= 0, Panic(ESgPanicBadImagePointer));
sl@0
   407
	RHeap* prevHeap = User::SwitchHeap(iHeap);
sl@0
   408
	iImagesByAddress.Remove(indexByAddress);
sl@0
   409
	iImagesById.Remove(indexById);
sl@0
   410
	iImagesByAddress.GranularCompress();
sl@0
   411
	iImagesById.GranularCompress();
sl@0
   412
	User::SwitchHeap(prevHeap);
sl@0
   413
	(void)iDevice.CloseResource(aImageImpl->Id().iId);
sl@0
   414
	aImageImpl->~XSgImage();
sl@0
   415
	iHeap->Free(aImageImpl);
sl@0
   416
	iMutex.Signal();
sl@0
   417
	}
sl@0
   418
sl@0
   419
TUint32 XSgDriver::MatchingEglConfigUsage(TUint32 aUsage) const
sl@0
   420
	{
sl@0
   421
	if (aUsage & KSgUsageAllSurfaceTypes)
sl@0
   422
		{
sl@0
   423
		if (iHasOpenVg)
sl@0
   424
			{
sl@0
   425
			aUsage |= ESgUsageBitOpenVgSurface;
sl@0
   426
			}
sl@0
   427
		if (iHasOpenGles)
sl@0
   428
			{
sl@0
   429
			aUsage |= ESgUsageBitOpenGlesSurface;
sl@0
   430
			}
sl@0
   431
		if (iHasOpenGles2)
sl@0
   432
			{
sl@0
   433
			aUsage |= ESgUsageBitOpenGles2Surface;
sl@0
   434
			}
sl@0
   435
		}
sl@0
   436
	return aUsage;
sl@0
   437
	}
sl@0
   438
sl@0
   439
TInt XSgDriver::CheckImageInfo(const TSgImageInfo& aInfo) const
sl@0
   440
	{
sl@0
   441
	if (aInfo.iSizeInPixels.iWidth <= 0 || aInfo.iSizeInPixels.iHeight <= 0
sl@0
   442
		|| aInfo.iPixelFormat == EUidPixelFormatUnknown || aInfo.iUsage == 0)
sl@0
   443
		{
sl@0
   444
		return KErrArgument;
sl@0
   445
		}
sl@0
   446
	if (aInfo.iSizeInPixels.iWidth > KMaxTInt16 / 2 || aInfo.iSizeInPixels.iHeight > KMaxTInt16 / 2)
sl@0
   447
		{
sl@0
   448
		return KErrTooBig;
sl@0
   449
		}
sl@0
   450
	if (aInfo.iUsage & ~KSgUsageAll)
sl@0
   451
		{
sl@0
   452
		return KErrNotSupported;
sl@0
   453
		}
sl@0
   454
	if ((aInfo.iUsage & (ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface)) && !iHasOpenVg
sl@0
   455
		|| (aInfo.iUsage & (ESgUsageBitOpenGlesTexture2D | ESgUsageBitOpenGlesSurface)) && !iHasOpenGles
sl@0
   456
		|| (aInfo.iUsage & (ESgUsageBitOpenGles2Texture2D | ESgUsageBitOpenGles2Surface)) && !iHasOpenGles2)
sl@0
   457
		{
sl@0
   458
		return KErrNotSupported;
sl@0
   459
		}
sl@0
   460
	switch (aInfo.iPixelFormat)
sl@0
   461
		{
sl@0
   462
	case ESgPixelFormatA_8:
sl@0
   463
		if (aInfo.iUsage & KSgUsageAllSurfaceTypes)
sl@0
   464
			{
sl@0
   465
			return KErrNotSupported;
sl@0
   466
			}
sl@0
   467
		// coverity[fallthrough]
sl@0
   468
	case ESgPixelFormatRGB_565:
sl@0
   469
	case ESgPixelFormatXRGB_8888:
sl@0
   470
	case ESgPixelFormatARGB_8888:
sl@0
   471
	case ESgPixelFormatARGB_8888_PRE:
sl@0
   472
		return KErrNone;
sl@0
   473
	default:
sl@0
   474
		return KErrNotSupported;
sl@0
   475
		}
sl@0
   476
	}
sl@0
   477
sl@0
   478
TBool XSgDriver::CheckImage(const TAny* aImageImpl) const
sl@0
   479
	{
sl@0
   480
	iMutex.Wait();
sl@0
   481
	TInt indexByAddress = iImagesByAddress.FindInAddressOrder(static_cast<const XSgImage*>(aImageImpl));
sl@0
   482
	iMutex.Signal();
sl@0
   483
	return indexByAddress >= 0;
sl@0
   484
	}
sl@0
   485
sl@0
   486
TInt XSgDriver::GetInterface(TUid aInterfaceUid, TAny*& aInterfacePtr)
sl@0
   487
	{
sl@0
   488
	if (aInterfaceUid == KNullUid)
sl@0
   489
		{
sl@0
   490
		return KErrArgument;
sl@0
   491
		}
sl@0
   492
	if (aInterfaceUid.iUid == MSgDriver_Profiling::EInterfaceUid)
sl@0
   493
		{
sl@0
   494
		aInterfacePtr = static_cast<MSgDriver_Profiling*>(this);
sl@0
   495
		return KErrNone;
sl@0
   496
		}
sl@0
   497
#ifdef _DEBUG
sl@0
   498
	if (aInterfaceUid.iUid == MSgDriver_Test::EInterfaceUid)
sl@0
   499
		{
sl@0
   500
		aInterfacePtr = static_cast<MSgDriver_Test*>(this);
sl@0
   501
		return KErrNone;
sl@0
   502
		}
sl@0
   503
#endif
sl@0
   504
	return KErrExtensionNotSupported;
sl@0
   505
	}
sl@0
   506
sl@0
   507
TInt XSgDriver::LocalResourceCount() const
sl@0
   508
	{
sl@0
   509
	TInt count = 0;
sl@0
   510
	iMutex.Wait();
sl@0
   511
	TInt n = iImagesByAddress.Count();
sl@0
   512
	for (TInt i = 0; i < n; ++i)
sl@0
   513
		{
sl@0
   514
		count += iImagesByAddress[i]->RefCount();
sl@0
   515
		}
sl@0
   516
	iMutex.Signal();
sl@0
   517
	return count;
sl@0
   518
	}
sl@0
   519
sl@0
   520
TInt XSgDriver::GlobalResourceCount() const
sl@0
   521
	{
sl@0
   522
	return iDevice.GlobalResourceCount();
sl@0
   523
	}
sl@0
   524
sl@0
   525
TInt XSgDriver::LocalGraphicsMemoryUsed() const
sl@0
   526
	{
sl@0
   527
	return iDevice.LocalGraphicsMemoryUsed();
sl@0
   528
	}
sl@0
   529
sl@0
   530
TInt XSgDriver::GlobalGraphicsMemoryUsed() const
sl@0
   531
	{
sl@0
   532
	return iDevice.GlobalGraphicsMemoryUsed();
sl@0
   533
	}
sl@0
   534
sl@0
   535
#ifdef _DEBUG
sl@0
   536
sl@0
   537
void XSgDriver::AllocMarkStart()
sl@0
   538
	{
sl@0
   539
	iMutex.Wait();
sl@0
   540
	iHeap->__DbgMarkStart();
sl@0
   541
	iMutex.Signal();
sl@0
   542
	}
sl@0
   543
sl@0
   544
void XSgDriver::AllocMarkEnd(TInt aCount)
sl@0
   545
	{
sl@0
   546
	iMutex.Wait();
sl@0
   547
	TUint32 badCell = iHeap->__DbgMarkEnd(aCount);
sl@0
   548
	iMutex.Signal();
sl@0
   549
	if (badCell != 0)
sl@0
   550
		{
sl@0
   551
		_LIT(KPanicCategoryFormat, "SGALLOC:%08x");
sl@0
   552
		TBuf<0x10> category;
sl@0
   553
		category.Format(KPanicCategoryFormat, badCell);
sl@0
   554
		User::Panic(category, 0);
sl@0
   555
		}
sl@0
   556
	}
sl@0
   557
sl@0
   558
void XSgDriver::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate)
sl@0
   559
	{
sl@0
   560
	iMutex.Wait();
sl@0
   561
	iHeap->__DbgSetAllocFail(aType, aRate);
sl@0
   562
	iMutex.Signal();
sl@0
   563
	}
sl@0
   564
sl@0
   565
#endif // _DEBUG
sl@0
   566
sl@0
   567
#ifndef __WINS__
sl@0
   568
XSgDriverPls gPls;
sl@0
   569
#endif