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
|