#define DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
-#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/property-array.h>
#include <chrono>
#include <memory>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
namespace Dali
{
/**
* The task of the vector animation.
*/
-class VectorAnimationTask : public RefObject
+class VectorAnimationTask : public AsyncTask, public ConnectionTracker
{
public:
- using UploadCompletedSignalType = Dali::VectorAnimationRenderer::UploadCompletedSignalType;
+ enum class ResourceStatus
+ {
+ LOADED, /// Resource is loaded
+ READY, /// Resource is ready
+ FAILED /// Resource is fail to load
+ };
- using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+ using ResourceReadySignalType = Signal<void(ResourceStatus)>;
+
+ using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+ using DynamicPropertyType = std::vector<DevelAnimatedVectorImageVisual::DynamicPropertyInfo>;
/**
* Flags for re-sending data to the vector animation thread
*/
enum ResendFlags
{
- RESEND_PLAY_RANGE = 1 << 0,
- RESEND_LOOP_COUNT = 1 << 1,
- RESEND_STOP_BEHAVIOR = 1 << 2,
- RESEND_LOOPING_MODE = 1 << 3,
- RESEND_CURRENT_FRAME = 1 << 4,
- RESEND_SIZE = 1 << 5,
- RESEND_PLAY_STATE = 1 << 6
+ RESEND_PLAY_RANGE = 1 << 0,
+ RESEND_LOOP_COUNT = 1 << 1,
+ RESEND_STOP_BEHAVIOR = 1 << 2,
+ RESEND_LOOPING_MODE = 1 << 3,
+ RESEND_CURRENT_FRAME = 1 << 4,
+ RESEND_SIZE = 1 << 5,
+ RESEND_PLAY_STATE = 1 << 6,
+ RESEND_NEED_RESOURCE_READY = 1 << 7,
+ RESEND_DYNAMIC_PROPERTY = 1 << 8,
+ RESEND_NOTIFY_AFTER_RASTERIZATION = 1 << 9,
};
/**
AnimationData()
: resendFlag(0),
playRange(),
+ dynamicProperties(),
playState(),
stopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
loopingMode(DevelImageVisual::LoopingMode::RESTART),
currentFrame(0),
width(0),
height(0),
- loopCount(-1)
+ loopCount(-1),
+ playStateId(0),
+ notifyAfterRasterization(false)
{
}
AnimationData& operator=(const AnimationData& rhs)
{
resendFlag |= rhs.resendFlag; // OR resend flag
- playRange = rhs.playRange;
- playState = rhs.playState;
- stopBehavior = rhs.stopBehavior;
- loopingMode = rhs.loopingMode;
- currentFrame = rhs.currentFrame;
- width = rhs.width;
- height = rhs.height;
- loopCount = rhs.loopCount;
+ playRange = rhs.playRange;
+ playState = rhs.playState;
+ stopBehavior = rhs.stopBehavior;
+ loopingMode = rhs.loopingMode;
+ currentFrame = rhs.currentFrame;
+ width = rhs.width;
+ height = rhs.height;
+ loopCount = rhs.loopCount;
+ playStateId = rhs.playStateId;
+ notifyAfterRasterization = rhs.notifyAfterRasterization;
+ dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end());
return *this;
}
uint32_t resendFlag;
Property::Array playRange;
+ DynamicPropertyType dynamicProperties;
DevelImageVisual::PlayState::Type playState;
DevelImageVisual::StopBehavior::Type stopBehavior;
DevelImageVisual::LoopingMode::Type loopingMode;
uint32_t width;
uint32_t height;
int32_t loopCount;
+ uint32_t playStateId;
+ bool notifyAfterRasterization;
};
/**
void Finalize();
/**
- * @brief Loads the animation file.
+ * @brief Sets the renderer used to display the result image.
*
- * @param[in] url The url of the vector animation file
- * @return True if loading success, false otherwise.
+ * @param[in] renderer The renderer used to display the result image
*/
- bool Load(const std::string& url);
+ void SetRenderer(Renderer renderer);
/**
- * @brief Sets the renderer used to display the result image.
+ * @brief Requests to load the animation file.
*
- * @param[in] renderer The renderer used to display the result image
+ * @param[in] url The url of the vector animation file
+ * @param[in] encodedImageBuffer The resource buffer if required.
+ * @param[in] synchronousLoading True if the url should be loaded synchronously
*/
- void SetRenderer(Renderer renderer);
+ void RequestLoad(const VisualUrl& url, EncodedImageBuffer encodedImageBuffer, bool synchronousLoading);
+
+ /**
+ * @brief Queries whether loading is requested.
+ * @return True if loading is requested.
+ */
+ bool IsLoadRequested() const;
/**
* @brief Sets data to specify animation playback.
* @brief This callback is called after the animation is finished.
* @param[in] callback The animation finished callback
*/
- void SetAnimationFinishedCallback(EventThreadCallback* callback);
+ void SetAnimationFinishedCallback(CallbackBase* callback);
/**
* @brief Gets the playing range in frame number.
void GetLayerInfo(Property::Map& map) const;
/**
- * @brief Connect to this signal to be notified when the texture upload is completed.
+ * @brief Gets the all marker information.
+ * @param[out] map The marker information
+ */
+ void GetMarkerInfo(Property::Map& map) const;
+
+ /**
+ * @brief Connect to this signal to be notified when the resource is ready.
* @return The signal to connect to.
*/
- UploadCompletedSignalType& UploadCompletedSignal();
+ ResourceReadySignalType& ResourceReadySignal();
/**
* @brief Rasterizes the current frame.
- * @return true if the animation is running, false otherwise.
+ * @return true if the rasterization succeeded, false otherwise.
*/
bool Rasterize();
*/
TimePoint GetNextFrameTime();
+ /**
+ * @brief Called when the rasterization is completed from the asyncTaskManager
+ * @param[in] task The completed task
+ */
+ void TaskCompleted(VectorAnimationTaskPtr task);
+
+ /**
+ * @brief Check the rasterization succeeded
+ * @return true if the rasterization succeeded, false otherwise.
+ */
+ bool IsRasterized();
+
+ /**
+ * @brief Check the animation is running
+ * @return true if the animation is running, false otherwise.
+ */
+ bool IsAnimating();
+
+ void KeepRasterizedBuffer(bool enableFrameCache)
+ {
+ mEnableFrameCache = enableFrameCache;
+ }
+
+ bool IsKeptRasterizedBuffer() const
+ {
+ return mEnableFrameCache;
+ }
+
+public: // Implementation of AsyncTask
+ /**
+ * @copydoc Dali::AsyncTask::Process()
+ */
+ void Process() override;
+
+ /**
+ * @copydoc Dali::AsyncTask::IsReady()
+ */
+ bool IsReady() override;
+
+ /**
+ * @copydoc Dali::AsyncTask::GetTaskName()
+ */
+ std::string_view GetTaskName() const override
+ {
+ return "VectorAnimationTask";
+ }
+
private:
/**
+ * @brief Loads the animation file.
+ *
+ * @param[in] synchronousLoading True if loading is requested synchronously
+ * @return True if loading succeeded, false otherwise.
+ */
+ bool Load(bool synchronousLoading);
+
+ /**
* @brief Play the vector animation.
*/
void PlayAnimation();
*/
void ApplyAnimationData();
+ /**
+ * @brief Called when the texture upload is completed.
+ */
+ void OnUploadCompleted();
+
+ /**
+ * @brief Event callback from rasterize thread. This is called when the file loading is completed.
+ */
+ void OnLoadCompleted(uint32_t argument);
+
// Undefined
VectorAnimationTask(const VectorAnimationTask& task) = delete;
PAUSED ///< The animation is paused
};
- std::string mUrl;
+ VisualUrl mImageUrl;
+ EncodedImageBuffer mEncodedImageBuffer;
VectorAnimationRenderer mVectorRenderer;
- AnimationData mAnimationData[2];
+ std::vector<AnimationData> mAnimationData[2];
VectorAnimationThread& mVectorAnimationThread;
- ConditionalWait mConditionalWait;
- std::unique_ptr<EventThreadCallback> mAnimationFinishedTrigger;
+ Mutex mMutex;
+ ResourceReadySignalType mResourceReadySignal;
+ std::unique_ptr<CallbackBase> mAnimationFinishedCallback{};
+ std::unique_ptr<CallbackBase> mLoadCompletedCallback{};
+ mutable Property::Map mCachedLayerInfo;
+ mutable Property::Map mCachedMarkerInfo;
PlayState mPlayState;
DevelImageVisual::StopBehavior::Type mStopBehavior;
DevelImageVisual::LoopingMode::Type mLoopingMode;
uint32_t mWidth;
uint32_t mHeight;
uint32_t mAnimationDataIndex;
+ uint32_t mAppliedPlayStateId;
int32_t mLoopCount;
int32_t mCurrentLoop;
- bool mForward;
- bool mUpdateFrameNumber;
- bool mNeedAnimationFinishedTrigger;
- bool mAnimationDataUpdated;
- bool mDestroyTask;
+ bool mForward : 1;
+ bool mUpdateFrameNumber : 1;
+ bool mNeedAnimationFinishedTrigger : 1;
+ bool mNeedForceRenderOnceTrigger : 1;
+ bool mAnimationDataUpdated : 1;
+ bool mDestroyTask : 1;
+ bool mLoadRequest : 1;
+ bool mLoadFailed : 1;
+ bool mRasterized : 1;
+ bool mKeepAnimation : 1;
+ mutable bool mLayerInfoCached : 1;
+ mutable bool mMarkerInfoCached : 1;
+ bool mEnableFrameCache : 1;
+ bool mNotifyAfterRasterization : 1;
+ bool mSizeUpdated : 1;
};
} // namespace Internal