Force call KeepRendering when lottie animation stopped, or frame changed 12/309612/4
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 12 Apr 2024 13:07:07 +0000 (22:07 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 12 Apr 2024 14:34:20 +0000 (23:34 +0900)
Change-Id: Ie9c44a8a3997a644080c934d36e99c8aee804bf2
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h

index 72a4966..08921c9 100644 (file)
@@ -1334,6 +1334,9 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 
   // Wait for animation finish
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  // EventThread will be triggered after animation finished (For render forcibly).
+  // TODO : Is this logic will works well on server-side?
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   // Jump to 3
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
index 9c81c3b..b23f066 100644 (file)
@@ -411,6 +411,7 @@ void AnimatedVectorImageVisual::OnInitialize(void)
 {
   mVectorAnimationTask->ResourceReadySignal().Connect(this, &AnimatedVectorImageVisual::OnResourceReady);
   mVectorAnimationTask->SetAnimationFinishedCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnAnimationFinished));
+  mVectorAnimationTask->SetForceRenderOnceCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnForceRendering));
 
   EncodedImageBuffer encodedImageBuffer;
 
@@ -724,6 +725,14 @@ void AnimatedVectorImageVisual::OnAnimationFinished(uint32_t playStateId)
   }
 }
 
+void AnimatedVectorImageVisual::OnForceRendering(uint32_t playStateId)
+{
+  if(!mCoreShutdown)
+  {
+    Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
+  }
+}
+
 void AnimatedVectorImageVisual::SendAnimationData()
 {
   if(mAnimationData.resendFlag)
index fc7d7a4..7e7b04d 100644 (file)
@@ -188,6 +188,13 @@ private:
   void OnAnimationFinished(uint32_t playStateId);
 
   /**
+   * @brief Event callback from rasterize thread. This is called when we want to ensure rendering next frame.
+   *
+   * @param[in] argument Not using arguments
+   */
+  void OnForceRendering(uint32_t argument);
+
+  /**
    * @brief Send animation data to the rasterize thread.
    */
   void SendAnimationData();
index 4f4e97d..423d3fc 100644 (file)
@@ -98,6 +98,7 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mForward(true),
   mUpdateFrameNumber(false),
   mNeedAnimationFinishedTrigger(true),
+  mNeedForceRenderOnceTrigger(false),
   mAnimationDataUpdated(false),
   mDestroyTask(false),
   mLoadRequest(false),
@@ -138,6 +139,11 @@ void VectorAnimationTask::Finalize()
       mVectorAnimationThread.RemoveEventTriggerCallbacks(mAnimationFinishedCallback.get());
       mAnimationFinishedCallback.reset();
     }
+    if(mForceRenderOnceCallback)
+    {
+      mVectorAnimationThread.RemoveEventTriggerCallbacks(mForceRenderOnceCallback.get());
+      mForceRenderOnceCallback.reset();
+    }
     if(mLoadCompletedCallback)
     {
       mVectorAnimationThread.RemoveEventTriggerCallbacks(mLoadCompletedCallback.get());
@@ -376,6 +382,9 @@ void VectorAnimationTask::PauseAnimation()
   {
     mPlayState = PlayState::PAUSED;
 
+    // Ensure to render paused frame.
+    mNeedForceRenderOnceTrigger = true;
+
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::PauseAnimation: Pause [%p]\n", this);
   }
 }
@@ -386,6 +395,12 @@ void VectorAnimationTask::SetAnimationFinishedCallback(CallbackBase* callback)
   mAnimationFinishedCallback = std::unique_ptr<CallbackBase>(callback);
 }
 
+void VectorAnimationTask::SetForceRenderOnceCallback(CallbackBase* callback)
+{
+  Mutex::ScopedLock lock(mMutex);
+  mForceRenderOnceCallback = std::unique_ptr<CallbackBase>(callback);
+}
+
 void VectorAnimationTask::SetLoopCount(int32_t count)
 {
   if(mLoopCount != count)
@@ -467,10 +482,22 @@ void VectorAnimationTask::SetPlayRange(const Property::Array& playRange)
     if(mStartFrame > mCurrentFrame)
     {
       mCurrentFrame = mStartFrame;
+
+      if(mPlayState != PlayState::PLAYING)
+      {
+        // Ensure to render current frame.
+        mNeedForceRenderOnceTrigger = true;
+      }
     }
     else if(mEndFrame < mCurrentFrame)
     {
       mCurrentFrame = mEndFrame;
+
+      if(mPlayState != PlayState::PLAYING)
+      {
+        // Ensure to render current frame.
+        mNeedForceRenderOnceTrigger = true;
+      }
     }
 
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%s] [%p]\n", mStartFrame, mEndFrame, mImageUrl.GetUrl().c_str(), this);
@@ -496,6 +523,12 @@ void VectorAnimationTask::SetCurrentFrameNumber(uint32_t frameNumber)
     mCurrentFrame      = frameNumber;
     mUpdateFrameNumber = false;
 
+    if(mPlayState != PlayState::PLAYING)
+    {
+      // Ensure to render current frame.
+      mNeedForceRenderOnceTrigger = true;
+    }
+
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: frame number = %d [%p]\n", mCurrentFrame, this);
   }
   else
@@ -693,6 +726,8 @@ bool VectorAnimationTask::Rasterize()
     mForward     = true;
     mCurrentLoop = 0;
 
+    mNeedForceRenderOnceTrigger = true;
+
     if(mVectorRenderer)
     {
       // Notify the Renderer that rendering is stopped.
@@ -711,6 +746,17 @@ bool VectorAnimationTask::Rasterize()
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this);
   }
 
+  // Forcely trigger render once if need.
+  if(mNeedForceRenderOnceTrigger)
+  {
+    Mutex::ScopedLock lock(mMutex);
+    if(mForceRenderOnceCallback)
+    {
+      mVectorAnimationThread.AddEventTriggerCallback(mForceRenderOnceCallback.get(), mAppliedPlayStateId);
+    }
+    mNeedForceRenderOnceTrigger = false;
+  }
+
   if(mPlayState != PlayState::PAUSED && mPlayState != PlayState::STOPPED)
   {
     mKeepAnimation = true;
index eb48a13..46976a5 100644 (file)
@@ -179,6 +179,12 @@ public:
   void SetAnimationFinishedCallback(CallbackBase* callback);
 
   /**
+   * @brief This callback is called when we want to force render next frame.
+   * @param[in] callback The force render once callback
+   */
+  void SetForceRenderOnceCallback(CallbackBase* callback);
+
+  /**
    * @brief Gets the playing range in frame number.
    * @param[out] startFrame The frame number to specify minimum progress.
    * @param[out] endFrame The frame number to specify maximum progress.
@@ -393,6 +399,7 @@ private:
   Mutex                                mMutex;
   ResourceReadySignalType              mResourceReadySignal;
   std::unique_ptr<CallbackBase>        mAnimationFinishedCallback{};
+  std::unique_ptr<CallbackBase>        mForceRenderOnceCallback{};
   std::unique_ptr<CallbackBase>        mLoadCompletedCallback{};
   mutable Property::Map                mCachedLayerInfo;
   mutable Property::Map                mCachedMarkerInfo;
@@ -416,6 +423,7 @@ private:
   bool                                 mForward : 1;
   bool                                 mUpdateFrameNumber : 1;
   bool                                 mNeedAnimationFinishedTrigger : 1;
+  bool                                 mNeedForceRenderOnceTrigger : 1;
   bool                                 mAnimationDataUpdated : 1;
   bool                                 mDestroyTask : 1;
   bool                                 mLoadRequest : 1;