From: Seungho Baek Date: Wed, 24 Apr 2024 12:21:39 +0000 (+0900) Subject: [Tizen] Fix several hit issue for offscreen rendering X-Git-Tag: accepted/tizen/8.0/unified/20240509.175855^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6bc5a85a8071111a367b09755bfd22c65957287e;p=platform%2Fcore%2Fuifw%2Fdali-core.git [Tizen] Fix several hit issue for offscreen rendering - Previous implementation - MappingActor is not hittable by default, but it was used to check whether it is hitted from OnScreen RenderTask or not in HitTestRenderTaskList. - There is nothing to check the layer including MappingActor is consuming hit. - Current implementation - For the OnScreen hit result, check whether there is a mappingActor of OffScreen hit results that can be hit in front of the OnScreen hit result. If it is, returns the OffScreen hit results. - If the OnScreen hit result is layer and the layer consumes hit(the layer must not be hittable), returns the OffScreen hit results. - If there is no hit in OnScreen but there are hit results from OffScreen RenderTask, returns the top OffScreen hit results. Change-Id: I2788ed90dbe0145b4c263c371353b201c65c2a80 Signed-off-by: Seungho Baek --- diff --git a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp index 64e7e7d..c01da5d 100644 --- a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp +++ b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp @@ -109,6 +109,41 @@ bool DefaultIsActorTouchableFunction(Dali::Actor actor, Dali::HitTestAlgorithm:: return hittable; }; +bool IsActorTouchableFunctionWithoutLayerHit(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type) +{ + bool hittable = false; + + switch(type) + { + case Dali::HitTestAlgorithm::CHECK_ACTOR: + { + if(actor.GetCurrentProperty(Actor::Property::VISIBLE) && + actor.GetProperty(Actor::Property::SENSITIVE) && + actor.GetCurrentProperty(Actor::Property::WORLD_COLOR).a > 0.01f && + actor.GetLayer() != actor) + { + hittable = true; + } + break; + } + case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE: + { + if(actor.GetCurrentProperty(Actor::Property::VISIBLE) && // Actor is visible, if not visible then none of its children are visible. + actor.GetProperty(Actor::Property::SENSITIVE)) // Actor is sensitive, if insensitive none of its children should be hittable either. + { + hittable = true; + } + break; + } + default: + { + break; + } + } + + return hittable; +}; + } // anonymous namespace // Positive test case for a method @@ -575,7 +610,7 @@ int UtcDaliHitTestAlgorithmDoesWantedHitTest(void) END_TEST; } -int UtcDaliHitTestAlgorithmOrder(void) +int UtcDaliHitTestAlgorithmOrder1(void) { TestApplication application; tet_infoline("Testing Dali::HitTestAlgorithm between On/Off render task"); @@ -630,6 +665,276 @@ int UtcDaliHitTestAlgorithmOrder(void) END_TEST; } +int UtcDaliHitTestAlgorithmOrder2(void) +{ + TestApplication application; + tet_infoline("Testing Dali::HitTestAlgorithm in for the mapping actor and its child"); + + 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; + + Actor red = Actor::New(); + red[Dali::Actor::Property::NAME] = "Red"; + red[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + red[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + red[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + red[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + + Actor yellow = Actor::New(); + yellow[Dali::Actor::Property::NAME] = "Yellow"; + yellow[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + yellow[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + yellow[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + yellow[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + + stage.Add(blue); + stage.Add(green); + stage.Add(yellow); + + RenderTaskList renderTaskList = stage.GetRenderTaskList(); + RenderTask offRenderTask = 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(yellow); + 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); + + // Render and notify + application.SendNotification(); + application.Render(10); + + HitTestAlgorithm::Results results; + HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction); + DALI_TEST_CHECK(results.actor == yellow); + + green.Add(red); + + // Render and notify + application.SendNotification(); + application.Render(10); + + results = HitTestAlgorithm::Results(); + HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction); + DALI_TEST_CHECK(results.actor == red); + + END_TEST; +} + +int UtcDaliHitTestAlgorithmInMultipleLayer(void) +{ + TestApplication application; + tet_infoline("Testing UtcDaliHitTestAlgorithmInMultipleLayer"); + + 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; + + Layer layer = Layer::New(); + layer[Dali::Actor::Property::NAME] = "Layer"; + layer[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + layer[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + layer[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + layer[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; + + Actor red = Actor::New(); + red[Dali::Actor::Property::NAME] = "Red"; + red[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + red[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + red[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + red[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + + stage.Add(blue); + stage.Add(layer); + layer.Add(green); + stage.Add(red); + + RenderTaskList renderTaskList = stage.GetRenderTaskList(); + RenderTask offRenderTask = 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(layer); + offRenderTask.SetScreenToFrameBufferMappingActor(red); + + 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); + + // 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; +} + +int UtcDaliHitTestAlgorithmOffSceneMappingActor(void) +{ + TestApplication application; + tet_infoline("Testing Dali::HitTestAlgorithm with OffSceneMappingActor"); + + 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; + + Actor red = Actor::New(); + red[Dali::Actor::Property::NAME] = "Red"; + red[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + red[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + red[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + red[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT; + + stage.Add(blue); + stage.Add(green); + + RenderTaskList renderTaskList = stage.GetRenderTaskList(); + RenderTask offRenderTask = 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(red); + + 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); + + // Render and notify + application.SendNotification(); + application.Render(10); + + HitTestAlgorithm::Results results; + HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction); + DALI_TEST_CHECK(results.actor == blue); + + stage.Add(red); + + // Render and notify + application.SendNotification(); + application.Render(10); + + HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction); + DALI_TEST_CHECK(results.actor == green); + + END_TEST; +} + +int UtcDaliHitTestAlgorithmScreenToFrameBufferFunction(void) +{ + TestApplication application; + tet_infoline("Testing Dali::HitTestAlgorithm using ScreenToFrameBufferFunction"); + + Stage stage = Stage::GetCurrent(); + Vector2 stageSize(stage.GetSize()); + + 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(green); + + RenderTaskList renderTaskList = stage.GetRenderTaskList(); + RenderTask offRenderTask = 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.SetScreenToFrameBufferFunction(RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION); + offRenderTask.SetViewport(Viewport(Vector4(0, 0, 480, 800))); + + 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); + + // Render and notify + application.SendNotification(); + application.Render(10); + + HitTestAlgorithm::Results results; + HitTest(stage, stageSize / 2.0f, results, &IsActorTouchableFunctionWithoutLayerHit); + DALI_TEST_CHECK(results.actor == green); + + END_TEST; +} + int UtcDaliHitTestAlgorithmExclusiveMultiple(void) { TestApplication application; diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index fdb45f7..578f5fe 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -459,7 +459,26 @@ bool IsWithinSourceActors(const Actor& sourceActor, const Actor& actor) } /** - * Returns true if the layer and all of the layer's parents are visible and sensitive. + * Returns true if the actor and all of the actor's parents are hittable. + */ +bool IsActorActuallyHittable(Actor* actor, HitTestInterface& hitCheck) +{ + Actor* currentActor = actor; + // Ensure that we can descend into the layer's (or any of its parent's) hierarchy. + while(currentActor) + { + if(!hitCheck.DescendActorHierarchy(currentActor)) + { + return false; + } + currentActor = currentActor->GetParent(); + } + + return true; +} + +/** + * Returns true if the layer and all of the layer's parents are hittable. */ inline bool IsActuallyHittable(Layer& layer, const Vector2& screenCoordinates, const Vector2& stageSize, HitTestInterface& hitCheck) { @@ -482,17 +501,7 @@ inline bool IsActuallyHittable(Layer& layer, const Vector2& screenCoordinates, c 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(!hitCheck.DescendActorHierarchy(actor)) - { - hittable = false; - break; - } - actor = actor->GetParent(); - } + hittable = IsActorActuallyHittable(actor, hitCheck); } return hittable; @@ -651,7 +660,9 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives, // Determine the layer depth of the source actor Actor* sourceActor(renderTask.GetSourceActor()); - if(sourceActor) + + // Check the source actor is actually hittable or not. + if(sourceActor && IsActorActuallyHittable(sourceActor, hitCheck)) { Dali::Layer sourceLayer(sourceActor->GetLayer()); if(sourceLayer) @@ -780,6 +791,68 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives, } /** + * Selects Prior Actor that is rendered later between firstActor and secondActor in the layer of rootActor. + * if only one of Actor is included in the layer, returns the Actor. + * if both of the firstActor and secondActor are not included in the layer, returns empty Actor. + */ +Dali::Actor FindPriorActorInLayer(Dali::Actor rootActor, Dali::Actor firstActor, Dali::Actor secondActor) +{ + Dali::Actor priorActor; + Dali::Layer layer = rootActor.GetLayer(); + bool firstActorIncluded = firstActor.GetLayer() == layer; + bool secondActorIncluded = secondActor.GetLayer() == layer; + + if(firstActorIncluded && !secondActorIncluded) + { + priorActor = firstActor; + } + else if(!firstActorIncluded && secondActorIncluded) + { + priorActor = secondActor; + } + else if(firstActorIncluded && secondActorIncluded) + { + priorActor = (GetImplementation(firstActor).GetSortingDepth() < GetImplementation(secondActor).GetSortingDepth()) ? secondActor : firstActor; + } + + return priorActor; +} + +/** + * Selects Prior Actor that is rendered later between firstActor and secondActor from child scene tree of rootActor. + */ +Dali::Actor FindPriorActorInLayers(const LayerList& layers, Dali::Actor rootActor, Dali::Actor firstActor, Dali::Actor secondActor) +{ + Dali::Layer sourceLayer = rootActor.GetLayer(); + const uint32_t sourceActorDepth(sourceLayer.GetProperty(Dali::Layer::Property::DEPTH)); + + Dali::Actor priorActor; + uint32_t layerCount = layers.GetLayerCount(); + if(layerCount > 0) + { + for(int32_t i = layerCount - 1; i >= 0; --i) + { + Layer* layer(layers.GetLayer(i)); + if(sourceActorDepth == static_cast(i)) + { + priorActor = FindPriorActorInLayer(rootActor, firstActor, secondActor); + } + else if(IsWithinSourceActors(GetImplementation(rootActor), *layer)) + { + Dali::Actor layerRoot = Dali::Actor(layer); + priorActor = FindPriorActorInLayer(layerRoot, firstActor, secondActor); + } + + if(priorActor) + { + break; + } + } + } + return priorActor; +} + +/** * Iterate through the RenderTaskList and perform hit testing. * * @param[in] sceneSize The scene size the tests will be performed in @@ -821,18 +894,68 @@ bool HitTestRenderTaskList(const Vector2& sceneSize, const auto& exclusives = taskList.GetExclusivesList(); RayTest rayTest; + Results storedResults = results; + std::vector> offScreenHitResults; // Hit test order should be reverse of draw order for(RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter) { RenderTask& renderTask = *iter->Get(); if(HitTestRenderTask(exclusives, sceneSize, layers, renderTask, screenCoordinates, results, hitCheck, rayTest)) { + if(renderTask.GetFrameBuffer()) + { + Results result = results; + offScreenHitResults.push_back(std::make_pair(renderTask.GetScreenToFrameBufferMappingActor(), std::move(result))); + continue; + } + + if(offScreenHitResults.empty()) + { + return true; + } + + Actor* sourceActor(renderTask.GetSourceActor()); + for(auto&& pair : offScreenHitResults) + { + Dali::Actor mappingActor = pair.first; + if(!mappingActor || !IsWithinSourceActors(*sourceActor, GetImplementation(mappingActor))) + { + continue; + } + + bool mappingActorInsideHitConsumingLayer = false; + if(GetImplementation(results.actor).IsLayer()) + { + Dali::Layer resultLayer = Dali::Layer::DownCast(results.actor); + // Check the resultLayer is consuming hit even though the layer is not hittable. + // And check the resultLayer is the layer of mappingActor too. + if(hitCheck.DoesLayerConsumeHit(&GetImplementation(resultLayer)) && !hitCheck.IsActorHittable(&GetImplementation(results.actor)) && results.actor == mappingActor.GetLayer()) + { + mappingActorInsideHitConsumingLayer = true; + } + } + if(mappingActorInsideHitConsumingLayer || mappingActor == FindPriorActorInLayers(layers, Dali::Actor(sourceActor), mappingActor, results.actor)) + { + results = pair.second; + break; + } + } // Return true when an actor is hit (or layer in our render-task consumes the hit) return true; } } - return false; + + // When no OnScreen Actor is hitted but there are hit results from OffScreen RenderTasks + // those use ScreenToFrameBufferFunction, simply returns first hitted result. + if(!offScreenHitResults.empty()) + { + results = offScreenHitResults.front().second; + return true; + } + + results = storedResults; } + return false; } /** diff --git a/dali/internal/event/render-tasks/render-task-impl.cpp b/dali/internal/event/render-tasks/render-task-impl.cpp index 25ca2dc..4ac98f3 100644 --- a/dali/internal/event/render-tasks/render-task-impl.cpp +++ b/dali/internal/event/render-tasks/render-task-impl.cpp @@ -490,6 +490,11 @@ bool RenderTask::TranslateCoordinates(Vector2& screenCoords) const if(mFrameBuffer && mappingActor) { Internal::Actor* inputMappingActor = &GetImplementation(mappingActor); + if(!inputMappingActor->OnScene()) + { + return false; + } + CameraActor* localCamera = GetCameraActor(); StagePtr stage = Stage::GetCurrent(); if(stage) @@ -556,6 +561,11 @@ void RenderTask::GetHittableViewport(Viewport& viewPort) const viewPort.width = static_cast(actorSize.x + 0.5f); // rounded viewPort.height = static_cast(actorSize.y + 0.5f); // rounded } + else + { + // For the case to use ScreenToFrameBufferFunction + GetViewport(viewPort); + } } else { diff --git a/dali/internal/event/render-tasks/render-task-impl.h b/dali/internal/event/render-tasks/render-task-impl.h index f8897b0..f2d7367 100644 --- a/dali/internal/event/render-tasks/render-task-impl.h +++ b/dali/internal/event/render-tasks/render-task-impl.h @@ -127,7 +127,7 @@ public: void SetScreenToFrameBufferMappingActor(Dali::Actor& mappingActor); /** - * @copydoc Dali::RenderTask::GetScreenToFrameBufferMAppingActor + * @copydoc Dali::RenderTask::GetScreenToFrameBufferMappingActor */ Dali::Actor GetScreenToFrameBufferMappingActor() const;