[NUI] Fix Process of LayoutController (#2841)
authorhuiyueun <35286162+huiyueun@users.noreply.github.com>
Thu, 8 Apr 2021 07:04:22 +0000 (16:04 +0900)
committerhuiyueun <35286162+huiyueun@users.noreply.github.com>
Tue, 20 Apr 2021 06:13:00 +0000 (15:13 +0900)
Add to check if layout is needed before OnMeasure
It makes performance improve of layouting.

Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
src/Tizen.NUI/src/internal/Layouting/LayoutController.cs
src/Tizen.NUI/src/public/Layouting/LayoutItem.cs

index 52127da..ef710cf 100755 (executable)
@@ -190,26 +190,32 @@ namespace Tizen.NUI
         {
             if (root.Layout != null)
             {
-                float positionX = root.PositionX;
-                float positionY = root.PositionY;
-
                 // Determine measure specification for root.
                 // The root layout policy could be an exact size, be match parent or wrap children.
                 // If wrap children then at most it can be the root parent size.
                 // If match parent then should be root parent size.
                 // If exact then should be that size limited by the root parent size.
-                MeasureSpecification parentWidthSpecification = CreateMeasureSpecification(parentWidth, root.WidthSpecification);
-                MeasureSpecification parentHeightSpecification = CreateMeasureSpecification(parentHeight, root.HeightSpecification);
+                float widthSize = GetLengthSize(parentWidth, root.WidthSpecification);
+                float heightSize = GetLengthSize(parentHeight, root.HeightSpecification);
+                MeasureSpecification.ModeType widthMode = GetMode(root.WidthSpecification);
+                MeasureSpecification.ModeType heightMode = GetMode(root.HeightSpecification);
+
+                if (root.Layout.NeedsLayout(widthSize, heightSize, widthMode, heightMode))
+                {
+                    MeasureSpecification widthSpec = CreateMeasureSpecification(widthSize, widthMode);
+                    MeasureSpecification heightSpec = CreateMeasureSpecification(heightSize, heightMode);
 
-                // Start at root with it's parent's widthSpecification and heightSpecification
-                MeasureHierarchy(root, parentWidthSpecification, parentHeightSpecification);
+                    // Start at root with it's parent's widthSpecification and heightSpecification
+                    MeasureHierarchy(root, widthSpec, heightSpec);
+                }
 
+                float positionX = root.PositionX;
+                float positionY = root.PositionY;
                 // Start at root which was just measured.
                 PerformLayout(root, new LayoutLength(positionX),
                                      new LayoutLength(positionY),
                                      new LayoutLength(positionX) + root.Layout.MeasuredWidth.Size,
                                      new LayoutLength(positionY) + root.Layout.MeasuredHeight.Size);
-
             }
 
             if (SetupCoreAnimation() && OverrideCoreAnimation == false)
@@ -218,22 +224,24 @@ namespace Tizen.NUI
             }
         }
 
-        private MeasureSpecification CreateMeasureSpecification(float size, int specification)
+        private float GetLengthSize(float size, int specification)
         {
-            LayoutLength length = new LayoutLength(size);
-            MeasureSpecification.ModeType mode = MeasureSpecification.ModeType.Unspecified;
+            // exact size provided so match width exactly
+            return (specification >= 0) ? specification : size;
+        }
 
-            if (specification >= 0)
-            {
-                // exact size provided so match width exactly
-                length = new LayoutLength(specification);
-                mode = MeasureSpecification.ModeType.Exactly;
-            }
-            else if (specification == LayoutParamPolicies.MatchParent)
+        private MeasureSpecification.ModeType GetMode(int specification)
+        {
+            if (specification >= 0 || specification == LayoutParamPolicies.MatchParent)
             {
-                mode = MeasureSpecification.ModeType.Exactly;
+                return MeasureSpecification.ModeType.Exactly;
             }
-            return new MeasureSpecification(length, mode);
+            return MeasureSpecification.ModeType.Unspecified;
+        }
+
+        private MeasureSpecification CreateMeasureSpecification(float size, MeasureSpecification.ModeType mode)
+        {
+            return new MeasureSpecification(new LayoutLength(size), mode);
         }
 
         /// <summary>
index 1ed275b..39ff389 100755 (executable)
@@ -203,30 +203,34 @@ namespace Tizen.NUI
         /// <since_tizen> 6 </since_tizen>
         public void Measure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
         {
+            OnMeasure(widthMeasureSpec, heightMeasureSpec);
+            OnMeasureIndependentChildren(widthMeasureSpec, heightMeasureSpec);
+            flags = flags | LayoutFlags.LayoutRequired;
+            flags &= ~LayoutFlags.ForceLayout;
+
+            oldWidthMeasureSpec = widthMeasureSpec;
+            oldHeightMeasureSpec = heightMeasureSpec;
+        }
+
+        internal bool NeedsLayout(float widthSize, float heightSize, MeasureSpecification.ModeType widthMode, MeasureSpecification.ModeType heightMode)
+        {
+            if (LayoutRequested)
+            {
+                return true;
+            }
+
             // Check if relayouting is required.
-            bool specChanged = (widthMeasureSpec.Size != oldWidthMeasureSpec.Size) ||
-                (heightMeasureSpec.Size != oldHeightMeasureSpec.Size) ||
-                (widthMeasureSpec.Mode != oldWidthMeasureSpec.Mode) ||
-                (heightMeasureSpec.Mode != oldHeightMeasureSpec.Mode);
+            bool specChanged = (widthSize != oldWidthMeasureSpec.Size.AsDecimal()) || (widthMode != oldWidthMeasureSpec.Mode) ||
+                               (heightSize != oldHeightMeasureSpec.Size.AsDecimal()) || (heightMode != oldHeightMeasureSpec.Mode);
 
-            bool isSpecExactly = (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) &&
-                (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly);
+            bool isSpecExactly = (widthMode == MeasureSpecification.ModeType.Exactly) &&
+                                 (heightMode == MeasureSpecification.ModeType.Exactly);
 
-            bool matchesSpecSize = (MeasuredWidth.Size == widthMeasureSpec.Size) &&
-                (MeasuredHeight.Size == heightMeasureSpec.Size);
+            bool matchesSpecSize = (MeasuredWidth.Size.AsDecimal() == widthSize) && (MeasuredHeight.Size.AsDecimal() == heightSize);
 
             bool needsLayout = specChanged && (!isSpecExactly || !matchesSpecSize);
-            needsLayout = needsLayout || ((flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout);
 
-            if (needsLayout)
-            {
-                OnMeasure(widthMeasureSpec, heightMeasureSpec);
-                OnMeasureIndependentChildren(widthMeasureSpec, heightMeasureSpec);
-                flags = flags | LayoutFlags.LayoutRequired;
-                flags &= ~LayoutFlags.ForceLayout;
-            }
-            oldWidthMeasureSpec = widthMeasureSpec;
-            oldHeightMeasureSpec = heightMeasureSpec;
+            return needsLayout;
         }
 
         /// <summary>