[NUI] Layout Performance improvement (#3522)
authorhuiyu <35286162+huiyueun@users.noreply.github.com>
Tue, 14 Sep 2021 06:44:52 +0000 (15:44 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Mon, 27 Sep 2021 08:27:23 +0000 (17:27 +0900)
* [NUI] Layout Performance improvement

- Change ItereLayoutChildren()
- Get stored window size

View 1000 items (ms)
 - AbsoluteLayout : 71  -> 32
 - LinearLayout   : 88  -> 71
 - GridLayout     : 73  -> 46
 - FlexLayout     : 90  -> 56
 - RelativeLayout : 103 -> 73

Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
* Update View.cs

src/Tizen.NUI/src/internal/Layouting/GridLocations.cs
src/Tizen.NUI/src/internal/Layouting/LayoutController.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/Layouting/AbsoluteLayout.cs
src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs
src/Tizen.NUI/src/public/Layouting/LinearLayout.cs

index 66fac24..8659b2c 100755 (executable)
@@ -33,7 +33,7 @@ namespace Tizen.NUI
         private int totalHorizontalExpand = 0;
         private int totalVerticalExpand = 0;
 
-        private List<GridChild> gridChildren;
+        private List<GridChild> gridChildren = new List<GridChild>();
 
         /// <summary>
         /// The nested class to represent a node of DAG.
@@ -153,15 +153,20 @@ namespace Tizen.NUI
 
             vLocations = hLocations = null;
             vEdgeList = hEdgeList = null;
-            gridChildren = new List<GridChild>();
+            gridChildren.Clear();
             maxColumnConut = Columns;
             maxRowCount = Rows;
 
             totalVerticalExpand = 0;
             totalHorizontalExpand = 0;
 
-            foreach (LayoutItem item in IterateLayoutChildren())
+            foreach (var item in LayoutChildren)
             {
+                if (!item.SetPositionByLayout)
+                {
+                    continue;
+                }
+
                 int column, columnSpan, row, rowSpan;
                 StretchFlags verticalStretch, horizontalStretch;
                 View view = item.Owner;
index 6405494..ae1f13c 100755 (executable)
@@ -35,6 +35,8 @@ namespace Tizen.NUI
         private Animation coreAnimation;
         private List<LayoutData> layoutTransitionDataQueue;
         private List<LayoutItem> itemRemovalQueue;
+        private float windowWidth;
+        private float windowHeight;
 
         private bool subscribed;
 
@@ -45,8 +47,22 @@ namespace Tizen.NUI
         public LayoutController(Window window)
         {
             this.window = window;
+            this.window.Resized += OnWindowResized;
+            var windowSize = window.GetSize();
+            windowWidth = windowSize.Width;
+            windowHeight = windowSize.Height;
+
             layoutTransitionDataQueue = new List<LayoutData>();
             id = layoutControllerID++;
+
+            windowSize.Dispose();
+            windowSize = null;
+        }
+
+        private void OnWindowResized(object sender, Window.ResizedEventArgs e)
+        {
+            windowWidth = e.WindowSize.Width;
+            windowHeight = e.WindowSize.Height;
         }
 
         /// <summary>
@@ -89,22 +105,16 @@ namespace Tizen.NUI
         /// </summary>
         public void Process(object source, EventArgs e)
         {
-            Vector2 windowSize = window.GetSize();
-            float width = windowSize.Width;
-            float height = windowSize.Height;
-
             window.LayersChildren?.ForEach(layer =>
             {
                 layer?.Children?.ForEach(view =>
                 {
                     if (view != null)
                     {
-                        FindRootLayouts(view, width, height);
+                        FindRootLayouts(view, windowWidth, windowHeight);
                     }
                 });
             });
-            windowSize.Dispose();
-            windowSize = null;
         }
         /// <summary>
         /// Get the Layouting animation object that transitions layouts and content.
@@ -196,8 +206,7 @@ namespace Tizen.NUI
                 // Search children of supplied node for a layout.
                 for (uint i = 0; i < rootNode.ChildCount; i++)
                 {
-                    View view = rootNode.GetChildAt(i);
-                    FindRootLayouts(view, rootWidth, rootHeight);
+                    FindRootLayouts(rootNode.GetChildAt(i), rootWidth, rootHeight);
                 }
             }
         }
@@ -217,13 +226,13 @@ namespace Tizen.NUI
                 // If exact then should be that size limited by the root parent size.
                 float widthSize = GetLengthSize(parentWidth, root.WidthSpecification);
                 float heightSize = GetLengthSize(parentHeight, root.HeightSpecification);
-                MeasureSpecification.ModeType widthMode = GetMode(root.WidthSpecification);
-                MeasureSpecification.ModeType heightMode = GetMode(root.HeightSpecification);
+                var widthMode = GetMode(root.WidthSpecification);
+                var heightMode = GetMode(root.HeightSpecification);
 
                 if (root.Layout.NeedsLayout(widthSize, heightSize, widthMode, heightMode))
                 {
-                    MeasureSpecification widthSpec = CreateMeasureSpecification(widthSize, widthMode);
-                    MeasureSpecification heightSpec = CreateMeasureSpecification(heightSize, heightMode);
+                    var widthSpec = CreateMeasureSpecification(widthSize, widthMode);
+                    var heightSpec = CreateMeasureSpecification(heightSize, heightMode);
 
                     // Start at root with it's parent's widthSpecification and heightSpecification
                     MeasureHierarchy(root, widthSpec, heightSpec);
index 6b31f13..52e6ea8 100755 (executable)
@@ -2463,14 +2463,12 @@ namespace Tizen.NUI.BaseComponents
                 if (value?.Owner != null)
                 {
                     // Previous owner of the layout gets a default layout as a replacement.
-                    value.Owner.Layout = new AbsoluteLayout();
-
-                    // Copy Margin and Padding to replacement LayoutGroup.
-                    if (value.Owner.Layout != null)
+                    value.Owner.Layout = new AbsoluteLayout()
                     {
-                        value.Owner.Layout.Margin = value.Margin;
-                        value.Owner.Layout.Padding = value.Padding;
-                    }
+                        // Copy Margin and Padding to replacement LayoutGroup.
+                        Margin = value.Margin,
+                        Padding = value.Padding,
+                    };
                 }
 
                 // Copy Margin and Padding to new layout being set or restore padding and margin back to
@@ -2483,6 +2481,7 @@ namespace Tizen.NUI.BaseComponents
                         // Existing layout being replaced so copy over margin and padding values.
                         value.Margin = layout.Margin;
                         value.Padding = layout.Padding;
+                        value.SetPositionByLayout = !excludeLayouting;
                     }
                     else
                     {
@@ -2522,14 +2521,14 @@ namespace Tizen.NUI.BaseComponents
                                 NotifyPropertyChanged();
                             }
                         }
+
+                        value.SetPositionByLayout = !excludeLayouting;
                     }
                 }
 
                 // Remove existing layout from it's parent layout group.
                 layout?.Unparent();
 
-                value.SetPositionByLayout = !excludeLayouting;
-
                 // Set layout to this view
                 SetLayout(value);
             }
index 08e55f0..d6675df 100755 (executable)
@@ -45,8 +45,13 @@ namespace Tizen.NUI
             MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
             MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
 
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
+
                 // Get size of child with no padding, no margin. we won't support margin, padding for AbsolutLayout.
                 MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
 
@@ -88,8 +93,13 @@ namespace Tizen.NUI
         {
             // Absolute layout positions it's children at their Actor positions.
             // Children could overlap or spill outside the parent, as is the nature of absolute positions.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
+
                 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
 
index 327c09d..d2ddb28 100755 (executable)
@@ -52,14 +52,7 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected IEnumerable<LayoutItem> IterateLayoutChildren()
         {
-            for (int i = 0; i < LayoutChildren.Count; i++)
-            {
-                LayoutItem childLayout = LayoutChildren[i];
-                if (!childLayout?.Owner?.ExcludeLayouting ?? false)
-                {
-                    yield return childLayout;
-                }
-            }
+            return LayoutChildren.Where<LayoutItem>(childLayout => childLayout.SetPositionByLayout);
         }
 
         /// <summary>
@@ -432,9 +425,12 @@ namespace Tizen.NUI
 
         internal override void OnMeasureIndependentChildren(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
         {
-            foreach (LayoutItem childLayout in LayoutChildren.Where(item => item?.Owner?.ExcludeLayouting ?? false))
+            foreach (var childLayout in LayoutChildren)
             {
-                MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
+                if (!childLayout.SetPositionByLayout)
+                {
+                    MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec);
+                }
             }
         }
 
@@ -480,15 +476,18 @@ namespace Tizen.NUI
         /// </summary>
         internal override void OnLayoutIndependentChildren(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
         {
-            foreach (LayoutItem childLayout in LayoutChildren.Where(item => item?.Owner?.ExcludeLayouting ?? false))
+            foreach (var childLayout in LayoutChildren)
             {
-                LayoutLength childWidth = childLayout.MeasuredWidth.Size;
-                LayoutLength childHeight = childLayout.MeasuredHeight.Size;
+                if (!childLayout.SetPositionByLayout)
+                {
+                    LayoutLength childWidth = childLayout.MeasuredWidth.Size;
+                    LayoutLength childHeight = childLayout.MeasuredHeight.Size;
 
-                LayoutLength childPositionX = new LayoutLength(childLayout.Owner.PositionX);
-                LayoutLength childPositionY = new LayoutLength(childLayout.Owner.PositionY);
+                    LayoutLength childPositionX = new LayoutLength(childLayout.Owner.PositionX);
+                    LayoutLength childPositionY = new LayoutLength(childLayout.Owner.PositionY);
 
-                childLayout.Layout(childPositionX, childPositionY, childPositionX + childWidth, childPositionY + childHeight, true);
+                    childLayout.Layout(childPositionX, childPositionY, childPositionX + childWidth, childPositionY + childHeight, true);
+                }
             }
         }
 
index 765ce99..31e80f1 100755 (executable)
@@ -270,8 +270,12 @@ namespace Tizen.NUI
             // We measure all children whose width specification policy is WrapContent without weight.
             // After 1st phase, remaining width of parent is accumulated to calculate width of children
             // whose width specification policy is MatchParent.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int childDesiredWidth = childLayout.Owner.WidthSpecification;
                 int childDesiredHeight = childLayout.Owner.HeightSpecification;
                 float childWeight = childLayout.Owner.Weight;
@@ -344,8 +348,12 @@ namespace Tizen.NUI
             // We measure all children whose width specification policy is MatchParent without weight.
             // After 2nd phase, all children's widths are calculated without considering weight.
             // And the widths of all weighted children are accumulated to calculate weighted width.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int childDesiredWidth = childLayout.Owner.WidthSpecification;
                 int childDesiredHeight = childLayout.Owner.HeightSpecification;
                 float childWeight = childLayout.Owner.Weight;
@@ -434,8 +442,12 @@ namespace Tizen.NUI
             // in remaining width of parent.
             if (totalWeight > 0.0f)
             {
-                foreach (LayoutItem childLayout in IterateLayoutChildren())
+                foreach (LayoutItem childLayout in LayoutChildren)
                 {
+                    if (!childLayout.SetPositionByLayout)
+                    {
+                        continue;
+                    }
                     int childDesiredWidth = childLayout.Owner.WidthSpecification;
                     float childWeight = childLayout.Owner.Weight;
 
@@ -503,8 +515,12 @@ namespace Tizen.NUI
             // We measure all children whose height specification policy is WrapContent without weight.
             // After 1st phase, remaining height of parent is accumulated to calculate height of children
             // whose height specification policy is MatchParent.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int childDesiredWidth = childLayout.Owner.WidthSpecification;
                 int childDesiredHeight = childLayout.Owner.HeightSpecification;
                 float childWeight = childLayout.Owner.Weight;
@@ -577,8 +593,12 @@ namespace Tizen.NUI
             // We measure all children whose height specification policy is MatchParent without weight.
             // After 2nd phase, all children's heights are calculated without considering weight.
             // And the heights of all weighted children are accumulated to calculate weighted height.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int childDesiredWidth = childLayout.Owner.WidthSpecification;
                 int childDesiredHeight = childLayout.Owner.HeightSpecification;
                 float childWeight = childLayout.Owner.Weight;
@@ -667,8 +687,12 @@ namespace Tizen.NUI
             // in remaining height of parent.
             if (totalWeight > 0)
             {
-                foreach (LayoutItem childLayout in IterateLayoutChildren())
+                foreach (var childLayout in LayoutChildren)
                 {
+                    if (!childLayout.SetPositionByLayout)
+                    {
+                        continue;
+                    }
                     int childDesiredHeight = childLayout.Owner.HeightSpecification;
                     float childWeight = childLayout.Owner.Weight;
 
@@ -722,8 +746,8 @@ namespace Tizen.NUI
             // Space available for child
             LayoutLength childSpace = new LayoutLength(height - Padding.Top - Padding.Bottom);
 
-            List<LayoutItem> LinearChildren = IterateLayoutChildren().ToList();
-            int count = LinearChildren.Count;
+            var LinearChildren = IterateLayoutChildren();
+            int count = LinearChildren.Count<LayoutItem>();
 
             switch (LinearAlignment)
             {
@@ -773,7 +797,7 @@ namespace Tizen.NUI
             {
                 int childIndex = start + dir * i;
                 // Get a reference to the childLayout at the given index
-                LayoutItem childLayout = LinearChildren[childIndex];
+                LayoutItem childLayout = LinearChildren.ElementAt<LayoutItem>(i);
 
                 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
@@ -810,8 +834,8 @@ namespace Tizen.NUI
             // Space available for child
             LayoutLength childSpace = new LayoutLength(width - Padding.Start - Padding.End);
 
-            List<LayoutItem> LinearChildren = IterateLayoutChildren().ToList();
-            int count = LinearChildren.Count;
+            var LinearChildren = IterateLayoutChildren();
+            int count = LinearChildren.Count<LayoutItem>();
 
             switch (LinearAlignment)
             {
@@ -833,7 +857,7 @@ namespace Tizen.NUI
 
             for (int i = 0; i < count; i++)
             {
-                LayoutItem childLayout = LinearChildren[i];
+                LayoutItem childLayout = LinearChildren.ElementAt<LayoutItem>(i);
 
                 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
@@ -871,8 +895,12 @@ namespace Tizen.NUI
             // ourselves. The measured height should be the max height of the children, changed
             // to accommodate the heightMeasureSpec from the parent
             MeasureSpecification uniformMeasureSpec = new MeasureSpecification(MeasuredHeight.Size, MeasureSpecification.ModeType.Exactly);
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int desiredChildHeight = childLayout.Owner.HeightSpecification;
                 int desiredChildWidth = childLayout.Owner.WidthSpecification;