[3.0] Clipping API feature in Actor 43/87843/3
authorTom Robinson <tom.robinson@samsung.com>
Fri, 18 Mar 2016 17:05:28 +0000 (17:05 +0000)
committerTom Robinson <tom.robinson@samsung.com>
Fri, 9 Sep 2016 15:43:27 +0000 (16:43 +0100)
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"

Change-Id: I5f787d6986dc87089566b7a1f721ec4f4ae74b46
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).

49 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp
automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp
automated-tests/src/dali/utc-Dali-HoverProcessing.cpp
automated-tests/src/dali/utc-Dali-Layer.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
automated-tests/src/dali/utc-Dali-Scripting.cpp
automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp
automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/layer-impl.h
dali/internal/event/events/gesture-processor.cpp
dali/internal/event/events/hit-test-algorithm-impl.cpp
dali/internal/event/events/hit-test-algorithm-impl.h
dali/internal/event/rendering/renderer-impl.cpp
dali/internal/file.list
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-debug.cpp
dali/internal/render/common/render-debug.h
dali/internal/render/common/render-item.cpp
dali/internal/render/common/render-item.h
dali/internal/render/common/render-list.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/update/manager/prepare-render-instructions.cpp [deleted file]
dali/internal/update/manager/prepare-render-instructions.h [deleted file]
dali/internal/update/manager/process-render-tasks.h [deleted file]
dali/internal/update/manager/render-instruction-processor.cpp [new file with mode: 0644]
dali/internal/update/manager/render-instruction-processor.h [new file with mode: 0644]
dali/internal/update/manager/render-task-processor.cpp [moved from dali/internal/update/manager/process-render-tasks.cpp with 52% similarity]
dali/internal/update/manager/render-task-processor.h [new file with mode: 0644]
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/manager/update-manager-debug.cpp
dali/internal/update/manager/update-manager-debug.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/internal/update/nodes/scene-graph-layer.cpp
dali/internal/update/nodes/scene-graph-layer.h
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/public-api/actors/actor-enumerations.h
dali/public-api/actors/actor.h
dali/public-api/actors/layer.h

index 3f2e6e5..0054e59 100644 (file)
@@ -130,6 +130,18 @@ bool TraceCallStack::FindMethodAndParams(std::string method, const NamedParams&
   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
index 137bfaf..e1882ea 100644 (file)
@@ -102,6 +102,19 @@ public:
   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
index f4f3fcc..c9966a4 100644 (file)
@@ -2500,17 +2500,11 @@ int UtcDaliActorSetDrawMode(void)
 
   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;
 }
 
@@ -2855,6 +2849,8 @@ const PropertyStringIndex PROPERTY_TABLE[] =
   { "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     },
+  { "clippingMode",             Actor::Property::CLIPPING_MODE,            Property::STRING      },
 };
 const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] );
 } // unnamed namespace
@@ -3550,3 +3546,262 @@ int UtcDaliActorRemoveRendererN(void)
 
   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;
+}
index 99d16c4..b4cd632 100644 (file)
@@ -361,7 +361,7 @@ int UtcDaliHitTestAlgorithmOrtho02(void)
   END_TEST;
 }
 
-int UtcDaliHitTestAlgorithmStencil(void)
+int UtcDaliHitTestAlgorithmClippingActor(void)
 {
   TestApplication application;
   tet_infoline("Testing Dali::HitTestAlgorithm with a stencil");
@@ -377,42 +377,38 @@ int UtcDaliHitTestAlgorithmStencil(void)
   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;
 }
 
index 7dd76a6..fd4a7e5 100644 (file)
@@ -1248,38 +1248,37 @@ int UtcDaliHoverLeaveActorReadded(void)
   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();
index 34c5741..7b31004 100644 (file)
@@ -583,3 +583,58 @@ int UtcDaliLayerBehaviour(void)
   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;
+}
index 0d93f91..6591dd9 100644 (file)
@@ -2292,6 +2292,9 @@ int UtcDaliRendererSetRenderModeToUseStencilBuffer(void)
   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 );
 
index e76ff62..12e50d0 100644 (file)
@@ -49,8 +49,7 @@ const unsigned int POSITION_INHERITANCE_MODE_VALUES_COUNT = sizeof( POSITION_INH
 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] );
 
@@ -484,7 +483,7 @@ int UtcDaliScriptingNewActorProperties(void)
   map[ "sensitive" ] = false;
   map[ "leaveRequired" ] = true;
   map[ "positionInheritance" ] = "DONT_INHERIT_POSITION";
-  map[ "drawMode" ] = "STENCIL";
+  map[ "drawMode" ] = "OVERLAY_2D";
   map[ "inheritOrientation" ] = false;
   map[ "inheritScale" ] = false;
 
@@ -507,7 +506,7 @@ int UtcDaliScriptingNewActorProperties(void)
     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 );
 
index 36e8488..9b519d3 100644 (file)
@@ -1526,37 +1526,37 @@ int UtcDaliTouchDataLeaveActorReadded(void)
   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();
index 998b8ec..82d514b 100644 (file)
@@ -1300,37 +1300,37 @@ int UtcDaliTouchLeaveActorReadded(void)
   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();
index 313fa72..7f2bc71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -44,6 +44,7 @@
 #include <dali/internal/update/common/discard-queue.h>
 #include <dali/internal/update/common/texture-cache-dispatcher.h>
 #include <dali/internal/update/manager/update-manager.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>
@@ -116,6 +117,8 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mTextureUploadedQueue );
 
+  mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
+
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
   TextureCache& textureCache = mRenderManager->GetTextureCache();
 
@@ -145,7 +148,8 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
                                        renderController,
                                       *mRenderManager,
                                        renderQueue,
-                                      *mTextureCacheDispatcher );
+                                      *mTextureCacheDispatcher,
+                                      *mRenderTaskProcessor );
 
   mRenderManager->SetShaderSaver( *mUpdateManager );
 
@@ -210,6 +214,7 @@ Core::~Core()
   delete mTextureCacheDispatcher;
   delete mUpdateManager;
   delete mRenderManager;
+  delete mRenderTaskProcessor;
   delete mTextureUploadedQueue;
 }
 
index b9472cd..61f20fd 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -66,6 +66,7 @@ class UpdateManager;
 class RenderManager;
 class DiscardQueue;
 class TextureCacheDispatcher;
+class RenderTaskProcessor;
 }
 
 /**
@@ -295,6 +296,7 @@ private:
   ResourceManager*                          mResourceManager;             ///< Asynchronous Resource Loading
   IntrusivePtr< RelayoutController >        mRelayoutController;          ///< Size negotiation relayout controller
 
+  SceneGraph::RenderTaskProcessor*          mRenderTaskProcessor;         ///< Handles the processing of render tasks
   bool                                      mIsActive         : 1;        ///< Whether Core is active or suspended
   bool                                      mProcessingEvent  : 1;        ///< True during ProcessEvents()
 
@@ -306,4 +308,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_CORE_H__
+#endif // DALI_INTERNAL_CORE_H
index 5df7b5c..4f8b8f0 100644 (file)
@@ -24,7 +24,6 @@
 #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>
@@ -32,9 +31,7 @@
 #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>
@@ -144,62 +141,63 @@ namespace // unnamed namespace
 /**
  * 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( "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_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
 
 // Signals
@@ -290,6 +288,12 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO )
 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 )
@@ -1000,6 +1004,11 @@ float Actor::GetCurrentOpacity() const
   return 1.0f;
 }
 
+ClippingMode::Type Actor::GetClippingMode() const
+{
+  return mClippingMode;
+}
+
 const Vector4& Actor::GetCurrentWorldColor() const
 {
   if( NULL != mNode )
@@ -1504,7 +1513,7 @@ void Actor::SetDrawMode( DrawMode::Type drawMode )
 {
   // 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 );
@@ -1707,12 +1716,11 @@ bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) con
   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
@@ -1974,7 +1982,8 @@ Actor::Actor( DerivedType derivedType )
   mInheritScale( true ),
   mDrawMode( DrawMode::NORMAL ),
   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
-  mColorMode( Node::DEFAULT_COLOR_MODE )
+  mColorMode( Node::DEFAULT_COLOR_MODE ),
+  mClippingMode( ClippingMode::DISABLED )
 {
 }
 
@@ -2648,6 +2657,20 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
       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
@@ -3139,6 +3162,12 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const
       break;
     }
 
+    case Dali::Actor::Property::CLIPPING_MODE:
+    {
+      value = mClippingMode;
+      break;
+    }
+
     default:
     {
       DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
index d38493b..e406bb0 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -636,6 +636,12 @@ public:
   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
@@ -1275,7 +1281,7 @@ public:
    */
   bool RayActorTest( const Vector4& rayOrigin,
                      const Vector4& rayDir,
-                     Vector4& hitPointLocal,
+                     Vector2& hitPointLocal,
                      float& distance ) const;
 
   /**
@@ -1827,6 +1833,7 @@ protected:
   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:
 
@@ -1859,4 +1866,4 @@ inline const Internal::Actor& GetImplementation( const Dali::Actor& actor )
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_ACTOR_H__
+#endif // DALI_INTERNAL_ACTOR_H
index 0e97f3a..d1ad93d 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -335,4 +335,4 @@ inline const Internal::Layer& GetImplementation(const Dali::Layer& layer)
 } // namespace Dali
 
 
-#endif //__DALI_INTERNAL_LAYER_H__
+#endif // DALI_INTERNAL_LAYER_H
index a196d1a..5ad06df 100644 (file)
@@ -147,12 +147,12 @@ void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults
               // 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.
                 }
               }
index 5c77ccc..5026b95 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -52,19 +52,15 @@ struct HitActor
 {
   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.
 };
 
 /**
@@ -135,16 +131,13 @@ bool IsActorExclusiveToAnotherRenderTask( const Actor& 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;
       }
     }
   }
@@ -168,37 +161,39 @@ HitActor HitTestWithinLayer( Actor& actor,
                              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.
@@ -206,36 +201,61 @@ HitActor HitTestWithinLayer( Actor& 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 )
@@ -252,12 +272,6 @@ HitActor HitTestWithinLayer( Actor& actor,
     }
   }
 
-  // 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 )
@@ -272,30 +286,29 @@ HitActor HitTestWithinLayer( Actor& actor,
     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
           {
@@ -303,17 +316,18 @@ HitActor HitTestWithinLayer( Actor& actor,
           }
         }
 
-        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;
 }
 
@@ -326,13 +340,11 @@ bool IsWithinSourceActors( const Actor& sourceActor, const Actor& actor )
   {
     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
@@ -346,7 +358,7 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates,
 {
   bool hittable( true );
 
-  if(layer.IsClipping())
+  if( layer.IsClipping() )
   {
     ClippingBox box = layer.GetClippingBox();
 
@@ -360,14 +372,14 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates,
     }
   }
 
-  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;
@@ -414,14 +426,14 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
     }
 
     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() );
 
@@ -438,26 +450,20 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
 
         // 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,
@@ -468,13 +474,12 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         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,
@@ -485,37 +490,31 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         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
         }
@@ -526,76 +525,86 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
 }
 
 /**
- * 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
@@ -609,7 +618,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgor
 
   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;
@@ -625,7 +634,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results,
   // Hit-test the system-overlay actors first
   SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal();
 
-  if ( systemOverlay )
+  if( systemOverlay )
   {
     RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
     LayerList& overlayLayerList = systemOverlay->GetLayerList();
@@ -634,7 +643,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results,
   }
 
   // Hit-test the regular on-stage actors
-  if ( !wasHit )
+  if( !wasHit )
   {
     RenderTaskList& taskList = stage.GetRenderTaskList();
     LayerList& layerList = stage.GetLayerList();
@@ -658,7 +667,7 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin
 
   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;
@@ -667,6 +676,7 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin
   return wasHit;
 }
 
+
 } // namespace HitTestAlgorithm
 
 } // namespace Internal
index 07b2291..c0b68e3 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -138,10 +138,11 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results )
 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
index b2f07e6..c430a5b 100644 (file)
@@ -885,7 +885,7 @@ void Renderer::Disconnect()
 }
 
 Renderer::Renderer()
-: mSceneObject (NULL ),
+: mSceneObject(NULL ),
   mBlendColor( NULL ),
   mDepthIndex( 0 ),
   mOnStageCount( 0 ),
index f7bcf2b..18b11cc 100644 (file)
@@ -145,8 +145,8 @@ internal_src_files = \
   $(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/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 \
index ce56324..87b3658 100644 (file)
@@ -70,7 +70,7 @@ inline void SetScissorTest( const RenderList& renderList, Context& context )
     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
   {
@@ -79,141 +79,223 @@ inline void SetScissorTest( const RenderList& renderList, Context& context )
 }
 
 /**
- * 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
- * @param[in] isLayer3D True if the layer is a 3D 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).
+    }
+
+    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 );
 
-  // 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() );
+      // 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 );
 
-  // The depth buffer must be enabled if either reading or writing.
-  context.EnableDepthBuffer( enableDepthWrite || enableDepthTest );
+  // 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 );
+  }
 }
 
 /**
- * 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.
  */
 inline void ProcessRenderList(
@@ -227,15 +309,18 @@ inline void ProcessRenderList(
 {
   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 );
 
-  const size_t count = renderList.Count();
-  for ( size_t index = 0; index < count; ++index )
+  // 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();
+  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 );
@@ -245,8 +330,11 @@ inline void ProcessRenderList(
     // 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 );
+    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 );
 
     item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader,
                             item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
@@ -264,11 +352,10 @@ void ProcessRenderInstruction( const RenderInstruction& instruction,
   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();
 
@@ -278,8 +365,7 @@ void ProcessRenderInstruction( const RenderInstruction& instruction,
     {
       const RenderList* renderList = instruction.GetRenderList( index );
 
-      if(  renderList &&
-          !renderList->IsEmpty() )
+      if( renderList && !renderList->IsEmpty() )
       {
         ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix );
       }
index d5f1165..e5e1d23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -26,7 +26,9 @@
 #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
@@ -38,6 +40,10 @@ namespace Internal
 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 );
@@ -71,35 +77,9 @@ void PrintRenderInstruction( const SceneGraph::RenderInstruction& instruction, B
 
 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;
@@ -126,6 +106,8 @@ void PrintRendererCount( unsigned int frameCount, unsigned int rendererCount )
   }
 }
 
+#endif
+
 } // Render
 
 } // Internal
index 8d5176e..5cb25be 100644 (file)
@@ -64,6 +64,7 @@ class PropertyInputImpl;
 
 namespace SceneGraph
 {
+class Node;
 class RenderInstruction;
 struct RenderList;
 struct RenderItem;
@@ -109,6 +110,13 @@ void PrintRenderItem( const SceneGraph::RenderItem& item );
  */
 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
index d81f068..335492f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
index d429452..7401280 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -45,6 +45,7 @@ struct RenderItem
 {
   /**
    * Construct a new RenderItem
+   * @return A pointer to a new RenderItem.
    */
   static RenderItem* New();
 
@@ -56,6 +57,7 @@ struct RenderItem
   /**
    * 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 );
 
@@ -78,6 +80,7 @@ private:
   // RenderItems should not be copied as they are heavy
   RenderItem( const RenderItem& item );
   RenderItem& operator = ( const RenderItem& item );
+
 };
 
 } // namespace SceneGraph
@@ -86,4 +89,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H
index 734ad0f..1aef561 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -47,29 +47,17 @@ struct RenderList;
 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 )
@@ -81,44 +69,17 @@ public:
    */
   ~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;
@@ -207,7 +168,7 @@ public:
    */
   bool IsEmpty() const
   {
-    return (mNextFree == 0);
+    return ( mNextFree == 0 );
   }
 
   /**
@@ -219,9 +180,8 @@ public:
   {
     if( clipping )
     {
-      ClippingBox* newBox = new ClippingBox( box );
       delete mClippingBox;
-      mClippingBox = newBox;
+      mClippingBox = new ClippingBox( box );;
     }
   }
 
@@ -230,7 +190,7 @@ public:
    */
   bool IsClipping() const
   {
-    return (NULL != mClippingBox);
+    return ( NULL != mClippingBox );
   }
 
   /**
@@ -306,17 +266,17 @@ private:
   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
index 4dfb27a..021c106 100644 (file)
@@ -625,7 +625,7 @@ void Renderer::Render( Context& context,
   }
 }
 
-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() );
index 0f17f26..fa04275 100644 (file)
@@ -30,7 +30,7 @@
 #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
@@ -50,7 +50,6 @@ class TextureCache;
 class NodeDataProvider;
 }
 
-
 namespace Render
 {
 
@@ -372,7 +371,7 @@ public:
    * @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:
 
@@ -427,11 +426,12 @@ 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;
 
@@ -448,6 +448,7 @@ private:
   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
+
 };
 
 } // namespace SceneGraph
diff --git a/dali/internal/update/manager/prepare-render-instructions.cpp b/dali/internal/update/manager/prepare-render-instructions.cpp
deleted file mode 100644 (file)
index 41616a1..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * 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>
-
-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 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,
-                                     bool isLayer3d,
-                                     bool cull )
-{
-  bool inside( true );
-  if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
-  {
-    const Vector4& boundingSphere = renderable.mNode->GetBoundingSphere();
-    inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
-             (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) );
-  }
-
-  if ( inside )
-  {
-    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
-      renderable.mNode->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 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,
-                                      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, 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 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,
-                               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, 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, 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, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull );
-}
-
-void PrepareRenderInstruction( BufferIndex updateBufferIndex,
-                               SortedLayerPointers& sortedLayers,
-                               RenderTask& renderTask,
-                               RendererSortingHelper& sortingHelper,
-                               bool cull,
-                               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 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,
-                         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
diff --git a/dali/internal/update/manager/prepare-render-instructions.h b/dali/internal/update/manager/prepare-render-instructions.h
deleted file mode 100644 (file)
index 0abbc2b..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#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;
-
-/**
- * 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 );
-
-} // namespace SceneGraph
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__
diff --git a/dali/internal/update/manager/process-render-tasks.h b/dali/internal/update/manager/process-render-tasks.h
deleted file mode 100644 (file)
index 24df0ea..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#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[out] instructions The instructions for rendering the next frame.
- */
-void ProcessRenderTasks( BufferIndex updateBufferIndex,
-                         RenderTaskList& renderTasks,
-                         Layer& rootNode,
-                         SortedLayerPointers& sortedLayers,
-                         RendererSortingHelper& sortingHelper,
-                         RenderInstructionContainer& instructions );
-
-} // namespace SceneGraph
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__
diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp
new file mode 100644 (file)
index 0000000..76dcc26
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * 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/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 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,
+                                     bool isLayer3d,
+                                     bool cull )
+{
+  bool inside( true );
+  if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
+  {
+    const Vector4& boundingSphere = renderable.mNode->GetBoundingSphere();
+    inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
+             (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) );
+  }
+
+  if ( inside )
+  {
+    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.
+      renderable.mNode->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 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,
+                                      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, 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,
+                                          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, 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, 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
diff --git a/dali/internal/update/manager/render-instruction-processor.h b/dali/internal/update/manager/render-instruction-processor.h
new file mode 100644 (file)
index 0000000..a7bcfa3
--- /dev/null
@@ -0,0 +1,148 @@
+#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;
+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]  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,
+                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>
@@ -48,22 +47,13 @@ namespace SceneGraph
 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();
@@ -72,17 +62,17 @@ bool CheckExclusivity( const Node& node, const RenderTask& task )
     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;
     }
@@ -94,45 +84,66 @@ Layer* FindLayer( Node& node )
 }
 
 /**
- * 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 = &currentLayer;
-  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 = &currentLayer;
+    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 )
@@ -142,53 +153,57 @@ bool AddRenderablesForTask( BufferIndex updateBufferIndex,
     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 )
+      // Normal is the more-likely draw mode to occur.
+      if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) )
       {
-        layer->stencilRenderables.PushBack( Renderable(&node, renderer ) );
-      }
-      else if( DrawMode::OVERLAY_2D == inheritedDrawMode )
-      {
-        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,
-                         RenderInstructionContainer& instructions )
+
+} // Anonymous namespace.
+
+
+RenderTaskProcessor::RenderTaskProcessor()
+{
+}
+
+RenderTaskProcessor::~RenderTaskProcessor()
+{
+}
+
+void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
+                                   RenderTaskList& renderTasks,
+                                   Layer& rootNode,
+                                   SortedLayerPointers& sortedLayers,
+                                   RenderInstructionContainer& instructions )
 {
   RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
 
-  if ( taskContainer.IsEmpty() )
+  if( taskContainer.IsEmpty() )
   {
     // Early-exit if there are no tasks to process
     return;
@@ -200,32 +215,30 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
   //   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 )
-    {
-      // Skip to next task
-      continue;
-    }
-
-    if ( !renderTask.ReadyToRender( updateBufferIndex ) )
+    // Off screen only.
+    if( ( ( 0 == renderTask.GetFrameBufferId() ) && ( renderTask.GetFrameBuffer() == 0 ) ) ||
+        ( !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;
     }
@@ -233,7 +246,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
     Layer* layer = FindLayer( *sourceNode );
     if( !layer )
     {
-      // Skip to next task as no layer
+      // Skip to next task as no layer.
       continue;
     }
 
@@ -250,15 +263,21 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
                                                  *sourceNode,
                                                  *layer,
                                                  renderTask,
-                                                 sourceNode->GetDrawMode() );
+                                                 sourceNode->GetDrawMode(),
+                                                 clippingId,
+                                                 0u );
 
       renderTask.SetResourcesFinished( resourcesFinished );
-      PrepareRenderInstruction( updateBufferIndex,
-                                sortedLayers,
-                                renderTask,
-                                sortingHelper,
-                                renderTask.GetCullMode(),
-                                instructions );
+
+      // 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(),
+                                  hasClippingNodes,
+                                  instructions );
     }
     else
     {
@@ -266,30 +285,29 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
     }
   }
 
-  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;
     }
@@ -297,7 +315,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
     Layer* layer = FindLayer( *sourceNode );
     if( !layer )
     {
-      // Skip to next task as no layer
+      // Skip to next task as no layer.
       continue;
     }
 
@@ -305,7 +323,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
     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();
       }
@@ -314,14 +332,19 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
                                                  *sourceNode,
                                                  *layer,
                                                  renderTask,
-                                                 sourceNode->GetDrawMode() );
-
-      PrepareRenderInstruction( updateBufferIndex,
-                                sortedLayers,
-                                renderTask,
-                                sortingHelper,
-                                renderTask.GetCullMode(),
-                                instructions );
+                                                 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(),
+                                  hasClippingNodes,
+                                  instructions );
     }
 
     renderTask.SetResourcesFinished( resourcesFinished );
diff --git a/dali/internal/update/manager/render-task-processor.h b/dali/internal/update/manager/render-task-processor.h
new file mode 100644 (file)
index 0000000..2b69406
--- /dev/null
@@ -0,0 +1,89 @@
+#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[out] instructions      The instructions for rendering the next frame.
+   */
+  void Process( BufferIndex updateBufferIndex,
+                RenderTaskList& renderTasks,
+                Layer& rootNode,
+                SortedLayerPointers& sortedLayers,
+                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
index 6f1fb4d..405d76a 100644 (file)
@@ -150,7 +150,7 @@ inline int UpdateNodes( Node& node,
 
   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 );
index c5f6159..093f779 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -30,6 +30,8 @@
 #include <dali/public-api/math/radian.h>
 #include <dali/public-api/math/vector2.h>
 
+#ifdef DALI_PRINT_UPDATE_INFO
+
 namespace Dali
 {
 
@@ -48,7 +50,6 @@ static Debug::Filter* gNodeLogFilter = Debug::Filter::New(Debug::Verbose, false,
  */
 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);
@@ -94,13 +95,10 @@ void PrintNodes( const Node& node, BufferIndex updateBufferIndex, int level )
   {
     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()
@@ -135,8 +133,6 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden
 
     PrintNodeTree(**iter, bufferIndex, nextIndent);
   }
-
-#endif // DEBUG_ENABLED
 }
 
 } // SceneGraph
@@ -144,3 +140,5 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden
 } // Internal
 
 } // Dali
+
+#endif
index a5f98f4..122abc1 100644 (file)
@@ -1,8 +1,8 @@
-#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
 {
 
@@ -44,4 +49,6 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden
 
 } // Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__
+#endif
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H
index b2a52d9..951c4c5 100644 (file)
@@ -46,7 +46,7 @@
 #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>
@@ -131,7 +131,8 @@ struct UpdateManager::Impl
         RenderController& renderController,
         RenderManager& renderManager,
         RenderQueue& renderQueue,
-        SceneGraphBuffers& sceneGraphBuffers )
+        SceneGraphBuffers& sceneGraphBuffers,
+        RenderTaskProcessor& renderTaskProcessor )
   : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
     notificationManager( notificationManager ),
     transformManager(),
@@ -145,6 +146,7 @@ struct UpdateManager::Impl
     renderManager( renderManager ),
     renderQueue( renderQueue ),
     renderInstructions( renderManager.GetRenderInstructionContainer() ),
+    renderTaskProcessor( renderTaskProcessor ),
     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
     taskList( renderMessageDispatcher, resourceManager ),
     systemLevelTaskList( renderMessageDispatcher, resourceManager ),
@@ -158,7 +160,6 @@ struct UpdateManager::Impl
     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 );
@@ -227,6 +228,7 @@ struct UpdateManager::Impl
   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
+  RenderTaskProcessor&                renderTaskProcessor;           ///< Handles RenderTasks and RenderInstrucitons
 
   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
 
@@ -248,7 +250,7 @@ struct UpdateManager::Impl
   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
 
@@ -264,7 +266,6 @@ struct UpdateManager::Impl
   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
@@ -278,7 +279,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager,
                               RenderController& controller,
                               RenderManager& renderManager,
                               RenderQueue& renderQueue,
-                              TextureCacheDispatcher& textureCacheDispatcher )
+                              TextureCacheDispatcher& textureCacheDispatcher,
+                              RenderTaskProcessor& renderTaskProcessor )
   : mImpl(NULL)
 {
   mImpl = new Impl( notificationManager,
@@ -289,7 +291,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager,
                     controller,
                     renderManager,
                     renderQueue,
-                    mSceneGraphBuffers );
+                    mSceneGraphBuffers,
+                    renderTaskProcessor );
 
   textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
 }
@@ -986,22 +989,20 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
 
     if ( NULL != mImpl->root )
     {
-      ProcessRenderTasks(  bufferIndex,
-                           mImpl->taskList,
-                           *mImpl->root,
-                           mImpl->sortedLayers,
-                           mImpl->renderSortingHelper,
-                           mImpl->renderInstructions );
+      mImpl->renderTaskProcessor.Process( bufferIndex,
+                                        mImpl->taskList,
+                                        *mImpl->root,
+                                        mImpl->sortedLayers,
+                                        mImpl->renderInstructions );
 
       // Process the system-level RenderTasks last
       if ( NULL != mImpl->systemLevelRoot )
       {
-        ProcessRenderTasks(  bufferIndex,
-                             mImpl->systemLevelTaskList,
-                             *mImpl->systemLevelRoot,
-                             mImpl->systemLevelSortedLayers,
-                             mImpl->renderSortingHelper,
-                             mImpl->renderInstructions );
+        mImpl->renderTaskProcessor.Process( bufferIndex,
+                                          mImpl->systemLevelTaskList,
+                                          *mImpl->systemLevelRoot,
+                                          mImpl->systemLevelSortedLayers,
+                                          mImpl->renderInstructions );
       }
     }
   }
index e90ab9d..9a285d3 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -75,6 +75,7 @@ class DiscardQueue;
 class PanGesture;
 class RenderManager;
 class RenderTaskList;
+class RenderTaskProcessor;
 class RenderQueue;
 class TextureCacheDispatcher;
 class PropertyBuffer;
@@ -104,6 +105,7 @@ public:
    * @param[in] renderManager This is responsible for rendering the results of each "update".
    * @param[in] renderQueue Used to queue messages for the next render.
    * @param[in] textureCacheDispatcher Used for sending messages to texture cache.
+   * @param[in] renderTaskProcessor Handles RenderTasks and RenderInstrucitons.
    */
   UpdateManager( NotificationManager& notificationManager,
                  CompleteNotificationInterface& animationFinishedNotifier,
@@ -113,7 +115,8 @@ public:
                  Integration::RenderController& controller,
                  RenderManager& renderManager,
                  RenderQueue& renderQueue,
-                 TextureCacheDispatcher& textureCacheDispatcher );
+                 TextureCacheDispatcher& textureCacheDispatcher,
+                 RenderTaskProcessor& renderTaskProcessor );
 
   /**
    * Destructor.
@@ -1278,10 +1281,11 @@ inline void AttachColorTextureToFrameBuffer( UpdateManager& manager, Render::Fra
   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
index b3a9767..e873a6f 100644 (file)
@@ -53,26 +53,29 @@ Node::Node()
   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 ),
+  mClippingSortModifier( 0u ),
   mParent( 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;
index 4846122..0712b53 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -45,9 +45,10 @@ namespace Dali
 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
 {
@@ -69,7 +70,7 @@ enum NodePropertyFlags
   SizeFlag             = 0x008,
   OverlayFlag          = 0x010,
   SortModifierFlag     = 0x020,
-  ChildDeletedFlag     = 0x040
+  ChildDeletedFlag     = 0x040,
 };
 
 static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
@@ -142,6 +143,65 @@ public:
   }
 
   /**
+   * 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
    */
@@ -669,15 +729,11 @@ public:
 
   /**
    * 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
@@ -781,47 +837,49 @@ private:
 
 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
+
+  uint32_t                           mClippingSortModifier;   ///< Contains bit-packed clipping information for quick access when sorting
 
 protected:
 
-  Node*               mParent;                       ///< Pointer to parent node (a child is owned by its parent)
-  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)
+  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;
@@ -927,10 +985,23 @@ inline void RemoveRendererMessage( EventThreadServices& eventThreadServices, con
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::RemoveRenderer, renderer );
 }
+
+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 Internal
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_H_
+#endif // DALI_INTERNAL_SCENE_GRAPH_NODE_H
index 1d920be..573ccee 100644 (file)
@@ -102,7 +102,6 @@ bool Layer::IsDepthTestDisabled() const
 
 void Layer::ClearRenderables()
 {
-  stencilRenderables.Clear();
   colorRenderables.Clear();
   overlayRenderables.Clear();
 }
index 89823a8..e036df1 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -45,13 +45,13 @@ class Camera;
 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;
@@ -222,13 +222,12 @@ private:
 
 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
@@ -236,8 +235,8 @@ private:
   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
@@ -337,4 +336,4 @@ inline void SetDepthTestDisabledMessage( EventThreadServices& eventThreadService
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_LAYER_H
index b1926ba..75df93d 100644 (file)
@@ -155,15 +155,15 @@ Renderer::Renderer()
 
 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;
   }
 }
 
@@ -647,7 +647,6 @@ Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Nod
     }
   }
 
-
   return opacity;
 }
 
index 61605b6..a68db0f 100644 (file)
@@ -30,6 +30,7 @@
 
 namespace Dali
 {
+
 namespace Internal
 {
 
@@ -362,7 +363,7 @@ private:
   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
index bed10d2..78b861d 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -59,18 +59,18 @@ enum PositionInheritanceMode
  */
 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
+  };
 }
 
 /**
@@ -79,18 +79,18 @@ enum Meta
  */
 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
 }
 
 /**
@@ -99,12 +99,12 @@ 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
+  };
 }
 
 /**
@@ -113,12 +113,12 @@ enum Type
  */
 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
+  };
 }
 
 /**
@@ -127,17 +127,31 @@ enum Type
  */
 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
index 1040218..4e9731b 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -28,6 +28,7 @@
 #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
 {
 /**
@@ -249,59 +250,60 @@ public:
   {
     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
+      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
     };
   };
 
@@ -1115,14 +1117,9 @@ public:
    * 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 );
@@ -1585,4 +1582,4 @@ inline void UnparentAndReset( Actor& actor )
  */
 } // namespace Dali
 
-#endif // __DALI_ACTOR_H__
+#endif // DALI_ACTOR_H
index 2f15cc8..8498550 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -360,7 +360,6 @@ public:
    * 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
@@ -485,4 +484,4 @@ public: // Not intended for application developers
  */
 } // namespace Dali
 
-#endif //__DALI_LAYER_H__
+#endif // DALI_LAYER_H