105 void Invalidate(const TGraphicDrawerId& aId); |
104 void Invalidate(const TGraphicDrawerId& aId); |
106 void OnInactive(); |
105 void OnInactive(); |
107 void OnActive(); |
106 void OnActive(); |
108 void ScheduleRedraw(MWsScreen& aScreen,const TTime& aWhen); |
107 void ScheduleRedraw(MWsScreen& aScreen,const TTime& aWhen); |
109 void DoRedrawNow(MWsScreen& aScreen); |
108 void DoRedrawNow(MWsScreen& aScreen); |
|
109 void DoRedrawNow(MWsScreen& aScreen, MWsAnimationScheduler::MScreenUpdateObserver& aObserver); |
|
110 void ClearScreenUpdateObserver(const MWsAnimationScheduler::MScreenUpdateObserver& aObserver); |
110 private: |
111 private: |
111 static TBool OnIdleCallBack(TAny* aAny); |
112 static TBool OnIdleCallBack(TAny* aAny); |
112 void ScheduleUpdate (TInt aScreenNumber, TBool aForce); |
113 void ScheduleUpdate (TInt aScreenNumber, TBool aForce); |
113 void OnIdleCallBack(TBool aForce); |
114 void OnIdleCallBack(TBool aForce); |
114 static TBool InvokeDueAnimation(TAny* aAny); |
115 static TBool InvokeDueAnimation(TAny* aAny); |
140 public: |
141 public: |
141 static CScreenState* NewL (CDefaultAnimationScheduler* aScheduler, TInt aScreenOrdinal); |
142 static CScreenState* NewL (CDefaultAnimationScheduler* aScheduler, TInt aScreenOrdinal); |
142 ~CScreenState(); |
143 ~CScreenState(); |
143 void SetActive (); |
144 void SetActive (); |
144 |
145 |
|
146 void WaitForRedraws(MWsAnimationScheduler::MScreenUpdateObserver& aObserver, TInt aNumRedraws); |
|
147 void ClearScreenUpdateObserver(const MWsAnimationScheduler::MScreenUpdateObserver& aObserver); |
145 CPeriodic* iUpdateOn; |
148 CPeriodic* iUpdateOn; |
146 TTime iExpectedTickTime; |
149 TTime iExpectedTickTime; |
147 TScreenUpdateDetails iScreenUpdateDetails; |
150 TScreenUpdateDetails iScreenUpdateDetails; |
148 RArray<TGraphicDrawerId> iInvalidated; |
151 RArray<TGraphicDrawerId> iInvalidated; |
149 TBool iInvalidateAll; |
152 TBool iInvalidateAll; |
150 |
153 |
151 private: |
154 private: |
152 CScreenState (CDefaultAnimationScheduler* aScheduler, TInt aScreenOrdinal); |
155 CScreenState (CDefaultAnimationScheduler* aScheduler, TInt aScreenOrdinal); |
153 void ConstructL (); |
156 void ConstructL (); |
|
157 void ReleaseRemainingClients(); |
|
158 void ReleaseClientsWaitingFor(TUint aCurrentFrame); |
154 |
159 |
155 void RunL(); |
160 void RunL(); |
156 void DoCancel() |
161 void DoCancel() |
157 { |
162 { |
158 TRequestStatus* tmpTRS = &iStatus; |
163 TRequestStatus* tmpTRS = &iStatus; |
159 User::RequestComplete(tmpTRS, KErrNone); |
164 User::RequestComplete(tmpTRS, KErrNone); |
160 }; |
165 }; |
|
166 class TWaitingClient |
|
167 { |
|
168 public: |
|
169 TWaitingClient(MWsAnimationScheduler::MScreenUpdateObserver& aObserver, TInt aTargetFrame) |
|
170 : iObserver(aObserver), iTargetFrame(aTargetFrame) |
|
171 { |
|
172 } |
|
173 MWsAnimationScheduler::MScreenUpdateObserver& iObserver; |
|
174 TUint iTargetFrame; |
|
175 }; |
|
176 TUint iFrameCount; |
|
177 RArray<TWaitingClient> iWaitingClients; |
161 }; |
178 }; |
162 |
179 |
163 // If using the default animation scheduler on a device, these two numbers may be worth tweaking in the inifile |
180 // If using the default animation scheduler on a device, these two numbers may be worth tweaking in the inifile |
164 // However, both are maximum periods - wserv will go faster than either if nothing else is using the system. |
181 // However, both are maximum periods - wserv will go faster than either if nothing else is using the system. |
165 const TInt64 CWindowServer::CDefaultAnimationScheduler::KRedrawGrace = 0; // do redraws immediately |
182 const TInt64 CWindowServer::CDefaultAnimationScheduler::KRedrawGrace = 0; // do redraws immediately |
273 } |
290 } |
274 |
291 |
275 void CWindowServer::CDefaultAnimationScheduler::CScreenState::ConstructL () |
292 void CWindowServer::CDefaultAnimationScheduler::CScreenState::ConstructL () |
276 { |
293 { |
277 iUpdateOn = CPeriodic::NewL(EComposeCompletePriority); |
294 iUpdateOn = CPeriodic::NewL(EComposeCompletePriority); |
|
295 iWaitingClients.ReserveL(8); |
278 CActiveScheduler::Add(this); |
296 CActiveScheduler::Add(this); |
279 } |
297 } |
280 |
298 |
281 CWindowServer::CDefaultAnimationScheduler::CScreenState::~CScreenState() |
299 CWindowServer::CDefaultAnimationScheduler::CScreenState::~CScreenState() |
282 { |
300 { |
283 CActive::Cancel(); |
301 CActive::Cancel(); |
284 iInvalidated.Close(); |
302 iInvalidated.Close(); |
285 delete iUpdateOn; |
303 delete iUpdateOn; |
|
304 TInt i = iWaitingClients.Count(); |
|
305 while(i--) |
|
306 { |
|
307 iWaitingClients[i].iObserver.ScreenUpdateComplete(KErrAbort); |
|
308 } |
|
309 iWaitingClients.Close(); |
286 } |
310 } |
287 |
311 |
288 void CWindowServer::CDefaultAnimationScheduler::CScreenState::SetActive() |
312 void CWindowServer::CDefaultAnimationScheduler::CScreenState::SetActive() |
289 { |
313 { |
290 CActive::SetActive (); |
314 CActive::SetActive (); |
291 } |
315 } |
292 |
316 |
|
317 /** |
|
318 This function is called from CWsClient d'tor to make sure we will not hang on to any deleted objects. |
|
319 */ |
|
320 void CWindowServer::CDefaultAnimationScheduler::CScreenState::ClearScreenUpdateObserver(const MWsAnimationScheduler::MScreenUpdateObserver& aObserver) |
|
321 { |
|
322 const TInt count = iWaitingClients.Count(); |
|
323 for(TInt i = count-1 ; i >= 0; i--) |
|
324 { |
|
325 if( &aObserver == &(iWaitingClients[i].iObserver) ) |
|
326 { |
|
327 TWaitingClient& client = iWaitingClients[i]; |
|
328 client.iObserver.ScreenUpdateComplete(KErrCancel); |
|
329 iWaitingClients.Remove(i); |
|
330 } |
|
331 } |
|
332 } |
|
333 |
|
334 void CWindowServer::CDefaultAnimationScheduler::CScreenState::WaitForRedraws(MWsAnimationScheduler::MScreenUpdateObserver& aObserver, TInt aNumRedraws) |
|
335 { |
|
336 const TUint targetFrame = iFrameCount + aNumRedraws; |
|
337 TWaitingClient request(aObserver, targetFrame); |
|
338 TInt err = iWaitingClients.Append(request); |
|
339 if(err != KErrNone) |
|
340 { |
|
341 //If OOM and already have 8 waiting clients we will not accept a 9th client |
|
342 aObserver.ScreenUpdateComplete(KErrNoMemory); |
|
343 } |
|
344 } |
|
345 |
|
346 void CWindowServer::CDefaultAnimationScheduler::CScreenState::ReleaseRemainingClients() |
|
347 { |
|
348 const TInt count = iWaitingClients.Count(); |
|
349 for(TInt i = count-1; i >= 0; i--) |
|
350 { |
|
351 TWaitingClient& client = iWaitingClients[i]; |
|
352 client.iObserver.ScreenUpdateComplete(KErrNone); |
|
353 iWaitingClients.Remove(i); |
|
354 } |
|
355 } |
|
356 |
|
357 void CWindowServer::CDefaultAnimationScheduler::CScreenState::ReleaseClientsWaitingFor(TUint aCurrentFrame) |
|
358 { |
|
359 const TInt count = iWaitingClients.Count(); |
|
360 for(TInt i = count-1; i >= 0; i--) |
|
361 { |
|
362 TWaitingClient& client = iWaitingClients[i]; |
|
363 if(aCurrentFrame == client.iTargetFrame) |
|
364 { |
|
365 client.iObserver.ScreenUpdateComplete(KErrNone); |
|
366 iWaitingClients.Remove(i); |
|
367 } |
|
368 } |
|
369 } |
|
370 |
293 /** |
371 /** |
294 Invoked when the rendering pipline signals that it is ready to recieve updated. |
372 Invoked when the rendering pipline signals that it is ready to receive updates. |
295 */ |
373 */ |
296 void CWindowServer::CDefaultAnimationScheduler::CScreenState::RunL() |
374 void CWindowServer::CDefaultAnimationScheduler::CScreenState::RunL() |
297 { |
375 { |
|
376 iFrameCount++; |
|
377 |
|
378 //Complete any clients waiting for this frame |
|
379 ReleaseClientsWaitingFor(iFrameCount); |
|
380 |
298 iScreenUpdateDetails.iScheduler->ProcessUpdateCompletion (iScreenUpdateDetails.iScreenNumber); |
381 iScreenUpdateDetails.iScheduler->ProcessUpdateCompletion (iScreenUpdateDetails.iScreenNumber); |
|
382 |
|
383 if(!IsActive()) |
|
384 { |
|
385 //No further pending frames, release all remaining clients |
|
386 ReleaseRemainingClients(); |
|
387 } |
|
388 |
299 } |
389 } |
300 |
390 |
301 void CWindowServer::CDefaultAnimationScheduler::ProcessUpdateCompletion (TInt aScreenNumber) |
391 void CWindowServer::CDefaultAnimationScheduler::ProcessUpdateCompletion (TInt aScreenNumber) |
302 { |
392 { |
303 // Stop all waitloops related to the specified screen. |
393 // Stop all waitloops related to the specified screen. |
308 |
398 |
309 // Perform any outstanding redraws on the specified screen. |
399 // Perform any outstanding redraws on the specified screen. |
310 ScheduleUpdate (aScreenNumber, ETrue); |
400 ScheduleUpdate (aScreenNumber, ETrue); |
311 } |
401 } |
312 |
402 |
|
403 void CWindowServer::CDefaultAnimationScheduler::DoRedrawNow(MWsScreen& aScreen, MWsAnimationScheduler::MScreenUpdateObserver& aObserver) |
|
404 { |
|
405 TInt screenNumber = ScreenNumber (aScreen); |
|
406 TInt redrawCount = 0; |
|
407 |
|
408 // redrawCount is the number of times we should wait for redraws to complete. |
|
409 // If a redraw is not currently active then we need to wait (at most) once: for |
|
410 // any outstanding scheduled update to complete. |
|
411 // If a redraw is currently active then we need to wait (at most) twice: once for |
|
412 // the current update to complete, and once for any outstanding scheduled update to complete. |
|
413 if (!iScreenState[screenNumber]->IsActive()) |
|
414 { |
|
415 // No animation in progress, so force a redraw of due updates. |
|
416 ScheduleUpdate(screenNumber, ETrue); |
|
417 |
|
418 // If there is still nothing drawing, set redrawCount to zero to make sure we do not wait. |
|
419 if (!iScreenState[screenNumber]->IsActive()) |
|
420 { |
|
421 redrawCount = 0; |
|
422 aObserver.ScreenUpdateComplete(KErrNone); |
|
423 } |
|
424 else |
|
425 { |
|
426 redrawCount = 1; |
|
427 iScreenState[screenNumber]->WaitForRedraws(aObserver, redrawCount); |
|
428 } |
|
429 } |
|
430 else |
|
431 { |
|
432 redrawCount = 2; |
|
433 iScreenState[screenNumber]->WaitForRedraws(aObserver, redrawCount); |
|
434 } |
|
435 } |
|
436 |
|
437 void CWindowServer::CDefaultAnimationScheduler::ClearScreenUpdateObserver(const MWsAnimationScheduler::MScreenUpdateObserver& aObserver) |
|
438 { |
|
439 const TInt count = iScreenState.Count(); |
|
440 for(TInt screenNumber=0; screenNumber<count; screenNumber++) |
|
441 { |
|
442 iScreenState[screenNumber]->ClearScreenUpdateObserver(aObserver); |
|
443 } |
|
444 } |
|
445 |
313 /** |
446 /** |
314 Switch to deactivate animation or drawing (based on setting of iInactivityBehaviour). |
447 Switch to deactivate animation or drawing (based on setting of iInactivityBehaviour). |
315 See InvokeDueAnimation(). |
448 See InvokeDueAnimation(). |
316 */ |
449 */ |
317 void CWindowServer::CDefaultAnimationScheduler::OnInactive() |
450 void CWindowServer::CDefaultAnimationScheduler::OnInactive() |
357 } |
490 } |
358 |
491 |
359 /** |
492 /** |
360 Perform redraw and return only when completed. |
493 Perform redraw and return only when completed. |
361 NOTE: This method uses CActiveSchedulerWait to run a "modal wait loop" while the |
494 NOTE: This method uses CActiveSchedulerWait to run a "modal wait loop" while the |
362 redraw complete signal is pending. When the signal is recieved, AsyncStop() is |
495 redraw complete signal is pending. When the signal is received, AsyncStop() is |
363 invoked on all active wait loops for the signalling screen. |
496 invoked on all active wait loops for the signalling screen. |
364 */ |
497 */ |
365 void CWindowServer::CDefaultAnimationScheduler::DoRedrawNow(MWsScreen& aScreen) |
498 void CWindowServer::CDefaultAnimationScheduler::DoRedrawNow(MWsScreen& aScreen) |
366 { |
499 { |
367 TInt screenNumber = ScreenNumber (aScreen); |
500 TInt screenNumber = ScreenNumber (aScreen); |
368 TInt redrawCount = 0; |
501 TInt redrawCount = 0; |
369 |
502 |
370 // redrawCount is the number of times we should wait for redraws to complete. |
503 // redrawCount is the number of times we should wait for redraws to complete. |
371 // If a redraw is not currently active then we need to wait (at most) once: for |
504 // If a redraw is not currently active then we need to wait (at most) once: for |
372 // any outstanding scheduled update to complete. |
505 // any outstanding scheduled update to complete. |
373 // If a redraw is currently active then we need to wait (at most) twice: once for |
506 // If a redraw is currently active then we need to wait (at most) twice: once for |
374 // the current update to complete, and once for any outstanding scheduled update to complete. |
507 // the current update to complete, and once for any outstanding scheduled update to complete. |
733 iMemoryReleases.Reset(); |
866 iMemoryReleases.Reset(); |
734 WS_ASSERT_DEBUG(iDrawerMasterIndex.IsEmpty(), EWsPanicWsGraphic); |
867 WS_ASSERT_DEBUG(iDrawerMasterIndex.IsEmpty(), EWsPanicWsGraphic); |
735 iDrawerMasterIndex.Close(); |
868 iDrawerMasterIndex.Close(); |
736 |
869 |
737 delete iDefaultAnimationScheduler; |
870 delete iDefaultAnimationScheduler; |
738 iDefaultAnimationScheduler = NULL; //might be called from clients during server destruction |
871 iDefaultAnimationScheduler = NULL; //might be called from clients during server destruction |
739 iCustomAnimationScheduler = NULL; // not owned |
|
740 } |
872 } |
741 |
873 |
742 void CWindowServer::ConstructL() |
874 void CWindowServer::ConstructL() |
743 { |
875 { |
744 iServer = CServer::NewL(); |
876 iServer = CServer::NewL(); |
797 } |
929 } |
798 |
930 |
799 /** |
931 /** |
800 Custom Animation Scheduler |
932 Custom Animation Scheduler |
801 */ |
933 */ |
802 TBool CWindowServer::SetCustomAnimationScheduler(MWsAnimationScheduler* aScheduler) |
934 TBool CWindowServer::SetCustomAnimationScheduler(MWsAnimationScheduler* /*aScheduler*/) |
803 { |
935 { |
804 if(!iCustomAnimationScheduler && aScheduler) |
|
805 { |
|
806 iCustomAnimationScheduler = aScheduler; |
|
807 return ETrue; |
|
808 } |
|
809 return EFalse; |
936 return EFalse; |
810 } |
937 } |
811 |
938 |
812 TBool CWindowServer::HasCustomAnimationScheduler() const |
939 TBool CWindowServer::HasCustomAnimationScheduler() const |
813 { |
940 { |
814 return !!iCustomAnimationScheduler; |
|
815 } |
|
816 |
|
817 TBool CWindowServer::ClearCustomAnimationScheduler(MWsAnimationScheduler* aCurrentScheduler) |
|
818 { |
|
819 if(iCustomAnimationScheduler && (iCustomAnimationScheduler == aCurrentScheduler)) |
|
820 { |
|
821 iCustomAnimationScheduler = NULL; |
|
822 return ETrue; |
|
823 } |
|
824 return EFalse; |
941 return EFalse; |
825 } |
942 } |
|
943 |
|
944 TBool CWindowServer::ClearCustomAnimationScheduler(MWsAnimationScheduler* /*aCurrentScheduler*/) |
|
945 { |
|
946 return EFalse; |
|
947 } |
826 |
948 |
827 MWsAnimationScheduler* CWindowServer::AnimationScheduler() |
949 MWsAnimationScheduler* CWindowServer::AnimationScheduler() |
828 { |
950 { |
829 if(iCustomAnimationScheduler) |
|
830 { |
|
831 return iCustomAnimationScheduler; |
|
832 } |
|
833 return iDefaultAnimationScheduler; |
951 return iDefaultAnimationScheduler; |
|
952 } |
|
953 |
|
954 void CWindowServer::PrepareShutdown() |
|
955 { |
|
956 //Stop the renderloop, i.e. prevent any further calls to MWsAnimationScheduler::Animate() |
|
957 delete iDefaultAnimationScheduler; |
|
958 iDefaultAnimationScheduler = NULL; |
834 } |
959 } |
835 |
960 |
836 TInt CWindowServer::RegisterEventHandler(CWsGraphicDrawer* aDrawer, MWsEventHandler* aHandler, TUint32 aEventMask) |
961 TInt CWindowServer::RegisterEventHandler(CWsGraphicDrawer* aDrawer, MWsEventHandler* aHandler, TUint32 aEventMask) |
837 { |
962 { |
838 if (!aDrawer || !aHandler || aEventMask==0) |
963 if (!aDrawer || !aHandler || aEventMask==0) |