DALi Version 2.2.11
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-vector-image / vector-animation-task.h
1 #ifndef DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
2 #define DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
3
4 /*
5  * Copyright (c) 2023 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 // EXTERNAL INCLUDES
21 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
22 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
23 #include <dali/devel-api/threading/conditional-wait.h>
24 #include <dali/public-api/adaptor-framework/async-task-manager.h>
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/object/property-array.h>
27 #include <chrono>
28 #include <memory>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
32 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
33
34 namespace Dali
35 {
36 namespace Toolkit
37 {
38 namespace Internal
39 {
40 class VisualFactoryCache;
41 class VectorAnimationThread;
42 class VectorAnimationTask;
43 typedef IntrusivePtr<VectorAnimationTask> VectorAnimationTaskPtr;
44
45 /**
46  * The task of the vector animation.
47  */
48 class VectorAnimationTask : public AsyncTask, public ConnectionTracker
49 {
50 public:
51   enum class ResourceStatus
52   {
53     LOADED, /// Resource is loaded
54     READY,  /// Resource is ready
55     FAILED  /// Resource is fail to load
56   };
57
58   using ResourceReadySignalType = Signal<void(ResourceStatus)>;
59
60   using TimePoint           = std::chrono::time_point<std::chrono::steady_clock>;
61   using DynamicPropertyType = std::vector<DevelAnimatedVectorImageVisual::DynamicPropertyInfo>;
62
63   /**
64    * Flags for re-sending data to the vector animation thread
65    */
66   enum ResendFlags
67   {
68     RESEND_PLAY_RANGE          = 1 << 0,
69     RESEND_LOOP_COUNT          = 1 << 1,
70     RESEND_STOP_BEHAVIOR       = 1 << 2,
71     RESEND_LOOPING_MODE        = 1 << 3,
72     RESEND_CURRENT_FRAME       = 1 << 4,
73     RESEND_SIZE                = 1 << 5,
74     RESEND_PLAY_STATE          = 1 << 6,
75     RESEND_NEED_RESOURCE_READY = 1 << 7,
76     RESEND_DYNAMIC_PROPERTY    = 1 << 8
77   };
78
79   /**
80    * @brief Structure used to pass parameters to the vector animation task
81    */
82   struct AnimationData
83   {
84     AnimationData()
85     : resendFlag(0),
86       playRange(),
87       dynamicProperties(),
88       playState(),
89       stopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
90       loopingMode(DevelImageVisual::LoopingMode::RESTART),
91       currentFrame(0),
92       width(0),
93       height(0),
94       loopCount(-1)
95     {
96     }
97
98     AnimationData& operator=(const AnimationData& rhs)
99     {
100       resendFlag |= rhs.resendFlag; // OR resend flag
101       playRange    = rhs.playRange;
102       playState    = rhs.playState;
103       stopBehavior = rhs.stopBehavior;
104       loopingMode  = rhs.loopingMode;
105       currentFrame = rhs.currentFrame;
106       width        = rhs.width;
107       height       = rhs.height;
108       loopCount    = rhs.loopCount;
109       dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end());
110       return *this;
111     }
112
113     uint32_t                             resendFlag;
114     Property::Array                      playRange;
115     DynamicPropertyType                  dynamicProperties;
116     DevelImageVisual::PlayState::Type    playState;
117     DevelImageVisual::StopBehavior::Type stopBehavior;
118     DevelImageVisual::LoopingMode::Type  loopingMode;
119     uint32_t                             currentFrame;
120     uint32_t                             width;
121     uint32_t                             height;
122     int32_t                              loopCount;
123   };
124
125   /**
126    * @brief Constructor.
127    *
128    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
129    */
130   VectorAnimationTask(VisualFactoryCache& factoryCache);
131
132   /**
133    * @brief Destructor.
134    */
135   ~VectorAnimationTask() override;
136
137   /**
138    * Process the task accodring to the type
139    */
140   void Process() override;
141
142   /**
143    * Whether the task is ready to process.
144    * @return True if the task is ready to process.
145    */
146   bool IsReady() override;
147
148   /**
149    * @brief Finalizes the task.
150    */
151   void Finalize();
152
153   /**
154    * @brief Sets the renderer used to display the result image.
155    *
156    * @param[in] renderer The renderer used to display the result image
157    */
158   void SetRenderer(Renderer renderer);
159
160   /**
161    * @brief Requests to load the animation file.
162    *
163    * @param[in] url The url of the vector animation file
164    * @param[in] synchronousLoading True if the url should be loaded synchronously
165    */
166   void RequestLoad(const std::string& url, bool synchronousLoading);
167
168   /**
169    * @brief Queries whether loading is requested.
170    * @return True if loading is requested.
171    */
172   bool IsLoadRequested() const;
173
174   /**
175    * @brief Sets data to specify animation playback.
176    * @param[in] data The animation data
177    */
178   void SetAnimationData(const AnimationData& data);
179
180   /**
181    * @brief This callback is called after the animation is finished.
182    * @param[in] callback The animation finished callback
183    */
184   void SetAnimationFinishedCallback(EventThreadCallback* callback);
185
186   /**
187    * @brief Gets the playing range in frame number.
188    * @param[out] startFrame The frame number to specify minimum progress.
189    * @param[out] endFrame The frame number to specify maximum progress.
190    */
191   void GetPlayRange(uint32_t& startFrame, uint32_t& endFrame);
192
193   /**
194    * @brief Retrieves the current frame number of the animation.
195    * @return The current frame number
196    */
197   uint32_t GetCurrentFrameNumber() const;
198
199   /**
200    * @brief Retrieves the total frame number of the animation.
201    * @return The total frame number
202    */
203   uint32_t GetTotalFrameNumber() const;
204
205   /**
206    * @brief Gets the default size of the file,.
207    * @return The default size of the file
208    */
209   void GetDefaultSize(uint32_t& width, uint32_t& height) const;
210
211   /**
212    * @brief Gets the layer information of all the child layers.
213    * @param[out] map The layer information
214    */
215   void GetLayerInfo(Property::Map& map) const;
216
217   /**
218    * @brief Connect to this signal to be notified when the resource is ready.
219    * @return The signal to connect to.
220    */
221   ResourceReadySignalType& ResourceReadySignal();
222
223   /**
224    * @brief Rasterizes the current frame.
225    * @return true if the rasterization succeeded, false otherwise.
226    */
227   bool Rasterize();
228
229   /**
230    * @brief Calculates the time for the next frame rasterization.
231    * @return The time for the next frame rasterization.
232    */
233   TimePoint CalculateNextFrameTime(bool renderNow);
234
235   /**
236    * @brief Gets the time for the next frame rasterization.
237    * @return The time for the next frame rasterization.
238    */
239   TimePoint GetNextFrameTime();
240
241   /**
242    * @brief Called when the rasterization is completed from the asyncTaskManager
243    * @param[in] task The completed task
244    */
245   void TaskCompleted(VectorAnimationTaskPtr task);
246
247   /**
248    * @brief Check the rasterization succeeded
249    * @return true if the rasterization succeeded, false otherwise.
250    */
251   bool IsRasterized();
252
253   /**
254    * @brief Check the animation is running
255    * @return true if the animation is running, false otherwise.
256    */
257   bool IsAnimating();
258
259 private:
260   /**
261    * @brief Loads the animation file.
262    *
263    * @param[in] synchronousLoading True if loading is requested synchronously
264    * @return True if loading succeeded, false otherwise.
265    */
266   bool Load(bool synchronousLoading);
267
268   /**
269    * @brief Play the vector animation.
270    */
271   void PlayAnimation();
272
273   /**
274    * @brief Stop the vector animation.
275    */
276   void StopAnimation();
277
278   /**
279    * @brief Pause the vector animation.
280    */
281   void PauseAnimation();
282
283   /**
284    * @brief Sets the target image size.
285    *
286    * @param[in] width The target image width
287    * @param[in] height The target image height
288    */
289   void SetSize(uint32_t width, uint32_t height);
290
291   /**
292    * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
293    * @param[in] count The number of times to loop
294    */
295   void SetLoopCount(int32_t count);
296
297   /**
298    * @brief Set the playing range in frame number.
299    * @param[in] playRange The array to specify minimum and maximum progress.
300    * The animation will play between those values.
301    */
302   void SetPlayRange(const Property::Array& playRange);
303
304   /**
305    * @brief Sets the current frame number of the animation.
306    * @param[in] frameNumber The new frame number between [0, the maximum frame number] or between the play range if specified.
307    */
308   void SetCurrentFrameNumber(uint32_t frameNumber);
309
310   /**
311    * @brief Sets the stop behavior of the animation. This is performed when the animation is stopped.
312    * @param[in] stopBehavior The stop behavior
313    */
314   void SetStopBehavior(DevelImageVisual::StopBehavior::Type stopBehavior);
315
316   /**
317    * @brief Sets the looping mode.
318    * Animation plays forwards and then restarts from the beginning or runs backwards again.
319    * @param[in] loopingMode The looping mode
320    */
321   void SetLoopingMode(DevelImageVisual::LoopingMode::Type loopingMode);
322
323   /**
324    * @brief Gets the frame number when the animation is stopped according to the stop behavior.
325    */
326   uint32_t GetStoppedFrame(uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame);
327
328   /**
329    * @brief Applies the animation data set by the main thread.
330    */
331   void ApplyAnimationData();
332
333   /**
334    * @brief Called when the texture upload is completed.
335    */
336   void OnUploadCompleted();
337
338   /**
339    * @brief Event callback from rasterize thread. This is called when the file loading is completed.
340    */
341   void OnLoadCompleted();
342
343   // Undefined
344   VectorAnimationTask(const VectorAnimationTask& task) = delete;
345
346   // Undefined
347   VectorAnimationTask& operator=(const VectorAnimationTask& task) = delete;
348
349 private:
350   enum class PlayState
351   {
352     STOPPING, ///< The animation is stopping
353     STOPPED,  ///< The animation has stopped
354     PLAYING,  ///< The animation is playing
355     PAUSED    ///< The animation is paused
356   };
357
358   std::string                          mUrl;
359   VectorAnimationRenderer              mVectorRenderer;
360   AnimationData                        mAnimationData[2];
361   VectorAnimationThread&               mVectorAnimationThread;
362   ConditionalWait                      mConditionalWait;
363   ResourceReadySignalType              mResourceReadySignal;
364   std::unique_ptr<EventThreadCallback> mAnimationFinishedTrigger;
365   std::unique_ptr<EventThreadCallback> mLoadCompletedTrigger;
366   PlayState                            mPlayState;
367   DevelImageVisual::StopBehavior::Type mStopBehavior;
368   DevelImageVisual::LoopingMode::Type  mLoopingMode;
369   TimePoint                            mNextFrameStartTime;
370   int64_t                              mFrameDurationMicroSeconds;
371   float                                mFrameRate;
372   uint32_t                             mCurrentFrame;
373   uint32_t                             mTotalFrame;
374   uint32_t                             mStartFrame;
375   uint32_t                             mEndFrame;
376   uint32_t                             mDroppedFrames;
377   uint32_t                             mWidth;
378   uint32_t                             mHeight;
379   uint32_t                             mAnimationDataIndex;
380   int32_t                              mLoopCount;
381   int32_t                              mCurrentLoop;
382   bool                                 mForward;
383   bool                                 mUpdateFrameNumber;
384   bool                                 mNeedAnimationFinishedTrigger;
385   bool                                 mAnimationDataUpdated;
386   bool                                 mDestroyTask;
387   bool                                 mLoadRequest;
388   bool                                 mLoadFailed;
389   bool                                 mRasterized;
390   bool                                 mKeepAnimation;
391 };
392
393 } // namespace Internal
394
395 } // namespace Toolkit
396
397 } // namespace Dali
398
399 #endif // DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H