Add more condition to avoid recomputations for async text
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 11 Jul 2024 10:38:31 +0000 (19:38 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Thu, 11 Jul 2024 10:38:31 +0000 (19:38 +0900)
Do not request async render if only the size has changed when manual render is completed.
Users may attempt to change the size inside the completed callback post manual render.
In case of ASYNC_AUTO, this could potentially trigger relayout and engender further computation.
This is needed to avoid recomputations, but it may have some limitations.

Change-Id: I6a54b6c47866f65faaa38ba4280b4f4ced4c637e
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

index c9b1a38a1e3f14b113e5158eda2b718655b83e08..787901b6e66e1e912c71c8172253220ebfb5b957 100644 (file)
@@ -1153,11 +1153,27 @@ void TextLabel::OnPropertySet(Property::Index index, const Property::Value& prop
       if(mSize != size)
       {
         mSize = size;
-        if(mController->GetRenderMode() != DevelTextLabel::Render::SYNC)
-        {
-          mTextUpdateNeeded = true;
-          mIsPropertyUpdated = true;
-        }
+        mIsSizeChanged = true;
+      }
+      break;
+    }
+    case Dali::Actor::Property::SIZE_WIDTH:
+    {
+      const float width = propertyValue.Get<float>();
+      if(mSize.width != width)
+      {
+        mSize.width = width;
+        mIsSizeChanged = true;
+      }
+      break;
+    }
+    case Dali::Actor::Property::SIZE_HEIGHT:
+    {
+      const float height = propertyValue.Get<float>();
+      if(mSize.height != height)
+      {
+        mSize.height = height;
+        mIsSizeChanged = true;
       }
       break;
     }
@@ -1257,6 +1273,10 @@ void TextLabel::OnSceneDisconnection()
 void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container)
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout\n");
+  bool sizeChanged    = mIsSizeChanged;
+  bool manualRendered = mIsManualRendered;
+  mIsSizeChanged      = false;
+  mIsManualRendered   = false;
 
   if(mController->GetRenderMode() == DevelTextLabel::Render::ASYNC_MANUAL)
   {
@@ -1288,14 +1308,24 @@ void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container)
   if(mController->GetRenderMode() == DevelTextLabel::Render::ASYNC_AUTO ||
      mController->GetRenderMode() == DevelTextLabel::Render::ASYNC_MANUAL)
   {
-    if(mController->GetRenderMode() == DevelTextLabel::Render::ASYNC_AUTO && mTextScroller && mTextScroller->IsScrolling() && !mTextUpdateNeeded)
+    if(mController->GetRenderMode() == DevelTextLabel::Render::ASYNC_AUTO && mTextScroller && mTextScroller->IsScrolling() && !(mTextUpdateNeeded || sizeChanged))
     {
       // When auto scroll is playing, a text load request is made only if a text update is absolutely necessary.
       return;
     }
 
-    if(!mIsPropertyUpdated || mIsManualRendering)
+    if(mIsManualRender || !(sizeChanged || mIsPropertyUpdated))
+    {
+      // Do not request async render if the manual render is still ongoing or if there are no size or property updates.
+      return;
+    }
+
+    if(manualRendered && sizeChanged && !mIsPropertyUpdated)
     {
+      // Do not request async render if only the size has changed when manual render is completed.
+      // Users may attempt to change the size inside the completed callback post manual render.
+      // In case of ASYNC_AUTO, this could potentially trigger relayout and engender further computation.
+      // This is needed to avoid recomputations, but it may have some limitations.
       return;
     }
 
@@ -1594,9 +1624,10 @@ void TextLabel::AsyncLoadComplete(Text::AsyncTextRenderInfo renderInfo)
   Extents padding;
   padding = self.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
 
-  if(mIsManualRendering)
+  if(mIsManualRender)
   {
-    mIsManualRendering = false;
+    mIsManualRender = false;
+    mIsManualRendered = true;
   }
 
   EmitAsyncTextRenderedSignal(renderInfo.renderedSize.width + (padding.start + padding.end), renderInfo.renderedSize.height + (padding.top + padding.bottom));
@@ -1647,7 +1678,9 @@ TextLabel::TextLabel(ControlBehaviour additionalBehaviour)
   mLastAutoScrollEnabled(false),
   mControlBackgroundEnabeld(true),
   mIsPropertyUpdated(false),
-  mIsManualRendering(false)
+  mIsSizeChanged(false),
+  mIsManualRender(false),
+  mIsManualRendered(false)
 {
 }
 
@@ -1751,7 +1784,7 @@ void TextLabel::RequestAsyncRenderWithFixedSize(float width, float height)
     return;
   }
 
-  mIsManualRendering = true;
+  mIsManualRender = true;
 
   Actor self = Self();
 
@@ -1787,7 +1820,7 @@ void TextLabel::RequestAsyncRenderWithFixedWidth(float width, float heightConstr
     return;
   }
 
-  mIsManualRendering = true;
+  mIsManualRender = true;
 
   Actor self = Self();
 
@@ -1823,7 +1856,7 @@ void TextLabel::RequestAsyncRenderWithConstraint(float widthConstraint, float he
     return;
   }
 
-  mIsManualRendering = true;
+  mIsManualRender = true;
 
   Actor self = Self();
 
index d488e6516027f12d939fa750411fd21f56e27eae..14cda708555c75ec99e86c6d36037d9de8aab4ec 100644 (file)
@@ -445,15 +445,17 @@ private: // Data
   Toolkit::DevelTextLabel::AsyncTextRenderedSignalType mAsyncTextRenderedSignal;
 
   std::string mLocale;
-  Vector2 mSize;
+  Vector2     mSize;
 
   int  mRenderingBackend;
-  bool mTextUpdateNeeded : 1;
-  bool mLastAutoScrollEnabled : 1;
+  bool mTextUpdateNeeded         : 1;
+  bool mLastAutoScrollEnabled    : 1;
   bool mControlBackgroundEnabeld : 1;
 
-  bool mIsPropertyUpdated : 1;
-  bool mIsManualRendering : 1;
+  bool mIsPropertyUpdated : 1; // true if a render request is required in ASYNC_AUTO mode, otherwise false.
+  bool mIsSizeChanged     : 1; // whether the size has been changed or not.
+  bool mIsManualRender    : 1; // whether an async manual render has been requested, returns false when completed.
+  bool mIsManualRendered  : 1; // whether an async manual render has been completed, returns false on the next relayout.
 
 protected:
   /**