From: Eunki, Hong Date: Tue, 9 Apr 2024 00:55:29 +0000 (+0900) Subject: [NUI] Add property NotifyAfterRasterization + Fix EnableFrameCache works well X-Git-Tag: submit/tizen/20240513.073750~1^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a051ad427ffacf2f1cb4129d64186f0b8924b0d;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Add property NotifyAfterRasterization + Fix EnableFrameCache works well Let we add some flag that notify to event/main thread every frames when given lottie image rasterize finished. Until before, there was no way to notify render thread that lottie surface updated. So we make render thread always make rendered if lottie image used. But sometimes, if some application want to render 30fps or less frame rate lottie image, 60fps rendering is not a neccessary behavior. To give them a choice, we give the property, `NotifyAfterRasterization`. If we set this flag, some 30fps lottie file will awake render thread every 30fps. Instead, the awake message might give overhead. So if lottie file is 60fps, we'd better set this flag as false. Below dali patch required: * https://review.tizen.org/gerrit/c/platform/core/uifw/dali-adaptor/+/309120 * https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/309127 * https://review.tizen.org/gerrit/c/platform/core/uifw/dali-extension/+/309128 Signed-off-by: Eunki, Hong --- diff --git a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs index 88a5ddcf3..2c8a788ab 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationView.cs @@ -44,10 +44,12 @@ namespace Tizen.NUI.BaseComponents LoopCountProperty = BindableProperty.Create(nameof(LoopCount), typeof(int), typeof(Tizen.NUI.BaseComponents.LottieAnimationView), 0, propertyChanged: SetInternalLoopCountProperty, defaultValueCreator: GetInternalLoopCountProperty); StopBehaviorProperty = BindableProperty.Create(nameof(StopBehavior), typeof(StopBehaviorType), typeof(LottieAnimationView), default(StopBehaviorType), propertyChanged: SetInternalStopBehaviorProperty, defaultValueCreator: GetInternalStopBehaviorProperty); - + RedrawInScalingDownProperty = BindableProperty.Create(nameof(RedrawInScalingDown), typeof(bool), typeof(Tizen.NUI.BaseComponents.LottieAnimationView), false, propertyChanged: SetInternalRedrawInScalingDownProperty, defaultValueCreator: GetInternalRedrawInScalingDownProperty); EnableFrameCacheProperty = BindableProperty.Create(nameof(EnableFrameCache), typeof(bool), typeof(Tizen.NUI.BaseComponents.LottieAnimationView), false, propertyChanged: SetInternalEnableFrameCacheProperty, defaultValueCreator: GetInternalEnableFrameCacheProperty); + + NotifyAfterRasterizationProperty = BindableProperty.Create(nameof(NotifyAfterRasterization), typeof(bool), typeof(Tizen.NUI.BaseComponents.LottieAnimationView), false, propertyChanged: SetInternalNotifyAfterRasterizationProperty, defaultValueCreator: GetInternalNotifyAfterRasterizationProperty); } } @@ -83,6 +85,8 @@ namespace Tizen.NUI.BaseComponents currentStates.desiredWidth = 0; currentStates.desiredHeight = 0; currentStates.synchronousLoading = true; + currentStates.enableFrameCache = false; + currentStates.notifyAfterRasterization = false; // Notify to base ImageView cache that default synchronousLoading for lottie file is true. base.SynchronousLoading = currentStates.synchronousLoading; @@ -195,7 +199,6 @@ namespace Tizen.NUI.BaseComponents currentStates.framePlayRangeMin = -1; currentStates.framePlayRangeMax = -1; currentStates.totalFrame = -1; - currentStates.enableFrameCache = false; string ret = (value == null ? "" : value); currentStates.url = ret; @@ -211,6 +214,8 @@ namespace Tizen.NUI.BaseComponents using PropertyValue loopMode = new PropertyValue((int)currentStates.loopMode); using PropertyValue redrawInScalingDown = new PropertyValue(currentStates.redrawInScalingDown); using PropertyValue synchronousLoading = new PropertyValue(currentStates.synchronousLoading); + using PropertyValue enableFrameCache = new PropertyValue(currentStates.enableFrameCache); + using PropertyValue notifyAfterRasterization = new PropertyValue(currentStates.notifyAfterRasterization); map.Add(Visual.Property.Type, type) .Add(ImageVisualProperty.URL, url) @@ -218,7 +223,9 @@ namespace Tizen.NUI.BaseComponents .Add(ImageVisualProperty.StopBehavior, stopAction) .Add(ImageVisualProperty.LoopingMode, loopMode) .Add(ImageVisualProperty.RedrawInScalingDown, redrawInScalingDown) - .Add(ImageVisualProperty.SynchronousLoading, synchronousLoading); + .Add(ImageVisualProperty.SynchronousLoading, synchronousLoading) + .Add(ImageVisualProperty.EnableFrameCache, enableFrameCache) + .Add(ImageVisualProperty.NotifyAfterRasterization, notifyAfterRasterization); if (currentStates.desiredWidth > 0) { @@ -390,7 +397,7 @@ namespace Tizen.NUI.BaseComponents } else { - return (int) GetInternalCurrentFrameProperty(this); + return (int)GetInternalCurrentFrameProperty(this); } } set @@ -653,7 +660,17 @@ namespace Tizen.NUI.BaseComponents } } - + /// + /// Whether to AnimatedVectorImageVisual fixed cache or not. + /// + /// + /// If this property is true, AnimatedVectorImageVisual enable frame cache for loading and keeps loaded frame + /// until the visual is removed. It reduces CPU cost when the animated image will be looping. + /// But it can spend a lot of memory if the resource has high resolution image or many frame count. + /// + /// Inhouse API. + /// It is used in the AnimatedVectorImageVisual.The default is false. + /// [EditorBrowsable(EditorBrowsableState.Never)] public bool EnableFrameCache { @@ -702,6 +719,66 @@ namespace Tizen.NUI.BaseComponents return currentStates.enableFrameCache; } } + + /// + /// Whether notify AnimatedVectorImageVisual to render thread after every rasterization or not. + /// + /// + /// If this property is true, AnimatedVectorImageVisual send notify to render thread after every rasterization. + /// If false, AnimatedVectorImageVisual set Renderer's Behaviour as Continouly (mean, always update the render thread.) + /// This flag is useful if given resource has low fps, so we don't need to render every frame. + /// + /// Inhouse API. + /// It is used in the AnimatedVectorImageVisual.The default is false. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool NotifyAfterRasterization + { + get + { + if (NUIApplication.IsUsingXaml) + { + return (bool)GetValue(NotifyAfterRasterizationProperty); + } + else + { + return (bool)GetInternalNotifyAfterRasterizationProperty(this); + } + } + set + { + if (NUIApplication.IsUsingXaml) + { + SetValue(NotifyAfterRasterizationProperty, value); + } + else + { + SetInternalNotifyAfterRasterizationProperty(this, null, value); + } + NotifyPropertyChanged(); + } + } + + private bool InternalNotifyAfterRasterization + { + set + { + if (currentStates.notifyAfterRasterization != value) + { + currentStates.changed = true; + currentStates.notifyAfterRasterization = value; + + NUILog.Debug($"<[{GetId()}]SET currentStates.NotifyAfterRasterization={currentStates.notifyAfterRasterization}>"); + + Interop.View.InternalUpdateVisualPropertyBool(this.SwigCPtr, ImageView.Property.IMAGE, ImageVisualProperty.NotifyAfterRasterization, currentStates.notifyAfterRasterization); + } + } + get + { + NUILog.Debug($"NotifyAfterRasterization get! {currentStates.notifyAfterRasterization}"); + return currentStates.notifyAfterRasterization; + } + } #endregion Property @@ -1017,13 +1094,15 @@ namespace Tizen.NUI.BaseComponents if (!imagePropertyUpdatedFlag) return; // Update currentStates properties to cachedImagePropertyMap - if(currentStates.changed) + if (currentStates.changed) { UpdateImage(ImageVisualProperty.LoopCount, new PropertyValue(currentStates.loopCount), false); UpdateImage(ImageVisualProperty.StopBehavior, new PropertyValue((int)currentStates.stopEndAction), false); UpdateImage(ImageVisualProperty.LoopingMode, new PropertyValue((int)currentStates.loopMode), false); UpdateImage(ImageVisualProperty.RedrawInScalingDown, new PropertyValue(currentStates.redrawInScalingDown), false); UpdateImage(ImageVisualProperty.SynchronousLoading, new PropertyValue(currentStates.synchronousLoading), false); + UpdateImage(ImageVisualProperty.EnableFrameCache, new PropertyValue(currentStates.enableFrameCache), false); + UpdateImage(ImageVisualProperty.NotifyAfterRasterization, new PropertyValue(currentStates.notifyAfterRasterization), false); // Do not cache PlayRange and TotalFrameNumber into cachedImagePropertyMap. // (To keep legacy implements behaviour) @@ -1404,6 +1483,8 @@ namespace Tizen.NUI.BaseComponents ImageVisualProperty.StopBehavior, ImageVisualProperty.LoopingMode, ImageVisualProperty.RedrawInScalingDown, + ImageVisualProperty.EnableFrameCache, + ImageVisualProperty.NotifyAfterRasterization, }; private struct states @@ -1424,6 +1505,7 @@ namespace Tizen.NUI.BaseComponents internal int desiredWidth, desiredHeight; internal bool synchronousLoading; internal bool enableFrameCache; + internal bool notifyAfterRasterization; internal bool changed; }; private states currentStates; diff --git a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationViewBindableProperty.cs b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationViewBindableProperty.cs index b82a95a5a..3a91a5a5c 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationViewBindableProperty.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/LottieAnimationViewBindableProperty.cs @@ -36,7 +36,7 @@ namespace Tizen.NUI.BaseComponents instance.InternalURL = (string)newValue; } } - + internal static object GetInternalURLProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; @@ -57,8 +57,7 @@ namespace Tizen.NUI.BaseComponents instance.InternalCurrentFrame = (int)newValue; } } - - + internal static object GetInternalCurrentFrameProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; @@ -100,7 +99,7 @@ namespace Tizen.NUI.BaseComponents instance.InternalLoopCount = (int)newValue; } } - internal static object GetInternalLoopCountProperty(BindableObject bindable) + internal static object GetInternalLoopCountProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; return instance.InternalLoopCount; @@ -120,7 +119,7 @@ namespace Tizen.NUI.BaseComponents instance.InternalStopBehavior = (Tizen.NUI.BaseComponents.LottieAnimationView.StopBehaviorType)newValue; } } - + internal static object GetInternalStopBehaviorProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; @@ -141,7 +140,7 @@ namespace Tizen.NUI.BaseComponents instance.InternalRedrawInScalingDown = (bool)newValue; } } - + internal static object GetInternalRedrawInScalingDownProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; @@ -162,11 +161,32 @@ namespace Tizen.NUI.BaseComponents instance.InternalEnableFrameCache = (bool)newValue; } } - + internal static object GetInternalEnableFrameCacheProperty(BindableObject bindable) { var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; return instance.InternalEnableFrameCache; } + + /// + /// NotifyAfterRasterizationProperty + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty NotifyAfterRasterizationProperty = null; + + internal static void SetInternalNotifyAfterRasterizationProperty(BindableObject bindable, object oldValue, object newValue) + { + var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; + if (newValue != null) + { + instance.InternalNotifyAfterRasterization = (bool)newValue; + } + } + + internal static object GetInternalNotifyAfterRasterizationProperty(BindableObject bindable) + { + var instance = (Tizen.NUI.BaseComponents.LottieAnimationView)bindable; + return instance.InternalNotifyAfterRasterization; + } } } diff --git a/src/Tizen.NUI/src/public/Visuals/VisualConstants.cs b/src/Tizen.NUI/src/public/Visuals/VisualConstants.cs index bfbdbd526..c73700f47 100755 --- a/src/Tizen.NUI/src/public/Visuals/VisualConstants.cs +++ b/src/Tizen.NUI/src/public/Visuals/VisualConstants.cs @@ -994,10 +994,22 @@ namespace Tizen.NUI /// If this property is true, animated image visual uses fixed cache for loading and keeps loaded frame /// until the visual is removed. It reduces CPU cost when the animated image will be looping. /// But it can spend a lot of memory if the resource has high resolution image or many frame count. - /// @note It is used in the AnimatedImageVisual. The default is false + /// @note It is used in the AnimatedVectorImageVisual. The default is false /// [EditorBrowsable(EditorBrowsableState.Never)] public static readonly int EnableFrameCache = NDalic.ImageVisualOrientationCorrection + 16; + + /// + /// @brief Whether notify AnimatedVectorImageVisual to render thread after every rasterization or not. + /// @details type Property::BOOLEAN. + /// If this property is true, AnimatedVectorImageVisual send notify to render thread after every rasterization. + /// If false, AnimatedVectorImageVisual set Renderer's Behaviour as Continouly (mean, always update the render thread.) + /// + /// This flag is useful if given resource has low fps, so we don't need to render every frame. + /// @note It is used in the AnimatedVectorImageVisual. The default is false. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly int NotifyAfterRasterization = NDalic.ImageVisualOrientationCorrection + 17; } /// diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/LottieAnimationTest.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/LottieAnimationTest.cs index d9f6c523f..3372215f9 100755 --- a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/LottieAnimationTest.cs +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/LottieAnimationTest.cs @@ -9,6 +9,7 @@ namespace Tizen.NUI.Samples { lav = new LottieAnimationView(); lav.SynchronousLoading = false; + lav.NotifyAfterRasterization = true; lav.URL = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "a.json"; lav.LoopCount = -1; lav.BackgroundColor = Color.White;