[Tizen] Make bake flag dont change set dirty flag 43/315443/2 accepted/tizen/8.0/unified/20240802.160846
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 25 Jul 2024 07:26:31 +0000 (16:26 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 1 Aug 2024 03:53:48 +0000 (12:53 +0900)
Since we can bake componet side, it may have problem
if component property baked, and full property is set.

In this case, property call reset to base value only 1 times.
So it will show flickering.

To fix this issue, let we make mDirtyFlag |= BAKED_FLAG instead of
mDirtyFlag = BAKED_FLAG

Change-Id: I7269ac79ab1ec7796f62eaea438ee47dd104e963
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-Animation.cpp
dali/internal/update/common/animatable-property.h
dali/internal/update/rendering/scene-graph-visual-renderer-property.h

index 137c5d0fb3f1fac1699709823ffe8173d148747f..79855870fe319dc7fd39acb3603f2d36249935d3 100644 (file)
@@ -21,6 +21,7 @@
 #include <dali/devel-api/animation/key-frames-devel.h>
 #include <dali/devel-api/threading/thread.h>
 #include <dali/public-api/dali-core.h>
+#include <mesh-builder.h>
 #include <stdlib.h>
 
 #include <algorithm>
@@ -1128,6 +1129,351 @@ int UtcDaliAnimationSetEndActionP02(void)
   END_TEST;
 }
 
+int UtcDaliAnimationSetEndActionP03(void)
+{
+  tet_infoline("Test Animation::EndAction with custom property\n");
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  application.GetScene().Add(actor);
+
+  // Register animatable property
+  Vector3         initialValue(0.0f, 2.0f, 0.0f);
+  Property::Index customPropertyIndex = actor.RegisterUniqueProperty("customAnimatable", initialValue);
+  DALI_TEST_EQUALS(actor.GetProperty<Vector3>(customPropertyIndex), initialValue, TEST_LOCATION);
+
+  // Build the animation
+  float     durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::BAKE);
+
+  Vector3 targetValue(1.0f, 1.0f, 1.0f);
+  animation.AnimateTo(Property(actor, customPropertyIndex), targetValue, AlphaFunction::LINEAR);
+
+  // Start the animation
+  animation.Play();
+
+  bool                 signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+
+  // Go back to the start
+  actor.SetProperty(customPropertyIndex, initialValue);
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+
+  tet_printf("Set EndAction::BAKE_FINAL\n");
+  // Test BakeFinal, animate again, for half the duration
+  finishCheck.Reset();
+  animation.SetEndAction(Animation::BAKE_FINAL);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::BAKE_FINAL);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 1000.0f * 0.5f) /*half of the animation duration*/);
+
+  // Stop the animation early
+  animation.Stop();
+
+  tet_printf("EndAction::BAKE_FINAL Animation stopped\n");
+  // We did NOT expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  DALI_TEST_EQUALS((initialValue + targetValue) * 0.5f, actor.GetCurrentProperty<Vector3>(customPropertyIndex), VECTOR3_EPSILON, TEST_LOCATION);
+
+  // The position should be same with target position in the next frame
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(targetValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+
+  // Go back to the start
+  actor.SetProperty(customPropertyIndex, initialValue);
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+
+  tet_printf("Set EndAction::Discard\n");
+  // Test EndAction::Discard, animate again, but don't bake this time
+  finishCheck.Reset();
+  animation.SetEndAction(Animation::DISCARD);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::DISCARD);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // Check whether we need to keep update at least 2 frames after discard-animation finished.
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  tet_printf("EndAction::Discard Animation finished\n");
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+
+  // The position should be discarded in the next frame
+  // And also, check whether we need to keep update next frames after discard-animation finished.
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue /*discarded*/, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  // Check that nothing has changed after a couple of buffer swaps
+  // After 2 frames rendered, UpdateStatus will not mark as animation runing.
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  tet_printf("Set EndAction::Discard and play another animation with EndAction::Bake\n");
+  // Test EndAction::Discard, animate again, but don't bake this time
+  finishCheck.Reset();
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::DISCARD);
+
+  float     customPropertyYValue = 100.0f;
+  Animation animation2           = Animation::New(durationSeconds);
+  DALI_TEST_CHECK(animation2.GetEndAction() == Animation::BAKE);
+  animation2.AnimateTo(Property(actor, customPropertyIndex, 1), customPropertyYValue, AlphaFunction::LINEAR);
+  animation.Play();
+  animation2.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // Check whether we need to keep update at least 2 frames after discard-animation finished.
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  tet_printf("EndAction::Discard Animation finished\n");
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue.x, actor.GetCurrentProperty<Vector3>(customPropertyIndex).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex).y, TEST_LOCATION);
+  DALI_TEST_EQUALS(targetValue.z, actor.GetCurrentProperty<Vector3>(customPropertyIndex).z, TEST_LOCATION);
+
+  // The position should be discarded in the next frame
+  // And also, check whether we need to keep update next frames after discard-animation finished.
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x /*discarded*/, actor.GetCurrentProperty<Vector3>(customPropertyIndex).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue /*baked*/, actor.GetCurrentProperty<Vector3>(customPropertyIndex).y, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialValue.z /*discarded*/, actor.GetCurrentProperty<Vector3>(customPropertyIndex).z, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  // Check that nothing has changed after a couple of buffer swaps
+  // After 2 frames rendered, UpdateStatus will not mark as animation runing.
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x, actor.GetCurrentProperty<Vector3>(customPropertyIndex).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex).y, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialValue.z, actor.GetCurrentProperty<Vector3>(customPropertyIndex).z, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x, actor.GetCurrentProperty<Vector3>(customPropertyIndex).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty<Vector3>(customPropertyIndex).y, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialValue.z, actor.GetCurrentProperty<Vector3>(customPropertyIndex).z, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+  END_TEST;
+}
+
+int UtcDaliAnimationSetEndActionP04(void)
+{
+  tet_infoline("Test Animation::EndAction with VisualRenderer property\n");
+  TestApplication application;
+
+  Actor          actor          = Actor::New();
+  Shader         shader         = Shader::New("VertexSource", "FragmentSource");
+  Geometry       geometry       = CreateQuadGeometry();
+  VisualRenderer visualRenderer = VisualRenderer::New(geometry, shader);
+  actor.AddRenderer(visualRenderer);
+
+  application.GetScene().Add(actor);
+
+  // Initialize transform size value
+  Vector2 initialValue(0.0f, 2.0f);
+  visualRenderer.SetProperty(Dali::VisualRenderer::Property::TRANSFORM_SIZE, initialValue);
+  DALI_TEST_EQUALS(visualRenderer.GetProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), initialValue, TEST_LOCATION);
+
+  // Build the animation
+  float     durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::BAKE);
+
+  Vector2 targetValue(1.0f, 1.0f);
+  animation.AnimateTo(Property(visualRenderer, Dali::VisualRenderer::Property::TRANSFORM_SIZE), targetValue, AlphaFunction::LINEAR);
+
+  // Start the animation
+  animation.Play();
+
+  bool                 signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+
+  // Go back to the start
+  visualRenderer.SetProperty(Dali::VisualRenderer::Property::TRANSFORM_SIZE, initialValue);
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+
+  tet_printf("Set EndAction::BAKE_FINAL\n");
+  // Test BakeFinal, animate again, for half the duration
+  finishCheck.Reset();
+  animation.SetEndAction(Animation::BAKE_FINAL);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::BAKE_FINAL);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 1000.0f * 0.5f) /*half of the animation duration*/);
+
+  // Stop the animation early
+  animation.Stop();
+
+  tet_printf("EndAction::BAKE_FINAL Animation stopped\n");
+  // We did NOT expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  DALI_TEST_EQUALS((initialValue + targetValue) * 0.5f, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), VECTOR3_EPSILON, TEST_LOCATION);
+
+  // The position should be same with target position in the next frame
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(targetValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+
+  // Go back to the start
+  visualRenderer.SetProperty(Dali::VisualRenderer::Property::TRANSFORM_SIZE, initialValue);
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+
+  tet_printf("Set EndAction::Discard\n");
+  // Test EndAction::Discard, animate again, but don't bake this time
+  finishCheck.Reset();
+  animation.SetEndAction(Animation::DISCARD);
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::DISCARD);
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // Check whether we need to keep update at least 2 frames after discard-animation finished.
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  tet_printf("EndAction::Discard Animation finished\n");
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+
+  // The position should be discarded in the next frame
+  // And also, check whether we need to keep update next frames after discard-animation finished.
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue /*discarded*/, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  // Check that nothing has changed after a couple of buffer swaps
+  // After 2 frames rendered, UpdateStatus will not mark as animation runing.
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE), TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  tet_printf("Set EndAction::Discard and play another animation with EndAction::Bake\n");
+  // Test EndAction::Discard, animate again, but don't bake this time
+  finishCheck.Reset();
+  DALI_TEST_CHECK(animation.GetEndAction() == Animation::DISCARD);
+
+  float     customPropertyYValue = 5.0f;
+  Animation animation2           = Animation::New(durationSeconds);
+  DALI_TEST_CHECK(animation2.GetEndAction() == Animation::BAKE);
+  animation2.AnimateTo(Property(visualRenderer, Dali::VisualRenderer::Property::TRANSFORM_SIZE, 1), customPropertyYValue, AlphaFunction::LINEAR);
+  animation.Play();
+  animation2.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
+
+  // Check whether we need to keep update at least 2 frames after discard-animation finished.
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  tet_printf("EndAction::Discard Animation finished\n");
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS(targetValue.x, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).y, TEST_LOCATION);
+
+  // The position should be discarded in the next frame
+  // And also, check whether we need to keep update next frames after discard-animation finished.
+  tet_printf("Check current value return well\n");
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x /*discarded*/, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue /*baked*/, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).y, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) != 0u);
+
+  // Check that nothing has changed after a couple of buffer swaps
+  // After 2 frames rendered, UpdateStatus will not mark as animation runing.
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).y, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+
+  application.Render(0);
+  DALI_TEST_EQUALS(initialValue.x, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).x, TEST_LOCATION);
+  DALI_TEST_EQUALS(customPropertyYValue, visualRenderer.GetCurrentProperty<Vector2>(Dali::VisualRenderer::Property::TRANSFORM_SIZE).y, TEST_LOCATION);
+  DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u);
+  END_TEST;
+}
+
 int UtcDaliAnimationGetEndActionP(void)
 {
   TestApplication application;
index 5e1e6bb6eee455616e3afbdc4f90d1c6e2c13b45..d8dc3a8a185d0ddc0e76cd148eca1214bf03d50b 100644 (file)
@@ -755,6 +755,14 @@ public:
     }
   }
 
+  /**
+   * @copydoc Dali::Internal::SceneGraph::AnimatablePropertyBase::OnBake()
+   */
+  void OnBake() override
+  {
+    mDirtyFlags |= BAKED_FLAG; ///< Dev note : We should not override dirtyflags as BAKED_FLAG since we can give flags component by component.
+  }
+
   /**
    * @copydoc Dali::PropertyInput::GetVector2()
    */
@@ -1037,6 +1045,14 @@ public:
     }
   }
 
+  /**
+   * @copydoc Dali::Internal::SceneGraph::AnimatablePropertyBase::OnBake()
+   */
+  void OnBake() override
+  {
+    mDirtyFlags |= BAKED_FLAG; ///< Dev note : We should not override dirtyflags as BAKED_FLAG since we can give flags component by component.
+  }
+
   /**
    * @copydoc Dali::PropertyInput::GetVector3()
    */
@@ -1373,6 +1389,14 @@ public:
     }
   }
 
+  /**
+   * @copydoc Dali::Internal::SceneGraph::AnimatablePropertyBase::OnBake()
+   */
+  void OnBake() override
+  {
+    mDirtyFlags |= BAKED_FLAG; ///< Dev note : We should not override dirtyflags as BAKED_FLAG since we can give flags component by component.
+  }
+
   /**
    * @copydoc Dali::PropertyInput::GetVector4()
    */
index 37f3de19af346ca519b96bb2d0bb52c3716e150f..b6ba9809ef5242a8cbd932da481ecd27847be401 100644 (file)
@@ -159,7 +159,7 @@ public:
   void OnSet() override
   {
     GetCacheBaseData()->Update(false);
-    AnimatablePropertyBase::OnSet();
+    AnimatableProperty<T>::OnSet();
   }
 
   /**
@@ -168,7 +168,7 @@ public:
   void OnBake() override
   {
     GetCacheBaseData()->Update(true);
-    AnimatablePropertyBase::OnBake();
+    AnimatableProperty<T>::OnBake();
   }
 };