Sort Animator only if required.
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animation.cpp
index d75199a..ec26435 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 namespace //Unnamed namespace
 {
 //Memory pool used to allocate new animations. Memory used by this pool will be released when shutting down DALi
-Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Animation> gAnimationMemoryPool;
+Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Animation>& GetAnimationMemoryPool()
+{
+  static Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Animation> gAnimationMemoryPool;
+  return gAnimationMemoryPool;
+}
 
 inline void WrapInPlayRange(float& elapsed, const float& playRangeStartSeconds, const float& playRangeEndSeconds)
 {
@@ -58,7 +62,7 @@ namespace SceneGraph
 {
 Animation* Animation::New(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction)
 {
-  return new(gAnimationMemoryPool.AllocateRawThreadSafe()) Animation(durationSeconds, speedFactor, playRange, loopCount, endAction, disconnectAction);
+  return new(GetAnimationMemoryPool().AllocateRawThreadSafe()) Animation(durationSeconds, speedFactor, playRange, loopCount, endAction, disconnectAction);
 }
 
 Animation::Animation(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction)
@@ -76,6 +80,7 @@ Animation::Animation(float durationSeconds, float speedFactor, const Vector2& pl
   mState(Stopped),
   mProgressReachedSignalRequired(false),
   mAutoReverseEnabled(false),
+  mAnimatorSortRequired(false),
   mIsActive{false}
 {
 }
@@ -84,7 +89,7 @@ Animation::~Animation() = default;
 
 void Animation::operator delete(void* ptr)
 {
-  gAnimationMemoryPool.FreeThreadSafe(static_cast<Animation*>(ptr));
+  GetAnimationMemoryPool().FreeThreadSafe(static_cast<Animation*>(ptr));
 }
 
 void Animation::SetDuration(float durationSeconds)
@@ -147,8 +152,12 @@ void Animation::SetPlayRange(const Vector2& range)
 
 void Animation::Play()
 {
-  // Sort according to end time with earlier end times coming first, if the end time is the same, then the animators are not moved
-  std::stable_sort(mAnimators.Begin(), mAnimators.End(), CompareAnimatorEndTimes);
+  if(mAnimatorSortRequired)
+  {
+    // Sort according to end time with earlier end times coming first, if the end time is the same, then the animators are not moved
+    std::stable_sort(mAnimators.Begin(), mAnimators.End(), CompareAnimatorEndTimes);
+    mAnimatorSortRequired = false;
+  }
 
   mState = Playing;
 
@@ -295,6 +304,16 @@ void Animation::AddAnimator(OwnerPointer<AnimatorBase>& animator)
   animator->ConnectToSceneGraph();
   animator->SetDisconnectAction(mDisconnectAction);
 
+  // Check whether we need to sort mAnimators or not.
+  // Sort will be required only if new item is smaller than last value of container.
+  if(!mAnimatorSortRequired && !mAnimators.Empty())
+  {
+    if(CompareAnimatorEndTimes(animator.Get(), *(mAnimators.End() - 1u)))
+    {
+      mAnimatorSortRequired = true;
+    }
+  }
+
   mAnimators.PushBack(animator.Release());
 }
 
@@ -481,12 +500,16 @@ void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animati
   {
     //Remove animators whose PropertyOwner has been destroyed
     mAnimators.EraseIf([](auto& animator) { return animator->Orphan(); });
+
+    // Need to be re-sort if remained animators size is bigger than one.
+    // Note that if animator contains only zero or one items, It is already sorted case.
+    mAnimatorSortRequired = (mAnimators.Count() >= 2);
   }
 }
 
 uint32_t Animation::GetMemoryPoolCapacity()
 {
-  return gAnimationMemoryPool.GetCapacity();
+  return GetAnimationMemoryPool().GetCapacity();
 }
 
 } // namespace SceneGraph