|
1 // Copyright (c) 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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Graphics Resource - logical channel implementation |
|
15 // |
|
16 |
|
17 #include <kernel/kern_priv.h> |
|
18 #include <sgresource/sgextension.h> |
|
19 #include "sgdeviceimpl.h" |
|
20 |
|
21 TInt DSgChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVersion) |
|
22 { |
|
23 TVersion version = SgExtension::Version(); |
|
24 if (aVersion.iMajor != version.iMajor || aVersion.iMinor > version.iMinor) |
|
25 { |
|
26 return KErrNotSupported; |
|
27 } |
|
28 return Kern::MutexCreate(iMutex, KNullDesC, KMutexOrdGeneral7); |
|
29 } |
|
30 |
|
31 DSgChannel::~DSgChannel() |
|
32 { |
|
33 if (iMutex) |
|
34 { |
|
35 iMutex->Close(NULL); |
|
36 } |
|
37 for (TInt i = 0; i < iResources.Count(); ++i) |
|
38 { |
|
39 iResources[i].iResource->Close(); |
|
40 } |
|
41 iResources.Close(); |
|
42 } |
|
43 |
|
44 TInt DSgChannel::Request(TInt aFunction, TAny* a1, TAny* a2) |
|
45 { |
|
46 switch (aFunction) |
|
47 { |
|
48 case RSgDevice::EControlCreateResource: |
|
49 { |
|
50 RSgDevice::TCreateResourceArgs args; |
|
51 kumemget32(&args, a1, sizeof(RSgDevice::TCreateResourceArgs)); |
|
52 TInt metaDataSize, maxMetaDataSize; |
|
53 Kern::KUDesInfo(*args.iMetaData, metaDataSize, maxMetaDataSize); |
|
54 __ASSERT_ALWAYS(metaDataSize <= KSgMaxMetaDataSize, Panic(ESgPanicMetaDataSizeTooBig)); |
|
55 __ASSERT_ALWAYS(args.iDataSize >= 0, Panic(ESgPanicDataSizeNegative)); |
|
56 TBuf8<KSgMaxMetaDataSize> metaData; |
|
57 Kern::KUDesGet(metaData, *args.iMetaData); |
|
58 TUint64 id; |
|
59 TInt err = CreateResource(args.iAttributes, metaData, args.iDataSize, id); |
|
60 kumemput32(a2, &id, sizeof(TUint64)); |
|
61 return err; |
|
62 } |
|
63 case RSgDevice::EControlOpenResource: |
|
64 { |
|
65 TUint64 id; |
|
66 kumemget32(&id, a1, sizeof(TUint64)); |
|
67 return OpenResource(id); |
|
68 } |
|
69 case RSgDevice::EControlCloseResource: |
|
70 { |
|
71 TUint64 id; |
|
72 kumemget32(&id, a1, sizeof(TUint64)); |
|
73 return CloseResource(id); |
|
74 } |
|
75 case RSgDevice::EControlResourceAttributes: |
|
76 { |
|
77 TUint64 id; |
|
78 kumemget32(&id, a1, sizeof(TUint64)); |
|
79 return static_cast<TInt>(ResourceAttributes(id)); |
|
80 } |
|
81 case RSgDevice::EControlGetResourceMetaData: |
|
82 { |
|
83 TUint64 id; |
|
84 kumemget32(&id, a1, sizeof(TUint64)); |
|
85 TBuf8<KSgMaxMetaDataSize> metaData; |
|
86 TInt err = GetResourceMetaData(id, metaData); |
|
87 if (err == KErrNone) |
|
88 { |
|
89 Kern::InfoCopy(*static_cast<TDes8*>(a2), metaData); |
|
90 } |
|
91 return err; |
|
92 } |
|
93 case RSgDevice::EControlResourceDataAddress: |
|
94 { |
|
95 TUint64 id; |
|
96 kumemget32(&id, a1, sizeof(TUint64)); |
|
97 return reinterpret_cast<TInt>(ResourceDataAddress(id)); |
|
98 } |
|
99 case RSgDevice::EControlResourceDataSize: |
|
100 { |
|
101 TUint64 id; |
|
102 kumemget32(&id, a1, sizeof(TUint64)); |
|
103 return ResourceDataSize(id); |
|
104 } |
|
105 case RSgDevice::EControlGlobalResourceCount: |
|
106 return GlobalResourceCount(); |
|
107 case RSgDevice::EControlLocalGraphicsMemoryUsed: |
|
108 return LocalGraphicsMemoryUsed(); |
|
109 case RSgDevice::EControlGlobalGraphicsMemoryUsed: |
|
110 return GlobalGraphicsMemoryUsed(); |
|
111 default: |
|
112 return KErrNotSupported; |
|
113 } |
|
114 } |
|
115 |
|
116 TInt DSgChannel::CreateResource(TUint32 aAttribs, const TDesC8& aMetaData, TInt aDataSize, TUint64& aId) |
|
117 { |
|
118 aId = 0; |
|
119 NKern::ThreadEnterCS(); |
|
120 DSgResource* resource; |
|
121 TInt err = SgExtension::CreateResource(aAttribs, aMetaData, aDataSize, resource); |
|
122 if (err != KErrNone) |
|
123 { |
|
124 NKern::ThreadLeaveCS(); |
|
125 return err; |
|
126 } |
|
127 TInt handle = Kern::MakeHandleAndOpen(NULL, resource->DataChunk(), EOwnerProcess); |
|
128 if (handle < 0) |
|
129 { |
|
130 resource->Close(); |
|
131 NKern::ThreadLeaveCS(); |
|
132 return handle; |
|
133 } |
|
134 Kern::MutexWait(*iMutex); |
|
135 err = iResources.InsertInOrder(TResourceListItem(resource, handle), Compare); |
|
136 Kern::MutexSignal(*iMutex); |
|
137 if (err != KErrNone) |
|
138 { |
|
139 (void)Kern::CloseHandle(NULL, handle); |
|
140 resource->Close(); |
|
141 NKern::ThreadLeaveCS(); |
|
142 return err; |
|
143 } |
|
144 NKern::ThreadLeaveCS(); |
|
145 aId = resource->Id(); |
|
146 return KErrNone; |
|
147 } |
|
148 |
|
149 TInt DSgChannel::OpenResource(TUint64 aId) |
|
150 { |
|
151 if (aId == 0) |
|
152 { |
|
153 return KErrArgument; |
|
154 } |
|
155 NKern::ThreadEnterCS(); |
|
156 Kern::MutexWait(*iMutex); |
|
157 TInt i = iResources.FindInOrder(aId, Compare); |
|
158 if (i >= 0) |
|
159 { |
|
160 Kern::MutexSignal(*iMutex); |
|
161 NKern::ThreadLeaveCS(); |
|
162 return KErrAlreadyExists; |
|
163 } |
|
164 DSgResource* resource; |
|
165 TInt err = SgExtension::FindAndOpenResource(aId, resource); |
|
166 if (err != KErrNone) |
|
167 { |
|
168 Kern::MutexSignal(*iMutex); |
|
169 NKern::ThreadLeaveCS(); |
|
170 return err; |
|
171 } |
|
172 TInt handle = Kern::MakeHandleAndOpen(NULL, resource->DataChunk(), EOwnerProcess); |
|
173 if (handle < 0) |
|
174 { |
|
175 resource->Close(); |
|
176 Kern::MutexSignal(*iMutex); |
|
177 NKern::ThreadLeaveCS(); |
|
178 return handle; |
|
179 } |
|
180 err = iResources.InsertInOrder(TResourceListItem(resource, handle), Compare); |
|
181 if (err != KErrNone) |
|
182 { |
|
183 (void)Kern::CloseHandle(NULL, handle); |
|
184 resource->Close(); |
|
185 Kern::MutexSignal(*iMutex); |
|
186 NKern::ThreadLeaveCS(); |
|
187 return err; |
|
188 } |
|
189 Kern::MutexSignal(*iMutex); |
|
190 NKern::ThreadLeaveCS(); |
|
191 return KErrNone; |
|
192 } |
|
193 |
|
194 TInt DSgChannel::CloseResource(TUint64 aId) |
|
195 { |
|
196 if (aId == 0) |
|
197 { |
|
198 return KErrArgument; |
|
199 } |
|
200 TInt err = KErrNotFound; |
|
201 NKern::ThreadEnterCS(); |
|
202 Kern::MutexWait(*iMutex); |
|
203 TInt i = iResources.FindInOrder(aId, Compare); |
|
204 if (i >= 0) |
|
205 { |
|
206 (void)Kern::CloseHandle(NULL, iResources[i].iChunkHandle); |
|
207 iResources[i].iResource->Close(); |
|
208 iResources.Remove(i); |
|
209 err = KErrNone; |
|
210 } |
|
211 Kern::MutexSignal(*iMutex); |
|
212 NKern::ThreadLeaveCS(); |
|
213 return err; |
|
214 } |
|
215 |
|
216 TUint32 DSgChannel::ResourceAttributes(TUint64 aId) const |
|
217 { |
|
218 if (aId == 0) |
|
219 { |
|
220 return 0; |
|
221 } |
|
222 TUint32 attribs = 0; |
|
223 NKern::ThreadEnterCS(); |
|
224 Kern::MutexWait(*iMutex); |
|
225 TInt i = iResources.FindInOrder(aId, Compare); |
|
226 if (i >= 0) |
|
227 { |
|
228 attribs = iResources[i].iResource->Attributes(); |
|
229 } |
|
230 Kern::MutexSignal(*iMutex); |
|
231 NKern::ThreadLeaveCS(); |
|
232 return attribs; |
|
233 } |
|
234 |
|
235 TInt DSgChannel::GetResourceMetaData(TUint64 aId, TDes8& aMetaData) const |
|
236 { |
|
237 if (aId == 0) |
|
238 { |
|
239 return KErrArgument; |
|
240 } |
|
241 TInt err = KErrNotFound; |
|
242 NKern::ThreadEnterCS(); |
|
243 Kern::MutexWait(*iMutex); |
|
244 TInt i = iResources.FindInOrder(aId, Compare); |
|
245 if (i >= 0) |
|
246 { |
|
247 err = iResources[i].iResource->GetMetaData(aMetaData); |
|
248 } |
|
249 Kern::MutexSignal(*iMutex); |
|
250 NKern::ThreadLeaveCS(); |
|
251 return err; |
|
252 } |
|
253 |
|
254 TAny* DSgChannel::ResourceDataAddress(TUint64 aId) const |
|
255 { |
|
256 if (aId == 0) |
|
257 { |
|
258 return NULL; |
|
259 } |
|
260 TAny* addr = NULL; |
|
261 NKern::ThreadEnterCS(); |
|
262 Kern::MutexWait(*iMutex); |
|
263 TInt i = iResources.FindInOrder(aId, Compare); |
|
264 if (i >= 0) |
|
265 { |
|
266 addr = Kern::ChunkUserBase(iResources[i].iResource->DataChunk(), &Kern::CurrentThread()); |
|
267 } |
|
268 Kern::MutexSignal(*iMutex); |
|
269 NKern::ThreadLeaveCS(); |
|
270 return addr; |
|
271 } |
|
272 |
|
273 TInt DSgChannel::ResourceDataSize(TUint64 aId) const |
|
274 { |
|
275 if (aId == 0) |
|
276 { |
|
277 return KErrArgument; |
|
278 } |
|
279 TInt ret = KErrNotFound; |
|
280 NKern::ThreadEnterCS(); |
|
281 Kern::MutexWait(*iMutex); |
|
282 TInt i = iResources.FindInOrder(aId, Compare); |
|
283 if (i >= 0) |
|
284 { |
|
285 ret = iResources[i].iResource->DataSize(); |
|
286 } |
|
287 Kern::MutexSignal(*iMutex); |
|
288 NKern::ThreadLeaveCS(); |
|
289 return ret; |
|
290 } |
|
291 |
|
292 TInt DSgChannel::GlobalResourceCount() const |
|
293 { |
|
294 NKern::ThreadEnterCS(); |
|
295 TInt ret = SgExtension::GlobalResourceCount(); |
|
296 NKern::ThreadLeaveCS(); |
|
297 return ret; |
|
298 } |
|
299 |
|
300 TInt DSgChannel::LocalGraphicsMemoryUsed() const |
|
301 { |
|
302 TInt ret = 0; |
|
303 NKern::ThreadEnterCS(); |
|
304 Kern::MutexWait(*iMutex); |
|
305 TInt n = iResources.Count(); |
|
306 for (TInt i = 0; i < n; ++i) |
|
307 { |
|
308 ret += iResources[i].iResource->DataChunk()->Size(); |
|
309 } |
|
310 Kern::MutexSignal(*iMutex); |
|
311 NKern::ThreadLeaveCS(); |
|
312 return ret; |
|
313 } |
|
314 |
|
315 TInt DSgChannel::GlobalGraphicsMemoryUsed() const |
|
316 { |
|
317 NKern::ThreadEnterCS(); |
|
318 TInt ret = SgExtension::GlobalGraphicsMemoryUsed(); |
|
319 NKern::ThreadLeaveCS(); |
|
320 return ret; |
|
321 } |
|
322 |
|
323 DSgChannel::TResourceListItem::TResourceListItem(DSgResource* aResource, TInt aChunkHandle) |
|
324 : iResource(aResource), iChunkHandle(aChunkHandle) |
|
325 { |
|
326 } |
|
327 |
|
328 TInt DSgChannel::Compare(const TUint64* aId, const TResourceListItem& aResourceListItem) |
|
329 { |
|
330 return DSgResource::Compare(aId, *aResourceListItem.iResource); |
|
331 } |
|
332 |
|
333 TInt DSgChannel::Compare(const TResourceListItem& aResourceListItem1, const TResourceListItem& aResourceListItem2) |
|
334 { |
|
335 return DSgResource::Compare(*aResourceListItem1.iResource, *aResourceListItem2.iResource); |
|
336 } |