(Partial Update) Fix animation delay issue 72/294572/1
authorHeeyong Song <heeyong.song@samsung.com>
Wed, 21 Jun 2023 08:49:07 +0000 (17:49 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Wed, 21 Jun 2023 08:49:07 +0000 (17:49 +0900)
Set updated flag when the animator is changed to the delayed state

Change-Id: I83bc23f19c7ca255f1c7e670c1afe306919b4e8c

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animator.h

index 5e275f8..e1519f5 100644 (file)
@@ -9656,7 +9656,7 @@ int utcDaliActorPartialUpdateActorsWithSizeHint03(void)
   END_TEST;
 }
 
-int utcDaliActorPartialUpdateAnimation(void)
+int utcDaliActorPartialUpdateAnimation01(void)
 {
   TestApplication application(
     TestApplication::DEFAULT_SURFACE_WIDTH,
@@ -9768,6 +9768,90 @@ int utcDaliActorPartialUpdateAnimation(void)
   END_TEST;
 }
 
+int utcDaliActorPartialUpdateAnimation02(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  tet_infoline("Check the damaged area with partial update and animation delay");
+
+  TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace();
+  drawTrace.Enable(true);
+  drawTrace.Reset();
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  application.GetScene().Add(actor);
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  clippingRect = Rect<int>(0, 784, 32, 32); // in screen coordinates, includes 1 last frames updates
+  DirtyRectChecker(damagedRects, {clippingRect}, true, TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Make an animation
+  Renderer  renderer  = actor.GetRendererAt(0);
+  Animation animation = Animation::New(1.0f);
+  animation.AnimateTo(Property(renderer, DevelRenderer::Property::OPACITY), 0.5f, TimePeriod(0.5f, 0.5f));
+  animation.SetLoopCount(3);
+  animation.Play();
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Delay time
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  clippingRect = Rect<int>(0, 784, 32, 32);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Started animation
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(500, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Delay time
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(500, nullptr, damagedRects);
+
+  // The property is reset to base value. Should be updated
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Next render during delay time
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(50, nullptr, damagedRects);
+
+  // Should not be updated
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  END_TEST;
+}
+
 int utcDaliActorPartialUpdateChangeVisibility(void)
 {
   TestApplication application(
index a6eae4b..8955f07 100644 (file)
@@ -632,7 +632,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
               // If the item refers to updated node or renderer.
               if(item.mIsUpdated ||
                  (item.mNode &&
-                  (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated(mImpl->renderBufferIndex)))))
+                  (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated()))))
               {
                 item.mIsUpdated = false;
 
index d3e18fe..56dbcc6 100644 (file)
@@ -938,7 +938,7 @@ void Renderer::SetShaderChanged(bool value)
   mShaderChanged = value;
 }
 
-bool Renderer::Updated(BufferIndex bufferIndex)
+bool Renderer::Updated()
 {
   if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged() || mRenderDataProvider->IsUpdated())
   {
index 0b06354..1f4aa6e 100644 (file)
@@ -468,10 +468,8 @@ public:
 
   /**
    * Check if the renderer attributes/uniforms are updated and returns the flag
-   *
-   * @param[in] bufferIndex The current update buffer index.
    */
-  bool Updated(BufferIndex bufferIndex);
+  bool Updated();
 
   template<class T>
   bool WriteDefaultUniform(const Graphics::UniformInfo* uniformInfo,
index 31a3e0a..75551c6 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/internal/common/memory-pool-object-allocator.h>
 #include <dali/internal/render/common/performance-monitor.h>
 #include <dali/public-api/math/math-utils.h>
+
 namespace // Unnamed namespace
 {
 // Memory pool used to allocate new animations. Memory used by this pool will be released when shutting down DALi
@@ -488,6 +489,10 @@ void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animati
           mIsActive[bufferIndex] = true;
         }
       }
+      else
+      {
+        animator->SetDelayed(true);
+      }
       applied = true;
     }
     else
index f761b50..108446c 100644 (file)
@@ -88,7 +88,8 @@ public:
     mAnimationPlaying(false),
     mEnabled(true),
     mConnectedToSceneGraph(false),
-    mAutoReverseEnabled(false)
+    mAutoReverseEnabled(false),
+    mDelayed(false)
   {
   }
 
@@ -237,6 +238,22 @@ public:
   }
 
   /**
+   * Sets whether the animator is delayed or not.
+   * @param delayed True if the animator is delayed.
+   */
+  void SetDelayed(bool delayed)
+  {
+    if(delayed != mDelayed)
+    {
+      if(mPropertyOwner)
+      {
+        mPropertyOwner->SetUpdated(true);
+      }
+      mDelayed = delayed;
+    }
+  }
+
+  /**
    * Set the alpha function for an animator.
    * @param [in] alphaFunc The alpha function to apply to the animation progress.
    */
@@ -469,6 +486,7 @@ public:
     DoUpdate(bufferIndex, bake, alpha, blendPoint);
 
     mCurrentProgress = progress;
+    mDelayed         = false;
   }
 
   /**
@@ -510,6 +528,7 @@ protected:
   bool                       mEnabled : 1;               ///< Animator is "enabled" while its target object is valid and on the stage.
   bool                       mConnectedToSceneGraph : 1; ///< True if ConnectToSceneGraph() has been called in update-thread.
   bool                       mAutoReverseEnabled : 1;
+  bool                       mDelayed : 1; ///< True if the animator is in delayed state
 };
 
 /**
@@ -663,8 +682,8 @@ private:
   }
 
   // Undefined
-  AnimatorTransformProperty()                                            = delete;
-  AnimatorTransformProperty(const AnimatorTransformProperty&)            = delete;
+  AnimatorTransformProperty()                                 = delete;
+  AnimatorTransformProperty(const AnimatorTransformProperty&) = delete;
   AnimatorTransformProperty& operator=(const AnimatorTransformProperty&) = delete;
 
 protected: