From f756c982a160d9e721eeb18ea2bfbd79a8bba756 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Thu, 25 Jul 2024 16:26:31 +0900 Subject: [PATCH] Make bake flag dont change set dirty flag 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 --- automated-tests/src/dali/utc-Dali-Animation.cpp | 172 ++++++++++++++++++++++ dali/internal/update/common/animatable-property.h | 24 +++ 2 files changed, 196 insertions(+) diff --git a/automated-tests/src/dali/utc-Dali-Animation.cpp b/automated-tests/src/dali/utc-Dali-Animation.cpp index 137c5d0..c1f30b5 100644 --- a/automated-tests/src/dali/utc-Dali-Animation.cpp +++ b/automated-tests/src/dali/utc-Dali-Animation.cpp @@ -1128,6 +1128,178 @@ 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(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(durationSeconds * 500.0f)); + application.Render(static_cast(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(customPropertyIndex), TEST_LOCATION); + + // Go back to the start + actor.SetProperty(customPropertyIndex, initialValue); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty(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(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(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(customPropertyIndex), TEST_LOCATION); + + // Go back to the start + actor.SetProperty(customPropertyIndex, initialValue); + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty(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(durationSeconds * 500.0f)); + application.Render(static_cast(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(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(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(customPropertyIndex), TEST_LOCATION); + DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u); + + application.Render(0); + DALI_TEST_EQUALS(initialValue, actor.GetCurrentProperty(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(durationSeconds * 500.0f)); + application.Render(static_cast(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(customPropertyIndex).x, TEST_LOCATION); + DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty(customPropertyIndex).y, TEST_LOCATION); + DALI_TEST_EQUALS(targetValue.z, actor.GetCurrentProperty(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(customPropertyIndex).x, TEST_LOCATION); + DALI_TEST_EQUALS(customPropertyYValue /*baked*/, actor.GetCurrentProperty(customPropertyIndex).y, TEST_LOCATION); + DALI_TEST_EQUALS(initialValue.z /*discarded*/, actor.GetCurrentProperty(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(customPropertyIndex).x, TEST_LOCATION); + DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty(customPropertyIndex).y, TEST_LOCATION); + DALI_TEST_EQUALS(initialValue.z, actor.GetCurrentProperty(customPropertyIndex).z, TEST_LOCATION); + DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u); + + application.Render(0); + DALI_TEST_EQUALS(initialValue.x, actor.GetCurrentProperty(customPropertyIndex).x, TEST_LOCATION); + DALI_TEST_EQUALS(customPropertyYValue, actor.GetCurrentProperty(customPropertyIndex).y, TEST_LOCATION); + DALI_TEST_EQUALS(initialValue.z, actor.GetCurrentProperty(customPropertyIndex).z, TEST_LOCATION); + DALI_TEST_CHECK((application.GetUpdateStatus() & Integration::KeepUpdating::ANIMATIONS_RUNNING) == 0u); + END_TEST; +} + int UtcDaliAnimationGetEndActionP(void) { TestApplication application; diff --git a/dali/internal/update/common/animatable-property.h b/dali/internal/update/common/animatable-property.h index 4697d88..2d11c66 100644 --- a/dali/internal/update/common/animatable-property.h +++ b/dali/internal/update/common/animatable-property.h @@ -756,6 +756,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() */ const Vector2& GetVector2(BufferIndex bufferIndex) const override @@ -1038,6 +1046,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() */ const Vector3& GetVector3(BufferIndex bufferIndex) const override @@ -1374,6 +1390,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() */ const Vector4& GetVector4(BufferIndex bufferIndex) const override -- 2.7.4