(Partial Update) Change damaged rect calcutation 96/279796/1
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 18 Aug 2022 04:49:13 +0000 (13:49 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 18 Aug 2022 04:49:13 +0000 (13:49 +0900)
Use only the previous frame's rect
The buffer age is considered by adaptor

Change-Id: Idba3977ba6987aba984d11141a3f45612f7e5cbe

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/update/common/scene-graph-scene.h

index d4debe90ebd12a3c79e95e1f27055bca941600e8..33fcdd9a710a6def5c5d1abd0a2e5b53a6eae059 100644 (file)
@@ -8415,18 +8415,15 @@ int utcDaliActorPartialUpdate(void)
   application.GetScene().Remove(actor);
   application.SendNotification();
 
-  // Actor removed, last 3 dirty rects are reported. Adaptor would merge them together.
+  // Actor removed, last a dirty rect is reported.
   damagedRects.clear();
   application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
-  DALI_TEST_EQUALS(damagedRects.size(), 3, TEST_LOCATION);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
 
   clippingRect = damagedRects[0];
-  clippingRect.Merge(damagedRects[1]);
-  clippingRect.Merge(damagedRects[2]);
 
-  DALI_TEST_EQUALS(clippingRect.IsEmpty(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(clippingRect.IsValid(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS<Rect<int>>(clippingRect, Rect<int>(16, 736, 64, 64), TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, Rect<int>(32, 736, 48, 48), TEST_LOCATION);
 
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
   DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
@@ -8918,7 +8915,7 @@ int utcDaliActorPartialUpdateAnimation(void)
   // Started animation
   damagedRects.clear();
   application.PreRenderWithPartialUpdate(500, nullptr, damagedRects);
-  DALI_TEST_EQUALS(damagedRects.size(), 5, TEST_LOCATION);
+  DALI_TEST_EQUALS(damagedRects.size(), 3, TEST_LOCATION);
 
   // The first dirty rect is actor3's.
   // We don't know the exact dirty rect of actor2
index 72b9632c0a38dc84d8461036037c7e4639e4f6f4..dff1e747d7cbaf390583c039d7692c41e8f800f2 100644 (file)
@@ -95,13 +95,8 @@ inline Graphics::Rect2D RecalculateScissorArea(Graphics::Rect2D scissorArea, int
   }
   return newScissorArea;
 }
-
-/**
- * @brief The number of dirty rects per renderer in itemDirtyRects list.
- * If this value is 3, keep only last 3 dirty rects for the same node and renderer.
- */
-constexpr int MAX_DIRTY_RECT_PER_RENDERER = 3;
 } // namespace
+
 /**
  * Structure to contain internal data
  */
@@ -609,7 +604,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
               }
 
               Rect<int> rect;
-              DirtyRect dirtyRect(item.mNode, item.mRenderer, mImpl->frameCount, rect);
+              DirtyRect dirtyRect(item.mNode, item.mRenderer, rect);
               // If the item refers to updated node or renderer.
               if(item.mIsUpdated ||
                  (item.mNode &&
@@ -630,51 +625,22 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
                   rect.height      = ((bottom + 16) / 16) * 16 - rect.y;
 
                   // Found valid dirty rect.
-                  // 1. Mark the related dirty rects as visited so they will not be removed below.
-                  // 2. Keep only last "MAX_DIRTY_RECT_PER_RENDERER" dirty rects for the same node and renderer (Tizen uses 3 back buffers, Ubuntu 1).
-                  // 3-1. If itemDirtyRect hold MAX_DIRTY_RECT_PER_RENDERER rects, remove oldest one and insert it in the sorted array of the dirty rects.
-                  // 3-2. Else, Insert it in the sorted array of the dirty rects.
                   dirtyRect.rect    = rect;
                   auto dirtyRectPos = std::lower_bound(itemsDirtyRects.begin(), itemsDirtyRects.end(), dirtyRect);
 
-                  auto originDirtyRectPos = dirtyRectPos;
-                  bool hasMaxDirtyRect    = false;
-                  while(dirtyRectPos != itemsDirtyRects.end())
+                  if(dirtyRectPos != itemsDirtyRects.end() && dirtyRectPos->node == item.mNode && dirtyRectPos->renderer == item.mRenderer)
                   {
-                    if(dirtyRectPos->node != item.mNode || dirtyRectPos->renderer != item.mRenderer)
-                    {
-                      break;
-                    }
-
-                    dirtyRectPos->visited = true;
+                    // Same item, merge it with the previous rect
                     rect.Merge(dirtyRectPos->rect);
 
-                    ++dirtyRectPos;
-
-                    if((dirtyRectPos - originDirtyRectPos) == MAX_DIRTY_RECT_PER_RENDERER) // no more than MAX_DIRTY_RECT_PER_RENDERER previous rects
-                    {
-                      hasMaxDirtyRect = true;
-                      break;
-                    }
-                  }
-
-                  if(hasMaxDirtyRect)
-                  {
-                    // If we have already MAX_DIRTY_RECT_PER_RENDERER for the same item, just copy it.
-                    // Remove the oldest rect (at pos + MAX_DIRTY_RECT_PER_RENDERER - 1)
-                    // and move other rects one step.
-                    // and insert new dirtyRect at originDirtyRectPos.
-                    auto pos = originDirtyRectPos - itemsDirtyRects.begin();
-                    for(auto i = MAX_DIRTY_RECT_PER_RENDERER - 1; i > 0; i--)
-                    {
-                      itemsDirtyRects[pos + i] = itemsDirtyRects[pos + i - 1];
-                    }
-                    itemsDirtyRects[pos] = dirtyRect;
+                    // Replace the rect
+                    dirtyRectPos->visited = true;
+                    dirtyRectPos->rect    = dirtyRect.rect;
                   }
                   else
                   {
                     // Else, just insert the new dirtyrect in the correct position
-                    itemsDirtyRects.insert(originDirtyRectPos, dirtyRect);
+                    itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
                   }
 
                   damagedRects.push_back(rect);
@@ -685,15 +651,9 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
                 // 1. The item is not dirty, the node and renderer referenced by the item are still exist.
                 // 2. Mark the related dirty rects as visited so they will not be removed below.
                 auto dirtyRectPos = std::lower_bound(itemsDirtyRects.begin(), itemsDirtyRects.end(), dirtyRect);
-                while(dirtyRectPos != itemsDirtyRects.end())
+                if(dirtyRectPos != itemsDirtyRects.end() && dirtyRectPos->node == item.mNode && dirtyRectPos->renderer == item.mRenderer)
                 {
-                  if(dirtyRectPos->node != item.mNode || dirtyRectPos->renderer != item.mRenderer)
-                  {
-                    break;
-                  }
-
                   dirtyRectPos->visited = true;
-                  dirtyRectPos++;
                 }
               }
             }
index b220be4192c39cce61b7568e8a96810b8bf4f2a2..cca0106441b3716f3ad1a2f213987247d68707db 100644 (file)
@@ -43,10 +43,9 @@ class Node;
 
 struct DirtyRect
 {
-  DirtyRect(Node* node, Render::Renderer* renderer, int32_t frame, Rect<int>& rect)
+  DirtyRect(Node* node, Render::Renderer* renderer, Rect<int>& rect)
   : node(node),
     renderer(renderer),
-    frame(frame),
     rect(rect),
     visited(true)
   {
@@ -58,14 +57,7 @@ struct DirtyRect
   {
     if(node == rhs.node)
     {
-      if(renderer == rhs.renderer)
-      {
-        return frame > rhs.frame; // Most recent rects come first
-      }
-      else
-      {
-        return renderer < rhs.renderer;
-      }
+      return renderer < rhs.renderer;
     }
     else
     {
@@ -75,7 +67,6 @@ struct DirtyRect
 
   Node*             node{nullptr};
   Render::Renderer* renderer{nullptr};
-  int32_t           frame{0};
   Rect<int32_t>     rect{};
   bool              visited{true};
 };