From 7dcd34602d12e17c0fb64cbc0560925878ed87d7 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Tue, 5 Jul 2016 13:42:37 +0100 Subject: [PATCH] Text - Stop destroying the text renderer when text decoration is updated. 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 --- .../src/dali-toolkit/utc-Dali-TextEditor.cpp | 16 +++++------ .../src/dali-toolkit/utc-Dali-TextField.cpp | 14 ++++----- .../controls/text-controls/text-editor-impl.cpp | 31 ++++++++++++-------- .../controls/text-controls/text-editor-impl.h | 2 +- .../controls/text-controls/text-field-impl.cpp | 33 +++++++++++++--------- .../controls/text-controls/text-field-impl.h | 2 +- .../controls/text-controls/text-label-impl.cpp | 4 ++- dali-toolkit/internal/text/text-controller.cpp | 21 ++++++++++---- dali-toolkit/internal/text/text-controller.h | 12 ++++++-- 9 files changed, 84 insertions(+), 51 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index a361701..52f4f87 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -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 ) ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index 1bcbe2b..65fa82e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -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. diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index be5f541..4763884 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -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::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) ); } else { diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h index 118f557..1c7376d 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -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 ); diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 4abf4c3..69776fa 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -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::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) ); } else { diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index bd02762..c574bb8 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -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 ); diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index c2b154e..308f947 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -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 ) diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 47de1a2..3abcccd 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -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 | 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() diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index e559fad..8517ca5 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -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. -- 2.7.4