From 5faaa678b9aafcf0b79c65a2821461b2b13c3efc Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Wed, 14 Feb 2024 11:51:16 +0900 Subject: [PATCH] Do not re-create SG::Animation when we call Clear to empty animation + Clear reset some values Since we always destroy & create scene obeject whenever we call Clear(), It will be make some useless memory increasement when user call Clear() infinitely. To avoid this cases, let we re-create that object only if we call Play() before or at least 1 animator exist. And also, make Clear() API reset some sensitive values, like CurrentLoop and State. Change-Id: I7f79b5e8e2bf822f01f094e4023e90e5f0922faa Signed-off-by: Eunki Hong --- automated-tests/src/dali/utc-Dali-Animation.cpp | 97 ++++++++++++++++++++++++ dali/internal/event/animation/animation-impl.cpp | 13 +++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Animation.cpp b/automated-tests/src/dali/utc-Dali-Animation.cpp index a4cfd8d..00847a6 100644 --- a/automated-tests/src/dali/utc-Dali-Animation.cpp +++ b/automated-tests/src/dali/utc-Dali-Animation.cpp @@ -3406,6 +3406,103 @@ int UtcDaliAnimationClearP(void) END_TEST; } +int UtcDaliAnimationEmptyAnimator(void) +{ + // Clear and play the empty animation, and get the state values. + TestApplication application; + + float durationSeconds(1.0f); + Animation animation = Animation::New(durationSeconds); + animation.SetLoopCount(3); + + bool signalReceived(false); + AnimationFinishCheck finishCheck(signalReceived); + animation.FinishedSignal().Connect(&application, finishCheck); + + try + { + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::STOPPED, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 0, TEST_LOCATION); + application.SendNotification(); + application.Render(); + + animation.Play(); + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::PLAYING, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 0, TEST_LOCATION); + application.SendNotification(); + application.Render(1500 /* 150% of loop. */); + application.SendNotification(); // Notification trigger. + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::PLAYING, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 1, TEST_LOCATION); + + application.SendNotification(); + application.Render(1400 /* 290% of loop. */); + application.SendNotification(); // Notification trigger. + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::PLAYING, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 2, TEST_LOCATION); + + application.SendNotification(); + application.Render(100 + 1100 /* 300% of loop. and extra 110%. */); + application.SendNotification(); // Notification trigger. + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::STOPPED, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 3, TEST_LOCATION); + + // Check wether empty animation also call finished signal. + finishCheck.CheckSignalReceived(); + finishCheck.Reset(); + + animation.Play(); + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::PLAYING, TEST_LOCATION); + //DALI_TEST_EQUALS(animation.GetCurrentLoop(), 0, TEST_LOCATION); ///< TODO : We'd better change the policy of GetCurrentLoop result + application.SendNotification(); + application.Render(1500 /* 150% of loop. */); + application.SendNotification(); // Notification trigger. + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::PLAYING, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 1, TEST_LOCATION); + + animation.Clear(); + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::STOPPED, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 0, TEST_LOCATION); + + application.SendNotification(); + application.Render(1000); + application.Render(1000); + application.Render(1100 /* Over the loop count */); + application.SendNotification(); // Notification trigger. + + // Check animation completed signal not recieved even of + finishCheck.CheckSignalNotReceived(); + + // Call clear again already cleared cases. + animation.Clear(); + + DALI_TEST_EQUALS(animation.GetState(), Dali::Animation::STOPPED, TEST_LOCATION); + DALI_TEST_EQUALS(animation.GetCurrentLoop(), 0, TEST_LOCATION); + + application.SendNotification(); + application.Render(1000); + application.Render(1000); + application.Render(1100 /* Over the loop count */); + application.SendNotification(); // Notification trigger. + + // Check animation completed signal not recieved even of + finishCheck.CheckSignalNotReceived(); + } + catch(...) + { + DALI_TEST_CHECK(false); // Should not get here + } + + END_TEST; +} + int UtcDaliAnimationFinishedSignalP(void) { TestApplication application; diff --git a/dali/internal/event/animation/animation-impl.cpp b/dali/internal/event/animation/animation-impl.cpp index f182e9e..b9a4de4 100644 --- a/dali/internal/event/animation/animation-impl.cpp +++ b/dali/internal/event/animation/animation-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -389,6 +389,13 @@ void Animation::Clear() { DALI_ASSERT_DEBUG(mAnimation); + // Recreate scene-object only if animation play now, or connector connected at least 1 times. + if(mConnectors.Count() == 0u && mState == Dali::Animation::STOPPED) + { + // Animation is empty. Fast-out + return; + } + // Only notify the objects with the current values if the end action is set to BAKE if(mEndAction == EndAction::BAKE && mState != Dali::Animation::STOPPED) { @@ -406,8 +413,10 @@ void Animation::Clear() DestroySceneObject(); CreateSceneObject(); - // Reset the notification count, since the new scene-object has never been played + // Reset the notification count and relative values, since the new scene-object has never been played mNotificationCount = 0; + mCurrentLoop = 0; + mState = Dali::Animation::STOPPED; // Update the current playlist mPlaylist.OnClear(*this); -- 2.7.4