(Partial Update) Change UPDATE_SIZE_HINT to UPDATE_AREA_HINT 73/278673/2
authorHeeyong Song <heeyong.song@samsung.com>
Mon, 25 Jul 2022 03:07:45 +0000 (12:07 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 26 Jul 2022 06:58:57 +0000 (15:58 +0900)
Change the property name and the type to Vector4 to support offset also

Change-Id: I589855950cf158d833506a782d0983da9d0e97cc

14 files changed:
automated-tests/src/dali/utc-Dali-Actor.cpp
dali/devel-api/actors/actor-devel.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-property-handler.cpp
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-item.cpp
dali/internal/render/common/render-item.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/data-providers/node-data-provider.h
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/actors/actor.h

index e233914..d4debe9 100644 (file)
@@ -8714,7 +8714,7 @@ int utcDaliActorPartialUpdateActorsWithSizeHint(void)
   Actor actor = CreateRenderableActor();
   actor.SetProperty(Actor::Property::POSITION, Vector3(64.0f, 64.0f, 0.0f));
   actor.SetProperty(Actor::Property::SIZE, Vector3(32.0f, 32.0f, 0.0f));
-  actor.SetProperty(DevelActor::Property::UPDATE_SIZE_HINT, Vector3(64.0f, 64.0f, 0.0f));
+  actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(0.0f, 0.0f, 64.0f, 64.0f));
   actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
   application.GetScene().Add(actor);
 
@@ -8734,6 +8734,90 @@ int utcDaliActorPartialUpdateActorsWithSizeHint(void)
   DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
   DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
 
+  // Reset
+  actor.Unparent();
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Chnage UPDATE_AREA_HINT
+  actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(16.0f, 16.0f, 32.0f, 32.0f));
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(64, 704, 48, 48);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  // Reset
+  actor.Unparent();
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Chnage UPDATE_AREA_HINT
+  actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(-32.0f, -16.0f, 64.0f, 64.0f));
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(0, 720, 80, 80);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
   END_TEST;
 }
 
index 25b6cef..80b52dc 100644 (file)
@@ -95,6 +95,7 @@ enum Type
   IS_LAYER                   = Dali::Actor::Property::IS_LAYER,
   CONNECTED_TO_SCENE         = Dali::Actor::Property::CONNECTED_TO_SCENE,
   KEYBOARD_FOCUSABLE         = Dali::Actor::Property::KEYBOARD_FOCUSABLE,
+  UPDATE_AREA_HINT           = Dali::Actor::Property::UPDATE_AREA_HINT,
 
   /**
    * @brief Sets the sibling order of the actor so depth position can be defined within the same parent.
@@ -106,13 +107,6 @@ enum Type
   SIBLING_ORDER,
 
   /**
-   * @brief Sets the update size hint of the actor.
-   * @details Name "updateSizeHint", type Property::VECTOR2.
-   * @note Overrides the size used for the actor damaged area calculation. Affected by the actor model view matrix.
-   */
-  UPDATE_SIZE_HINT,
-
-  /**
     * @brief If this actor receives a touch-start event, then all following touch events are sent to this actor until a touch-end.
     * @details Name "captureAllTouchAfterStart", type Property::BOOLEAN
     * @note Default is false, i.e. actor under touch event will receive the touch even if touch started on this actor
index f9de794..4414f1d 100644 (file)
@@ -141,8 +141,8 @@ DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_
 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
+DALI_PROPERTY("updateAreaHint", VECTOR4, true, false, false, Dali::Actor::Property::UPDATE_AREA_HINT)
 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
-DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
@@ -1707,10 +1707,10 @@ void Actor::SetInheritLayoutDirection(bool inherit)
   }
 }
 
-void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
+void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
 {
   // node is being used in a separate thread; queue a message to set the value & base value
-  SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
+  SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateAreaHint, &AnimatableProperty<Vector4>::Bake, updateAreaHint);
 }
 
 } // namespace Internal
index 51fb710..d0d985f 100644 (file)
@@ -1877,10 +1877,10 @@ private:
   }
 
   /**
-   * @brief Sets the update size hint of an actor.
-   * @param [in] updateSizeHint The update size hint.
+   * @brief Sets the update area hint of an actor.
+   * @param [in] updateAreaHint The update area hint.
    */
-  void SetUpdateSizeHint(const Vector2& updateSizeHint);
+  void SetUpdateAreaHint(const Vector4& updateAreaHint);
 
 protected:
   ActorParentImpl    mParentImpl;   ///< Implementation of ActorParent;
index 8e3aeaa..b9d63cd 100644 (file)
@@ -563,9 +563,9 @@ void Actor::PropertyHandler::SetDefaultProperty(Internal::Actor& actor, Property
       break;
     }
 
-    case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
+    case Dali::Actor::Property::UPDATE_AREA_HINT:
     {
-      actor.SetUpdateSizeHint(property.Get<Vector2>());
+      actor.SetUpdateAreaHint(property.Get<Vector4>());
       break;
     }
 
@@ -1874,10 +1874,10 @@ bool Actor::PropertyHandler::GetCurrentPropertyValue(const Internal::Actor& acto
       break;
     }
 
-    case Dali::DevelActor::Property::UPDATE_SIZE_HINT:
+    case Dali::Actor::Property::UPDATE_AREA_HINT:
     {
       // node is being used in a separate thread, the value from the previous update is the same, set by user
-      value = Vector2(actor.GetNode().GetUpdateSizeHint());
+      value = Vector4(actor.GetNode().GetUpdateAreaHint());
       break;
     }
 
index ff82cd3..2cfd8a9 100644 (file)
@@ -429,7 +429,7 @@ inline void RenderAlgorithms::SetupScissorClipping(
       // This is a clipping node. We generate the AABB for this node and intersect it with the previous intersection further up the tree.
 
       // Get the AABB bounding box for the current render item.
-      const ClippingBox scissorBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
+      const ClippingBox scissorBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3::ZERO, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
 
       // Get the AABB for the parent item that we must intersect with.
       const ClippingBox& parentBox(mScissorStack.back());
@@ -471,7 +471,7 @@ inline void RenderAlgorithms::SetupScissorClipping(
     {
       // store clipping box inside the render callback input structure
       auto& input       = item.mRenderer->GetRenderCallbackInput();
-      input.clippingBox = ClippingBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
+      input.clippingBox = ClippingBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3::ZERO, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
     }
   }
 }
@@ -636,7 +636,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
     bool skip = true;
     if(!rootClippingRect.IsEmpty())
     {
-      auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mUpdateSize, mViewportRectangle.width, mViewportRectangle.height);
+      auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(item.mUpdateArea.x, item.mUpdateArea.y, 0.0f), Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f), mViewportRectangle.width, mViewportRectangle.height);
 
       if(rect.Intersect(rootClippingRect))
       {
index 4a4733f..9b3ba8c 100644 (file)
@@ -55,7 +55,7 @@ RenderItem::RenderItem()
 
 RenderItem::~RenderItem() = default;
 
-ClippingBox RenderItem::CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& size)
+ClippingBox RenderItem::CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& position, const Vector3& size)
 {
   // Calculate extent vector of the AABB:
   const float halfActorX = size.x * 0.5f;
@@ -68,9 +68,9 @@ ClippingBox RenderItem::CalculateTransformSpaceAABB(const Matrix& transformMatri
   // We place the coords into the array in clockwise order, so we know opposite corners are always i + 2 from corner i.
   // We skip the 4th corner here as we can calculate that from the other 3, bypassing matrix multiplication.
   // Note: The below transform methods use a fast (2D) matrix multiply (only 4 multiplications are done).
-  Vector2 corners[4]{Transform2D(transformMatrix, -halfActorX, -halfActorY),
-                     Transform2D(transformMatrix, halfActorX, -halfActorY),
-                     Transform2D(transformMatrix, halfActorX, halfActorY)};
+  Vector2 corners[4]{Transform2D(transformMatrix, -halfActorX + position.x, -halfActorY + position.y),
+                     Transform2D(transformMatrix, halfActorX + position.x, -halfActorY + position.y),
+                     Transform2D(transformMatrix, halfActorX + position.x, halfActorY + position.y)};
 
   // As we are dealing with a rectangle, we can do a fast calculation to get the 4th corner from knowing the other 3 (even if rotated).
   corners[3] = Vector2(corners[0] + (corners[2] - corners[1]));
@@ -106,7 +106,7 @@ ClippingBox RenderItem::CalculateTransformSpaceAABB(const Matrix& transformMatri
   return ClippingBox(x, y, z - x, fabsf(w - y));
 }
 
-ClippingBox RenderItem::CalculateViewportSpaceAABB(const Matrix& modelViewMatrix, const Vector3& size, const int viewportWidth, const int viewportHeight)
+ClippingBox RenderItem::CalculateViewportSpaceAABB(const Matrix& modelViewMatrix, const Vector3& position, const Vector3& size, const int viewportWidth, const int viewportHeight)
 {
   // Calculate extent vector of the AABB:
   const float halfActorX = size.x * 0.5f;
@@ -119,9 +119,9 @@ ClippingBox RenderItem::CalculateViewportSpaceAABB(const Matrix& modelViewMatrix
   // We place the coords into the array in clockwise order, so we know opposite corners are always i + 2 from corner i.
   // We skip the 4th corner here as we can calculate that from the other 3, bypassing matrix multiplication.
   // Note: The below transform methods use a fast (2D) matrix multiply (only 4 multiplications are done).
-  Vector2 corners[4]{Transform2D(modelViewMatrix, -halfActorX, -halfActorY),
-                     Transform2D(modelViewMatrix, halfActorX, -halfActorY),
-                     Transform2D(modelViewMatrix, halfActorX, halfActorY)};
+  Vector2 corners[4]{Transform2D(modelViewMatrix, -halfActorX + position.x, -halfActorY + position.y),
+                     Transform2D(modelViewMatrix, halfActorX + position.x, -halfActorY + position.y),
+                     Transform2D(modelViewMatrix, halfActorX + position.x, halfActorY + position.y)};
 
   // As we are dealing with a rectangle, we can do a fast calculation to get the 4th corner from knowing the other 3 (even if rotated).
   corners[3] = Vector2(corners[0] + (corners[2] - corners[1]));
index 66d7158..d1ca0f4 100644 (file)
@@ -56,9 +56,10 @@ struct RenderItem
    * See below for caveats.
    *
    * @param[in]    transformMatrix   The matrix for converting to a different space
+   * @param[in]    position          The center position of the render item
    * @param[in]    size              The size of the render item
    */
-  static ClippingBox CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& size);
+  static ClippingBox CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& position, const Vector3& size);
 
   /**
    * @brief This method is an optimized calculation of a viewport-space AABB (Axis-Aligned-Bounding-Box).
@@ -72,12 +73,13 @@ struct RenderItem
    * Note: ASSUMES THAT THE VIEWPORT COVERS THE SCREEN AND THAT THE CANVAS SIZE AND VIEWPORT SIZE ARE THE SAME!!!!!  (Not the case for magnifier)
    *
    * @param[in]    modelViewMatrix   The model view matrix
+   * @param[in]    position          The center position of the render item
    * @param[in]    size              The size of the render item
    * @param[in]    viewportWidth     The width of the viewport to calculate for
    * @param[in]    viewportHeight    The height of the viewport to calculate for
    * @return                         The AABB coordinates in viewport-space (x, y, width, height)
    */
-  static ClippingBox CalculateViewportSpaceAABB(const Matrix& modelViewMatrix, const Vector3& size, const int viewportWidth, const int viewportHeight);
+  static ClippingBox CalculateViewportSpaceAABB(const Matrix& modelViewMatrix, const Vector3& position, const Vector3& size, const int viewportWidth, const int viewportHeight);
 
   /**
    * Overriden delete operator.
@@ -90,10 +92,10 @@ struct RenderItem
   Matrix            mModelViewMatrix;
   Vector4           mColor;
   Vector3           mSize;
-  Vector3           mUpdateSize;
+  Vector4           mUpdateArea; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
   Render::Renderer* mRenderer;
   Node*             mNode;
-  const void*       mTextureSet; //< Used for sorting only
+  const void*       mTextureSet; ///< Used for sorting only
   int               mDepthIndex;
   bool              mIsOpaque : 1;
   bool              mIsUpdated : 1;
index d0de5ef..72b9632 100644 (file)
@@ -603,7 +603,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
             {
               RenderItem& item = renderList->GetItem(listIndex);
               // If the item does 3D transformation, do early exit and clean the damaged rect array
-              if(item.mUpdateSize == Vector3::ZERO)
+              if(item.mUpdateArea == Vector4::ZERO)
               {
                 return;
               }
@@ -617,7 +617,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
               {
                 item.mIsUpdated = false;
 
-                rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mUpdateSize, viewportRect.width, viewportRect.height);
+                rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(item.mUpdateArea.x, item.mUpdateArea.y, 0.0f), Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f), viewportRect.width, viewportRect.height);
                 if(rect.IsValid() && rect.Intersect(viewportRect) && !rect.IsEmpty())
                 {
                   const int left   = rect.x;
index 636528d..0c02dc7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_NODE_DATA_PROVIDER_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -40,15 +40,15 @@ class TextureSet;
  */
 struct PartialRenderingCacheInfo
 {
-  Node*             node{nullptr};       /// Node associated with the entry
-  const Renderer*   renderer{nullptr};   /// Renderer object
-  const TextureSet* textureSet{nullptr}; /// TextureSet object
-  Matrix            matrix{};            /// Model-view matrix
-  Vector4           color{};             /// Color
-  Vector3           size{};              /// Size
-  Vector3           updatedSize{};       /// Updated size
-  bool              isOpaque{};          /// Opacity state
-  uint32_t          depthIndex{0u};      /// Depth index
+  Node*             node{nullptr};         /// Node associated with the entry
+  const Renderer*   renderer{nullptr};     /// Renderer object
+  const TextureSet* textureSet{nullptr};   /// TextureSet object
+  Matrix            matrix{};              /// Model-view matrix
+  Vector4           color{};               /// Color
+  Vector3           size{};                /// Size
+  Vector4           updatedPositionSize{}; /// Updated position/size (x, y, width, height)
+  bool              isOpaque{};            /// Opacity state
+  uint32_t          depthIndex{0u};        /// Depth index
 };
 
 /**
index 67b47a5..74b76c1 100644 (file)
@@ -137,34 +137,34 @@ bool CompareItems3DWithClipping(const RenderInstructionProcessor::SortAttributes
 }
 
 /**
- * Set the update size of the node
+ * Set the update area of the node
  * @param[in] node The node of the renderer
  * @param[in] isLayer3d Whether we are processing a 3D layer or not
  * @param[in,out] nodeWorldMatrix The world matrix of the node
  * @param[in,out] nodeSize The size of the node
- * @param[in,out] nodeUpdateSize The update size of the node
+ * @param[in,out] nodeUpdateArea The update area of the node
  *
- * @return True if node use it's own UpdateSizeHint, or z transform occured. False if we use nodeUpdateSize equal with nodeSize.
+ * @return True if node use it's own UpdateAreaHint, or z transform occured. False if we use nodeUpdateArea equal with Vector4(0, 0, nodeSize.width, nodeSize.height).
  */
-inline bool SetNodeUpdateSize(Node* node, bool isLayer3d, Matrix& nodeWorldMatrix, Vector3& nodeSize, Vector3& nodeUpdateSize)
+inline bool SetNodeUpdateArea(Node* node, bool isLayer3d, Matrix& nodeWorldMatrix, Vector3& nodeSize, Vector4& nodeUpdateArea)
 {
   node->GetWorldMatrixAndSize(nodeWorldMatrix, nodeSize);
 
-  if(node->GetUpdateSizeHint() == Vector3::ZERO)
+  if(node->GetUpdateAreaHint() == Vector4::ZERO)
   {
     // RenderItem::CalculateViewportSpaceAABB cannot cope with z transform
     // I don't use item.mModelMatrix.GetTransformComponents() for z transform, would be too slow
     if(!isLayer3d && nodeWorldMatrix.GetZAxis() == Vector3(0.0f, 0.0f, 1.0f))
     {
-      nodeUpdateSize = nodeSize;
+      nodeUpdateArea = Vector4(0.0f, 0.0f, nodeSize.width, nodeSize.height);
       return false;
     }
-    // Keep nodeUpdateSize as Vector3::ZERO, and return true.
+    // Keep nodeUpdateArea as Vector4::ZERO, and return true.
     return true;
   }
   else
   {
-    nodeUpdateSize = node->GetUpdateSizeHint();
+    nodeUpdateArea = node->GetUpdateAreaHint();
     return true;
   }
 }
@@ -195,9 +195,9 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
   Node*   node = renderable.mNode;
   Matrix  nodeWorldMatrix(false);
   Vector3 nodeSize;
-  Vector3 nodeUpdateSize;
-  bool    nodeUpdateSizeSet(false);
-  bool    nodeUpdateSizeUseHint(false);
+  Vector4 nodeUpdateArea;
+  bool    nodeUpdateAreaSet(false);
+  bool    nodeUpdateAreaUseHint(false);
   Matrix  nodeModelViewMatrix(false);
   bool    nodeModelViewMatrixSet(false);
 
@@ -212,11 +212,11 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
 
     if(inside && !isLayer3d && viewportSet)
     {
-      nodeUpdateSizeUseHint = SetNodeUpdateSize(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateSize);
-      nodeUpdateSizeSet     = true;
+      nodeUpdateAreaUseHint = SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
+      nodeUpdateAreaSet     = true;
 
       const Vector3& scale = node->GetWorldScale(updateBufferIndex);
-      const Vector3& size  = nodeUpdateSize * scale;
+      const Vector3& size  = Vector3(nodeUpdateArea.z, nodeUpdateArea.w, 1.0f) * scale;
 
       if(size.LengthSquared() > Math::MACHINE_EPSILON_1000)
       {
@@ -226,7 +226,7 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
         // Assume actors are at z=0, compute AABB in view space & test rect intersection
         // against z=0 plane boundaries for frustum. (NOT viewport). This should take into account
         // magnification due to FOV etc.
-        ClippingBox boundingBox = RenderItem::CalculateTransformSpaceAABB(nodeModelViewMatrix, nodeUpdateSize);
+        ClippingBox boundingBox = RenderItem::CalculateTransformSpaceAABB(nodeModelViewMatrix, Vector3(nodeUpdateArea.x, nodeUpdateArea.y, 0.0f), Vector3(nodeUpdateArea.z, nodeUpdateArea.w, 0.0f));
         ClippingBox clippingBox(camera.mLeftClippingPlane, camera.mBottomClippingPlane, camera.mRightClippingPlane - camera.mLeftClippingPlane, fabsf(camera.mBottomClippingPlane - camera.mTopClippingPlane));
         inside = clippingBox.Intersects(boundingBox);
       }
@@ -298,19 +298,21 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
 
       item.mIsUpdated |= isLayer3d;
 
-      if(!nodeUpdateSizeSet)
+      if(!nodeUpdateAreaSet)
       {
-        nodeUpdateSizeUseHint = SetNodeUpdateSize(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateSize);
+        nodeUpdateAreaUseHint = SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
       }
 
       item.mSize        = nodeSize;
-      item.mUpdateSize  = nodeUpdateSize;
+      item.mUpdateArea  = nodeUpdateArea;
       item.mModelMatrix = nodeWorldMatrix;
 
       // Apply transform informations if node doesn't have update size hint and use VisualRenderer.
-      if(!nodeUpdateSizeUseHint && renderable.mRenderer && renderable.mRenderer->GetVisualProperties())
+      if(!nodeUpdateAreaUseHint && renderable.mRenderer && renderable.mRenderer->GetVisualProperties())
       {
-        item.mUpdateSize = renderable.mRenderer->CalculateVisualTransformedUpdateSize(updateBufferIndex, item.mUpdateSize);
+        Vector3 updateSize = renderable.mRenderer->CalculateVisualTransformedUpdateSize(updateBufferIndex, Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f));
+        item.mUpdateArea.z = updateSize.x;
+        item.mUpdateArea.w = updateSize.y;
       }
 
       if(!nodeModelViewMatrixSet)
@@ -319,9 +321,9 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
       }
       item.mModelViewMatrix = nodeModelViewMatrix;
 
-      partialRenderingCacheInfo.matrix      = item.mModelViewMatrix;
-      partialRenderingCacheInfo.size        = item.mSize;
-      partialRenderingCacheInfo.updatedSize = item.mUpdateSize;
+      partialRenderingCacheInfo.matrix              = item.mModelViewMatrix;
+      partialRenderingCacheInfo.size                = item.mSize;
+      partialRenderingCacheInfo.updatedPositionSize = item.mUpdateArea;
 
       item.mIsUpdated = partialRenderingData.IsUpdated() || item.mIsUpdated;
 
index 5ae5e1c..c7a1dbb 100644 (file)
@@ -80,7 +80,7 @@ Node::Node()
   mVisible(true),
   mCulled(false),
   mColor(Color::WHITE),
-  mUpdateSizeHint(Vector3::ZERO),
+  mUpdateAreaHint(Vector4::ZERO),
   mWorldPosition(TRANSFORM_PROPERTY_WORLD_POSITION, Vector3(0.0f, 0.0f, 0.0f)), // Zero initialized by default
   mWorldScale(TRANSFORM_PROPERTY_WORLD_SCALE, Vector3(1.0f, 1.0f, 1.0f)),
   mWorldOrientation(), // Initialized to identity by default
index 7a1221c..64baf5b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_NODE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -651,17 +651,17 @@ public:
   }
 
   /**
-   * Retrieve the update size hint of the node.
-   * @return The update size hint.
+   * Retrieve the update area hint of the node.
+   * @return The update area hint.
    */
-  const Vector3& GetUpdateSizeHint() const
+  const Vector4& GetUpdateAreaHint() const
   {
     if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
     {
-      return mUpdateSizeHint.Get(0);
+      return mUpdateAreaHint.Get(0);
     }
 
-    return Vector3::ZERO;
+    return Vector4::ZERO;
   }
 
   /**
@@ -930,7 +930,8 @@ public: // Default properties
   AnimatableProperty<bool>    mVisible;        ///< Visibility can be inherited from the Node hierachy
   AnimatableProperty<bool>    mCulled;         ///< True if the node is culled. This is not animatable. It is just double-buffered.
   AnimatableProperty<Vector4> mColor;          ///< Color can be inherited from the Node hierarchy
-  AnimatableProperty<Vector3> mUpdateSizeHint; ///< Update size hint is provided for damaged area calculation. This is not animatable. It is just double-buffered. (Because all these bloody properties are).
+  AnimatableProperty<Vector4> mUpdateAreaHint; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
+                                               ///< This is not animatable. It is just double-buffered. (Because all these bloody properties are).
 
   // Inherited properties; read-only from public API
 
index f4d4b3e..0252ce5 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_ACTOR_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -724,6 +724,15 @@ public:
        * @SINCE_1_9.17
        */
       KEYBOARD_FOCUSABLE,
+
+      /**
+       * @brief Sets the update area hint of the actor.
+       * @details Name "updateAreaHint", type Property::VECTOR4 (x, y, width, height).
+       * @note Overrides the area - the position and the size - used for the actor damaged area calculation. Affected by the actor model view matrix.
+       * The position is relative to the center of the actor and it is also the center of the damaged area.
+       * @SINCE_2_1.33
+       */
+      UPDATE_AREA_HINT
     };
   };