Merge "Add imgSrc to GetAttribute return map if available" 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) 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       playStateId(0)
98     {
99     }
100
101     AnimationData& operator=(const AnimationData& rhs)
102     {
103       resendFlag |= rhs.resendFlag; // OR resend flag
104       playRange    = rhs.playRange;
105       playState    = rhs.playState;
106       stopBehavior = rhs.stopBehavior;
107       loopingMode  = rhs.loopingMode;
108       currentFrame = rhs.currentFrame;
109       width        = rhs.width;
110       height       = rhs.height;
111       loopCount    = rhs.loopCount;
112       playStateId  = rhs.playStateId;
113       dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end());
114       return *this;
115     }
116
117     uint32_t                             resendFlag;
118     Property::Array                      playRange;
119     DynamicPropertyType                  dynamicProperties;
120     DevelImageVisual::PlayState::Type    playState;
121     DevelImageVisual::StopBehavior::Type stopBehavior;
122     DevelImageVisual::LoopingMode::Type  loopingMode;
123     uint32_t                             currentFrame;
124     uint32_t                             width;
125     uint32_t                             height;
126     int32_t                              loopCount;
127     uint32_t                             playStateId;
128   };
129
130   /**
131    * @brief Constructor.
132    *
133    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
134    */
135   VectorAnimationTask(VisualFactoryCache& factoryCache);
136
137   /**
138    * @brief Destructor.
139    */
140   ~VectorAnimationTask() override;
141
142   /**
143    * @brief Finalizes the task.
144    */
145   void Finalize();
146
147   /**
148    * @brief Sets the renderer used to display the result image.
149    *
150    * @param[in] renderer The renderer used to display the result image
151    */
152   void SetRenderer(Renderer renderer);
153
154   /**
155    * @brief Requests to load the animation file.
156    *
157    * @param[in] url The url of the vector animation file
158    * @param[in] encodedImageBuffer The resource buffer if required.
159    * @param[in] synchronousLoading True if the url should be loaded synchronously
160    */
161   void RequestLoad(const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, bool synchronousLoading);
162
163   /**
164    * @brief Queries whether loading is requested.
165    * @return True if loading is requested.
166    */
167   bool IsLoadRequested() const;
168
169   /**
170    * @brief Sets data to specify animation playback.
171    * @param[in] data The animation data
172    */
173   void SetAnimationData(const AnimationData& data);
174
175   /**
176    * @brief This callback is called after the animation is finished.
177    * @param[in] callback The animation finished callback
178    */
179   void SetAnimationFinishedCallback(CallbackBase* callback);
180
181   /**
182    * @brief This callback is called when we want to force render next frame.
183    * @param[in] callback The force render once callback
184    */
185   void SetForceRenderOnceCallback(CallbackBase* callback);
186
187   /**
188    * @brief Gets the playing range in frame number.
189    * @param[out] startFrame The frame number to specify minimum progress.
190    * @param[out] endFrame The frame number to specify maximum progress.
191    */
192   void GetPlayRange(uint32_t& startFrame, uint32_t& endFrame);
193
194   /**
195    * @brief Retrieves the current frame number of the animation.
196    * @return The current frame number
197    */
198   uint32_t GetCurrentFrameNumber() const;
199
200   /**
201    * @brief Retrieves the total frame number of the animation.
202    * @return The total frame number
203    */
204   uint32_t GetTotalFrameNumber() const;
205
206   /**
207    * @brief Gets the default size of the file,.
208    * @return The default size of the file
209    */
210   void GetDefaultSize(uint32_t& width, uint32_t& height) const;
211
212   /**
213    * @brief Gets the layer information of all the child layers.
214    * @param[out] map The layer information
215    */
216   void GetLayerInfo(Property::Map& map) const;
217
218   /**
219    * @brief Gets the all marker information.
220    * @param[out] map The marker information
221    */
222   void GetMarkerInfo(Property::Map& map) const;
223
224   /**
225    * @brief Connect to this signal to be notified when the resource is ready.
226    * @return The signal to connect to.
227    */
228   ResourceReadySignalType& ResourceReadySignal();
229
230   /**
231    * @brief Rasterizes the current frame.
232    * @return true if the rasterization succeeded, false otherwise.
233    */
234   bool Rasterize();
235
236   /**
237    * @brief Calculates the time for the next frame rasterization.
238    * @return The time for the next frame rasterization.
239    */
240   TimePoint CalculateNextFrameTime(bool renderNow);
241
242   /**
243    * @brief Gets the time for the next frame rasterization.
244    * @return The time for the next frame rasterization.
245    */
246   TimePoint GetNextFrameTime();
247
248   /**
249    * @brief Called when the rasterization is completed from the asyncTaskManager
250    * @param[in] task The completed task
251    */
252   void TaskCompleted(VectorAnimationTaskPtr task);
253
254   /**
255    * @brief Check the rasterization succeeded
256    * @return true if the rasterization succeeded, false otherwise.
257    */
258   bool IsRasterized();
259
260   /**
261    * @brief Check the animation is running
262    * @return true if the animation is running, false otherwise.
263    */
264   bool IsAnimating();
265
266 public: // Implementation of AsyncTask
267   /**
268    * @copydoc Dali::AsyncTask::Process()
269    */
270   void Process() override;
271
272   /**
273    * @copydoc Dali::AsyncTask::IsReady()
274    */
275   bool IsReady() override;
276
277   /**
278    * @copydoc Dali::AsyncTask::GetTaskName()
279    */
280   std::string_view GetTaskName() const override
281   {
282     return "VectorAnimationTask";
283   }
284
285   void KeepRasterizedBuffer(bool enableFrameCache)
286   {
287     mEnableFrameCache = enableFrameCache;
288   }
289
290   bool IsKeptRasterizedBuffer()
291   {
292     return mEnableFrameCache;
293   }
294
295 private:
296   /**
297    * @brief Loads the animation file.
298    *
299    * @param[in] synchronousLoading True if loading is requested synchronously
300    * @return True if loading succeeded, false otherwise.
301    */
302   bool Load(bool synchronousLoading);
303
304   /**
305    * @brief Play the vector animation.
306    */
307   void PlayAnimation();
308
309   /**
310    * @brief Stop the vector animation.
311    */
312   void StopAnimation();
313
314   /**
315    * @brief Pause the vector animation.
316    */
317   void PauseAnimation();
318
319   /**
320    * @brief Sets the target image size.
321    *
322    * @param[in] width The target image width
323    * @param[in] height The target image height
324    */
325   void SetSize(uint32_t width, uint32_t height);
326
327   /**
328    * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
329    * @param[in] count The number of times to loop
330    */
331   void SetLoopCount(int32_t count);
332
333   /**
334    * @brief Set the playing range in frame number.
335    * @param[in] playRange The array to specify minimum and maximum progress.
336    * The animation will play between those values.
337    */
338   void SetPlayRange(const Property::Array& playRange);
339
340   /**
341    * @brief Sets the current frame number of the animation.
342    * @param[in] frameNumber The new frame number between [0, the maximum frame number] or between the play range if specified.
343    */
344   void SetCurrentFrameNumber(uint32_t frameNumber);
345
346   /**
347    * @brief Sets the stop behavior of the animation. This is performed when the animation is stopped.
348    * @param[in] stopBehavior The stop behavior
349    */
350   void SetStopBehavior(DevelImageVisual::StopBehavior::Type stopBehavior);
351
352   /**
353    * @brief Sets the looping mode.
354    * Animation plays forwards and then restarts from the beginning or runs backwards again.
355    * @param[in] loopingMode The looping mode
356    */
357   void SetLoopingMode(DevelImageVisual::LoopingMode::Type loopingMode);
358
359   /**
360    * @brief Gets the frame number when the animation is stopped according to the stop behavior.
361    */
362   uint32_t GetStoppedFrame(uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame);
363
364   /**
365    * @brief Applies the animation data set by the main thread.
366    */
367   void ApplyAnimationData();
368
369   /**
370    * @brief Called when the texture upload is completed.
371    */
372   void OnUploadCompleted();
373
374   /**
375    * @brief Event callback from rasterize thread. This is called when the file loading is completed.
376    */
377   void OnLoadCompleted(uint32_t argument);
378
379   // Undefined
380   VectorAnimationTask(const VectorAnimationTask& task) = delete;
381
382   // Undefined
383   VectorAnimationTask& operator=(const VectorAnimationTask& task) = delete;
384
385 private:
386   enum class PlayState
387   {
388     STOPPING, ///< The animation is stopping
389     STOPPED,  ///< The animation has stopped
390     PLAYING,  ///< The animation is playing
391     PAUSED    ///< The animation is paused
392   };
393
394   VisualUrl                            mImageUrl;
395   EncodedImageBuffer                   mEncodedImageBuffer;
396   VectorAnimationRenderer              mVectorRenderer;
397   std::vector<AnimationData>           mAnimationData[2];
398   VectorAnimationThread&               mVectorAnimationThread;
399   Mutex                                mMutex;
400   ResourceReadySignalType              mResourceReadySignal;
401   std::unique_ptr<CallbackBase>        mAnimationFinishedCallback{};
402   std::unique_ptr<CallbackBase>        mForceRenderOnceCallback{};
403   std::unique_ptr<CallbackBase>        mLoadCompletedCallback{};
404   mutable Property::Map                mCachedLayerInfo;
405   mutable Property::Map                mCachedMarkerInfo;
406   PlayState                            mPlayState;
407   DevelImageVisual::StopBehavior::Type mStopBehavior;
408   DevelImageVisual::LoopingMode::Type  mLoopingMode;
409   TimePoint                            mNextFrameStartTime;
410   int64_t                              mFrameDurationMicroSeconds;
411   float                                mFrameRate;
412   uint32_t                             mCurrentFrame;
413   uint32_t                             mTotalFrame;
414   uint32_t                             mStartFrame;
415   uint32_t                             mEndFrame;
416   uint32_t                             mDroppedFrames;
417   uint32_t                             mWidth;
418   uint32_t                             mHeight;
419   uint32_t                             mAnimationDataIndex;
420   uint32_t                             mAppliedPlayStateId;
421   int32_t                              mLoopCount;
422   int32_t                              mCurrentLoop;
423   bool                                 mForward : 1;
424   bool                                 mUpdateFrameNumber : 1;
425   bool                                 mNeedAnimationFinishedTrigger : 1;
426   bool                                 mNeedForceRenderOnceTrigger : 1;
427   bool                                 mAnimationDataUpdated : 1;
428   bool                                 mDestroyTask : 1;
429   bool                                 mLoadRequest : 1;
430   bool                                 mLoadFailed : 1;
431   bool                                 mRasterized : 1;
432   bool                                 mKeepAnimation : 1;
433   mutable bool                         mLayerInfoCached : 1;
434   mutable bool                         mMarkerInfoCached : 1;
435   bool                                 mEnableFrameCache : 1;
436   bool                                 mSizeUpdated : 1;
437 };
438
439 } // namespace Internal
440
441 } // namespace Toolkit
442
443 } // namespace Dali
444
445 #endif // DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H