[Tizen] Fix MapView touch patch + UTC for mutli exclusive touch 91/301891/3 accepted/tizen/7.0/unified/20231130.101956
authorhuiyu.eun <huiyu.eun@samsung.com>
Wed, 1 Nov 2023 05:02:23 +0000 (14:02 +0900)
committerhuiyu.eun <huiyu.eun@samsung.com>
Mon, 27 Nov 2023 05:13:15 +0000 (14:13 +0900)
Change-Id: I91906db2f756441dd059abf76d283aee858f0b84
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp
dali/internal/event/events/hit-test-algorithm-impl.cpp

index 4d17b65..af5b0dd 100644 (file)
@@ -628,4 +628,67 @@ int UtcDaliHitTestAlgorithmOrder(void)
   DALI_TEST_CHECK(results.actor == green);
 
   END_TEST;
+}
+
+int UtcDaliHitTestAlgorithmExclusiveMultiple(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::HitTestAlgorithm between On/Off render task with multiple exclusived");
+
+  Stage   stage = Stage::GetCurrent();
+  Vector2 stageSize(stage.GetSize());
+
+  Actor blue                                        = Actor::New();
+  blue[Dali::Actor::Property::NAME]                 = "Blue";
+  blue[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
+  blue[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
+  blue[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
+  blue[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
+
+  Actor green                                        = Actor::New();
+  green[Dali::Actor::Property::NAME]                 = "Green";
+  green[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
+  green[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
+  green[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
+  green[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
+
+  stage.Add(blue);
+  stage.Add(green);
+
+  RenderTaskList renderTaskList = stage.GetRenderTaskList();
+  RenderTask     offRenderTask  = renderTaskList.CreateTask();
+  RenderTask     offRenderTask2 = renderTaskList.CreateTask();
+
+  Dali::CameraActor cameraActor                     = Dali::CameraActor::New(stageSize);
+  cameraActor[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
+  cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+  stage.Add(cameraActor);
+
+  offRenderTask.SetExclusive(true);
+  offRenderTask.SetInputEnabled(true);
+  offRenderTask.SetCameraActor(cameraActor);
+  offRenderTask.SetSourceActor(green);
+  offRenderTask.SetScreenToFrameBufferMappingActor(green);
+
+  Dali::Texture texture      = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(stageSize.width), unsigned(stageSize.height));
+  FrameBuffer   renderTarget = FrameBuffer::New(stageSize.width, stageSize.height, FrameBuffer::Attachment::DEPTH);
+  renderTarget.AttachColorTexture(texture);
+  offRenderTask.SetFrameBuffer(renderTarget);
+
+  offRenderTask2.SetExclusive(true);
+  offRenderTask2.SetInputEnabled(true);
+  offRenderTask2.SetCameraActor(cameraActor);
+  offRenderTask2.SetSourceActor(green);
+  offRenderTask2.SetScreenToFrameBufferMappingActor(green);
+  offRenderTask2.SetFrameBuffer(renderTarget);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render(10);
+
+  HitTestAlgorithm::Results results;
+  HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
+  DALI_TEST_CHECK(results.actor == green);
+
+  END_TEST;
 }
\ No newline at end of file
index 77adf67..56e6871 100644 (file)
@@ -144,17 +144,26 @@ bool IsActorExclusiveToAnotherRenderTask(const Actor&
                                          const RenderTaskList::ExclusivesContainer& exclusives)
 
 {
+  bool exclusiveByOtherTask = false;
   if(exclusives.size())
   {
     for(const auto& exclusive : exclusives)
     {
-      if((exclusive.renderTaskPtr != &renderTask) && (exclusive.actor.GetActor() == &actor))
+      if(exclusive.actor.GetActor() == &actor)
       {
-        return true;
+        if(exclusive.renderTaskPtr != &renderTask)
+        {
+          exclusiveByOtherTask = true;
+        }
+        else
+        {
+          // Fast-out if render task is itself
+          return false;
+        }
       }
     }
   }
-  return false;
+  return exclusiveByOtherTask;
 }
 
 /**
@@ -485,10 +494,26 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
         bool     overlayHit       = false;
         bool     layerConsumesHit = false;
 
+        // Be used when we decide to consume layer.
+        // We should not consume hit if sourceLayer is above on consumable layer. Otherwise, we should consume. So just initialize it as 0.
+        // sourceLayerIndex can be a relative value to calculate the relationship with the layer.
+        // If the layer is consumed first, sourceLayerIndex is not the actual index, but it must be guaranteed to have an index smaller than the layer.
+        // If there is a sourceLayer above the consumable layer, the sourceLayerIndex is determined and the index of the consumable layer is also determined.
+        // Then we can calculate the relationship between the two layers.
+        bool    IsHitTestWithinLayer = false;
+        int32_t sourceLayerIndex     = 0;
+        int32_t consumedLayerIndex   = -1;
+
         for(int32_t i = layers.GetLayerCount() - 1; i >= 0 && !(hit.actor); --i)
         {
           Layer* layer(layers.GetLayer(i));
-          overlayHit = false;
+          overlayHit           = false;
+          IsHitTestWithinLayer = false;
+
+          if(sourceLayer == layer)
+          {
+            sourceLayerIndex = i;
+          }
 
           // Ensure layer is touchable (also checks whether ancestors are also touchable)
           if(IsActuallyHittable(*layer, screenCoordinates, sceneSize, hitCheck))
@@ -496,6 +521,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             // Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy
             if(sourceActorDepth == static_cast<uint32_t>(i))
             {
+              IsHitTestWithinLayer = true;
               // Recursively hit test the source actor & children, without crossing into other layers.
               hit = HitTestWithinLayer(*sourceActor,
                                        renderTask,
@@ -514,6 +540,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             }
             else if(IsWithinSourceActors(*sourceActor, *layer))
             {
+              IsHitTestWithinLayer = true;
               // Recursively hit test all the actors, without crossing into other layers.
               hit = HitTestWithinLayer(*layer,
                                        renderTask,
@@ -532,10 +559,10 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             }
 
             // If this layer is set to consume the hit, then do not check any layers behind it
-            if(hitCheck.DoesLayerConsumeHit(layer))
+            if(IsHitTestWithinLayer && hitCheck.DoesLayerConsumeHit(layer))
             {
-              // Consume the hit if this layer is same as SourceActor's layer
-              layerConsumesHit = (sourceLayer == Dali::Layer(layer));
+              consumedLayerIndex = i;
+              layerConsumesHit   = true;
               break;
             }
           }
@@ -552,7 +579,15 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
 
         if(layerConsumesHit)
         {
-          return true; // Also success if layer is consuming the hit
+          // Consumes if the hitted layer is above the SourceActor's layer.
+          bool ret = sourceLayerIndex <= consumedLayerIndex;
+          if(ret)
+          {
+            DALI_LOG_RELEASE_INFO("layer is set to consume the hit\n");
+            results.renderTask = RenderTaskPtr(&renderTask);
+            results.actor      = Dali::Layer(layers.GetLayer(consumedLayerIndex));
+          }
+          return ret; // Also success if layer is consuming the hit
         }
       }
     }