[NUI] Lazy Update CornerRadius/Borderline
authorEunki Hong <eunkiki.hong@samsung.com>
Tue, 1 Aug 2023 12:38:28 +0000 (21:38 +0900)
committerEunki Hong <h.pichulia@gmail.com>
Wed, 9 Aug 2023 07:58:31 +0000 (16:58 +0900)
Prototype codes for Borderline / CornerRadius feature update lazy.

Since we don't need to apply background extra data multiple times,
Let we collect all changeness informations + Apply it once.

Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
src/Tizen.NUI/src/public/BaseComponents/ImageView.cs
src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs
src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs

index af61687..95ecb53 100755 (executable)
@@ -1344,13 +1344,15 @@ namespace Tizen.NUI.BaseComponents
 
             if (backgroundExtraData == null) return;
 
-
             // Update corner radius properties to image by ActionUpdateProperty
-            if (backgroundExtraData.CornerRadius != null)
+            if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ContentsCornerRadius))
             {
-                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+                if (backgroundExtraData.CornerRadius != null)
+                {
+                    Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+                }
+                Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
             }
-            Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
         }
 
         internal override void ApplyBorderline()
@@ -1359,11 +1361,13 @@ namespace Tizen.NUI.BaseComponents
 
             if (backgroundExtraData == null) return;
 
-
-            // Update borderline properties to image by ActionUpdateProperty
-            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
-            Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
-            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
+            if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ContentsBorderline))
+            {
+                // Update borderline properties to image by ActionUpdateProperty
+                Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
+                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
+                Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
+            }
         }
 
         internal ResourceLoadingStatusType GetResourceStatus()
@@ -1633,6 +1637,10 @@ namespace Tizen.NUI.BaseComponents
                 }
             }
 
+            // We already applied background extra data now.
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.ContentsCornerRadius;
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.ContentsBorderline;
+
             // Do Fitting Buffer when desired dimension is set
             // TODO : Couldn't we do this job in dali-engine side.
             if (_desired_width != -1 && _desired_height != -1)
index ac40787..6fb7c54 100755 (executable)
@@ -291,6 +291,14 @@ namespace Tizen.NUI.BaseComponents
 
                     view.backgroundExtraData = null;
 
+                    // Background extra data is not valid anymore. We should ignore lazy UpdateBackgroundExtraData
+                    view.backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None;
+                    if (view.backgroundExtraDataUpdateProcessAttachedFlag)
+                    {
+                        ProcessorController.Instance.ProcessorOnceEvent -= view.UpdateBackgroundExtraData;
+                        view.backgroundExtraDataUpdateProcessAttachedFlag = false;
+                    }
+
                     propertyValue.Dispose();
                     propertyValue = null;
                 }
@@ -298,6 +306,10 @@ namespace Tizen.NUI.BaseComponents
             defaultValueCreator: (bindable) =>
             {
                 var view = (View)bindable;
+
+                // Sync as current properties
+                view?.UpdateBackgroundExtraData();
+
                 PropertyMap tmp = new PropertyMap();
                 var propertyValue = Object.GetProperty(view.SwigCPtr, Property.BACKGROUND);
                 propertyValue.Get(tmp);
@@ -1876,6 +1888,9 @@ namespace Tizen.NUI.BaseComponents
         {
             var view = (View)bindable;
 
+            // Sync as current properties
+            view?.UpdateBackgroundExtraData();
+
             PropertyMap map = new PropertyMap();
             Tizen.NUI.Object.GetProperty((System.Runtime.InteropServices.HandleRef)view.SwigCPtr, View.Property.SHADOW).Get(map);
 
@@ -1907,6 +1922,9 @@ namespace Tizen.NUI.BaseComponents
         {
             var view = (View)bindable;
 
+            // Sync as current properties
+            view?.UpdateBackgroundExtraData();
+
             PropertyMap map = new PropertyMap();
             Tizen.NUI.Object.GetProperty((System.Runtime.InteropServices.HandleRef)view.SwigCPtr, View.Property.SHADOW).Get(map);
 
@@ -1922,7 +1940,7 @@ namespace Tizen.NUI.BaseComponents
         {
             var view = (View)bindable;
             (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).CornerRadius = (Vector4)newValue;
-            view.ApplyCornerRadius();
+            view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.CornerRadius);
         },
         defaultValueCreator: (bindable) =>
         {
@@ -1941,7 +1959,7 @@ namespace Tizen.NUI.BaseComponents
 
             if (view.backgroundExtraData.CornerRadius != null)
             {
-                view.ApplyCornerRadius();
+                view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.CornerRadius);
             }
         },
         defaultValueCreator: (bindable) =>
@@ -1958,7 +1976,7 @@ namespace Tizen.NUI.BaseComponents
         {
             var view = (View)bindable;
             (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).BorderlineWidth = (float)newValue;
-            view.ApplyBorderline();
+            view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline);
         },
         defaultValueCreator: (bindable) =>
         {
@@ -2032,7 +2050,7 @@ namespace Tizen.NUI.BaseComponents
         {
             var view = (View)bindable;
             (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).BorderlineOffset = (float)newValue;
-            view.ApplyBorderline();
+            view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline);
         },
         defaultValueCreator: (bindable) =>
         {
@@ -2576,6 +2594,8 @@ namespace Tizen.NUI.BaseComponents
         {
             if (string.IsNullOrEmpty(value))
             {
+                backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background;
+
                 var empty = new PropertyValue();
                 // Clear background
                 Object.SetProperty(SwigCPtr, Property.BACKGROUND, empty);
@@ -2629,6 +2649,8 @@ namespace Tizen.NUI.BaseComponents
                 map.Add(Visual.Property.Type, imageType);
             }
 
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background;
+
             var mapValue = new PropertyValue(map);
             Object.SetProperty(SwigCPtr, Property.BACKGROUND, mapValue);
 
@@ -2679,6 +2701,9 @@ namespace Tizen.NUI.BaseComponents
                 map[Visual.Property.Type] = new PropertyValue((int)Visual.Type.NPatch);
             }
 
+            // Background extra data flag is not meanful anymore.
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background;
+
             Tizen.NUI.Object.SetProperty((System.Runtime.InteropServices.HandleRef)SwigCPtr, View.Property.BACKGROUND, new PropertyValue(map));
         }
 
@@ -2691,7 +2716,7 @@ namespace Tizen.NUI.BaseComponents
 
             (backgroundExtraData ?? (backgroundExtraData = new BackgroundExtraData())).BorderlineColor = value;
 
-            ApplyBorderline();
+            UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline);
         }
 
         private void SetBackgroundColor(Color value)
@@ -2727,6 +2752,8 @@ namespace Tizen.NUI.BaseComponents
                .Add(Visual.Property.BorderlineColor, borderlineColor)
                .Add(Visual.Property.BorderlineOffset, borderlineOffset);
 
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background;
+
             var mapValue = new PropertyValue(map);
             Object.SetProperty(SwigCPtr, Property.BACKGROUND, mapValue);
 
@@ -2803,6 +2830,7 @@ namespace Tizen.NUI.BaseComponents
 
         private void SetShadow(ShadowBase value)
         {
+            backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Shadow;
             Tizen.NUI.Object.SetProperty((System.Runtime.InteropServices.HandleRef)SwigCPtr, View.Property.SHADOW, value == null ? new PropertyValue() : value.ToPropertyValue(this));
         }
     }
index dc168bb..49a346e 100755 (executable)
@@ -30,6 +30,29 @@ namespace Tizen.NUI.BaseComponents
     {
         internal string styleName;
 
+        [Flags]
+        internal enum BackgroundExtraDataUpdatedFlag : byte
+        {
+            BackgroundCornerRadius = 1 << 0,
+            BackgroundBorderline = 1 << 1,
+            ShadowCornerRadius = 1 << 2,
+            ContentsCornerRadius = 1 << 3, /// Subclass cases.
+            ContentsBorderline = 1 << 4, /// Subclass cases.
+
+            Background = BackgroundCornerRadius | BackgroundBorderline,
+            Shadow = ShadowCornerRadius,
+
+            CornerRadius = BackgroundCornerRadius | ShadowCornerRadius | ContentsCornerRadius,
+            Borderline = BackgroundBorderline | ContentsBorderline,
+
+            None = 0,
+            All = Background | Shadow,
+        }
+
+        internal BackgroundExtraDataUpdatedFlag backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None;
+
+        private bool backgroundExtraDataUpdateProcessAttachedFlag = false;
+
         internal virtual LayoutItem CreateDefaultLayout()
         {
             return new AbsoluteLayout();
@@ -1058,12 +1081,21 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         internal bool IsBackgroundEmpty()
         {
-
             int visualType = (int)Visual.Type.Invalid;
             Interop.View.InternalRetrievingVisualPropertyInt(this.SwigCPtr, Property.BACKGROUND, Visual.Property.Type, out visualType);
             return visualType == (int)Visual.Type.Invalid;
         }
 
+        /// <summary>
+        /// Check whether Current view don't has ShadowVisual or not.
+        /// </summary>
+        internal bool IsShadowEmpty()
+        {
+            int visualType = (int)Visual.Type.Invalid;
+            Interop.View.InternalRetrievingVisualPropertyInt(this.SwigCPtr, Property.SHADOW, Visual.Property.Type, out visualType);
+            return visualType == (int)Visual.Type.Invalid;
+        }
+
         internal void SetKeyInputFocus()
         {
             Interop.ViewInternal.SetKeyInputFocus(SwigCPtr);
@@ -1151,20 +1183,98 @@ namespace Tizen.NUI.BaseComponents
             return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.BACKGROUND);
         }
 
+        /// <summary>
+        /// Lazy call to UpdateBackgroundExtraData.
+        /// Collect Properties need to be update, and set properties that starts the Processing.
+        /// </summary>
+        internal virtual void UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag flag)
+        {
+            if (backgroundExtraData == null)
+            {
+                return;
+            }
+
+            if (!backgroundExtraDataUpdatedFlag.HasFlag(flag))
+            {
+                backgroundExtraDataUpdatedFlag |= flag;
+                if (!backgroundExtraDataUpdateProcessAttachedFlag)
+                {
+                    backgroundExtraDataUpdateProcessAttachedFlag = true;
+                    ProcessorController.Instance.ProcessorOnceEvent += UpdateBackgroundExtraData;
+                    // Call process hardly.
+                    ProcessorController.Instance.Awake();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Callback function to Lazy UpdateBackgroundExtraData.
+        /// </summary>
+        private void UpdateBackgroundExtraData(object source, EventArgs e)
+        {
+            // Note : To allow event attachment during UpdateBackgroundExtraData, let we make flag as false before call UpdateBackgroundExtraData().
+            backgroundExtraDataUpdateProcessAttachedFlag = false;
+            UpdateBackgroundExtraData();
+        }
+
+        /// <summary>
+        /// Update background extra data properties synchronously.
+        /// After call this API, All background extra data properties updated.
+        /// </summary>
+        internal virtual void UpdateBackgroundExtraData()
+        {
+            if (backgroundExtraData == null)
+            {
+                return;
+            }
+
+            if (IsShadowEmpty())
+            {
+                backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Shadow;
+            }
+            if (!Rectangle.IsNullOrZero(backgroundExtraData.BackgroundImageBorder))
+            {
+                backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background;
+            }
+
+            if (backgroundExtraDataUpdatedFlag == BackgroundExtraDataUpdatedFlag.None)
+            {
+                return;
+            }
+
+            if ((backgroundExtraDataUpdatedFlag & BackgroundExtraDataUpdatedFlag.Borderline) != BackgroundExtraDataUpdatedFlag.None)
+            {
+                ApplyBorderline();
+            }
+            if ((backgroundExtraDataUpdatedFlag & BackgroundExtraDataUpdatedFlag.CornerRadius) != BackgroundExtraDataUpdatedFlag.None)
+            {
+                ApplyCornerRadius();
+            }
+            backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None;
+        }
+
         /// TODO open as a protected level
         internal virtual void ApplyCornerRadius()
         {
             if (backgroundExtraData == null) return;
 
-
             // Update corner radius properties to background and shadow by ActionUpdateProperty
-            if (backgroundExtraData.CornerRadius != null)
+            if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.BackgroundCornerRadius))
             {
-                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
-                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+                if (backgroundExtraData.CornerRadius != null)
+                {
+                    Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+                }
+                Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
+            }
+            if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ShadowCornerRadius))
+            {
+                if (backgroundExtraData.CornerRadius != null)
+                {
+                    Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+                }
+                Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
             }
-            Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
-            Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
         }
 
         /// TODO open as a protected level
@@ -1172,7 +1282,6 @@ namespace Tizen.NUI.BaseComponents
         {
             if (backgroundExtraData == null) return;
 
-
             // ActionUpdateProperty works well only if BACKGROUND visual setup before.
             // If view don't have BACKGROUND visual, we set transparent background color in default.
             if (IsBackgroundEmpty())
@@ -1185,9 +1294,12 @@ namespace Tizen.NUI.BaseComponents
             }
 
             // Update borderline properties to background by ActionUpdateProperty
-            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
-            Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
-            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
+            if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.BackgroundBorderline))
+            {
+                Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
+                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
+                Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
+            }
         }
 
         /// <summary>
@@ -1335,6 +1447,13 @@ namespace Tizen.NUI.BaseComponents
                 view.InternalParent = null;
             }
 
+            backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None;
+            if (backgroundExtraDataUpdateProcessAttachedFlag)
+            {
+                ProcessorController.Instance.ProcessorOnceEvent -= UpdateBackgroundExtraData;
+                backgroundExtraDataUpdateProcessAttachedFlag = false;
+            }
+
             LayoutCount = 0;
 
             NUILog.Debug($"[Dispose] View.Dispose({type}) END");