|
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 #ifndef __SURFACEUPDATECLIENT_H__ |
|
17 #define __SURFACEUPDATECLIENT_H__ |
|
18 |
|
19 #include <e32std.h> |
|
20 #ifdef TEST_SURFACE_UPDATE |
|
21 #include "surfaceupdate.h" |
|
22 #include "surfaceupdatetest.h" |
|
23 #endif |
|
24 |
|
25 class TSurfaceId; |
|
26 |
|
27 const TInt KDefaultMessageSlot = 6; |
|
28 |
|
29 typedef TPckgBuf<TUint32> TTimeStamp; |
|
30 |
|
31 /** |
|
32 The RSurfaceUpdateSession class is intended to be used by surface update control flow. |
|
33 The class implements an interface between the Compositor and clients. It allows a client to |
|
34 inform the Compositor when a surface has been modified and to receive notification when |
|
35 its buffer becomes available and/or displayed. |
|
36 */ |
|
37 class RSurfaceUpdateSession : public RSessionBase |
|
38 { |
|
39 public: |
|
40 IMPORT_C RSurfaceUpdateSession(); |
|
41 /** |
|
42 Connect to the server using given number of message slots. |
|
43 |
|
44 @param aMessageSlots The number of message slots available to this session. |
|
45 This parameter is defined in RSessionBase specification; it signifies the maximum number |
|
46 of asynchronous outstanding requests to the server. |
|
47 SubmitUpdate commands could contain up to three asynchronous requests to the server, |
|
48 each corresponds to a different type of notification. |
|
49 |
|
50 @see RSessionBase |
|
51 |
|
52 @pre The surface update server is started up |
|
53 @post Connection to the server has been established. |
|
54 |
|
55 @return KErrNone if successful. |
|
56 @return KErrAlreadyExists if the session has already been established. |
|
57 @return KErrArgument if arguments don’t lie within expected range. |
|
58 @return KErrNotFound if the server is not in operation, otherwise one of the |
|
59 system-wide error codes. |
|
60 */ |
|
61 IMPORT_C TInt Connect(TInt aMessageSlots = KDefaultMessageSlot); |
|
62 |
|
63 /** |
|
64 Close the session to the server. |
|
65 |
|
66 @pre Outstanding notification requests (if any) are cancelled. |
|
67 @post The session is disconnected. |
|
68 */ |
|
69 IMPORT_C void Close(); |
|
70 |
|
71 /** |
|
72 Send update message to the server. All notification requests will also be submitted at |
|
73 this stage. |
|
74 This is referring to when notifications are requested before the update request. |
|
75 <p>The GCE may collapse a few requests into one. |
|
76 If a few requests with different buffer numbers specified for the same surface have |
|
77 been submitted at specific composition cycle, only last such request will have effect. |
|
78 <p>Clients can send a global submit update which will be broadcast by the SUS to all |
|
79 backends presented in the system. For a global update, to all screens, |
|
80 the pre-defined constant KAllScreens needs to be passed as the screen parameter |
|
81 to SubmitUpdate. |
|
82 Note that once a Client has begun issuing SubmitUpdate with either KAllScreens or a |
|
83 specific screen, then only that type of screen can be used thereafter for that |
|
84 Surface Update Session, i.e. the client cannot have a mix of SubmitUpdate with |
|
85 KAllScreens and specific screens. |
|
86 |
|
87 @see RSurfaceUpdateSession::NotifyWhenAvailable |
|
88 @see RSurfaceUpdateSession::NotifyWhenDisplayed |
|
89 @see RSurfaceUpdateSession::NotifyWhenDisplayedXTimes |
|
90 |
|
91 @param aScreen Screen number. Varies from 0 to N-1, where N is a total number of screens |
|
92 in the system. If pre-defined constant KAllScreens is passed, the submission will |
|
93 be broadcast to all screens. |
|
94 @param aSurfaceId Secure 128-bit surface unique identifier, which fully specified the |
|
95 surface. Surface ID must be assigned and registered with the GCE. |
|
96 @param aBuffer Current buffer for composition. Varies from 0 to N-1, where N is the |
|
97 total number of buffers in the surface. |
|
98 @param aRegion The region requiring update, if this is NULL or empty, the whole |
|
99 surface will be used for composition. The function doesn’t take ownership of |
|
100 this parameter. |
|
101 |
|
102 @pre The surface session must be established to the server. |
|
103 @post The GCE will trigger composition to use this region at the next composition cycle. |
|
104 |
|
105 @return KErrNone if a message has been transferred to the server successfully. |
|
106 @return KErrArgument if arguments don’t lie within expected range. |
|
107 @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered |
|
108 with the server. |
|
109 @return KErrNotSupported if global and per-screen update are mixed within the same session. |
|
110 @return KErrNoMemory if the memory is not enough to fulfill the request, |
|
111 otherwise one of the system-wide error codes. |
|
112 Will panic if applied on disconnected session. |
|
113 */ |
|
114 IMPORT_C TInt SubmitUpdate(TInt aScreen, const TSurfaceId& aSurfaceId, TInt aBuffer, |
|
115 const TRegion* aDirtyRegion = NULL); |
|
116 |
|
117 /** |
|
118 The message signals the client that the buffer associated with the notifier is available |
|
119 for further updates. |
|
120 <p>For performance reasons, the GCE uses the buffer sent by the client for composition |
|
121 directly rather than composing with a copy of the buffer. |
|
122 This means that, potentially, a client could be rendering to a buffer which is currently |
|
123 being used for composition, leading to artefacts and possible tearing. |
|
124 Depending on whether the surface is single or multi-buffered, there is some difference |
|
125 in behaviour: |
|
126 <li>In the case of single-buffered surfaces, the GCE will not wait for the next |
|
127 submit update and will complete the request after the composition. </li> |
|
128 <li>In case of multi-buffered surfaces, the GCE can postpone with the issuing the notification |
|
129 to the client even after the composition with the specified surface buffer has already happened, |
|
130 and issues the request when the client changes the active buffer, i.e. submits another |
|
131 request for update with different buffer. This will help the GCE to keep the active buffer in a |
|
132 valid state should another composition required.</li> |
|
133 <p>This notification enables a client to, if desired, be able to perform artefact free |
|
134 rendering using this notification in conjunction with a multi-buffered surface. |
|
135 <p>Note that since the compositor can delay to issue request complete for multi-buffered |
|
136 surface until the change of the active buffer occurs, the completion of a particular |
|
137 notifier may not relate to the buffer to which it is intuitively associated. |
|
138 <p>Only the last call of this function before SubmitUpdate command takes place will have |
|
139 effect, i.e. the following call will override the previous one. |
|
140 This request will only be associated with the following single call of the SubmitUpdate. |
|
141 <p>When a SubmitUpdate has been broadcast to all available screen, i.e. KAllScreens was |
|
142 supplied as a screen number, for multi-buffered surfaces, the notification will be completed |
|
143 when the surface buffer has been released by all displays it is being shown on. |
|
144 For single-buffered surfaces, notification will be completed when all displays have read |
|
145 the buffer once. |
|
146 |
|
147 @param aStatus Reference to the request status object. |
|
148 |
|
149 @see RSurfaceUpdateSession::SubmitUpdate |
|
150 |
|
151 @pre The surface session must be established to the server. |
|
152 @post This request for the consumption notification event will be transferred to the GCE |
|
153 at next SubmitUpdate command. |
|
154 |
|
155 @return KErrNone if consumption has succeeded, the request completed aStatus will |
|
156 contain this code. |
|
157 @return KErrOverflow if the GCE drops the frame for composition. That could happen |
|
158 if the GCE can’t cope with the current composition rate or the new request arrives |
|
159 while the current is still in a progress. |
|
160 The buffer overflow error can only happen with double buffering: |
|
161 <li>If notification is not being used</li> |
|
162 <li>If notification is not being used correctly as the client is not waiting for |
|
163 notification to complete before sending a further buffer.</li> |
|
164 |
|
165 If an application such as video is using three (or more) buffers, this error can occur. |
|
166 For instance, the video may be producing frames at a fixed rate which is faster than |
|
167 the GCE can cope with, and in this case frames will be “lost”, but the notification |
|
168 mechanism will still operate correctly. |
|
169 |
|
170 @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered |
|
171 with the server. |
|
172 @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. |
|
173 @return KErrCancel if notification has been cancelled. It could happen, for instance, |
|
174 if CancelUpdateNotification is called before the request is completed. |
|
175 @return KErrServerBusy if the number of outstanding requests has exceeded specified |
|
176 value (see RSurfaceUpdateSession::Connect for details). |
|
177 @return KErrNotReady if the environment is in invalid state (for instance, the Surface |
|
178 Update Server has not been launched or the session is disconnected). |
|
179 @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. |
|
180 @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. |
|
181 This could happen if there is no layer associated with the surface or no active |
|
182 composition scene. |
|
183 Note, the absence of this error code does not guarantee that the surface |
|
184 is visible. For example, if the surface is behind another surface that has alpha blending |
|
185 enabled the compositor will not do a pixel level comparison to determine surface visibility. |
|
186 @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. |
|
187 @return KErrNotSupported if global and per-screen update are mixed within the same session. |
|
188 @return KErrNoMemory if the memory is not enough to fulfil the request, any other |
|
189 system error codes. |
|
190 Will panic if applied on disconnected session. |
|
191 */ |
|
192 IMPORT_C void NotifyWhenAvailable(TRequestStatus& aStatus); |
|
193 |
|
194 /** |
|
195 Ask the server to notify when the surface buffer which will be specified in the next |
|
196 update request has been displayed for the first time. |
|
197 The notification will also include exact time of the event as it is supplied by the |
|
198 User::FastCounter(). |
|
199 Only the last call of this function before SubmitUpdate command takes place will |
|
200 have effect, i.e. the following call will override the previous one. |
|
201 |
|
202 @param aStatus Reference to the request status object. |
|
203 @param aTimeStamp Reference to the timestamp of the display notification event, |
|
204 packed into the modified buffer descriptor. |
|
205 Will only be valid if aStatus is equal to KErrNone. |
|
206 |
|
207 @see RSurfaceUpdateSession::SubmitUpdate |
|
208 |
|
209 @pre The surface session must be established to the server. |
|
210 @post This request for the display notification event will be transferred to the GCE |
|
211 at next SubmitUpdate command. |
|
212 |
|
213 @return KErrNone if the surface has been displayed successfully, when request |
|
214 completed aStatus will contain this error code. |
|
215 @return KErrOverflow if the updated buffer was not displayed because it was |
|
216 superseded by a further update on the same surface. |
|
217 @return KErrBackendNotAvailable if backend for specified screen hasn’t been |
|
218 registered with the server. |
|
219 @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. |
|
220 @return KErrCancel if notification has been cancelled. It could happen, for instance, |
|
221 if CancelUpdateNotification is called before the request is completed. |
|
222 @return KErrServerBusy if the number of outstanding requests has exceeded specified |
|
223 value (@see RSurfaceUpdateSession::Connect for details). |
|
224 @return KErrNotReady if the environment is in invalid state (for instance, the |
|
225 Surface Update Server has not been launched or session is disconnected). |
|
226 @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. |
|
227 This could happen if there is no layer associated with the surface or no active |
|
228 composition scene. |
|
229 For global update it signifies that the surface is not visible for any screen. |
|
230 Note, the absence of this error code does not guarantee that the surface is visible. |
|
231 For example, if the surface is behind another surface that has alpha blending |
|
232 enabled the compositor will not do a pixel level comparison to determine surface visibility. |
|
233 @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. |
|
234 @return KErrNotSupported if global and per-screen update are mixed within the same session. |
|
235 @return ErrNoMemory if the memory is not enough to fulfill the request, otherwise any |
|
236 other system error codes. |
|
237 Will panic if applied on disconnected session. |
|
238 */ |
|
239 IMPORT_C void NotifyWhenDisplayed(TRequestStatus& aStatus, TTimeStamp& aTimeStamp); |
|
240 |
|
241 /** |
|
242 Ask the server to notify when the surface buffer which will |
|
243 be specified in the next update request has been displayed for the X times. |
|
244 <p>Only the last call of this function before SubmitUpdate command takes place |
|
245 will have effect, i.e. the following call will override the previous one. |
|
246 <p>In case of the global update the notification will always be aligned with the master |
|
247 display. The SUS will send notification to client when the surface has been displayed on a |
|
248 master display for the X times or if there is no master display for that surface. |
|
249 If the master becomes invisible while the request is still in a progress it will be |
|
250 reassigned to the next visible display with highest priority. |
|
251 <p>This request will only be associated with the following single call of the SubmitUpdate. |
|
252 |
|
253 @param aCount Number of times the surface is displayed before the request is completed. |
|
254 Varies from 1 and greater. |
|
255 @param aStatus Reference to the request status object. |
|
256 |
|
257 @pre The surface session must be established to the server. |
|
258 @post This request for the display notification event will be transferred to the GCE at |
|
259 next SubmitUpdate command. |
|
260 |
|
261 @return KErrNone if the surface has been displayed successfully for specified numbers |
|
262 of times, when request completed aStatus will contain this error code. |
|
263 @return KErrOverflow if the updated buffer did not remain on-screen for the specified |
|
264 number of display refreshes because it was superseded by a further update on the |
|
265 same surface. |
|
266 @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. |
|
267 @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered |
|
268 with the server. |
|
269 @return KErrCancel if notification has been cancelled. It could happen, for instance, |
|
270 if CancelUpdateNotification is called before the request is completed. |
|
271 @return KErrServerBusy if the number of outstanding requests has exceeded |
|
272 specified value (@see RSurfaceUpdateSession::Connect for details). |
|
273 @return KErrNotReady if the environment is in invalid state (for instance, the |
|
274 Surface Update Server has not been launched or session is disconnected). |
|
275 @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. |
|
276 This could happen if there is no layer associated with the surface or no active |
|
277 composition scene. |
|
278 For global update it signifies that the surface is not visible for any screen. |
|
279 Note, the absence of this error code does not guarantee that the surface is visible. |
|
280 For example, if the surface is behind another surface that has alpha blending |
|
281 enabled the compositor will not do a pixel level comparison to determine surface visibility. |
|
282 @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. |
|
283 @return KErrNotSupported if global and per-screen update are mixed within the same session. |
|
284 @return KErrNoMemory if the memory is not enough to fulfill the request, otherwise |
|
285 any other system error codes. |
|
286 Will panic if applied on disconnected session. |
|
287 */ |
|
288 IMPORT_C void NotifyWhenDisplayedXTimes(TInt aCount, TRequestStatus& aStatus); |
|
289 |
|
290 /** |
|
291 Cancel all outstanding requests for notification. |
|
292 The function doesn't cancel the submit update requests themselves. |
|
293 |
|
294 @pre The surface session must be established to the server. |
|
295 @post The server will issue request complete immediately for all outstanding requests |
|
296 related to particular session. |
|
297 Will panic if applied on disconnected session. |
|
298 */ |
|
299 IMPORT_C void CancelAllUpdateNotifications(); |
|
300 |
|
301 protected: |
|
302 /** |
|
303 Allow to retrieve the version number. |
|
304 |
|
305 @return client version number |
|
306 */ |
|
307 TVersion Version() const; |
|
308 |
|
309 private: |
|
310 void IssueRequestComplete(TInt aErr); |
|
311 |
|
312 private: |
|
313 TRequestStatus *iStatusAvailable; |
|
314 TRequestStatus *iStatusDisplayed; |
|
315 TRequestStatus *iStatusDisplayedXTimes; |
|
316 TTimeStamp* iTimeStamp; |
|
317 TInt iCount; |
|
318 }; |
|
319 |
|
320 #endif |