Added memory pool logging
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animation.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/animation.h>
23
24 #include <dali/internal/common/buffer-index.h>
25 #include <dali/internal/common/message.h>
26 #include <dali/internal/event/common/event-thread-services.h>
27 #include <dali/internal/update/animation/scene-graph-animator.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace SceneGraph
34 {
35 /**
36  * Animations are used to change the properties of scene graph objects, as part of a scene
37  * managers "update" phase. An animation is a container of Animator objects; the actual setting
38  * of object values is done by the animators.
39  */
40 class Animation
41 {
42 public:
43   using EndAction = Dali::Animation::EndAction;
44
45   enum State
46   {
47     Stopped,
48     Playing,
49     Paused,
50     Destroyed
51   };
52
53   /**
54    * Construct a new Animation.
55    * @param[in] durationSeconds The duration of the animation in seconds.
56    * @param[in] speedFactor Multiplier to the animation velocity.
57    * @param[in] playRange Minimum and maximum progress between which the animation will play.
58    * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
59    * @param[in] endAction The action to perform when the animation ends.
60    * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
61    * @return A new Animation
62    */
63   static Animation* New(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
64
65   /**
66    * Virtual destructor
67    */
68   virtual ~Animation();
69
70   /**
71    * Overriden delete operator
72    * Deletes the animation from its global memory pool
73    */
74   void operator delete(void* ptr);
75
76   /**
77    * Set the duration of an animation.
78    * @pre durationSeconds must be greater than zero.
79    * @param[in] durationSeconds The duration in seconds.
80    */
81   void SetDuration(float durationSeconds);
82
83   /**
84    * Set the progress marker to trigger notification
85    * @param[in] progress percent of progress to trigger notification, 0.0f < progress <= 1.0f
86    */
87   void SetProgressNotification(float progress);
88
89   /**
90    * Retrieve the duration of the animation.
91    * @return The duration in seconds.
92    */
93   float GetDuration() const
94   {
95     return mDurationSeconds;
96   }
97
98   /**
99    * Retrieve the current progress of the animation.
100    * @return The current progress as a normalized value between [0,1].
101    */
102   float GetCurrentProgress() const
103   {
104     if(mDurationSeconds > 0.0f)
105     {
106       return mElapsedSeconds / mDurationSeconds;
107     }
108
109     return 0.0f;
110   }
111
112   /**
113    * Sets the progress of the animation.
114    * @param[in] The new progress as a normalized value between [0,1]
115    */
116   void SetCurrentProgress(float progress)
117   {
118     mElapsedSeconds = mDurationSeconds * progress;
119   }
120
121   /**
122    * Specifies a speed factor for the animation.
123    * @param[in] factor A value which will multiply the velocity
124    */
125   void SetSpeedFactor(float factor)
126   {
127     mSpeedFactor = factor;
128   }
129
130   /**
131    * Set the animation loop count.
132    * 0 is loop forever, N loop play N times
133    * @param[in] loopCount The loop count
134    */
135   void SetLoopCount(int32_t loopCount);
136
137   /**
138    * Query whether the animation will loop.
139    * @return True if the animation will loop.
140    */
141   bool IsLooping() const
142   {
143     return mLoopCount != 1;
144   }
145
146   /**
147    * Get the loop count
148    * @return the loop count
149    */
150   int32_t GetLoopCount() const
151   {
152     return mLoopCount;
153   }
154
155   /**
156    * Set the end action of the animation.
157    * @param[in] action The end action.
158    */
159   void SetEndAction(EndAction action);
160
161   /**
162    * Retrieve the action performed when the animation ends.
163    * @return The end action.
164    */
165   EndAction GetEndAction()
166   {
167     return mEndAction;
168   }
169
170   /**
171    * Set the disconnect action of the animation when connected objects are disconnected.
172    * This action is performed during the next update when
173    * the connected object is disconnected.
174    * @param[in] action The disconnect action.
175    */
176   void SetDisconnectAction(EndAction action);
177
178   /**
179    * Retrieve the action performed when the animation is destroyed.
180    * @return The destroy action.
181    */
182   EndAction GetDisconnectAction()
183   {
184     return mDisconnectAction;
185   }
186
187   /**
188    * Set the playing range. The animation will only play between the minimum and maximum progress
189    * speficied.
190    *
191    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
192    */
193   void SetPlayRange(const Vector2& range);
194
195   /**
196    * Play the animation.
197    */
198   void Play();
199
200   /**
201    * Play the animation from a given point
202    * @param[in] progress A value between [0,1] form where the animation should start playing
203    */
204   void PlayFrom(float progress);
205
206   /**
207    * @brief Play the animation after a given delay time.
208    * @param[in] delaySeconds The delay time
209    */
210   void PlayAfter(float delaySeconds);
211
212   /**
213    * Pause the animation.
214    */
215   void Pause();
216
217   /**
218    * Stop the animation.
219    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
220    * @return True if the animation has finished (otherwise it wasn't playing)
221    */
222   bool Stop(BufferIndex bufferIndex);
223
224   /**
225    * Called shortly before the animation is destroyed.
226    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
227    */
228   void OnDestroy(BufferIndex bufferIndex);
229
230   /**
231    * Query whether the animation is playing, paused or stopped.
232    * Note that even when paused, the Update() method should be called,
233    * since the current progress must be reapplied each frame.
234    */
235   State GetState() const
236   {
237     return mState;
238   }
239
240   /**
241    * Retrive a count of the number of times the animation has been played to completion.
242    * This can be used to emit "Finised" signals from the public-api
243    */
244   int32_t GetPlayedCount() const
245   {
246     return mPlayedCount;
247   }
248
249   /**
250    * Get the current loop count from zero to GetLoopCount().
251    */
252   int32_t GetCurrentLoop() const
253   {
254     return mCurrentLoop;
255   }
256
257   /**
258    * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
259    * @return True if the animation is currently active
260    */
261   bool IsActive() const
262   {
263     // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
264     return mIsActive[0] || mIsActive[1];
265   }
266
267   /**
268    * @brief Sets the looping mode.
269    *
270    * Animation plays forwards and then restarts from the beginning or runs backwards again.
271    * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
272    */
273   void SetLoopingMode(bool loopingMode);
274
275   /**
276    * Add a newly created animator.
277    * Animators are automatically removed, when orphaned from an animatable scene object.
278    * @param[in] animator The animator to add.
279    * @param[in] propertyOwner The scene-object that owns the animatable property.
280    * @post The animator is owned by this animation.
281    */
282   void AddAnimator(OwnerPointer<AnimatorBase>& animator);
283
284   /**
285    * This causes the animators to change the properties of objects in the scene graph.
286    * @pre The animation is playing or paused.
287    * @param[in] bufferIndex The buffer to update.
288    * @param[in] elapsedSeconds The time elapsed since the previous frame.
289    * @param[out] looped True if the animation looped
290    * @param[out] finished True if the animation has finished.
291    * @param[out] progressReached True if progress marker reached
292    */
293   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached);
294
295   static uint32_t GetMemoryPoolCapacity();
296
297 protected:
298   /**
299    * Protected constructor. See New()
300    */
301   Animation(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
302
303 private:
304   /**
305    * Helper for Update, also used to bake when the animation is stopped or destroyed.
306    * @param[in] bufferIndex The buffer to update.
307    * @param[in] bake True if the final result should be baked.
308    * @param[in] animationFinished True if the animation has finished.
309    */
310   void UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animationFinished);
311
312   /**
313    * Helper function to bake the result of the animation when it is stopped or
314    * destroyed.
315    * @param[in] bufferIndex The buffer to update.
316    * @param[in] action The end action specified.
317    */
318   void Bake(BufferIndex bufferIndex, EndAction action);
319
320   /**
321    * Helper function to set active state of animators.
322    * @param[in] active Every animator is set to this state
323    */
324   void SetAnimatorsActive(bool active);
325
326   // Undefined
327   Animation(const Animation&);
328
329   // Undefined
330   Animation& operator=(const Animation& rhs);
331
332 protected:
333   OwnerContainer<AnimatorBase*> mAnimators;
334
335   Vector2 mPlayRange;
336
337   float mDurationSeconds;
338   float mDelaySeconds;
339   float mElapsedSeconds;
340   float mSpeedFactor;
341   float mProgressMarker; // Progress marker to trigger a notification
342
343   int32_t mPlayedCount; // Incremented at end of animation or completion of all loops
344                         // Never incremented when looping forever. Event thread tracks to signal end.
345   int32_t mLoopCount;   // N loop setting
346   int32_t mCurrentLoop; // Current loop number
347
348   EndAction mEndAction;
349   EndAction mDisconnectAction;
350
351   State mState;
352
353   bool mProgressReachedSignalRequired; // Flag to indicate the progress marker was hit
354   bool mAutoReverseEnabled;            // Flag to identify that the looping mode is auto reverse.
355   bool mIsActive[2];                   // Flag to indicate whether the animation is active in the current frame (which is double buffered)
356 };
357
358 }; //namespace SceneGraph
359
360 // value types used by messages
361 template<>
362 struct ParameterType<Dali::Animation::EndAction> : public BasicType<Dali::Animation::EndAction>
363 {
364 };
365
366 namespace SceneGraph
367 {
368 // Messages for Animation
369
370 inline void SetDurationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds)
371 {
372   using LocalType = MessageValue1<Animation, float>;
373
374   // Reserve some memory inside the message queue
375   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
376
377   // Construct message in the message queue memory; note that delete should not be called on the return value
378   new(slot) LocalType(&animation, &Animation::SetDuration, durationSeconds);
379 }
380
381 inline void SetProgressNotificationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
382 {
383   using LocalType = MessageValue1<Animation, float>;
384
385   // Reserve some memory inside the message queue
386   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
387
388   // Construct message in the message queue memory; note that delete should not be called on the return value
389   new(slot) LocalType(&animation, &Animation::SetProgressNotification, progress);
390 }
391
392 inline void SetLoopingMessage(EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount)
393 {
394   using LocalType = MessageValue1<Animation, int32_t>;
395
396   // Reserve some memory inside the message queue
397   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
398
399   // Construct message in the message queue memory; note that delete should not be called on the return value
400   new(slot) LocalType(&animation, &Animation::SetLoopCount, loopCount);
401 }
402
403 inline void SetEndActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
404 {
405   using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
406
407   // Reserve some memory inside the message queue
408   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
409
410   // Construct message in the message queue memory; note that delete should not be called on the return value
411   new(slot) LocalType(&animation, &Animation::SetEndAction, action);
412 }
413
414 inline void SetDisconnectActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
415 {
416   using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
417
418   // Reserve some memory inside the message queue
419   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
420
421   // Construct message in the message queue memory; note that delete should not be called on the return value
422   new(slot) LocalType(&animation, &Animation::SetDisconnectAction, action);
423 }
424
425 inline void SetCurrentProgressMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
426 {
427   using LocalType = MessageValue1<Animation, float>;
428
429   // Reserve some memory inside the message queue
430   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
431
432   // Construct message in the message queue memory; note that delete should not be called on the return value
433   new(slot) LocalType(&animation, &Animation::SetCurrentProgress, progress);
434 }
435
436 inline void SetSpeedFactorMessage(EventThreadServices& eventThreadServices, const Animation& animation, float factor)
437 {
438   using LocalType = MessageValue1<Animation, float>;
439
440   // Reserve some memory inside the message queue
441   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
442
443   // Construct message in the message queue memory; note that delete should not be called on the return value
444   new(slot) LocalType(&animation, &Animation::SetSpeedFactor, factor);
445 }
446
447 inline void SetPlayRangeMessage(EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range)
448 {
449   using LocalType = MessageValue1<Animation, Vector2>;
450
451   // Reserve some memory inside the message queue
452   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
453
454   // Construct message in the message queue memory; note that delete should not be called on the return value
455   new(slot) LocalType(&animation, &Animation::SetPlayRange, range);
456 }
457
458 inline void PlayAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
459 {
460   using LocalType = Message<Animation>;
461
462   // Reserve some memory inside the message queue
463   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
464
465   // Construct message in the message queue memory; note that delete should not be called on the return value
466   new(slot) LocalType(&animation, &Animation::Play);
467 }
468
469 inline void PlayAnimationFromMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
470 {
471   using LocalType = MessageValue1<Animation, float>;
472
473   // Reserve some memory inside the message queue
474   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
475
476   // Construct message in the message queue memory; note that delete should not be called on the return value
477   new(slot) LocalType(&animation, &Animation::PlayFrom, progress);
478 }
479
480 inline void PauseAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
481 {
482   using LocalType = Message<Animation>;
483
484   // Reserve some memory inside the message queue
485   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
486
487   // Construct message in the message queue memory; note that delete should not be called on the return value
488   new(slot) LocalType(&animation, &Animation::Pause);
489 }
490
491 inline void AddAnimatorMessage(EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator)
492 {
493   using LocalType = MessageValue1<Animation, OwnerPointer<AnimatorBase> >;
494
495   // Reserve some memory inside the message queue
496   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
497
498   // Construct message in the message queue memory; note that delete should not be called on the return value
499   OwnerPointer<AnimatorBase> parameter(&animator);
500   new(slot) LocalType(&animation, &Animation::AddAnimator, parameter);
501 }
502
503 inline void PlayAfterMessage(EventThreadServices& eventThreadServices, const Animation& animation, float delaySeconds)
504 {
505   using LocalType = MessageValue1<Animation, float>;
506
507   // Reserve some memory inside the message queue
508   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
509
510   // Construct message in the message queue memory; note that delete should not be called on the return value
511   new(slot) LocalType(&animation, &Animation::PlayAfter, delaySeconds);
512 }
513
514 inline void SetLoopingModeMessage(EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode)
515 {
516   using LocalType = MessageValue1<Animation, bool>;
517
518   // Reserve some memory inside the message queue
519   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
520
521   // Construct message in the message queue memory; note that delete should not be called on the return value
522   new(slot) LocalType(&animation, &Animation::SetLoopingMode, loopingMode);
523 }
524
525 } // namespace SceneGraph
526
527 } // namespace Internal
528
529 } // namespace Dali
530
531 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H