Calculate VisualRenderer coefficient only if updated. 02/289702/3
authorEunki Hong <eunkiki.hong@samsung.com>
Mon, 13 Mar 2023 17:41:06 +0000 (02:41 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 14 Mar 2023 03:47:31 +0000 (12:47 +0900)
Calculate UpdateArea need to be calculated for each RenderItems.

Since we were check the each properties changeness by Hash function,
The PreRender time was increased.

This patch make we change the coefficient only if the
AnimatableProperty was changed.

Change-Id: I9d86ab21de9f361cac652314b328d0ba5c6ab3d5
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
dali/internal/update/common/animatable-property.h
dali/internal/update/nodes/node-helper.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-property.h [new file with mode: 0644]
dali/internal/update/rendering/scene-graph-visual-renderer.h [new file with mode: 0644]

index 949fec7..612af3f 100644 (file)
@@ -79,7 +79,7 @@ protected: // for derived classes
   /**
    * Flag that the property has been Set during the current frame.
    */
-  void OnSet()
+  virtual void OnSet()
   {
     mDirtyFlags = SET_FLAG;
   }
@@ -87,7 +87,7 @@ protected: // for derived classes
   /**
    * Flag that the property has been Baked during the current frame.
    */
-  void OnBake()
+  virtual void OnBake()
   {
     mDirtyFlags = BAKED_FLAG;
   }
index 4997868..f6e5d40 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
 
 /*
- * 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.
  * It is assumed that successive elements are aligned, and that no padding
  * is inserted by the compiler.
  */
-#define PROPERTY_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _PROPERTY, _ELEMENT)       \
-  using _TEMPLATE##_PROPERTY = _TEMPLATE<_PROPERTY, OFFSET_##_BASE_ELEMENT>;  \
-  _TEMPLATE##_PROPERTY _ELEMENT;                                              \
-  enum                                                                        \
-  {                                                                           \
-    OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_PROPERTY) + OFFSET_##_BASE_ELEMENT \
+#define PROPERTY_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _PROPERTY, _ELEMENT)      \
+  using _TEMPLATE##_ELEMENT = _TEMPLATE<_PROPERTY, OFFSET_##_BASE_ELEMENT>;  \
+  _TEMPLATE##_ELEMENT _ELEMENT;                                              \
+  enum                                                                       \
+  {                                                                          \
+    OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_ELEMENT) + OFFSET_##_BASE_ELEMENT \
   };
 
 /*
index 752a56d..4978b56 100644 (file)
@@ -793,22 +793,9 @@ Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex,
   {
     auto& coefficient = mVisualProperties->mCoefficient;
 
-    // TODO : We may need to get some method that visual properties changed, without hash.
-    // Or, need to call this API in PreRender side.
-
-    uint64_t hash = 0xc70f6907UL;
-
-    hash = mVisualProperties->mTransformOffset.Hash(updateBufferIndex, hash);
-    hash = mVisualProperties->mTransformOffsetSizeMode.Hash(updateBufferIndex, hash);
-    hash = mVisualProperties->mTransformSize.Hash(updateBufferIndex, hash);
-    hash = mVisualProperties->mTransformOrigin.Hash(updateBufferIndex, hash);
-    hash = mVisualProperties->mTransformAnchorPoint.Hash(updateBufferIndex, hash);
-    hash = mVisualProperties->mExtraSize.Hash(updateBufferIndex, hash);
-
-    if(coefficient.hash != hash)
+    // Recalculate only if coefficient need to be updated.
+    if(coefficient.IsUpdated())
     {
-      coefficient.hash = hash;
-
       // VisualProperty
       const Vector2 transformOffset         = mVisualProperties->mTransformOffset.Get(updateBufferIndex);
       const Vector4 transformOffsetSizeMode = mVisualProperties->mTransformOffsetSizeMode.Get(updateBufferIndex);
@@ -859,20 +846,18 @@ Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex,
       coefficient.coefCA = transformSize * Vector2(transformOffsetSizeMode.z, transformOffsetSizeMode.w) + extraSize;
       coefficient.coefCB = coefficient.coefCA * transformAnchorPoint + transformOffset * Vector2(transformOffsetSizeMode.x, transformOffsetSizeMode.y);
     }
+
+    float coefD = 0.0f; ///< Default as 0.0f when we don't use decorated renderer.
+
     if(mVisualProperties->mExtendedProperties)
     {
       const auto decoratedVisualProperties = static_cast<VisualRenderer::AnimatableDecoratedVisualProperties*>(mVisualProperties->mExtendedProperties);
 
-      uint64_t decoratedHash = 0xc70f6907UL;
-
-      decoratedHash = decoratedVisualProperties->mBorderlineWidth.Hash(updateBufferIndex, decoratedHash);
-      decoratedHash = decoratedVisualProperties->mBorderlineOffset.Hash(updateBufferIndex, decoratedHash);
-      decoratedHash = decoratedVisualProperties->mBlurRadius.Hash(updateBufferIndex, decoratedHash);
+      auto& decoratedCoefficient = decoratedVisualProperties->mCoefficient;
 
-      if(coefficient.decoratedHash != decoratedHash)
+      // Recalculate only if coefficient need to be updated.
+      if(decoratedCoefficient.IsUpdated())
       {
-        coefficient.decoratedHash = decoratedHash;
-
         // DecoratedVisualProperty
         const float borderlineWidth  = decoratedVisualProperties->mBorderlineWidth.Get(updateBufferIndex);
         const float borderlineOffset = decoratedVisualProperties->mBorderlineOffset.Get(updateBufferIndex);
@@ -883,10 +868,12 @@ Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex,
         DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "blur radius       %5.3f\n", blurRadius);
 
         // D coefficients be used only decoratedVisual.
-        // It can be calculated parallely with transform.
-
-        coefficient.coefD = std::max((1.0f + Dali::Clamp(borderlineOffset, -1.0f, 1.0f)) * borderlineWidth, 2.0f * blurRadius);
+        // It can be calculated parallely with visual transform.
+        decoratedCoefficient.coefD = std::max((1.0f + Dali::Clamp(borderlineOffset, -1.0f, 1.0f)) * borderlineWidth, 2.0f * blurRadius);
       }
+
+      // Update coefD so we can use this value out of this scope.
+      coefD = decoratedCoefficient.coefD;
     }
 
     // Calculate vertex position by coefficient
@@ -916,8 +903,8 @@ Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex,
     // TODO : We need to re-generate coefficient to consitder area width/height
     const Vector4 resultArea = Vector4(originalXY.x,
                                        originalXY.y,
-                                       scaleVertexPosition.x + 2.0f * abs(basicVertexPosition.x) + coefficient.coefD,
-                                       scaleVertexPosition.y + 2.0f * abs(basicVertexPosition.y) + coefficient.coefD);
+                                       scaleVertexPosition.x + 2.0f * abs(basicVertexPosition.x) + coefD,
+                                       scaleVertexPosition.y + 2.0f * abs(basicVertexPosition.y) + coefD);
 
     DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "%f %f %f %f--> %f %f %f %f\n", originalUpdateArea.x, originalUpdateArea.y, originalUpdateArea.z, originalUpdateArea.w, resultArea.x, resultArea.y, resultArea.z, resultArea.w);
 
index 889a791..b6fd972 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/property-owner.h>
 #include <dali/internal/update/common/uniform-map.h>
+#include <dali/internal/update/rendering/scene-graph-visual-renderer.h>
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/renderer.h> // Dali::Renderer
 
@@ -70,93 +71,6 @@ using RendererContainer = Dali::Vector<RendererKey>;
 using RendererIter      = RendererContainer::Iterator;
 using RendererConstIter = RendererContainer::ConstIterator;
 
-namespace VisualRenderer
-{
-struct AnimatableVisualProperties
-{
-  AnimatableVisualProperties()
-  : mTransformOffset(Vector2::ZERO),
-    mTransformSize(Vector2::ONE),
-    mTransformOrigin(Vector2::ZERO),
-    mTransformAnchorPoint(Vector2::ZERO),
-    mTransformOffsetSizeMode(Vector4::ZERO),
-    mExtraSize(Vector2::ZERO),
-    mMixColor(Vector3::ONE),
-    mPreMultipliedAlpha(0.0f),
-    mExtendedPropertiesDeleteFunction(nullptr)
-  {
-  }
-
-  ~AnimatableVisualProperties()
-  {
-    if(mExtendedProperties && mExtendedPropertiesDeleteFunction)
-    {
-      mExtendedPropertiesDeleteFunction(mExtendedProperties);
-    }
-  }
-
-  /**
-   * @brief Cached coefficient value when we calculate visual transformed update size.
-   * It can reduce complexity of calculate the vertex position.
-   *
-   * Vector2 vertexPosition = (XA * aPosition + XB) * originalSize + (CA * aPosition + CB) + Vector2(D, D) * aPosition
-   */
-  struct VisualTransformedUpdateSizeCoefficientCache
-  {
-    Vector2 coefXA{Vector2::ZERO};
-    Vector2 coefXB{Vector2::ZERO};
-    Vector2 coefCA{Vector2::ZERO};
-    Vector2 coefCB{Vector2::ZERO};
-    float   coefD{0.0f};
-
-    uint64_t hash{0u};
-    uint64_t decoratedHash{0u};
-  };
-  VisualTransformedUpdateSizeCoefficientCache mCoefficient; ///< Coefficient value to calculate visual transformed update size by VisualProperties more faster.
-
-  AnimatableProperty<Vector2> mTransformOffset;
-  AnimatableProperty<Vector2> mTransformSize;
-  AnimatableProperty<Vector2> mTransformOrigin;
-  AnimatableProperty<Vector2> mTransformAnchorPoint;
-  AnimatableProperty<Vector4> mTransformOffsetSizeMode;
-  AnimatableProperty<Vector2> mExtraSize;
-  AnimatableProperty<Vector3> mMixColor;
-  AnimatableProperty<float>   mPreMultipliedAlpha;
-
-  void* mExtendedProperties{nullptr};                        // Enable derived class to extend properties further
-  void (*mExtendedPropertiesDeleteFunction)(void*){nullptr}; // Derived class's custom delete functor
-};
-
-struct AnimatableDecoratedVisualProperties
-{
-  AnimatableDecoratedVisualProperties()
-  : mCornerRadius(Vector4::ZERO),
-    mCornerRadiusPolicy(1.0f),
-    mBorderlineWidth(0.0f),
-    mBorderlineColor(Color::BLACK),
-    mBorderlineOffset(0.0f),
-    mBlurRadius(0.0f)
-  {
-  }
-  ~AnimatableDecoratedVisualProperties()
-  {
-  }
-
-  // Delete function of AnimatableDecoratedVisualProperties* converted as void*
-  static void DeleteFunction(void* data)
-  {
-    delete static_cast<AnimatableDecoratedVisualProperties*>(data);
-  }
-
-  AnimatableProperty<Vector4> mCornerRadius;
-  AnimatableProperty<float>   mCornerRadiusPolicy;
-  AnimatableProperty<float>   mBorderlineWidth;
-  AnimatableProperty<Vector4> mBorderlineColor;
-  AnimatableProperty<float>   mBorderlineOffset;
-  AnimatableProperty<float>   mBlurRadius;
-};
-} // namespace VisualRenderer
-
 class Renderer : public PropertyOwner,
                  public UniformMapDataProvider,
                  public RenderDataProvider
diff --git a/dali/internal/update/rendering/scene-graph-visual-renderer-property.h b/dali/internal/update/rendering/scene-graph-visual-renderer-property.h
new file mode 100644 (file)
index 0000000..5360173
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_PROPERTY_H
+#define DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_PROPERTY_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/internal/update/common/animatable-property.h>
+
+namespace Dali::Internal::SceneGraph::VisualRenderer
+{
+/**
+ * @brief Base class for VisualRender properties coefficient.
+ * It will mark update flag as dirty if some properties are changed.
+ * By that update flag, we can determine that we need to re-calculate
+ * coefficient values or not.
+ */
+struct VisualRendererCoefficientCacheBase
+{
+  VisualRendererCoefficientCacheBase()
+  : mUpdated(true)
+  {
+  }
+
+  virtual ~VisualRendererCoefficientCacheBase() = default;
+
+  /**
+   * @brief Check whether this cache need to be update.
+   * After call this API, update flag will be reset.
+   *
+   * @return True if this coefficient updated. False otherwise.
+   */
+  bool IsUpdated()
+  {
+    bool ret = mUpdated;
+    mUpdated = false;
+    return ret;
+  }
+
+  /**
+   * @brief Mark update flag as true.
+   */
+  void Update()
+  {
+    mUpdated = true;
+  }
+
+private:
+  bool mUpdated; ///< Updated flag for this coefficient cache.
+};
+
+/**
+ * @brief Special AnimatableProperty class for VisualRenderer properties
+ * that will be used for coefficient calculation.
+ * It will be used to avoid useless coefficient update.
+ *
+ * @tparam T Type of animatable property
+ */
+template<typename T, size_t CacheBaseDataOffset>
+struct VisualRendererProperty : public AnimatableProperty<T>
+{
+  enum
+  {
+    VISUAL_RENDERER_CACHE_BASE_DATA_OFFSET = CacheBaseDataOffset
+  };
+  VisualRendererCoefficientCacheBase* GetCacheBaseData()
+  {
+    return reinterpret_cast<VisualRendererCoefficientCacheBase*>(
+      reinterpret_cast<uint8_t*>(this) - VISUAL_RENDERER_CACHE_BASE_DATA_OFFSET);
+  }
+  const VisualRendererCoefficientCacheBase* GetCacheBaseData() const
+  {
+    return reinterpret_cast<const VisualRendererCoefficientCacheBase*>(
+      reinterpret_cast<const uint8_t*>(this) - VISUAL_RENDERER_CACHE_BASE_DATA_OFFSET);
+  }
+
+public:
+  /**
+   * Constructor, initialize the dirty flag
+   */
+  VisualRendererProperty(const T& initialValue)
+  : AnimatableProperty<T>(initialValue)
+  {
+  }
+
+  /**
+   * Virtual destructor.
+   */
+  ~VisualRendererProperty() override = default;
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::AnimatablePropertyBase::OnSet
+   */
+  void OnSet() override
+  {
+    GetCacheBaseData()->Update();
+    AnimatablePropertyBase::OnSet();
+  }
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::AnimatablePropertyBase::OnBake
+   */
+  void OnBake() override
+  {
+    GetCacheBaseData()->Update();
+    AnimatablePropertyBase::OnBake();
+  }
+};
+
+} // namespace Dali::Internal::SceneGraph::VisualRenderer
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_PROPERTY_H
diff --git a/dali/internal/update/rendering/scene-graph-visual-renderer.h b/dali/internal/update/rendering/scene-graph-visual-renderer.h
new file mode 100644 (file)
index 0000000..610aee0
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_H
+#define DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <stdint.h> ///< For size_t
+
+// INTERNAL INCLUDES
+#include <dali/internal/update/nodes/node-helper.h> ///< For property wrapper macro
+#include <dali/internal/update/rendering/scene-graph-visual-renderer-property.h>
+
+namespace Dali::Internal::SceneGraph::VisualRenderer
+{
+struct AnimatableVisualProperties
+{
+  AnimatableVisualProperties()
+  : mTransformOffset(Vector2::ZERO),
+    mTransformSize(Vector2::ONE),
+    mTransformOrigin(Vector2::ZERO),
+    mTransformAnchorPoint(Vector2::ZERO),
+    mTransformOffsetSizeMode(Vector4::ZERO),
+    mExtraSize(Vector2::ZERO),
+    mMixColor(Vector3::ONE),
+    mPreMultipliedAlpha(0.0f),
+    mExtendedPropertiesDeleteFunction(nullptr)
+  {
+  }
+
+  ~AnimatableVisualProperties()
+  {
+    if(mExtendedProperties && mExtendedPropertiesDeleteFunction)
+    {
+      mExtendedPropertiesDeleteFunction(mExtendedProperties);
+    }
+  }
+
+  /**
+   * @brief Cached coefficient value when we calculate visual transformed update size.
+   * It can reduce complexity of calculate the vertex position.
+   *
+   * Vector2 vertexPosition = (XA * aPosition + XB) * originalSize + (CA * aPosition + CB)
+   */
+  struct VisualTransformedUpdateSizeCoefficientCache : public VisualRendererCoefficientCacheBase
+  {
+    VisualTransformedUpdateSizeCoefficientCache()
+    : VisualRendererCoefficientCacheBase(),
+      coefXA(Vector2::ZERO),
+      coefXB(Vector2::ZERO),
+      coefCA(Vector2::ZERO),
+      coefCB(Vector2::ZERO)
+    {
+    }
+
+    ~VisualTransformedUpdateSizeCoefficientCache() override = default;
+
+    Vector2 coefXA;
+    Vector2 coefXB;
+    Vector2 coefCA;
+    Vector2 coefCB;
+  };
+
+public: // Default properties
+  // Define a base offset for the following wrappers. The wrapper macros calculate offsets from the previous
+  // element such that each wrapper type generates a compile time offset to the CoefficientCache data.
+  BASE(VisualTransformedUpdateSizeCoefficientCache, mCoefficient); ///< Coefficient value to calculate visual transformed update size by VisualProperties more faster.
+
+  PROPERTY_WRAPPER(mCoefficient, VisualRendererProperty, Vector2, mTransformOffset);
+  PROPERTY_WRAPPER(mTransformOffset, VisualRendererProperty, Vector2, mTransformSize);
+  PROPERTY_WRAPPER(mTransformSize, VisualRendererProperty, Vector2, mTransformOrigin);
+  PROPERTY_WRAPPER(mTransformOrigin, VisualRendererProperty, Vector2, mTransformAnchorPoint);
+  PROPERTY_WRAPPER(mTransformAnchorPoint, VisualRendererProperty, Vector4, mTransformOffsetSizeMode);
+  PROPERTY_WRAPPER(mTransformOffsetSizeMode, VisualRendererProperty, Vector2, mExtraSize);
+
+  // Properties that don't give any effort to coefficient.
+  AnimatableProperty<Vector3> mMixColor;
+  AnimatableProperty<float>   mPreMultipliedAlpha;
+
+public:                                                      // Extended properties
+  void* mExtendedProperties{nullptr};                        // Enable derived class to extend properties further
+  void (*mExtendedPropertiesDeleteFunction)(void*){nullptr}; // Derived class's custom delete functor
+};
+
+struct AnimatableDecoratedVisualProperties
+{
+  AnimatableDecoratedVisualProperties()
+  : mBorderlineWidth(0.0f),
+    mBorderlineOffset(0.0f),
+    mBlurRadius(0.0f),
+    mBorderlineColor(Color::BLACK),
+    mCornerRadius(Vector4::ZERO),
+    mCornerRadiusPolicy(1.0f)
+  {
+  }
+  ~AnimatableDecoratedVisualProperties()
+  {
+  }
+
+  // Delete function of AnimatableDecoratedVisualProperties* converted as void*
+  static void DeleteFunction(void* data)
+  {
+    delete static_cast<AnimatableDecoratedVisualProperties*>(data);
+  }
+
+  /**
+   * @brief Cached coefficient value when we calculate visual transformed update size.
+   * It can reduce complexity of calculate the vertex position.
+   *
+   * Vector2 vertexPosition += Vector2(D, D) * aPosition
+   */
+  struct DecoratedVisualTransformedUpdateSizeCoefficientCache : public VisualRendererCoefficientCacheBase
+  {
+    DecoratedVisualTransformedUpdateSizeCoefficientCache()
+    : VisualRendererCoefficientCacheBase(),
+      coefD(0.0f)
+    {
+    }
+
+    ~DecoratedVisualTransformedUpdateSizeCoefficientCache() override = default;
+
+    float coefD;
+  };
+
+public: // Default properties
+  // Define a base offset for the following wrappers. The wrapper macros calculate offsets from the previous
+  // element such that each wrapper type generates a compile time offset to the CoefficientCache data.
+  BASE(DecoratedVisualTransformedUpdateSizeCoefficientCache, mCoefficient); ///< Coefficient value to calculate visual transformed update size by VisualProperties more faster.
+
+  PROPERTY_WRAPPER(mCoefficient, VisualRendererProperty, float, mBorderlineWidth);
+  PROPERTY_WRAPPER(mBorderlineWidth, VisualRendererProperty, float, mBorderlineOffset);
+  PROPERTY_WRAPPER(mBorderlineOffset, VisualRendererProperty, float, mBlurRadius);
+
+  // Properties that don't give any effort to coefficient.
+  AnimatableProperty<Vector4> mBorderlineColor;
+  AnimatableProperty<Vector4> mCornerRadius;
+  AnimatableProperty<float>   mCornerRadiusPolicy;
+};
+} // namespace Dali::Internal::SceneGraph::VisualRenderer
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_VISUAL_RENDERER_H