(Vector) Fix deadlock issue: remove lock
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-vector-image / vector-animation-task.cpp
index c229a99..3966d0c 100644 (file)
@@ -37,7 +37,7 @@ namespace Internal
 namespace
 {
 constexpr auto LOOP_FOREVER = -1;
-constexpr auto NANOSECONDS_PER_SECOND(1e+9);
+constexpr auto MICROSECONDS_PER_SECOND(1e+6);
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_VECTOR_ANIMATION");
@@ -45,9 +45,9 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging,
 
 } // unnamed namespace
 
-VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache, const std::string& url)
-: mUrl(url),
-  mVectorRenderer(),
+VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
+: mUrl(),
+  mVectorRenderer(VectorAnimationRenderer::New()),
   mAnimationData(),
   mVectorAnimationThread(factoryCache.GetVectorAnimationManager().GetVectorAnimationThread()),
   mConditionalWait(),
@@ -56,12 +56,13 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache, const
   mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
   mLoopingMode(DevelImageVisual::LoopingMode::RESTART),
   mNextFrameStartTime(),
-  mFrameDurationNanoSeconds(0),
+  mFrameDurationMicroSeconds(MICROSECONDS_PER_SECOND / 60.0f),
   mFrameRate(60.0f),
   mCurrentFrame(0),
   mTotalFrame(0),
   mStartFrame(0),
   mEndFrame(0),
+  mDroppedFrames(0),
   mWidth(0),
   mHeight(0),
   mAnimationDataIndex(0),
@@ -73,7 +74,6 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache, const
   mAnimationDataUpdated(false),
   mDestroyTask(false)
 {
-  Initialize();
 }
 
 VectorAnimationTask::~VectorAnimationTask()
@@ -96,6 +96,33 @@ void VectorAnimationTask::Finalize()
   mDestroyTask = true;
 }
 
+bool VectorAnimationTask::Load(const std::string& url)
+{
+  mUrl = url;
+
+  if(!mVectorRenderer.Load(mUrl))
+  {
+    DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mUrl.c_str());
+    return false;
+  }
+
+  mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
+
+  mEndFrame = mTotalFrame - 1;
+
+  mFrameRate                 = mVectorRenderer.GetFrameRate();
+  mFrameDurationMicroSeconds = MICROSECONDS_PER_SECOND / mFrameRate;
+
+  uint32_t width, height;
+  mVectorRenderer.GetDefaultSize(width, height);
+
+  SetSize(width, height);
+
+  DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Load: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this);
+
+  return true;
+}
+
 void VectorAnimationTask::SetRenderer(Renderer renderer)
 {
   ConditionalWait::ScopedLock lock(mConditionalWait);
@@ -343,25 +370,6 @@ VectorAnimationTask::UploadCompletedSignalType& VectorAnimationTask::UploadCompl
   return mVectorRenderer.UploadCompletedSignal();
 }
 
-void VectorAnimationTask::Initialize()
-{
-  mVectorRenderer = VectorAnimationRenderer::New(mUrl);
-
-  mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
-
-  mEndFrame = mTotalFrame - 1;
-
-  mFrameRate                = mVectorRenderer.GetFrameRate();
-  mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate;
-
-  uint32_t width, height;
-  mVectorRenderer.GetDefaultSize(width, height);
-
-  SetSize(width, height);
-
-  DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Initialize: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this);
-}
-
 bool VectorAnimationTask::Rasterize()
 {
   bool     stopped = false;
@@ -380,7 +388,7 @@ bool VectorAnimationTask::Rasterize()
 
   if(mPlayState == PlayState::PLAYING && mUpdateFrameNumber)
   {
-    mCurrentFrame = mForward ? mCurrentFrame + 1 : mCurrentFrame - 1;
+    mCurrentFrame = mForward ? mCurrentFrame + mDroppedFrames + 1 : mCurrentFrame - mDroppedFrames - 1;
     Dali::ClampInPlace(mCurrentFrame, mStartFrame, mEndFrame);
   }
 
@@ -514,22 +522,36 @@ uint32_t VectorAnimationTask::GetStoppedFrame(uint32_t startFrame, uint32_t endF
   return frame;
 }
 
-std::chrono::time_point<std::chrono::system_clock> VectorAnimationTask::CalculateNextFrameTime(bool renderNow)
+VectorAnimationTask::TimePoint VectorAnimationTask::CalculateNextFrameTime(bool renderNow)
 {
   // std::chrono::time_point template has second parameter duration which defaults to the std::chrono::system_clock supported
   // duration. In some C++11 implementations it is a milliseconds duration, so it fails to compile unless mNextFrameStartTime
   // is casted to use the default duration.
-  mNextFrameStartTime = std::chrono::time_point_cast<std::chrono::time_point<std::chrono::system_clock>::duration>(
-    mNextFrameStartTime + std::chrono::nanoseconds(mFrameDurationNanoSeconds));
-  auto current = std::chrono::system_clock::now();
-  if(renderNow || mNextFrameStartTime < current)
+  mNextFrameStartTime = std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds));
+  auto current        = std::chrono::system_clock::now();
+  if(renderNow)
+  {
+    mNextFrameStartTime = current;
+    mDroppedFrames      = 0;
+  }
+  else if(mNextFrameStartTime < current)
   {
+    uint32_t droppedFrames = 0;
+
+    while(current > std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds)))
+    {
+      droppedFrames++;
+      mNextFrameStartTime = std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds));
+    }
+
     mNextFrameStartTime = current;
+    mDroppedFrames      = droppedFrames;
   }
+
   return mNextFrameStartTime;
 }
 
-std::chrono::time_point<std::chrono::system_clock> VectorAnimationTask::GetNextFrameTime()
+VectorAnimationTask::TimePoint VectorAnimationTask::GetNextFrameTime()
 {
   return mNextFrameStartTime;
 }