Removed Overlay override from hit-test-algorithm 45/41345/16
authorRichard Underhill <r.underhill@partner.samsung.com>
Thu, 18 Jun 2015 12:22:22 +0000 (13:22 +0100)
committerRichard Underhill <r.underhill@partner.samsung.com>
Thu, 18 Jun 2015 13:21:48 +0000 (14:21 +0100)
Change-Id: I3466823d209986261d0ffc2327313334c71a3091
Signed-off-by: Richard Underhill <r.underhill@partner.samsung.com>
12 files changed:
automated-tests/src/dali-internal/utc-Dali-HitTestAlgorithm.cpp
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-HoverProcessing.cpp
automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
dali/internal/event/actors/image-actor-impl.cpp
dali/internal/event/actors/image-actor-impl.h
dali/internal/event/events/hit-test-algorithm-impl.cpp
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/public-api/actors/image-actor.cpp
dali/public-api/actors/image-actor.h

index 891d6c7..ecde51d 100644 (file)
@@ -217,15 +217,14 @@ int UtcDaliHitTestAlgorithmWithFunctorOnRenderTask(void)
   DALI_TEST_CHECK( results.actor == actor[1]);
   DALI_TEST_EQUALS( screenCoordinates - position, results.actorCoordinates, 0.1f, TEST_LOCATION );
 
-
   screenCoordinates.x = 120.f;
   screenCoordinates.y = 130.f;
 
   results.actor = Actor();
   results.actorCoordinates = Vector2::ZERO;
   Dali::HitTestAlgorithm::HitTest( renderTask[0], screenCoordinates, results, IsActorHittableFunction );
-  DALI_TEST_CHECK( results.actor == actor[1] );
-  DALI_TEST_EQUALS( screenCoordinates - position, results.actorCoordinates, 0.1f, TEST_LOCATION );
+  DALI_TEST_CHECK( !results.actor );
+  DALI_TEST_EQUALS( Vector2::ZERO, results.actorCoordinates, 0.1f, TEST_LOCATION );
 
   results.actor = Actor();
   results.actorCoordinates = Vector2::ZERO;
index 412936f..44a83f3 100644 (file)
@@ -42,7 +42,6 @@ void utc_dali_actor_cleanup(void)
 namespace
 {
 bool gTouchCallBackCalled=false;
-bool gTouchCallBack2Called=false;
 bool gHoverCallBackCalled=false;
 
 /**
@@ -57,7 +56,6 @@ int SimulateTouchForSetOverlayHitTest(TestApplication& app)
   app.Render(1);
 
   gTouchCallBackCalled = false;
-  gTouchCallBack2Called = false;
 
   // simulate a touch event
   Dali::TouchPoint point( 0, TouchPoint::Down, 25.0f, 25.0f );
@@ -113,13 +111,6 @@ static bool TestCallback(Actor actor, const TouchEvent& event)
   END_TEST;
 }
 
-static bool TestCallback2(Actor actor, const TouchEvent& event)
-{
-  gTouchCallBack2Called = true;
-  return false;
-  END_TEST;
-}
-
 static bool TestCallback3(Actor actor, const HoverEvent& event)
 {
   gHoverCallBackCalled = true;
@@ -2318,89 +2309,6 @@ int UtcDaliActorSetDrawModeOverlayRender(void)
   END_TEST;
 }
 
-
-int UtcDaliActorSetDrawModeOverlayHitTest(void)
-{
-  TestApplication app;
-  tet_infoline(" UtcDaliActorSetDrawModeOverlayHitTest");
-
-  BufferImage imageA = BufferImage::New(16, 16);
-  BufferImage imageB = BufferImage::New(16, 16);
-  ImageActor a = ImageActor::New( imageA );
-  ImageActor b = ImageActor::New( imageB );
-
-  // Render a,b as regular non-overlays. so order will be:
-  Stage::GetCurrent().Add(a);
-  Stage::GetCurrent().Add(b);
-
-  a.SetSize( 100.0f, 100.0f );
-  b.SetSize( 100.0f, 100.0f );
-
-  // position b overlapping a. (regular non-overlays)
-  // hit test at point 'x'
-  // --------
-  // |      |
-  // | a    |
-  // |   --------
-  // |   |x     |
-  // |   |      |
-  // ----|      |
-  //     |   b  |
-  //     |      |
-  //     --------
-  // note: b is on top, because it's Z position is higher.
-  a.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
-  b.SetPosition(Vector3(50.0f, 50.0f, 1.0f));
-
-  // connect to their touch signals
-  a.TouchedSignal().Connect(TestCallback);
-  b.TouchedSignal().Connect(TestCallback2);
-
-  a.SetDrawMode( DrawMode::NORMAL );
-  b.SetDrawMode( DrawMode::NORMAL );
-  SimulateTouchForSetOverlayHitTest(app);
-
-  DALI_TEST_CHECK( gTouchCallBackCalled == false );
-  DALI_TEST_CHECK( gTouchCallBack2Called == true );
-  // Make Actor a an overlay.
-  // --------
-  // |      |
-  // | a    |
-  // |      |----
-  // |    x |   |
-  // |      |   |
-  // --------   |
-  //     |   b  |
-  //     |      |
-  //     --------
-  // note: a is on top, because it is an overlay.
-  a.SetDrawMode( DrawMode::OVERLAY );
-  b.SetDrawMode( DrawMode::NORMAL );
-  SimulateTouchForSetOverlayHitTest(app);
-
-  DALI_TEST_CHECK( gTouchCallBackCalled == true );
-  DALI_TEST_CHECK( gTouchCallBack2Called == false );
-  // Make both Actors as overlays
-  // --------
-  // |      |
-  // | a    |
-  // |   --------
-  // |   |x     |
-  // |   |      |
-  // ----|      |
-  //     |   b  |
-  //     |      |
-  //     --------
-  // note: b is on top, because it is the 2nd child in the hierarchy.
-  a.SetDrawMode( DrawMode::OVERLAY );
-  b.SetDrawMode( DrawMode::OVERLAY );
-  SimulateTouchForSetOverlayHitTest(app);
-
-  DALI_TEST_CHECK( gTouchCallBackCalled == false );
-  DALI_TEST_CHECK( gTouchCallBack2Called == true );
-  END_TEST;
-}
-
 int UtcDaliActorGetCurrentWorldMatrix(void)
 {
   TestApplication app;
index 3eae1df..840ae91 100644 (file)
@@ -1006,14 +1006,15 @@ int UtcDaliHoverMultipleRenderableActors(void)
   Stage stage ( Stage::GetCurrent() );
   Vector2 stageSize ( stage.GetSize() );
 
-  Actor parent = ImageActor::New();
+  ImageActor parent = ImageActor::New();
   parent.SetSize( 100.0f, 100.0f );
   parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   stage.Add(parent);
 
-  Actor actor = ImageActor::New();
+  ImageActor actor = ImageActor::New();
   actor.SetSize( 100.0f, 100.0f );
   actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor.SetDepthIndex( 1 );
   parent.Add(actor);
 
   // Render and notify
index 1d46199..e076475 100644 (file)
@@ -1000,14 +1000,15 @@ int UtcDaliTouchMultipleRenderableActors(void)
   Stage stage ( Stage::GetCurrent() );
   Vector2 stageSize ( stage.GetSize() );
 
-  Actor parent = ImageActor::New();
+  ImageActor parent = ImageActor::New();
   parent.SetSize(100.0f, 100.0f);
   parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   stage.Add(parent);
 
-  Actor actor = ImageActor::New();
+  ImageActor actor = ImageActor::New();
   actor.SetSize(100.0f, 100.0f);
   actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  actor.SetDepthIndex( 1 );
   parent.Add(actor);
 
   // Render and notify
index e8f2851..a2188c4 100644 (file)
@@ -462,7 +462,7 @@ Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
 
 void ImageActor::SetSortModifier(float modifier)
 {
-  mImageAttachment->SetSortModifier(modifier);
+  mImageAttachment->SetSortModifier( modifier );
 }
 
 float ImageActor::GetSortModifier() const
@@ -470,6 +470,16 @@ float ImageActor::GetSortModifier() const
   return mImageAttachment->GetSortModifier();
 }
 
+void ImageActor::SetDepthIndex( int depthIndex )
+{
+   mImageAttachment->SetSortModifier( depthIndex );
+}
+
+int ImageActor::GetDepthIndex() const
+{
+  return static_cast< int >( GetSortModifier() );
+}
+
 void ImageActor::SetCullFace(CullFaceMode mode)
 {
   mImageAttachment->SetCullFace( mode );
index 49aac5a..ae8c9dd 100644 (file)
@@ -136,6 +136,16 @@ public:
   float GetSortModifier() const;
 
   /**
+   * @copydoc Dali::RenderableActor::SetDepthIndex()
+   */
+  void SetDepthIndex( int depthIndex );
+
+  /**
+   * @copydoc Dali::RenderableActor::GetDepthIndex()
+   */
+  int GetDepthIndex() const;
+
+  /**
    * @copydoc Dali::RenderableActor::SetCullFace()
    */
   void SetCullFace(CullFaceMode mode);
index e43d5fa..218c779 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/actors/camera-actor-impl.h>
+#include <dali/internal/event/actors/image-actor-impl.h>
 #include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/actors/layer-list.h>
 #include <dali/internal/event/actors/renderable-actor-impl.h>
@@ -54,16 +55,15 @@ struct HitActor
     x( 0 ),
     y( 0 ),
     distance( std::numeric_limits<float>::max() ),
-    overlay( false )
+    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
-  bool overlay;                         ///< true if the hit actor is an overlay
+  int depth;                            ///< depth index of this actor
 
 };
 
@@ -128,20 +128,43 @@ struct ActorTouchableCheck : public HitTestInterface
 };
 
 /**
+ * Check to see if the actor we're about to hit test is exclusively owned by another rendertask?
+ */
+bool IsActorExclusiveToAnotherRenderTask( const Actor& actor,
+                                          const RenderTask& renderTask,
+                                          const Vector< RenderTaskList::Exclusive >& exclusives )
+
+{
+  if ( exclusives.Size() )
+  {
+    for ( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt )
+    {
+      if ( exclusiveIt->renderTaskPtr != &renderTask )
+      {
+        if ( exclusiveIt->actorPtr == &actor )
+        {
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
+/**
  * Recursively hit test all the actors, without crossing into other layers.
  * This algorithm performs a Depth-First-Search (DFS) on all Actors within Layer.
  * Hit-Testing each Actor, noting the distance from the Ray-Origin (3D origin
  * of touch vector). The closest Hit-Tested Actor is that which is returned.
  * Exceptions to this rule are:
- * - If the Actor is an overlay then it is considered closer than all previous
- * overlays encountered in the hit test traversal.
  * - When comparing against renderable parents, if Actor is the same distance
  * or closer than it's renderable parent, then it takes priority.
  */
 HitActor HitTestWithinLayer( Actor& actor,
+                             const RenderTask& renderTask,
+                             const Vector< RenderTaskList::Exclusive >& exclusives,
                              const Vector4& rayOrigin,
                              const Vector4& rayDir,
-                             bool worldOverlay,
                              float& nearClippingPlane,
                              float& farClippingPlane,
                              HitTestInterface& hitCheck,
@@ -149,10 +172,13 @@ HitActor HitTestWithinLayer( Actor& actor,
                              bool& stencilHit,
                              bool parentIsStencil )
 {
-  worldOverlay |= actor.IsOverlay();
-
   HitActor hit;
 
+  if ( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) )
+  {
+    return hit;
+  }
+
   // Children should inherit the stencil draw mode
   bool isStencil = parentIsStencil;
 
@@ -189,7 +215,23 @@ HitActor HitTestWithinLayer( Actor& actor,
             hit.x = hitPointLocal.x;
             hit.y = hitPointLocal.y;
             hit.distance = distance;
-            hit.overlay = worldOverlay;
+
+            // Is this actor an Image Actor or contains a renderer?
+            if ( ImageActor* imageActor = dynamic_cast< ImageActor* >( &actor ) )
+            {
+              hit.depth = imageActor->GetDepthIndex();
+            }
+            else
+            {
+              if ( actor.GetRendererCount() )
+              {
+                hit.depth = actor.GetRendererAt( 0 ).GetCurrentDepthIndex();
+              }
+              else
+              {
+                hit.depth = 0;
+              }
+            }
           }
         }
       }
@@ -207,6 +249,7 @@ HitActor HitTestWithinLayer( Actor& actor,
   if( actor.GetChildCount() > 0 )
   {
     childHit.distance = std::numeric_limits<float>::max();
+    childHit.depth = std::numeric_limits<int>::min();
     ActorContainer& children = actor.GetChildrenInternal();
 
     // Hit test ALL children and calculate their distance.
@@ -218,25 +261,45 @@ HitActor HitTestWithinLayer( Actor& actor,
       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( &GetImplementation( *iter ) ) ) ) // We are a stencil OR we can descend into child hierarchy
       {
-        HitActor currentHit( HitTestWithinLayer( GetImplementation(*iter), rayOrigin, rayDir, worldOverlay, nearClippingPlane, farClippingPlane, hitCheck, stencilOnLayer, stencilHit, isStencil ) );
-
-        // If Current child is an overlay, then it takes priority.
-        // If it is not an overlay, and the previously hit sibling is also not an overlay, then closest takes priority.
-        // (last overlay sibling has priority as is rendered on top)
-        if ( currentHit.distance >= 0.f && (currentHit.overlay || (!childHit.overlay && currentHit.distance < childHit.distance) ) )
+        HitActor currentHit( HitTestWithinLayer(  GetImplementation(*iter),
+                                                  renderTask,
+                                                  exclusives,
+                                                  rayOrigin,
+                                                  rayDir,
+                                                  nearClippingPlane,
+                                                  farClippingPlane,
+                                                  hitCheck,
+                                                  stencilOnLayer,
+                                                  stencilHit,
+                                                  isStencil ) );
+
+        bool updateChildHit = false;
+        // If our ray casting hit, then check then if the hit actor's depth is greater that the favorite, it will be preferred
+        if ( currentHit.distance >= 0.0f )
         {
-          if ( !parentIsRenderable )
+          if ( currentHit.depth > childHit.depth )
           {
-            // If our parent is not renderable, then child should be hit regardless of distance.
-            childHit = currentHit;
+            updateChildHit = true;
           }
-          else if ( currentHit.overlay || (!hit.overlay && currentHit.distance <= hit.distance) )
+
+          // If the hit actor's depth is equal to current favorite, then we check the distance and prefer the closer
+          else if ( currentHit.depth == childHit.depth )
           {
-            // If our parent is renderable, then child should only be hit if it is an overlay, or if it is closer than a non-overlay.
-            // (child overlay has priority as is rendered on top of it's parent)
-            childHit = currentHit;
+            if ( currentHit.distance < childHit.distance )
+            {
+              updateChildHit = true;
+            }
           }
         }
+
+        if ( updateChildHit )
+        {
+          if( !parentIsRenderable || currentHit.depth > hit.depth ||
+            ( currentHit.depth == hit.depth && currentHit.distance < hit.distance ) )
+            {
+              childHit = currentHit;
+            }
+        }
       }
     }
   }
@@ -318,7 +381,8 @@ void GetCameraClippingPlane( RenderTask& renderTask, float& nearClippingPlane, f
 /**
  * Hit test a RenderTask
  */
-bool HitTestRenderTask( LayerList& layers,
+bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
+                        LayerList& layers,
                         RenderTask& renderTask,
                         Vector2 screenCoordinates,
                         Results& results,
@@ -370,7 +434,6 @@ bool HitTestRenderTask( LayerList& layers,
         for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i)
         {
           Layer* layer( layers.GetLayer(i) );
-
           HitActor previousHit = hit;
           stencilOnLayer = false;
           stencilHit = false;
@@ -382,12 +445,32 @@ bool HitTestRenderTask( LayerList& layers,
             if ( sourceActorDepth == static_cast<unsigned int>(i) )
             {
               // Recursively hit test the source actor & children, without crossing into other layers.
-              hit = HitTestWithinLayer( *sourceActor, results.rayOrigin, results.rayDirection, false, nearClippingPlane, farClippingPlane, hitCheck, stencilOnLayer, stencilHit, false );
+              hit = HitTestWithinLayer( *sourceActor,
+                                        renderTask,
+                                        exclusives,
+                                        results.rayOrigin,
+                                        results.rayDirection,
+                                        nearClippingPlane,
+                                        farClippingPlane,
+                                        hitCheck,
+                                        stencilOnLayer,
+                                        stencilHit,
+                                        false );
             }
             else if ( IsWithinSourceActors( *sourceActor, *layer ) )
             {
               // Recursively hit test all the actors, without crossing into other layers.
-              hit = HitTestWithinLayer( *layer, results.rayOrigin, results.rayDirection, false, nearClippingPlane, farClippingPlane, hitCheck, stencilOnLayer, stencilHit, false );
+              hit = HitTestWithinLayer( *layer,
+                                        renderTask,
+                                        exclusives,
+                                        results.rayOrigin,
+                                        results.rayDirection,
+                                        nearClippingPlane,
+                                        farClippingPlane,
+                                        hitCheck,
+                                        stencilOnLayer,
+                                        stencilHit,
+                                        false );
             }
 
             // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable
@@ -437,6 +520,8 @@ bool HitTestForEachRenderTask( LayerList& layers,
   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
@@ -458,7 +543,7 @@ bool HitTestForEachRenderTask( LayerList& layers,
       }
     }
 
-    if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, hitCheck ) )
+    if ( HitTestRenderTask( exclusives, 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
@@ -483,7 +568,7 @@ bool HitTestForEachRenderTask( LayerList& layers,
         continue;
       }
 
-      if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, hitCheck ) )
+      if ( HitTestRenderTask( exclusives, layers, renderTask, screenCoordinates, results, hitCheck ) )
       {
         // Return true when an actor is hit (or a layer in our render-task consumes the hit)
         return true;
@@ -551,8 +636,9 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin
   bool wasHit( false );
   Results hitTestResults;
 
+  const Vector< RenderTaskList::Exclusive >& exclusives = Stage::GetCurrent()->GetRenderTaskList().GetExclusivesList();
   HitTestFunctionWrapper hitTestFunctionWrapper( func );
-  if ( HitTestRenderTask( stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  if ( HitTestRenderTask( exclusives, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
   {
     results.actor = hitTestResults.actor;
     results.actorCoordinates = hitTestResults.actorCoordinates;
index ff8c400..84d24bd 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/images/frame-buffer-image-impl.h>
 #include <dali/internal/update/nodes/node.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
 
 #if defined(DEBUG_ENABLED)
@@ -77,6 +78,11 @@ RenderTask* RenderTask::New( bool isSystemLevel )
 
 void RenderTask::SetSourceActor( Actor* actor )
 {
+  const Stage* stage = Stage::GetCurrent();
+  if ( stage )
+  {
+    stage->GetRenderTaskList().SetExclusive( this, mExclusive );
+  }
   mSourceConnector.SetActor( actor );
 }
 
@@ -91,6 +97,12 @@ void RenderTask::SetExclusive( bool exclusive )
   {
     mExclusive = exclusive;
 
+    const Stage* stage = Stage::GetCurrent();
+    if ( stage )
+    {
+      stage->GetRenderTaskList().SetExclusive( this, exclusive );
+    }
+
     if ( mSceneObject )
     {
       // mSceneObject is being used in a separate thread; queue a message to set the value
index df9d7e1..e7da30b 100644 (file)
@@ -81,10 +81,9 @@ void RenderTaskList::RemoveTask( Dali::RenderTask task )
   {
     if ( *iter == task )
     {
+      RenderTask& taskImpl = GetImplementation( task );
       if ( mSceneObject )
       {
-        RenderTask& taskImpl = GetImplementation( task );
-
         SceneGraph::RenderTask* sceneObject = taskImpl.GetRenderTaskSceneObject();
         DALI_ASSERT_DEBUG( NULL != sceneObject );
 
@@ -96,6 +95,15 @@ void RenderTaskList::RemoveTask( Dali::RenderTask task )
       }
 
       mTasks.erase( iter );
+
+      for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
+      {
+        if ( exclusiveIt->renderTaskPtr == &taskImpl )
+        {
+          mExclusives.Erase( exclusiveIt );
+          break;
+        }
+      }
       break; // we're finished
     }
   }
@@ -113,6 +121,35 @@ Dali::RenderTask RenderTaskList::GetTask( unsigned int index ) const
   return mTasks[index];
 }
 
+void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive )
+{
+  // Check to see if this rendertask has an entry?
+  for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
+  {
+    if ( exclusiveIt->renderTaskPtr == task )
+    {
+      if ( !exclusive )
+      {
+        mExclusives.Erase( exclusiveIt );
+        break;
+      }
+      else
+      {
+        exclusiveIt->actorPtr = task->GetSourceActor();
+        exclusive = false;
+        break;
+      }
+    }
+  }
+  if ( exclusive )
+  {
+    Exclusive exclusiveSlot;
+    exclusiveSlot.renderTaskPtr = task;
+    exclusiveSlot.actorPtr = task->GetSourceActor();
+    mExclusives.PushBack( exclusiveSlot );
+  }
+}
+
 RenderTaskList::RenderTaskList( EventThreadServices& eventThreadServices, RenderTaskDefaults& defaults, bool systemLevel )
 : mEventThreadServices( eventThreadServices ),
   mDefaults( defaults ),
index c82c917..3216793 100644 (file)
@@ -33,6 +33,7 @@ namespace Internal
 
 class EventThreadServices;
 class RenderTaskDefaults;
+class Actor;
 
 namespace SceneGraph
 {
@@ -50,6 +51,12 @@ public:
 
   typedef std::vector< Dali::RenderTask > RenderTaskContainer;
 
+  struct Exclusive
+  {
+    RenderTask* renderTaskPtr;        ///< Pointer for comparison with current rendertask.
+    Actor* actorPtr;                  ///< Pointer for comparison with current actor.
+  };
+
   /**
    * Create a RenderTaskList.
    * @param[in] eventServices Used for sending message to the scene graph.
@@ -89,6 +96,24 @@ public:
   }
 
   /**
+   * @brief Mark a rendertask as having exclusive access to its source actor.
+   *
+   * @param[in] task Pointer to the rendertask.
+   * @param[in] exclusive If a rendertask is to have exclusive acesss to its source actor.
+   */
+  void SetExclusive( RenderTask* task, bool exclusive );
+
+  /**
+   * @brief Return the list of rendertasks that exclusively own their source actor.
+   *
+   * @return [description]
+   */
+  const Vector< Exclusive >& GetExclusivesList() const
+  {
+    return mExclusives;
+  }
+
+  /**
    * Provide notification signals for a "Finished" render task.
    * This method should be called in the event-thread
    * Queue NotifyFinishedMessage() from update-thread
@@ -138,7 +163,8 @@ private:
 
   SceneGraph::RenderTaskList* mSceneObject; ///< Raw-pointer to the scene-graph object; not owned.
 
-  RenderTaskContainer mTasks; ///< Reference counted render-tasks
+  RenderTaskContainer mTasks;           ///< Reference counted render-tasks
+  Vector< Exclusive > mExclusives;      ///< List of rendertasks with exclusively owned source actors.
 };
 
 } // namespace Internal
index da3cf18..2773159 100644 (file)
@@ -130,6 +130,16 @@ float ImageActor::GetSortModifier() const
   return GetImplementation(*this).GetSortModifier();
 }
 
+void ImageActor::SetDepthIndex( int depthIndex )
+{
+  GetImplementation(*this).SetDepthIndex( depthIndex );
+}
+
+int ImageActor::GetDepthIndex() const
+{
+  return GetImplementation(*this).GetDepthIndex();
+}
+
 void ImageActor::SetCullFace(const CullFaceMode mode)
 {
   GetImplementation(*this).SetCullFace(mode);
index 158f9fb..0f91e38 100644 (file)
@@ -318,6 +318,24 @@ public:
   float GetSortModifier() const;
 
   /**
+   * @brief Sets the depth index within a layer for the depth sort algorithm.
+   *
+   * This is intended to replace SetSortModifier, which will be deprecated and remains currently for backwards compatibility.
+   *
+   * @param[in] depthIndex The depth index to use for sorting within a layer.
+   */
+  void SetDepthIndex( int depthIndex );
+
+  /**
+   * @brief Retrieves the depth index within a layer.
+   *
+   * This will replace GetSortModifier in the same manner as SetDepthIndex.
+   *
+   * @return The depth index used for sorting within a layer.
+   */
+  int GetDepthIndex() const;
+
+  /**
    * @brief Set the face-culling mode for this actor.
    *
    * @param[in] mode The culling mode.