From: Ferran Sole Date: Mon, 28 Nov 2016 15:04:06 +0000 (+0000) Subject: Added sibling order property to Actor X-Git-Tag: dali_1.2.17~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F20%2F100620%2F8;p=platform%2Fcore%2Fuifw%2Fdali-core.git Added sibling order property to Actor - Added a sibling order to allow the user to control drawing order in LAYER_UI Change-Id: Ife3995b46d61ebe7abbc39b6035834b7a581c674 --- diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index 8d1bc31..0a89471 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -16,6 +16,8 @@ */ // EXTERNAL INCLUDES +#include + #include #include #include @@ -1645,6 +1647,157 @@ int UtcDaliRendererRenderOrder2DLayerMultipleRenderers(void) END_TEST; } +int UtcDaliRendererRenderOrder2DLayerDepthIndex(void) +{ + TestApplication application; + tet_infoline("Test the rendering order in a 2D layer is correct using multiple renderers per actor"); + + /* + * Creates the following hierarchy: + * + * Layer + * / \ + * / \ + * / \ + * / \ + * / \ + * actor0 (SIBLING_ORDER:1) actor1 (SIBLING_ORDER:0) + * / | \ / | \ + * / | \ / | \ + * / | \ / | \ + * renderer0 renderer1 actor2 renderer2 renderer3 renderer4 + * | + * | + * renderer5 + * + * actor0 has sibling order 1 + * actor1 has sibling order 0 + * actor2 has sibling order 0 + * + * renderer0 has depth index 2 + * renderer1 has depth index 0 + * + * renderer2 has depth index 0 + * renderer3 has depth index 1 + * renderer4 has depth index 2 + * + * renderer5 has depth index -1 + * + * Expected rendering order: renderer2 - renderer3 - renderer4 - renderer1 - renderer0 - renderer5 + */ + + Shader shader = Shader::New("VertexSource", "FragmentSource"); + Geometry geometry = CreateQuadGeometry(); + + Actor actor0 = Actor::New(); + actor0.SetAnchorPoint(AnchorPoint::CENTER); + actor0.SetParentOrigin(AnchorPoint::CENTER); + actor0.SetPosition(0.0f,0.0f); + actor0.SetSize(1, 1); + actor0.SetProperty( Dali::DevelActor::Property::SIBLING_ORDER, 1 ); + DALI_TEST_EQUALS( actor0.GetProperty( Dali::DevelActor::Property::SIBLING_ORDER), 1, TEST_LOCATION ); + Stage::GetCurrent().Add(actor0); + + Actor actor1 = Actor::New(); + actor1.SetAnchorPoint(AnchorPoint::CENTER); + actor1.SetParentOrigin(AnchorPoint::CENTER); + actor1.SetPosition(0.0f,0.0f); + actor1.SetSize(1, 1); + DALI_TEST_EQUALS( actor1.GetProperty( Dali::DevelActor::Property::SIBLING_ORDER), 0, TEST_LOCATION ); + Stage::GetCurrent().Add(actor1); + + Actor actor2 = Actor::New(); + actor2.SetAnchorPoint(AnchorPoint::CENTER); + actor2.SetParentOrigin(AnchorPoint::CENTER); + actor2.SetPosition(0.0f,0.0f); + actor2.SetSize(1, 1); + DALI_TEST_EQUALS( actor1.GetProperty( Dali::DevelActor::Property::SIBLING_ORDER), 0, TEST_LOCATION ); + actor0.Add(actor2); + + //Renderer0 + Image image0 = BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet0 = CreateTextureSet( image0 ); + Renderer renderer0 = Renderer::New( geometry, shader ); + renderer0.SetTextures( textureSet0 ); + renderer0.SetProperty( Renderer::Property::DEPTH_INDEX, 2 ); + actor0.AddRenderer(renderer0); + application.SendNotification(); + application.Render(0); + + //Renderer1 + Image image1= BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet1 = CreateTextureSet( image1 ); + Renderer renderer1 = Renderer::New( geometry, shader ); + renderer1.SetTextures( textureSet1 ); + renderer1.SetProperty( Renderer::Property::DEPTH_INDEX, 0 ); + actor0.AddRenderer(renderer1); + application.SendNotification(); + application.Render(0); + + //Renderer2 + Image image2= BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet2 = CreateTextureSet( image2 ); + Renderer renderer2 = Renderer::New( geometry, shader ); + renderer2.SetTextures( textureSet2 ); + renderer2.SetProperty( Renderer::Property::DEPTH_INDEX, 0 ); + actor1.AddRenderer(renderer2); + application.SendNotification(); + application.Render(0); + + //Renderer3 + Image image3 = BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet3 = CreateTextureSet( image3 ); + Renderer renderer3 = Renderer::New( geometry, shader ); + renderer3.SetTextures( textureSet3 ); + renderer3.SetProperty( Renderer::Property::DEPTH_INDEX, 1 ); + actor1.AddRenderer(renderer3); + application.SendNotification(); + application.Render(0); + + //Renderer4 + Image image4= BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet4 = CreateTextureSet( image4 ); + Renderer renderer4 = Renderer::New( geometry, shader ); + renderer4.SetTextures( textureSet4 ); + renderer4.SetProperty( Renderer::Property::DEPTH_INDEX, 2 ); + actor1.AddRenderer(renderer4); + application.SendNotification(); + application.Render(0); + + //Renderer5 + Image image5= BufferImage::New( 64, 64, Pixel::RGB888 ); + TextureSet textureSet5 = CreateTextureSet( image5 ); + Renderer renderer5 = Renderer::New( geometry, shader ); + renderer5.SetTextures( textureSet5 ); + renderer5.SetProperty( Renderer::Property::DEPTH_INDEX, -1 ); + actor2.AddRenderer(renderer5); + application.SendNotification(); + application.Render(0); + + + TestGlAbstraction& gl = application.GetGlAbstraction(); + gl.EnableTextureCallTrace(true); + application.SendNotification(); + application.Render(0); + + int textureBindIndex[6]; + for( unsigned int i(0); i<6; ++i ) + { + std::stringstream params; + params << GL_TEXTURE_2D<<", "< + +namespace Dali +{ + +namespace DevelLayer +{ + + /** + * @brief TREE_DEPTH_MULTIPLIER is used by the rendering sorting algorithm to decide which actors to render first. + * @SINCE_1_0.0 + */ + enum TreeDepthMultiplier + { + TREE_DEPTH_MULTIPLIER = 1000000, + }; + + /** + * @brief SIBLING_ORDER_MULTIPLIER is used by the rendering sorting algorithm to decide which actors to render first. + * @SINCE_1_2.16 + */ + enum SiblingOrderMultiplier + { + SIBLING_ORDER_MULTIPLIER = 1000, + }; + +} + +} + +#endif //DALI_LAYER_DEVEL_H diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index 1729634..eefdb14 100644 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -21,7 +21,8 @@ devel_api_src_files = \ # Add devel header files here DALi internal developer files used by Adaptor & Toolkit devel_api_core_actors_header_files = \ - $(devel_api_src_dir)/actors/actor-devel.h + $(devel_api_src_dir)/actors/actor-devel.h \ + $(devel_api_src_dir)/actors/layer-devel.h devel_api_core_animation_header_files = \ $(devel_api_src_dir)/animation/animation-data.h \ diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 1f1a54b..ce9d371 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -24,6 +24,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -355,6 +356,10 @@ float GetDimensionValue( const Vector3& values, Dimension::Type dimension ) return GetDimensionValue( values.GetVectorXY(), dimension ); } +unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder ) +{ + return depth * Dali::DevelLayer::TREE_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER; +} } // unnamed namespace @@ -1970,6 +1975,7 @@ Actor::Actor( DerivedType derivedType ) mName(), mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved mDepth( 0u ), + mSiblingOrder(0u), mIsRoot( ROOT_LAYER == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), @@ -2071,6 +2077,7 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned in mIsOnStage = true; mDepth = depth; + SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) ); ConnectToSceneGraph(); @@ -2677,6 +2684,24 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr break; } + case Dali::DevelActor::Property::SIBLING_ORDER: + { + int value; + + if( property.Get( value ) ) + { + if( static_cast(value) != mSiblingOrder ) + { + mSiblingOrder = value; + if( mIsOnStage ) + { + SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) ); + } + } + } + break; + } + case Dali::Actor::Property::CLIPPING_MODE: { ClippingMode::Type convertedValue = mClippingMode; @@ -3187,6 +3212,12 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const break; } + case Dali::DevelActor::Property::SIBLING_ORDER: + { + value = static_cast(mSiblingOrder); + break; + } + case Dali::Actor::Property::CLIPPING_MODE: { value = mClippingMode; diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 2b3074f..1d37366 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -1815,7 +1815,9 @@ protected: std::string mName; ///< Name of the actor unsigned int mId; ///< A unique ID to identify the actor starting from 1, and 0 is reserved - unsigned short mDepth :12; ///< Cached: The depth in the hierarchy of the actor. Only 4096 levels of depth are supported + uint16_t mDepth; ///< The depth in the hierarchy of the actor. Only 4096 levels of depth are supported + uint16_t mSiblingOrder; ///< The sibling order of the actor + const bool mIsRoot : 1; ///< Flag to identify the root actor const bool mIsLayer : 1; ///< Flag to identify that this is a layer bool mIsOnStage : 1; ///< Flag to identify whether the actor is on-stage diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp index d8e0c0e..75a1f1a 100644 --- a/dali/internal/update/manager/render-instruction-processor.cpp +++ b/dali/internal/update/manager/render-instruction-processor.cpp @@ -225,7 +225,7 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex, if( !isLayer3d ) { - item.mDepthIndex += static_cast( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER; + item.mDepthIndex += renderable.mNode->GetDepthIndex(); } // Save ModelView matrix onto the item. diff --git a/dali/internal/update/manager/render-task-processor.cpp b/dali/internal/update/manager/render-task-processor.cpp index e620005..ec99e03 100644 --- a/dali/internal/update/manager/render-task-processor.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -93,6 +93,7 @@ Layer* FindLayer( Node& node ) * @param[in] currentLayer The current layer containing lists of opaque/transparent renderables. * @param[in] renderTask The current render-task. * @param[in] inheritedDrawMode The draw mode of the parent + * @param[in] parentDepthIndex The inherited parent node depth index * @param[in] currentClippingId The current Clipping Id * Note: ClippingId is passed by reference, so it is permanently modified when traversing back up the tree for uniqueness. * @param[in] clippingDepth The current clipping depth diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 73b52ee..150556d 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -74,8 +74,8 @@ Node::Node() mExclusiveRenderTask( NULL ), mChildren(), mClippingDepth( 0u ), + mDepthIndex( 0u ), mRegenerateUniformMap( 0 ), - mDepth( 0u ), mDirtyFlags( AllFlags ), mDrawMode( DrawMode::NORMAL ), mColorMode( DEFAULT_COLOR_MODE ), @@ -296,7 +296,6 @@ void Node::SetParent( Node& parentNode ) DALI_ASSERT_ALWAYS(mParent == NULL); mParent = &parentNode; - mDepth = mParent->GetDepth() + 1u; if( mTransformId != INVALID_TRANSFORM_ID ) { @@ -343,7 +342,6 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex ) // Remove back-pointer to parent mParent = NULL; - mDepth = 0u; // Remove all child pointers mChildren.Clear(); diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 3cd0117..6e3f98d 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -715,11 +715,6 @@ public: return ( this == rhs ); } - unsigned short GetDepth() const - { - return mDepth; - } - /** * @brief Turns on or off being a batch parent for the node * @param[in] enabled If true the node becomes a parent for batch of its children @@ -727,6 +722,18 @@ public: void SetIsBatchParent( bool enabled ); /** + * @brief Sets the sibling order of the node + * @param[in] order The new order + */ + void SetDepthIndex( unsigned int depthIndex ){ mDepthIndex = depthIndex; } + + /** + * @brief Get the depth index of the node + * @return Current depth index + */ + unsigned int GetDepthIndex(){ return mDepthIndex; } + + /** * @brief Tells if the node is a batch parent * @return True if node is a batch parent, false otherwise. */ @@ -887,10 +894,11 @@ protected: CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node unsigned int mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame uint32_t mClippingDepth; ///< The number of clipping nodes deep this node is - unsigned int mRegenerateUniformMap:2; ///< Indicate if the uniform map has to be regenerated this frame + + uint32_t mDepthIndex; ///< Depth index of the node // flags, compressed to bitfield - unsigned short mDepth:12; ///< Depth in the hierarchy + unsigned int mRegenerateUniformMap:2; ///< Indicate if the uniform map has to be regenerated this frame int mDirtyFlags:8; ///< A composite set of flags for each of the Node properties DrawMode::Type mDrawMode:2; ///< How the Node and its children should be drawn ColorMode mColorMode:2; ///< Determines whether mWorldColor is inherited, 2 bits is enough @@ -1013,6 +1021,17 @@ inline void SetIsBatchParentMessage( EventThreadServices& eventThreadServices, c new (slot) LocalType( &node, &Node::SetIsBatchParent, isBatchParent ); } +inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const Node& node, unsigned int depthIndex ) +{ + typedef MessageValue1< Node, unsigned int > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &node, &Node::SetDepthIndex, depthIndex ); +} + inline void SetClippingModeMessage( EventThreadServices& eventThreadServices, const Node& node, ClippingMode::Type clippingMode ) { typedef MessageValue1< Node, ClippingMode::Type > LocalType;