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