Text - Stop destroying the text renderer when text decoration is updated. 50/78450/3
authorVictor Cebollada <v.cebollada@samsung.com>
Tue, 5 Jul 2016 12:42:37 +0000 (13:42 +0100)
committerVictor Cebollada <v.cebollada@samsung.com>
Tue, 5 Jul 2016 15:44:31 +0000 (16:44 +0100)
  Currently the text renderer is destroyed every time the text or
the decoration is updated.

  This patch changes the Text::Controller::Relayout() method to return
and enum type. The text controls can avoid the destruction of the text
renderer if the text model is not updated.

Change-Id: Ie0ccbc7e1c7e64dba778059c12bd7a6625de53cc
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h

index a361701..52f4f87 100644 (file)
@@ -597,17 +597,14 @@ int utcDaliTextEditorEvent02(void)
   application.SendNotification();
   application.Render();
 
-  // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image view
-  DALI_TEST_EQUALS( editor.GetChildCount(), 3u, TEST_LOCATION );
+  // Check there are the expected number of children ( offscreen root actor, and the offscreen image view
+  DALI_TEST_EQUALS( editor.GetChildCount(), 2u, TEST_LOCATION );
 
-  Actor layer = editor.GetChildAt( 0u );
-  DALI_TEST_CHECK( layer.IsLayer() );
-
-  Actor offscreenRoot = editor.GetChildAt( 1u );
+  Actor offscreenRoot = editor.GetChildAt( 0u );
   DALI_TEST_CHECK( offscreenRoot.IsLayer() );
   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
 
-  Actor offscreenImage = editor.GetChildAt( 2u );
+  Actor offscreenImage = editor.GetChildAt( 1u );
   DALI_TEST_CHECK( offscreenImage );
 
   // Create a tap event to touch the text editor.
@@ -618,6 +615,9 @@ int utcDaliTextEditorEvent02(void)
   application.SendNotification();
   application.Render();
 
+  Actor layer = editor.GetChildAt( 2u );
+  DALI_TEST_CHECK( layer.IsLayer() );
+
   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
 
@@ -756,7 +756,7 @@ int utcDaliTextEditorEvent03(void)
   application.Render();
 
   // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor.
-  Actor offscreenRoot = editor.GetChildAt( 1u );
+  Actor offscreenRoot = editor.GetChildAt( 0u );
   DALI_TEST_CHECK( offscreenRoot.IsLayer() );
 
   CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
index 1bcbe2b..65fa82e 100644 (file)
@@ -707,17 +707,14 @@ int utcDaliTextFieldEvent02(void)
   application.SendNotification();
   application.Render();
 
-  // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image view
-  DALI_TEST_EQUALS( field.GetChildCount(), 3u, TEST_LOCATION );
+  // Check there are the expected number of children ( offscreen root actor, and the offscreen image view
+  DALI_TEST_EQUALS( field.GetChildCount(), 2u, TEST_LOCATION );
 
-  Actor layer = field.GetChildAt( 0u );
-  DALI_TEST_CHECK( layer.IsLayer() );
-
-  Actor offscreenRoot = field.GetChildAt( 1u );
+  Actor offscreenRoot = field.GetChildAt( 0u );
   DALI_TEST_CHECK( offscreenRoot.IsLayer() );
   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
 
-  Actor offscreenImage = field.GetChildAt( 2u );
+  Actor offscreenImage = field.GetChildAt( 1u );
   DALI_TEST_CHECK( offscreenImage );
 
   // Create a tap event to touch the text field.
@@ -728,6 +725,9 @@ int utcDaliTextFieldEvent02(void)
   application.SendNotification();
   application.Render();
 
+  Actor layer = field.GetChildAt( 2u );
+  DALI_TEST_CHECK( layer.IsLayer() );
+
   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
   DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
 
index be5f541..4763884 100644 (file)
@@ -1005,12 +1005,15 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
 
-  if( mController->Relayout( size ) ||
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
   {
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get() );
 
-    if( mDecorator )
+    if( mDecorator &&
+        ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
     {
       mDecorator->Relayout( size );
     }
@@ -1021,23 +1024,27 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
     }
 
     EnableClipping( true, size );
-    RenderText();
+    RenderText( updateTextType );
   }
 }
 
-void TextEditor::RenderText()
+void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
 {
   Actor self = Self();
   Actor renderableActor;
-  if( mRenderer )
-  {
-    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
-  }
 
-  if( renderableActor != mRenderableActor )
+  if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
   {
-    UnparentAndReset( mRenderableActor );
-    mRenderableActor = renderableActor;
+    if( mRenderer )
+    {
+      renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
+    }
+
+    if( renderableActor != mRenderableActor )
+    {
+      UnparentAndReset( mRenderableActor );
+      mRenderableActor = renderableActor;
+    }
   }
 
   if( mRenderableActor )
@@ -1225,7 +1232,7 @@ void TextEditor::OnStageConnect( Dali::Actor actor )
 {
   if ( mHasBeenStaged )
   {
-    RenderText();
+    RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
   }
   else
   {
index 118f557..1c7376d 100644 (file)
@@ -232,7 +232,7 @@ private: // Implementation
   /**
    * @brief Render view, create and attach actor(s) to this text editor.
    */
-  void RenderText();
+  void RenderText( Text::Controller::UpdateTextType updateTextType );
 
   // Connection needed to re-render text, when a text editor returns to the stage.
   void OnStageConnect( Dali::Actor actor );
index 4abf4c3..69776fa 100644 (file)
@@ -1189,12 +1189,15 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
 
-  if( mController->Relayout( size ) ||
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
       !mRenderer )
   {
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
 
-    if( mDecorator )
+    if( mDecorator &&
+        ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
     {
       mDecorator->Relayout( size );
     }
@@ -1204,24 +1207,28 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
     }
 
-    EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
-    RenderText();
+    EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
+    RenderText( updateTextType );
   }
 }
 
-void TextField::RenderText()
+void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 {
   Actor self = Self();
   Actor renderableActor;
-  if( mRenderer )
-  {
-    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
-  }
 
-  if( renderableActor != mRenderableActor )
+  if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
   {
-    UnparentAndReset( mRenderableActor );
-    mRenderableActor = renderableActor;
+    if( mRenderer )
+    {
+      renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
+    }
+
+    if( renderableActor != mRenderableActor )
+    {
+      UnparentAndReset( mRenderableActor );
+      mRenderableActor = renderableActor;
+    }
   }
 
   if( mRenderableActor )
@@ -1405,7 +1412,7 @@ void TextField::OnStageConnect( Dali::Actor actor )
 {
   if ( mHasBeenStaged )
   {
-    RenderText();
+    RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
   }
   else
   {
index bd02762..c574bb8 100644 (file)
@@ -237,7 +237,7 @@ private: // Implementation
   /**
    * @brief Render view, create and attach actor(s) to this Text Field.
    */
-  void RenderText();
+  void RenderText( Text::Controller::UpdateTextType updateTextType );
 
   // Connection needed to re-render text, when a Text Field returns to the stage.
   void OnStageConnect( Dali::Actor actor );
index c2b154e..308f947 100644 (file)
@@ -711,7 +711,9 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
 
-  if( mController->Relayout( size ) ||
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
       !mRenderer )
   {
     if( !mRenderer )
index 47de1a2..3abcccd 100644 (file)
@@ -1379,17 +1379,18 @@ float Controller::GetHeightForWidth( float width )
   return layoutSize.height;
 }
 
-bool Controller::Relayout( const Size& size )
+Controller::UpdateTextType Controller::Relayout( const Size& size )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, (mImpl->mAutoScrollEnabled)?"true":"false"  );
 
+  UpdateTextType updateTextType = NONE_UPDATED;
+
   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
   {
-    bool glyphsRemoved( false );
     if( 0u != mImpl->mVisualModel->mGlyphPositions.Count() )
     {
       mImpl->mVisualModel->mGlyphPositions.Clear();
-      glyphsRemoved = true;
+      updateTextType = MODEL_UPDATED;
     }
 
     // Clear the update info. This info will be set the next time the text is updated.
@@ -1398,7 +1399,7 @@ bool Controller::Relayout( const Size& size )
     // Not worth to relayout if width or height is equal to zero.
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::Relayout (skipped)\n" );
 
-    return glyphsRemoved;
+    return updateTextType;
   }
 
   // Whether a new size has been set.
@@ -1437,6 +1438,11 @@ bool Controller::Relayout( const Size& size )
                         mImpl->mOperationsPending,
                         layoutSize ) || updated;
 
+  if( updated )
+  {
+    updateTextType = MODEL_UPDATED;
+  }
+
   // Do not re-do any operation until something changes.
   mImpl->mOperationsPending = NO_OPERATION;
 
@@ -1468,14 +1474,17 @@ bool Controller::Relayout( const Size& size )
     }
 
     // Move the cursor, grab handle etc.
-    updated = mImpl->ProcessInputEvents() || updated;
+    if( mImpl->ProcessInputEvents() )
+    {
+      updateTextType = static_cast<UpdateTextType>( updateTextType | DECORATOR_UPDATED );
+    }
   }
 
   // Clear the update info. This info will be set the next time the text is updated.
   mImpl->mTextUpdateInfo.Clear();
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::Relayout\n" );
 
-  return updated;
+  return updateTextType;
 }
 
 void Controller::ProcessModifyEvents()
index e559fad..8517ca5 100644 (file)
@@ -108,6 +108,13 @@ public:
     DONT_UPDATE_INPUT_STYLE
   };
 
+  enum UpdateTextType
+  {
+    NONE_UPDATED      = 0x0,
+    MODEL_UPDATED     = 0x1,
+    DECORATOR_UPDATED = 0x2
+  };
+
   /**
    * @brief Create a new instance of a Controller.
    *
@@ -722,9 +729,10 @@ public:
    *
    * @note UI Controls are expected to minimize calls to this method e.g. call once after size negotiation.
    * @param[in] size A the size of a bounding box to layout text within.
-   * @return True if the text model or decorations were updated.
+   *
+   * @return Whether the text model or decorations were updated.
    */
-  bool Relayout( const Size& size );
+  UpdateTextType Relayout( const Size& size );
 
   /**
    * @brief Process queued events which modify the model.