Call ResetToBaseValue only 1 times per PropertyBase 60/312360/4
authorEunki Hong <eunkiki.hong@samsung.com>
Fri, 7 Jun 2024 08:26:06 +0000 (17:26 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 12 Jun 2024 01:30:26 +0000 (10:30 +0900)
If multiple animation try to change single property, the dirty flag
of PropertyBase would not be works well.

To ensure the dirty flag, let we collect resetter required properties
into single container, and call ResetToBaseValue only one times.

It will ensure that we call the resetter only 1 times per 1 frame.

Change-Id: I1a3792993f2ef681399f72f6f1718731408f2128
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
13 files changed:
dali/internal/update/common/node-resetter.h
dali/internal/update/common/property-base.cpp
dali/internal/update/common/property-base.h
dali/internal/update/common/property-resetter.h
dali/internal/update/common/renderer-resetter.h
dali/internal/update/common/resetter-manager.h
dali/internal/update/manager/resetter-container.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/internal/update/rendering/scene-graph-visual-renderer.cpp
dali/internal/update/rendering/scene-graph-visual-renderer.h

index f0e155e..b6961a5 100644 (file)
@@ -70,10 +70,9 @@ public:
   }
 
   /**
-   * Reset the node properties to their base values if the node is still alive and on stage
-   * @param[in] updateBufferIndex the current buffer index
+   * Request to reset the node properties to their base values if the node is still alive and on stage
    */
-  void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void RequestResetToBaseValues()
   {
     if(mNode != nullptr && mActive)
     {
@@ -82,8 +81,8 @@ public:
       // property values are set appropriately.
       --mActive;
 
-      mNode->mVisible.ResetToBaseValue(updateBufferIndex);
-      mNode->mColor.ResetToBaseValue(updateBufferIndex);
+      mNode->mVisible.RequestResetToBaseValue();
+      mNode->mColor.RequestResetToBaseValue();
     }
   };
 
@@ -160,9 +159,10 @@ protected:
     mNode->mColor.MarkAsDirty();
   }
 
-  Node*  mNode;         ///< The node that owns the properties
-  int8_t mActive;       ///< 2 if active, 1 if aging, 0 if stopped
-  bool   mDisconnected; ///< True if the node has been disconnected
+  Node* mNode; ///< The node that owns the properties
+
+  uint8_t mActive : 2;       ///< 2 if active, 1 if aging, 0 if stopped
+  bool    mDisconnected : 1; ///< True if the node has been disconnected
 };
 
 } // namespace SceneGraph
index 3f9b337..99ab4cd 100644 (file)
 // CLASS HEADER
 #include <dali/internal/update/common/property-base.h>
 
+// INTERNAL INCLUDES
+#include <dali/internal/update/common/resetter-manager.h> ///< For RequestPropertyBaseResetToBaseValue
+
 namespace Dali
 {
 namespace Internal
 {
 namespace SceneGraph
 {
-PropertyBase::PropertyBase() = default;
+namespace
+{
+ResetterManager* gResetterManager = nullptr;
+} // unnamed namespace
+
+void PropertyBase::RegisterResetterManager(ResetterManager& manager)
+{
+  DALI_ASSERT_ALWAYS(gResetterManager == nullptr && "PropertyBase::RegisterResetterManager called twice!");
+
+  gResetterManager = &manager;
+}
+
+void PropertyBase::UnregisterResetterManager()
+{
+  DALI_ASSERT_ALWAYS(gResetterManager && "PropertyBase::RegisterResetterManager not be called before!");
+
+  gResetterManager = nullptr;
+}
+
+void PropertyBase::RequestResetToBaseValue()
+{
+  DALI_ASSERT_ALWAYS(gResetterManager && "PropertyBase::RequestResetToBaseValue called without RegisterResetterManager!!");
 
-PropertyBase::~PropertyBase() = default;
+  gResetterManager->RequestPropertyBaseResetToBaseValue(this);
+}
 
 } // namespace SceneGraph
 
index f21eb93..7636ae7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_PROPERTY_BASE_H
 
 /*
- * Copyright (c) 2021 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.
@@ -33,6 +33,8 @@ namespace Internal
 {
 namespace SceneGraph
 {
+class ResetterManager;
+
 /**
  * Polymorphic base class for scene-graph properties, held by Nodes etc.
  */
@@ -42,12 +44,29 @@ public:
   /**
    * Default constructor.
    */
-  PropertyBase();
+  PropertyBase() = default;
 
   /**
    * Virtual destructor.
    */
-  ~PropertyBase() override;
+  ~PropertyBase() = default;
+
+  /**
+   * @brief Registers a resetter manager for whole property bases.
+   *
+   * @param [in] manager The manager to register.
+   */
+  static void RegisterResetterManager(ResetterManager& manager);
+
+  /**
+   * @brief Unregisters a resetter manager.
+   */
+  static void UnregisterResetterManager();
+
+  /**
+   * @brief Request to reset the property to a base value to registered ResetterManager.
+   */
+  void RequestResetToBaseValue();
 
   /**
    * Reset the property to a base value; only required if the property is animated.
index 52ef2bb..ec338f4 100644 (file)
@@ -70,10 +70,9 @@ public:
   }
 
   /**
-   * Reset the property to it's base value if the property owner is still alive and on stage
-   * @param[in] updateBufferIndex the current buffer index
+   * Request to reset the property to it's base value if the property owner is still alive and on stage
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  virtual void RequestResetToBaseValues()
   {
     if(mPropertyOwner != nullptr && mActive)
     {
@@ -85,7 +84,10 @@ public:
         --mActive;
       }
 
-      mBaseProperty->ResetToBaseValue(updateBufferIndex);
+      if(DALI_LIKELY(mBaseProperty))
+      {
+        mBaseProperty->RequestResetToBaseValue();
+      }
     }
   };
 
@@ -176,10 +178,11 @@ protected:
 
   PropertyOwner* mPropertyOwner; ///< The property owner
   PropertyBase*  mBaseProperty;  ///< The base property being animated or constrained
-  int8_t         mRunning;       ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
-  int8_t         mActive;        ///< 2 if active, 1 if aging, 0 if stopped
-  bool           mInitialized : 1;
-  bool           mDisconnected : 1; ///< True if the property owner has been disconnected
+
+  int8_t mRunning; ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
+  int8_t mActive;  ///< 2 if active, 1 if aging, 0 if stopped
+  bool   mInitialized : 1;
+  bool   mDisconnected : 1; ///< True if the property owner has been disconnected
 };
 
 class BakerResetter : public PropertyResetterBase
@@ -227,19 +230,21 @@ public:
   ~BakerResetter() override = default;
 
   /**
-   * @param updateBufferIndex
+   * @copydoc Dali::Internal::SceneGraph::PropertyResetterBase::RequestResetToBaseValues
    */
-  void ResetToBaseValue(BufferIndex updateBufferIndex) override
+  void RequestResetToBaseValues() override
   {
     if(mPropertyOwner && mRunning > 0)
     {
-      mRunning--;
-      mBaseProperty->ResetToBaseValue(updateBufferIndex);
-
+      --mRunning;
       if(mRunning > 0)
       {
         mPropertyOwner->SetUpdated(true);
       }
+      if(DALI_LIKELY(mBaseProperty))
+      {
+        mBaseProperty->RequestResetToBaseValue();
+      }
     }
   }
 };
index dbecb47..b01c7eb 100644 (file)
@@ -70,10 +70,9 @@ public:
   }
 
   /**
-   * Reset the renderer properties to their base values if the renderer is still alive and on stage
-   * @param[in] updateBufferIndex the current buffer index
+   * Request to reset the renderer properties to their base values if the renderer is still alive and on stage
    */
-  void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void RequestResetToBaseValues()
   {
     if(mRenderer != nullptr && mActive)
     {
@@ -82,7 +81,7 @@ public:
       // initialized case.
       --mActive;
 
-      mRenderer->ResetToBaseValues(updateBufferIndex);
+      mRenderer->RequestResetToBaseValues();
     }
   };
 
index 66f31f2..e155009 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENEGRAPH_RESETTER_MANAGER_H
 
 /*
- * 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.
@@ -52,6 +52,12 @@ public:
    */
   virtual void AddRendererResetter(const Renderer& renderer) = 0;
 
+  /**
+   * @brief Request to reset base value.
+   * @param[in] propertyBase The property base to reset.
+   */
+  virtual void RequestPropertyBaseResetToBaseValue(PropertyBase* propertyBase) = 0;
+
 protected:
   /**
    * Destructor. Protected as no derived class should ever be deleted
index 9c042b1..b5aa1e8 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_UPDATE_RESETTER_CONTAINER_H
 
 /*
- * 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.
@@ -19,7 +19,6 @@
 
 namespace Dali::Internal::SceneGraph
 {
-
 /**
  * Template class to manage node/property resetters
  */
@@ -147,13 +146,12 @@ public:
   }
 
   /**
-   * Iterate over the container, resetting all the referenced
+   * Iterate over the container, request to resetting all the referenced
    * properties. If a resetter has finished (e.g. it's animation /
    * constraint has ended, or it's baked 2 values), then it is removed
    * from the list.
-   * @param[in] bufferIndex The buffer index of the property to be reset
    */
-  void ResetToBaseValues(BufferIndex bufferIndex)
+  void RequestResetToBaseValues()
   {
     if(!mContainer.empty())
     {
@@ -161,7 +159,7 @@ public:
       auto iter = mContainer.begin();
       while(iter != end)
       {
-        (*iter)->ResetToBaseValue(bufferIndex);
+        (*iter)->RequestResetToBaseValues();
         if((*iter)->IsFinished())
         {
           iter = EraseObject(iter);
index 778ac67..3c2a422 100644 (file)
 // EXTERNAL INCLUDES
 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
 #include <dali/devel-api/common/map-wrapper.h>
+#include <dali/devel-api/common/set-wrapper.h>
 #else
 #include <unordered_map>
+#include <unordered_set>
 #endif
 
 // INTERNAL INCLUDES
@@ -317,8 +319,12 @@ struct UpdateManager::Impl
 
 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
   using NodeIdMap = std::map<uint32_t, Node*>;
+
+  using PropertyBaseResetRequestedContainer = std::set<PropertyBase*>;
 #else
   using NodeIdMap = std::unordered_map<uint32_t, Node*>;
+
+  using PropertyBaseResetRequestedContainer = std::unordered_set<PropertyBase*>;
 #endif
   NodeIdMap nodeIdMap; ///< A container of nodes map by id.
 
@@ -330,6 +336,8 @@ struct UpdateManager::Impl
   ResetterContainer<NodeResetter>         nodeResetters;     ///< A container of node resetters
   ResetterContainer<RendererResetter>     rendererResetters; ///< A container of renderer resetters
 
+  PropertyBaseResetRequestedContainer resetRequestedPropertyBases; ///< A container of property base to be resets
+
   OwnerContainer<Animation*>            animations;            ///< A container of owned animations
   OwnerContainer<PropertyNotification*> propertyNotifications; ///< A container of owner property notifications.
   OwnerKeyContainer<Renderer>           renderers;             ///< A container of owned renderers
@@ -383,6 +391,8 @@ UpdateManager::UpdateManager(NotificationManager&           notificationManager,
                              RenderTaskProcessor&           renderTaskProcessor)
 : mImpl(nullptr)
 {
+  PropertyBase::RegisterResetterManager(*this);
+
   mImpl = new Impl(notificationManager,
                    animationFinishedNotifier,
                    propertyNotifier,
@@ -396,6 +406,7 @@ UpdateManager::UpdateManager(NotificationManager&           notificationManager,
 UpdateManager::~UpdateManager()
 {
   delete mImpl;
+  PropertyBase::UnregisterResetterManager();
 }
 
 void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
@@ -704,6 +715,11 @@ void UpdateManager::AddRendererResetter(const Renderer& renderer)
   mImpl->rendererResetters.PushBack(rendererResetter.Release());
 }
 
+void UpdateManager::RequestPropertyBaseResetToBaseValue(PropertyBase* propertyBase)
+{
+  mImpl->resetRequestedPropertyBases.insert(propertyBase);
+}
+
 void UpdateManager::AddPropertyNotification(OwnerPointer<PropertyNotification>& propertyNotification)
 {
   mImpl->propertyNotifications.PushBack(propertyNotification.Release());
@@ -853,14 +869,27 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex)
   // Age down discard animations.
   mImpl->discardAnimationFinishedAge >>= 1;
 
+  // Ensure that their was no request to reset to base values during the previous update
+  // (Since requested property base doesn't consider the lifecycle of PropertyBase,
+  // It might be invalid after the previous update finished)
+  DALI_ASSERT_DEBUG(mImpl->resetRequestedPropertyBases.empty() && "Reset to base values requested during the previous update!");
+  mImpl->resetRequestedPropertyBases.clear();
+
   // Reset node properties
-  mImpl->nodeResetters.ResetToBaseValues(bufferIndex);
+  mImpl->nodeResetters.RequestResetToBaseValues();
 
   // Reset renderer properties
-  mImpl->rendererResetters.ResetToBaseValues(bufferIndex);
+  mImpl->rendererResetters.RequestResetToBaseValues();
 
   // Reset all animating / constrained properties
-  mImpl->propertyResetters.ResetToBaseValues(bufferIndex);
+  mImpl->propertyResetters.RequestResetToBaseValues();
+
+  // Actual reset to base values here
+  for(auto&& propertyBase : mImpl->resetRequestedPropertyBases)
+  {
+    propertyBase->ResetToBaseValue(bufferIndex);
+  }
+  mImpl->resetRequestedPropertyBases.clear();
 
   // Clear all root nodes dirty flags
   for(auto& scene : mImpl->scenes)
index 914f3af..64e096c 100644 (file)
@@ -269,6 +269,11 @@ public:
    */
   void AddRendererResetter(const Renderer& renderer) override;
 
+  /**
+   * @copydoc Dali::Internal::SceneGraph::ResetterManager::RequestPropertyBaseResetToBaseValue()
+   */
+  void RequestPropertyBaseResetToBaseValue(PropertyBase* propertyBase) override;
+
   // Property Notification
 
   /**
index 3fbc62d..3cc80cb 100644 (file)
@@ -826,12 +826,12 @@ bool Renderer::IsDirty() const
   return (Updated() || !mOpacity.IsClean());
 }
 
-void Renderer::ResetToBaseValues(BufferIndex updateBufferIndex)
+void Renderer::RequestResetToBaseValues()
 {
-  mOpacity.ResetToBaseValue(updateBufferIndex);
+  mOpacity.RequestResetToBaseValue();
   if(mVisualProperties)
   {
-    mVisualProperties->ResetToBaseValues(updateBufferIndex);
+    mVisualProperties->RequestResetToBaseValues();
   }
 }
 
index a6ad912..e2753c1 100644 (file)
@@ -488,11 +488,9 @@ public:
   bool IsDirty() const;
 
   /**
-   * @brief Reset to base values of all animatable properties.
-   *
-   * @param[in] updateBufferIndex the current buffer index
+   * @brief Request to reset to base values of all animatable properties.
    */
-  void ResetToBaseValues(BufferIndex updateBufferIndex);
+  void RequestResetToBaseValues();
 
   /**
    * Get the capacity of the memory pools
index 904bb2c..81b5a67 100644 (file)
@@ -28,20 +28,20 @@ extern Debug::Filter* gSceneGraphRendererLogFilter; ///< Defined at scene-graph-
 #endif
 namespace VisualRenderer
 {
-void AnimatableVisualProperties::ResetToBaseValues(BufferIndex updateBufferIndex)
+void AnimatableVisualProperties::RequestResetToBaseValues()
 {
-  mTransformOffset.ResetToBaseValue(updateBufferIndex);
-  mTransformSize.ResetToBaseValue(updateBufferIndex);
-  mTransformOrigin.ResetToBaseValue(updateBufferIndex);
-  mTransformAnchorPoint.ResetToBaseValue(updateBufferIndex);
-  mTransformOffsetSizeMode.ResetToBaseValue(updateBufferIndex);
-  mExtraSize.ResetToBaseValue(updateBufferIndex);
-  mMixColor.ResetToBaseValue(updateBufferIndex);
-  mPreMultipliedAlpha.ResetToBaseValue(updateBufferIndex);
+  mTransformOffset.RequestResetToBaseValue();
+  mTransformSize.RequestResetToBaseValue();
+  mTransformOrigin.RequestResetToBaseValue();
+  mTransformAnchorPoint.RequestResetToBaseValue();
+  mTransformOffsetSizeMode.RequestResetToBaseValue();
+  mExtraSize.RequestResetToBaseValue();
+  mMixColor.RequestResetToBaseValue();
+  mPreMultipliedAlpha.RequestResetToBaseValue();
   if(mExtendedProperties)
   {
     auto* decoratedVisualProperties = static_cast<VisualRenderer::AnimatableDecoratedVisualProperties*>(mExtendedProperties);
-    decoratedVisualProperties->ResetToBaseValues(updateBufferIndex);
+    decoratedVisualProperties->RequestResetToBaseValues();
   }
 }
 
@@ -191,14 +191,14 @@ bool AnimatableVisualProperties::PrepareProperties()
   return rendererUpdated;
 }
 
-void AnimatableDecoratedVisualProperties::ResetToBaseValues(BufferIndex updateBufferIndex)
+void AnimatableDecoratedVisualProperties::RequestResetToBaseValues()
 {
-  mCornerRadius.ResetToBaseValue(updateBufferIndex);
-  mCornerRadiusPolicy.ResetToBaseValue(updateBufferIndex);
-  mBorderlineWidth.ResetToBaseValue(updateBufferIndex);
-  mBorderlineColor.ResetToBaseValue(updateBufferIndex);
-  mBorderlineOffset.ResetToBaseValue(updateBufferIndex);
-  mBlurRadius.ResetToBaseValue(updateBufferIndex);
+  mCornerRadius.RequestResetToBaseValue();
+  mCornerRadiusPolicy.RequestResetToBaseValue();
+  mBorderlineWidth.RequestResetToBaseValue();
+  mBorderlineColor.RequestResetToBaseValue();
+  mBorderlineOffset.RequestResetToBaseValue();
+  mBlurRadius.RequestResetToBaseValue();
 }
 
 bool AnimatableDecoratedVisualProperties::Updated() const
index 02244c7..6ca2d64 100644 (file)
@@ -51,9 +51,9 @@ struct AnimatableVisualProperties
 
 public: // Public API
   /**
-   * @copydoc Dali::Internal::SceneGraph::Renderer::ResetToBaseValues
+   * @copydoc Dali::Internal::SceneGraph::Renderer::RequestResetToBaseValues
    */
-  void ResetToBaseValues(BufferIndex updateBufferIndex);
+  void RequestResetToBaseValues();
 
   /**
    * @copydoc Dali::Internal::SceneGraph::Renderer::Updated
@@ -143,9 +143,9 @@ public: // Public API
   }
 
   /**
-   * @copydoc Dali::Internal::SceneGraph::Renderer::ResetToBaseValues
+   * @copydoc Dali::Internal::SceneGraph::Renderer::RequestResetToBaseValues
    */
-  void ResetToBaseValues(BufferIndex updateBufferIndex);
+  void RequestResetToBaseValues();
 
   /**
    * @copydoc Dali::Internal::SceneGraph::Renderer::Updated