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