+int UtcDaliActorPropertyClippingActorDrawOrder(void)
+{
+ // This test checks that a hierarchy of actors are drawn in the correct order when clipping is enabled.
+ tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_CHILDREN draw order" );
+ TestApplication application;
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ /* We create a small tree of actors as follows:
+
+ A
+ / \
+ Clipping enabled -> B D
+ | |
+ C E
+
+ The correct draw order is "ABCDE" (the same as if clipping was not enabled).
+ */
+ Actor actors[5];
+ for( int i = 0; i < 5; ++i )
+ {
+ BufferImage image = BufferImage::New( 16u, 16u );
+ Actor actor = CreateRenderableActor( image );
+
+ // Setup dimensions and position so actor is not skipped by culling.
+ actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+ actor.SetSize( 16.0f, 16.0f );
+
+ if( i == 0 )
+ {
+ actor.SetParentOrigin( ParentOrigin::CENTER );
+ }
+ else
+ {
+ float b = i > 2 ? 1.0f : -1.0f;
+ actor.SetParentOrigin( Vector3( 0.5 + ( 0.2f * b ), 0.8f, 0.8f ) );
+ }
+
+ actors[i] = actor;
+ }
+
+ // Enable clipping on the actor at the top of the left branch.
+ actors[1].SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+ // Build the scene graph.
+ Stage::GetCurrent().Add( actors[0] );
+
+ // Left branch:
+ actors[0].Add( actors[1] );
+ actors[1].Add( actors[2] );
+
+ // Right branch:
+ actors[0].Add( actors[3] );
+ actors[3].Add( actors[4] );
+
+ // Gather the call trace.
+ enabledDisableTrace.Reset();
+ enabledDisableTrace.Enable( true );
+ application.SendNotification();
+ application.Render();
+ enabledDisableTrace.Enable( false );
+
+ /* Check stencil is enabled and disabled again (as right-hand branch of tree is drawn).
+
+ Note: Correct enable call trace: StackTrace: Index:0, Function:Enable, ParamList:3042 StackTrace: Index:1, Function:Enable, ParamList:2960 StackTrace: Index:2, Function:Disable, ParamList:2960
+ Incorrect enable call trace: StackTrace: Index:0, Function:Enable, ParamList:3042 StackTrace: Index:1, Function:Enable, ParamList:2960
+ */
+ size_t startIndex = 0u;
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParamsFromStartIndex( "Enable", "3042", startIndex ) );
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParamsFromStartIndex( "Enable", "2960", startIndex ) ); // 2960 is GL_STENCIL_TEST
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParamsFromStartIndex( "Disable", "2960", startIndex ) );
+
+ // Swap the clipping actor from top of left branch to top of right branch.
+ actors[1].SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::DISABLED );
+ actors[3].SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+ // Gather the call trace.
+ enabledDisableTrace.Reset();
+ enabledDisableTrace.Enable( true );
+ application.SendNotification();
+ application.Render();
+ enabledDisableTrace.Enable( false );
+
+ // Check stencil is enabled but NOT disabled again (as right-hand branch of tree is drawn).
+ // This proves the draw order has remained the same.
+ startIndex = 0u;
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParamsFromStartIndex( "Enable", "2960", startIndex ) );
+ DALI_TEST_CHECK( !enabledDisableTrace.FindMethodAndParamsFromStartIndex( "Disable", "2960", startIndex ) );
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyScissorClippingActor(void)
+{
+ // This test checks that an actor is correctly setup for clipping.
+ tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_TO_BOUNDING_BOX actor" );
+ TestApplication application;
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ const Vector2 stageSize( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT );
+ const Vector2 imageSize( 16.0f, 16.0f );
+
+ // Create a clipping actor.
+ Actor clippingActorA = CreateActorWithContent();
+ // Note: Scissor coords are have flipped Y values compared with DALi's coordinate system.
+ // We choose BOTTOM_LEFT to give us x=0, y=0 starting coordinates for the first test.
+ clippingActorA.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
+ clippingActorA.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
+ clippingActorA.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+ Stage::GetCurrent().Add( clippingActorA );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, scissorTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check scissor test was enabled.
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+ // Check the scissor was set, and the coordinates are correct.
+ std::stringstream compareParametersString;
+ compareParametersString << "0, 0, " << imageSize.x << ", " << imageSize.y;
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with 0, 0, 16, 16
+
+ clippingActorA.SetParentOrigin( ParentOrigin::TOP_RIGHT );
+ clippingActorA.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, scissorTrace );
+
+ // Check the scissor was set, and the coordinates are correct.
+ compareParametersString.str( std::string() );
+ compareParametersString.clear();
+ compareParametersString << ( stageSize.x - imageSize.x ) << ", " << ( stageSize.y - imageSize.y ) << ", " << imageSize.x << ", " << imageSize.y;
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with 464, 784, 16, 16
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyScissorClippingActorNested01(void)
+{
+ // This test checks that an actor is correctly setup for clipping.
+ tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_TO_BOUNDING_BOX actor nested" );
+ TestApplication application;
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ const Vector2 stageSize( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT );
+ const Vector2 imageSize( 16.0f, 16.0f );
+
+ /* Create a nest of 2 scissors to test nesting (intersecting clips).
+
+ A is drawn first - with scissor clipping on
+ B is drawn second - also with scissor clipping on
+ C is the generated clipping region, the intersection ( A ∩ B )
+
+ ┏━━━━━━━┓ ┌───────┐
+ ┃ B ┃ │ B │
+ ┌───╂┄┄┄┐ ┃ ┌┄┄┄╆━━━┓ │
+ │ ┃ ┊ ┃ ━━━━━> ┊ ┃ C ┃ │
+ │ ┗━━━┿━━━┛ ┊ ┗━━━╃───┘
+ │ A │ ┊ A ┊
+ └───────┘ └┄┄┄┄┄┄┄┘
+
+ We then reposition B around each corner of A to test the 4 overlap combinations (thus testing intersecting works correctly).
+ */
+
+ // Create a clipping actor.
+ Actor clippingActorA = CreateActorWithContent();
+ // Note: Scissor coords are have flipped Y values compared with DALi's coordinate system.
+ // We choose BOTTOM_LEFT to give us x=0, y=0 starting coordinates for the first test.
+ clippingActorA.SetParentOrigin( ParentOrigin::CENTER );
+ clippingActorA.SetAnchorPoint( AnchorPoint::CENTER );
+ clippingActorA.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+ Stage::GetCurrent().Add( clippingActorA );
+
+ // Create a child clipping actor.
+ Actor clippingActorB = CreateActorWithContent();
+ clippingActorB.SetParentOrigin( ParentOrigin::CENTER );
+ clippingActorB.SetAnchorPoint( AnchorPoint::CENTER );
+ clippingActorB.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+ clippingActorA.Add( clippingActorB );
+
+ // positionModifiers is an array of positions to position B around.
+ // expect is an array of expected scissor clip coordinate results.
+ const Vector2 positionModifiers[4] = { Vector2( 1.0f, 1.0f ), Vector2( -1.0f, 1.0f ), Vector2( -1.0f, -1.0f ), Vector2( 1.0f, -1.0f ) };
+ const Vector4 expect[4] = { Vector4( 240, 392, 8, 8 ), Vector4( 232, 392, 8, 8 ), Vector4( 232, 400, 8, 8 ), Vector4( 240, 400, 8, 8 ) };
+
+ // Loop through each overlap combination.
+ for( unsigned int test = 0u; test < 4u; ++test )
+ {
+ // Position the child clipping actor so it intersects with the 1st clipping actor. This changes each loop.
+ const Vector2 position = ( imageSize / 2.0f ) * positionModifiers[test];
+ clippingActorB.SetPosition( position.x, position.y );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, scissorTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check scissor test was enabled.
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+ // Check the scissor was set, and the coordinates are correct.
+ const Vector4& expectResults( expect[test] );
+ std::stringstream compareParametersString;
+ compareParametersString << expectResults.x << ", " << expectResults.y << ", " << expectResults.z << ", " << expectResults.w;
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with the expected result
+ }
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyScissorClippingActorNested02(void)
+{
+ // This test checks that an actor is correctly setup for clipping.
+ tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_TO_BOUNDING_BOX actor nested" );
+ TestApplication application;
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ /* Create a nest of 2 scissors and siblings of the parent.
+
+ stage
+ |
+ ┌─────┐─────┐
+ A C D
+ | |
+ B E
+ */
+
+ const Vector2 stageSize( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT );
+ const Vector2 sizeA{ stageSize.width, stageSize.height * 0.25f };
+ const Vector2 sizeB{ stageSize.width, stageSize.height * 0.05f };
+ const Vector2 sizeC{ stageSize.width, stageSize.height * 0.25f };
+ const Vector2 sizeD{ stageSize.width, stageSize.height * 0.25f };
+ const Vector2 sizeE{ stageSize.width, stageSize.height * 0.05f };
+
+ // Create a clipping actors.
+ Actor clippingActorA = CreateActorWithContent( sizeA.width, sizeA.height );
+ Actor clippingActorB = CreateActorWithContent( sizeB.width, sizeB.height );
+ Actor clippingActorC = CreateActorWithContent( sizeC.width, sizeC.height );
+ Actor clippingActorD = CreateActorWithContent( sizeD.width, sizeD.height );
+ Actor clippingActorE = CreateActorWithContent( sizeE.width, sizeE.height );
+
+ clippingActorA.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ clippingActorA.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ clippingActorA.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+
+ clippingActorB.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ clippingActorB.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ clippingActorB.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+
+ clippingActorC.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ clippingActorC.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ clippingActorC.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+
+ clippingActorD.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ clippingActorD.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ clippingActorD.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
+
+ clippingActorE.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ clippingActorE.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+
+ clippingActorA.SetPosition( 0.0f, -200.0f, 0.0f );
+ clippingActorB.SetPosition( 0.0f, 0.0f, 0.0f );
+ clippingActorC.SetPosition( 0.0f, 100.0f, 0.0f );
+ clippingActorD.SetPosition( 0.0f, 0.0f, 0.0f );
+ clippingActorE.SetPosition( 0.0f, 0.0f, 0.0f );
+
+ Stage::GetCurrent().Add( clippingActorA );
+ clippingActorA.Add( clippingActorB );
+ Stage::GetCurrent().Add( clippingActorC );
+ Stage::GetCurrent().Add( clippingActorD );
+ clippingActorD.Add( clippingActorE );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, scissorTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check scissor test was enabled.
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+ // Check the scissor was set, and the coordinates are correct.
+ std::string clipA( "0, 500, 480, 200" );
+ std::string clipB( "0, 580, 480, 40" );
+ std::string clipC( "0, 200, 480, 200" );
+ std::string clipD( "0, 300, 480, 200" );
+
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", clipA ) );
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", clipB ) );
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", clipC ) );
+ DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", clipD ) );
+ DALI_TEST_CHECK( scissorTrace.CountMethod( "Scissor" ) == 4 ); // Scissor rect should not be changed in clippingActorE case. So count should be 4.
+
+ END_TEST;
+}
+