From: Eunki, Hong Date: Tue, 22 Feb 2022 08:19:22 +0000 (+0900) Subject: Ignore insert/erase function during PreRender's itemsDirtyRects X-Git-Tag: dali_2.1.11~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f19e582fe69147df2e753162086b2d18611b12ae;p=platform%2Fcore%2Fuifw%2Fdali-core.git Ignore insert/erase function during PreRender's itemsDirtyRects Previous code just insert and erase when the renderer hold dirtyRect more than 3. Each insert & erase operation in std::vector cost O(N). and it is expensive. This patch reduce the insert & erase operation when renderer hold dirtyRect more than 3. We can do tge same job by just moving data linearly. (This patch is follow up 250728) Change-Id: I230f32f07c72c3a4f15c6bb7f6a42bd61ce87d1d Signed-off-by: Eunki, Hong --- diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index bb35b69..084db0e 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -95,6 +95,12 @@ 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 @@ -624,15 +630,16 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& rect.height = ((bottom + 16) / 16) * 16 - rect.y; // Found valid dirty rect. - // 1. Insert it in the sorted array of the dirty rects. - // 2. Mark the related dirty rects as visited so they will not be removed below. - // 3. Keep only last 3 dirty rects for the same node and renderer (Tizen uses 3 back buffers, Ubuntu 1). + // 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); - dirtyRectPos = itemsDirtyRects.insert(dirtyRectPos, dirtyRect); - int c = 1; - while(++dirtyRectPos != itemsDirtyRects.end()) + auto originDirtyRectPos = dirtyRectPos; + bool hasMaxDirtyRect = false; + while(dirtyRectPos != itemsDirtyRects.end()) { if(dirtyRectPos->node != item.mNode || dirtyRectPos->renderer != item.mRenderer) { @@ -640,17 +647,36 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& } dirtyRectPos->visited = true; - Rect& dirtRect = dirtyRectPos->rect; - rect.Merge(dirtRect); + rect.Merge(dirtyRectPos->rect); - c++; - if(c > 3) // no more then 3 previous rects + ++dirtyRectPos; + + if((dirtyRectPos - originDirtyRectPos) == MAX_DIRTY_RECT_PER_RENDERER) // no more than MAX_DIRTY_RECT_PER_RENDERER previous rects { - itemsDirtyRects.erase(dirtyRectPos); + 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; + } + else + { + // Else, just insert the new dirtyrect in the correct position + itemsDirtyRects.insert(originDirtyRectPos, dirtyRect); + } + damagedRects.push_back(rect); } }