Merge "Removed some junk from Makefile.am" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / events / hit-test-algorithm-impl.cpp
index 7ebf256..604f71e 100644 (file)
@@ -1,35 +1,38 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.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://floralicense.org/license/
-//
-// 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.
-//
+/*
+ * Copyright (c) 2014 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/event/events/hit-test-algorithm-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/system-overlay.h>
+#include <dali/public-api/actors/layer.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector4.h>
 #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>
 #include <dali/internal/event/common/system-overlay-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/images/frame-buffer-image-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
 
@@ -52,54 +55,100 @@ 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
 
 };
 
 /**
- * The function to be used in the hit-test algorithm to check whether the actor is touchable.
- * It is used by the touch event and gesture processor.
+ * Creates an Actor handle so that a HitTestFunction provided via the public API can be called.
  */
-bool IsActorTouchableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type)
+struct HitTestFunctionWrapper : public HitTestInterface
 {
-  bool hittable = false;
+  /**
+   * Constructor
+   *
+   * @param[in] func HitTestFunction to call with an Actor handle.
+   */
+  HitTestFunctionWrapper( Dali::HitTestAlgorithm::HitTestFunction func )
+  : mFunc( func )
+  {
+  }
 
-  switch (type)
+  virtual bool IsActorHittable( Actor* actor )
   {
-    case Dali::HitTestAlgorithm::CHECK_ACTOR:
-    {
-      if( GetImplementation(actor).GetTouchRequired() && // Does the Application or derived actor type require a touch event?
-          GetImplementation(actor).IsHittable() ) // Is actor sensitive, visible and on the scene?
-      {
-        hittable = true;
-      }
-      break;
-    }
-    case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
+    return mFunc( Dali::Actor( actor ), Dali::HitTestAlgorithm::CHECK_ACTOR );
+  }
+
+  virtual bool DescendActorHierarchy( Actor* actor )
+  {
+    return mFunc( Dali::Actor( actor ), Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE );
+  }
+
+  virtual bool DoesLayerConsumeHit( Layer* layer )
+  {
+    // Layer::IsTouchConsumed() focuses on touch only. Here we are a wrapper for the public-api
+    // where the caller may want to check for something completely different.
+    // TODO: Should provide a means to let caller decide. For now do not allow layers to consume
+    return false;
+  }
+
+  Dali::HitTestAlgorithm::HitTestFunction mFunc;
+};
+
+/**
+ * Used in the hit-test algorithm to check whether the actor is touchable.
+ * It is used by the touch event processor.
+ */
+struct ActorTouchableCheck : public HitTestInterface
+{
+  virtual bool IsActorHittable( Actor* actor )
+  {
+    return actor->GetTouchRequired() && // Does the Application or derived actor type require a touch event?
+           actor->IsHittable();         // Is actor sensitive, visible and on the scene?
+  }
+
+  virtual bool DescendActorHierarchy( Actor* actor )
+  {
+    return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
+           actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
+  }
+
+  virtual bool DoesLayerConsumeHit( Layer* layer )
+  {
+    return layer->IsTouchConsumed();
+  }
+};
+
+/**
+ * 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( actor.IsVisible() &&     // Actor is visible, if not visible then none of its children are visible.
-          actor.IsSensitive() )    // Actor is sensitive, if insensitive none of its children should be hittable either.
+      if ( exclusiveIt->renderTaskPtr != &renderTask )
       {
-        hittable = true;
+        if ( exclusiveIt->actorPtr == &actor )
+        {
+          return true;
+        }
       }
-      break;
-    }
-    default:
-    {
-      break;
     }
   }
-
-  return hittable;
+  return false;
 }
 
 /**
@@ -108,26 +157,29 @@ bool IsActorTouchableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::Travers
  * 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,
-                             Dali::HitTestAlgorithm::HitTestFunction func,
+                             HitTestInterface& hitCheck,
                              bool& stencilOnLayer,
                              bool& stencilHit,
-                             bool parentIsStencil )
+                             bool parentIsStencil,
+                             bool layerIs3d )
 {
-  worldOverlay |= actor.IsOverlay();
-
   HitActor hit;
 
+  if ( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) )
+  {
+    return hit;
+  }
+
   // Children should inherit the stencil draw mode
   bool isStencil = parentIsStencil;
 
@@ -138,11 +190,11 @@ HitActor HitTestWithinLayer( Actor& actor,
   }
 
   // If we are a stencil or hittable...
-  if ( isStencil || func(Dali::Actor(&actor), Dali::HitTestAlgorithm::CHECK_ACTOR) ) // Is actor hittable
+  if ( isStencil || hitCheck.IsActorHittable( &actor ) )
   {
     Vector3 size( actor.GetCurrentSize() );
 
-    if ( size.x > 0.0f && size.y > 0.0f &&              // Ensure the actor has a valid size.
+    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.
     {
       Vector4 hitPointLocal;
@@ -164,15 +216,30 @@ HitActor HitTestWithinLayer( Actor& actor,
             hit.x = hitPointLocal.x;
             hit.y = hitPointLocal.y;
             hit.distance = distance;
-            hit.overlay = worldOverlay;
+            hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER;
+
+            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)
+              {
+                int depth = actor.GetRendererAt( i ).Get()->GetDepthIndex();
+                if( depth > rendererMaxDepth )
+                {
+                  rendererMaxDepth = depth;
+                }
+              }
+              hit.depth += rendererMaxDepth;
+            }
           }
         }
       }
     }
   }
 
-  // If there is a stencil on this layer and we've also registered a hit, then don't both searching any children
-  if ( stencilHit && hit.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;
   }
@@ -182,36 +249,53 @@ HitActor HitTestWithinLayer( Actor& actor,
   if( actor.GetChildCount() > 0 )
   {
     childHit.distance = std::numeric_limits<float>::max();
-    Dali::ActorContainer& children = actor.GetChildrenInternal();
+    childHit.depth = std::numeric_limits<int>::min();
+    ActorContainer& children = actor.GetChildrenInternal();
 
     // Hit test ALL children and calculate their distance.
     bool parentIsRenderable = actor.IsRenderable();
 
-    for (Dali::ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter)
+    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 || func(*iter, Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE ) ) ) // Child is visible and sensitive, otherwise none of its children should be hittable.
+      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
       {
-        HitActor currentHit( HitTestWithinLayer( GetImplementation(*iter), rayOrigin, rayDir, worldOverlay, nearClippingPlane, farClippingPlane, func, 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(  (*iter->Get()),
+                                                  renderTask,
+                                                  exclusives,
+                                                  rayOrigin,
+                                                  rayDir,
+                                                  nearClippingPlane,
+                                                  farClippingPlane,
+                                                  hitCheck,
+                                                  stencilOnLayer,
+                                                  stencilHit,
+                                                  isStencil,
+                                                  layerIs3d) );
+
+        bool updateChildHit = false;
+        if ( currentHit.distance >= 0.0f )
         {
-          if ( !parentIsRenderable )
+          if( layerIs3d )
           {
-            // If our parent is not renderable, then child should be hit regardless of distance.
-            childHit = currentHit;
+            updateChildHit = ( ( currentHit.depth > childHit.depth ) ||
+                ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) );
           }
-          else if ( currentHit.overlay || (!hit.overlay && currentHit.distance <= hit.distance) )
+          else
           {
-            // 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;
+            updateChildHit = currentHit.depth >= childHit.depth;
           }
         }
+
+        if ( updateChildHit )
+        {
+          if( !parentIsRenderable || currentHit.depth > hit.depth ||
+            ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) )
+            {
+              childHit = currentHit;
+            }
+        }
       }
     }
   }
@@ -243,7 +327,7 @@ bool IsWithinSourceActors( const Actor& sourceActor, const Actor& actor )
 /**
  * Returns true if the layer and all of the layer's parents are visible and sensitive.
  */
-inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, const Vector2& stageSize, Dali::HitTestAlgorithm::HitTestFunction func )
+inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, const Vector2& stageSize, HitTestInterface& hitCheck )
 {
   bool hittable( true );
 
@@ -264,9 +348,11 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates,
   if(hittable)
   {
     Actor* actor( &layer );
+
+    // Ensure that we can descend into the layer's (or any of its parent's) hierarchy.
     while ( actor && hittable )
     {
-      if ( !(func(Dali::Actor(actor), Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE)) ) // Layer (or its Parent) is NOT visible and sensitive, so our layer is not either.
+      if ( ! hitCheck.DescendActorHierarchy( actor ) )
       {
         hittable = false;
         break;
@@ -291,11 +377,13 @@ void GetCameraClippingPlane( RenderTask& renderTask, float& nearClippingPlane, f
 /**
  * Hit test a RenderTask
  */
-bool HitTestRenderTask( LayerList& layers,
+bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
+                        Stage& stage,
+                        LayerList& layers,
                         RenderTask& renderTask,
                         Vector2 screenCoordinates,
                         Results& results,
-                        Dali::HitTestAlgorithm::HitTestFunction func )
+                        HitTestInterface& hitCheck )
 {
   if ( renderTask.IsHittable( screenCoordinates ) )
   {
@@ -337,34 +425,66 @@ bool HitTestRenderTask( LayerList& layers,
         HitActor hit;
         bool stencilOnLayer = false;
         bool stencilHit = false;
-        const Vector2& stageSize = Stage::GetCurrent()->GetSize();
+        bool layerConsumesHit = false;
+
+        const Vector2& stageSize = stage.GetSize();
 
         for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i)
         {
           Layer* layer( layers.GetLayer(i) );
-
           HitActor previousHit = hit;
           stencilOnLayer = false;
           stencilHit = false;
 
           // Ensure layer is touchable (also checks whether ancestors are also touchable)
-          if ( IsActuallyHittable ( *layer, screenCoordinates, stageSize, func ) )
+          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) )
             {
               // Recursively hit test the source actor & children, without crossing into other layers.
-              hit = HitTestWithinLayer( *sourceActor, results.rayOrigin, results.rayDirection, false, nearClippingPlane, farClippingPlane, func, stencilOnLayer, stencilHit, false );
+              hit = HitTestWithinLayer( *sourceActor,
+                                        renderTask,
+                                        exclusives,
+                                        results.rayOrigin,
+                                        results.rayDirection,
+                                        nearClippingPlane,
+                                        farClippingPlane,
+                                        hitCheck,
+                                        stencilOnLayer,
+                                        stencilHit,
+                                        false,
+                                        layer->GetBehavior() == Dali::Layer::LAYER_3D);
             }
             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, func, stencilOnLayer, stencilHit, false );
+              hit = HitTestWithinLayer( *layer,
+                                        renderTask,
+                                        exclusives,
+                                        results.rayOrigin,
+                                        results.rayDirection,
+                                        nearClippingPlane,
+                                        farClippingPlane,
+                                        hitCheck,
+                                        stencilOnLayer,
+                                        stencilHit,
+                                        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 ( stencilOnLayer && !stencilHit )
+
+            // 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;
+              hit = previousHit;
+            }
+
+            // If this layer is set to consume the hit, then do not check any layers behind it
+            if ( hitCheck.DoesLayerConsumeHit( layer ) )
+            {
+              layerConsumesHit = true;
+              break;
             }
           }
         }
@@ -376,6 +496,10 @@ bool HitTestRenderTask( LayerList& layers,
           results.actorCoordinates.y = hit.y;
           return true; // Success
         }
+        else if ( layerConsumesHit )
+        {
+          return true; // Also success if layer is consuming the hit
+        }
       }
     }
   }
@@ -384,17 +508,21 @@ bool HitTestRenderTask( LayerList& layers,
 
 /**
  * Iterate through RenderTaskList and perform hit test.
+ *
+ * @return true if we have a hit, false otherwise
  */
-
-void HitTestForEachRenderTask( LayerList& layers,
+bool HitTestForEachRenderTask( Stage& stage,
+                               LayerList& layers,
                                RenderTaskList& taskList,
                                const Vector2& screenCoordinates,
                                Results& results,
-                               Dali::HitTestAlgorithm::HitTestFunction func )
+                               HitTestInterface& hitCheck )
 {
   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
@@ -416,10 +544,10 @@ void HitTestForEachRenderTask( LayerList& layers,
       }
     }
 
-    if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, func ) )
+    if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
     {
-      // Exit when an actor is hit
-      return; // don't bother checking off screen tasks
+      // 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
     }
   }
 
@@ -441,32 +569,40 @@ void HitTestForEachRenderTask( LayerList& layers,
         continue;
       }
 
-      if ( HitTestRenderTask( layers, renderTask, screenCoordinates, results, func ) )
+      if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
       {
-        // Exit when an actor is hit
-        break;
+        // Return true when an actor is hit (or a layer in our render-task consumes the hit)
+        return true;
       }
     }
   }
+  return false;
 }
 
 } // unnamed namespace
 
-void HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func )
+bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func )
 {
+  bool wasHit( false );
   // Hit-test the regular on-stage actors
   RenderTaskList& taskList = stage.GetRenderTaskList();
   LayerList& layerList = stage.GetLayerList();
 
   Results hitTestResults;
-  HitTestForEachRenderTask( layerList, taskList, screenCoordinates, hitTestResults, func );
-
-  results.actor = hitTestResults.actor;
-  results.actorCoordinates = hitTestResults.actorCoordinates;
+  HitTestFunctionWrapper hitTestFunctionWrapper( func );
+  if (  HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  {
+    results.actor = hitTestResults.actor;
+    results.actorCoordinates = hitTestResults.actorCoordinates;
+    wasHit = true;
+  }
+  return wasHit;
 }
 
-void HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results )
+bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, HitTestInterface& hitTestInterface )
 {
+  bool wasHit( false );
+
   // Hit-test the system-overlay actors first
   SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal();
 
@@ -475,26 +611,41 @@ void HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results )
     RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
     LayerList& overlayLayerList = systemOverlay->GetLayerList();
 
-    HitTestForEachRenderTask( overlayLayerList, overlayTaskList, screenCoordinates, results, IsActorTouchableFunction );
+    wasHit = HitTestForEachRenderTask( stage, overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
   }
 
   // Hit-test the regular on-stage actors
-  if ( !results.actor )
+  if ( !wasHit )
   {
     RenderTaskList& taskList = stage.GetRenderTaskList();
     LayerList& layerList = stage.GetLayerList();
 
-    HitTestForEachRenderTask( layerList, taskList, screenCoordinates, results, IsActorTouchableFunction );
+    wasHit = HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, results, hitTestInterface );
   }
+  return wasHit;
+}
+
+bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results )
+{
+  ActorTouchableCheck actorTouchableCheck;
+  return HitTest( stage, screenCoordinates, results, actorTouchableCheck );
 }
 
-void HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates,
+bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates,
               Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func )
 {
+  bool wasHit( false );
   Results hitTestResults;
-  HitTestRenderTask( stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, func );
-  results.actor = hitTestResults.actor;
-  results.actorCoordinates = hitTestResults.actorCoordinates;
+
+  const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList();
+  HitTestFunctionWrapper hitTestFunctionWrapper( func );
+  if ( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  {
+    results.actor = hitTestResults.actor;
+    results.actorCoordinates = hitTestResults.actorCoordinates;
+    wasHit = true;
+  }
+  return wasHit;
 }
 
 } // namespace HitTestAlgorithm