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