Reduce default visual-base-data memory - Allocate only if we use decoration. 27/285627/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 15 Dec 2022 12:56:20 +0000 (21:56 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 19 Dec 2022 07:51:43 +0000 (16:51 +0900)
Borderline relative properties has (4+1+1)*4 = 24 byte and
CornerRadius relative properties has (4+1)*4 = 20 byte.

But most usual visuals don't required that kind of things.
And also, some visual like Text / Npatch doesnt support decoration feature.

So let we make only required visual use that values by allocation.

Now default memory per visual reduced from 44 to 4~8 byte.

Change-Id: Ib27118bcd66339a3d50f78661c133f6588ab9085
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp

index 49a14de..b3d8201 100644 (file)
@@ -115,16 +115,12 @@ bool GetPolicyFromValue(const Property::Value& value, Vector2& policy)
 } // unnamed namespace
 
 Internal::Visual::Base::Impl::Impl(FittingMode fittingMode, Toolkit::Visual::Type type)
-: mCustomShader(NULL),
-  mEventObserver(NULL),
+: mCustomShader(nullptr),
+  mEventObserver(nullptr),
   mTransform(),
   mMixColor(Color::WHITE),
   mControlSize(Vector2::ZERO),
-  mBorderlineWidth(0.0f),
-  mBorderlineColor(Color::BLACK),
-  mBorderlineOffset(0.0f),
-  mCornerRadius(Vector4::ZERO),
-  mCornerRadiusPolicy(1.0f),
+  mDecorationData(nullptr),
   mDepthIndex(0.0f),
   mFittingMode(fittingMode),
   mFlags(0),
@@ -138,6 +134,10 @@ Internal::Visual::Base::Impl::Impl(FittingMode fittingMode, Toolkit::Visual::Typ
 Internal::Visual::Base::Impl::~Impl()
 {
   delete mCustomShader;
+  if(mDecorationData)
+  {
+    delete mDecorationData;
+  }
 }
 
 Internal::Visual::Base::Impl::CustomShader::CustomShader(const Property::Map& map)
index 568af24..16d7a76 100644 (file)
@@ -114,6 +114,133 @@ struct Base::Impl
     Toolkit::Align::Type mAnchorPoint;
   };
 
+  struct DecorationData
+  {
+    // Default constructor
+    DecorationData()
+    : mBorderlineColor(Color::BLACK),
+      mCornerRadius(Vector4::ZERO),
+      mBorderlineWidth(0.0f),
+      mBorderlineOffset(0.0f),
+      mCornerRadiusPolicy(static_cast<int>(Toolkit::Visual::Transform::Policy::ABSOLUTE))
+    {
+    }
+    Vector4 mBorderlineColor;
+    Vector4 mCornerRadius;
+    float   mBorderlineWidth;
+    float   mBorderlineOffset;
+    int     mCornerRadiusPolicy;
+  };
+
+  DecorationData* EnsureDecorationData()
+  {
+    if(mDecorationData == nullptr)
+    {
+      mDecorationData = new DecorationData();
+    }
+    return mDecorationData;
+  }
+
+  /**
+   * @brief Get decoration data value : borderline width
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  float GetBorderlineWidth()
+  {
+    return mDecorationData ? mDecorationData->mBorderlineWidth : 0.0f;
+  }
+
+  /**
+   * @brief Set decoration data value : borderline width
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  void SetBorderlineWidth(float value)
+  {
+    EnsureDecorationData()->mBorderlineWidth = value;
+  }
+
+  /**
+   * @brief Get decoration data value : borderline color
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  Vector4 GetBorderlineColor()
+  {
+    return mDecorationData ? mDecorationData->mBorderlineColor : Color::BLACK;
+  }
+
+  /**
+   * @brief Set decoration data value : borderline color
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  void SetBorderlineColor(Vector4 value)
+  {
+    EnsureDecorationData()->mBorderlineColor = value;
+  }
+
+  /**
+   * @brief Get decoration data value : borderline offset
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  float GetBorderlineOffset()
+  {
+    return mDecorationData ? mDecorationData->mBorderlineOffset : 0.0f;
+  }
+
+  /**
+   * @brief Set decoration data value : borderline offset
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  void SetBorderlineOffset(float value)
+  {
+    EnsureDecorationData()->mBorderlineOffset = value;
+  }
+
+  /**
+   * @brief Get decoration data value : corner radius
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  Vector4 GetCornerRadius()
+  {
+    return mDecorationData ? mDecorationData->mCornerRadius : Vector4::ZERO;
+  }
+
+  /**
+   * @brief Set decoration data value : corner radius
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  void SetCornerRadius(Vector4 value)
+  {
+    EnsureDecorationData()->mCornerRadius = value;
+  }
+
+  /**
+   * @brief Get decoration data value : corner radius policy
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  int GetCornerRadiusPolicy()
+  {
+    return mDecorationData ? mDecorationData->mCornerRadiusPolicy : static_cast<int>(Toolkit::Visual::Transform::Policy::ABSOLUTE);
+  }
+
+  /**
+   * @brief Set decoration data value : corner radius policy
+   *
+   * Keep these API as inline function due to the performance.
+   */
+  void SetCornerRadiusPolicy(int value)
+  {
+    EnsureDecorationData()->mCornerRadiusPolicy = value;
+  }
+
   VisualRenderer                  mRenderer;
   CustomShader*                   mCustomShader;
   EventObserver*                  mEventObserver; ///< Allows controls to observe when the visual has events to notify
@@ -121,11 +248,7 @@ struct Base::Impl
   Transform                       mTransform;
   Vector4                         mMixColor;
   Size                            mControlSize;
-  float                           mBorderlineWidth;
-  Vector4                         mBorderlineColor;
-  float                           mBorderlineOffset;
-  Vector4                         mCornerRadius;
-  float                           mCornerRadiusPolicy;
+  DecorationData*                 mDecorationData;
   int                             mDepthIndex;
   FittingMode                     mFittingMode; ///< How the contents should fit the view
   int                             mFlags;
index 55610ec..1539bc4 100644 (file)
@@ -293,7 +293,10 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
         float width;
         if(value.Get(width))
         {
-          mImpl->mBorderlineWidth = width;
+          if(mImpl->mDecorationData != nullptr || !Dali::EqualsZero(width))
+          {
+            mImpl->SetBorderlineWidth(width);
+          }
         }
 
         if(DALI_UNLIKELY(mImpl->mRenderer && IsTypeAvailableForBorderline(mImpl->mType)))
@@ -301,14 +304,14 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
           // Unusual case. SetProperty called after OnInitialize().
           // Assume that DoAction call UPDATE_PROPERTY.
           DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterBorderlineUniform();
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->GetBorderlineWidth());
 
           // Check whether we must update shader.
           if(!mImpl->mAlwaysUsingBorderline && IsBorderlineRequired())
           {
             // Required to change shader mean, we didn't setup BORDERLINE_COLOR and BORDERLINE_OFFSET into mRenderer before. Set property now.
-            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->mBorderlineColor);
-            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
+            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->GetBorderlineColor());
+            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->GetBorderlineOffset());
 
             // Make Blend mode ON_WITHOUT_CULL for transparent mix color.
             mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
@@ -330,14 +333,17 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
         Vector4 color;
         if(value.Get(color))
         {
-          mImpl->mBorderlineColor = color;
+          if(mImpl->mDecorationData != nullptr || color != Vector4::ZERO)
+          {
+            mImpl->SetBorderlineColor(color);
+          }
         }
 
         if(DALI_UNLIKELY(mImpl->mRenderer && IsTypeAvailableForBorderline(mImpl->mType)))
         {
           // Unusual case. SetProperty called after OnInitialize().
           // Assume that DoAction call UPDATE_PROPERTY.
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->mBorderlineColor);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->GetBorderlineColor());
         }
         break;
       }
@@ -346,14 +352,17 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
         float offset;
         if(value.Get(offset))
         {
-          mImpl->mBorderlineOffset = offset;
+          if(mImpl->mDecorationData != nullptr || !Dali::EqualsZero(offset))
+          {
+            mImpl->SetBorderlineOffset(offset);
+          }
         }
 
         if(DALI_UNLIKELY(mImpl->mRenderer && IsTypeAvailableForBorderline(mImpl->mType)))
         {
           // Unusual case. SetProperty called after OnInitialize().
           // Assume that DoAction call UPDATE_PROPERTY.
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->GetBorderlineOffset());
         }
         break;
       }
@@ -367,7 +376,10 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
           Vector4 radius;
           if(value.Get(radius))
           {
-            mImpl->mCornerRadius = radius;
+            if(mImpl->mDecorationData != nullptr || radius != Vector4::ZERO)
+            {
+              mImpl->SetCornerRadius(radius);
+            }
           }
         }
         else
@@ -377,7 +389,10 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
           float radius;
           if(value.Get(radius))
           {
-            mImpl->mCornerRadius = Vector4(radius, radius, radius, radius);
+            if(mImpl->mDecorationData != nullptr || !Dali::EqualsZero(radius))
+            {
+              mImpl->SetCornerRadius(Vector4(radius, radius, radius, radius));
+            }
           }
         }
 
@@ -386,13 +401,13 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
           // Unusual case. SetProperty called after OnInitialize().
           // Assume that DoAction call UPDATE_PROPERTY.
           DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterCornerRadiusUniform();
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->mCornerRadius);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->GetCornerRadius());
 
           // Check whether we must update shader.
           if(!mImpl->mAlwaysUsingCornerRadius && IsRoundedCornerRequired())
           {
             // Required to change shader mean, we didn't setup CORNER_RADIUS_POLICY into mRenderer before. Set property now.
-            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
+            mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, static_cast<float>(mImpl->GetCornerRadiusPolicy()));
 
             // Change the shader must not be occured many times. we always have to use corner radius feature.
             mImpl->mAlwaysUsingCornerRadius = true;
@@ -423,12 +438,12 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap)
             case Toolkit::Visual::Transform::Policy::RELATIVE:
             case Toolkit::Visual::Transform::Policy::ABSOLUTE:
             {
-              mImpl->mCornerRadiusPolicy = policy;
+              mImpl->SetCornerRadiusPolicy(policy);
               if(DALI_UNLIKELY(mImpl->mRenderer))
               {
                 // Unusual case. SetProperty called after OnInitialize().
                 // Assume that DoAction call UPDATE_PROPERTY.
-                mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
+                mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, static_cast<float>(mImpl->GetCornerRadiusPolicy()));
               }
               break;
             }
@@ -583,13 +598,13 @@ void Visual::Base::CreatePropertyMap(Property::Map& map) const
 
     if(IsRoundedCornerRequired())
     {
-      mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<Vector4>(DecoratedVisualRenderer::Property::CORNER_RADIUS);
+      mImpl->SetCornerRadius(mImpl->mRenderer.GetProperty<Vector4>(DecoratedVisualRenderer::Property::CORNER_RADIUS));
     }
     if(IsBorderlineRequired())
     {
-      mImpl->mBorderlineWidth  = mImpl->mRenderer.GetProperty<float>(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH);
-      mImpl->mBorderlineColor  = mImpl->mRenderer.GetProperty<Vector4>(DecoratedVisualRenderer::Property::BORDERLINE_COLOR);
-      mImpl->mBorderlineOffset = mImpl->mRenderer.GetProperty<float>(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET);
+      mImpl->SetBorderlineWidth(mImpl->mRenderer.GetProperty<float>(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH));
+      mImpl->SetBorderlineColor(mImpl->mRenderer.GetProperty<Vector4>(DecoratedVisualRenderer::Property::BORDERLINE_COLOR));
+      mImpl->SetBorderlineOffset(mImpl->mRenderer.GetProperty<float>(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET));
     }
   }
 
@@ -618,15 +633,15 @@ void Visual::Base::CreatePropertyMap(Property::Map& map) const
 
   if(IsTypeAvailableForBorderline(mImpl->mType))
   {
-    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
-    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_COLOR, mImpl->mBorderlineColor);
-    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
+    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, mImpl->GetBorderlineWidth());
+    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_COLOR, mImpl->GetBorderlineColor());
+    map.Insert(Toolkit::DevelVisual::Property::BORDERLINE_OFFSET, mImpl->GetBorderlineOffset());
   }
 
   if(IsTypeAvailableForCornerRadius(mImpl->mType))
   {
-    map.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, mImpl->mCornerRadius);
-    map.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY, static_cast<int>(mImpl->mCornerRadiusPolicy));
+    map.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, mImpl->GetCornerRadius());
+    map.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY, mImpl->GetCornerRadiusPolicy());
   }
 }
 
@@ -682,9 +697,17 @@ bool Visual::Base::IsRoundedCornerRequired() const
     {
       // Update values from Renderer
       Property::Value value = mImpl->mRenderer.GetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS);
-      value.Get(mImpl->mCornerRadius);
+
+      Vector4 retValue = Vector4::ZERO;
+      if(value.Get(retValue))
+      {
+        if(mImpl->mDecorationData != nullptr || retValue != Vector4::ZERO)
+        {
+          mImpl->SetCornerRadius(retValue);
+        }
+      }
     }
-    return mImpl->mAlwaysUsingCornerRadius || !(mImpl->mCornerRadius == Vector4::ZERO);
+    return mImpl->mAlwaysUsingCornerRadius || !(mImpl->GetCornerRadius() == Vector4::ZERO);
   }
   return false;
 }
@@ -698,9 +721,17 @@ bool Visual::Base::IsBorderlineRequired() const
     {
       // Update values from Renderer
       Property::Value value = mImpl->mRenderer.GetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH);
-      value.Get(mImpl->mBorderlineWidth);
+
+      float retValue = 0.0f;
+      if(value.Get(retValue))
+      {
+        if(mImpl->mDecorationData != nullptr || !Dali::EqualsZero(retValue))
+        {
+          mImpl->SetBorderlineWidth(retValue);
+        }
+      }
     }
-    return mImpl->mAlwaysUsingBorderline || !EqualsZero(mImpl->mBorderlineWidth);
+    return mImpl->mAlwaysUsingBorderline || !EqualsZero(mImpl->GetBorderlineWidth());
   }
   return false;
 }
@@ -738,21 +769,21 @@ void Visual::Base::RegisterDecoration()
   {
     if(IsTypeAvailableForCornerRadius(mImpl->mType))
     {
-      if(mImpl->mAlwaysUsingCornerRadius || !(mImpl->mCornerRadius == Vector4::ZERO))
+      if(mImpl->mAlwaysUsingCornerRadius || !(mImpl->GetCornerRadius() == Vector4::ZERO))
       {
         DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterCornerRadiusUniform();
-        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->mCornerRadius);
-        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
+        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->GetCornerRadius());
+        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, static_cast<float>(mImpl->GetCornerRadiusPolicy()));
       }
     }
     if(IsTypeAvailableForBorderline(mImpl->mType))
     {
-      if(mImpl->mAlwaysUsingBorderline || !EqualsZero(mImpl->mBorderlineWidth))
+      if(mImpl->mAlwaysUsingBorderline || !EqualsZero(mImpl->GetBorderlineWidth()))
       {
         DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterBorderlineUniform();
-        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
-        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->mBorderlineColor);
-        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
+        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->GetBorderlineWidth());
+        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->GetBorderlineColor());
+        mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->GetBorderlineOffset());
       }
     }
   }
@@ -1208,8 +1239,8 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
         {
           // Update each values to renderer
           DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterCornerRadiusUniform();
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->mCornerRadius);
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS, mImpl->GetCornerRadius());
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, static_cast<float>(mImpl->GetCornerRadiusPolicy()));
 
           // Change shader
           UpdateShader();
@@ -1238,9 +1269,9 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
         {
           // Update each values to renderer
           DownCast<DecoratedVisualRenderer>(mImpl->mRenderer).RegisterBorderlineUniform();
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->mBorderlineColor);
-          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, mImpl->GetBorderlineWidth());
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_COLOR, mImpl->GetBorderlineColor());
+          mImpl->mRenderer.SetProperty(DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, mImpl->GetBorderlineOffset());
 
           // Change shader
           UpdateShader();