From e83bedff72a292a5ee310d8aa86ff36e08d0c2d6 Mon Sep 17 00:00:00 2001 From: Kimmo Hoikka Date: Fri, 28 Feb 2014 15:12:59 +0000 Subject: [PATCH] Inline default layer sort function to avoid unnecessary function call [Issue#] N/A [Problem] [Cause] [Solution] inline it and make layer aware when default function is used Change-Id: Ic5376536a9a0925dcfab71aa02f9a0c0a337ab1e Signed-off-by: Paul Wisbey --- dali/internal/event/actors/layer-impl.h | 9 +++++ .../update/manager/prepare-render-instructions.cpp | 38 +++++++++++++--------- .../scene-graph-renderable-attachment.cpp | 5 --- .../scene-graph-renderable-attachment.h | 6 +++- dali/internal/update/nodes/scene-graph-layer.cpp | 13 +++++++- dali/internal/update/nodes/scene-graph-layer.h | 10 ++++++ dali/public-api/actors/layer.cpp | 2 +- 7 files changed, 60 insertions(+), 23 deletions(-) diff --git a/dali/internal/event/actors/layer-impl.h b/dali/internal/event/actors/layer-impl.h index caff89d..7de886b 100644 --- a/dali/internal/event/actors/layer-impl.h +++ b/dali/internal/event/actors/layer-impl.h @@ -44,6 +44,15 @@ class Layer : public Actor public: /** + * @copydoc Dali::Layer::ZValue(const Vector3&, float) + */ + static float ZValue(const Vector3& position, float sortModifier) + { + // inlined so we avoid a function call when sorting renderers + return -position.z + sortModifier; + } + + /** * Create a new Layer. * @return A smart-pointer to the newly allocated Layer. */ diff --git a/dali/internal/update/manager/prepare-render-instructions.cpp b/dali/internal/update/manager/prepare-render-instructions.cpp index e64472f..0f4713f 100644 --- a/dali/internal/update/manager/prepare-render-instructions.cpp +++ b/dali/internal/update/manager/prepare-render-instructions.cpp @@ -18,6 +18,7 @@ #include // INTERNAL INCLUDES +#include // for the default sorting function #include #include #include @@ -278,22 +279,29 @@ inline void SortTransparentRenderItems( RenderList& transparentRenderList, Layer // clear extra elements from helper, does not decrease capability sortingHelper.resize( renderableCount ); } - float sortingValue = 0; - - // calculate sorting values - const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); - for( size_t index = 0; index < renderableCount; ++index ) + // calculate the sorting value, once per item by calling the layers sort function + // Using an if and two for-loops rather than if inside for as its better for branch prediction + if( layer.UsesDefaultSortFunction() ) { - RenderableAttachment& attachment = *layer.transparentRenderables[ index ]; - RenderItem& item = transparentRenderList.GetItem( index ); - - // calculate the sorting value, once per item by calling the layers sort function - const Matrix& modelViewMatrix = item.GetModelViewMatrix(); - sortingValue = (*sortFunction)( modelViewMatrix.GetTranslation3(), attachment.GetSortModifier() ); - - // keep the renderitem pointer in the helper so we can quickly reorder items after sort - sortingHelper[ index ].first = sortingValue; - sortingHelper[ index ].second = &item; + for( size_t index = 0; index < renderableCount; ++index ) + { + RenderItem& item = transparentRenderList.GetItem( index ); + // the default sorting function should get inlined here + sortingHelper[ index ].first = Internal::Layer::ZValue( item.GetModelViewMatrix().GetTranslation3(), layer.transparentRenderables[ index ]->GetSortModifier() ); + // keep the renderitem pointer in the helper so we can quickly reorder items after sort + sortingHelper[ index ].second = &item; + } + } + else + { + const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); + for( size_t index = 0; index < renderableCount; ++index ) + { + RenderItem& item = transparentRenderList.GetItem( index ); + sortingHelper[ index ].first = (*sortFunction)( item.GetModelViewMatrix().GetTranslation3(), layer.transparentRenderables[ index ]->GetSortModifier() ); + // keep the renderitem pointer in the helper so we can quickly reorder items after sort + sortingHelper[ index ].second = &item; + } } // sort the values diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp index 2610f3b..b57ee27 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp @@ -50,11 +50,6 @@ void RenderableAttachment::SetSortModifier(float modifier) mSortModifier = modifier; } -float RenderableAttachment::GetSortModifier() const -{ - return mSortModifier; -} - void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode ) { mBlendingMode = mode; diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h index b3bfe50..670c23e 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h @@ -60,7 +60,11 @@ public: // API * Retrieve the sort-modifier for the attachment. * @return The sort-modifier. */ - float GetSortModifier() const; + float GetSortModifier() const + { + // inlined as its called a lot when sorting transparent renderers + return mSortModifier; + } /** * @See Dali::RenderableActor::SetBlendMode(). diff --git a/dali/internal/update/nodes/scene-graph-layer.cpp b/dali/internal/update/nodes/scene-graph-layer.cpp index a42715a..9adc151 100644 --- a/dali/internal/update/nodes/scene-graph-layer.cpp +++ b/dali/internal/update/nodes/scene-graph-layer.cpp @@ -41,7 +41,8 @@ Layer::Layer() : mSortFunction( Dali::Layer::ZValue ), mClippingBox( 0,0,0,0 ), mIsClipping( false ), - mDepthTestDisabled( false ) + mDepthTestDisabled( false ), + mIsDefaultSortFunction( true ) { // layer starts off dirty mAllChildTransformsClean[ 0 ] = false; @@ -56,6 +57,16 @@ void Layer::SetSortFunction( Dali::Layer::SortFunctionType function ) { if( mSortFunction != function ) { + // is a custom sort function used + if( function != Dali::Layer::ZValue ) + { + mIsDefaultSortFunction = false; + } + else + { + mIsDefaultSortFunction = true; + } + // changing the sort function makes the layer dirty mAllChildTransformsClean[ 0 ] = false; mAllChildTransformsClean[ 1 ] = false; diff --git a/dali/internal/update/nodes/scene-graph-layer.h b/dali/internal/update/nodes/scene-graph-layer.h index 2c3418e..3a23b83 100644 --- a/dali/internal/update/nodes/scene-graph-layer.h +++ b/dali/internal/update/nodes/scene-graph-layer.h @@ -148,6 +148,14 @@ public: return mAllChildTransformsClean[ 0 ] && mAllChildTransformsClean[ 1 ]; } + /** + * @return True if default sort function is used + */ + bool UsesDefaultSortFunction() + { + return mIsDefaultSortFunction; + } + private: /** @@ -179,6 +187,8 @@ private: /// this allows us to cache render items when layer is "static" bool mIsClipping:1; ///< True when clipping is enabled bool mDepthTestDisabled:1; ///< Whether depth test is disabled. + bool mIsDefaultSortFunction:1; ///< whether the default depth sort function is used + }; // Messages for Layer diff --git a/dali/public-api/actors/layer.cpp b/dali/public-api/actors/layer.cpp index 2904160..4f7cbe4 100644 --- a/dali/public-api/actors/layer.cpp +++ b/dali/public-api/actors/layer.cpp @@ -134,7 +134,7 @@ bool Layer::IsDepthTestDisabled() const float Layer::ZValue(const Vector3& position, float sortModifier) { - return -position.z + sortModifier; + return Internal::Layer::ZValue( position, sortModifier ); } void Layer::SetSortFunction(SortFunctionType function) -- 2.7.4