|
1 // Copyright (c) 2006-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 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @publishedPartner |
|
19 @prototype |
|
20 |
|
21 */ |
|
22 |
|
23 #include "surfacemanager.h" |
|
24 #include <e32base.h> |
|
25 #include "surfacemanagerdriver.h" |
|
26 |
|
27 |
|
28 /** |
|
29 Default constructor |
|
30 */ |
|
31 EXPORT_C RSurfaceManager::RSurfaceManager() |
|
32 { |
|
33 __ASSERT_COMPILE(sizeof(RSurfaceManagerDriver) <= sizeof(iDriverBuf)); |
|
34 new(iDriverBuf) RSurfaceManagerDriver(); |
|
35 } |
|
36 |
|
37 /** |
|
38 Opens a connection to the Surface Manager. |
|
39 |
|
40 The connection needs to be closed by calling Close() when it is no longer required. |
|
41 @return Returns KErrNone if successful, otherwise a system wide error code. |
|
42 */ |
|
43 EXPORT_C TInt RSurfaceManager::Open() |
|
44 { |
|
45 TInt err = User::LoadLogicalDevice( RSurfaceManagerDriver::Name() ); |
|
46 if(! ((KErrNone == err) || (KErrAlreadyExists == err))) |
|
47 { |
|
48 return err; |
|
49 } |
|
50 return Driver().Open(); |
|
51 } |
|
52 |
|
53 /** |
|
54 Closes the connection to the Surface Manager. |
|
55 |
|
56 Cleanup is performed by the Surface Manager when a client process exits or |
|
57 closes its last connection. It is not guaranteed that the resources held by the |
|
58 Surface Manager are going to be released synchronously. |
|
59 */ |
|
60 EXPORT_C void RSurfaceManager::Close() |
|
61 { |
|
62 Driver().Close(); |
|
63 } |
|
64 |
|
65 /** |
|
66 Returns information specific to the Surface Manager implementation. |
|
67 @param aAttrib Attribute to retrieve |
|
68 @param aValue Output parameter set to the value for the specified attribute |
|
69 @return KErrNone if successful, KErrNotReady if the Surface Manager hasn't been |
|
70 opened, KErrArgument if the attribute UID is not recognized, otherwise a system |
|
71 wide error code. |
|
72 */ |
|
73 EXPORT_C TInt RSurfaceManager::GetSurfaceManagerAttrib(TSurfaceManagerAttrib aAttrib, TInt& aValue) |
|
74 { |
|
75 return Driver().GetSurfaceManagerAttrib(aAttrib, aValue); |
|
76 } |
|
77 |
|
78 /** |
|
79 Opens a surface. |
|
80 |
|
81 If the surface is already open in this process, this call increments the |
|
82 reference count for the surface for this process. If the surface hasn't been opened |
|
83 in this process, it opens the surface in this process and sets the reference count |
|
84 to 1 for this process. |
|
85 |
|
86 A surface will be deleted when all its reference counts are 0. |
|
87 @param aSurfaceId The surface id originally returned when the surface was created. |
|
88 @pre The surface id is for an existing surface. |
|
89 @post The surface is open in this process. |
|
90 @return KErrNone if successful otherwise a system wide error code. |
|
91 */ |
|
92 EXPORT_C TInt RSurfaceManager::OpenSurface(const TSurfaceId& aSurfaceId) |
|
93 { |
|
94 return Driver().OpenSurface(aSurfaceId); |
|
95 } |
|
96 |
|
97 /** |
|
98 Creates a surface and returns its global unique identifier. |
|
99 |
|
100 Depending on the implementation, this method will allocate the surface in a new |
|
101 shared chunk or in external memory. Surfaces created in external memory cannot |
|
102 be mapped (see TSurfaceInfoV01::iMappable for more information). If the creation |
|
103 succeeds, the surface will be opened with a reference count of 1 in the calling |
|
104 process. |
|
105 |
|
106 The Surface Manager implementation should validate at least the following: |
|
107 - The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned. |
|
108 - The offset to first buffer is correctly aligned. |
|
109 - The width and height are both greater than zero. |
|
110 - There is at least one buffer. |
|
111 - The calculated chunk size isn't so big that it will exceed a signed int. |
|
112 - The caching attribute is valid |
|
113 - If the offset between the start of one buffer and the next is specified |
|
114 (not zero), it must be correctly aligned and at least as big as the |
|
115 buffer size calculated from the height and stride. |
|
116 - A surface hint key of zero is allowed when creating a surface, it is ignored |
|
117 |
|
118 The Surface Manager implementation will treat iStride, iOffsetToFirstBuffer, and |
|
119 iOffsetBetweenBuffers as minimum values as opposed to required values. The caller |
|
120 of this method must not rely on the passed values as it is not guaranteed that |
|
121 they remain the same after surface creation (SurfaceInfo() and GetBufferOffset() |
|
122 should be used instead). |
|
123 |
|
124 If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout |
|
125 buffer at its own discretion. Although, a buffer's offset must remain constant |
|
126 during the surface's lifetime. |
|
127 |
|
128 If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface() |
|
129 will fail. |
|
130 |
|
131 @param aReqs Input parameter, specifies attributes of the surface required. |
|
132 @param aSurfaceId Output parameter, the surface ID, set if the call succeeds. |
|
133 @pre The Surface Manager has been successfully opened. |
|
134 @post The surface is created and opened in the creating process. |
|
135 @return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect, |
|
136 KErrNoMemory if the surface cannot be created due to out of memory, KErrOverflow if |
|
137 the chunk limit has been exceeded in the moving memory model, otherwise a standard |
|
138 Symbian error code. |
|
139 */ |
|
140 EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId) |
|
141 { |
|
142 return Driver().CreateSurface(aReqs,aSurfaceId); |
|
143 } |
|
144 |
|
145 /** |
|
146 Creates a surface in an existing shared chunk specified by the caller and returns |
|
147 its global unique identifier. |
|
148 |
|
149 If the creation succeeds, the surface will be opened with a reference count of 1 in the calling |
|
150 process. |
|
151 |
|
152 The Surface Manager implementation should validate at least the following: |
|
153 - The alignment is 1, 2, 4, 8, 16, 32, 64 or TPageAlignment::EPageAligned. |
|
154 - The offset to first buffer is correctly aligned. |
|
155 - The width and height are both greater than zero. |
|
156 - There is at least one buffer. |
|
157 - The calculated chunk size isn't so big that it will exceed a signed int. |
|
158 - The caching attribute is valid |
|
159 - If the offset between the start of one buffer and the next is specified |
|
160 (not zero), it must be correctly aligned and at least as big as the |
|
161 buffer size calculated from the height and stride. |
|
162 - A surface hint key of zero is allowed when creating a surface, it is ignored |
|
163 |
|
164 If iOffsetBetweenBuffers is zero, the Surface Manager implementation will layout |
|
165 buffer at its own discretion. Although, a buffer's offset must remain constant |
|
166 during the surface's lifetime. |
|
167 |
|
168 The attributes iContiguous and iCacheAttribute are ignored for existing chunks. |
|
169 |
|
170 Also, note that surface manager will not do any rounding for offset to first |
|
171 buffer and offset between buffers. It is up to the user, to give exact aligned |
|
172 values for this attributes, otherwise surface creation will fail. |
|
173 |
|
174 If iMappable is EFalse the surface won't be mappable, hence calls to MapSurface() |
|
175 will fail. |
|
176 |
|
177 @param aReqs Input parameter, specifies attributes of the surface required. |
|
178 @param aSurfaceId Output parameter, the surface ID, set if the call succeeds. |
|
179 @param aChunkHandle Handle of the existing shared chunk. |
|
180 @pre The Surface Manager has been successfully opened. |
|
181 @pre A valid shared chunk exists. The shared chunk type should be Shared Kernel |
|
182 multiple and should be right the size, i.e. the size should be calculated as |
|
183 Offset to first buffer + (the number of buffers * ((stride * height * |
|
184 pixel depth in bytes) rounded up to the specified alignment) all rounded to a page size |
|
185 @post The Surface Manager has opened the chunk. |
|
186 @post The surface is created and opened in the creating process. |
|
187 @return KErrNone if it succeeds, KErrArgument if the surface attributes are incorrect. |
|
188 KErrNotReady if the handle is of an invalid shared chunk memory |
|
189 */ |
|
190 EXPORT_C TInt RSurfaceManager::CreateSurface(const TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId, const RChunk& aChunkHandle) |
|
191 { |
|
192 return Driver().CreateSurface(aReqs,aSurfaceId,aChunkHandle); |
|
193 } |
|
194 |
|
195 /** |
|
196 Closes the surface. Decrements the reference count for the surface for the calling |
|
197 process. |
|
198 |
|
199 If the surface has other owners, it will not be deleted from memory. If this is |
|
200 the last process to close the surface, the surface will be deleted and the |
|
201 surface ID will become invalid. Resources associated with the surface are not |
|
202 guaranteed to be released synchronously. |
|
203 @param aSurfaceId The surface identifier originally returned when the surface was created. |
|
204 @pre The surface is open. |
|
205 @post The surface is closed. |
|
206 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface, |
|
207 KErrAccessDenied if the surface is not open in the current process, otherwise a system wide |
|
208 error code. |
|
209 */ |
|
210 EXPORT_C TInt RSurfaceManager::CloseSurface(const TSurfaceId& aSurfaceId) |
|
211 { |
|
212 return Driver().CloseSurface(aSurfaceId); |
|
213 } |
|
214 |
|
215 /** |
|
216 Maps the surface into the current client process address space. |
|
217 |
|
218 The actual memory will remain mapped into the calling process for as long as |
|
219 the RChunk handle aChunk is open. |
|
220 |
|
221 Whether or not a surface is mappable is determined at creation time, see |
|
222 TSurfaceCreationAttributes::iMappable. |
|
223 |
|
224 The address of the pixel data in buffer N is chunk.Base() + GetBufferOffset(N). |
|
225 |
|
226 Surfaces created with existing shared chunks will get the same chunk handle. |
|
227 |
|
228 The RChunk handle is owned by the calling thread, so will need to be duplicated |
|
229 if passed to other threads in the process. |
|
230 @param aSurfaceId The surface identifier originally returned when the surface was created. |
|
231 @param aHandle Output parameter, handle to the implementation specific Shared Chunk. |
|
232 @pre The surface is open. |
|
233 @post The surface memory will be mapped into the calling process's address space. |
|
234 The surface is mapped. |
|
235 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a |
|
236 surface, KErrAccessDenied if the surface is not open in the current process, |
|
237 KErrNotSupported if the surface is not mappable, KErrOverflow if the chunk limit has been |
|
238 exceeded in the moving memory model, otherwise a system wide error code. |
|
239 @see RChunk |
|
240 @see RHandleBase::Duplicate |
|
241 @see TSurfaceCreationAttributes::iMappable |
|
242 */ |
|
243 EXPORT_C TInt RSurfaceManager::MapSurface(const TSurfaceId& aSurfaceId, RChunk& aHandle) |
|
244 { |
|
245 return Driver().MapSurface(aSurfaceId,aHandle); |
|
246 } |
|
247 |
|
248 /** |
|
249 Returns information about a particular surface identified by its surface ID. |
|
250 @param aSurfaceId The surface identifier originally returned when the surface |
|
251 was created. |
|
252 @param aInfo TInfoBuf to receive the information about the surface. |
|
253 @pre The surface is open in the calling process. |
|
254 @return KErrNone if successful, KErrArgument if the surface ID does not refer to a surface, |
|
255 KErrAccessDenied if the surface is not open in the current process, otherwise a system wide |
|
256 error code. |
|
257 */ |
|
258 EXPORT_C TInt RSurfaceManager::SurfaceInfo(const TSurfaceId& aSurfaceId, TInfoBuf& aInfo) |
|
259 { |
|
260 return Driver().SurfaceInfo(aSurfaceId,aInfo); |
|
261 } |
|
262 |
|
263 /** |
|
264 This function ensures the memory is updated consistently before and/or after |
|
265 triggering non CPU hardware access. Also ensures the CPU cache and the physical |
|
266 memory are in a consistent state before and after non CPU hardware or DMA access |
|
267 to the physical memory. |
|
268 @param aSurfaceId The surface identifier originally returned when the surface |
|
269 was created. |
|
270 @param aBuffer The buffer number indexed from 0 within the surface whose memory |
|
271 region is to be flushed. |
|
272 @param aOperation Specifies the sync operation as before non CPU hardware reads |
|
273 or before non CPU hardware writes or after non CPU hardware writes between |
|
274 physical memory of the surface and the cache contents. |
|
275 @pre The surface is open in the calling process. |
|
276 @post The surface buffer memory will be synchronized properly with cache contents. |
|
277 @return KErrNone if successful, KErrArgument if the surface ID is invalid or |
|
278 buffer number is invalid, KErrAccessDenied if the surface is not open in this |
|
279 process, otherwise a system wide error code. |
|
280 */ |
|
281 EXPORT_C TInt RSurfaceManager::SynchronizeCache(const TSurfaceId& aSurfaceId, TInt aBuffer, TSyncOperation aOperation) |
|
282 { |
|
283 return Driver().SynchronizeCache(aSurfaceId,aBuffer,aOperation); |
|
284 } |
|
285 |
|
286 /** |
|
287 Get the surface hint value for the given surface ID and hint pair key. |
|
288 @param aSurfaceId The surface identifier originally returned when the surface |
|
289 was created. |
|
290 @param aHint The hint value for the requested hint pair key. |
|
291 @pre The surface is open in the calling process. |
|
292 @pre Hint key should be a key for a hint set for this surface. |
|
293 @post The hint value will be updated in the hint pair. |
|
294 @return KErrNone if successful, KErrArgument if the surface ID is invalid or |
|
295 invalid hint pair key used, KErrAccessDenied if the surface is not open in the |
|
296 current process, otherwise a system wide error code. |
|
297 */ |
|
298 EXPORT_C TInt RSurfaceManager::GetSurfaceHint(const TSurfaceId& aSurfaceId, THintPair& aHint) |
|
299 { |
|
300 return Driver().GetSurfaceHint(aSurfaceId,aHint); |
|
301 } |
|
302 |
|
303 /** |
|
304 Set the surface hint value for the surface ID. |
|
305 @param aSurfaceId The surface identifier originally returned when the surface |
|
306 was created. |
|
307 @param aHint The value of the hint pair to set. |
|
308 @pre The surface is open in the calling process. |
|
309 @pre The hint key should be a key for a hint set for this surface. |
|
310 @pre Only mutable hints can be updated. |
|
311 @post The hint value will be updated in the surface hint pair. |
|
312 @return KErrNone if successful, KErrArgument if the surface ID is invalid or if invalid |
|
313 hint key used, KErrAccessDenied if the hint pair is immutable or the surface is not open |
|
314 in the current process, otherwise a system wide error code. |
|
315 */ |
|
316 EXPORT_C TInt RSurfaceManager::SetSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint) |
|
317 { |
|
318 return Driver().SetSurfaceHint(aSurfaceId,aHint); |
|
319 } |
|
320 |
|
321 /** |
|
322 Adds a new surface hint to the surface. |
|
323 |
|
324 This function will fail if the surface already has its maximum number of hints |
|
325 or if the hint key is a duplicate or invalid. |
|
326 @param aSurfaceId The surface identifier originally returned when the surface |
|
327 was created. |
|
328 @param aHint The value of the hint pair to add. |
|
329 @pre The surface is open in the calling process. |
|
330 @pre At least one free space to add a hint pair. |
|
331 @pre The new hint key should be non zero and unique for this surface. |
|
332 @post New hint pair will be added in the surface. |
|
333 @return Returns KErrNone if successful, KErrArgument if the surface ID is invalid or the |
|
334 hint pair has invalid key UID, KErrAccessDenied if the surface is not open in the current |
|
335 process, KErrAlreadyExists if duplicate hint key used, KErrOverflow if no space to add new |
|
336 pair, otherwise a system wide error code. |
|
337 */ |
|
338 EXPORT_C TInt RSurfaceManager::AddSurfaceHint(const TSurfaceId& aSurfaceId, const THintPair& aHint) |
|
339 { |
|
340 return Driver().AddSurfaceHint(aSurfaceId,aHint); |
|
341 } |
|
342 |
|
343 /** |
|
344 Get the offset of the specified buffer from the base address of the underlying |
|
345 chunk. |
|
346 |
|
347 To obtain the address of the buffer, the offset returned must be added onto the |
|
348 base address of the RChunk returned in a call to MapSurface(). Note that |
|
349 buffer offsets are immutable during the lifetime of the surface. |
|
350 @param aSurfaceId The surface identifier originally returned when the surface |
|
351 was created. |
|
352 @param aBuffer The buffer for which the offset is requested. Indexed from 0. |
|
353 @param aOffset Output parameter set to the offset within the chunk. |
|
354 @pre The surface is open in the calling process. |
|
355 @return KErrNone if successful, KErrArgument if aSurfaceId or aBuffer are invalid, |
|
356 KErrAccessDenied if the surface is not open in the current process, KErrNotSupported if |
|
357 the surface is not mappable, otherwise a system wide error code. |
|
358 */ |
|
359 EXPORT_C TInt RSurfaceManager::GetBufferOffset(const TSurfaceId& aSurfaceId, TInt aBuffer, TInt& aOffset) |
|
360 { |
|
361 return Driver().GetBufferOffset(aSurfaceId, aBuffer, aOffset); |
|
362 } |
|
363 |
|
364 /** |
|
365 Get a reference of the implementation of the surface manager. |
|
366 @return reference of the implementation of the surface manager |
|
367 */ |
|
368 inline RSurfaceManagerDriver& RSurfaceManager::Driver() |
|
369 { |
|
370 return reinterpret_cast<RSurfaceManagerDriver&>(*iDriverBuf); |
|
371 } |
|
372 |