Fix background flickering issue during async cutout
authorBowon Ryu <bowon.ryu@samsung.com>
Tue, 18 Jun 2024 05:43:27 +0000 (14:43 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Tue, 18 Jun 2024 05:46:15 +0000 (14:46 +0900)
during the cutout property's on/off, the background visual will turned on/off.
in async load, we need to turn on/off the background visual
at the point of load complete to avoid flickering issues.

Change-Id: Ida87e9e5e4f59c42e76e506a10e9c84b126d4cbd
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/text/async-text/async-text-interface.h
dali-toolkit/internal/visuals/text/text-visual.cpp

index 8acea27..8d9b18b 100644 (file)
@@ -1108,45 +1108,39 @@ void TextLabel::OnPropertySet(Property::Index index, const Property::Value& prop
     }
     case Toolkit::Control::Property::BACKGROUND:
     {
-      const Vector4 backgroundColor = propertyValue.Get<Vector4>();
-
       if(mController->IsTextCutout())
       {
-        DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, false);
-        mController->SetBackgroundWithCutoutEnabled(true);
+        const Vector4 backgroundColor = propertyValue.Get<Vector4>();
         mController->SetBackgroundColorWithCutout(backgroundColor);
-      }
+        mController->SetBackgroundWithCutoutEnabled(true);
 
+        if(!mController->IsAsyncTextLoadEnabled())
+        {
+          EnableControlBackground(false);
+        }
+      }
       break;
     }
     case Toolkit::DevelTextLabel::Property::CUTOUT:
     {
       const bool cutoutEnabled = propertyValue.Get<bool>();
-
+      mController->SetBackgroundWithCutoutEnabled(cutoutEnabled);
       if(cutoutEnabled)
       {
-        Vector4 backgroundColor = Vector4::ZERO;
-
         const Property::Map backgroundMap   = Self().GetProperty(Toolkit::Control::Property::BACKGROUND).Get<Property::Map>();
         Property::Value*    backgroundValue = backgroundMap.Find(ColorVisual::Property::MIX_COLOR);
         if(backgroundValue)
         {
+          Vector4 backgroundColor = Vector4::ZERO;
           backgroundColor = backgroundValue->Get<Vector4>();
+          mController->SetBackgroundColorWithCutout(backgroundColor);
         }
-
-        DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, false);
-        mController->SetBackgroundWithCutoutEnabled(true);
-        mController->SetBackgroundColorWithCutout(backgroundColor);
       }
-      else
+      if(!mController->IsAsyncTextLoadEnabled())
       {
-        DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, true);
-
-        Property::Map backgroundMapSet;
-        mController->SetBackgroundWithCutoutEnabled(false);
+        EnableControlBackground(!cutoutEnabled);
+        TextVisual::SetRequireRender(mVisual, cutoutEnabled);
       }
-
-      TextVisual::SetRequireRender(mVisual, cutoutEnabled);
       break;
     }
     default:
@@ -1502,6 +1496,15 @@ void TextLabel::AsyncTextFitChanged(float pointSize)
   }
 }
 
+void TextLabel::AsyncLoadComplete()
+{
+  // Pure Virtual from AsyncTextInterface
+  DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::AsyncLoadComplete\n");
+
+  // To avoid flickering issues, enable/disable the background visual when async load is completed.
+  EnableControlBackground(!mController->IsTextCutout());
+}
+
 void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
 {
   mController->ChangedLayoutDirection();
@@ -1537,7 +1540,8 @@ TextLabel::TextLabel(ControlBehaviour additionalBehaviour)
   mLocale(std::string()),
   mRenderingBackend(DEFAULT_RENDERING_BACKEND),
   mTextUpdateNeeded(false),
-  mLastAutoScrollEnabled(false)
+  mLastAutoScrollEnabled(false),
+  mControlBackgroundEnabeld(true)
 {
 }
 
@@ -1621,6 +1625,16 @@ bool TextLabel::IsRemoveBackInset() const
   return mController->IsRemoveBackInset();
 }
 
+void TextLabel::EnableControlBackground(const bool enable)
+{
+  // Avoid function calls if there is no change.
+  if(mControlBackgroundEnabeld != enable)
+  {
+    mControlBackgroundEnabeld = enable;
+    DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, enable);
+  }
+}
+
 std::string TextLabel::TextLabelAccessible::GetNameRaw() const
 {
   return GetWholeText();
index 98d6696..a6bf159 100644 (file)
@@ -227,6 +227,13 @@ public:
    */
   bool IsRemoveBackInset() const;
 
+  /**
+   * @brief Enable control's background
+   *
+   * @param[in] enable Whether to enable the background of control.
+   */
+  void EnableControlBackground(const bool enable);
+
 private: // From Control
   /**
    * @copydoc Control::OnInitialize()
@@ -309,6 +316,11 @@ private: // from AsyncTextInterface
    */
   void AsyncTextFitChanged(float pointSize) override;
 
+  /**
+   * @copydoc Text::AsyncTextInterface::AsyncLoadComplete()
+   */
+  void AsyncLoadComplete();
+
 private: // Implementation
   /**
    * Construct a new TextLabel.
@@ -392,6 +404,7 @@ private: // Data
   int  mRenderingBackend;
   bool mTextUpdateNeeded : 1;
   bool mLastAutoScrollEnabled : 1;
+  bool mControlBackgroundEnabeld : 1;
 
 protected:
   /**
index 79ecdbb..7f406fc 100644 (file)
@@ -53,6 +53,11 @@ public:
    * @brief Called when the text fit changed.
    */
   virtual void AsyncTextFitChanged(float pointSize) = 0;
+
+  /**
+   * @brief Called when the async load complete.
+   */
+  virtual void AsyncLoadComplete() = 0;
 };
 
 } // namespace Text
index 219b18c..eefa52c 100644 (file)
@@ -760,6 +760,8 @@ void TextVisual::LoadComplete(bool loadingSuccess, TextInformation textInformati
       visualTransformOffset.y = roundf(parameters.padding.top + alignmentOffset.y);
     }
 
+    SetRequireRender(renderInfo.isCutout);
+
     // Transform offset is used for subpixel data upload in text tiling.
     // We should set the transform before creating a tiling texture.
     Property::Map visualTransform;
@@ -915,6 +917,7 @@ void TextVisual::LoadComplete(bool loadingSuccess, TextInformation textInformati
             // VisualRenderer::Property::OPACITY uses same animatable property internally.
             Constraint opacityConstraint = Constraint::New<float>(renderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
             opacityConstraint.AddSource(Source(control, mAnimatableTextColorPropertyIndex));
+            opacityConstraint.AddSource(Source(mImpl->mRenderer, mTextRequireRenderPropertyIndex));
             opacityConstraint.Apply();
           }
         }
@@ -930,6 +933,11 @@ void TextVisual::LoadComplete(bool loadingSuccess, TextInformation textInformati
     {
       mAsyncTextInterface->AsyncTextFitChanged(parameters.fontSize);
     }
+
+    if(mAsyncTextInterface)
+    {
+      mAsyncTextInterface->AsyncLoadComplete();
+    }
   }
   else
   {
@@ -1213,10 +1221,14 @@ Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, const TextVis
 
 void TextVisual::SetRequireRender(bool requireRender)
 {
-  mTextRequireRender = requireRender;
-  if(mImpl->mRenderer)
+  // Avoid function calls if there is no change.
+  if(mTextRequireRender != requireRender)
   {
-    mImpl->mRenderer.SetProperty(mTextRequireRenderPropertyIndex, mTextRequireRender);
+    mTextRequireRender = requireRender;
+    if(mImpl->mRenderer)
+    {
+      mImpl->mRenderer.SetProperty(mTextRequireRenderPropertyIndex, mTextRequireRender);
+    }
   }
 }