utc-Dali-Internal-FixedSizeMemoryPool.cpp
utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
utc-Dali-Internal-FrustumCulling.cpp
+ utc-Dali-Internal-ActorDepth.cpp
)
LIST(APPEND TC_SOURCES
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+
+#include <dali-test-suite-utils.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+// Internal headers are allowed here
+#define protected public
+#include <dali/internal/event/actors/actor-impl.h>
+
+using namespace Dali;
+
+void utc_dali_internal_actor_depth_startup()
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_actor_depth_cleanup()
+{
+ test_return_value = TET_PASS;
+}
+
+Actor CreateActor( Actor parent, int siblingOrder, const char* name )
+{
+ Actor actor = Actor::New();
+ actor.SetProperty( DevelActor::Property::SIBLING_ORDER, siblingOrder);
+ actor.SetName( name );
+ parent.Add(actor);
+ return actor;
+}
+
+void PrintActor(Dali::Actor a, int depth)
+{
+ int siblingOrder;
+ Dali::Property::Value v = a.GetProperty( Dali::DevelActor::Property::SIBLING_ORDER );
+ v.Get(siblingOrder);
+
+ Dali::Internal::Actor& actorImpl = GetImplementation(a);
+ for( int i=0; i<depth; ++i)
+ std::cout << " ";
+ std::cout << "Actor: " << a.GetName() << "(" << a.GetId() << ") siblingOrder: " <<
+ siblingOrder << " depthOrder: " << actorImpl.GetSortingDepth() << std::endl;
+}
+
+void PrintActorTree( Dali::Actor a, int depth )
+{
+ PrintActor( a, depth );
+ for( unsigned int i=0; i<a.GetChildCount(); ++i )
+ {
+ PrintActorTree( a.GetChildAt(i), depth+1 );
+ }
+}
+
+void PrintNode( Dali::Internal::ActorDepthTreeNode& node, int depth )
+{
+ for( int i=0; i<depth; ++i)
+ std::cout << " ";
+ std::cout << "Node: " << &node << " siblingOrder:" << node.mSiblingOrder << " Actors:";
+ for( std::vector<Internal::Actor*>::iterator iter = node.mActors.begin() ;
+ iter != node.mActors.end(); ++iter )
+ {
+ std::cout << (*iter)->GetName() << ", ";
+ }
+ std::cout << std::endl;
+
+ if( node.mFirstChildNode )
+ PrintNode( *node.mFirstChildNode, depth+1);
+
+ if( node.mNextSiblingNode )
+ {
+ PrintNode( *node.mNextSiblingNode, depth );
+ }
+}
+
+void CheckNodeForActor( Dali::Internal::ActorDepthTreeNode*node, Actor actor, const char* loc )
+{
+ bool found = false;
+ Dali::Internal::Actor& actorImpl = Dali::GetImplementation(actor);
+
+ for( std::vector<Internal::Actor*>::iterator iter = node->mActors.begin(); iter != node->mActors.end(); ++iter )
+ {
+ if( *iter == &actorImpl )
+ {
+ found = true;
+ break;
+ }
+ }
+ DALI_TEST_EQUALS( found, true, loc );
+}
+
+unsigned int GetActorCount( Dali::Internal::ActorDepthTreeNode*node )
+{
+ unsigned int size = node->mActors.size();
+
+ for( Dali::Internal::ActorDepthTreeNode* childNode = node->mFirstChildNode;
+ childNode != NULL;
+ childNode = childNode->mNextSiblingNode )
+ {
+ size += GetActorCount( childNode );
+ }
+
+ return size;
+}
+
+int UtcDaliActorDepthTreeTest01(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Actor tree depth");
+
+ Stage stage = Stage::GetCurrent();
+
+ Actor Root = CreateActor(stage.GetRootLayer(), 0, "ROOT" );
+ Actor A = CreateActor( Root, 0, "A");
+ Actor B = CreateActor( Root, 2, "B");
+ Actor C = CreateActor( Root, 0, "C");
+ Actor D = CreateActor( Root, 1, "D");
+
+ Actor E = CreateActor(A, 0, "E");
+ Actor F = CreateActor(A, 2, "F");
+ Actor G = CreateActor(A, 1, "G");
+
+ Actor H = CreateActor(B, 2, "H");
+ Actor I = CreateActor(B, 1, "I");
+ Actor J = CreateActor(B, 0, "J");
+
+ Actor K = CreateActor(C, 1, "K");
+ Actor L = CreateActor(C, 2, "L");
+ Actor M = CreateActor(C, 0, "M");
+
+ Actor N = CreateActor(D, 2, "N");
+ Actor O = CreateActor(D, 2, "O");
+ Actor P = CreateActor(D, 1, "P");
+
+ PrintActorTree( Root, 0 );
+
+ Internal::Actor& rootLayerImpl = GetImplementation(Root);
+
+ Internal::DepthNodeMemoryPool nodeMemoryPool;
+ Internal::ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) Internal::ActorDepthTreeNode( &rootLayerImpl, 0 );
+ rootLayerImpl.BuildDepthTree( nodeMemoryPool, rootNode ) ;
+
+ int depth=0;
+ PrintNode( *rootNode, depth );
+
+ // Check that first child node contains actors A and C
+ // check that first grand child node contains actors E, M
+ // check that it's sibling node contains actors G, K
+ // check that it's sibling node contains actors F, L
+ // Check that tree only contains 16 actors.
+ CheckNodeForActor( rootNode->mFirstChildNode, A, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode, C, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, E, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, M, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode, G, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode, K, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, F, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, L, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, B, TEST_LOCATION );
+
+ unsigned int actorCount = GetActorCount( rootNode );
+ DALI_TEST_EQUALS( actorCount, 17, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+
+int UtcDaliActorDepthTreeTest02(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Actor tree depth");
+
+ Stage stage = Stage::GetCurrent();
+
+ Actor Root = CreateActor(stage.GetRootLayer(), 0, "ROOT" );
+ Actor A = CreateActor( Root, 0, "A");
+ Actor B = CreateActor( Root, 0, "B");
+ Actor C = CreateActor( Root, 0, "C");
+ Actor D = CreateActor( Root, 0, "D");
+
+ Actor E = CreateActor(A, 0, "E");
+ Actor F = CreateActor(A, 0, "F");
+ Actor G = CreateActor(A, 0, "G");
+
+ Actor H = CreateActor(B, 0, "H");
+ Actor I = CreateActor(B, 0, "I");
+ Actor J = CreateActor(B, 0, "J");
+
+ Actor K = CreateActor(C, 0, "K");
+ Actor L = CreateActor(C, 0, "L");
+ Actor M = CreateActor(C, 0, "M");
+
+ Actor N = CreateActor(D, 0, "N");
+ Actor O = CreateActor(D, 0, "O");
+ Actor P = CreateActor(D, 0, "P");
+
+ PrintActorTree( Root, 0 );
+
+ Internal::Actor& rootLayerImpl = GetImplementation(Root);
+
+ Internal::DepthNodeMemoryPool nodeMemoryPool;
+ Internal::ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) Internal::ActorDepthTreeNode( &rootLayerImpl, 0 );
+ rootLayerImpl.BuildDepthTree( nodeMemoryPool, rootNode ) ;
+
+ int depth=0;
+ PrintNode( *rootNode, depth );
+
+ CheckNodeForActor( rootNode->mFirstChildNode, A, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode, C, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, E, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, M, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, G, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, K, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, F, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, L, TEST_LOCATION );
+ CheckNodeForActor( rootNode->mFirstChildNode, B, TEST_LOCATION );
+
+ unsigned int actorCount = GetActorCount( rootNode );
+ DALI_TEST_EQUALS( actorCount, 17, TEST_LOCATION );
+
+ END_TEST;
+}
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( touchPoint.x, touchPoint.y ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
- application.ProcessEvent( event );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
+ application.ProcessEvent( touchEvent );
DALI_TEST_CHECK( gTouchCallBackCalled == true );
END_TEST;
point.SetDeviceId( 1 );
point.SetState( PointState::MOTION );
point.SetScreenPosition( Vector2( touchPoint.x, touchPoint.y ) );
- Dali::Integration::HoverEvent event;
- event.AddPoint( point );
- application.ProcessEvent( event );
+ Dali::Integration::HoverEvent hoverEvent;
+ hoverEvent.AddPoint( point );
+ application.ProcessEvent( hoverEvent );
DALI_TEST_CHECK( gHoverCallBackCalled == true );
END_TEST;
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
value.Get( preActorOrder );
DevelActor::Raise( actorB );
+ // Ensure sort order is calculated before next touch event
+ application.SendNotification();
value = actorB.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
value.Get( postActorOrder );
tet_printf( "Raised ActorB from (%d) to (%d) \n", preActorOrder, postActorOrder );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, true , TEST_LOCATION );
value.Get( preActorOrder );
DevelActor::Lower( actorB );
+ application.SendNotification(); // ensure sort order calculated before next touch event
value = actorB.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
value.Get( postActorOrder );
tet_printf( "Lowered ActorB from (%d) to (%d) \n", preActorOrder, postActorOrder );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false , TEST_LOCATION );
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
tet_printf( "RaiseToTop ActorA\n" );
DevelActor::RaiseToTop( actorA );
+ application.SendNotification(); // ensure sorting order is calculated before next touch event
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
tet_printf( "RaiseToTop ActorB\n" );
DevelActor::RaiseToTop( actorB );
+ application.SendNotification(); // Ensure sort order is calculated before next touch event
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
application.SendNotification();
application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
tet_printf( "Raise actor B Above Actor C\n" );
DevelActor::RaiseAbove( actorB, actorC );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, true, TEST_LOCATION );
DevelActor::RaiseAbove( actorA, actorB );
- application.ProcessEvent( event );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
+
+ application.ProcessEvent( touchEvent ); // process a touch event on ordered actors.
DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
tet_infoline( "UtcDaliActor Test Set up completed \n" );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
tet_printf( "Lower actor C below Actor B ( actor B and A on same level due to insertion order) so C is below both \n" );
DevelActor::LowerBelow( actorC, actorB );
-
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
application.SendNotification();
application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent ); // touch event
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
tet_printf( "Lower actor B below Actor C leaving A on top\n" );
DevelActor::LowerBelow( actorB, actorC );
-
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
application.SendNotification();
application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
tet_printf( "Lower actor A below Actor C leaving C on top\n" );
DevelActor::LowerBelow( actorA, actorC );
-
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
application.SendNotification();
application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
glAbstraction.ResetSetUniformCallStack();
glSetUniformStack = glAbstraction.GetSetUniformTrace();
Actor sibling = parent.GetChildAt( 5 );
DevelActor::RaiseToTop( sibling );
+ // Ensure sorting happens at end of Core::ProcessEvents()
application.SendNotification();
application.Render();
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
tet_printf( "Raise actor A Above Actor C which have different parents\n" );
DevelActor::RaiseAbove( actorA, actorC );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent ); // touch event
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
tet_printf( "Raise actor A Above Actor C which have no parents\n" );
DevelActor::RaiseAbove( actorA, actorC );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so RaiseAbove should show no effect\n" );
ResetTouchCallbacks();
stage.Add ( actorB );
+ tet_printf( "Lower actor A below Actor C when only A is not on stage \n" );
+ DevelActor::LowerBelow( actorA, actorC );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
application.SendNotification();
application.Render();
- tet_printf( "Lower actor A below Actor C when only A is not on stage \n" );
- DevelActor::LowerBelow( actorA, actorC );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Actor A not parented so LowerBelow should show no effect\n" );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
tet_printf( "Raise actor B Above Actor C when only B has a parent\n" );
DevelActor::RaiseAbove( actorB, actorC );
- application.ProcessEvent( event );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
+
+ application.ProcessEvent( touchEvent );
tet_printf( "C not parented so RaiseAbove should show no effect\n" );
DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
tet_printf( "Lower actor A below Actor C when only A has a parent\n" );
DevelActor::LowerBelow( actorA, actorC );
- application.ProcessEvent( event );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
+ application.SendNotification();
+
+ application.ProcessEvent( touchEvent );
tet_printf( "C not parented so LowerBelow should show no effect\n" );
DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
ResetTouchCallbacks();
stage.Add ( actorC );
-
+ DevelActor::RaiseAbove( actorA, actorC );
+ // Ensure sorting happens at end of Core::ProcessEvents() before next touch
application.SendNotification();
application.Render();
- DevelActor::RaiseAbove( actorA, actorC );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Raise actor A Above Actor C, now both have same parent \n" );
DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
stage.Add ( actorA );
+ tet_printf( "Raise actor B Above Actor C but B not parented\n" );
+ DevelActor::Raise( actorB );
application.SendNotification();
application.Render();
- tet_printf( "Raise actor B Above Actor C but B not parented\n" );
-
- DevelActor::Raise( actorB );
-
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so RaiseAbove should show no effect\n" );
ResetTouchCallbacks();
DevelActor::Lower( actorC );
+ // Sort actor tree before next touch event
+ application.SendNotification();
+ application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so RaiseAbove should show no effect\n" );
tet_printf( "Lower actor C below B but C not parented\n" );
DevelActor::Lower( actorB );
+ // Sort actor tree before next touch event
+ application.SendNotification();
+ application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so Lower should show no effect\n" );
tet_printf( "Raise actor B to top\n" );
DevelActor::RaiseToTop( actorB );
+ // Sort actor tree before next touch event
+ application.SendNotification();
+ application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so RaiseToTop should show no effect\n" );
stage.Add ( actorB );
- application.SendNotification();
- application.Render();
-
tet_printf( "Lower actor C to Bottom, B stays at top\n" );
DevelActor::LowerToBottom( actorC );
+ application.SendNotification();
+ application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_printf( "Not parented so LowerToBottom should show no effect\n" );
point.SetDeviceId( 1 );
point.SetState( PointState::DOWN );
point.SetScreenPosition( Vector2( 10.f, 10.f ) );
- Dali::Integration::TouchEvent event;
- event.AddPoint( point );
+ Dali::Integration::TouchEvent touchEvent;
+ touchEvent.AddPoint( point );
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
tet_infoline( "Raise actor A Above Actor A which is the same actor!!\n" );
DevelActor::RaiseAbove( actorA, actorA );
+ application.SendNotification();
+ application.Render();
- application.ProcessEvent( event );
+ application.ProcessEvent( touchEvent );
tet_infoline( "No target is source Actor so RaiseAbove should show no effect\n" );
ResetTouchCallbacks();
DevelActor::RaiseAbove( actorA, actorC );
- application.ProcessEvent( event );
+ application.SendNotification();
+ application.Render();
+
+ application.ProcessEvent( touchEvent );
tet_infoline( "Raise actor A Above Actor C which will now be successful \n" );
DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
END_TEST;
}
-
int utcDaliActorVisibilityChangeSignalSelf(void)
{
TestApplication application;
END_TEST;
}
+
+Renderer CreateRenderer( Actor actor, Geometry geometry, Shader shader, int depthIndex )
+{
+ 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, depthIndex );
+ actor.AddRenderer(renderer0);
+ return renderer0;
+}
+
+
+Actor CreateActor( Actor parent, int siblingOrder, const char* location )
+{
+ Actor actor0 = Actor::New();
+ actor0.SetAnchorPoint(AnchorPoint::CENTER);
+ actor0.SetParentOrigin(AnchorPoint::CENTER);
+ actor0.SetPosition(0.0f,0.0f);
+ actor0.SetSize(100, 100);
+ actor0.SetProperty( Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder );
+ DALI_TEST_EQUALS( actor0.GetProperty<int>( Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location) );
+ parent.Add(actor0);
+
+ return actor0;
+}
+
int UtcDaliRendererRenderOrder2DLayer(void)
{
TestApplication application;
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);
- Image image0 = BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet0 = CreateTextureSet( image0 );
- Renderer renderer0 = Renderer::New( geometry, shader );
- renderer0.SetTextures( textureSet0 );
- actor0.AddRenderer(renderer0);
- actor0.SetSize(1, 1);
- Stage::GetCurrent().Add(actor0);
- application.SendNotification();
- application.Render(0);
+ Actor root = Stage::GetCurrent().GetRootLayer();
- Actor actor1 = Actor::New();
- actor1.SetAnchorPoint(AnchorPoint::CENTER);
- actor1.SetParentOrigin(AnchorPoint::CENTER);
- actor1.SetPosition(0.0f,0.0f);
- Image image1= BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet1 = CreateTextureSet( image1 );
- Renderer renderer1 = Renderer::New( geometry, shader );
- renderer1.SetTextures( textureSet1 );
- actor1.AddRenderer(renderer1);
- actor1.SetSize(1, 1);
- Stage::GetCurrent().Add(actor1);
- application.SendNotification();
- application.Render(0);
+ Actor actor0 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer0 = CreateRenderer( actor0, geometry, shader, 0 );
- Actor actor2 = Actor::New();
- actor2.SetAnchorPoint(AnchorPoint::CENTER);
- actor2.SetParentOrigin(AnchorPoint::CENTER);
- actor2.SetPosition(0.0f,0.0f);
- Image image2= BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet2 = CreateTextureSet( image2 );
- Renderer renderer2 = Renderer::New( geometry, shader );
- renderer2.SetTextures( textureSet2 );
- actor2.AddRenderer(renderer2);
- actor2.SetSize(1, 1);
- Stage::GetCurrent().Add(actor2);
- application.SendNotification();
- application.Render(0);
+ Actor actor1 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer1 = CreateRenderer( actor1, geometry, shader, 0 );
+
+ Actor actor2 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer2 = CreateRenderer( actor2, geometry, shader, 0 );
+
+ Actor actor3 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer3 = CreateRenderer( actor3, geometry, shader, 0 );
- Actor actor3 = Actor::New();
- actor3.SetAnchorPoint(AnchorPoint::CENTER);
- actor3.SetParentOrigin(AnchorPoint::CENTER);
- actor3.SetPosition(0.0f,0.0f);
- Image image3 = BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet3 = CreateTextureSet( image3 );
- Renderer renderer3 = Renderer::New( geometry, shader );
- renderer3.SetTextures( textureSet3 );
- actor3.AddRenderer(renderer3);
- actor3.SetSize(1, 1);
- Stage::GetCurrent().Add(actor3);
application.SendNotification();
application.Render(0);
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);
- 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);
- actor0.Add(actor1);
-
- //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, 1 );
- actor0.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);
+ Actor root = Stage::GetCurrent().GetRootLayer();
- //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, 0 );
- actor1.AddRenderer(renderer4);
- application.SendNotification();
- application.Render(0);
+ Actor actor0 = CreateActor( root, 0, TEST_LOCATION );
+ Actor actor1 = CreateActor( actor0, 0, TEST_LOCATION );
+ Renderer renderer0 = CreateRenderer( actor0, geometry, shader, 2 );
+ Renderer renderer1 = CreateRenderer( actor0, geometry, shader, 0 );
+ Renderer renderer2 = CreateRenderer( actor0, geometry, shader, 1 );
+ Renderer renderer3 = CreateRenderer( actor1, geometry, shader, 1 );
+ Renderer renderer4 = CreateRenderer( actor1, geometry, shader, 0 );
+ Renderer renderer5 = CreateRenderer( actor1, geometry, shader, -1 );
- //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 );
- actor1.AddRenderer(renderer5);
application.SendNotification();
application.Render(0);
-
TestGlAbstraction& gl = application.GetGlAbstraction();
gl.EnableTextureCallTrace(true);
application.SendNotification();
END_TEST;
}
+
int UtcDaliRendererRenderOrder2DLayerSiblingOrder(void)
{
TestApplication application;
* / | \ / | \
* / | \ / | \
* renderer0 renderer1 actor2 renderer2 renderer3 renderer4
- * |
+ * DI:2 DI:0 | DI:0 DI:1 DI:2
* |
* renderer5
+ * DI:-1
*
* actor0 has sibling order 1
* actor1 has sibling order 0
Shader shader = Shader::New("VertexSource", "FragmentSource");
Geometry geometry = CreateQuadGeometry();
+ Actor root = Stage::GetCurrent().GetRootLayer();
+ Actor actor0 = CreateActor( root, 1, TEST_LOCATION );
+ Actor actor1 = CreateActor( root, 0, TEST_LOCATION );
+ Actor actor2 = CreateActor( actor0, 0, TEST_LOCATION );
- 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<int>( 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<int>( 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<int>( 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);
+ Renderer renderer0 = CreateRenderer( actor0, geometry, shader, 2 );
+ Renderer renderer1 = CreateRenderer( actor0, geometry, shader, 0 );
+ Renderer renderer2 = CreateRenderer( actor1, geometry, shader, 0 );
+ Renderer renderer3 = CreateRenderer( actor1, geometry, shader, 1 );
+ Renderer renderer4 = CreateRenderer( actor1, geometry, shader, 2 );
+ Renderer renderer5 = CreateRenderer( actor2, geometry, shader, -1 );
- //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);
-
+ application.Render();
TestGlAbstraction& gl = application.GetGlAbstraction();
gl.EnableTextureCallTrace(true);
DALI_TEST_EQUALS( textureBindIndex[0], 4, TEST_LOCATION );
DALI_TEST_EQUALS( textureBindIndex[5], 5, TEST_LOCATION );
- //Change sibling order of actor1
- //New Expected rendering order: renderer1 - renderer0 - renderer2 - renderer3 - renderer4 - renderer5
+ // Change sibling order of actor1
+ // New Expected rendering order: renderer1 - renderer0 - renderer 5 - renderer2 - renderer3 - renderer4
actor1.SetProperty( Dali::DevelActor::Property::SIBLING_ORDER, 2 );
gl.GetTextureTrace().Reset();
DALI_TEST_EQUALS( textureBindIndex[1], 0, TEST_LOCATION );
DALI_TEST_EQUALS( textureBindIndex[0], 1, TEST_LOCATION );
- DALI_TEST_EQUALS( textureBindIndex[2], 2, TEST_LOCATION );
- DALI_TEST_EQUALS( textureBindIndex[3], 3, TEST_LOCATION );
- DALI_TEST_EQUALS( textureBindIndex[4], 4, TEST_LOCATION );
- DALI_TEST_EQUALS( textureBindIndex[5], 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( textureBindIndex[5], 2, TEST_LOCATION );
+ DALI_TEST_EQUALS( textureBindIndex[2], 3, TEST_LOCATION );
+ DALI_TEST_EQUALS( textureBindIndex[3], 4, TEST_LOCATION );
+ DALI_TEST_EQUALS( textureBindIndex[4], 5, TEST_LOCATION );
END_TEST;
}
Shader shader = Shader::New("VertexSource", "FragmentSource");
Geometry geometry = CreateQuadGeometry();
-
- Actor actor0 = Actor::New();
- actor0.SetAnchorPoint(AnchorPoint::CENTER);
- actor0.SetParentOrigin(AnchorPoint::CENTER);
- Image image0 = BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet0 = CreateTextureSet( image0 );
- Renderer renderer0 = Renderer::New( geometry, shader );
- renderer0.SetTextures( textureSet0 );
- actor0.AddRenderer(renderer0);
- actor0.SetPosition(0.0f,0.0f);
- actor0.SetSize(100, 100);
- Stage::GetCurrent().Add(actor0);
- actor0.SetDrawMode( DrawMode::OVERLAY_2D );
- application.SendNotification();
- application.Render(0);
-
- Actor actor1 = Actor::New();
- actor1.SetAnchorPoint(AnchorPoint::CENTER);
- actor1.SetParentOrigin(AnchorPoint::CENTER);
- Image image1= BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet1 = CreateTextureSet( image1 );
- Renderer renderer1 = Renderer::New( geometry, shader );
- renderer1.SetTextures( textureSet1 );
- actor1.SetPosition(0.0f,0.0f);
- actor1.AddRenderer(renderer1);
- actor1.SetSize(100, 100);
- Stage::GetCurrent().Add(actor1);
- actor1.SetDrawMode( DrawMode::OVERLAY_2D );
- application.SendNotification();
- application.Render(0);
-
- Actor actor2 = Actor::New();
- actor2.SetAnchorPoint(AnchorPoint::CENTER);
- actor2.SetParentOrigin(AnchorPoint::CENTER);
- Image image2= BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet2 = CreateTextureSet( image2 );
- Renderer renderer2 = Renderer::New( geometry, shader );
- renderer2.SetTextures( textureSet2 );
- actor2.AddRenderer(renderer2);
- actor2.SetPosition(0.0f,0.0f);
- actor2.SetSize(100, 100);
- Stage::GetCurrent().Add(actor2);
- application.SendNotification();
- application.Render(0);
-
- Actor actor3 = Actor::New();
- actor3.SetAnchorPoint(AnchorPoint::CENTER);
- actor3.SetParentOrigin(AnchorPoint::CENTER);
- Image image3 = BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet3 = CreateTextureSet( image3 );
- Renderer renderer3 = Renderer::New( geometry, shader );
- renderer3.SetTextures( textureSet3 );
- actor3.SetPosition(0.0f,0.0f);
- actor3.AddRenderer(renderer3);
- actor3.SetSize(100, 100);
- Stage::GetCurrent().Add(actor3);
- actor3.SetDrawMode( DrawMode::OVERLAY_2D );
- application.SendNotification();
- application.Render(0);
-
- Actor actor4 = Actor::New();
- actor4.SetAnchorPoint(AnchorPoint::CENTER);
- actor4.SetParentOrigin(AnchorPoint::CENTER);
- Image image4 = BufferImage::New( 64, 64, Pixel::RGB888 );
- TextureSet textureSet4 = CreateTextureSet( image4 );
- Renderer renderer4 = Renderer::New( geometry, shader );
- renderer4.SetTextures( textureSet4 );
- actor4.AddRenderer(renderer4);
- actor4.SetPosition(0.0f,0.0f);
- actor4.SetSize(100, 100);
- Stage::GetCurrent().Add(actor4);
- application.SendNotification();
- application.Render(0);
+ Actor root = Stage::GetCurrent().GetRootLayer();
/*
* Create the following hierarchy:
*
* Expected rendering order : actor2 - actor4 - actor1 - actor0 - actor3
*/
- Stage::GetCurrent().Add( actor2 );
+
+ Actor actor0 = CreateActor( root, 0, TEST_LOCATION );
+ actor0.SetDrawMode( DrawMode::OVERLAY_2D );
+ Renderer renderer0 = CreateRenderer( actor0, geometry, shader, 0 );
+
+ Actor actor1 = CreateActor( root, 0, TEST_LOCATION );
+ actor1.SetDrawMode( DrawMode::OVERLAY_2D );
+ Renderer renderer1 = CreateRenderer( actor1, geometry, shader, 0 );
+
+ Actor actor2 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer2 = CreateRenderer( actor2, geometry, shader, 0 );
+
+ Actor actor3 = CreateActor( root, 0, TEST_LOCATION );
+ actor3.SetDrawMode( DrawMode::OVERLAY_2D );
+ Renderer renderer3 = CreateRenderer( actor3, geometry, shader, 0 );
+
+ Actor actor4 = CreateActor( root, 0, TEST_LOCATION );
+ Renderer renderer4 = CreateRenderer( actor4, geometry, shader, 0 );
+
+ application.SendNotification();
+ application.Render(0);
+
actor2.Add(actor1);
actor2.Add(actor4);
actor1.Add(actor0);
actor0.Add(actor3);
- application.SendNotification();
- application.Render(0);
TestGlAbstraction& gl = application.GetGlAbstraction();
gl.EnableTextureCallTrace(true);
#include <cstdlib>
#include <sstream>
#include <iomanip>
+#include <ctime>
// INTERNAL INCLUDES
#include <dali/public-api/common/constants.h>
namespace // unnamed namespace
{
+const uint64_t NANOSECONDS_PER_SECOND = 1e+9;
+
/**
* Generic function to print out any 2-Dimensional array
* @param[in] data pointer to the source data stored as float[rows][cols]
return Array2DToString(m.AsFloat(), 4, 4, precision, indent);
}
+void GetNanoseconds( uint64_t& timeInNanoseconds )
+{
+ timespec timeSpec;
+ clock_gettime( CLOCK_MONOTONIC, &timeSpec );
+
+ // Convert all values to uint64_t to match our return type
+ timeInNanoseconds = ( static_cast< uint64_t >( timeSpec.tv_sec ) * NANOSECONDS_PER_SECOND ) + static_cast< uint64_t >( timeSpec.tv_nsec );
+}
+
} // namespace Log
} // namespace Integration
#include <string>
#include <sstream>
#include <list>
+#include <stdint.h>
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
#endif
-}}} // Dali/Integration/Debug namespaces
+/********************************************************************************
+ * Time instrumentation *
+ ********************************************************************************/
+
+#if defined(DEBUG_ENABLED)
+
+void GetNanoseconds( uint64_t& timeInNanoseconds );
+
+#define DALI_LOG_TIMER_START( timeVariable ) \
+ uint64_t timeVariable##1; \
+ Debug::GetNanoseconds( timeVariable##1 );
+
+#define DALI_LOG_TIMER_END( timeVariable, filter, level, preString) \
+ uint64_t timeVariable##2; \
+ Debug::GetNanoseconds( timeVariable##2 ); \
+ DALI_LOG_INFO( filter, level, preString " %ld uSec\n", ((timeVariable##2-timeVariable##1)/1000));
+
+#else // DEBUG_ENABLED
+
+#define DALI_LOG_TIMER_START( timeVariable )
+#define DALI_LOG_TIMER_END( timeVariable, filter, level, preString)
+
+#endif
+
+} // Debug
+} // Integration
+} // Dali
#endif // __DALI_INTEGRATION_DEBUG_H__
// Run the size negotiation after event processing finished signal
mRelayoutController->Relayout();
+ // Rebuild depth tree after event processing has finished
+ mStage->RebuildDepthTree();
+
// Flush any queued messages for the update-thread
const bool messagesToProcess = mUpdateManager->FlushQueue();
#include <dali/public-api/math/radian.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/object/weak-handle.h>
#include <dali/devel-api/scripting/scripting.h>
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/event/common/event-thread-services.h>
using Dali::Internal::SceneGraph::AnimatableProperty;
using Dali::Internal::SceneGraph::PropertyBase;
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
+Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
+#endif
+
namespace Dali
{
return GetDimensionValue( values.GetVectorXY(), dimension );
}
-unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder )
-{
- return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
-}
-
/**
* @brief Recursively emits the visibility-changed-signal on the actor tree.
* @param[in] actor The actor to emit the signal on
unsigned int Actor::GetSortingDepth()
{
- return GetDepthIndex( mDepth, mSiblingOrder );
+ return mSortedDepth;
}
const Vector4& Actor::GetCurrentWorldColor() const
mTargetScale( Vector3::ONE ),
mName(),
mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
+ mSortedDepth( 0u ),
mDepth( 0u ),
mSiblingOrder(0u),
mIsRoot( ROOT_LAYER == derivedType ),
// It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
ActorContainer connectionList;
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
+
// This stage is atomic i.e. not interrupted by user callbacks.
RecursiveConnectToStage( connectionList, parentDepth + 1 );
mIsOnStage = true;
mDepth = depth;
- SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
ConnectToSceneGraph();
// It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
ActorContainer disconnectionList;
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
+
// This stage is atomic i.e. not interrupted by user callbacks
RecursiveDisconnectFromStage( disconnectionList );
return connected;
}
+// This method generates the depth tree using the recursive function below,
+// then walks the tree and sets a depth index based on traversal order. It
+// sends a single message to update manager to update all the actor's nodes in this
+// tree with the depth index. The sceneGraphNodeDepths vector's elements are ordered
+// by depth, and could be used to reduce sorting in the update thread.
+void Actor::RebuildDepthTree()
+{
+ DALI_LOG_TIMER_START(depthTimer);
+
+ DepthNodeMemoryPool nodeMemoryPool;
+ ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( this, mSiblingOrder );
+
+ int actorCount = BuildDepthTree( nodeMemoryPool, rootNode );
+
+ // Vector of scene-graph nodes and their depths to send to UpdateManager
+ // in a single message
+ SceneGraph::NodeDepths* sceneGraphNodeDepths = new SceneGraph::NodeDepths(actorCount);
+
+ // Traverse depth tree and set mSortedDepth on each actor and scenegraph node
+ uint32_t sortOrder = 1u; // Don't start at zero, as visual depth can be negative
+ ActorDepthTreeNode* currentNode = rootNode;
+ bool firstVisit = true;
+ while( currentNode != rootNode || firstVisit)
+ {
+ firstVisit = false;
+
+ // Visit node, performing action
+ for( std::vector<Actor*>::iterator iter = currentNode->mActors.begin(); iter != currentNode->mActors.end(); ++iter )
+ {
+ (*iter)->mSortedDepth = sortOrder * DevelLayer::SIBLING_ORDER_MULTIPLIER;
+ sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>((*iter)->mNode), (*iter)->mSortedDepth );
+ }
+ ++sortOrder;
+
+ // Descend tree
+ if( currentNode->mFirstChildNode )
+ {
+ currentNode = currentNode->mFirstChildNode;
+ }
+ else // leaf node, goto next sibling, or return up tree.
+ {
+ bool breakout=false;
+ while( ! currentNode->mNextSiblingNode )
+ {
+ if( currentNode == rootNode ) // If we get to root of tree, stop
+ {
+ breakout = true;
+ break;
+ }
+ currentNode = currentNode->mParentNode;
+ }
+
+ if( breakout )
+ {
+ break;
+ }
+ currentNode = currentNode->mNextSiblingNode;
+ }
+ }
+
+ SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
+ DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree create time: ");
+}
+
+/**
+ * Structure to store the actor's associated node in the depth tree for child
+ * traversal
+ */
+struct ActorNodePair
+{
+ Actor* actor;
+ ActorDepthTreeNode* node;
+ ActorNodePair( Actor* actor, ActorDepthTreeNode* node )
+ : actor(actor),
+ node(node)
+ {
+ }
+};
+
+/*
+ * Descend actor tree, building a depth tree based on actor's sibling order.
+ * Actors with the same sibling order share the same depth tree. Siblings
+ * in the depth tree are ordered by actor's sibling order.
+ *
+ * An actor tree like this:
+ *
+ * Root (SO:0)
+ * _/ | \_
+ * _/ | \_
+ * _/ | \_
+ * / | \
+ * A(SO:1) B(SO:2) C(SO:1)
+ * _/\_ | _/ \_
+ * / \ | / \
+ * D(SO:0) E(SO:0) F(SO:0) G(SO:1) H(SO:0)
+ *
+ * will end up as a depth tree like this:
+ *
+ * RootNode [ Root ] -> NULL
+ * |(mFC)
+ * V (mNS)
+ * Node [ A, C ] ------------------------> Node [ B ] -> NULL
+ * | |
+ * V V
+ * Node [ D, E, H ] -> Node [ G ] -> NULL Node [ F ] -> NULL
+ * | | |
+ * V V V
+ * NULL NULL NULL
+ *
+ * (All nodes also point to their parents to enable storage free traversal)
+ */
+int Actor::BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* node )
+{
+ int treeCount=1; // Count self and children
+
+ // Create/add to children of this node
+ if( mChildren )
+ {
+ std::vector<ActorNodePair> storedChildren;
+ storedChildren.reserve( mChildren->size() );
+
+ for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
+ {
+ Actor* childActor = (*it).Get();
+ if( childActor->IsLayer() )
+ {
+ Layer* layer = static_cast<Layer*>(childActor);
+ if( layer->GetBehavior() == Dali::Layer::LAYER_3D )
+ {
+ // Ignore this actor and children.
+ continue;
+ }
+ }
+
+ // If no existing depth node children
+ if( node->mFirstChildNode == NULL )
+ {
+ node->mFirstChildNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
+ node->mFirstChildNode->mParentNode = node;
+ storedChildren.push_back(ActorNodePair( childActor, node->mFirstChildNode ));
+ }
+ else // find child node with matching sibling order (insertion sort)
+ {
+ bool addedChildActor = false;
+
+ // depth tree child nodes ordered by sibling order
+ ActorDepthTreeNode* lastNode = NULL;
+ for( ActorDepthTreeNode* childNode = node->mFirstChildNode; childNode != NULL; childNode = childNode->mNextSiblingNode )
+ {
+ uint16_t actorSiblingOrder = childActor->mSiblingOrder;
+ uint16_t currentSiblingOrder = childNode->GetSiblingOrder();
+
+ if( actorSiblingOrder == currentSiblingOrder )
+ {
+ // Don't need a new depth node, add to existing node
+ childNode->AddActor( childActor );
+ storedChildren.push_back(ActorNodePair( childActor, childNode ));
+ addedChildActor = true;
+ break;
+ }
+ else if( actorSiblingOrder < currentSiblingOrder )
+ {
+ break;
+ }
+ lastNode = childNode;
+ }
+
+ // No matching sibling order - create new node and insert into sibling list
+ if( !addedChildActor )
+ {
+ ActorDepthTreeNode* newNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
+
+ newNode->mParentNode = node;
+ storedChildren.push_back(ActorNodePair( childActor, newNode ));
+
+ if( lastNode == NULL ) // Insert at start of siblings
+ {
+ ActorDepthTreeNode* nextNode = node->mFirstChildNode;
+ node->mFirstChildNode = newNode;
+ newNode->mNextSiblingNode = nextNode;
+ }
+ else // insert into siblings after last node
+ {
+ newNode->mNextSiblingNode = lastNode->mNextSiblingNode;
+ lastNode->mNextSiblingNode = newNode;
+ }
+ }
+ }
+ }
+
+ // Order of descent doesn't matter; we're using insertion to sort.
+ for( std::vector<ActorNodePair>::iterator iter = storedChildren.begin(); iter != storedChildren.end(); ++iter )
+ {
+ treeCount += iter->actor->BuildDepthTree( nodeMemoryPool, iter->node );
+ }
+ }
+ return treeCount;
+}
+
unsigned int Actor::GetDefaultPropertyCount() const
{
return DEFAULT_PROPERTY_COUNT;
// relayout container afterwards, the dirty flags would still be clear...
// causing a relayout to be skipped. Here we force any actors added to the
// container to be relayed out.
+ DALI_LOG_TIMER_START( NegSizeTimer1 );
+
if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
{
SetLayoutNegotiated(false, Dimension::WIDTH);
container.Add( Dali::Actor( child.Get() ), newBounds );
}
}
+ DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
}
void Actor::RelayoutRequest( Dimension::Type dimension )
void Actor::SetSiblingOrder( unsigned int order )
{
mSiblingOrder = std::min( order, static_cast<unsigned int>( DevelLayer::SIBLING_ORDER_MULTIPLIER ) );
+
if( mIsOnStage )
{
- SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
+ StagePtr stage = Stage::GetCurrent();
+ if( stage )
+ {
+ stage->RequestRebuildDepthTree();
+ }
}
}
#include <dali/public-api/math/viewport.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/event/actors/actor-declarations.h>
#include <dali/internal/event/common/object-impl.h>
#include <dali/internal/event/common/stage-def.h>
typedef std::vector< RendererPtr > RendererContainer;
typedef RendererContainer::iterator RendererIter;
+class ActorDepthTreeNode;
+typedef Dali::Internal::MemoryPoolObjectAllocator< ActorDepthTreeNode > DepthNodeMemoryPool;
+
/**
* Actor is the primary object which Dali applications interact with.
* UI controls can be built by combining multiple actors.
}
/**
- * Get the actor's sorting depth (The hierarchy depth combined with
- * the sibling order)
+ * Get the actor's sorting depth
*
* @return The depth used for hit-testing and renderer sorting
*/
bool IsNodeConnected() const;
public:
+ /**
+ * Trigger a rebuild of the actor depth tree from this root
+ * If a Layer3D is encountered, then this doesn't descend any further.
+ * The mSortedDepth of each actor is set appropriately.
+ */
+ void RebuildDepthTree();
+
+protected:
+
+ /**
+ * Traverse the actor tree, inserting actors into the depth tree in sibling order.
+ * For all actors that share a sibling order, they also share a depth tree, for
+ * optimal render performance.
+ * @param[in] nodeMemoryPool The memory pool used to allocate depth nodes
+ * @param[in,out] depthTreeNode The depth tree node to which to add this actor's children
+ * @return The count of actors in this depth tree
+ */
+ int BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* depthTreeNode );
+
+public:
// Default property extensions from Object
std::string mName; ///< Name of the actor
unsigned int mId; ///< A unique ID to identify the actor starting from 1, and 0 is reserved
+ uint32_t mSortedDepth; ///< The sorted depth index. A combination of tree traversal and sibling order.
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
static unsigned int mActorCounter; ///< A counter to track the actor instance creation
};
+/**
+ * Helper class to create sorted depth index
+ */
+class ActorDepthTreeNode
+{
+public:
+ ActorDepthTreeNode()
+ : mParentNode(NULL),
+ mNextSiblingNode(NULL),
+ mFirstChildNode(NULL),
+ mSiblingOrder( 0 )
+ {
+ }
+
+ ActorDepthTreeNode( Actor* actor, uint16_t siblingOrder )
+ : mParentNode(NULL),
+ mNextSiblingNode(NULL),
+ mFirstChildNode(NULL),
+ mSiblingOrder( siblingOrder )
+ {
+ mActors.push_back( actor );
+ }
+
+ ~ActorDepthTreeNode()
+ {
+ if( mFirstChildNode )
+ {
+ delete mFirstChildNode;
+ mFirstChildNode = NULL;
+ }
+ if( mNextSiblingNode )
+ {
+ delete mNextSiblingNode;
+ mNextSiblingNode = NULL;
+ }
+ mParentNode = NULL;
+ }
+
+ uint16_t GetSiblingOrder()
+ {
+ return mSiblingOrder;
+ }
+
+ void AddActor( Actor* actor )
+ {
+ mActors.push_back( actor );
+ }
+
+public:
+ std::vector<Actor*> mActors; // Array of actors with the same sibling order and same ancestor sibling orders
+ ActorDepthTreeNode* mParentNode;
+ ActorDepthTreeNode* mNextSiblingNode;
+ ActorDepthTreeNode* mFirstChildNode;
+ uint16_t mSiblingOrder;
+
+private:
+ ActorDepthTreeNode( ActorDepthTreeNode& );
+ ActorDepthTreeNode& operator=(const ActorDepthTreeNode& );
+};
+
+
} // namespace Internal
// Helpers for public-api forwarding methods
using Dali::Internal::SceneGraph::Node;
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
+#endif
+}
+
namespace Dali
{
mContextRegainedSignal.Emit();
}
+
+void Stage::RequestRebuildDepthTree()
+{
+ DALI_LOG_INFO(gLogFilter, Debug::General, "RequestRebuildDepthTree()\n");
+ mDepthTreeDirty = true;
+}
+
+void Stage::RebuildDepthTree()
+{
+ // If the depth tree needs rebuilding, do it in this frame only.
+ if( mDepthTreeDirty )
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::Concise, "RebuildDepthTree() dirty:T\n");
+
+ ActorPtr actor( mRootLayer.Get() );
+ actor->RebuildDepthTree();
+ mDepthTreeDirty = false;
+ }
+}
+
+
Stage::Stage( AnimationPlaylist& playlist,
PropertyNotificationManager& propertyNotificationManager,
SceneGraph::UpdateManager& updateManager,
*/
virtual BufferIndex GetEventBufferIndex() const;
+ /**
+ * Request that the depth tree is rebuilt
+ */
+ void RequestRebuildDepthTree();
+
+ /**
+ * Rebuilds the depth tree at the end of the event frame if
+ * it was requested this frame.
+ */
+ void RebuildDepthTree();
+
private:
/**
// The touched signals
Dali::Stage::TouchedSignalType mTouchedSignal;
Dali::Stage::TouchSignalType mTouchSignal;
+ bool mDepthTreeDirty; ///< True if the depth tree needs recalculating
// The wheel event signal
Dali::Stage::WheelEventSignalType mWheelEventSignal;
}
}
+void UpdateManager::SetDepthIndices( NodeDepths* nodeDepths )
+{
+ if( nodeDepths )
+ {
+ // note,this vector is already in depth order. It could be used as-is to
+ // remove sorting in update algorithm. However, it lacks layer boundary markers.
+ for( std::vector<NodeDepthPair>::iterator iter = nodeDepths->nodeDepths.begin(),
+ end = nodeDepths->nodeDepths.end() ;
+ iter != end ; ++iter )
+ {
+ iter->node->SetDepthIndex( iter->sortedDepth );
+ }
+ }
+}
+
void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
{
mImpl->shaderSaver = &upstream;
class PropertyBuffer;
class TextureSet;
+struct NodeDepthPair
+{
+ SceneGraph::Node* node;
+ uint32_t sortedDepth;
+ NodeDepthPair( SceneGraph::Node* node, uint32_t sortedDepth )
+ : node(node),
+ sortedDepth(sortedDepth)
+ {
+ }
+};
+
+struct NodeDepths
+{
+ std::vector<NodeDepthPair> nodeDepths;
+ NodeDepths( int reserveSize )
+ {
+ nodeDepths.reserve(reserveSize);
+ }
+
+ void Add( SceneGraph::Node* node, uint32_t sortedDepth )
+ {
+ nodeDepths.push_back( NodeDepthPair( node, sortedDepth ) );
+ }
+};
+
+
/**
* UpdateManager maintains a scene graph i.e. a tree of nodes as well as
* other scene graph property owning objects.
*/
void SetLayerDepths( const std::vector< Layer* >& layers, bool systemLevel );
+ /**
+ * Set the depth indices of all nodes (in LayerUI's)
+ * @param[in] nodeDepths A vector of nodes and associated depth indices
+ */
+ void SetDepthIndices( NodeDepths* nodeDepths );
+
private:
// Undefined
new (slot) LocalType( &manager, &UpdateManager::AttachColorTextureToFrameBuffer, &frameBuffer, texture, mipmapLevel, layer );
}
+inline void SetDepthIndicesMessage( UpdateManager& manager, NodeDepths* nodeDepths )
+{
+ typedef MessageValue1< UpdateManager, OwnerPointer< NodeDepths > > LocalType;
+
+ // Reserve some memory inside the message queue
+ unsigned int* slot = manager.ReserveMessageSlot( sizeof( LocalType ) );
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new (slot) LocalType( &manager, &UpdateManager::SetDepthIndices, nodeDepths );
+}
+
} // namespace SceneGraph