From 03fe2aa267258f2b1b8a7af4ad4c72fe5b6787ac Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Wed, 1 Nov 2023 14:02:23 +0900 Subject: [PATCH] [Tizen] Fix MapView touch patch + UTC for mutli exclusive touch Change-Id: I91906db2f756441dd059abf76d283aee858f0b84 Signed-off-by: Eunki, Hong Signed-off-by: huiyu.eun --- .../src/dali/utc-Dali-HitTestAlgorithm.cpp | 63 ++++++++++++++++++++++ .../event/events/hit-test-algorithm-impl.cpp | 51 +++++++++++++++--- 2 files changed, 106 insertions(+), 8 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp index 4d17b65..af5b0dd 100644 --- a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp +++ b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp @@ -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 diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index 77adf67..56e6871 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -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(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 } } } -- 2.7.4