[dali_2.3.22] Merge branch 'devel/master' 47/310647/1 master
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 3 May 2024 08:27:17 +0000 (09:27 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 3 May 2024 08:27:17 +0000 (09:27 +0100)
Change-Id: If58d06243cf24098412f6c06340434c446e9be4d

39 files changed:
automated-tests/src/dali-internal/utc-Dali-Internal-OrderedSet.cpp
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-FrameCallbackInterface.cpp
automated-tests/src/dali/utc-Dali-PanGestureRecognizer.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
dali/integration-api/core.h
dali/integration-api/file.list
dali/integration-api/ordered-set.h [moved from dali/internal/common/ordered-set.h with 96% similarity]
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-parent-impl.cpp
dali/internal/event/actors/actor-parent-impl.h
dali/internal/event/animation/animation-playlist.h
dali/internal/event/common/property-notification-manager.h
dali/internal/event/events/gesture-event-processor.cpp
dali/internal/event/events/pan-gesture/pan-gesture-processor.cpp
dali/internal/event/events/pan-gesture/pan-gesture-processor.h
dali/internal/event/events/pan-gesture/pan-gesture-recognizer.cpp
dali/internal/event/events/pan-gesture/pan-gesture-recognizer.h
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/event/render-tasks/render-task-impl.h
dali/internal/event/size-negotiation/memory-pool-relayout-container.h
dali/internal/event/size-negotiation/relayout-controller-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/update/common/property-resetter.h
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/manager/update-manager.cpp
dali/internal/update/render-tasks/scene-graph-render-task-messages.h
dali/internal/update/render-tasks/scene-graph-render-task.cpp
dali/internal/update/render-tasks/scene-graph-render-task.h
dali/public-api/actors/actor.cpp
dali/public-api/actors/actor.h
dali/public-api/dali-core-version.cpp
dali/public-api/events/device.h
dali/public-api/render-tasks/render-task.cpp
dali/public-api/render-tasks/render-task.h
packaging/dali.spec

index 01c24ed..abc2cb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
 
 // INTERNAL INCLUDES
 #include <dali-test-suite-utils.h>
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
 
-using namespace Dali::Internal;
+using namespace Dali;
+using namespace Dali::Integration;
 
-void utc_dali_internal_owner_set_startup(void)
+void utc_dali_internal_ordered_set_startup(void)
 {
   test_return_value = TET_UNDEF;
 }
 
-void utc_dali_internal_owner_set_cleanup(void)
+void utc_dali_internal_ordered_set_cleanup(void)
 {
   test_return_value = TET_PASS;
 }
index f08e19d..a245c5c 100644 (file)
@@ -276,6 +276,56 @@ struct VisibilityChangedVoidFunctor
   bool& mSignalCalled;
 };
 
+struct InheritedVisibilityChangedFunctorData
+{
+  InheritedVisibilityChangedFunctorData()
+  : actor(),
+    visible(false),
+    called(false)
+  {
+  }
+
+  void Reset()
+  {
+    actor.Reset();
+    visible = false;
+    called  = false;
+  }
+
+  void Check(bool compareCalled, Actor compareActor, bool compareVisible, const char* location)
+  {
+    DALI_TEST_EQUALS(called, compareCalled, TEST_INNER_LOCATION(location));
+    DALI_TEST_EQUALS(actor, compareActor, TEST_INNER_LOCATION(location));
+    DALI_TEST_EQUALS(visible, compareVisible, TEST_INNER_LOCATION(location));
+  }
+
+  void Check(bool compareCalled, const std::string& location)
+  {
+    DALI_TEST_EQUALS(called, compareCalled, TEST_INNER_LOCATION(location));
+  }
+
+  Actor                              actor;
+  bool                               visible;
+  bool                               called;
+};
+
+struct InheritedVisibilityChangedFunctor
+{
+  InheritedVisibilityChangedFunctor(InheritedVisibilityChangedFunctorData& dataVar)
+  : data(dataVar)
+  {
+  }
+
+  void operator()(Actor actor, bool visible)
+  {
+    data.actor   = actor;
+    data.visible = visible;
+    data.called  = true;
+  }
+
+  InheritedVisibilityChangedFunctorData& data;
+};
+
 struct ChildOrderChangedFunctor
 {
   ChildOrderChangedFunctor(bool& signalCalled, Actor& actor)
@@ -9811,6 +9861,284 @@ int utcDaliActorVisibilityChangeSignalByName(void)
   END_TEST;
 }
 
+int utcDaliActorInheritedVisibilityChangeSignal1(void)
+{
+  TestApplication application;
+  tet_infoline("Check that the inherited visibility change signal is called when the visibility changes for the actor itself");
+
+  Actor parentActor = Actor::New();
+  Actor actor = Actor::New();
+
+  InheritedVisibilityChangedFunctorData data;
+  actor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(data));
+
+  parentActor.Add(actor);
+  data.Check(false, TEST_LOCATION);
+
+  data.Reset();
+  application.GetScene().Add(parentActor);
+  data.Check(true, actor, true, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(true, actor, false, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(false, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(true, actor, true, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(false, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal2(void)
+{
+  TestApplication application;
+  tet_infoline("Check that the inherited visibility change signal is called when the actor or one of the parent become on scene or off scene");
+
+  Actor parentActor = Actor::New();
+  Actor childActor = Actor::New();
+
+  InheritedVisibilityChangedFunctorData dataP, dataC;
+  parentActor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataP));
+  childActor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataC));
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.Add(childActor);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  application.GetScene().Add(parentActor);
+  dataP.Check(true, parentActor, true, TEST_LOCATION);
+  dataC.Check(true, childActor, true, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  childActor.Unparent();
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(true, childActor, false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  childActor.SetProperty(Actor::Property::VISIBLE, false);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.Add(childActor);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  childActor.SetProperty(Actor::Property::VISIBLE, true);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(true, childActor, true, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.SetProperty(Actor::Property::VISIBLE, false);
+  dataP.Check(true, parentActor, false, TEST_LOCATION);
+  dataC.Check(true, childActor, false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  childActor.Unparent();
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.SetProperty(Actor::Property::VISIBLE, true);
+  dataP.Check(true, parentActor, true, TEST_LOCATION);
+  dataC.Check(false, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.Add(childActor);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(true, childActor, true, TEST_LOCATION);
+
+  dataP.Reset();
+  dataC.Reset();
+  parentActor.Remove(childActor);
+  dataP.Check(false, TEST_LOCATION);
+  dataC.Check(true, childActor, false, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal3(void)
+{
+  TestApplication application;
+  tet_infoline("Check that the inherited visibility change signal is called when the visibility changes for the parent actor");
+
+  Actor parentActor = Actor::New();
+  Actor actor = Actor::New();
+  parentActor.Add(actor);
+
+  InheritedVisibilityChangedFunctorData data;
+  actor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(data));
+
+  application.GetScene().Add(parentActor);
+  data.Check(true, actor, true, TEST_LOCATION);
+
+  // Case 1
+  // Parent true -> false : called
+  // actor true -> false  : not called
+  // actor false -> true  : not called
+  data.Reset();
+  parentActor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(true, actor, false, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(false, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(false, TEST_LOCATION);
+
+
+  // Prepare Case 2
+  // Parent : false
+  // actor : false
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(false, TEST_LOCATION);
+
+  // Case 2
+  // actor : false
+  // parent false -> true : not called
+  data.Reset();
+  parentActor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(false, TEST_LOCATION);
+
+
+  // Prepare Case 3
+  // parent : false
+  // actor : true
+  data.Reset();
+  parentActor.SetProperty(Actor::Property::VISIBLE, false);
+  data.Check(false, TEST_LOCATION);
+
+  data.Reset();
+  actor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(false, TEST_LOCATION);
+
+  // Case 3
+  // actor : true
+  // parent false -> true : called
+  parentActor.SetProperty(Actor::Property::VISIBLE, true);
+  data.Check(true, actor, true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+namespace
+{
+  InheritedVisibilityChangedFunctorData dataPA, dataPB, dataCA, dataCB, dataCC;
+  void ResetInheritedVisibilityChangedFunctorData()
+  {
+    dataPA.Reset();
+    dataPB.Reset();
+    dataCA.Reset();
+    dataCB.Reset();
+    dataCC.Reset();
+  }
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal4(void)
+{
+  TestApplication application;
+  tet_infoline("Check that the inherited visibility change signal is in tree");
+
+  /**
+   * ParentA
+   *    |
+   * ParentB
+   *    |
+   * ChildA   ChildB   ChildC
+   */
+
+  Actor parentA = Actor::New();
+  Actor parentB = Actor::New();
+  Actor childA = Actor::New();
+  Actor childB = Actor::New();
+  Actor childC = Actor::New();
+  parentA.Add(parentB);
+  parentB.Add(childA);
+  parentB.Add(childB);
+  parentB.Add(childC);
+
+  parentA.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataPA));
+  parentB.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataPB));
+  childA.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCA));
+  childB.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCB));
+  childC.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCC));
+
+  ResetInheritedVisibilityChangedFunctorData();
+  application.GetScene().Add(parentA);
+  dataPA.Check(true, parentA, true, TEST_LOCATION);
+  dataPB.Check(true, parentB, true, TEST_LOCATION);
+  dataCA.Check(true, childA,  true, TEST_LOCATION);
+  dataCB.Check(true, childB,  true, TEST_LOCATION);
+  dataCC.Check(true, childC,  true, TEST_LOCATION);
+
+  ResetInheritedVisibilityChangedFunctorData();
+  parentA.SetProperty(Actor::Property::VISIBLE, false);
+  dataPA.Check(true, parentA, false, TEST_LOCATION);
+  dataPB.Check(true, parentB, false, TEST_LOCATION);
+  dataCA.Check(true, childA,  false, TEST_LOCATION);
+  dataCB.Check(true, childB,  false, TEST_LOCATION);
+  dataCC.Check(true, childC,  false, TEST_LOCATION);
+
+  ResetInheritedVisibilityChangedFunctorData();
+  childA.SetProperty(Actor::Property::VISIBLE, false);
+  dataPA.Check(false, TEST_LOCATION);
+  dataPB.Check(false, TEST_LOCATION);
+  dataCA.Check(false, TEST_LOCATION);
+  dataCB.Check(false, TEST_LOCATION);
+  dataCC.Check(false, TEST_LOCATION);
+
+  ResetInheritedVisibilityChangedFunctorData();
+  parentB.SetProperty(Actor::Property::VISIBLE, false);
+  dataPA.Check(false, TEST_LOCATION);
+  dataPB.Check(false, TEST_LOCATION);
+  dataCA.Check(false, TEST_LOCATION);
+  dataCB.Check(false, TEST_LOCATION);
+  dataCC.Check(false, TEST_LOCATION);
+
+  ResetInheritedVisibilityChangedFunctorData();
+  parentA.SetProperty(Actor::Property::VISIBLE, true);
+  dataPA.Check(true, parentA, true, TEST_LOCATION);
+  dataPB.Check(false, TEST_LOCATION);
+  dataCA.Check(false, TEST_LOCATION);
+  dataCB.Check(false, TEST_LOCATION);
+  dataCC.Check(false, TEST_LOCATION);
+
+  ResetInheritedVisibilityChangedFunctorData();
+  parentB.SetProperty(Actor::Property::VISIBLE, true);
+  dataPA.Check(false, TEST_LOCATION);
+  dataPB.Check(true, parentB, true, TEST_LOCATION);
+  dataCA.Check(false, TEST_LOCATION);
+  dataCB.Check(true, childB,  true, TEST_LOCATION);
+  dataCC.Check(true, childC,  true, TEST_LOCATION);
+
+  END_TEST;
+}
+
 static void LayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
 {
   gLayoutDirectionType = type;
index 9de27be..dd95d0f 100644 (file)
@@ -301,12 +301,12 @@ public:
     mBakeColorCallSuccess                    = updateProxy.BakeColor(mActorId, vec4);
     mBakeScaleCallSuccess                    = updateProxy.BakeScale(mActorId, vec3);
 
-    mGetOrientationCallSuccess               = updateProxy.GetOrientation(mActorId, quat);
-    mSetOrientationCallSuccess               = updateProxy.SetOrientation(mActorId, quat);
-    mBakeOrientationCallSuccess              = updateProxy.BakeOrientation(mActorId, quat);
-    mGetWorldTransformCallSuccess            = updateProxy.GetWorldTransformAndSize(mActorId, vec3, vec3, quat, vec3);
-    mGetUpdateAreaCallSuccess                = updateProxy.GetUpdateArea(mActorId, vec4);
-    mSetUpdateAreaCallSuccess                = updateProxy.SetUpdateArea(mActorId, vec4);
+    mGetOrientationCallSuccess    = updateProxy.GetOrientation(mActorId, quat);
+    mSetOrientationCallSuccess    = updateProxy.SetOrientation(mActorId, quat);
+    mBakeOrientationCallSuccess   = updateProxy.BakeOrientation(mActorId, quat);
+    mGetWorldTransformCallSuccess = updateProxy.GetWorldTransformAndSize(mActorId, vec3, vec3, quat, vec3);
+    mGetUpdateAreaCallSuccess     = updateProxy.GetUpdateArea(mActorId, vec4);
+    mSetUpdateAreaCallSuccess     = updateProxy.SetUpdateArea(mActorId, vec4);
 
     return false;
   }
@@ -331,13 +331,13 @@ public:
     mBakeColorCallSuccess                    = false;
     mBakeScaleCallSuccess                    = false;
 
-    mSetOrientationCallSuccess               = false;
-    mGetOrientationCallSuccess               = false;
-    mBakeOrientationCallSuccess              = false;
+    mSetOrientationCallSuccess  = false;
+    mGetOrientationCallSuccess  = false;
+    mBakeOrientationCallSuccess = false;
 
-    mGetWorldTransformCallSuccess            = false;
-    mGetUpdateAreaCallSuccess                = false;
-    mSetUpdateAreaCallSuccess                = false;
+    mGetWorldTransformCallSuccess = false;
+    mGetUpdateAreaCallSuccess     = false;
+    mSetUpdateAreaCallSuccess     = false;
   }
 
   const uint32_t mActorId;
@@ -1118,7 +1118,7 @@ int UtcDaliFrameCallbackUpdateStatus(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(application.GetUpdateStatus(), Integration::KeepUpdating::STAGE_KEEP_RENDERING, TEST_LOCATION);
+  DALI_TEST_EQUALS(application.GetUpdateStatus(), Integration::KeepUpdating::FRAME_UPDATE_CALLBACK, TEST_LOCATION);
 
   END_TEST;
 }
index 5f6e075..c6ee297 100644 (file)
@@ -696,6 +696,62 @@ int UtcDaliPanGestureRecognizerNewParamsMinNum(void)
   END_TEST;
 }
 
+int UtcDaliPanGestureRecognizerUpdateParamsMinNum(void)
+{
+  TestApplication application;
+
+  Integration::SetPanGestureMinimumPanEvents(8);
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  detector.Attach(actor);
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 90.0f), 756));
+  application.SendNotification();
+  data.Reset();
+
+  Integration::SetPanGestureMinimumPanEvents(10);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 100.0f), 756));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 110.0f), 857));
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
 int UtcDaliPanGestureRecognizerNewParamsMinDistance(void)
 {
   TestApplication application;
@@ -732,3 +788,59 @@ int UtcDaliPanGestureRecognizerNewParamsMinDistance(void)
 
   END_TEST;
 }
+
+int UtcDaliPanGestureRecognizerUpdateParamsMinDistance(void)
+{
+  TestApplication application;
+
+  Integration::SetPanGestureMinimumDistance(100);
+
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  detector.Attach(actor);
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 90.0f), 756));
+  application.SendNotification();
+  data.Reset();
+
+  Integration::SetPanGestureMinimumDistance(130);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 100.0f),756));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 110.0f),857));
+  application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 120.0f),858));
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  END_TEST;
+}
index cf7bd97..a2d870e 100644 (file)
@@ -692,6 +692,89 @@ int UtcDaliRenderTaskGetSourceActorN(void)
   END_TEST;
 }
 
+int UtcDaliRenderTaskGetStopperActorP(void)
+{
+  TestApplication application;
+
+  tet_infoline("Testing RenderTask::GetStopperActor() Create a new render task, Add a new actor to the stage and set RenderTask::RenderUntil(actor). Get its stopper actor and check it is equivalent to what was set.");
+
+  RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+  RenderTask     task     = taskList.CreateTask();
+  Actor          actor    = Actor::New();
+  application.GetScene().Add(actor);
+  task.RenderUntil(actor);
+
+  DALI_TEST_EQUALS(actor, task.GetStopperActor(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliRenderTaskGetStopperActorN(void)
+{
+  TestApplication application;
+
+  tet_infoline("Testing RenderTask::GetStopperActor() Try with empty handle");
+
+  RenderTask task;
+
+  try
+  {
+    Actor actor = task.GetStopperActor();
+  }
+  catch(Dali::DaliException& e)
+  {
+    DALI_TEST_PRINT_ASSERT(e);
+    DALI_TEST_ASSERT(e, "RenderTask handle is empty", TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
+int UtcDaliRenderTaskRenderUntil(void)
+{
+  TestApplication application;
+  tet_infoline("Testing RenderTask::RenderUntil(actor) Check that rendering stops at the actor.");
+
+  // Make a new render task and compose a tree.
+  RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+  RenderTask     task     = taskList.GetTask(0u);
+
+  Integration::Scene stage = application.GetScene();
+
+  Actor secondChild;
+  for(int i = 0; i < 5; i++)
+  {
+    Actor parent = CreateRenderableActor();
+    parent.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+    parent.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+    Actor  child = CreateRenderableActor();
+    child.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+
+    stage.Add(parent);
+    parent.Add(child);
+
+    if (i == 1)
+    {
+      secondChild = child;
+    }
+  }
+  task.RenderUntil(secondChild);
+
+  // Update & Render with the actor on-stage
+  TestGlAbstraction& gl        = application.GetGlAbstraction();
+  TraceCallStack&    drawTrace = gl.GetDrawTrace();
+  drawTrace.Enable(true);
+
+  // Update & Render
+  application.SendNotification();
+  application.Render();
+
+  // Check that rendering was cut.
+  DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 3, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliRenderTaskSetExclusive(void)
 {
   TestApplication application;
index 0b09348..14f607d 100644 (file)
@@ -3538,7 +3538,7 @@ int UtcDaliRendererRenderingBehavior(void)
 
   uint32_t updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+  DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
 
   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
   TraceCallStack&    drawTrace     = glAbstraction.GetDrawTrace();
@@ -3557,7 +3557,7 @@ int UtcDaliRendererRenderingBehavior(void)
 
   updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+  DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
 
   value = renderer.GetCurrentProperty(DevelRenderer::Property::RENDERING_BEHAVIOR);
   DALI_TEST_CHECK(value.Get(renderingBehavior));
@@ -3573,7 +3573,7 @@ int UtcDaliRendererRenderingBehavior(void)
 
   updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+  DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
 
   DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
 
@@ -3597,7 +3597,7 @@ int UtcDaliRendererRenderingBehavior(void)
 
     updateStatus = application.GetUpdateStatus();
 
-    DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+    DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
 
     DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
   }
@@ -3611,7 +3611,7 @@ int UtcDaliRendererRenderingBehavior(void)
 
   updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+  DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
 
   END_TEST;
 }
@@ -3701,7 +3701,7 @@ int UtcDaliRendererRenderAfterAddShader(void)
 
   uint32_t updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+  DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
 
   // Update for several frames
   application.SendNotification();
@@ -3732,7 +3732,7 @@ int UtcDaliRendererRenderAfterAddShader(void)
 
   updateStatus = application.GetUpdateStatus();
 
-  DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+  DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
 
   DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
 
index c958522..d570f9b 100644 (file)
@@ -65,7 +65,9 @@ enum Reasons
   STAGE_KEEP_RENDERING   = 1 << 1, ///<  - Stage::KeepRendering() is being used
   ANIMATIONS_RUNNING     = 1 << 2, ///< - Animations are ongoing
   MONITORING_PERFORMANCE = 1 << 3, ///< - The --enable-performance-monitor option is being used
-  RENDER_TASK_SYNC       = 1 << 4  ///< - A render task is waiting for render sync
+  RENDER_TASK_SYNC       = 1 << 4, ///< - A render task is waiting for render sync
+  FRAME_UPDATE_CALLBACK  = 1 << 5, ///< - Some FrameUpdateCallback return true
+  RENDERER_CONTINUOUSLY  = 1 << 6  ///< - Some Renderer renderinb behaviour is continuously
 };
 }
 
index be358ac..7b6dc9a 100644 (file)
@@ -42,6 +42,7 @@ SET( platform_abstraction_header_files
    ${platform_abstraction_src_dir}/graphics-sync-abstraction.h
    ${platform_abstraction_src_dir}/input-options.h
    ${platform_abstraction_src_dir}/lockless-buffer.h
+   ${platform_abstraction_src_dir}/ordered-set.h
    ${platform_abstraction_src_dir}/pixel-data-integ.h
    ${platform_abstraction_src_dir}/platform-abstraction.h
    ${platform_abstraction_src_dir}/profiling.h
similarity index 96%
rename from dali/internal/common/ordered-set.h
rename to dali/integration-api/ordered-set.h
index 65b798b..9e5cc1d 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef DALI_INTERNAL_ORDERED_SET_H
-#define DALI_INTERNAL_ORDERED_SET_H
+#ifndef DALI_INTEGRATION_ORDERED_SET_H
+#define DALI_INTEGRATION_ORDERED_SET_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
 
 namespace Dali
 {
-namespace Internal
+namespace Integration
 {
 /**
  * @brief Container of data which has strong point to Find & Erase.
  * It will be useful when we need to iterate the order of data insertion.
  * and need to check whether some object is exist or not very fast.
  * @note Since the data's memory is not continuos, iteration is slower than normal vector contianer.
+ * @note Currently, we only support to hold pointer type data.
  *
  * @tparam T The type of class
  * @tparam owned True if data is owned, So we will automatcally release the memory
@@ -316,8 +317,7 @@ private:
   MapContainer  mMap{};  ///< Helper cache map to find item fast.
   ListContainer mList{}; ///< Ordered by PushBack API called. Actual ownership will be stored here.
 };
-} // namespace Internal
-
+} // namespace Integration
 } // namespace Dali
 
-#endif // DALI_INTERNAL_ORDERED_SET_H
+#endif // DALI_INTEGRATION_ORDERED_SET_H
index 2aafb89..54ac552 100644 (file)
@@ -155,16 +155,17 @@ DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperti
 
 // Signals
 
-static constexpr std::string_view SIGNAL_HOVERED                  = "hovered";
-static constexpr std::string_view SIGNAL_WHEEL_EVENT              = "wheelEvent";
-static constexpr std::string_view SIGNAL_ON_SCENE                 = "onScene";
-static constexpr std::string_view SIGNAL_OFF_SCENE                = "offScene";
-static constexpr std::string_view SIGNAL_ON_RELAYOUT              = "onRelayout";
-static constexpr std::string_view SIGNAL_TOUCHED                  = "touched";
-static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED       = "visibilityChanged";
-static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
-static constexpr std::string_view SIGNAL_CHILD_ADDED              = "childAdded";
-static constexpr std::string_view SIGNAL_CHILD_REMOVED            = "childRemoved";
+static constexpr std::string_view SIGNAL_HOVERED                      = "hovered";
+static constexpr std::string_view SIGNAL_WHEEL_EVENT                  = "wheelEvent";
+static constexpr std::string_view SIGNAL_ON_SCENE                     = "onScene";
+static constexpr std::string_view SIGNAL_OFF_SCENE                    = "offScene";
+static constexpr std::string_view SIGNAL_ON_RELAYOUT                  = "onRelayout";
+static constexpr std::string_view SIGNAL_TOUCHED                      = "touched";
+static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED           = "visibilityChanged";
+static constexpr std::string_view SIGNAL_INHERITED_VISIBILITY_CHANGED = "inheritedVisibilityChanged";
+static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED     = "layoutDirectionChanged";
+static constexpr std::string_view SIGNAL_CHILD_ADDED                  = "childAdded";
+static constexpr std::string_view SIGNAL_CHILD_REMOVED                = "childRemoved";
 
 // Actions
 
@@ -223,6 +224,10 @@ static bool DoConnectSignal(BaseObject*                 object,
   {
     actor->VisibilityChangedSignal().Connect(tracker, functor);
   }
+  else if(name == SIGNAL_INHERITED_VISIBILITY_CHANGED)
+  {
+    actor->InheritedVisibilityChangedSignal().Connect(tracker, functor);
+  }
   else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
   {
     actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
@@ -285,9 +290,10 @@ SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoCo
 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
-SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
-SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
-SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
+SignalConnectorType signalConnector9(mType, std::string(SIGNAL_INHERITED_VISIBILITY_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector10(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
+SignalConnectorType signalConnector12(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
 
 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
@@ -1023,6 +1029,11 @@ void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChan
   EmitSignal(*this, mVisibilityChangedSignal, visible, type);
 }
 
+void Actor::EmitInheritedVisibilityChangedSignal(bool visible)
+{
+  EmitSignal(*this, mInheritedVisibilityChangedSignal, visible);
+}
+
 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
 {
   EmitSignal(*this, mLayoutDirectionChangedSignal, type);
@@ -1078,6 +1089,7 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mOffSceneSignal(),
   mOnRelayoutSignal(),
   mVisibilityChangedSignal(),
+  mInheritedVisibilityChangedSignal(),
   mLayoutDirectionChangedSignal(),
   mHitTestResultSignal(),
   mTargetOrientation(Quaternion::IDENTITY),
@@ -1488,6 +1500,8 @@ void Actor::LowerBelow(Internal::Actor& target)
 
 void Actor::SetParent(ActorParent* parent, bool notify)
 {
+  bool emitInheritedVisible = false;
+  bool visiblility = true;
   if(parent)
   {
     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
@@ -1501,6 +1515,14 @@ void Actor::SetParent(ActorParent* parent, bool notify)
     {
       // Instruct each actor to create a corresponding node in the scene graph
       ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
+
+      Actor* actor         = this;
+      emitInheritedVisible = true;
+      while(emitInheritedVisible && actor)
+      {
+        emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+        actor = actor->GetParent();
+      }
     }
 
     // Resolve the name and index for the child properties if any
@@ -1510,6 +1532,19 @@ void Actor::SetParent(ActorParent* parent, bool notify)
   {
     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
 
+    if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
+       OnScene())
+    {
+      Actor* actor         = this;
+      emitInheritedVisible = true;
+      while(emitInheritedVisible && actor)
+      {
+        emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+        actor = actor->GetParent();
+      }
+      visiblility = false;
+    }
+
     mParent = nullptr;
 
     if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
@@ -1524,6 +1559,11 @@ void Actor::SetParent(ActorParent* parent, bool notify)
 
     mScene = nullptr;
   }
+
+  if(emitInheritedVisible)
+  {
+    EmitInheritedVisibilityChangedSignalRecursively(visiblility);
+  }
 }
 
 Rect<> Actor::CalculateScreenExtents() const
@@ -1691,10 +1731,33 @@ void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
     }
 
+    Actor* actor = this->GetParent();
+    bool emitInheritedVisible = OnScene();
+    while(emitInheritedVisible && actor)
+    {
+      emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+      actor = actor->GetParent();
+    }
+
     mVisible = visible;
 
     // Emit the signal on this actor and all its children
     mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
+    if(emitInheritedVisible)
+    {
+      EmitInheritedVisibilityChangedSignalRecursively(visible);
+    }
+  }
+}
+
+void Actor::EmitInheritedVisibilityChangedSignalRecursively(bool visible)
+{
+  ActorContainer inheritedVisibilityChangedList;
+  mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
+  // Notify applications about the newly connected actors.
+  for(const auto& actor : inheritedVisibilityChangedList)
+  {
+    actor->EmitInheritedVisibilityChangedSignal(visible);
   }
 }
 
index cd71a09..9c9985c 100644 (file)
@@ -1431,6 +1431,12 @@ public:
   void EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type);
 
   /**
+   * @brief Emits the inherited visibility change signal for this actor.
+   * @param[in] visible Whether the actor has become visible or not considering all parent Actors.
+   */
+  void EmitInheritedVisibilityChangedSignal(bool visible);
+
+  /**
    * @brief Emits the layout direction change signal for this actor and all its children.
    * @param[in] type Whether the actor's layout direction property has changed or a parent's.
    */
@@ -1526,6 +1532,14 @@ public:
   }
 
   /**
+   * @copydoc DevelActor::InheritedVisibilityChangedSignal
+   */
+  Dali::Actor::InheritedVisibilityChangedSignalType& InheritedVisibilityChangedSignal()
+  {
+    return mInheritedVisibilityChangedSignal;
+  }
+
+  /**
    * @copydoc LayoutDirectionChangedSignal
    */
   Dali::Actor::LayoutDirectionChangedSignalType& LayoutDirectionChangedSignal()
@@ -1873,6 +1887,13 @@ private:
   void SetVisibleInternal(bool visible, SendMessage::Type sendMessage);
 
   /**
+   * Emits the visibility flag of an actor.
+   * @param[in] visible The new visibility flag.
+   * @param[in] sendMessage Whether to send a message to the update thread or not.
+   */
+  void EmitInheritedVisibilityChangedSignalRecursively(bool visible);
+
+  /**
    * @copydoc ActorParent::SetSiblingOrderOfChild
    */
   void SetSiblingOrderOfChild(Actor& child, uint32_t order) override;
@@ -1944,17 +1965,18 @@ protected:
   ActorGestureData*  mGestureData;  ///< Optional Gesture data. Only created when actor requires gestures
 
   // Signals
-  Dali::Actor::TouchEventSignalType             mInterceptTouchedSignal;
-  Dali::Actor::TouchEventSignalType             mTouchedSignal;
-  Dali::Actor::HoverSignalType                  mHoveredSignal;
-  Dali::Actor::WheelEventSignalType             mInterceptWheelSignal;
-  Dali::Actor::WheelEventSignalType             mWheelEventSignal;
-  Dali::Actor::OnSceneSignalType                mOnSceneSignal;
-  Dali::Actor::OffSceneSignalType               mOffSceneSignal;
-  Dali::Actor::OnRelayoutSignalType             mOnRelayoutSignal;
-  DevelActor::VisibilityChangedSignalType       mVisibilityChangedSignal;
-  Dali::Actor::LayoutDirectionChangedSignalType mLayoutDirectionChangedSignal;
-  Dali::Actor::TouchEventSignalType             mHitTestResultSignal;
+  Dali::Actor::TouchEventSignalType                 mInterceptTouchedSignal;
+  Dali::Actor::TouchEventSignalType                 mTouchedSignal;
+  Dali::Actor::HoverSignalType                      mHoveredSignal;
+  Dali::Actor::WheelEventSignalType                 mInterceptWheelSignal;
+  Dali::Actor::WheelEventSignalType                 mWheelEventSignal;
+  Dali::Actor::OnSceneSignalType                    mOnSceneSignal;
+  Dali::Actor::OffSceneSignalType                   mOffSceneSignal;
+  Dali::Actor::OnRelayoutSignalType                 mOnRelayoutSignal;
+  DevelActor::VisibilityChangedSignalType           mVisibilityChangedSignal;
+  Dali::Actor::InheritedVisibilityChangedSignalType mInheritedVisibilityChangedSignal;
+  Dali::Actor::LayoutDirectionChangedSignalType     mLayoutDirectionChangedSignal;
+  Dali::Actor::TouchEventSignalType                 mHitTestResultSignal;
 
   Quaternion mTargetOrientation; ///< Event-side storage for orientation
   Vector4    mTargetColor;       ///< Event-side storage for color
index bf1b823..8a03b02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -126,18 +126,16 @@ void ActorParentImpl::Remove(Actor& child, bool notify)
   ActorIter end = mChildren->end();
   for(ActorIter iter = mChildren->begin(); iter != end; ++iter)
   {
-    ActorPtr actor = (*iter);
-
-    if(actor.Get() == &child)
+    if((*iter).Get() == &child)
     {
       // Keep handle for OnChildRemove notification
-      removed = actor;
+      removed = (*iter);
 
       // Do this first, since user callbacks from within SetParent() may need to add the child
       mChildren->erase(iter);
 
-      DALI_ASSERT_DEBUG(actor->GetParent() == &mOwner);
-      actor->SetParent(nullptr, notify);
+      DALI_ASSERT_DEBUG(removed->GetParent() == &mOwner);
+      removed->SetParent(nullptr, notify);
 
       break;
     }
@@ -332,8 +330,10 @@ void ActorParentImpl::RaiseChildToTop(Actor& child)
     auto iter = std::find(mChildren->begin(), mChildren->end(), &child);
     if(iter != mChildren->end())
     {
+      ActorPtr childPtr(&child); // ensure actor remains referenced.
+
       mChildren->erase(iter);
-      mChildren->push_back(ActorPtr(&child));
+      mChildren->push_back(childPtr);
       changed = true;
     }
   }
@@ -348,11 +348,11 @@ void ActorParentImpl::LowerChildToBottom(Actor& child)
   bool changed = false;
   if(mChildren && !mChildren->empty() && mChildren->front() != &child) // If not already at bottom,
   {
-    ActorPtr childPtr(&child); // ensure actor remains referenced.
-
     auto iter = std::find(mChildren->begin(), mChildren->end(), &child);
     if(iter != mChildren->end())
     {
+      ActorPtr childPtr(&child); // ensure actor remains referenced.
+
       mChildren->erase(iter);
       mChildren->insert(mChildren->begin(), childPtr);
       changed = true;
@@ -369,12 +369,12 @@ void ActorParentImpl::RaiseChildAbove(Actor& child, Actor& target)
   bool raised = false;
   if(mChildren && !mChildren->empty() && mChildren->back() != &child && target.GetParent() == child.GetParent()) // If not already at top
   {
-    ActorPtr childPtr(&child); // ensure actor actor remains referenced.
-
     auto targetIter = std::find(mChildren->begin(), mChildren->end(), &target);
     auto childIter  = std::find(mChildren->begin(), mChildren->end(), &child);
     if(childIter < targetIter)
     {
+      ActorPtr childPtr(&child); // ensure actor actor remains referenced.
+
       mChildren->erase(childIter);
       // Erasing early invalidates the targetIter. (Conversely, inserting first may also
       // invalidate actorIter)
@@ -397,13 +397,13 @@ void ActorParentImpl::LowerChildBelow(Actor& child, Actor& target)
   // If not already at bottom
   if(mChildren && !mChildren->empty() && mChildren->front() != &child && target.GetParent() == child.GetParent())
   {
-    ActorPtr childPtr(&child); // ensure actor actor remains referenced.
-
     auto targetIter = std::find(mChildren->begin(), mChildren->end(), &target);
     auto childIter  = std::find(mChildren->begin(), mChildren->end(), &child);
 
     if(childIter > targetIter)
     {
+      ActorPtr childPtr(&child); // ensure actor actor remains referenced.
+
       mChildren->erase(childIter); // actor only invalidates iterators at or after actor point.
       mChildren->insert(targetIter, childPtr);
     }
@@ -548,6 +548,22 @@ void ActorParentImpl::EmitVisibilityChangedSignalRecursively(
   }
 }
 
+void ActorParentImpl::InheritVisibilityRecursively(ActorContainer& inheritedVisibilityChangedList)
+{
+  inheritedVisibilityChangedList.push_back(ActorPtr(&mOwner));
+
+  if(mChildren)
+  {
+    for(const auto& child : *mChildren)
+    {
+      if(child->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>())
+      {
+        child->mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
+      }
+    }
+  }
+}
+
 void ActorParentImpl::EmitChildAddedSignal(Actor& child)
 {
   EmitSignal(child, mChildAddedSignal);
index c284953..c7fedb2 100644 (file)
@@ -239,6 +239,13 @@ public:
   void EmitVisibilityChangedSignalRecursively(bool                               visible,
                                               DevelActor::VisibilityChange::Type type);
 
+  /**
+   * @brief Propagates the actor's visibility on the actor tree, and retreives actor list to emit inherited-visibility-changed-signal.
+   *
+   * @param[out] inheritedVisibilityChangedList On return, the list of actors whose inherited visibility is changed.
+   */
+  void InheritVisibilityRecursively(ActorContainer& inheritedVisibilityChangedList);
+
 private:
   /**
    * @brief Emits the ChildAdded signal for this actor
index ddecbd0..e27b4bb 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ANIMATION_PLAYLIST_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -20,8 +20,8 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/common/map-wrapper.h>
+#include <dali/integration-api/ordered-set.h>
 #include <dali/internal/common/message.h>
-#include <dali/internal/common/ordered-set.h>
 #include <dali/internal/event/common/complete-notification-interface.h>
 #include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
 #include <dali/public-api/animation/animation.h>
@@ -119,9 +119,9 @@ private: // from CompleteNotificationInterface
   void NotifyCompleted(CompleteNotificationInterface::ParameterList notifierList) override;
 
 private:
-  OrderedSet<Animation, false>        mAnimations; ///< All existing animations (not owned)
-  std::map<Dali::Animation, uint32_t> mPlaylist;   ///< The currently playing animations (owned through handle).
-                                                   ///< Note we can hold same handles multiple, since OnClear can be called after NotifyCompleted.
+  Integration::OrderedSet<Animation, false> mAnimations; ///< All existing animations (not owned)
+  std::map<Dali::Animation, uint32_t>       mPlaylist;   ///< The currently playing animations (owned through handle).
+                                                         ///< Note we can hold same handles multiple, since OnClear can be called after NotifyCompleted.
 };
 
 /**
index 58a87d8..e54f359 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_PROPERTY_NOTIFICATION_MANAGER_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -22,7 +22,7 @@
 #include <unordered_map>
 
 // INTERNAL INCLUDES
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
 #include <dali/internal/event/common/property-notifier.h>
 #include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
 #include <dali/public-api/common/dali-vector.h>
@@ -82,7 +82,7 @@ private:
   PropertyNotificationManager& operator=(const PropertyNotificationManager& rhs);
 
 private:
-  OrderedSet<PropertyNotification, false> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
+  Integration::OrderedSet<PropertyNotification, false> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
 };
 
 } // namespace Internal
index 135097d..85abccc 100644 (file)
@@ -329,11 +329,13 @@ void GestureEventProcessor::SetPanGestureMultitapSmoothingRange(int32_t value)
 void GestureEventProcessor::SetPanGestureMinimumDistance(int32_t value)
 {
   envOptionMinimumPanDistance = value;
+  mPanGestureProcessor.SetMinimumDistance(value);
 }
 
 void GestureEventProcessor::SetPanGestureMinimumPanEvents(int32_t value)
 {
   envOptionMinimumPanEvents = value;
+  mPanGestureProcessor.SetMinimumPanEvents(value);
 }
 
 void GestureEventProcessor::SetPinchGestureMinimumDistance(float value)
index e1ff19e..a495995 100644 (file)
@@ -495,6 +495,31 @@ void PanGestureProcessor::SetMultitapSmoothingRange(int value)
   mSceneObject->SetMultitapSmoothingRange(value);
 }
 
+void PanGestureProcessor::SetMinimumDistance(int32_t value)
+{
+  if(mGestureRecognizer)
+  {
+    PanGestureRecognizer* panRecognizer = dynamic_cast<PanGestureRecognizer*>(mGestureRecognizer.Get());
+    if(panRecognizer)
+    {
+      panRecognizer->SetMinimumDistance(value);
+    }
+  }
+}
+
+void PanGestureProcessor::SetMinimumPanEvents(int32_t value)
+{
+  if(mGestureRecognizer)
+  {
+    PanGestureRecognizer* panRecognizer = dynamic_cast<PanGestureRecognizer*>(mGestureRecognizer.Get());
+    if(panRecognizer)
+    {
+      panRecognizer->SetMinimumPanEvents(value);
+    }
+  }
+}
+
+
 const SceneGraph::PanGesture& PanGestureProcessor::GetSceneObject() const
 {
   return *mSceneObject;
index bfeb623..c9f60c3 100644 (file)
@@ -221,6 +221,18 @@ public: // To be called by GestureEventProcessor
    */
   void SetMultitapSmoothingRange(int value);
 
+  /**
+   * This method sets the minimum distance to start a pan
+   * @param[in] value The distance in pixels
+   */
+  void SetMinimumDistance(int32_t value);
+
+  /**
+   * Sets the minimum touch events required before a pan can be started
+   * @param[in] value The number of touch events
+   */
+  void SetMinimumPanEvents(int32_t value);
+
 public: // for PanGestureDetector
   /**
    * @return the pan gesture scene object
index 4e6ad9e..d5b40d0 100644 (file)
@@ -345,6 +345,27 @@ void PanGestureRecognizer::SendPan(GestureState state, const Integration::TouchE
   }
 }
 
+void PanGestureRecognizer::SetMinimumDistance(int32_t minimumDistance)
+{
+  if(minimumDistance >= 0)
+  {
+    mMinimumDistanceSquared = minimumDistance * minimumDistance;
+
+    // Usually, we do not want to apply the threshold straight away, but phased over the first few pans
+    // Set our distance to threshold adjustments ratio here.
+    float fMinimumDistance     = static_cast<float>(minimumDistance);
+    mThresholdTotalAdjustments = static_cast<unsigned int>(fMinimumDistance * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO);
+  }
+}
+
+void PanGestureRecognizer::SetMinimumPanEvents(int32_t minimumPanEvents)
+{
+  if(minimumPanEvents >= 1)
+  {
+    mMinimumMotionEvents = minimumPanEvents - 1; // Down is the first event
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 8bc3715..c1b1f30 100644 (file)
@@ -63,6 +63,18 @@ public:
 
 public:
   /**
+   * This method sets the minimum distance to start a pan
+   * @param[in] minimumDistance The distance in pixels
+   */
+  void SetMinimumDistance(int32_t minimumDistance);
+
+  /**
+   * Sets the minimum touch events required before a pan can be started
+   * @param[in] minimumPanEvents The number of touch events
+   */
+  void SetMinimumPanEvents(int32_t minimumPanEvents);
+
+  /**
    * @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
    */
   void SendEvent(const Integration::TouchEvent& event) override;
index a47c8c5..c624a8e 100644 (file)
@@ -214,6 +214,7 @@ void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point
      distanceDelta.y > mMaximumMotionAllowedDistance)
   {
     event.state = GestureState::CANCELLED;
+    DALI_LOG_RELEASE_INFO("There is a long distance between touch down and touch up. (%f or %f > %f)\n", distanceDelta.x, distanceDelta.y, mMaximumMotionAllowedDistance);
   }
   EmitTap(time, event);
 }
index 25ca2dc..b28f64c 100644 (file)
@@ -117,6 +117,11 @@ Actor* RenderTask::GetSourceActor() const
   return mSourceActor.GetActor();
 }
 
+Actor* RenderTask::GetStopperActor() const
+{
+  return mStopperActor.GetActor();
+}
+
 void RenderTask::SetExclusive(bool exclusive)
 {
   if(mExclusive != exclusive)
@@ -640,6 +645,27 @@ uint32_t RenderTask::GetRenderTaskId() const
   return mRenderTaskId;
 }
 
+void RenderTask::RenderUntil(Actor* actor)
+{
+  Actor* target = mSourceActor.GetActor();
+  DALI_ASSERT_ALWAYS((target && actor)
+      && "RenderTask::RenderUntil() has empty actors.");
+  DALI_ASSERT_ALWAYS((target->GetHierarchyDepth() < actor->GetHierarchyDepth())
+      && "RenderTask::RenderUntil() has reversed hierarchy.");
+
+  Actor* parent = actor;
+  while(parent != target && !(parent->IsLayer()))
+  {
+    parent = parent->GetParent();
+  }
+
+  if(parent == target && GetRenderTaskSceneObject())
+  {
+    mStopperActor.SetActor(actor);
+    SetStopperNodeMessage(GetEventThreadServices(), *GetRenderTaskSceneObject(), &actor->GetNode());
+  }
+}
+
 const SceneGraph::RenderTask* RenderTask::GetRenderTaskSceneObject() const
 {
   return static_cast<const SceneGraph::RenderTask*>(mUpdateObject);
index f8897b0..7c57c3e 100644 (file)
@@ -71,6 +71,8 @@ public:
    */
   Actor* GetSourceActor() const;
 
+  Actor* GetStopperActor() const;
+
   /**
    * @copydoc Dali::RenderTask::SetExclusive()
    */
@@ -284,6 +286,8 @@ public:
    */
   uint32_t GetRenderTaskId() const;
 
+  void RenderUntil(Actor* actor);
+
 public: // Used by RenderTaskList, which owns the SceneGraph::RenderTasks
   /**
    * Retrieve the scene-graph RenderTask object.
@@ -388,6 +392,7 @@ private:
   ActorObserver           mSourceActor;        ///< Source actor
   ActorObserver           mCameraActor;        ///< Camera actor
   ActorObserver           mViewportGuideActor; ///< Actor to matching viewport of this render task to this Actor.
+  ActorObserver           mStopperActor;       ///< A child of mSourceActor. Actor to stop rendering.
   WeakHandle<Dali::Actor> mInputMappingActor;  /// used to mapping screen to frame buffer coordinate, not kept alive by rendertask
   RenderTaskList&         mRenderTaskList;     ///< The render task list
 
index 87e7176..967c9d3 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -26,8 +26,8 @@
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/size-negotiation/relayout-container.h>
 
+#include <dali/integration-api/ordered-set.h>
 #include <dali/internal/common/memory-pool-object-allocator.h>
-#include <dali/internal/common/ordered-set.h>
 
 namespace Dali
 {
@@ -124,7 +124,7 @@ private:
   bool Contains(const Dali::Actor& actor);
 
 private:
-  using RelayoutInfoContainer = Dali::Internal::OrderedSet<RelayoutInfo, false, RelayoutInfo::RelayoutInfoHash, RelayoutInfo::RelayoutInfoCompare>;
+  using RelayoutInfoContainer = Dali::Integration::OrderedSet<RelayoutInfo, false, RelayoutInfo::RelayoutInfoHash, RelayoutInfo::RelayoutInfoCompare>;
 
   RelayoutInfoContainer mRelayoutInfos; ///< The list of relayout infos
 
index 91ffd97..d0045dd 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -23,8 +23,8 @@
 #include <memory> // for unique_ptr
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/ordered-set.h>
 #include <dali/internal/common/memory-pool-object-allocator.h>
-#include <dali/internal/common/ordered-set.h>
 #include <dali/internal/event/size-negotiation/memory-pool-relayout-container.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/base-object.h>
@@ -146,7 +146,7 @@ public: // CALLBACKS
   void OnObjectDestroyed(const Dali::RefObject* object);
 
 private:
-  using RawActorList = Dali::Internal::OrderedSet<Dali::Internal::Actor, false>;
+  using RawActorList = Dali::Integration::OrderedSet<Dali::Internal::Actor, false>;
 
   /**
    * @brief Request for relayout. Relays out whole scene.
index 04b58f8..1747bcc 100644 (file)
@@ -23,7 +23,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
 
 #include <dali/internal/event/common/scene-impl.h>
 
@@ -178,14 +178,14 @@ struct RenderManager::Impl
   std::vector<SceneGraph::Scene*> sceneContainer;   ///< List of pointers to the scene graph objects of the scenes
   Render::RenderAlgorithms        renderAlgorithms; ///< The RenderAlgorithms object is used to action the renders required by a RenderInstruction
 
-  OrderedSet<Render::Sampler>         samplerContainer;      ///< List of owned samplers
-  OrderedSet<Render::FrameBuffer>     frameBufferContainer;  ///< List of owned framebuffers
-  OrderedSet<Render::VertexBuffer>    vertexBufferContainer; ///< List of owned vertex buffers
-  OrderedSet<Render::Geometry>        geometryContainer;     ///< List of owned Geometries
-  OwnerKeyContainer<Render::Renderer> rendererContainer;     ///< List of owned renderers
-  OwnerKeyContainer<Render::Texture>  textureContainer;      ///< List of owned textures
+  Integration::OrderedSet<Render::Sampler>      samplerContainer;      ///< List of owned samplers
+  Integration::OrderedSet<Render::FrameBuffer>  frameBufferContainer;  ///< List of owned framebuffers
+  Integration::OrderedSet<Render::VertexBuffer> vertexBufferContainer; ///< List of owned vertex buffers
+  Integration::OrderedSet<Render::Geometry>     geometryContainer;     ///< List of owned Geometries
+  OwnerKeyContainer<Render::Renderer>           rendererContainer;     ///< List of owned renderers
+  OwnerKeyContainer<Render::Texture>            textureContainer;      ///< List of owned textures
 
-  OrderedSet<Render::RenderTracker> mRenderTrackers; ///< List of owned render trackers
+  Integration::OrderedSet<Render::RenderTracker> mRenderTrackers; ///< List of owned render trackers
 
   OwnerKeyContainer<Render::Texture> textureDiscardQueue; ///< Discarded textures
 
index 833be60..8b68fbf 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -46,9 +46,12 @@ public:
    */
   ~PropertyResetterBase() override
   {
-    if(mPropertyOwner != nullptr)
+    if(DALI_LIKELY(mInitialized))
     {
-      mPropertyOwner->RemoveObserver(*this);
+      if(mPropertyOwner != nullptr)
+      {
+        mPropertyOwner->RemoveObserver(*this);
+      }
     }
   }
 
@@ -59,6 +62,9 @@ public:
    */
   void Initialize()
   {
+    DALI_ASSERT_ALWAYS(!mInitialized && "Dont call PropertyResetterBase::Initialize() twice");
+
+    mInitialized = true;
     mPropertyOwner->AddObserver(*this);
     mPropertyOwner->SetUpdated(true);
   }
@@ -162,6 +168,7 @@ protected:
     mBaseProperty(baseProperty),
     mRunning(ACTIVE),
     mActive(ACTIVE),
+    mInitialized(false),
     mDisconnected(false)
   {
   }
@@ -170,7 +177,8 @@ protected:
   PropertyBase*  mBaseProperty;  ///< The base property being animated or constrained
   int8_t         mRunning;       ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
   int8_t         mActive;        ///< 2 if active, 1 if aging, 0 if stopped
-  bool           mDisconnected;  ///< True if the property owner has been disconnected
+  bool           mInitialized : 1;
+  bool           mDisconnected : 1; ///< True if the property owner has been disconnected
 };
 
 class BakerResetter : public PropertyResetterBase
index b3c3d20..6059a12 100644 (file)
@@ -94,6 +94,7 @@ Layer* FindLayer(Node& node)
  * @param[in]  clippingDepth The current scissor clipping depth
  * @param[out] clippingUsed  Gets set to true if any clipping nodes have been found
  * @param[out] keepRendering Gets set to true if rendering should be kept.
+ * @param[out] renderStopped Gets set to true if rendering should be stopped.
  */
 void AddRenderablesForTask(BufferIndex updateBufferIndex,
                            Node&       node,
@@ -105,8 +106,14 @@ void AddRenderablesForTask(BufferIndex updateBufferIndex,
                            uint32_t    clippingDepth,
                            uint32_t    scissorDepth,
                            bool&       clippingUsed,
-                           bool&       keepRendering)
+                           bool&       keepRendering,
+                           bool&       renderStopped)
 {
+  if(renderStopped)
+  {
+    return;
+  }
+
   // Short-circuit for invisible nodes
   if(!node.IsVisible(updateBufferIndex))
   {
@@ -188,10 +195,15 @@ void AddRenderablesForTask(BufferIndex updateBufferIndex,
   // Recurse children.
   NodeContainer& children = node.GetChildren();
   const NodeIter endIter  = children.End();
-  for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
+  for(NodeIter iter = children.Begin(); !renderStopped && iter != endIter; ++iter)
   {
     Node& child = **iter;
-    AddRenderablesForTask(updateBufferIndex, child, parentVisibilityChanged, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering);
+    if(child == renderTask.GetStopperNode())
+    {
+      renderStopped = true;
+      break;
+    }
+    AddRenderablesForTask(updateBufferIndex, child, parentVisibilityChanged, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering, renderStopped);
   }
 }
 
@@ -285,6 +297,8 @@ void ProcessTasks(BufferIndex                          updateBufferIndex,
         sortedLayer->ClearRenderables();
       }
 
+      bool stopRendering = false;
+
       AddRenderablesForTask(updateBufferIndex,
                             *sourceNode,
                             false,
@@ -295,7 +309,8 @@ void ProcessTasks(BufferIndex                          updateBufferIndex,
                             0u,
                             0u,
                             hasClippingNodes,
-                            keepRendering);
+                            keepRendering,
+                            stopRendering);
 
       renderInstructionProcessor.Prepare(updateBufferIndex,
                                          sortedLayers,
index 7a971f5..e97fde8 100644 (file)
@@ -1024,9 +1024,8 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     mImpl->frameCallbackProcessor ||                   // ..a frame callback processor is existed OR
     gestureUpdated;                                    // ..a gesture property was updated
 
-  uint32_t keepUpdating          = 0;
-  bool     keepRendererRendering = false;
-  mImpl->renderingRequired       = false;
+  uint32_t keepUpdating    = 0;
+  mImpl->renderingRequired = false;
 
   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
   // values if the scene was updated in the previous frame.
@@ -1075,7 +1074,10 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     // Call the frame-callback-processor if set
     if(mImpl->frameCallbackProcessor)
     {
-      keepRendererRendering |= mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
+      if(mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds))
+      {
+        keepUpdating |= KeepUpdating::FRAME_UPDATE_CALLBACK;
+      }
     }
 
     // Update node hierarchy, apply constraints,
@@ -1117,7 +1119,9 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     if(mImpl->renderersAdded)
     {
       // Calculate how many render tasks we have in total
-      std::size_t numberOfRenderTasks = 0;
+      std::size_t numberOfRenderTasks        = 0;
+      std::size_t numberOfRenderInstructions = 0;
+      bool        renderContinuously         = false;
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->taskList)
@@ -1126,8 +1130,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
         }
       }
 
-      std::size_t numberOfRenderInstructions = 0;
-      mImpl->renderInstructionCapacity       = 0u;
+      mImpl->renderInstructionCapacity = 0u;
       for(auto&& scene : mImpl->scenes)
       {
         if(scene && scene->root && scene->taskList && scene->scene)
@@ -1146,13 +1149,13 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
           // or keep rendering is requested
           if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
           {
-            keepRendererRendering |= mImpl->renderTaskProcessor.Process(bufferIndex,
-                                                                        *scene->taskList,
-                                                                        *scene->root,
-                                                                        scene->sortedLayerList,
-                                                                        scene->scene->GetRenderInstructions(),
-                                                                        renderToFboEnabled,
-                                                                        isRenderingToFbo);
+            renderContinuously |= mImpl->renderTaskProcessor.Process(bufferIndex,
+                                                                     *scene->taskList,
+                                                                     *scene->root,
+                                                                     scene->sortedLayerList,
+                                                                     scene->scene->GetRenderInstructions(),
+                                                                     renderToFboEnabled,
+                                                                     isRenderingToFbo);
 
             mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
             scene->scene->SetSkipRendering(false);
@@ -1166,6 +1169,11 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
         }
       }
 
+      if(renderContinuously)
+      {
+        keepUpdating |= KeepUpdating::RENDERER_CONTINUOUSLY;
+      }
+
       DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
     }
   }
@@ -1217,12 +1225,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   // Check whether further updates are required
   keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
 
-  if(keepRendererRendering)
-  {
-    keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
-  }
-
-  if(keepUpdating & KeepUpdating::STAGE_KEEP_RENDERING)
+  if(keepUpdating & (KeepUpdating::STAGE_KEEP_RENDERING | KeepUpdating::FRAME_UPDATE_CALLBACK | KeepUpdating::RENDERER_CONTINUOUSLY))
   {
     // Set dirty flags for next frame to continue rendering
     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
index b2de30a..f58a30c 100644 (file)
@@ -91,6 +91,20 @@ inline void SetSourceNodeMessage(EventThreadServices& eventThreadServices, const
   new(slot) LocalType(&task, &RenderTask::SetSourceNode, node);
 }
 
+inline void SetStopperNodeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode)
+{
+  // Scene graph thread can destroy this object.
+  Node* node = const_cast<Node*>(constNode);
+
+  using LocalType = MessageValue1<RenderTask, Node*>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&task, &RenderTask::SetStopperNode, node);
+}
+
 inline void SetCameraMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Camera* constCamera)
 {
   using LocalType = MessageValue1<RenderTask, Camera*>;
index bfe2f5e..dd58a5f 100644 (file)
@@ -94,6 +94,16 @@ Node* RenderTask::GetSourceNode() const
   return mSourceNode;
 }
 
+void RenderTask::SetStopperNode(Node* node)
+{
+  mStopperNode = node;
+}
+
+Node* RenderTask::GetStopperNode() const
+{
+  return mStopperNode;
+}
+
 void RenderTask::SetViewportGuideNode(Node* node)
 {
   mViewportGuideNode = node;
index 3ff90fc..7e07b08 100644 (file)
@@ -87,6 +87,9 @@ public:
    */
   Node* GetSourceNode() const;
 
+  void SetStopperNode(Node* node);
+  Node* GetStopperNode() const;
+
   /**
    * Set the ViewportGuideNode.
    * @param[in] node This node is used to compute viewport of the render task.
@@ -406,6 +409,7 @@ private:
   RenderMessageDispatcher* mRenderMessageDispatcher;
   Render::RenderTracker*   mRenderSyncTracker;
   Node*                    mSourceNode;
+  Node*                    mStopperNode;
   SceneGraph::Camera*      mCameraNode;
   Node*                    mViewportGuideNode;
   Render::FrameBuffer*     mFrameBuffer;
index 0c1b911..cb5b8e7 100644 (file)
@@ -259,6 +259,11 @@ Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
   return GetImplementation(*this).LayoutDirectionChangedSignal();
 }
 
+Actor::InheritedVisibilityChangedSignalType& Actor::InheritedVisibilityChangedSignal()
+{
+  return GetImplementation(*this).InheritedVisibilityChangedSignal();
+}
+
 Actor::Actor(Internal::Actor* internal)
 : Handle(internal)
 {
index 0a58015..c12c6bc 100644 (file)
@@ -218,14 +218,16 @@ using Padding = Rect<float>; ///< Padding definition @SINCE_1_0.0
  * @nosubgrouping
  *
  * Signals
- * | %Signal Name      | Method                       |
- * |-------------------|------------------------------|
- * | touched           | @ref TouchedSignal()         |
- * | hovered           | @ref HoveredSignal()         |
- * | wheelEvent        | @ref WheelEventSignal()      |
- * | onScene           | @ref OnSceneSignal()         |
- * | offScene          | @ref OffSceneSignal()        |
- * | onRelayout        | @ref OnRelayoutSignal()      |
+ * | %Signal Name               | Method                                  |
+ * |----------------------------|-----------------------------------------|
+ * | touched                    | @ref TouchedSignal()                    |
+ * | hovered                    | @ref HoveredSignal()                    |
+ * | wheelEvent                 | @ref WheelEventSignal()                 |
+ * | onScene                    | @ref OnSceneSignal()                    |
+ * | offScene                   | @ref OffSceneSignal()                   |
+ * | onRelayout                 | @ref OnRelayoutSignal()                 |
+ * | layoutDirectionChanged     | @ref LayoutDirectionChangedSignal()     |
+ * | inheritedVisibilityChanged | @ref InheritedVisibilityChangedSignal() |
  *
  * Actions
  * | %Action Name      | %Actor method called         |
@@ -743,13 +745,14 @@ public:
 
   // Typedefs
 
-  using TouchEventSignalType             = Signal<bool(Actor, const TouchEvent&)>;     ///< Touch signal type @SINCE_1_1.37
-  using HoverSignalType                  = Signal<bool(Actor, const HoverEvent&)>;     ///< Hover signal type @SINCE_1_0.0
-  using WheelEventSignalType             = Signal<bool(Actor, const WheelEvent&)>;     ///< Wheel signal type @SINCE_1_0.0
-  using OnSceneSignalType                = Signal<void(Actor)>;                        ///< Scene connection signal type @SINCE_1_9.24
-  using OffSceneSignalType               = Signal<void(Actor)>;                        ///< Scene disconnection signal type @SINCE_1_9.24
-  using OnRelayoutSignalType             = Signal<void(Actor)>;                        ///< Called when the actor is relaid out @SINCE_1_0.0
-  using LayoutDirectionChangedSignalType = Signal<void(Actor, LayoutDirection::Type)>; ///< Layout direction changes signal type. @SINCE_1_2.60
+  using TouchEventSignalType                 = Signal<bool(Actor, const TouchEvent&)>;     ///< Touch signal type @SINCE_1_1.37
+  using HoverSignalType                      = Signal<bool(Actor, const HoverEvent&)>;     ///< Hover signal type @SINCE_1_0.0
+  using WheelEventSignalType                 = Signal<bool(Actor, const WheelEvent&)>;     ///< Wheel signal type @SINCE_1_0.0
+  using OnSceneSignalType                    = Signal<void(Actor)>;                        ///< Scene connection signal type @SINCE_1_9.24
+  using OffSceneSignalType                   = Signal<void(Actor)>;                        ///< Scene disconnection signal type @SINCE_1_9.24
+  using OnRelayoutSignalType                 = Signal<void(Actor)>;                        ///< Called when the actor is relaid out @SINCE_1_0.0
+  using LayoutDirectionChangedSignalType     = Signal<void(Actor, LayoutDirection::Type)>; ///< Layout direction changes signal type. @SINCE_1_2.60
+  using InheritedVisibilityChangedSignalType = Signal<void(Actor, bool)>;                  ///< Signal type of InheritedVisibilityChangedSignalType. @SINCE_2_3.22
 
   // Creation
 
@@ -1288,6 +1291,30 @@ public: // Signals
    */
   LayoutDirectionChangedSignalType& LayoutDirectionChangedSignal();
 
+  /**
+   * @brief This signal is emitted when the visible property of this actor or any of its parents (right up to the root layer) changes.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( Actor actor, bool visible );
+   * @endcode
+   * actor: The actor whose inherited visibility has changed.
+   * visible: This is true if this actor's inherited VISIBLE property is true.
+   * If it is true, it denotes one of the 2 cases.
+   * One is VISIBLE property of this actor or only one of the parent actors were originally false and it becomes true now.
+   * Another is this actor is connected on Scene now with that the VISIBLE property of this actor and all of its parent were true.
+   * If it is false, it also denotes one of the 2 cases.
+   * One is that VISIBLE property of this actor and all of the parent actors were originally true but one of them becomes false now.
+   * Another is VISIBLE property of this actor and all of the parent actors are true and this actor is disconnected from the Scene now.
+   *
+   * @SINCE_2_3.22
+   * @return The signal to connect to
+   * @pre The Actor has been initialized.
+   * @note This signal is NOT emitted if the actor becomes transparent (or the reverse).
+   * @note For reference, an actor is only shown if it and it's parents (up to the root actor) are also visible, are not transparent, and this actor has a non-zero size.
+   */
+  DALI_CORE_API InheritedVisibilityChangedSignalType& InheritedVisibilityChangedSignal();
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index 3b2acaa..b5bcdae 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 3;
-const uint32_t    CORE_MICRO_VERSION = 19;
+const uint32_t    CORE_MICRO_VERSION = 22;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 934e843..5a85dab 100644 (file)
@@ -85,6 +85,8 @@ enum Type
   TRACKBALL,        ///< A trackball style mouse. @SINCE_1_2.60
   REMOCON,          ///< A remote controller. @SINCE_1_2.61
   VIRTUAL_KEYBOARD, ///< A virtual keyboard. @SINCE_1_2.61
+  VIRTUAL_REMOCON,  ///< A virtual remocon. @SINCE_2_3.22
+  VIRTUAL_MOUSE,    ///< A virtual mouse. @SINCE_2_3.22
 };
 
 } // namespace Subclass
index 4521f44..7b26b56 100644 (file)
@@ -85,6 +85,11 @@ Actor RenderTask::GetSourceActor() const
   return Dali::Actor(GetImplementation(*this).GetSourceActor());
 }
 
+Actor RenderTask::GetStopperActor() const
+{
+  return Dali::Actor(GetImplementation(*this).GetStopperActor());
+}
+
 void RenderTask::SetExclusive(bool exclusive)
 {
   GetImplementation(*this).SetExclusive(exclusive);
@@ -307,6 +312,13 @@ uint32_t RenderTask::GetRenderTaskId() const
   return GetImplementation(*this).GetRenderTaskId();
 }
 
+void RenderTask::RenderUntil(Actor actor)
+{
+  DALI_ASSERT_ALWAYS(actor && "RenderUntil() actor does not exist.");
+  Internal::Actor* actorImpl(&GetImplementation(actor));
+  return GetImplementation(*this).RenderUntil(actorImpl);
+}
+
 RenderTask::RenderTask(Internal::RenderTask* internal)
 : Handle(internal)
 {
index 6eab3d4..5d6be1a 100644 (file)
@@ -256,6 +256,8 @@ public:
    */
   Actor GetSourceActor() const;
 
+  Actor GetStopperActor() const;
+
   /**
    * @brief Sets whether the RenderTask has exclusive access to the source actors; the default is false.
    * @SINCE_1_0.0
@@ -579,6 +581,8 @@ public:
    */
   uint32_t GetRenderTaskId() const;
 
+  void RenderUntil(Actor actor);
+
 public: // Signals
   /**
    * @brief If the refresh rate is REFRESH_ONCE, connect to this signal to be notified when a RenderTask has finished.
index cbb4c4c..0711374 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.3.19
+Version:    2.3.22
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT