(Vector) Flush lottie update informations 60/296160/12
authorEunki Hong <eunkiki.hong@samsung.com>
Thu, 20 Jul 2023 15:49:48 +0000 (00:49 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Mon, 28 Aug 2023 01:23:23 +0000 (01:23 +0000)
Add flush action that we can ensure the values updated forcely.

Change-Id: I9ebd65b006e314e087148826b0e5be6842d3679b
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h

index 6a5a089..732d6b1 100644 (file)
@@ -2126,3 +2126,153 @@ int UtcDaliAnimatedVectorImageVisualDesiredSize(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualFlushAction(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline("UtcDaliAnimatedVectorImageVisualFlushAction");
+
+  int startFrame = 1;
+  int endFrame   = 2;
+
+  int totalFrameCount = 0;
+
+  Property::Array playRange;
+  playRange.PushBack(startFrame);
+  playRange.PushBack(endFrame);
+
+  Property::Map    resultMap;
+  Property::Value* value = nullptr;
+
+  // request AnimatedVectorImageVisual with a property map
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base  visual  = factory.CreateVisual(
+    Property::Map()
+      .Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+      .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+      .Add(DevelImageVisual::Property::PLAY_RANGE, playRange)
+      .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, true));
+
+  DummyControl        dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+  dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+
+  application.GetScene().Add(dummyControl);
+
+  // Retry function to get playrange until expect values comes.
+  auto CheckAndRetryPlayRange = [&](int expectStartFrame, int expectEndFrame, std::vector<std::pair<int, int>> retrialFrames) {
+    int tryCount    = 0;
+    int tryCountMax = 30;
+    while(++tryCount <= tryCountMax)
+    {
+      Property::Map resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+      Property::Value* value = resultMap.Find(DevelImageVisual::Property::PLAY_RANGE, Property::ARRAY);
+      DALI_TEST_CHECK(value);
+
+      Property::Array* result = value->GetArray();
+      DALI_TEST_CHECK(result);
+      DALI_TEST_EQUALS(result->Count(), 2, TEST_LOCATION);
+
+      bool tryAgain = false;
+      for(auto& framePair : retrialFrames)
+      {
+        if(result->GetElementAt(0).Get<int>() == framePair.first && result->GetElementAt(1).Get<int>() == framePair.second)
+        {
+          tryAgain = true;
+          break;
+        }
+      }
+      if(tryAgain)
+      {
+        tet_printf("Retry to get value again! [%d]\n", tryCount);
+        // Dummy sleep 1 second.
+        Test::WaitForEventThreadTrigger(1, 1);
+        continue;
+      }
+
+      DALI_TEST_EQUALS(result->GetElementAt(0).Get<int>(), expectStartFrame, TEST_LOCATION);
+      DALI_TEST_EQUALS(result->GetElementAt(1).Get<int>(), expectEndFrame, TEST_LOCATION);
+      break;
+    }
+    DALI_TEST_CHECK(tryCount <= tryCountMax);
+  };
+
+  tet_printf("Pause lottie first.\n");
+
+  Property::Map attributes;
+  DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes);
+
+  application.SendNotification();
+  application.Render(16);
+
+  do
+  {
+    resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+    value = resultMap.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER, Property::INTEGER);
+    DALI_TEST_CHECK(value);
+    totalFrameCount = value->Get<int>();
+  } while(totalFrameCount == 0);
+
+  // Ensure that vector data sended well.
+  CheckAndRetryPlayRange(startFrame, endFrame, {{0, 0}, {0, totalFrameCount - 1}});
+
+  resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  value = resultMap.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), startFrame, TEST_LOCATION);
+
+  tet_printf("Now logically, range : [%d~%d], current : %d\n", startFrame, endFrame, startFrame);
+
+  int changedStartFrame1 = startFrame + 2;
+  int changedEndFrame1   = endFrame + 2;
+
+  playRange.Clear();
+  playRange.Add(changedStartFrame1);
+  playRange.Add(changedEndFrame1);
+
+  tet_printf("Change play range\n");
+  attributes.Add(DevelImageVisual::Property::PLAY_RANGE, playRange);
+  DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
+
+  tet_printf("Jump to changedEndFrame!\n");
+  DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, changedEndFrame1);
+
+  attributes.Clear();
+  tet_infoline("Flush Action!");
+  tet_printf("Now logically, range : [%d~%d], current : %d\n", changedStartFrame1, changedEndFrame1, changedEndFrame1);
+  DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::FLUSH, attributes);
+
+  int changedStartFrame2 = startFrame + 1;
+  int changedEndFrame2   = endFrame + 1;
+
+  playRange.Clear();
+  playRange.Add(changedStartFrame2);
+  playRange.Add(changedEndFrame2);
+
+  tet_printf("Change play range again\n");
+  tet_printf("Now logically, range : [%d~%d], current : %d\n", changedStartFrame2, changedEndFrame2, changedEndFrame2);
+  attributes.Add(DevelImageVisual::Property::PLAY_RANGE, playRange);
+  DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Ensure that vector data sended well.
+  CheckAndRetryPlayRange(changedStartFrame2, changedEndFrame2, {{changedStartFrame1, changedEndFrame1}, {startFrame, endFrame}});
+
+  resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  tet_printf("Test whether current frame number changed well. If Flush not works, current frame become startFrame.");
+  value = resultMap.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), changedEndFrame2, TEST_LOCATION);
+
+  dummyControl.Unparent();
+
+  END_TEST;
+}
\ No newline at end of file
index a175eb3..b17e79d 100644 (file)
@@ -20,8 +20,8 @@
 
 // EXTERNAL INCLUDES
 #include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
-#include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/animated-image-visual-actions-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali/public-api/signals/callback.h>
 #include <string>
 
@@ -48,7 +48,9 @@ enum Type
   JUMP_TO = DevelAnimatedImageVisual::Action::JUMP_TO, ///< Jump to the specified frame. Property::INTEGER value should be passed.
 
   // AnimatedVectorImageVisual only actions
-  SET_DYNAMIC_PROPERTY = DevelAnimatedImageVisual::Action::ANIMATED_IMAGE_VISUAL_ACTION_END_INDEX ///< Set the dynamic property.
+  SET_DYNAMIC_PROPERTY = DevelAnimatedImageVisual::Action::ANIMATED_IMAGE_VISUAL_ACTION_END_INDEX, ///< Set the dynamic property.
+
+  FLUSH, ///< Flush animation data. It will make ensure that changeness of animated vector image properties flushed.
 };
 
 } // namespace Action
index 8a4ada9..8da0313 100644 (file)
@@ -557,6 +557,14 @@ void AnimatedVectorImageVisual::OnDoAction(const Property::Index actionId, const
       }
       break;
     }
+    case DevelAnimatedVectorImageVisual::Action::FLUSH:
+    {
+      if(DALI_LIKELY(!mCoreShutdown))
+      {
+        SendAnimationData();
+      }
+      break;
+    }
   }
 
   TriggerVectorRasterization();
index c19a440..6bb0d13 100644 (file)
@@ -215,7 +215,7 @@ void VectorAnimationTask::SetAnimationData(const AnimationData& data)
 
   uint32_t index = mAnimationDataIndex == 0 ? 1 : 0; // Use the other buffer
 
-  mAnimationData[index] = data;
+  mAnimationData[index].push_back(data);
   mAnimationDataUpdated = true;
 
   if(data.resendFlag & VectorAnimationTask::RESEND_SIZE)
@@ -660,7 +660,7 @@ void VectorAnimationTask::ApplyAnimationData()
   {
     ConditionalWait::ScopedLock lock(mConditionalWait);
 
-    if(!mAnimationDataUpdated || mAnimationData[mAnimationDataIndex].resendFlag != 0)
+    if(!mAnimationDataUpdated || mAnimationData[mAnimationDataIndex].size() != 0)
     {
       // Data is not updated or the previous data is not applied yet.
       return;
@@ -672,63 +672,65 @@ void VectorAnimationTask::ApplyAnimationData()
     index = mAnimationDataIndex;
   }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOP_COUNT)
+  for(const auto& animationData : mAnimationData[index])
   {
-    SetLoopCount(mAnimationData[index].loopCount);
-  }
-
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_RANGE)
-  {
-    SetPlayRange(mAnimationData[index].playRange);
-  }
-
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_STOP_BEHAVIOR)
-  {
-    SetStopBehavior(mAnimationData[index].stopBehavior);
-  }
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_LOOP_COUNT)
+    {
+      SetLoopCount(animationData.loopCount);
+    }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_LOOPING_MODE)
-  {
-    SetLoopingMode(mAnimationData[index].loopingMode);
-  }
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_PLAY_RANGE)
+    {
+      SetPlayRange(animationData.playRange);
+    }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_CURRENT_FRAME)
-  {
-    SetCurrentFrameNumber(mAnimationData[index].currentFrame);
-  }
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_STOP_BEHAVIOR)
+    {
+      SetStopBehavior(animationData.stopBehavior);
+    }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY)
-  {
-    mVectorRenderer.InvalidateBuffer();
-  }
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_LOOPING_MODE)
+    {
+      SetLoopingMode(animationData.loopingMode);
+    }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_DYNAMIC_PROPERTY)
-  {
-    for(auto&& iter : mAnimationData[index].dynamicProperties)
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_CURRENT_FRAME)
     {
-      mVectorRenderer.AddPropertyValueCallback(iter.keyPath, static_cast<VectorAnimationRenderer::VectorProperty>(iter.property), iter.callback, iter.id);
+      SetCurrentFrameNumber(animationData.currentFrame);
     }
-  }
 
-  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE)
-  {
-    if(mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING)
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY)
     {
-      PlayAnimation();
+      mVectorRenderer.InvalidateBuffer();
     }
-    else if(mAnimationData[index].playState == DevelImageVisual::PlayState::PAUSED)
+
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_DYNAMIC_PROPERTY)
     {
-      PauseAnimation();
+      for(auto&& iter : animationData.dynamicProperties)
+      {
+        mVectorRenderer.AddPropertyValueCallback(iter.keyPath, static_cast<VectorAnimationRenderer::VectorProperty>(iter.property), iter.callback, iter.id);
+      }
     }
-    else if(mAnimationData[index].playState == DevelImageVisual::PlayState::STOPPED)
+
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_PLAY_STATE)
     {
-      StopAnimation();
+      if(animationData.playState == DevelImageVisual::PlayState::PLAYING)
+      {
+        PlayAnimation();
+      }
+      else if(animationData.playState == DevelImageVisual::PlayState::PAUSED)
+      {
+        PauseAnimation();
+      }
+      else if(animationData.playState == DevelImageVisual::PlayState::STOPPED)
+      {
+        StopAnimation();
+      }
     }
   }
 
-  // reset data
-  mAnimationData[index].dynamicProperties.clear();
-  mAnimationData[index].resendFlag = 0;
+  // reset data list
+  mAnimationData[index].clear();
 }
 
 void VectorAnimationTask::OnUploadCompleted()
index e1b80c3..fdf1e2c 100644 (file)
@@ -357,7 +357,7 @@ private:
 
   std::string                          mUrl;
   VectorAnimationRenderer              mVectorRenderer;
-  AnimationData                        mAnimationData[2];
+  std::vector<AnimationData>           mAnimationData[2];
   VectorAnimationThread&               mVectorAnimationThread;
   ConditionalWait                      mConditionalWait;
   ResourceReadySignalType              mResourceReadySignal;