A clipping mode property has been added to Actor.
This property controls how the actor will clip its children against it.
Property: Actor::Property::ClippingMode / "clippingMode"
Values:
DISABLED This Actor will not clip its children.
CLIP_CHILDREN This Actor will clip all children to its contents (the actor will also be visible itself).
Change-Id: Ic96ee03bd6048b06abcbd36569db455ab8129d25
return FindIndexFromMethodAndParams( method, params ) > -1;
}
+bool TraceCallStack::FindMethodAndParamsFromStartIndex( std::string method, std::string params, size_t& startIndex ) const
+{
+ for( size_t i = startIndex; i < mCallStack.size(); ++i )
+ {
+ if( ( mCallStack[i].method.compare( method ) == 0 ) && ( mCallStack[i].paramList.compare( params ) == 0 ) )
+ {
+ startIndex = i;
+ return true;
+ }
+ }
+ return false;
+}
/**
* Search for a method in the stack with the given parameter list
bool FindMethodAndParams(std::string method, const NamedParams& params) const;
/**
+ * Search for a method in the stack with the given parameter list.
+ * The search is done from a given index.
+ * This allows the order of methods and parameters to be checked.
+ * @param[in] method The name of the method
+ * @param[in] params A comma separated list of parameter values
+ * @param[in/out] startIndex The method index to start looking from.
+ * This is updated if a method is found so subsequent
+ * calls can search for methods occuring after this one.
+ * @return True if the method was in the stack
+ */
+ bool FindMethodAndParamsFromStartIndex( std::string method, std::string params, size_t& startIndex ) const;
+
+ /**
* Search for a method in the stack with the given parameter list
* @param[in] method The name of the method
* @param[in] params A comma separated list of parameter values
DALI_TEST_CHECK( DrawMode::OVERLAY_2D == a.GetDrawMode() ); // Check Actor is overlay
- a.SetDrawMode( DrawMode::STENCIL );
- app.SendNotification();
- app.Render(1);
-
- DALI_TEST_CHECK( DrawMode::STENCIL == a.GetDrawMode() ); // Check Actor is stencil, not overlay
-
a.SetDrawMode( DrawMode::NORMAL );
app.SendNotification();
app.Render(1);
- DALI_TEST_CHECK( DrawMode::NORMAL == a.GetDrawMode() ); // Check Actor is not stencil
+ DALI_TEST_CHECK( DrawMode::NORMAL == a.GetDrawMode() ); // Check Actor is normal
END_TEST;
}
{ "padding", Actor::Property::PADDING, Property::VECTOR4 },
{ "minimumSize", Actor::Property::MINIMUM_SIZE, Property::VECTOR2 },
{ "maximumSize", Actor::Property::MAXIMUM_SIZE, Property::VECTOR2 },
+ { "inheritPosition", Actor::Property::INHERIT_POSITION, Property::BOOLEAN },
+ { "batchParent", Actor::Property::BATCH_PARENT, Property::BOOLEAN },
+ { "clippingMode", Actor::Property::CLIPPING_MODE, Property::STRING },
};
const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] );
} // unnamed namespace
END_TEST;
}
+
+// Clipping test helper functions:
+Actor CreateActorWithContent()
+{
+ 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 );
+ actor.SetParentOrigin( ParentOrigin::CENTER );
+ actor.SetAnchorPoint( AnchorPoint::CENTER );
+
+ return actor;
+}
+
+void GenerateTrace( TestApplication& application, TraceCallStack& enabledDisableTrace, TraceCallStack& stencilTrace )
+{
+ enabledDisableTrace.Reset();
+ stencilTrace.Reset();
+ enabledDisableTrace.Enable( true );
+ stencilTrace.Enable( true );
+
+ application.SendNotification();
+ application.Render();
+
+ enabledDisableTrace.Enable( false );
+ stencilTrace.Enable( false );
+}
+
+void CheckColorMask( TestGlAbstraction& glAbstraction, bool maskValue )
+{
+ const TestGlAbstraction::ColorMaskParams& colorMaskParams = glAbstraction.GetColorMaskParams();
+
+ DALI_TEST_EQUALS<bool>( colorMaskParams.red, maskValue, TEST_LOCATION );
+ DALI_TEST_EQUALS<bool>( colorMaskParams.green, maskValue, TEST_LOCATION );
+ DALI_TEST_EQUALS<bool>( colorMaskParams.blue, maskValue, TEST_LOCATION );
+ DALI_TEST_EQUALS<bool>( colorMaskParams.alpha, maskValue, TEST_LOCATION );
+}
+
+int UtcDaliActorPropertyClippingP(void)
+{
+ // This test checks the clippingMode property.
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE P" );
+ TestApplication application;
+
+ Actor actor = Actor::New();
+
+ // Check default clippingEnabled value.
+ Property::Value getValue( actor.GetProperty( Actor::Property::CLIPPING_MODE ) );
+
+ int value = 0;
+ bool getValueResult = getValue.Get( value );
+ DALI_TEST_CHECK( getValueResult );
+
+ if( getValueResult )
+ {
+ DALI_TEST_EQUALS<int>( value, ClippingMode::DISABLED, TEST_LOCATION );
+ }
+
+ // Check setting the property.
+ actor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+
+ // Check the new value was set.
+ getValue = actor.GetProperty( Actor::Property::CLIPPING_MODE );
+ getValueResult = getValue.Get( value );
+ DALI_TEST_CHECK( getValueResult );
+
+ if( getValueResult )
+ {
+ DALI_TEST_EQUALS<int>( value, ClippingMode::CLIP_CHILDREN, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyClippingN(void)
+{
+ // Negative test case for Clipping.
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE N" );
+ TestApplication application;
+
+ Actor actor = Actor::New();
+
+ // Check default clippingEnabled value.
+ Property::Value getValue( actor.GetProperty( Actor::Property::CLIPPING_MODE ) );
+
+ int value = 0;
+ bool getValueResult = getValue.Get( value );
+ DALI_TEST_CHECK( getValueResult );
+
+ if( getValueResult )
+ {
+ DALI_TEST_EQUALS<int>( value, ClippingMode::DISABLED, TEST_LOCATION );
+ }
+
+ // Check setting an invalid property value won't change the current property value.
+ actor.SetProperty( Actor::Property::CLIPPING_MODE, "INVALID_PROPERTY" );
+
+ getValue = actor.GetProperty( Actor::Property::CLIPPING_MODE );
+ getValueResult = getValue.Get( value );
+ DALI_TEST_CHECK( getValueResult );
+
+ if( getValueResult )
+ {
+ DALI_TEST_EQUALS<int>( value, ClippingMode::DISABLED, TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyClippingActor(void)
+{
+ // This test checks that an actor is correctly setup for clipping.
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor" );
+ TestApplication application;
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+ size_t startIndex = 0u;
+
+ // Create a clipping actor.
+ Actor actorDepth1Clip = CreateActorWithContent();
+ actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ Stage::GetCurrent().Add( actorDepth1Clip );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, stencilTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check the stencil buffer was enabled.
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST
+
+ // Check the stencil buffer was cleared.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "ClearStencil", "0", startIndex ) );
+
+ // Check the correct setup was done to write to the first bit-plane (only) of the stencil buffer.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 0", startIndex ) ); // 514 is GL_EQUAL, But testing no bit-planes for the first clipping node.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "1", startIndex ) );
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyClippingNestedChildren(void)
+{
+ // This test checks that a hierarchy of actors are clipped correctly by
+ // writing to and reading from the correct bit-planes of the stencil buffer.
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE nested children" );
+ TestApplication application;
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ // Create a clipping actor.
+ Actor actorDepth1Clip = CreateActorWithContent();
+ actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ Stage::GetCurrent().Add( actorDepth1Clip );
+
+ // Create a child actor.
+ Actor childDepth2 = CreateActorWithContent();
+ actorDepth1Clip.Add( childDepth2 );
+
+ // Create another clipping actor.
+ Actor childDepth2Clip = CreateActorWithContent();
+ childDepth2Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ childDepth2.Add( childDepth2Clip );
+
+ // Create another 2 child actors. We do this so 2 nodes will have the same clipping ID.
+ // This tests the sort algorithm.
+ Actor childDepth3 = CreateActorWithContent();
+ childDepth2Clip.Add( childDepth3 );
+ Actor childDepth4 = CreateActorWithContent();
+ childDepth3.Add( childDepth4 );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, stencilTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check the stencil buffer was enabled.
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST
+
+ // Perform the test twice, once for 2D layer, and once for 3D.
+ for( unsigned int i = 0u ; i < 2u; ++i )
+ {
+ size_t startIndex = 0u;
+
+ // Check the stencil buffer was cleared.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "ClearStencil", "0", startIndex ) );
+
+ // Check the correct setup was done to write to the first bit-plane (only) of the stencil buffer.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 0", startIndex ) ); // 514 is GL_EQUAL, But testing no bit-planes for the first clipping node.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "1", startIndex ) ); // Write to the first bit-plane
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE
+
+ // Check the correct setup was done to test against first bit-plane (only) of the stencil buffer.
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 255", startIndex ) ); // 514 is GL_EQUAL
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7680, 7680", startIndex ) ); // GL_KEEP, GL_KEEP, GL_KEEP
+
+ // Check we are set up to write to the second bitplane of the stencil buffer (only).
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 3, 1", startIndex ) ); // 514 is GL_EQUAL, Test both bit-planes 1 & 2
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "3", startIndex ) ); // Write to second (and previous) bit-planes
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE
+
+ // Check we are set up to test against both the first and second bit-planes of the stencil buffer.
+ // (Both must be set to pass the check).
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 3, 255", startIndex ) ); // 514 is GL_EQUAL, Test both bit-planes 1 & 2
+ DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7680, 7680", startIndex ) ); // GL_KEEP, GL_KEEP, GL_KEEP
+
+ // If we are on the first loop, set the layer to 3D and loop to perform the test again.
+ if( i == 0u )
+ {
+ Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_3D );
+ GenerateTrace( application, enabledDisableTrace, stencilTrace );
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliActorPropertyClippingActorWithRendererOverride(void)
+{
+ // This test checks that an actor with clipping will be ignored if overridden by the Renderer properties.
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor with renderer override" );
+ TestApplication application;
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ // Create a clipping actor.
+ Actor actorDepth1Clip = CreateActorWithContent();
+ actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ Stage::GetCurrent().Add( actorDepth1Clip );
+
+ // Turn the RenderMode to just "COLOR" at the Renderer level to ignore the clippingMode.
+ actorDepth1Clip.GetRendererAt( 0 ).SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR );
+
+ // Gather the call trace.
+ GenerateTrace( application, enabledDisableTrace, stencilTrace );
+
+ // Check we are writing to the color buffer.
+ CheckColorMask( glAbstraction, true );
+
+ // Check the stencil buffer was not enabled.
+ DALI_TEST_CHECK( !enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST
+
+ // Check stencil functions are not called.
+ DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilFunc" ) );
+ DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilMask" ) );
+ DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilOp" ) );
+
+ END_TEST;
+}
END_TEST;
}
-int UtcDaliHitTestAlgorithmStencil(void)
+int UtcDaliHitTestAlgorithmClippingActor(void)
{
TestApplication application;
tet_infoline("Testing Dali::HitTestAlgorithm with a stencil");
layer.SetName( "layer" );
stage.Add( layer );
- // Create a stencil and add that to the layer
- Actor stencil = CreateRenderableActor(Dali::BufferImage::WHITE() );
- stencil.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- stencil.SetParentOrigin( ParentOrigin::TOP_LEFT );
- stencil.SetSize( 50.0f, 50.0f );
- stencil.SetDrawMode( DrawMode::STENCIL );
- stencil.SetName( "stencil" );
- layer.Add( stencil );
-
- // Create a renderable actor and add that to the layer
- Actor layerHitActor = CreateRenderableActor( Dali::BufferImage::WHITE() );
- layerHitActor.SetSize( 100.0f, 100.0f );
- layerHitActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- layerHitActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- layerHitActor.SetName( "layerHitActor" );
- layer.Add( layerHitActor );
+ // Create a clipping actor and add it to the layer.
+ Actor clippingActor = CreateRenderableActor( Dali::BufferImage::WHITE() );
+ clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ clippingActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ clippingActor.SetSize( 50.0f, 50.0f );
+ clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ clippingActor.SetName( "clippingActor" );
+ layer.Add( clippingActor );
+
+ // Create a renderable actor and add it to the clipping actor.
+ Actor childActor = CreateRenderableActor( Dali::BufferImage::WHITE() );
+ childActor.SetSize( 100.0f, 100.0f );
+ childActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ childActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ childActor.SetName( "childActor" );
+ clippingActor.Add( childActor );
// Render and notify
application.SendNotification();
application.Render();
- // Hit within stencil and actor
- {
- HitTestAlgorithm::Results results;
- HitTest(stage, Vector2( 10.0f, 10.0f ), results, &DefaultIsActorTouchableFunction);
- DALI_TEST_CHECK( results.actor == layerHitActor );
- tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) );
- }
+ // Hit within clippingActor and childActor.
+ HitTestAlgorithm::Results results;
+ HitTest( stage, Vector2( 10.0f, 10.0f ), results, &DefaultIsActorTouchableFunction );
+ DALI_TEST_CHECK( results.actor == childActor );
+ tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) );
+
+ // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
+ HitTest( stage, Vector2( 60.0f, 60.0f ), results, &DefaultIsActorTouchableFunction);
+ DALI_TEST_CHECK( results.actor == rootLayer );
+ tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) );
- // Hit within actor but outside of stencil, should hit the root-layer
- {
- HitTestAlgorithm::Results results;
- HitTest(stage, Vector2( 60.0f, 60.0f ), results, &DefaultIsActorTouchableFunction);
- DALI_TEST_CHECK( results.actor == rootLayer );
- tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) );
- }
END_TEST;
}
END_TEST;
}
-
-int UtcDaliHoverStencilNonRenderableActor(void)
+int UtcDaliHoverClippingActor(void)
{
TestApplication application;
Stage stage = Stage::GetCurrent();
Actor actor = Actor::New();
- actor.SetSize(100.0f, 100.0f);
- actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stage.Add(actor);
+ actor.SetSize( 100.0f, 100.0f );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ stage.Add( actor );
- Actor stencil = Actor::New();
- stencil.SetSize(50.0f, 50.0f);
- stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stencil.SetDrawMode( DrawMode::STENCIL );
- stage.Add(stencil);
+ Actor clippingActor = Actor::New();
+ clippingActor.SetSize( 50.0f, 50.0f );
+ clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ stage.Add( clippingActor );
- // Render and notify
+ // Render and notify.
application.SendNotification();
application.Render();
- // Connect to actor's hovered signal
+ // Connect to actor's hovered signal.
SignalData data;
HoverEventFunctor functor( data );
actor.HoveredSignal().Connect( &application, functor );
- // Emit an event within stencil area
+ // Emit an event within clipped area.
application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, Vector2( 10.0f, 10.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
- // Emit an event outside the stencil area but within the actor area, we should have a hit!
+ // Emit an event outside the clipped area but within the actor area, we should have a hit.
application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, Vector2( 60.0f, 60.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
DALI_TEST_EQUALS( layer.GetBehavior(), Dali::Layer::LAYER_3D, TEST_LOCATION );
END_TEST;
}
+
+Actor CreateActor( bool withAlpha )
+{
+ Dali::BufferImage bufferImage;
+
+ if( withAlpha )
+ {
+ bufferImage = Dali::BufferImage::WHITE();
+ }
+ else
+ {
+ bufferImage = BufferImage::New( 1u, 1u, Pixel::RGB888, Dali::Image::NEVER );
+ PixelBuffer* pBuffer = bufferImage.GetBuffer();
+ if( pBuffer )
+ {
+ pBuffer[0] = pBuffer[1] = pBuffer[2] = 0xFF;
+ }
+ }
+
+ Actor actor = CreateRenderableActor( bufferImage );
+ actor.SetParentOrigin( ParentOrigin::CENTER );
+ actor.SetAnchorPoint( AnchorPoint::CENTER );
+
+ return actor;
+}
+
+int UtcDaliLayer3DSort(void)
+{
+ tet_infoline( "Testing LAYER_3D sort coverage test" );
+ TestApplication application;
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+
+ Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_3D );
+
+ // Create an actor.
+ Actor actor = CreateActor( false );
+ Stage::GetCurrent().Add( actor );
+
+ // Create child actors.
+ Actor child1 = CreateActor( true );
+ actor.Add( child1 );
+ Actor child2 = CreateActor( false );
+ child1.Add( child2 );
+
+ enabledDisableTrace.Reset();
+ enabledDisableTrace.Enable( true );
+ application.SendNotification();
+ application.Render();
+ enabledDisableTrace.Enable( false );
+
+ DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2929" ) ); // 2929 is GL_DEPTH_TEST
+
+ END_TEST;
+}
DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) );
// Test the COLOR_STENCIL RenderMode as it also enables the stencil buffer.
+ // First set a mode to turn off the stencil buffer, so the enable is required.
+ renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR );
+ ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR_STENCIL );
ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
const StringEnum DRAW_MODE_VALUES[] =
{
{ "NORMAL", DrawMode::NORMAL },
- { "OVERLAY_2D", DrawMode::OVERLAY_2D },
- { "STENCIL", DrawMode::STENCIL },
+ { "OVERLAY_2D", DrawMode::OVERLAY_2D }
};
const unsigned int DRAW_MODE_VALUES_COUNT = sizeof( DRAW_MODE_VALUES ) / sizeof( DRAW_MODE_VALUES[0] );
map[ "sensitive" ] = false;
map[ "leaveRequired" ] = true;
map[ "positionInheritance" ] = "DONT_INHERIT_POSITION";
- map[ "drawMode" ] = "STENCIL";
+ map[ "drawMode" ] = "OVERLAY_2D";
map[ "inheritOrientation" ] = false;
map[ "inheritScale" ] = false;
DALI_TEST_EQUALS( handle.IsSensitive(), false, TEST_LOCATION );
DALI_TEST_EQUALS( handle.GetLeaveRequired(), true, TEST_LOCATION );
DALI_TEST_EQUALS( handle.GetPositionInheritanceMode(), DONT_INHERIT_POSITION, TEST_LOCATION );
- DALI_TEST_EQUALS( handle.GetDrawMode(), DrawMode::STENCIL, TEST_LOCATION );
+ DALI_TEST_EQUALS( handle.GetDrawMode(), DrawMode::OVERLAY_2D, TEST_LOCATION );
DALI_TEST_EQUALS( handle.IsOrientationInherited(), false, TEST_LOCATION );
DALI_TEST_EQUALS( handle.IsScaleInherited(), false, TEST_LOCATION );
END_TEST;
}
-int UtcDaliTouchDataStencilNonRenderableActor(void)
+int UtcDaliTouchDataClippedActor(void)
{
TestApplication application;
Stage stage = Stage::GetCurrent();
Actor actor = Actor::New();
- actor.SetSize(100.0f, 100.0f);
- actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stage.Add(actor);
+ actor.SetSize( 100.0f, 100.0f );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ stage.Add( actor );
- Actor stencil = Actor::New();
- stencil.SetSize(50.0f, 50.0f);
- stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stencil.SetDrawMode( DrawMode::STENCIL );
- stage.Add(stencil);
+ Actor clippingActor = Actor::New();
+ clippingActor.SetSize( 50.0f, 50.0f );
+ clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ stage.Add( clippingActor );
- // Render and notify
+ // Render and notify.
application.SendNotification();
application.Render();
- // Connect to actor's touched signal
+ // Connect to actor's touch signal.
SignalData data;
TouchDataFunctor functor( data );
actor.TouchSignal().Connect( &application, functor );
- // Emit an event within stencil area
+ // Emit an event within clipped area.
application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 10.0f, 10.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
- // Emit an event outside the stencil area but within the actor area, we should have a hit!
+ // Emit an event outside the clipped area but within the actor area, we should have a hit.
application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 60.0f, 60.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
END_TEST;
}
-int UtcDaliTouchStencilNonRenderableActor(void)
+int UtcDaliTouchClippingActor(void)
{
TestApplication application;
Stage stage = Stage::GetCurrent();
Actor actor = Actor::New();
- actor.SetSize(100.0f, 100.0f);
- actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stage.Add(actor);
+ actor.SetSize( 100.0f, 100.0f );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ stage.Add( actor );
- Actor stencil = Actor::New();
- stencil.SetSize(50.0f, 50.0f);
- stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- stencil.SetDrawMode( DrawMode::STENCIL );
- stage.Add(stencil);
+ Actor clippingActor = Actor::New();
+ clippingActor.SetSize( 50.0f, 50.0f );
+ clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+ stage.Add( clippingActor );
- // Render and notify
+ // Render and notify.
application.SendNotification();
application.Render();
- // Connect to actor's touched signal
+ // Connect to actor's touched signal.
SignalData data;
TouchEventFunctor functor( data );
actor.TouchedSignal().Connect( &application, functor );
- // Emit an event within stencil area
+ // Emit an event within clipped area.
application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
- // Emit an event outside the stencil area but within the actor area, we should have a hit!
+ // Emit an event outside the clipped area but within the actor area, we should have a hit.
application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 60.0f, 60.0f ) ) );
DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
data.Reset();
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/internal/update/common/texture-cache-dispatcher.h>
#include <dali/internal/update/manager/update-manager.h>
#include <dali/internal/update/manager/geometry-batcher.h>
+#include <dali/internal/update/manager/render-task-processor.h>
#include <dali/internal/update/resources/resource-manager.h>
#include <dali/internal/render/common/performance-monitor.h>
mGeometryBatcher = new SceneGraph::GeometryBatcher();
+ mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
+
mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mTextureUploadedQueue );
RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
*mRenderManager,
renderQueue,
*mTextureCacheDispatcher,
- *mGeometryBatcher );
+ *mGeometryBatcher,
+ *mRenderTaskProcessor );
mRenderManager->SetShaderSaver( *mUpdateManager );
delete mTextureCacheDispatcher;
delete mUpdateManager;
delete mRenderManager;
+ delete mRenderTaskProcessor;
delete mGeometryBatcher;
delete mTextureUploadedQueue;
}
-#ifndef __DALI_INTERNAL_CORE_H__
-#define __DALI_INTERNAL_CORE_H__
+#ifndef DALI_INTERNAL_CORE_H
+#define DALI_INTERNAL_CORE_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
class DiscardQueue;
class TextureCacheDispatcher;
class GeometryBatcher;
+class RenderTaskProcessor;
}
/**
ResourceManager* mResourceManager; ///< Asynchronous Resource Loading
IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller
SceneGraph::GeometryBatcher* mGeometryBatcher; ///< Instance of the geometry batcher
+ SceneGraph::RenderTaskProcessor* mRenderTaskProcessor; ///< Handles the processing of render tasks
bool mIsActive : 1; ///< Whether Core is active or suspended
bool mProcessingEvent : 1; ///< True during ProcessEvents()
} // namespace Dali
-#endif // __DALI_INTERNAL_CORE_H__
+#endif // DALI_INTERNAL_CORE_H
#include <cfloat>
// INTERNAL INCLUDES
-
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/common/constants.h>
#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/math/vector3.h>
#include <dali/public-api/math/radian.h>
#include <dali/public-api/object/type-registry.h>
-
#include <dali/devel-api/scripting/scripting.h>
-
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/event/common/event-thread-services.h>
#include <dali/internal/event/render-tasks/render-task-impl.h>
/**
* We want to discourage the use of property strings (minimize string comparisons),
* particularly for the default properties.
- * Name Type writable animatable constraint-input enum for index-checking
+ * Name Type writable animatable constraint-input enum for index-checking
*/
DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
-DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
-DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
-DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
-DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
-DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
-DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
-DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
-DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
-DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
-DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
-DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
-DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
-DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
-DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
-DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
-DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
-DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
-DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
-DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
-DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
-DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
-DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
-DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
-DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
-DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
-DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
-DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
-DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
-DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
-DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
-DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
-DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
-DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
-DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
-DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
-DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
-DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
-DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
-DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
-DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
-DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
-DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
-DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
-DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
-DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
-DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
-DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
-DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
-DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
-DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
-DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
-DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
-DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT )
+DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
+DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
+DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
+DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
+DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
+DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
+DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
+DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
+DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
+DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
+DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
+DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
+DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
+DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
+DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
+DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
+DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
+DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
+DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
+DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
+DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
+DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
+DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
+DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
+DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
+DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
+DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
+DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
+DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
+DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
+DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
+DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
+DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
+DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
+DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
+DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
+DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
+DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
+DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
+DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
+DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
+DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
+DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
+DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
+DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
+DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
+DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
+DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
+DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
+DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
+DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
+DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
+DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION )
+DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE )
+DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT )
DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
// Signals
DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO )
DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY )
+DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
+DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
+DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
+
+
bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
{
for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i )
return 1.0f;
}
+ClippingMode::Type Actor::GetClippingMode() const
+{
+ return mClippingMode;
+}
+
const Vector4& Actor::GetCurrentWorldColor() const
{
if( NULL != mNode )
{
// this flag is not animatable so keep the value
mDrawMode = drawMode;
- if( NULL != mNode )
+ if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) )
{
// mNode is being used in a separate thread; queue a message to set the value
SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode );
return ( b2 * b2 - a * c ) >= 0.f;
}
-bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
+bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const
{
bool hit = false;
- if( OnStage() &&
- NULL != mNode )
+ if( OnStage() && NULL != mNode )
{
// Transforms the ray to the local reference system.
// Calculate the inverse of Model matrix
mDrawMode( DrawMode::NORMAL ),
mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
mColorMode( Node::DEFAULT_COLOR_MODE ),
+ mClippingMode( ClippingMode::DISABLED ),
mIsBatchParent( false )
{
}
}
break;
}
+
+ case Dali::Actor::Property::CLIPPING_MODE:
+ {
+ ClippingMode::Type convertedValue = mClippingMode;
+ if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) )
+ {
+ mClippingMode = convertedValue;
+ if( NULL != mNode )
+ {
+ SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode );
+ }
+ }
+ break;
+ }
+
default:
{
// this can happen in the case of a non-animatable default property so just do nothing
break;
}
+ case Dali::Actor::Property::CLIPPING_MODE:
+ {
+ value = mClippingMode;
+ break;
+ }
+
default:
{
DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
-#ifndef __DALI_INTERNAL_ACTOR_H__
-#define __DALI_INTERNAL_ACTOR_H__
+#ifndef DALI_INTERNAL_ACTOR_H
+#define DALI_INTERNAL_ACTOR_H
/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
float GetCurrentOpacity() const;
/**
+ * Retrieve the actor's clipping mode.
+ * @return The actor's clipping mode (cached)
+ */
+ ClippingMode::Type GetClippingMode() const;
+
+ /**
* Sets whether an actor should emit touch or hover signals; see SignalTouch() and SignalHover().
* An actor is sensitive by default, which means that as soon as an application connects to the SignalTouch(),
* the touch event signal will be emitted, and as soon as an application connects to the SignalHover(), the
*/
bool RayActorTest( const Vector4& rayOrigin,
const Vector4& rayDir,
- Vector4& hitPointLocal,
+ Vector2& hitPointLocal,
float& distance ) const;
/**
DrawMode::Type mDrawMode : 2; ///< Cached: How the actor and its children should be drawn
PositionInheritanceMode mPositionInheritanceMode : 2; ///< Cached: Determines how position is inherited
ColorMode mColorMode : 2; ///< Cached: Determines whether mWorldColor is inherited
+ ClippingMode::Type mClippingMode : 2; ///< Cached: Determines which clipping mode (if any) to use.
private:
} // namespace Dali
-#endif // __DALI_INTERNAL_ACTOR_H__
+#endif // DALI_INTERNAL_ACTOR_H
-#ifndef __DALI_INTERNAL_LAYER_H__
-#define __DALI_INTERNAL_LAYER_H__
+#ifndef DALI_INTERNAL_LAYER_H
+#define DALI_INTERNAL_LAYER_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
} // namespace Dali
-#endif //__DALI_INTERNAL_LAYER_H__
+#endif // DALI_INTERNAL_LAYER_H
// Ensure tap is within the actor's area
if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check
{
- Vector4 hitPointLocal;
+ Vector2 hitPointLocal;
float distance( 0.0f );
if( actor->RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) )
{
// One of the parents was the gestured actor so we can emit the signal for that actor.
- EmitGestureSignal( actor, gestureDetectors, Vector2( hitPointLocal.x, hitPointLocal.y ) );
+ EmitGestureSignal( actor, gestureDetectors, hitPointLocal );
break; // We have found AND emitted a signal on the gestured actor, break out.
}
}
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
{
HitActor()
: actor( NULL ),
- x( 0 ),
- y( 0 ),
distance( std::numeric_limits<float>::max() ),
depth( std::numeric_limits<int>::min() )
{
}
- Actor *actor; ///< the actor hit. (if actor hit, then initialised)
- float x; ///< x position of hit (only valid if actor valid)
- float y; ///< y position of hit (only valid if actor valid)
- float distance; ///< distance from ray origin to hit actor
- int depth; ///< depth index of this actor
-
+ Actor *actor; ///< The actor hit (if actor is hit, then this is initialised).
+ Vector2 hitPosition; ///< Position of hit (only valid if actor valid).
+ float distance; ///< Distance from ray origin to hit actor.
+ int depth; ///< Depth index of this actor.
};
/**
const Vector< RenderTaskList::Exclusive >& exclusives )
{
- if ( exclusives.Size() )
+ if( exclusives.Size() )
{
- for ( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt )
+ for( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt )
{
- if ( exclusiveIt->renderTaskPtr != &renderTask )
+ if( ( exclusiveIt->renderTaskPtr != &renderTask ) && ( exclusiveIt->actorPtr == &actor ) )
{
- if ( exclusiveIt->actorPtr == &actor )
- {
- return true;
- }
+ return true;
}
}
}
float& nearClippingPlane,
float& farClippingPlane,
HitTestInterface& hitCheck,
- bool& stencilOnLayer,
- bool& stencilHit,
bool& overlayHit,
- bool parentIsStencil,
- bool layerIs3d )
+ bool layerIs3d,
+ unsigned int clippingDepth,
+ unsigned int clippingBitPlaneMask )
{
HitActor hit;
- if ( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) )
+ if( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) )
{
return hit;
}
- // Children should inherit the stencil draw mode
- bool isStencil = parentIsStencil;
-
- if ( actor.GetDrawMode() == DrawMode::STENCIL && actor.IsVisible() )
+ // For clipping, regardless of whether we have hit this actor or not,
+ // we increase the clipping depth if we have hit a clipping actor.
+ // This is used later to ensure all nested clipped children have hit
+ // all clipping actors also for them to be counted as hit.
+ unsigned int newClippingDepth = clippingDepth;
+ bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED;
+ if( clippingActor )
{
- isStencil = true;
- stencilOnLayer = true;
+ ++newClippingDepth;
}
- // If we are a stencil or hittable...
- if ( isStencil || hitCheck.IsActorHittable( &actor ) )
+ // If we are a clipping actor or hittable...
+ if( clippingActor || hitCheck.IsActorHittable( &actor ) )
{
Vector3 size( actor.GetCurrentSize() );
- if ( size.x > 0.0f && size.y > 0.0f && // Ensure the actor has a valid size.
- actor.RaySphereTest( rayOrigin, rayDir ) ) // Perform quicker ray sphere test to see if our ray is close to the actor.
+ // Ensure the actor has a valid size.
+ // If so, perform a quick ray sphere test to see if our ray is close to the actor.
+ if( size.x > 0.0f && size.y > 0.0f && actor.RaySphereTest( rayOrigin, rayDir ) )
{
- Vector4 hitPointLocal;
+ Vector2 hitPointLocal;
float distance;
// Finally, perform a more accurate ray test to see if our ray actually hits the actor.
{
if( distance >= nearClippingPlane && distance <= farClippingPlane )
{
- // If the hit has happened on a stencil then register, but don't record as hit result
- if ( isStencil )
+ // If the hit has happened on a clipping actor, then add this clipping depth to the mask of hit clipping depths.
+ // This mask shows all the actors that have been hit at different clipping depths.
+ if( clippingActor )
{
- stencilHit = true;
+ clippingBitPlaneMask |= 1u << clippingDepth;
+ }
+
+ if( overlayHit && !actor.IsOverlay() )
+ {
+ // If we have already hit an overlay and current actor is not an overlay ignore current actor.
}
else
{
- if( overlayHit && !actor.IsOverlay() )
+ if( actor.IsOverlay() )
{
- //If we have already hit an overlay and current actor is not an overlay
- //ignore current actor
+ overlayHit = true;
}
- else
+
+ // At this point we have hit an actor.
+ // Now perform checks for clipping.
+ // Assume we have hit the actor first as if it is not clipped this would be the case.
+ bool haveHitActor = true;
+
+ // Check if we are performing clipping. IE. if any actors so far have clipping enabled - not necessarily this one.
+ // We can do this by checking the clipping depth has a value 1 or above.
+ if( newClippingDepth >= 1u )
{
- if( actor.IsOverlay() )
+ // Now for us to count this actor as hit, we must have also hit
+ // all CLIPPING actors up to this point in the hierarchy as well.
+ // This information is stored in the clippingBitPlaneMask we updated above.
+ // Here we calculate a comparison mask by setting all the bits up to the current depth value.
+ // EG. a depth of 4 (10000 binary) = a mask of 1111 binary.
+ // This allows us a fast way of comparing all bits are set up to this depth.
+ unsigned int clippingDepthMask = ( 1u << clippingDepth ) - 1u;
+
+ // The two masks must be equal to be a hit, as we are already assuming a hit
+ // (for non-clipping mode) then they must be not-equal to disqualify the hit.
+ if( clippingBitPlaneMask != clippingDepthMask )
{
- overlayHit = true;
+ haveHitActor = false;
}
+ }
+ if( haveHitActor )
+ {
hit.actor = &actor;
- hit.x = hitPointLocal.x;
- hit.y = hitPointLocal.y;
+ hit.hitPosition = hitPointLocal;
hit.distance = distance;
hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER;
- if ( actor.GetRendererCount() > 0 )
+ if( actor.GetRendererCount() > 0 )
{
//Get renderer with maximum depth
int rendererMaxDepth(actor.GetRendererAt( 0 ).Get()->GetDepthIndex());
- for( unsigned int i(1); i<actor.GetRendererCount(); ++i)
+ for( unsigned int i(1); i < actor.GetRendererCount(); ++i )
{
int depth = actor.GetRendererAt( i ).Get()->GetDepthIndex();
if( depth > rendererMaxDepth )
}
}
- // If we are a stencil (or a child of a stencil) and we have already ascertained that the stencil has been hit then there is no need to hit-test the children of this stencil-actor
- if ( isStencil && stencilHit )
- {
- return hit;
- }
-
// Find a child hit, until we run out of actors in the current layer.
HitActor childHit;
if( actor.GetChildCount() > 0 )
for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
{
// Descend tree only if...
- if ( !(*iter)->IsLayer() && // Child is NOT a layer, hit testing current layer only or Child is not a layer and we've inherited the stencil draw mode
- ( isStencil || hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We are a stencil OR we can descend into child hierarchy
+ if ( !( *iter )->IsLayer() && // Child is NOT a layer, hit testing current layer only
+ ( hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We can descend into child hierarchy
{
- HitActor currentHit( HitTestWithinLayer( (*iter->Get()),
- renderTask,
- exclusives,
- rayOrigin,
- rayDir,
- nearClippingPlane,
- farClippingPlane,
- hitCheck,
- stencilOnLayer,
- stencilHit,
- overlayHit,
- isStencil,
- layerIs3d) );
+ HitActor currentHit( HitTestWithinLayer( ( *iter->Get() ),
+ renderTask,
+ exclusives,
+ rayOrigin,
+ rayDir,
+ nearClippingPlane,
+ farClippingPlane,
+ hitCheck,
+ overlayHit,
+ layerIs3d,
+ newClippingDepth,
+ clippingBitPlaneMask ) );
bool updateChildHit = false;
- if ( currentHit.distance >= 0.0f )
+ if( currentHit.distance >= 0.0f )
{
if( layerIs3d )
{
updateChildHit = ( ( currentHit.depth > childHit.depth ) ||
- ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) );
+ ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) );
}
else
{
}
}
- if ( updateChildHit )
+ if( updateChildHit )
{
if( !parentIsRenderable || currentHit.depth > hit.depth ||
( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) )
- {
- childHit = currentHit;
- }
+ {
+ childHit = currentHit;
+ }
}
}
}
}
+
return ( childHit.actor ) ? childHit : hit;
}
{
return true;
}
- else
+
+ Actor* parent = actor.GetParent();
+ if ( parent )
{
- Actor* parent = actor.GetParent();
- if ( parent )
- {
- return IsWithinSourceActors( sourceActor, *parent );
- }
+ return IsWithinSourceActors( sourceActor, *parent );
}
// Not within source actors
{
bool hittable( true );
- if(layer.IsClipping())
+ if( layer.IsClipping() )
{
ClippingBox box = layer.GetClippingBox();
}
}
- if(hittable)
+ if( hittable )
{
Actor* actor( &layer );
// Ensure that we can descend into the layer's (or any of its parent's) hierarchy.
- while ( actor && hittable )
+ while( actor && hittable )
{
- if ( ! hitCheck.DescendActorHierarchy( actor ) )
+ if( ! hitCheck.DescendActorHierarchy( actor ) )
{
hittable = false;
break;
}
float nearClippingPlane, farClippingPlane;
- GetCameraClippingPlane(renderTask, nearClippingPlane, farClippingPlane);
+ GetCameraClippingPlane( renderTask, nearClippingPlane, farClippingPlane );
// Determine the layer depth of the source actor
Actor* sourceActor( renderTask.GetSourceActor() );
- if ( sourceActor )
+ if( sourceActor )
{
Dali::Layer layer( sourceActor->GetLayer() );
- if ( layer )
+ if( layer )
{
const unsigned int sourceActorDepth( layer.GetDepth() );
// Hit test starting with the top layer, working towards the bottom layer.
HitActor hit;
- bool stencilOnLayer = false;
- bool stencilHit = false;
bool overlayHit = false;
bool layerConsumesHit = false;
-
const Vector2& stageSize = stage.GetSize();
- for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i)
+ for( int i = layers.GetLayerCount() - 1; i >= 0 && !( hit.actor ); --i )
{
- Layer* layer( layers.GetLayer(i) );
- HitActor previousHit = hit;
- stencilOnLayer = false;
- stencilHit = false;
+ Layer* layer( layers.GetLayer( i ) );
overlayHit = false;
// Ensure layer is touchable (also checks whether ancestors are also touchable)
- if ( IsActuallyHittable ( *layer, screenCoordinates, stageSize, hitCheck ) )
+ if( IsActuallyHittable( *layer, screenCoordinates, stageSize, hitCheck ) )
{
// Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy
- if ( sourceActorDepth == static_cast<unsigned int>(i) )
+ if( sourceActorDepth == static_cast<unsigned int>( i ) )
{
// Recursively hit test the source actor & children, without crossing into other layers.
hit = HitTestWithinLayer( *sourceActor,
nearClippingPlane,
farClippingPlane,
hitCheck,
- stencilOnLayer,
- stencilHit,
overlayHit,
- false,
- layer->GetBehavior() == Dali::Layer::LAYER_3D);
+ layer->GetBehavior() == Dali::Layer::LAYER_3D,
+ 0u,
+ 0u );
}
- else if ( IsWithinSourceActors( *sourceActor, *layer ) )
+ else if( IsWithinSourceActors( *sourceActor, *layer ) )
{
// Recursively hit test all the actors, without crossing into other layers.
hit = HitTestWithinLayer( *layer,
nearClippingPlane,
farClippingPlane,
hitCheck,
- stencilOnLayer,
- stencilHit,
overlayHit,
- false,
- layer->GetBehavior() == Dali::Layer::LAYER_3D);
- }
-
- // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable
- if ( stencilOnLayer && !stencilHit &&
- hit.actor && hit.actor->IsRenderable() )
- {
- hit = previousHit;
+ layer->GetBehavior() == Dali::Layer::LAYER_3D,
+ 0u,
+ 0u );
}
// If this layer is set to consume the hit, then do not check any layers behind it
- if ( hitCheck.DoesLayerConsumeHit( layer ) )
+ if( hitCheck.DoesLayerConsumeHit( layer ) )
{
layerConsumesHit = true;
break;
}
}
}
- if ( hit.actor )
+
+ if( hit.actor )
{
- results.renderTask = Dali::RenderTask(&renderTask);
- results.actor = Dali::Actor(hit.actor);
- results.actorCoordinates.x = hit.x;
- results.actorCoordinates.y = hit.y;
+ results.renderTask = Dali::RenderTask( &renderTask );
+ results.actor = Dali::Actor( hit.actor );
+ results.actorCoordinates = hit.hitPosition;
+
return true; // Success
}
- else if ( layerConsumesHit )
+
+ if( layerConsumesHit )
{
return true; // Also success if layer is consuming the hit
}
}
/**
- * Iterate through RenderTaskList and perform hit test.
+ * Iterate through the RenderTaskList and perform hit testing.
*
- * @return true if we have a hit, false otherwise
+ * @param[in] stage The stage the tests will be performed in
+ * @param[in] layers The list of layers to test
+ * @param[in] taskList The list of render tasks
+ * @param[out] results Ray information calculated by the camera
+ * @param[in] hitCheck The hit testing interface object to use
+ * @param[in] onScreen True to test on-screen, false to test off-screen
+ * @return True if we have a hit, false otherwise
*/
-bool HitTestForEachRenderTask( Stage& stage,
- LayerList& layers,
- RenderTaskList& taskList,
- const Vector2& screenCoordinates,
- Results& results,
- HitTestInterface& hitCheck )
+bool HitTestRenderTaskList( Stage& stage,
+ LayerList& layers,
+ RenderTaskList& taskList,
+ const Vector2& screenCoordinates,
+ Results& results,
+ HitTestInterface& hitCheck,
+ bool onScreen )
{
RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
RenderTaskList::RenderTaskContainer::reverse_iterator endIter = tasks.rend();
-
const Vector< RenderTaskList::Exclusive >& exclusives = taskList.GetExclusivesList();
- // Check onscreen tasks before offscreen ones, hit test order should be reverse of draw order (see ProcessRenderTasks() where offscreen tasks are drawn first).
-
- // on screen
- for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter )
+ for( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter )
{
RenderTask& renderTask = GetImplementation( *iter );
Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer();
// Note that if frameBufferImage is NULL we are using the default (on screen) render target
- if(frameBufferImage)
+ if( frameBufferImage )
{
- ResourceId id = GetImplementation(frameBufferImage).GetResourceId();
+ ResourceId id = GetImplementation( frameBufferImage ).GetResourceId();
- // on screen only
- if(0 != id)
+ // Change comparison depending on if on-screen or off-screen.
+ if( onScreen ? ( 0 != id ) : ( 0 == id ) )
{
// Skip to next task
continue;
}
}
- if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
+ if( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
{
// Return true when an actor is hit (or layer in our render-task consumes the hit)
return true; // don't bother checking off screen tasks
}
}
- // off screen
- for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter )
- {
- RenderTask& renderTask = GetImplementation( *iter );
- Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer();
-
- // Note that if frameBufferImage is NULL we are using the default (on screen) render target
- if(frameBufferImage)
- {
- ResourceId id = GetImplementation(frameBufferImage).GetResourceId();
+ return false;
+}
- // off screen only
- if(0 == id)
- {
- // Skip to next task
- continue;
- }
+/**
+ * Iterate through the RenderTaskList and perform hit testing for both on-screen and off-screen.
+ *
+ * @param[in] stage The stage the tests will be performed in
+ * @param[in] layers The list of layers to test
+ * @param[in] taskList The list of render tasks
+ * @param[out] results Ray information calculated by the camera
+ * @param[in] hitCheck The hit testing interface object to use
+ * @param[in] onScreen True to test on-screen, false to test off-screen
+ * @return True if we have a hit, false otherwise
+ */
+bool HitTestForEachRenderTask( Stage& stage,
+ LayerList& layers,
+ RenderTaskList& taskList,
+ const Vector2& screenCoordinates,
+ Results& results,
+ HitTestInterface& hitCheck )
+{
+ bool result = false;
- if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
- {
- // Return true when an actor is hit (or a layer in our render-task consumes the hit)
- return true;
- }
- }
+ // Check on-screen tasks before off-screen ones.
+ // Hit test order should be reverse of draw order (see ProcessRenderTasks() where off-screen tasks are drawn first).
+ if( HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, true ) ||
+ HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, false ) )
+ {
+ // Found hit.
+ result = true;
}
- return false;
+
+ return result;
}
} // unnamed namespace
Results hitTestResults;
HitTestFunctionWrapper hitTestFunctionWrapper( func );
- if ( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+ if( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
{
results.actor = hitTestResults.actor;
results.actorCoordinates = hitTestResults.actorCoordinates;
// Hit-test the system-overlay actors first
SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal();
- if ( systemOverlay )
+ if( systemOverlay )
{
RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
LayerList& overlayLayerList = systemOverlay->GetLayerList();
}
// Hit-test the regular on-stage actors
- if ( !wasHit )
+ if( !wasHit )
{
RenderTaskList& taskList = stage.GetRenderTaskList();
LayerList& layerList = stage.GetLayerList();
const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList();
HitTestFunctionWrapper hitTestFunctionWrapper( func );
- if ( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+ if( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
{
results.actor = hitTestResults.actor;
results.actorCoordinates = hitTestResults.actorCoordinates;
return wasHit;
}
+
} // namespace HitTestAlgorithm
} // namespace Internal
-#ifndef __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__
-#define __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__
+#ifndef DALI_INTERNAL_HIT_TEST_ALGORITHM_H
+#define DALI_INTERNAL_HIT_TEST_ALGORITHM_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates,
Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func );
+
} // namespace HitTestAlgorithm
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__
+#endif // DALI_INTERNAL_HIT_TEST_ALGORITHM_H
}
Renderer::Renderer()
-: mSceneObject (NULL ),
+: mSceneObject(NULL ),
mBlendColor( NULL ),
mDepthIndex( 0 ),
mOnStageCount( 0 ),
$(internal_src_dir)/update/gestures/pan-gesture-profiling.cpp \
$(internal_src_dir)/update/gestures/scene-graph-pan-gesture.cpp \
$(internal_src_dir)/update/queue/update-message-queue.cpp \
- $(internal_src_dir)/update/manager/prepare-render-instructions.cpp \
$(internal_src_dir)/update/manager/geometry-batcher.cpp \
- $(internal_src_dir)/update/manager/process-render-tasks.cpp \
+ $(internal_src_dir)/update/manager/render-instruction-processor.cpp \
+ $(internal_src_dir)/update/manager/render-task-processor.cpp \
$(internal_src_dir)/update/manager/transform-manager.cpp \
$(internal_src_dir)/update/manager/update-algorithms.cpp \
$(internal_src_dir)/update/manager/update-manager.cpp \
context.SetScissorTest( true );
const Dali::ClippingBox& clip = renderList.GetClippingBox();
- context.Scissor(clip.x, clip.y, clip.width, clip.height);
+ context.Scissor( clip.x, clip.y, clip.width, clip.height );
}
else
{
}
/**
- * Sets the render flags for the stencil buffer and clears all required buffers (depth and stencil if required).
- * @param[in] renderList The render list from which to get the render flags
- * @param[in] context The context
- * @param[in] depthTestEnabled True if depth test is enabled for the layer
+ * @brief Set up the stencil and color buffer for automatic clipping (StencilMode::AUTO).
+ * @param[in] item The current RenderItem about to be rendered
+ * @param[in] context The context
+ * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn.
+ * @param[in/out] lastClippingId The clipping ID of the last renderer drawn.
*/
-inline void SetRenderFlags( const RenderList& renderList, Context& context, bool depthTestEnabled )
+inline void SetupClipping( const RenderItem& item, Context& context, uint32_t& lastStencilDepth, uint32_t& lastClippingId )
{
- const unsigned int renderFlags = renderList.GetFlags();
- GLbitfield clearMask = 0u;
-
- // Stencil enabled, writing, and clearing...
- const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED );
- const bool enableStencilWrite( renderFlags & RenderList::STENCIL_WRITE );
- context.EnableStencilBuffer( enableStencilBuffer );
- if( enableStencilBuffer )
- {
- context.StencilFunc( ( enableStencilWrite ? GL_ALWAYS : GL_EQUAL ), 1, 0xFF );
- context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );
+ const Dali::Internal::SceneGraph::Node* node = item.mNode;
+ const uint32_t clippingId = node->GetClippingId();
- // Write to stencil buffer or color buffer, but not both.
- // These should only be set if the Actor::DrawMode is managing the stencil (and color) buffer.
- context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
- context.ColorMask( !enableStencilWrite );
+ // Turn the color buffer on as we always want to render this renderer, regardless of clipping hierarchy.
+ context.ColorMask( true );
- clearMask |= ( renderFlags & RenderList::STENCIL_CLEAR ) ? GL_STENCIL_BUFFER_BIT : 0u;
+ // If there is no clipping Id, then either we haven't reached a clipping Node yet, or there aren't any.
+ // Either way we can skip clipping setup for this renderer.
+ if( clippingId == 0u )
+ {
+ // Exit immediately if there are no clipping actions to perform (EG. we have not yet hit a clipping node).
+ context.EnableStencilBuffer( false );
+ return;
}
- // Enable and Clear the depth buffer if required.
- if( depthTestEnabled )
+ const ClippingMode::Type clippingMode( node->GetClippingMode() );
+ const uint32_t currentStencilDepth( node->GetClippingDepth() );
+
+ context.EnableStencilBuffer( true );
+
+ // Pre-calculate a mask which has all bits set up to and including the current clipping depth.
+ // EG. If depth is 3, the mask would be "111" in binary.
+ const uint32_t currentDepthMask = ( 1u << currentStencilDepth ) - 1u;
+
+ // If we have a clipping mode specified, we are writing to the stencil buffer.
+ if( clippingMode != ClippingMode::DISABLED )
{
- clearMask |= GL_DEPTH_BUFFER_BIT;
+ // We are writing to the stencil buffer.
+ // If clipping Id is 1, this is the first clipping renderer within this render-list.
+ if( clippingId == 1u )
+ {
+ // We are enabling the stencil-buffer for the first time within this render list.
+ // Clear the buffer at this point.
+ context.StencilMask( 0xff );
+ context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+ }
+ else if( ( currentStencilDepth < lastStencilDepth ) || ( clippingId != lastClippingId ) )
+ {
+ // The above if() statement tests if we need to clear some (not all) stencil bit-planes.
+ // We need to do this if either of the following are true:
+ // 1) We traverse up the scene-graph to a previous stencil
+ // 2) We are at the same stencil depth but the clipping Id has changed.
+ //
+ // This calculation takes the new depth to move to, and creates an inverse-mask of that number of consecutive bits.
+ // This has the effect of clearing everything except the bit-planes up to (and including) our current depth.
+ const uint32_t stencilClearMask = ( currentDepthMask >> 1u ) ^ 0xff;
+
+ context.StencilMask( stencilClearMask );
+ context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+ }
- // We need to enable the depth buffer to clear it.
- // Subsequently it is enabled and disabled on a per-RenderItem basis.
- context.EnableDepthBuffer( true );
+ // We keep track of the last clipping Id and depth so we can determine when we are
+ // moving back up the scene graph and require some of the stencil bit-planes to be deleted.
+ lastStencilDepth = currentStencilDepth;
+ lastClippingId = clippingId;
+
+ // We only ever write to bit-planes up to the current depth as we may need
+ // to erase individual bit-planes and revert to a previous clipping area.
+ // Our reference value for testing (in StencilFunc) is written to to the buffer, but we actually
+ // want to test a different value. IE. All the bit-planes up to but not including the current depth.
+ // So we use the Mask parameter of StencilFunc to mask off the top bit-plane when testing.
+ // Here we create our test mask to innore the top bit of the reference test value.
+ // As the mask is made up of contiguous "1" values, we can do this quickly with a bit-shift.
+ const uint32_t testMask = currentDepthMask >> 1u;
+
+ context.StencilFunc( GL_EQUAL, currentDepthMask, testMask ); // Test against existing stencil bit-planes. All must match up to (but not including) this depth.
+ context.StencilMask( currentDepthMask ); // Write to the new stencil bit-plane (the other previous bit-planes are also written to).
+ context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );
}
else
{
- context.EnableDepthBuffer( false );
+ // We are reading from the stencil buffer. Set up the stencil accordingly
+ // This calculation sets all the bits up to the current depth bit.
+ // This has the effect of testing that the pixel being written to exists in every bit-plane up to the current depth.
+ context.StencilFunc( GL_EQUAL, currentDepthMask, 0xff );
+ context.StencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
}
-
- // Clear Depth and/or stencil buffers as required.
- // Note: The buffers will only be cleared if written to since a previous clear.
- context.Clear( clearMask, Context::CHECK_CACHED_VALUES );
}
/**
- * @brief This method sets up the stencil and color buffer based on the current Renderers flags.
+ * @brief Set up the stencil and color buffer based on the current Renderers properties.
* @param[in] item The current RenderItem about to be rendered
* @param[in] context The context
- * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList
- * @param[in] stencilManagedByDrawMode True if the stencil and color buffer is being managed by DrawMode::STENCIL
+ * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList. Used by StencilMode::ON.
+ * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
+ * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
*/
-inline void SetupPerRendererFlags( const RenderItem& item, Context& context, bool& usedStencilBuffer, bool stencilManagedByDrawMode )
+inline void SetupStencilBuffer( const RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastStencilDepth, uint32_t& lastClippingId )
{
- // DrawMode::STENCIL is deprecated, however to support it we must not set
- // flags based on the renderer properties if it is in use.
- if( stencilManagedByDrawMode )
- {
- return;
- }
+ const Renderer *renderer = item.mRenderer;
- // Setup the color buffer based on the renderers properties.
- Renderer *renderer = item.mRenderer;
+ // Setup the stencil using either the automatic clipping feature, or, the manual per-renderer stencil API.
+ // Note: This switch is in order of most likely value first.
RenderMode::Type renderMode = renderer->GetRenderMode();
- const bool writeToColorBuffer = ( renderMode == RenderMode::AUTO ) || ( renderMode == RenderMode::COLOR ) || ( renderMode == RenderMode::COLOR_STENCIL );
- context.ColorMask( writeToColorBuffer );
-
- // If the stencil buffer is disabled for this renderer, exit now to save unnecessary value setting.
- if( ( renderMode != RenderMode::STENCIL ) && ( renderMode != RenderMode::COLOR_STENCIL ) )
+ switch( renderMode )
{
- // No per-renderer stencil setup, exit.
- context.EnableStencilBuffer( false );
- return;
- }
+ case RenderMode::AUTO:
+ {
+ // The automatic clipping feature will manage the stencil functions and color buffer mask.
+ SetupClipping( item, context, lastStencilDepth, lastClippingId );
+ break;
+ }
- // At this point, the stencil buffer is enabled.
- context.EnableStencilBuffer( true );
+ case RenderMode::NONE:
+ case RenderMode::COLOR:
+ {
+ // The stencil buffer will not be used at all.
+ context.EnableStencilBuffer( false );
- // If this is the first use of the stencil buffer within this RenderList, clear it now.
- // This avoids unnecessary clears.
- if( !usedStencilBuffer )
- {
- context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
- usedStencilBuffer = true;
- }
+ // Setup the color buffer based on the RenderMode.
+ context.ColorMask( renderMode == RenderMode::COLOR );
+ return;
+ break; // Break statement for consistency (although return will be called instead).
+ }
- // Setup the stencil buffer based on the renderers properties.
- context.StencilFunc( DaliStencilFunctionToGL[ renderer->GetStencilFunction() ],
- renderer->GetStencilFunctionReference(),
- renderer->GetStencilFunctionMask() );
- context.StencilOp( DaliStencilOperationToGL[ renderer->GetStencilOperationOnFail() ],
- DaliStencilOperationToGL[ renderer->GetStencilOperationOnZFail() ],
- DaliStencilOperationToGL[ renderer->GetStencilOperationOnZPass() ] );
- context.StencilMask( renderer->GetStencilMask() );
+ case RenderMode::STENCIL:
+ case RenderMode::COLOR_STENCIL:
+ {
+ // We are using the low-level Renderer Stencil API.
+ // The stencil buffer must be enabled for every renderer with stencil mode on, as renderers in between can disable it.
+ // Note: As the command state is cached, it is only sent when needed.
+ context.EnableStencilBuffer( true );
+
+ // Setup the color buffer based on the RenderMode.
+ context.ColorMask( renderMode == RenderMode::COLOR_STENCIL );
+
+ // If this is the first use of the stencil buffer within this RenderList, clear it (this avoids unnecessary clears).
+ if( !usedStencilBuffer )
+ {
+ context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+ usedStencilBuffer = true;
+ }
+
+ // Setup the stencil buffer based on the renderers properties.
+ context.StencilFunc( DaliStencilFunctionToGL[ renderer->GetStencilFunction() ],
+ renderer->GetStencilFunctionReference(),
+ renderer->GetStencilFunctionMask() );
+ context.StencilOp( DaliStencilOperationToGL[ renderer->GetStencilOperationOnFail() ],
+ DaliStencilOperationToGL[ renderer->GetStencilOperationOnZFail() ],
+ DaliStencilOperationToGL[ renderer->GetStencilOperationOnZPass() ] );
+ context.StencilMask( renderer->GetStencilMask() );
+ break;
+ }
+ }
}
/**
- * Sets up the depth buffer for reading and writing based on the current render item.
+ * @brief Sets up the depth buffer for reading and writing based on the current render item.
* The items read and write mode are used if specified.
- * If AUTO is selected for reading, the decision will be based on the Layer Behavior.
- * If AUTO is selected for writing, the decision will be based on the items opacity.
- * @param item The RenderItem to set up the depth buffer for
- * @param context The context used to execute GL commands.
- * @param depthTestEnabled True if depth testing has been enabled.
+ * - If AUTO is selected for reading, the decision will be based on the Layer Behavior.
+ * - If AUTO is selected for writing, the decision will be based on the items opacity.
+ * @param[in] item The RenderItem to set up the depth buffer for.
+ * @param[in] context The context used to execute GL commands.
+ * @param[in] depthTestEnabled True if depth testing has been enabled.
+ * @param[in/out] firstDepthBufferUse Initialise to true on the first call, this method will set it to false afterwards.
*/
-inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool depthTestEnabled )
+inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool depthTestEnabled, bool& firstDepthBufferUse )
{
// Set up whether or not to write to the depth buffer.
const DepthWriteMode::Type depthWriteMode = item.mRenderer->GetDepthWriteMode();
// Most common mode (AUTO) is tested first.
- bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && depthTestEnabled && item.mIsOpaque ) ||
- ( depthWriteMode == DepthWriteMode::ON );
- context.DepthMask( enableDepthWrite );
+ const bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && depthTestEnabled && item.mIsOpaque ) ||
+ ( depthWriteMode == DepthWriteMode::ON );
// Set up whether or not to read from (test) the depth buffer.
const DepthTestMode::Type depthTestMode = item.mRenderer->GetDepthTestMode();
// Most common mode (AUTO) is tested first.
- bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && depthTestEnabled ) ||
- ( depthTestMode == DepthTestMode::ON );
- // Look-up the GL depth function from the Dali::DepthFunction enum, and set it.
- context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] );
+ const bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && depthTestEnabled ) ||
+ ( depthTestMode == DepthTestMode::ON );
+
+ // Is the depth buffer in use?
+ if( enableDepthWrite || enableDepthTest )
+ {
+ // The depth buffer must be enabled if either reading or writing.
+ context.EnableDepthBuffer( true );
+
+ // Set up the depth mask based on our depth write setting.
+ context.DepthMask( enableDepthWrite );
+
+ // Look-up the GL depth function from the Dali::DepthFunction enum, and set it.
+ context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] );
+
+ // If this is the first use of the depth buffer this RenderTask, perform a clear.
+ // Note: We could do this at the beginning of the RenderTask and rely on the
+ // context cache to ignore the clear if not required, but, we would have to enable
+ // the depth buffer to do so, which could be a redundant enable.
+ if( DALI_UNLIKELY( firstDepthBufferUse ) )
+ {
+ // This is the first time the depth buffer is being written to or read.
+ firstDepthBufferUse = false;
+
+ // Note: The buffer will only be cleared if written to since a previous clear.
+ context.Clear( GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+ }
+ }
+ else
+ {
+ // The depth buffer is not being used by this renderer, so we must disable it to stop it being tested.
+ context.EnableDepthBuffer( false );
+ }
+}
+
+/**
+ * @brief Setup Batching and calculate if we should perform or skip the upcoming render.
+ *
+ * Check if the node has a valid batch index value ( set previously by
+ * GeometryBatcher ). If so, then it queries the geometry object for this particular batch.
+ * If not, it still checks if the batch parent is set as it is possible, batching may
+ * fail (for example if vertex format or buffers are not set). In that case we need
+ * to skip rendering, otherwise unwanted GPU buffers will get uploaded. This is very rare case.
+ * @param[in] item The item to test / setup for batching
+ * @param[in] geometryBatcher The instance of the Geometry Batcher
+ * @return True if we should perform a render as normal. False if we should skip it due to batching.
+ */
+inline bool SetupBatching( const RenderItem& item, GeometryBatcher* geometryBatcher )
+{
+ bool performRender( true );
+ uint32_t batchIndex( item.mNode->mBatchIndex );
+
+ if( batchIndex != BATCH_NULL_HANDLE )
+ {
+ item.mBatchRenderGeometry = geometryBatcher->GetGeometry( batchIndex );
+ }
+ else
+ {
+ performRender = !( item.mNode->GetBatchParent() );
+ item.mBatchRenderGeometry = NULL;
+ }
- // The depth buffer must be enabled if either reading or writing.
- context.EnableDepthBuffer( enableDepthWrite || enableDepthTest );
+ return performRender;
}
/**
- * Process a render-list.
- * @param[in] renderList The render-list to process.
- * @param[in] context The GL context.
- * @param[in] defaultShader The default shader to use.
- * @param[in] buffer The current render buffer index (previous update buffer)
- * @param[in] viewMatrix The view matrix from the appropriate camera.
+ * @brief Process a render-list.
+ * @param[in] renderList The render-list to process.
+ * @param[in] context The GL context.
+ * @param[in] defaultShader The default shader to use.
+ * @param[in] buffer The current render buffer index (previous update buffer)
+ * @param[in] viewMatrix The view matrix from the appropriate camera.
* @param[in] projectionMatrix The projection matrix from the appropriate camera.
- * @param[in] geometryBatcher The instance of the geometry batcher
+ * @param[in] geometryBatcher The instance of the geometry batcher
*/
inline void ProcessRenderList(
const RenderList& renderList,
{
DALI_PRINT_RENDER_LIST( renderList );
- bool autoDepthTestMode = !( renderList.GetSourceLayer()->IsDepthTestDisabled() ) && renderList.HasColorRenderItems();
- bool usedStencilBuffer = false;
- bool stencilManagedByDrawMode = renderList.GetFlags() & RenderList::STENCIL_BUFFER_ENABLED;
-
SetScissorTest( renderList, context );
- SetRenderFlags( renderList, context, autoDepthTestMode );
+ // Note: The depth buffer is enabled or disabled on a per-renderer basis.
+ // Here we pre-calculate the value to use if these modes are set to AUTO.
+ const bool autoDepthTestMode( !( renderList.GetSourceLayer()->IsDepthTestDisabled() ) && renderList.HasColorRenderItems() );
const std::size_t count = renderList.Count();
- bool skip( false );
- for ( size_t index = 0; index < count; ++index )
+ uint32_t lastStencilDepth( 0u );
+ uint32_t lastClippingId( 0u );
+ bool usedStencilBuffer( false );
+ bool firstDepthBufferUse( true );
+
+ for( size_t index( 0u ); index < count; ++index )
{
const RenderItem& item = renderList.GetItem( index );
DALI_PRINT_RENDER_ITEM( item );
// draw-mode state, such as Overlays.
// If the flags are set to "AUTO", the behaviour then depends on the type of renderer. Overlay Renderers will always
// disable depth testing and writing. Color Renderers will enable them if the Layer does.
- SetupDepthBuffer( item, context, autoDepthTestMode );
- SetupPerRendererFlags( item, context, usedStencilBuffer, stencilManagedByDrawMode );
-
- // Check if the node has a valid batch index value ( set previously by
- // GeometryBatcher ). If so, then it queries the geometry object for this particular batch.
- // If not, it still checks if the batch parent is set as it is possible, batching may
- // fail ( for example if vertex format or buffers are not set ). In that case we need
- // to skip rendering, otherwise unwanted GPU buffers will get uploaded. This is very rare case.
- uint32_t batchIndex = item.mNode->mBatchIndex;
- if( batchIndex != BATCH_NULL_HANDLE )
- {
- item.mBatchRenderGeometry = geometryBatcher->GetGeometry( batchIndex );
- }
- else
- {
- skip = item.mNode->GetBatchParent();
- item.mBatchRenderGeometry = NULL;
- }
- if( DALI_LIKELY( !skip ) )
+ SetupDepthBuffer( item, context, autoDepthTestMode, firstDepthBufferUse );
+
+ // Set up the stencil buffer based on both the Renderer and Actor APIs.
+ // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
+ SetupStencilBuffer( item, context, usedStencilBuffer, lastStencilDepth, lastClippingId );
+
+ // Setup Batching and calculate if we should perform or skip the upcoming render.
+ const bool performRender( SetupBatching( item, geometryBatcher ) );
+
+ // Render the item if it has not been skipped by batching.
+ if( DALI_LIKELY( performRender ) )
{
item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader,
- item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque );
+ item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix,
+ item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque );
}
}
}
const Matrix* viewMatrix = instruction.GetViewMatrix( bufferIndex );
const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex );
- DALI_ASSERT_DEBUG( NULL != viewMatrix );
- DALI_ASSERT_DEBUG( NULL != projectionMatrix );
+ DALI_ASSERT_DEBUG( viewMatrix );
+ DALI_ASSERT_DEBUG( projectionMatrix );
- if( NULL != viewMatrix &&
- NULL != projectionMatrix )
+ if( viewMatrix && projectionMatrix )
{
const RenderListContainer::SizeType count = instruction.RenderListCount();
{
const RenderList* renderList = instruction.GetRenderList( index );
- if( renderList &&
- !renderList->IsEmpty() )
+ if( renderList && !renderList->IsEmpty() )
{
ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix, &geometryBatcher );
}
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/internal/render/common/render-item.h>
#include <dali/internal/render/common/render-list.h>
#include <dali/internal/render/common/render-instruction.h>
+#include <dali/internal/update/nodes/node.h>
+using Dali::Internal::SceneGraph::Node;
using Dali::Internal::SceneGraph::RenderList;
namespace Dali
namespace Render
{
+// These functions should only be defined if they are being used by the #define in the header.
+// Otherwise they will contribute negatively to code coverage.
+#ifdef DALI_PRINT_RENDER_INFO
+
void PrintFrameStart( BufferIndex bufferIndex )
{
DALI_LOG_RENDER_INFO( "RENDER START - bufferIndex: %d\n", bufferIndex );
void PrintRenderList( const RenderList& list )
{
- unsigned int flags = list.GetFlags();
-
std::stringstream debugStream;
debugStream << "Rendering items";
- if( flags )
- {
- debugStream << " with:";
-
- if( flags & RenderList::STENCIL_BUFFER_ENABLED )
- {
- debugStream << " STENCIL_TEST";
- }
-
- if( flags & RenderList::STENCIL_WRITE )
- {
- debugStream << " STENCIL_WRITE";
- }
-
- if( flags & RenderList::STENCIL_CLEAR )
- {
- debugStream << " STENCIL_CLEAR";
- }
- }
- else
- {
- debugStream << " without any STENCIL settings";
- }
-
if( list.IsClipping() )
{
debugStream << ", ClippingBox: " << list.GetClippingBox().x << "," << list.GetClippingBox().y << " " << list.GetClippingBox().width << "x" << list.GetClippingBox().height;
}
}
+#endif
+
} // Render
} // Internal
namespace SceneGraph
{
+class Node;
class RenderInstruction;
struct RenderList;
struct RenderItem;
*/
void PrintRendererCount( unsigned int frameCount, unsigned int rendererCount );
+/**
+ * Recursively dumps a Node tree.
+ * @param[in] node The starting node to dump from
+ * @param[in] indent Optional. Leave unset for default indent (used internally while recursing)
+ */
+void DumpNode( const SceneGraph::Node* node, unsigned int indent = 0 );
+
} // Render
} // Internal
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
{
/**
* Construct a new RenderItem
+ * @return A pointer to a new RenderItem.
*/
static RenderItem* New();
/**
* Overriden delete operator.
* Deletes the RenderItem from its global memory pool
+ * @param[in] A pointer to the RenderItem to delete.
*/
void operator delete( void* ptr );
bool mIsOpaque:1;
bool mBatched:1;
-
private:
/**
// RenderItems should not be copied as they are heavy
RenderItem( const RenderItem& item );
RenderItem& operator = ( const RenderItem& item );
+
};
} // namespace SceneGraph
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
typedef OwnerContainer< RenderList* > RenderListContainer;
/**
- * The RenderList structure provides the renderer with a list of renderers and
- * a set of flags to tell it what depth buffering is required.
+ * The RenderList structure provides the renderer with a list of renderers.
*/
struct RenderList
{
public:
/**
- * The RenderFlags describe how the objects are rendered using the stencil buffer.
- */
- enum RenderFlags
- {
- STENCIL_BUFFER_ENABLED = 1 << 0, ///< If stencil buffer should be used for writing / test operation
- STENCIL_WRITE = 1 << 1, ///< If the stencil buffer is writable
- STENCIL_CLEAR = 1 << 2, ///< If the stencil buffer should first be cleared
- };
-
- /**
* Constructor
*/
RenderList()
: mNextFree( 0 ),
- mRenderFlags( 0u ),
mClippingBox( NULL ),
mSourceLayer( NULL ),
mHasColorRenderItems( false )
*/
~RenderList()
{
- // pointer container deletes the render items
+ // Pointer container deletes the render items
delete mClippingBox;
}
/**
- * Clear the render flags
- */
- void ClearFlags()
- {
- mRenderFlags = 0u;
- }
-
- /**
- * Set particular render flags
- * @param[in] flags The set of flags to bitwise or with existing flags
- */
- void SetFlags( unsigned int flags )
- {
- mRenderFlags |= flags;
- }
-
- /**
- * Retrieve the render flags.
- * @return the render flags.
- */
- unsigned int GetFlags() const
- {
- return mRenderFlags;
- }
-
- /**
* Reset the render list for next frame
*/
void Reset()
{
- // we dont want to delete and re-create the render items every frame
+ // We don't want to delete and re-create the render items every frame
mNextFree = 0;
- mRenderFlags = 0u;
delete mClippingBox;
mClippingBox = NULL;
*/
bool IsEmpty() const
{
- return (mNextFree == 0);
+ return ( mNextFree == 0 );
}
/**
{
if( clipping )
{
- ClippingBox* newBox = new ClippingBox( box );
delete mClippingBox;
- mClippingBox = newBox;
+ mClippingBox = new ClippingBox( box );;
}
}
*/
bool IsClipping() const
{
- return (NULL != mClippingBox);
+ return ( NULL != mClippingBox );
}
/**
RenderItemContainer mItems; ///< Each item is a renderer and matrix pair
RenderItemContainer::SizeType mNextFree; ///< index for the next free item to use
- unsigned int mRenderFlags; ///< The render flags
-
ClippingBox* mClippingBox; ///< The clipping box, in window coordinates, when clipping is enabled
Layer* mSourceLayer; ///< The originating layer where the renderers are from
bool mHasColorRenderItems : 1; ///< True if list contains color render items
+
};
+
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H
}
}
-void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const
+void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const
{
sortAttributes.shader = &( mRenderDataProvider->GetShader() );
const std::vector<Render::Texture>& textures( mRenderDataProvider->GetTextures() );
#include <dali/internal/render/data-providers/render-data-provider.h>
#include <dali/internal/render/gl-resources/gl-resource-owner.h>
#include <dali/internal/render/renderers/render-geometry.h>
-#include <dali/internal/update/manager/prepare-render-instructions.h>
+#include <dali/internal/update/manager/render-instruction-processor.h>
#include <dali/integration-api/debug.h>
namespace Dali
class NodeDataProvider;
}
-
namespace Render
{
* @param[in] bufferIndex The current update buffer index.
* @param[out] sortAttributes
*/
- void SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const;
+ void SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const;
private:
struct UniformIndexMap
{
- unsigned int uniformIndex; ///< The index of the cached location in the Program
+ unsigned int uniformIndex; ///< The index of the cached location in the Program
const PropertyInputImpl* propertyValue;
};
typedef Dali::Vector< UniformIndexMap > UniformIndexMappings;
+
UniformIndexMappings mUniformIndexMap;
Vector<GLint> mAttributesLocation;
DepthTestMode::Type mDepthTestMode:2; ///< The depth test mode
bool mUpdateAttributesLocation:1; ///< Indicates attribute locations have changed
bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
- bool mBatchingEnabled:1; ///< Flag indicating if the renderer is batchable
+ bool mBatchingEnabled:1; ///< Flag indicating if the renderer is batchable
+
};
} // namespace SceneGraph
+++ /dev/null
-/*
- * Copyright (c) 2016 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.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/update/manager/prepare-render-instructions.h>
-
-// INTERNAL INCLUDES
-#include <dali/public-api/shader-effects/shader-effect.h>
-#include <dali/public-api/actors/layer.h>
-#include <dali/integration-api/debug.h>
-#include <dali/internal/event/actors/layer-impl.h> // for the default sorting function
-#include <dali/internal/update/nodes/scene-graph-layer.h>
-#include <dali/internal/update/manager/sorted-layers.h>
-#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
-#include <dali/internal/update/rendering/scene-graph-texture-set.h>
-#include <dali/internal/update/resources/resource-manager-declarations.h>
-#include <dali/internal/render/common/render-item.h>
-#include <dali/internal/render/common/render-tracker.h>
-#include <dali/internal/render/common/render-instruction.h>
-#include <dali/internal/render/common/render-instruction-container.h>
-#include <dali/internal/render/shaders/scene-graph-shader.h>
-#include <dali/internal/render/renderers/render-renderer.h>
-#include <dali/internal/render/renderers/render-property-buffer.h>
-#include <dali/internal/update/manager/geometry-batcher.h>
-
-namespace
-{
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS");
-#endif
-}
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace SceneGraph
-{
-
-/**
- * Add a renderer to the list
- * @param updateBufferIndex to read the model matrix from
- * @param renderList to add the item to
- * @param renderable Node-Renderer pair
- * @param viewMatrix used to calculate modelview matrix for the item
- * @param camera The camera used to render
- * @param geometryBatcher The instance of the geometry batcher
- * @param isLayer3d Whether we are processing a 3D layer or not
- * @param cull Whether frustum culling is enabled or not
- */
-inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
- RenderList& renderList,
- Renderable& renderable,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- GeometryBatcher& geometryBatcher,
- bool isLayer3d,
- bool cull )
-{
- // discard renderable early if it belongs to the batch which has been consumed in during frame
- Node* renderableNode = renderable.mNode;
- const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE );
- if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) )
- {
- return;
- }
-
- bool inside( true );
- const Node* batchParentNode = renderable.mNode->GetBatchParent();
- const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ?
- batchParentNode : renderableNode;
-
- if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
- {
- const Vector4& boundingSphere = node->GetBoundingSphere();
- inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
- (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) );
- }
-
- if( inside )
- {
- if( batchingValid )
- {
- geometryBatcher.SetRendered( renderableNode->mBatchIndex );
- }
-
- Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode );
- if( opacity != Renderer::TRANSPARENT )
- {
- // Get the next free RenderItem
- RenderItem& item = renderList.GetNextFreeItem();
- item.mRenderer = &renderable.mRenderer->GetRenderer();
- item.mNode = renderable.mNode;
- item.mIsOpaque = (opacity == Renderer::OPAQUE);
-
- if( isLayer3d )
- {
- item.mDepthIndex = renderable.mRenderer->GetDepthIndex();
- }
- else
- {
- item.mDepthIndex = renderable.mRenderer->GetDepthIndex() + static_cast<int>( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER;
- }
- // save MV matrix onto the item
- node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
- Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
- }
- }
-}
-
-/**
- * Add all renderers to the list
- * @param updateBufferIndex to read the model matrix from
- * @param renderList to add the items to
- * @param renderers to render
- * NodeRendererContainer Node-Renderer pairs
- * @param viewMatrix used to calculate modelview matrix for the items
- * @param camera The camera used to render
- * @param geometryBatcher The instance of the geometry batcher
- * @param isLayer3d Whether we are processing a 3D layer or not
- * @param cull Whether frustum culling is enabled or not
- */
-inline void AddRenderersToRenderList( BufferIndex updateBufferIndex,
- RenderList& renderList,
- RenderableContainer& renderers,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- GeometryBatcher* geometryBatcher,
- bool isLayer3d,
- bool cull)
-{
- DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n");
-
- unsigned int rendererCount( renderers.Size() );
- for( unsigned int i(0); i<rendererCount; ++i )
- {
- AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, *geometryBatcher, isLayer3d, cull );
- }
-}
-
-/**
- * Try to reuse cached renderitems from the renderlist
- * This avoids recalculating the model view matrices in case this part of the scene was static
- * An example case is a toolbar layer that rarely changes or a popup on top of the rest of the stage
- * @param layer that is being processed
- * @param renderList that is cached from frame N-1
- * @param renderables list of renderables
- */
-inline bool TryReuseCachedRenderers( Layer& layer,
- RenderList& renderList,
- RenderableContainer& renderables )
-{
- bool retValue = false;
- size_t renderableCount = renderables.Size();
- // check that the cached list originates from this layer and that the counts match
- if( ( renderList.GetSourceLayer() == &layer )&&
- ( renderList.GetCachedItemCount() == renderableCount ) )
- {
- // check that all the same renderers are there. This gives us additional security in avoiding rendering the wrong things
- // Render list is sorted so at this stage renderers may be in different order
- // therefore we check a combined sum of all renderer addresses
- size_t checkSumNew = 0;
- size_t checkSumOld = 0;
- for( size_t index = 0; index < renderableCount; ++index )
- {
- const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer();
- checkSumNew += size_t( &renderer );
- checkSumOld += size_t( &renderList.GetRenderer( index ) );
- }
- if( checkSumNew == checkSumOld )
- {
- // tell list to reuse its existing items
- renderList.ReuseCachedItems();
- retValue = true;
- }
- }
- return retValue;
-}
-
-/**
- * Function which sorts render items by depth index then by instance
- * ptrs of shader/texture/geometry.
- * @param lhs item
- * @param rhs item
- * @return true if left item is greater than right
- */
-bool CompareItems( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs )
-{
- if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex )
- {
- if( lhs.shader == rhs.shader )
- {
- if( lhs.textureResourceId == rhs.textureResourceId )
- {
- return lhs.geometry < rhs.geometry;
- }
- return lhs.textureResourceId < rhs.textureResourceId;
- }
- return lhs.shader < rhs.shader;
- }
- return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex;
-}
-/**
- * Function which sorts the render items by Z function, then
- * by instance ptrs of shader/texture/geometry.
- * @param lhs item
- * @param rhs item
- * @return true if left item is greater than right
- */
-bool CompareItems3D( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs )
-{
- bool lhsIsOpaque = lhs.renderItem->mIsOpaque;
- if( lhsIsOpaque == rhs.renderItem->mIsOpaque )
- {
- if( lhsIsOpaque )
- {
- //If both RenderItems are opaque, sort using shader, then texture then geometry
- if( lhs.shader == rhs.shader )
- {
- if( lhs.textureResourceId == rhs.textureResourceId )
- {
- return lhs.geometry < rhs.geometry;
- }
- return lhs.textureResourceId < rhs.textureResourceId;
- }
- return lhs.shader < rhs.shader;
- }
- else
- {
- //If both RenderItems are transparent, sort using z,then shader, then texture, then geometry
- if( Equals(lhs.zValue, rhs.zValue) )
- {
- if( lhs.shader == rhs.shader )
- {
- if( lhs.textureResourceId == rhs.textureResourceId )
- {
- return lhs.geometry < rhs.geometry;
- }
- return lhs.textureResourceId < rhs.textureResourceId;
- }
- return lhs.shader < rhs.shader;
- }
- return lhs.zValue > rhs.zValue;
- }
- }
- else
- {
- return lhsIsOpaque;
- }
-}
-
-/**
- * Sort render items
- * @param bufferIndex The buffer to read from
- * @param renderList to sort
- * @param layer where the renderers are from
- * @param sortingHelper to use for sorting the renderitems (to avoid reallocating)
- */
-inline void SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, RendererSortingHelper& sortingHelper )
-{
- const size_t renderableCount = renderList.Count();
- // reserve space if needed
- const unsigned int oldcapacity = sortingHelper.size();
- if( oldcapacity < renderableCount )
- {
- sortingHelper.reserve( renderableCount );
- // add real objects (reserve does not construct objects)
- sortingHelper.insert( sortingHelper.begin() + oldcapacity,
- (renderableCount - oldcapacity),
- RendererWithSortAttributes() );
- }
- else
- {
- // clear extra elements from helper, does not decrease capability
- sortingHelper.resize( renderableCount );
- }
-
- // 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() )
- {
- for( size_t index = 0; index < renderableCount; ++index )
- {
- RenderItem& item = renderList.GetItem( index );
-
- item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
-
- // the default sorting function should get inlined here
- sortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
-
- // keep the renderitem pointer in the helper so we can quickly reorder items after sort
- sortingHelper[ index ].renderItem = &item;
- }
- }
- else
- {
- const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction();
- for( size_t index = 0; index < renderableCount; ++index )
- {
- RenderItem& item = renderList.GetItem( index );
-
- item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
- sortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
-
- // keep the renderitem pointer in the helper so we can quickly reorder items after sort
- sortingHelper[ index ].renderItem = &item;
- }
- }
-
- if( layer.GetBehavior() == Dali::Layer::LAYER_3D)
- {
- // sort the renderers back to front, Z Axis point from near plane to far plane
- std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems3D );
- }
- else
- {
- // sort the renderers based on DepthIndex
- std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems );
- }
-
- // reorder/repopulate the renderitems in renderlist to correct order based on sortinghelper
- DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n");
- RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin();
- for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter )
- {
- *renderListIter = sortingHelper[ index ].renderItem;
- DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, sortingHelper[ index ].renderItem->mRenderer);
- }
-}
-
-/**
- * Add color renderers from the layer onto the next free render list
- * @param updateBufferIndex to use
- * @param layer to get the renderers from
- * @param viewmatrix for the camera from rendertask
- * @param camera to use the view frustum
- * @param stencilRenderablesExist is true if there are stencil renderers on this layer
- * @param instruction to fill in
- * @param sortingHelper to use for sorting the renderitems (to avoid reallocating)
- * @param geometryBatcher the instance of the geometry batcher
- * @param tryReuseRenderList whether to try to reuse the cached items from the instruction
- * @param cull Whether frustum culling is enabled or not
- */
-inline void AddColorRenderers( BufferIndex updateBufferIndex,
- Layer& layer,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- bool stencilRenderablesExist,
- RenderInstruction& instruction,
- RendererSortingHelper& sortingHelper,
- GeometryBatcher& geometryBatcher,
- bool tryReuseRenderList,
- bool cull)
-{
- RenderList& renderList = instruction.GetNextFreeRenderList( layer.colorRenderables.Size() );
- renderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
- renderList.SetSourceLayer( &layer );
- renderList.SetHasColorRenderItems( true );
-
- // try to reuse cached renderitems from last time around
- if( tryReuseRenderList )
- {
- if( TryReuseCachedRenderers( layer, renderList, layer.colorRenderables ) )
- {
- return;
- }
- }
-
- AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, camera, &geometryBatcher, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
- SortRenderItems( updateBufferIndex, renderList, layer, sortingHelper );
-
- // Setup the render flags for stencil.
- renderList.ClearFlags();
- if( stencilRenderablesExist )
- {
- // Note: SetFlags does not overwrite, it ORs, so ClearFlags() is also required.
- renderList.SetFlags( RenderList::STENCIL_BUFFER_ENABLED );
- }
-}
-
-/**
- * Add overlay renderers from the layer onto the next free render list
- * @param updateBufferIndex to use
- * @param layer to get the renderers from
- * @param viewmatrix for the camera from rendertask
- * @param camera to use
- * @param stencilRenderablesExist is true if there are stencil renderers on this layer
- * @param instruction to fill in
- * @param tryReuseRenderList whether to try to reuse the cached items from the instruction
- * @param cull Whether frustum culling is enabled or not
- */
-inline void AddOverlayRenderers( BufferIndex updateBufferIndex,
- Layer& layer,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- bool stencilRenderablesExist,
- RenderInstruction& instruction,
- RendererSortingHelper& sortingHelper,
- bool tryReuseRenderList,
- bool cull )
-{
- RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.Size() );
- overlayRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
- overlayRenderList.SetSourceLayer( &layer );
- overlayRenderList.SetHasColorRenderItems( false );
-
- //Set render flags
- overlayRenderList.ClearFlags();
- if(stencilRenderablesExist)
- {
- overlayRenderList.SetFlags(RenderList::STENCIL_BUFFER_ENABLED);
- }
-
- // try to reuse cached renderitems from last time around
- if( tryReuseRenderList )
- {
- if( TryReuseCachedRenderers( layer, overlayRenderList, layer.overlayRenderables ) )
- {
- return;
- }
- }
- AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
- SortRenderItems( updateBufferIndex, overlayRenderList, layer, sortingHelper );
-}
-
-/**
- * Add stencil renderers from the layer onto the next free render list
- * @param updateBufferIndex to use
- * @param layer to get the renderers from
- * @param viewmatrix for the camera from rendertask
- * @param camera to use
- * @param instruction to fill in
- * @param tryReuseRenderList whether to try to reuse the cached items from the instruction
- * @param cull Whether frustum culling is enabled or not
- */
-inline void AddStencilRenderers( BufferIndex updateBufferIndex,
- Layer& layer,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- RenderInstruction& instruction,
- bool tryReuseRenderList,
- bool cull )
-{
- RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.Size() );
- stencilRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
- stencilRenderList.SetSourceLayer( &layer );
- stencilRenderList.SetHasColorRenderItems( false );
-
- //Set render flags
- stencilRenderList.ClearFlags();
- stencilRenderList.SetFlags(RenderList::STENCIL_CLEAR | RenderList::STENCIL_WRITE | RenderList::STENCIL_BUFFER_ENABLED );
-
- // try to reuse cached renderitems from last time around
- if( tryReuseRenderList )
- {
- if( TryReuseCachedRenderers( layer, stencilRenderList, layer.stencilRenderables ) )
- {
- return;
- }
- }
- AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
-}
-
-void PrepareRenderInstruction( BufferIndex updateBufferIndex,
- SortedLayerPointers& sortedLayers,
- RenderTask& renderTask,
- RendererSortingHelper& sortingHelper,
- bool cull,
- RenderInstructionContainer& instructions,
- GeometryBatcher& geometryBatcher )
-{
- // Retrieve the RenderInstruction buffer from the RenderInstructionContainer
- // then populate with instructions.
- RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex );
- renderTask.PrepareRenderInstruction( instruction, updateBufferIndex );
- bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated();
-
- const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex );
- SceneGraph::Camera& camera = renderTask.GetCamera();
-
- const SortedLayersIter endIter = sortedLayers.end();
- for ( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter )
- {
- Layer& layer = **iter;
-
- const bool stencilRenderablesExist( !layer.stencilRenderables.Empty() );
- const bool colorRenderablesExist( !layer.colorRenderables.Empty() );
- const bool overlayRenderablesExist( !layer.overlayRenderables.Empty() );
- const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers( &renderTask.GetCamera() ) );
-
- // Ignore stencils if there's nothing to test
- if( stencilRenderablesExist &&
- ( colorRenderablesExist || overlayRenderablesExist ) )
- {
- AddStencilRenderers( updateBufferIndex, layer, viewMatrix, camera, instruction, tryReuseRenderList, cull );
- }
-
- if ( colorRenderablesExist )
- {
- AddColorRenderers( updateBufferIndex,
- layer,
- viewMatrix,
- camera,
- stencilRenderablesExist,
- instruction,
- sortingHelper,
- geometryBatcher,
- tryReuseRenderList,
- cull );
- }
-
- if ( overlayRenderablesExist )
- {
- AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, camera, stencilRenderablesExist,
- instruction, sortingHelper, tryReuseRenderList, cull );
- }
- }
-
- // inform the render instruction that all renderers have been added and this frame is complete
- instruction.UpdateCompleted();
-}
-
-} // SceneGraph
-
-} // Internal
-
-} // Dali
+++ /dev/null
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__
-
-/*
- * Copyright (c) 2016 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.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/internal/common/buffer-index.h>
-#include <dali/internal/update/manager/sorted-layers.h>
-#include <dali/integration-api/resource-declarations.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Render
-{
-class Geometry;
-}
-
-namespace SceneGraph
-{
-class RenderTracker;
-struct RenderItem;
-class Shader;
-class GeometryBatcher;
-
-/**
- * Structure to store information for sorting the renderers.
- * (Note, depthIndex is stored within the renderItem).
- */
-struct RendererWithSortAttributes
-{
- RendererWithSortAttributes()
- : renderItem( NULL ),
- shader(NULL),
- textureResourceId( Integration::InvalidResourceId ),
- geometry(NULL),
- zValue(0.0f)
- {
- }
-
- RenderItem* renderItem; ///< The render item that is being sorted (includes depth index)
- const Shader* shader; ///< The shader instance
- Integration::ResourceId textureResourceId;///< The first texture resource ID of the texture set instance, is InvalidResourceId if the texture set doesn't have any textures
- const Render::Geometry* geometry; ///< The geometry instance
- float zValue; ///< The zValue of the given renderer (either distance from camera, or a custom calculated value)
-};
-
-typedef std::vector< RendererWithSortAttributes > RendererSortingHelper;
-
-class RenderTask;
-class RenderInstructionContainer;
-
-/**
- * Sorts and prepares the list of opaque/transparent renderers for each layer.
- * Whilst iterating through each layer, update the renderitems ModelView matrices
- *
- * The opaque and transparent render lists are sorted first by depth
- * index, then by Z (for transparent only), then by shader, texture
- * and geometry. The render algorithm should then work through both
- * lists simultaneously, working through opaque then transparent
- * items at each depth index, resetting the flags appropriately.
- *
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables.
- * @param[in] renderTask The rendering task information.
- * @param[in] sortingHelper to avoid allocating containers for sorting every frame
- * @param[in] cull Whether frustum culling is enabled or not
- * @param[out] instructions The rendering instructions for the next frame.
- */
-void PrepareRenderInstruction( BufferIndex updateBufferIndex,
- SortedLayerPointers& sortedLayers,
- RenderTask& renderTask,
- RendererSortingHelper& sortingHelper,
- bool cull,
- RenderInstructionContainer& instructions,
- GeometryBatcher& geometryBatcher );
-
-} // namespace SceneGraph
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__
+++ /dev/null
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__
-
-/*
- * Copyright (c) 2016 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.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/internal/update/manager/sorted-layers.h>
-#include <dali/internal/update/manager/prepare-render-instructions.h>
-
-namespace Dali
-{
-namespace Internal
-{
-
-namespace SceneGraph
-{
-
-class RenderTaskList;
-
-/**
- * Process the list of render-tasks; the output is a series of render instructions.
- * @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render.
- * If there is only one default render-task, then no further processing is required.
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] renderTasks The list of render-tasks.
- * @param[in] rootNode The root node of the scene-graph.
- * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables.
- * @param[in] sortingHelper Helper container for sorting transparent renderables.
- * @param[in] geometryBatcher The instance of the geometry batcher
- * @param[out] instructions The instructions for rendering the next frame.
- */
-void ProcessRenderTasks( BufferIndex updateBufferIndex,
- RenderTaskList& renderTasks,
- Layer& rootNode,
- SortedLayerPointers& sortedLayers,
- RendererSortingHelper& sortingHelper,
- GeometryBatcher& geometryBatcher,
- RenderInstructionContainer& instructions );
-
-} // namespace SceneGraph
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__
--- /dev/null
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/update/manager/render-instruction-processor.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali/integration-api/debug.h>
+#include <dali/internal/event/actors/layer-impl.h> // for the default sorting function
+#include <dali/internal/update/manager/sorted-layers.h>
+#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
+#include <dali/internal/update/rendering/scene-graph-texture-set.h>
+#include <dali/internal/update/resources/resource-manager-declarations.h>
+#include <dali/internal/render/common/render-item.h>
+#include <dali/internal/render/common/render-tracker.h>
+#include <dali/internal/render/common/render-instruction.h>
+#include <dali/internal/render/common/render-instruction-container.h>
+#include <dali/internal/render/shaders/scene-graph-shader.h>
+#include <dali/internal/render/renderers/render-renderer.h>
+#include <dali/internal/render/renderers/render-property-buffer.h>
+#include <dali/internal/update/manager/geometry-batcher.h>
+#include <dali/internal/update/nodes/scene-graph-layer.h>
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS");
+#endif
+}
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace SceneGraph
+{
+
+namespace
+{
+
+/**
+ * Function which sorts render items by depth index then by instance
+ * ptrs of shader/geometry/material.
+ * @param[in] lhs Left hand side item
+ * @param[in] rhs Right hand side item
+ * @return True if left item is greater than right
+ */
+bool CompareItems( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs )
+{
+ // @todo Consider replacing all these sortAttributes with a single long int that
+ // encapsulates the same data (e.g. the middle-order bits of the ptrs).
+ if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex )
+ {
+ if( lhs.shader == rhs.shader )
+ {
+ if( lhs.textureResourceId == rhs.textureResourceId )
+ {
+ return lhs.geometry < rhs.geometry;
+ }
+ return lhs.textureResourceId < rhs.textureResourceId;
+ }
+ return lhs.shader < rhs.shader;
+ }
+ return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex;
+}
+
+/**
+ * Function which sorts render items by clipping hierarchy, then depth index and instance
+ * ptrs of shader/geometry/material.
+ * @param[in] lhs Left hand side item
+ * @param[in] rhs Right hand side item
+ * @return True if left item is greater than right
+ */
+bool CompareItemsWithClipping( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs )
+{
+ // Items must be sorted in order of clipping first, otherwise incorrect clipping regions could be used.
+ if( lhs.renderItem->mNode->mClippingSortModifier == rhs.renderItem->mNode->mClippingSortModifier )
+ {
+ return CompareItems( lhs, rhs );
+ }
+
+ return lhs.renderItem->mNode->mClippingSortModifier < rhs.renderItem->mNode->mClippingSortModifier;
+}
+
+/**
+ * Function which sorts the render items by Z function, then
+ * by instance ptrs of shader / geometry / material.
+ * @param[in] lhs Left hand side item
+ * @param[in] rhs Right hand side item
+ * @return True if left item is greater than right
+ */
+bool CompareItems3D( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs )
+{
+ bool lhsIsOpaque = lhs.renderItem->mIsOpaque;
+ if( lhsIsOpaque == rhs.renderItem->mIsOpaque )
+ {
+ if( lhsIsOpaque )
+ {
+ // If both RenderItems are opaque, sort using shader, then material then geometry.
+ if( lhs.shader == rhs.shader )
+ {
+ if( lhs.textureResourceId == rhs.textureResourceId )
+ {
+ return lhs.geometry < rhs.geometry;
+ }
+ return lhs.textureResourceId < rhs.textureResourceId;
+ }
+ return lhs.shader < rhs.shader;
+ }
+ else
+ {
+ // If both RenderItems are transparent, sort using Z, then shader, then material, then geometry.
+ if( Equals( lhs.zValue, rhs.zValue ) )
+ {
+ if( lhs.shader == rhs.shader )
+ {
+ if( lhs.textureResourceId == rhs.textureResourceId )
+ {
+ return lhs.geometry < rhs.geometry;
+ }
+ return lhs.textureResourceId < rhs.textureResourceId;
+ }
+ return lhs.shader < rhs.shader;
+ }
+ return lhs.zValue > rhs.zValue;
+ }
+ }
+ else
+ {
+ return lhsIsOpaque;
+ }
+}
+
+/**
+ * Function which sorts render items by clipping hierarchy, then Z function and instance ptrs of shader / geometry / material.
+ * @param[in] lhs Left hand side item
+ * @param[in] rhs Right hand side item
+ * @return True if left item is greater than right
+ */
+bool CompareItems3DWithClipping( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs )
+{
+ // Items must be sorted in order of clipping first, otherwise incorrect clipping regions could be used.
+ if( lhs.renderItem->mNode->mClippingSortModifier == rhs.renderItem->mNode->mClippingSortModifier )
+ {
+ return CompareItems3D( lhs, rhs );
+ }
+
+ return lhs.renderItem->mNode->mClippingSortModifier < rhs.renderItem->mNode->mClippingSortModifier;
+}
+
+/**
+ * Add a renderer to the list
+ * @param updateBufferIndex to read the model matrix from
+ * @param renderList to add the item to
+ * @param renderable Node-Renderer pair
+ * @param viewMatrix used to calculate modelview matrix for the item
+ * @param camera The camera used to render
+ * @param geometryBatcher The instance of the geometry batcher
+ * @param isLayer3d Whether we are processing a 3D layer or not
+ * @param cull Whether frustum culling is enabled or not
+ */
+inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
+ RenderList& renderList,
+ Renderable& renderable,
+ const Matrix& viewMatrix,
+ SceneGraph::Camera& camera,
+ GeometryBatcher& geometryBatcher,
+ bool isLayer3d,
+ bool cull )
+{
+ // Discard renderable early if it belongs to the batch which has been consumed in during frame.
+ Node* renderableNode = renderable.mNode;
+ const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE );
+ if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) )
+ {
+ return;
+ }
+
+ bool inside( true );
+ const Node* batchParentNode = renderable.mNode->GetBatchParent();
+ const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ?
+ batchParentNode : renderableNode;
+
+ if( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
+ {
+ const Vector4& boundingSphere = node->GetBoundingSphere();
+ inside = ( boundingSphere.w > Math::MACHINE_EPSILON_1000 ) &&
+ ( camera.CheckSphereInFrustum( updateBufferIndex, Vector3( boundingSphere ), boundingSphere.w ) );
+ }
+
+ if( inside )
+ {
+ if( batchingValid )
+ {
+ geometryBatcher.SetRendered( renderableNode->mBatchIndex );
+ }
+
+ Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode );
+ if( opacity != Renderer::TRANSPARENT )
+ {
+ // Get the next free RenderItem.
+ RenderItem& item = renderList.GetNextFreeItem();
+ item.mRenderer = &renderable.mRenderer->GetRenderer();
+ item.mNode = renderable.mNode;
+ item.mIsOpaque = ( opacity == Renderer::OPAQUE );
+ item.mDepthIndex = renderable.mRenderer->GetDepthIndex();
+
+ if( !isLayer3d )
+ {
+ item.mDepthIndex += static_cast<int>( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER;
+ }
+
+ // Save ModelView matrix onto the item.
+ node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
+
+ Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
+ }
+ }
+}
+
+/**
+ * Add all renderers to the list
+ * @param updateBufferIndex to read the model matrix from
+ * @param renderList to add the items to
+ * @param renderers to render
+ * NodeRendererContainer Node-Renderer pairs
+ * @param viewMatrix used to calculate modelview matrix for the items
+ * @param camera The camera used to render
+ * @param geometryBatcher The instance of the geometry batcher
+ * @param isLayer3d Whether we are processing a 3D layer or not
+ * @param cull Whether frustum culling is enabled or not
+ */
+inline void AddRenderersToRenderList( BufferIndex updateBufferIndex,
+ RenderList& renderList,
+ RenderableContainer& renderers,
+ const Matrix& viewMatrix,
+ SceneGraph::Camera& camera,
+ GeometryBatcher* geometryBatcher,
+ bool isLayer3d,
+ bool cull )
+{
+ DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n");
+
+ unsigned int rendererCount( renderers.Size() );
+ for( unsigned int i(0); i < rendererCount; ++i )
+ {
+ AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, *geometryBatcher, isLayer3d, cull );
+ }
+}
+
+/**
+ * Try to reuse cached RenderItems from the RenderList
+ * This avoids recalculating the model view matrices in case this part of the scene was static
+ * An example case is a toolbar layer that rarely changes or a popup on top of the rest of the stage
+ * @param layer that is being processed
+ * @param renderList that is cached from frame N-1
+ * @param renderables list of renderables
+ */
+inline bool TryReuseCachedRenderers( Layer& layer,
+ RenderList& renderList,
+ RenderableContainer& renderables )
+{
+ bool retValue = false;
+ size_t renderableCount = renderables.Size();
+ // Check that the cached list originates from this layer and that the counts match
+ if( ( renderList.GetSourceLayer() == &layer )&&
+ ( renderList.GetCachedItemCount() == renderableCount ) )
+ {
+ // Check that all the same renderers are there. This gives us additional security in avoiding rendering the wrong things.
+ // Render list is sorted so at this stage renderers may be in different order.
+ // Therefore we check a combined sum of all renderer addresses.
+ size_t checkSumNew = 0;
+ size_t checkSumOld = 0;
+ for( size_t index = 0; index < renderableCount; ++index )
+ {
+ const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer();
+ checkSumNew += size_t( &renderer );
+ checkSumOld += size_t( &renderList.GetRenderer( index ) );
+ }
+ if( checkSumNew == checkSumOld )
+ {
+ // tell list to reuse its existing items
+ renderList.ReuseCachedItems();
+ retValue = true;
+ }
+ }
+ return retValue;
+}
+
+inline bool SetupRenderList( RenderableContainer& renderables,
+ Layer& layer,
+ RenderInstruction& instruction,
+ bool tryReuseRenderList,
+ RenderList** renderList )
+{
+ *renderList = &( instruction.GetNextFreeRenderList( renderables.Size() ) );
+ ( *renderList )->SetClipping( layer.IsClipping(), layer.GetClippingBox() );
+ ( *renderList )->SetSourceLayer( &layer );
+
+ // Try to reuse cached RenderItems from last time around.
+ return ( tryReuseRenderList && TryReuseCachedRenderers( layer, **renderList, renderables ) );
+}
+
+} // Anonymous namespace.
+
+
+RenderInstructionProcessor::RenderInstructionProcessor()
+: mSortingHelper()
+{
+ // Set up a container of comparators for fast run-time selection.
+ mSortComparitors.Reserve( 4u );
+
+ mSortComparitors.PushBack( CompareItems );
+ mSortComparitors.PushBack( CompareItemsWithClipping );
+ mSortComparitors.PushBack( CompareItems3D );
+ mSortComparitors.PushBack( CompareItems3DWithClipping );
+}
+
+RenderInstructionProcessor::~RenderInstructionProcessor()
+{
+}
+
+inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder )
+{
+ const size_t renderableCount = renderList.Count();
+ // Reserve space if needed.
+ const unsigned int oldcapacity = mSortingHelper.size();
+ if( oldcapacity < renderableCount )
+ {
+ mSortingHelper.reserve( renderableCount );
+ // Add real objects (reserve does not construct objects).
+ mSortingHelper.insert( mSortingHelper.begin() + oldcapacity,
+ (renderableCount - oldcapacity),
+ RenderInstructionProcessor::SortAttributes() );
+ }
+ else
+ {
+ // Clear extra elements from helper, does not decrease capability.
+ mSortingHelper.resize( renderableCount );
+ }
+
+ // 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() )
+ {
+ for( size_t index = 0; index < renderableCount; ++index )
+ {
+ RenderItem& item = renderList.GetItem( index );
+
+ item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] );
+
+ // The default sorting function should get inlined here.
+ mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
+
+ // Keep the renderitem pointer in the helper so we can quickly reorder items after sort.
+ mSortingHelper[ index ].renderItem = &item;
+ }
+ }
+ else
+ {
+ const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction();
+ for( size_t index = 0; index < renderableCount; ++index )
+ {
+ RenderItem& item = renderList.GetItem( index );
+
+ item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] );
+ mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
+
+ // Keep the RenderItem pointer in the helper so we can quickly reorder items after sort.
+ mSortingHelper[ index ].renderItem = &item;
+ }
+ }
+
+ // Here we detemine which comparitor (of the 4) to use.
+ // The comparitors work like a bitmask.
+ // 1 << 0 is added to select a clipping comparitor.
+ // 1 << 1 is added for 3D comparitors.
+ const unsigned int comparitorIndex = ( respectClippingOrder ? ( 1u << 0u ) : 0u ) |
+ ( layer.GetBehavior() == Dali::Layer::LAYER_3D ? ( 1u << 1u ) : 0u );
+
+ std::stable_sort( mSortingHelper.begin(), mSortingHelper.end(), mSortComparitors[ comparitorIndex ] );
+
+ // Reorder / re-populate the RenderItems in the RenderList to correct order based on the sortinghelper.
+ DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n");
+ RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin();
+ for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter )
+ {
+ *renderListIter = mSortingHelper[ index ].renderItem;
+ DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, mSortingHelper[ index ].renderItem->mRenderer);
+ }
+}
+
+void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex,
+ SortedLayerPointers& sortedLayers,
+ RenderTask& renderTask,
+ bool cull,
+ GeometryBatcher& geometryBatcher,
+ bool hasClippingNodes,
+ RenderInstructionContainer& instructions )
+{
+ // Retrieve the RenderInstruction buffer from the RenderInstructionContainer
+ // then populate with instructions.
+ RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex );
+ renderTask.PrepareRenderInstruction( instruction, updateBufferIndex );
+ bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated();
+
+ const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex );
+ SceneGraph::Camera& camera = renderTask.GetCamera();
+
+ const SortedLayersIter endIter = sortedLayers.end();
+ for( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter )
+ {
+ Layer& layer = **iter;
+ const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers( &renderTask.GetCamera() ) );
+ const bool isLayer3D = layer.GetBehavior() == Dali::Layer::LAYER_3D;
+ RenderList* renderList = NULL;
+
+ if( !layer.colorRenderables.Empty() )
+ {
+ RenderableContainer& renderables = layer.colorRenderables;
+
+ if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) )
+ {
+ renderList->SetHasColorRenderItems( true );
+ AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, &geometryBatcher, isLayer3D, cull );
+
+ // We only use the clipping version of the sort comparitor if any clipping nodes exist within the RenderList.
+ SortRenderItems( updateBufferIndex, *renderList, layer, hasClippingNodes );
+ }
+ }
+
+ if( !layer.overlayRenderables.Empty() )
+ {
+ RenderableContainer& renderables = layer.overlayRenderables;
+
+ if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) )
+ {
+ renderList->SetHasColorRenderItems( false );
+ AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, NULL, isLayer3D, cull );
+
+ // Clipping hierarchy is irrelevant when sorting overlay items, so we specify using the non-clipping version of the sort comparitor.
+ SortRenderItems( updateBufferIndex, *renderList, layer, false );
+ }
+ }
+ }
+
+ // Inform the render instruction that all renderers have been added and this frame is complete.
+ instruction.UpdateCompleted();
+}
+
+
+} // SceneGraph
+
+} // Internal
+
+} // Dali
--- /dev/null
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/common/buffer-index.h>
+#include <dali/internal/update/manager/sorted-layers.h>
+#include <dali/integration-api/resource-declarations.h>
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Render
+{
+class Geometry;
+}
+
+namespace SceneGraph
+{
+
+class RenderTracker;
+struct RenderItem;
+class Shader;
+class GeometryBatcher;
+struct RenderList;
+class RenderTask;
+class RenderInstructionContainer;
+
+
+/**
+ * @brief This class handles the sorting and preparation of Renderers for each layer.
+ */
+class RenderInstructionProcessor
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ RenderInstructionProcessor();
+
+ /**
+ * @brief Destructor.
+ */
+ ~RenderInstructionProcessor();
+
+ /**
+ * @brief Structure to store information for sorting the renderers.
+ * (Note, depthIndex is stored within the renderItem).
+ */
+ struct SortAttributes
+ {
+ SortAttributes()
+ : renderItem( NULL ),
+ shader( NULL ),
+ textureResourceId( Integration::InvalidResourceId ),
+ geometry( NULL ),
+ zValue( 0.0f )
+ {
+ }
+
+ RenderItem* renderItem; ///< The render item that is being sorted (includes depth index)
+ const Shader* shader; ///< The shader instance
+ Integration::ResourceId textureResourceId; ///< The first texture resource ID of the texture set instance, is InvalidResourceId if the texture set doesn't have any textures
+ const Render::Geometry* geometry; ///< The geometry instance
+ float zValue; ///< The Z value of the given renderer (either distance from camera, or a custom calculated value)
+ };
+
+
+ /**
+ * @brief Sorts and prepares the list of opaque/transparent Renderers for each layer.
+ * Whilst iterating through each layer, update the RenderItems ModelView matrices
+ *
+ * The opaque and transparent render lists are sorted first by depth
+ * index, then by Z (for transparent only), then by shader, texture
+ * and geometry. The render algorithm should then work through both
+ * lists simultaneously, working through opaque then transparent
+ * items at each depth index, resetting the flags appropriately.
+ *
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables.
+ * @param[in] renderTask The rendering task information.
+ * @param[in] cull Whether frustum culling is enabled or not
+ * @param[in] geometryBatcher The instance of the geometry batcher
+ * @param[in] hasClippingNodes Whether any clipping nodes exist within this layer, to optimize sorting if not
+ * @param[out] instructions The rendering instructions for the next frame.
+ */
+ void Prepare( BufferIndex updateBufferIndex,
+ SortedLayerPointers& sortedLayers,
+ RenderTask& renderTask,
+ bool cull,
+ GeometryBatcher& geometryBatcher,
+ bool hasClippingNodes,
+ RenderInstructionContainer& instructions );
+
+private:
+
+ /**
+ * Undefine copy and assignment operators.
+ */
+ RenderInstructionProcessor( const RenderInstructionProcessor& renderInstructionProcessor ); ///< No definition
+ RenderInstructionProcessor& operator=( const RenderInstructionProcessor& renderInstructionProcessor ); ///< No definition
+
+private:
+
+ /**
+ * @brief Sort render items
+ * @param bufferIndex The buffer to read from
+ * @param renderList to sort
+ * @param layer where the Renderers are from
+ * @param respectClippingOrder Sort with the correct clipping hierarchy.
+ */
+ inline void SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder );
+
+ /// Sort comparitor function pointer type.
+ typedef bool ( *ComparitorPointer )( const SortAttributes& lhs, const SortAttributes& rhs );
+ typedef std::vector< SortAttributes > SortingHelper;
+
+ Dali::Vector< ComparitorPointer > mSortComparitors; ///< Contains all sort comparitors, used for quick look-up
+ RenderInstructionProcessor::SortingHelper mSortingHelper; ///< Helper used to sort Renderers
+
+};
+
+
+} // namespace SceneGraph
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H
*/
// CLASS HEADER
-#include <dali/internal/update/manager/process-render-tasks.h>
+#include <dali/internal/update/manager/render-task-processor.h>
// INTERNAL INCLUDES
-#include <dali/internal/update/manager/prepare-render-instructions.h>
#include <dali/internal/update/manager/sorted-layers.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
namespace //Unnamed namespace
{
-// Return false if the node or it's parents are exclusive to another render-task
+// Return false if the node or it's parents are exclusive to another render-task.
bool CheckExclusivity( const Node& node, const RenderTask& task )
{
const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
- if ( exclusiveTo )
+ if( exclusiveTo )
{
- if ( exclusiveTo == &task )
- {
- // Exclusive to the same render-task
- return true;
- }
- else
- {
- // Exclusive to another render-task
- return false;
- }
+ return ( exclusiveTo == &task );
}
const Node* parent = node.GetParent();
return CheckExclusivity( *parent, task );
}
- // No exclusive flags set
+ // No exclusive flags set.
return true;
}
Layer* FindLayer( Node& node )
{
Node* currentNode( &node );
- Layer* layer(NULL);
+ Layer* layer( NULL );
while( currentNode )
{
- if( (layer = currentNode->GetLayer()) != NULL )
+ if( ( layer = currentNode->GetLayer() ) != NULL )
{
return layer;
}
}
/**
- * Rebuild the Layer::colorRenderables, stencilRenderables and overlayRenderables members,
+ * Rebuild the Layer::colorRenderables and overlayRenderables members,
* including only renderers which are included in the current render-task.
* Returns true if all renderers have finished acquiring resources.
+ *
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] node The current node of the scene-graph.
+ * @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] 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
*/
bool AddRenderablesForTask( BufferIndex updateBufferIndex,
Node& node,
Layer& currentLayer,
RenderTask& renderTask,
- int inheritedDrawMode )
+ int inheritedDrawMode,
+ uint32_t& currentClippingId,
+ uint32_t clippingDepth )
{
bool resourcesFinished = true;
// Short-circuit for invisible nodes
- if ( !node.IsVisible( updateBufferIndex ) )
+ if( !node.IsVisible( updateBufferIndex ) )
{
return resourcesFinished;
}
// Check whether node is exclusive to a different render-task
const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
- if ( exclusiveTo &&
- exclusiveTo != &renderTask )
+ if( exclusiveTo && ( exclusiveTo != &renderTask ) )
{
return resourcesFinished;
}
- Layer* layer = ¤tLayer;
- Layer* nodeIsLayer( node.GetLayer() );
- if ( nodeIsLayer )
+ // Assume all children go to this layer (if this node is a layer).
+ Layer* layer = node.GetLayer();
+ if( layer )
{
- // All children go to this layer
- layer = nodeIsLayer;
-
// Layers do not inherit the DrawMode from their parents
- inheritedDrawMode = DrawMode::NORMAL;
+ inheritedDrawMode = node.GetDrawMode();
+ }
+ else
+ {
+ // This node is not a layer.
+ layer = ¤tLayer;
+ inheritedDrawMode |= node.GetDrawMode();
}
+
DALI_ASSERT_DEBUG( NULL != layer );
- inheritedDrawMode |= node.GetDrawMode();
+ // Update the clipping Id and depth for this node (if clipping is enabled).
+ if( DALI_UNLIKELY( node.GetClippingMode() != ClippingMode::DISABLED ) )
+ {
+ ++currentClippingId; // This modifies the reference passed in as well as the local value, causing the value to be global to the recursion.
+ ++clippingDepth; // This only modifies the local value (which is passed in when the method recurses).
+ }
+ // Set the information in the node.
+ node.SetClippingInformation( currentClippingId, clippingDepth );
const unsigned int count = node.GetRendererCount();
for( unsigned int i = 0; i < count; ++i )
bool complete = false;
renderer->GetReadyAndComplete( ready, complete );
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready?"T":"F", complete?"T":"F");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready ? "T" : "F", complete ? "T" : "F" );
resourcesFinished &= complete;
- if( ready ) // i.e. should be rendered (all resources are available)
+ if( ready ) // IE. should be rendered (all resources are available)
{
- if( DrawMode::STENCIL == inheritedDrawMode )
- {
- layer->stencilRenderables.PushBack( Renderable(&node, renderer ) );
- }
- else if( DrawMode::OVERLAY_2D == inheritedDrawMode )
+ // Normal is the more-likely draw mode to occur.
+ if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) )
{
- layer->overlayRenderables.PushBack( Renderable(&node, renderer ) );
+ layer->colorRenderables.PushBack( Renderable( &node, renderer ) );
}
else
{
- layer->colorRenderables.PushBack( Renderable(&node, renderer ) );
+ layer->overlayRenderables.PushBack( Renderable( &node, renderer ) );
}
}
}
- // Recurse children
+ // Recurse children.
NodeContainer& children = node.GetChildren();
const NodeIter endIter = children.End();
- for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
+ for( NodeIter iter = children.Begin(); iter != endIter; ++iter )
{
Node& child = **iter;
- bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode );
+ bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth );
resourcesFinished &= childResourcesComplete;
}
return resourcesFinished;
}
-} //Unnamed namespace
-
-void ProcessRenderTasks( BufferIndex updateBufferIndex,
- RenderTaskList& renderTasks,
- Layer& rootNode,
- SortedLayerPointers& sortedLayers,
- RendererSortingHelper& sortingHelper,
- GeometryBatcher& geometryBatcher,
- RenderInstructionContainer& instructions )
+
+} // Anonymous namespace.
+
+
+RenderTaskProcessor::RenderTaskProcessor()
+{
+}
+
+RenderTaskProcessor::~RenderTaskProcessor()
+{
+}
+
+void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
+ RenderTaskList& renderTasks,
+ Layer& rootNode,
+ SortedLayerPointers& sortedLayers,
+ GeometryBatcher& geometryBatcher,
+ RenderInstructionContainer& instructions )
{
RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
- if ( taskContainer.IsEmpty() )
+ if( taskContainer.IsEmpty() )
{
// Early-exit if there are no tasks to process
return;
// 3) Traverse the scene-graph, filling the lists for the current render-task
// 4) Prepare render-instructions
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Offscreens first\n");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Offscreens first\n" );
// First process off screen render tasks - we may need the results of these for the on screen renders
+ uint32_t clippingId = 0u;
+ bool hasClippingNodes = false;
+
RenderTaskList::RenderTaskContainer::ConstIterator endIter = taskContainer.End();
- for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
+ for( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
- // off screen only
- if(0 == renderTask.GetFrameBufferId() && renderTask.GetFrameBuffer() == 0 )
+ // Off screen only.
+ if( ( ( 0 == renderTask.GetFrameBufferId() ) && ( renderTask.GetFrameBuffer() == 0 ) ) ||
+ ( !renderTask.ReadyToRender( updateBufferIndex ) ) )
{
- // Skip to next task
- continue;
- }
-
- if ( !renderTask.ReadyToRender( updateBufferIndex ) )
- {
- // Skip to next task
+ // Skip to next task.
continue;
}
Node* sourceNode = renderTask.GetSourceNode();
- DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false
+ DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false
- // Check that the source node is not exclusive to another task
- if ( ! CheckExclusivity( *sourceNode, renderTask ) )
+ // Check that the source node is not exclusive to another task.
+ if( ! CheckExclusivity( *sourceNode, renderTask ) )
{
continue;
}
Layer* layer = FindLayer( *sourceNode );
if( !layer )
{
- // Skip to next task as no layer
+ // Skip to next task as no layer.
continue;
}
*sourceNode,
*layer,
renderTask,
- sourceNode->GetDrawMode() );
+ sourceNode->GetDrawMode(),
+ clippingId,
+ 0u );
renderTask.SetResourcesFinished( resourcesFinished );
- PrepareRenderInstruction( updateBufferIndex,
- sortedLayers,
- renderTask,
- sortingHelper,
- renderTask.GetCullMode(),
- instructions,
- geometryBatcher );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0u;
+
+ mRenderInstructionProcessor.Prepare( updateBufferIndex,
+ sortedLayers,
+ renderTask,
+ renderTask.GetCullMode(),
+ geometryBatcher,
+ hasClippingNodes,
+ instructions );
}
else
{
}
}
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Onscreen\n");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n" );
- // Now that the off screen renders are done we can process on screen render tasks
+ // Now that the off screen renders are done we can process on screen render tasks.
+ // Reset the clipping Id for the OnScreen render tasks.
+ clippingId = 0u;
for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
- // on screen only
- if(0 != renderTask.GetFrameBufferId() || renderTask.GetFrameBuffer() != 0 )
+ // On screen only.
+ if( ( 0 != renderTask.GetFrameBufferId() ) ||
+ ( renderTask.GetFrameBuffer() != 0 ) ||
+ ( !renderTask.ReadyToRender( updateBufferIndex ) ) )
{
- // Skip to next task
- continue;
- }
- if ( !renderTask.ReadyToRender( updateBufferIndex ) )
- {
- // Skip to next task
+ // Skip to next task.
continue;
}
Node* sourceNode = renderTask.GetSourceNode();
- DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false
+ DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false.
- // Check that the source node is not exclusive to another task
- if ( ! CheckExclusivity( *sourceNode, renderTask ) )
+ // Check that the source node is not exclusive to another task.
+ if( ! CheckExclusivity( *sourceNode, renderTask ) )
{
continue;
}
Layer* layer = FindLayer( *sourceNode );
if( !layer )
{
- // Skip to next task as no layer
+ // Skip to next task as no layer.
continue;
}
if( renderTask.IsRenderRequired() )
{
size_t layerCount( sortedLayers.size() );
- for( size_t i(0); i<layerCount; ++i )
+ for( size_t i(0); i < layerCount; ++i )
{
sortedLayers[i]->ClearRenderables();
}
*sourceNode,
*layer,
renderTask,
- sourceNode->GetDrawMode() );
-
- PrepareRenderInstruction( updateBufferIndex,
- sortedLayers,
- renderTask,
- sortingHelper,
- renderTask.GetCullMode(),
- instructions,
- geometryBatcher );
+ sourceNode->GetDrawMode(),
+ clippingId,
+ 0u );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0;
+
+ mRenderInstructionProcessor.Prepare( updateBufferIndex,
+ sortedLayers,
+ renderTask,
+ renderTask.GetCullMode(),
+ geometryBatcher,
+ hasClippingNodes,
+ instructions );
}
renderTask.SetResourcesFinished( resourcesFinished );
--- /dev/null
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H
+
+/*
+ * Copyright (c) 2016 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/update/manager/sorted-layers.h>
+#include <dali/internal/update/manager/render-instruction-processor.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace SceneGraph
+{
+
+class RenderTaskList;
+
+/**
+ * @brief This class handles processing a given list of render tasks and generating render instructions from them.
+ */
+class RenderTaskProcessor
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ RenderTaskProcessor();
+
+ /**
+ * @brief Destructor.
+ */
+ ~RenderTaskProcessor();
+
+ /**
+ * Process the list of render-tasks; the output is a series of render instructions.
+ * @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render.
+ * If there is only one default render-task, then no further processing is required.
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] renderTasks The list of render-tasks.
+ * @param[in] rootNode The root node of the scene-graph.
+ * @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
+ * @param[in] geometryBatcher The instance of the geometry batcher
+ * @param[out] instructions The instructions for rendering the next frame.
+ */
+ void Process( BufferIndex updateBufferIndex,
+ RenderTaskList& renderTasks,
+ Layer& rootNode,
+ SortedLayerPointers& sortedLayers,
+ GeometryBatcher& geometryBatcher,
+ RenderInstructionContainer& instructions );
+
+private:
+
+ /**
+ * Undefine copy and assignment operators.
+ */
+ RenderTaskProcessor( const RenderTaskProcessor& renderTaskProcessor ); ///< No definition
+ RenderTaskProcessor& operator=( const RenderTaskProcessor& renderTaskProcessor ); ///< No definition
+
+private:
+
+ RenderInstructionProcessor mRenderInstructionProcessor; ///< An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer.
+};
+
+
+} // namespace SceneGraph
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H
UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
- // Setting STENCIL will override OVERLAY_2D, if that would otherwise have been inherited.
+ // Draw mode inheritance is treated as or-ing the modes together (as they are a bit-mask).
inheritedDrawMode |= node.GetDrawMode();
node.PrepareRender( updateBufferIndex );
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/public-api/math/radian.h>
#include <dali/public-api/math/vector2.h>
+#ifdef DALI_PRINT_UPDATE_INFO
+
namespace Dali
{
*/
void PrintNodes( const Node& node, BufferIndex updateBufferIndex, int level )
{
-#if defined(DEBUG_ENABLED)
const Vector3& position = node.GetPosition(updateBufferIndex);
const Vector3& scale = node.GetScale(updateBufferIndex);
const Vector3& fullPos = node.GetWorldPosition(updateBufferIndex);
{
PrintNodes(**iter, updateBufferIndex, level);
}
-#endif // DEBUG_ENABLED
}
void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string indentation )
{
-#if defined(DEBUG_ENABLED)
-
std::cout << "Node " << &node
<< " \"" << node.mDebugString << "\""
<< " Origin: " << node.GetParentOrigin()
PrintNodeTree(**iter, bufferIndex, nextIndent);
}
-
-#endif // DEBUG_ENABLED
}
} // SceneGraph
} // Internal
} // Dali
+
+#endif
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H
+#define DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/internal/update/nodes/node.h>
#include <dali/integration-api/debug.h>
+// Define this to access debug functions for the update manager.
+#undef DALI_PRINT_UPDATE_INFO
+
+#ifdef DALI_PRINT_UPDATE_INFO
+
namespace Dali
{
} // Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__
+#endif
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H
#include <dali/internal/update/controllers/scene-controller-impl.h>
#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
#include <dali/internal/update/manager/object-owner-container.h>
-#include <dali/internal/update/manager/process-render-tasks.h>
+#include <dali/internal/update/manager/render-task-processor.h>
#include <dali/internal/update/manager/sorted-layers.h>
#include <dali/internal/update/manager/update-algorithms.h>
#include <dali/internal/update/manager/update-manager-debug.h>
RenderManager& renderManager,
RenderQueue& renderQueue,
SceneGraphBuffers& sceneGraphBuffers,
- GeometryBatcher& geometryBatcher )
+ GeometryBatcher& geometryBatcher,
+ RenderTaskProcessor& renderTaskProcessor )
: renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
notificationManager( notificationManager ),
transformManager(),
renderQueue( renderQueue ),
renderInstructions( renderManager.GetRenderInstructionContainer() ),
geometryBatcher( geometryBatcher ),
+ renderTaskProcessor( renderTaskProcessor ),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
taskList( renderMessageDispatcher, resourceManager ),
systemLevelTaskList( renderMessageDispatcher, resourceManager ),
nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
previousUpdateScene( false ),
frameCounter( 0 ),
- renderSortingHelper(),
renderTaskWaiting( false )
{
sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
RenderQueue& renderQueue; ///< Used to queue messages for the next render
RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher
+ RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
ObjectOwnerContainer<Renderer> renderers;
- TextureSetContainer textureSets; ///< A container of texture sets
+ TextureSetContainer textureSets; ///< A container of texture sets
ShaderContainer shaders; ///< A container of owned shaders
bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
- RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
GestureContainer gestures; ///< A container of owned gesture detectors
bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
RenderManager& renderManager,
RenderQueue& renderQueue,
TextureCacheDispatcher& textureCacheDispatcher,
- GeometryBatcher& geometryBatcher )
+ GeometryBatcher& geometryBatcher,
+ RenderTaskProcessor& renderTaskProcessor )
: mImpl(NULL)
{
mImpl = new Impl( notificationManager,
renderManager,
renderQueue,
mSceneGraphBuffers,
- geometryBatcher );
+ geometryBatcher,
+ renderTaskProcessor );
textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
mImpl->geometryBatcher.SetUpdateManager( this );
if ( NULL != mImpl->root )
{
- ProcessRenderTasks( bufferIndex,
- mImpl->taskList,
- *mImpl->root,
- mImpl->sortedLayers,
- mImpl->renderSortingHelper,
- mImpl->geometryBatcher,
- mImpl->renderInstructions );
+ mImpl->renderTaskProcessor.Process( bufferIndex,
+ mImpl->taskList,
+ *mImpl->root,
+ mImpl->sortedLayers,
+ mImpl->geometryBatcher,
+ mImpl->renderInstructions );
// Process the system-level RenderTasks last
if ( NULL != mImpl->systemLevelRoot )
{
- ProcessRenderTasks( bufferIndex,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
- mImpl->renderSortingHelper,
- mImpl->geometryBatcher,
- mImpl->renderInstructions );
+ mImpl->renderTaskProcessor.Process( bufferIndex,
+ mImpl->systemLevelTaskList,
+ *mImpl->systemLevelRoot,
+ mImpl->systemLevelSortedLayers,
+ mImpl->geometryBatcher,
+ mImpl->renderInstructions );
}
}
}
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H
+#define DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H
/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
class PanGesture;
class RenderManager;
class RenderTaskList;
+class RenderTaskProcessor;
class RenderQueue;
class TextureCacheDispatcher;
class PropertyBuffer;
* @param[in] renderQueue Used to queue messages for the next render.
* @param[in] textureCacheDispatcher Used for sending messages to texture cache.
* @param[in] geometryBatcher Used when geometry batching is enabled.
+ * @param[in] renderTaskProcessor Handles RenderTasks and RenderInstrucitons.
*/
UpdateManager( NotificationManager& notificationManager,
CompleteNotificationInterface& animationFinishedNotifier,
RenderManager& renderManager,
RenderQueue& renderQueue,
TextureCacheDispatcher& textureCacheDispatcher,
- GeometryBatcher& geometryBatcher );
+ GeometryBatcher& geometryBatcher,
+ RenderTaskProcessor& renderTaskProcessor );
/**
* Destructor.
new (slot) LocalType( &manager, &UpdateManager::AttachColorTextureToFrameBuffer, &frameBuffer, texture, mipmapLevel, layer );
}
+
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H
mTransformId( INVALID_TRANSFORM_ID ),
mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ),
mAnchorPoint( TRANSFORM_PROPERTY_ANCHOR_POINT ),
- mSize(TRANSFORM_PROPERTY_SIZE), // zero initialized by default
- mPosition(TRANSFORM_PROPERTY_POSITION), // zero initialized by default
- mOrientation(), // initialized to identity by default
+ mSize( TRANSFORM_PROPERTY_SIZE ), // Zero initialized by default
+ mPosition( TRANSFORM_PROPERTY_POSITION ), // Zero initialized by default
+ mOrientation(), // Initialized to identity by default
mScale( TRANSFORM_PROPERTY_SCALE ),
mVisible( true ),
mColor( Color::WHITE ),
- mWorldPosition(TRANSFORM_PROPERTY_WORLD_POSITION, Vector3(0.0f,0.0f,0.0f)), // zero initialized by default
- mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3(1.0f,1.0f,1.0f) ),
- mWorldOrientation(), // initialized to identity by default
+ mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default
+ mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ),
+ mWorldOrientation(), // Initialized to identity by default
mWorldMatrix(),
mWorldColor( Color::WHITE ),
mGeometryBatcher( NULL ),
mBatchIndex( BATCH_NULL_HANDLE ),
+ mClippingSortModifier( 0u ),
mIsBatchParent( false ),
mParent( NULL ),
mBatchParent( NULL ),
mExclusiveRenderTask( NULL ),
mChildren(),
+ mClippingDepth( 0u ),
mRegenerateUniformMap( 0 ),
- mDepth(0u),
- mDirtyFlags(AllFlags),
- mIsRoot( false ),
+ mDepth( 0u ),
+ mDirtyFlags( AllFlags ),
mDrawMode( DrawMode::NORMAL ),
- mColorMode( DEFAULT_COLOR_MODE )
+ mColorMode( DEFAULT_COLOR_MODE ),
+ mClippingMode( ClippingMode::DISABLED ),
+ mIsRoot( false )
{
mUniformMapChanged[0] = 0u;
mUniformMapChanged[1] = 0u;
void Node::AddRenderer( Renderer* renderer )
{
- //Check that it has not been already added
+ // Check that it has not been already added.
unsigned int rendererCount( mRenderer.Size() );
- for( unsigned int i(0); i<rendererCount; ++i )
+ for( unsigned int i(0); i < rendererCount; ++i )
{
if( mRenderer[i] == renderer )
{
- //Renderer already in the list
+ // Renderer is already in the list.
return;
}
}
- //If it is the first renderer added, make sure the world transform will be calculated
- //in the next update as world transform is not computed if node has no renderers
+ // If it is the first renderer added, make sure the world transform will be calculated
+ // in the next update as world transform is not computed if node has no renderers.
if( rendererCount == 0 )
{
mDirtyFlags |= TransformFlag;
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_NODE_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_NODE_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_NODE_H
+#define DALI_INTERNAL_SCENE_GRAPH_NODE_H
/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
namespace Internal
{
-// value types used by messages
+// Value types used by messages.
template <> struct ParameterType< ColorMode > : public BasicType< ColorMode > {};
template <> struct ParameterType< PositionInheritanceMode > : public BasicType< PositionInheritanceMode > {};
+template <> struct ParameterType< ClippingMode::Type > : public BasicType< ClippingMode::Type > {};
namespace SceneGraph
{
SizeFlag = 0x008,
OverlayFlag = 0x010,
SortModifierFlag = 0x020,
- ChildDeletedFlag = 0x040
+ ChildDeletedFlag = 0x040,
};
static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
}
/**
+ * This method sets clipping information on the node based on its hierarchy in the scene-graph.
+ * A value is calculated that can be used during sorting to increase sort speed.
+ * @param[in] clippingId The Clipping ID of the node to set
+ * @param[in] clippingDepth The Clipping Depth of the node to set
+ */
+ void SetClippingInformation( const uint32_t clippingId, const uint32_t clippingDepth )
+ {
+ // We only set up the sort value if we have a clipping depth, IE. At least 1 clipping node has been hit.
+ // If not, if we traverse down a clipping tree and back up, and there is another
+ // node on the parent, this will have a non-zero clipping ID that must be ignored
+ if( DALI_LIKELY( clippingDepth > 0u ) )
+ {
+ mClippingDepth = clippingDepth;
+
+ // Calculate the sort value here on write, as when read (during sort) it may be accessed several times.
+ // The items must be sorted by Clipping ID first (so the ID is kept in the most-significant bits).
+ // For the same ID, the clipping nodes must be first, so we negate the
+ // clipping enabled flag and set it as the least significant bit.
+ mClippingSortModifier = ( clippingId << 1u ) | ( mClippingMode == ClippingMode::DISABLED ? 1u : 0u );
+ }
+ }
+
+ /**
+ * Gets the Clipping ID for this node.
+ * @return The Clipping ID for this node.
+ */
+ uint32_t GetClippingId() const
+ {
+ return mClippingSortModifier >> 1u;
+ }
+
+ /**
+ * Gets the Clipping Depth for this node.
+ * @return The Clipping Depth for this node.
+ */
+ uint32_t GetClippingDepth() const
+ {
+ return mClippingDepth;
+ }
+
+ /**
+ * Sets the clipping mode for this node.
+ * @param[in] clippingMode The ClippingMode to set
+ */
+ void SetClippingMode( const ClippingMode::Type clippingMode )
+ {
+ mClippingMode = clippingMode;
+ }
+
+ /**
+ * Gets the Clipping Mode for this node.
+ * @return The ClippingMode of this node
+ */
+ ClippingMode::Type GetClippingMode() const
+ {
+ return mClippingMode;
+ }
+
+ /**
* Add a renderer to the node
* @param[in] renderer The renderer added to the node
*/
/**
* Equality operator, checks for identity, not values.
- *
+ * @param[in]
*/
bool operator==( const Node* rhs ) const
{
- if ( this == rhs )
- {
- return true;
- }
- return false;
+ return ( this == rhs );
}
unsigned short GetDepth() const
public: // Default properties
- TransformManager* mTransformManager;
- TransformId mTransformId;
- TransformManagerPropertyVector3 mParentOrigin; ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed
- TransformManagerPropertyVector3 mAnchorPoint; ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed
- TransformManagerPropertyVector3 mSize; ///< Size is provided for layouting
- TransformManagerPropertyVector3 mPosition; ///< Local transform; distance between parent-origin & anchor-point
- TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node
- TransformManagerPropertyVector3 mScale; ///< Local transform; scale relative to parent node
+ TransformManager* mTransformManager;
+ TransformId mTransformId;
+ TransformManagerPropertyVector3 mParentOrigin; ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed
+ TransformManagerPropertyVector3 mAnchorPoint; ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed
+ TransformManagerPropertyVector3 mSize; ///< Size is provided for layouting
+ TransformManagerPropertyVector3 mPosition; ///< Local transform; distance between parent-origin & anchor-point
+ TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node
+ TransformManagerPropertyVector3 mScale; ///< Local transform; scale relative to parent node
- AnimatableProperty<bool> mVisible; ///< Visibility can be inherited from the Node hierachy
- AnimatableProperty<Vector4> mColor; ///< Color can be inherited from the Node hierarchy
+ AnimatableProperty<bool> mVisible; ///< Visibility can be inherited from the Node hierachy
+ AnimatableProperty<Vector4> mColor; ///< Color can be inherited from the Node hierarchy
// Inherited properties; read-only from public API
- TransformManagerVector3Input mWorldPosition; ///< Full inherited position
- TransformManagerVector3Input mWorldScale;
- TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation
- TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix
- InheritedColor mWorldColor; ///< Full inherited color
+ TransformManagerVector3Input mWorldPosition; ///< Full inherited position
+ TransformManagerVector3Input mWorldScale;
+ TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation
+ TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix
+ InheritedColor mWorldColor; ///< Full inherited color
+
+ GeometryBatcher* mGeometryBatcher; ///< A pointer to an instance of geometry batcher
+ uint32_t mBatchIndex; ///< Batch 32bit handle, BATCH_NULL_HANDLE by default
+ uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
- GeometryBatcher* mGeometryBatcher; ///< A pointer to an instance of geometry batcher
- uint32_t mBatchIndex; ///< Batch 32bit handle, BATCH_NULL_HANDLE by default
- bool mIsBatchParent:1; ///< Marks node as a batch parent
+ bool mIsBatchParent:1; ///< Marks node as a batch parent
protected:
- Node* mParent; ///< Pointer to parent node (a child is owned by its parent)
- Node* mBatchParent; ///< Pointer to batch parent node
- RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask
+ Node* mParent; ///< Pointer to parent node (a child is owned by its parent)
+ Node* mBatchParent; ///< Pointer to batch parent node
+ RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask
- RendererContainer mRenderer; ///< Container of renderers; not owned
+ RendererContainer mRenderer; ///< Container of renderers; not owned
- NodeContainer mChildren; ///< Container of children; not owned
+ NodeContainer mChildren; ///< Container of children; not owned
- CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node
- unsigned int mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame
- unsigned int mRegenerateUniformMap : 2; ///< Indicate if the uniform map has to be regenerated this frame
+ 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
// flags, compressed to bitfield
- unsigned short mDepth: 12; ///< Depth in the hierarchy
- int mDirtyFlags:8; ///< A composite set of flags for each of the Node properties
-
- bool mIsRoot:1; ///< True if the node cannot have a parent
-
- 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
+ unsigned short mDepth:12; ///< Depth in the hierarchy
+ 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
+ ClippingMode::Type mClippingMode:2; ///< The clipping mode of this node
+ bool mIsRoot:1; ///< True if the node cannot have a parent
// Changes scope, should be at end of class
DALI_LOG_OBJECT_STRING_DECLARATION;
new (slot) LocalType( &node, &Node::SetIsBatchParent, isBatchParent );
}
+inline void SetClippingModeMessage( EventThreadServices& eventThreadServices, const Node& node, ClippingMode::Type clippingMode )
+{
+ typedef MessageValue1< Node, ClippingMode::Type > 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::SetClippingMode, clippingMode );
+}
+
} // namespace SceneGraph
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_H_
+#endif // DALI_INTERNAL_SCENE_GRAPH_NODE_H
void Layer::ClearRenderables()
{
- stencilRenderables.Clear();
colorRenderables.Clear();
overlayRenderables.Clear();
}
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_LAYER_H
+#define DALI_INTERNAL_SCENE_GRAPH_LAYER_H
/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
struct Renderable
{
Renderable()
- :mNode(0),
- mRenderer(0)
+ : mNode( 0 ),
+ mRenderer( 0 )
{}
Renderable( Node* node, Renderer* renderer )
- :mNode(node),
- mRenderer(renderer)
+ : mNode( node ),
+ mRenderer( renderer )
{}
Node* mNode;
public: // For update-algorithms
- RenderableContainer stencilRenderables;
RenderableContainer colorRenderables;
RenderableContainer overlayRenderables;
private:
- SortFunctionType mSortFunction; ///< Used to sort semi-transparent geometry
+ SortFunctionType mSortFunction; ///< Used to sort semi-transparent geometry
ClippingBox mClippingBox; ///< The clipping box, in window coordinates
Camera* mLastCamera; ///< Pointer to the last camera that has rendered the layer
Dali::Layer::Behavior mBehavior; ///< The behavior of the layer
bool mAllChildTransformsClean[ 2 ]; ///< True if all child nodes transforms are clean,
- /// double buffered as we need two clean frames before we can reuse N-1 for N+1
- /// this allows us to cache render items when layer is "static"
+ /// double buffered as we need two clean frames before we can reuse N-1 for N+1
+ /// 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
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_LAYER_H
Renderer::~Renderer()
{
- if (mTextureSet)
+ if( mTextureSet )
{
- mTextureSet->RemoveObserver(this);
- mTextureSet=NULL;
+ mTextureSet->RemoveObserver( this );
+ mTextureSet = NULL;
}
if( mShader )
{
- mShader->RemoveConnectionObserver(*this);
- mShader=NULL;
+ mShader->RemoveConnectionObserver( *this );
+ mShader = NULL;
}
}
}
}
-
return opacity;
}
namespace Dali
{
+
namespace Internal
{
Shader* mShader; ///< The shader this renderer uses. (Not owned)
Vector4* mBlendColor; ///< The blend color for blending operation
- Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
+ Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
size_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw
size_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw
public:
- bool mBatchingEnabled : 1; ///< Flag indicating whether the render supports batching
+ bool mBatchingEnabled:1; ///< Flag indicating whether the render supports batching
+
int mDepthIndex; ///< Used only in PrepareRenderInstructions
};
-#ifndef __DALI_ACTOR_ENUMERATIONS_H__
-#define __DALI_ACTOR_ENUMERATIONS_H__
+#ifndef DALI_ACTOR_ENUMERATIONS_H
+#define DALI_ACTOR_ENUMERATIONS_H
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
*/
namespace Dimension
{
-enum Type
-{
- WIDTH = 0x1, ///< Width dimension @SINCE_1_0.0
- HEIGHT = 0x2, ///< Height dimension @SINCE_1_0.0
+ enum Type
+ {
+ WIDTH = 0x1, ///< Width dimension @SINCE_1_0.0
+ HEIGHT = 0x2, ///< Height dimension @SINCE_1_0.0
- ALL_DIMENSIONS = 0x3 ///< Mask to cover all flags @SINCE_1_0.0
-};
+ ALL_DIMENSIONS = 0x3 ///< Mask to cover all flags @SINCE_1_0.0
+ };
-enum Meta
-{
- DIMENSION_COUNT = 2 ///< Number of dimensions - update this if adding new dimension @SINCE_1_0.0
-};
+ enum Meta
+ {
+ DIMENSION_COUNT = 2 ///< Number of dimensions - update this if adding new dimension @SINCE_1_0.0
+ };
}
/**
*/
namespace ResizePolicy
{
-enum Type
-{
- FIXED, ///< Size is fixed as set by SetSize @SINCE_1_0.0
- USE_NATURAL_SIZE, ///< Size is to use the actor's natural size @SINCE_1_0.0 @see Actor::GetNaturalSize()
- FILL_TO_PARENT, ///< Size is to fill up to the actor's parent's bounds. Aspect ratio is not maintained. @SINCE_1_0.0
- SIZE_RELATIVE_TO_PARENT, ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ). @SINCE_1_0.0
- SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ). @SINCE_1_0.0
- FIT_TO_CHILDREN, ///< Size will adjust to wrap around all children @SINCE_1_0.0
- DIMENSION_DEPENDENCY, ///< One dimension is dependent on the other @SINCE_1_0.0
- USE_ASSIGNED_SIZE ///< The size will be assigned to the actor @SINCE_1_0.0
-};
-const Type DEFAULT = USE_NATURAL_SIZE; ///< Default resize policy
+ enum Type
+ {
+ FIXED, ///< Size is fixed as set by SetSize @SINCE_1_0.0
+ USE_NATURAL_SIZE, ///< Size is to use the actor's natural size @SINCE_1_0.0 @see Actor::GetNaturalSize()
+ FILL_TO_PARENT, ///< Size is to fill up to the actor's parent's bounds. Aspect ratio is not maintained. @SINCE_1_0.0
+ SIZE_RELATIVE_TO_PARENT, ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ). @SINCE_1_0.0
+ SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ). @SINCE_1_0.0
+ FIT_TO_CHILDREN, ///< Size will adjust to wrap around all children @SINCE_1_0.0
+ DIMENSION_DEPENDENCY, ///< One dimension is dependent on the other @SINCE_1_0.0
+ USE_ASSIGNED_SIZE ///< The size will be assigned to the actor @SINCE_1_0.0
+ };
+ const Type DEFAULT = USE_NATURAL_SIZE; ///< Default resize policy
}
/**
*/
namespace SizeScalePolicy
{
-enum Type
-{
- USE_SIZE_SET, ///< Use the size that was set @SINCE_1_0.0
- FIT_WITH_ASPECT_RATIO, ///< Fit within the size set maintaining natural size aspect ratio @SINCE_1_0.0
- FILL_WITH_ASPECT_RATIO ///< Fill up the size set maintaining natural size aspect ratio. May exceed size bounds in one dimension. @SINCE_1_0.0
-};
+ enum Type
+ {
+ USE_SIZE_SET, ///< Use the size that was set @SINCE_1_0.0
+ FIT_WITH_ASPECT_RATIO, ///< Fit within the size set maintaining natural size aspect ratio @SINCE_1_0.0
+ FILL_WITH_ASPECT_RATIO ///< Fill up the size set maintaining natural size aspect ratio. May exceed size bounds in one dimension. @SINCE_1_0.0
+ };
}
/**
*/
namespace HorizontalAlignment
{
-enum Type
-{
- LEFT, ///< Align horizontally left @SINCE_1_0.0
- CENTER, ///< Align horizontally center @SINCE_1_0.0
- RIGHT ///< Align horiztonally right @SINCE_1_0.0
-};
+ enum Type
+ {
+ LEFT, ///< Align horizontally left @SINCE_1_0.0
+ CENTER, ///< Align horizontally center @SINCE_1_0.0
+ RIGHT ///< Align horizontally right @SINCE_1_0.0
+ };
}
/**
*/
namespace VerticalAlignment
{
-enum Type
+ enum Type
+ {
+ TOP, ///< Align vertically top @SINCE_1_0.0
+ CENTER, ///< Align vertically center @SINCE_1_0.0
+ BOTTOM ///< Align vertically bottom @SINCE_1_0.0
+ };
+}
+
+/**
+ * @brief The ClippingMode describes how this Actors children will be clipped against it.
+ * @SINCE_1_2.5
+ */
+namespace ClippingMode
{
- TOP, ///< Align vertically top @SINCE_1_0.0
- CENTER, ///< Align vertically center @SINCE_1_0.0
- BOTTOM ///< Align vertically bottom @SINCE_1_0.0
-};
+ enum Type
+ {
+ DISABLED, ///< This Actor will not clip its children. @SINCE_1_2.5
+ CLIP_CHILDREN, ///< This Actor will clip all children to within its boundaries (the actor will also be visible itself). @SINCE_1_2.5
+ };
}
+
/**
* @}
*/
} // namespace Dali
-#endif // __DALI_ACTOR_ENUMERATIONS_H__
+#endif // DALI_ACTOR_ENUMERATIONS_H
-#ifndef __DALI_ACTOR_H__
-#define __DALI_ACTOR_H__
+#ifndef DALI_ACTOR_H
+#define DALI_ACTOR_H
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
#include <dali/public-api/object/handle.h>
#include <dali/public-api/object/property-index-ranges.h>
#include <dali/public-api/signals/dali-signal.h>
+
namespace Dali
{
/**
{
enum
{
- PARENT_ORIGIN = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "parentOrigin", type Vector3 (constraint-input) @SINCE_1_0.0
- PARENT_ORIGIN_X, ///< name "parentOriginX", type float (constraint-input) @SINCE_1_0.0
- PARENT_ORIGIN_Y, ///< name "parentOriginY", type float (constraint-input) @SINCE_1_0.0
- PARENT_ORIGIN_Z, ///< name "parentOriginZ", type float (constraint-input) @SINCE_1_0.0
- ANCHOR_POINT, ///< name "anchorPoint", type Vector3 (constraint-input) @SINCE_1_0.0
- ANCHOR_POINT_X, ///< name "anchorPointX", type float (constraint-input) @SINCE_1_0.0
- ANCHOR_POINT_Y, ///< name "anchorPointY", type float (constraint-input) @SINCE_1_0.0
- ANCHOR_POINT_Z, ///< name "anchorPointZ", type float (constraint-input) @SINCE_1_0.0
- SIZE, ///< name "size", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
- SIZE_WIDTH, ///< name "sizeWidth", type float (animatable / constraint-input) @SINCE_1_0.0
- SIZE_HEIGHT, ///< name "sizeHeight", type float (animatable / constraint-input) @SINCE_1_0.0
- SIZE_DEPTH, ///< name "sizeDepth", type float (animatable / constraint-input) @SINCE_1_0.0
- POSITION, ///< name "position", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
- POSITION_X, ///< name "positionX", type float (animatable / constraint-input) @SINCE_1_0.0
- POSITION_Y, ///< name "positionY", type float (animatable / constraint-input) @SINCE_1_0.0
- POSITION_Z, ///< name "positionZ", type float (animatable / constraint-input) @SINCE_1_0.0
- WORLD_POSITION, ///< name "worldPosition", type Vector3 (read-only / constraint-input) @SINCE_1_0.0
- WORLD_POSITION_X, ///< name "worldPositionX", type float (read-only / constraint-input) @SINCE_1_0.0
- WORLD_POSITION_Y, ///< name "worldPositionY", type float (read-only / constraint-input) @SINCE_1_0.0
- WORLD_POSITION_Z, ///< name "worldPositionZ", type float (read-only / constraint-input) @SINCE_1_0.0
- ORIENTATION, ///< name "orientation", type Quaternion (animatable / constraint-input) @SINCE_1_0.0
- WORLD_ORIENTATION, ///< name "worldOrientation", type Quaternion (read-only / constraint-input) @SINCE_1_0.0
- SCALE, ///< name "scale", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
- SCALE_X, ///< name "scaleX", type float (animatable / constraint-input) @SINCE_1_0.0
- SCALE_Y, ///< name "scaleY", type float (animatable / constraint-input) @SINCE_1_0.0
- SCALE_Z, ///< name "scaleZ", type float (animatable / constraint-input) @SINCE_1_0.0
- WORLD_SCALE, ///< name "worldScale", type Vector3 (read-only / constraint-input) @SINCE_1_0.0
- VISIBLE, ///< name "visible", type bool (animatable / constraint-input) @SINCE_1_0.0
- COLOR, ///< name "color", type Vector4 (animatable / constraint-input) @SINCE_1_0.0
- COLOR_RED, ///< name "colorRed", type float (animatable / constraint-input) @SINCE_1_0.0
- COLOR_GREEN, ///< name "colorGreen", type float (animatable / constraint-input) @SINCE_1_0.0
- COLOR_BLUE, ///< name "colorBlue", type float (animatable / constraint-input) @SINCE_1_0.0
- COLOR_ALPHA, ///< name "colorAlpha", type float (animatable / constraint-input) @SINCE_1_0.0
- WORLD_COLOR, ///< name "worldColor", type Vector4 (read-only / constraint-input) @SINCE_1_0.0
- WORLD_MATRIX, ///< name "worldMatrix", type Matrix (read-only / constraint-input) @SINCE_1_0.0
+ PARENT_ORIGIN = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "parentOrigin", type Vector3 (constraint-input) @SINCE_1_0.0
+ PARENT_ORIGIN_X, ///< name "parentOriginX", type float (constraint-input) @SINCE_1_0.0
+ PARENT_ORIGIN_Y, ///< name "parentOriginY", type float (constraint-input) @SINCE_1_0.0
+ PARENT_ORIGIN_Z, ///< name "parentOriginZ", type float (constraint-input) @SINCE_1_0.0
+ ANCHOR_POINT, ///< name "anchorPoint", type Vector3 (constraint-input) @SINCE_1_0.0
+ ANCHOR_POINT_X, ///< name "anchorPointX", type float (constraint-input) @SINCE_1_0.0
+ ANCHOR_POINT_Y, ///< name "anchorPointY", type float (constraint-input) @SINCE_1_0.0
+ ANCHOR_POINT_Z, ///< name "anchorPointZ", type float (constraint-input) @SINCE_1_0.0
+ SIZE, ///< name "size", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
+ SIZE_WIDTH, ///< name "sizeWidth", type float (animatable / constraint-input) @SINCE_1_0.0
+ SIZE_HEIGHT, ///< name "sizeHeight", type float (animatable / constraint-input) @SINCE_1_0.0
+ SIZE_DEPTH, ///< name "sizeDepth", type float (animatable / constraint-input) @SINCE_1_0.0
+ POSITION, ///< name "position", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
+ POSITION_X, ///< name "positionX", type float (animatable / constraint-input) @SINCE_1_0.0
+ POSITION_Y, ///< name "positionY", type float (animatable / constraint-input) @SINCE_1_0.0
+ POSITION_Z, ///< name "positionZ", type float (animatable / constraint-input) @SINCE_1_0.0
+ WORLD_POSITION, ///< name "worldPosition", type Vector3 (read-only / constraint-input) @SINCE_1_0.0
+ WORLD_POSITION_X, ///< name "worldPositionX", type float (read-only / constraint-input) @SINCE_1_0.0
+ WORLD_POSITION_Y, ///< name "worldPositionY", type float (read-only / constraint-input) @SINCE_1_0.0
+ WORLD_POSITION_Z, ///< name "worldPositionZ", type float (read-only / constraint-input) @SINCE_1_0.0
+ ORIENTATION, ///< name "orientation", type Quaternion (animatable / constraint-input) @SINCE_1_0.0
+ WORLD_ORIENTATION, ///< name "worldOrientation", type Quaternion (read-only / constraint-input) @SINCE_1_0.0
+ SCALE, ///< name "scale", type Vector3 (animatable / constraint-input) @SINCE_1_0.0
+ SCALE_X, ///< name "scaleX", type float (animatable / constraint-input) @SINCE_1_0.0
+ SCALE_Y, ///< name "scaleY", type float (animatable / constraint-input) @SINCE_1_0.0
+ SCALE_Z, ///< name "scaleZ", type float (animatable / constraint-input) @SINCE_1_0.0
+ WORLD_SCALE, ///< name "worldScale", type Vector3 (read-only / constraint-input) @SINCE_1_0.0
+ VISIBLE, ///< name "visible", type bool (animatable / constraint-input) @SINCE_1_0.0
+ COLOR, ///< name "color", type Vector4 (animatable / constraint-input) @SINCE_1_0.0
+ COLOR_RED, ///< name "colorRed", type float (animatable / constraint-input) @SINCE_1_0.0
+ COLOR_GREEN, ///< name "colorGreen", type float (animatable / constraint-input) @SINCE_1_0.0
+ COLOR_BLUE, ///< name "colorBlue", type float (animatable / constraint-input) @SINCE_1_0.0
+ COLOR_ALPHA, ///< name "colorAlpha", type float (animatable / constraint-input) @SINCE_1_0.0
+ WORLD_COLOR, ///< name "worldColor", type Vector4 (read-only / constraint-input) @SINCE_1_0.0
+ WORLD_MATRIX, ///< name "worldMatrix", type Matrix (read-only / constraint-input) @SINCE_1_0.0
NAME, ///< name "name", type std::string @SINCE_1_0.0
- SENSITIVE, ///< name "sensitive", type bool @SINCE_1_0.0
- LEAVE_REQUIRED, ///< name "leaveRequired", type bool @SINCE_1_0.0
- INHERIT_ORIENTATION, ///< name "inheritOrientation", type bool @SINCE_1_0.0
- INHERIT_SCALE, ///< name "inheritScale", type bool @SINCE_1_0.0
+ SENSITIVE, ///< name "sensitive", type bool @SINCE_1_0.0
+ LEAVE_REQUIRED, ///< name "leaveRequired", type bool @SINCE_1_0.0
+ INHERIT_ORIENTATION, ///< name "inheritOrientation", type bool @SINCE_1_0.0
+ INHERIT_SCALE, ///< name "inheritScale", type bool @SINCE_1_0.0
COLOR_MODE, ///< name "colorMode", type std::string @SINCE_1_0.0
POSITION_INHERITANCE, ///< name "positionInheritance", type std::string @DEPRECATED_1_1.24 Use INHERIT_POSITION instead
DRAW_MODE, ///< name "drawMode", type std::string @SINCE_1_0.0
- SIZE_MODE_FACTOR, ///< name "sizeModeFactor", type Vector3 @SINCE_1_0.0
- WIDTH_RESIZE_POLICY, ///< name "widthResizePolicy", type String @SINCE_1_0.0
- HEIGHT_RESIZE_POLICY, ///< name "heightResizePolicy", type String @SINCE_1_0.0
- SIZE_SCALE_POLICY, ///< name "sizeScalePolicy", type String @SINCE_1_0.0
- WIDTH_FOR_HEIGHT, ///< name "widthForHeight", type Boolean @SINCE_1_0.0
- HEIGHT_FOR_WIDTH, ///< name "heightForWidth", type Boolean @SINCE_1_0.0
- PADDING, ///< name "padding", type Vector4 @SINCE_1_0.0
- MINIMUM_SIZE, ///< name "minimumSize", type Vector2 @SINCE_1_0.0
- MAXIMUM_SIZE, ///< name "maximumSize", type Vector2 @SINCE_1_0.0
- INHERIT_POSITION, ///< name "inheritPosition", type bool @SINCE_1_1.24
- BATCH_PARENT, ///< name "batchParent", type bool @SINCE_1_2.0
+ SIZE_MODE_FACTOR, ///< name "sizeModeFactor", type Vector3 @SINCE_1_0.0
+ WIDTH_RESIZE_POLICY, ///< name "widthResizePolicy", type String @SINCE_1_0.0
+ HEIGHT_RESIZE_POLICY, ///< name "heightResizePolicy", type String @SINCE_1_0.0
+ SIZE_SCALE_POLICY, ///< name "sizeScalePolicy", type String @SINCE_1_0.0
+ WIDTH_FOR_HEIGHT, ///< name "widthForHeight", type bool @SINCE_1_0.0
+ HEIGHT_FOR_WIDTH, ///< name "heightForWidth", type bool @SINCE_1_0.0
+ PADDING, ///< name "padding", type Vector4 @SINCE_1_0.0
+ MINIMUM_SIZE, ///< name "minimumSize", type Vector2 @SINCE_1_0.0
+ MAXIMUM_SIZE, ///< name "maximumSize", type Vector2 @SINCE_1_0.0
+ INHERIT_POSITION, ///< name "inheritPosition", type bool @SINCE_1_1.24
+ CLIPPING_MODE, ///< name "clippingMode", type String @SINCE_1_2.5
+ BATCH_PARENT, ///< name "batchParent", type bool @SINCE_1_2.0
};
};
* Overlay actors are drawn in a separate pass, after all non-overlay actors within the Layer.
* For overlay actors, the drawing order is with respect to tree levels of Actors,
* and depth-testing will not be used.
- *
- * If DrawMode::STENCIL is used, the actor and its children will be used to stencil-test other actors
- * within the Layer. Stencil actors are therefore drawn into the stencil buffer before any other
- * actors within the Layer.
- *
+
* @SINCE_1_0.0
* @param[in] drawMode The new draw-mode to use.
- * @note Setting STENCIL will override OVERLAY_2D, if that would otherwise have been inherited.
* @note Layers do not inherit the DrawMode from their parents.
*/
void SetDrawMode( DrawMode::Type drawMode );
*/
} // namespace Dali
-#endif // __DALI_ACTOR_H__
+#endif // DALI_ACTOR_H
-#ifndef __DALI_LAYER_H__
-#define __DALI_LAYER_H__
+#ifndef DALI_LAYER_H
+#define DALI_LAYER_H
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
* The contents of the layer will not be visible outside this box, when clipping is
* enabled. The default clipping box is empty (0,0,0,0) which means everything is clipped.
* You can only do rectangular clipping using this API in window coordinates.
- * For other kinds of clipping, see Dali::Actor::SetDrawMode().
* @SINCE_1_0.0
* @param [in] x The X-coordinate of the top-left corner of the box
* @param [in] y The Y-coordinate of the top-left corner of the box
*/
} // namespace Dali
-#endif //__DALI_LAYER_H__
+#endif // DALI_LAYER_H