[dali_2.2.10] Merge branch 'devel/master' 61/287161/1
authorDavid Steele <david.steele@samsung.com>
Fri, 20 Jan 2023 13:10:24 +0000 (13:10 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 20 Jan 2023 13:10:24 +0000 (13:10 +0000)
Change-Id: Idff4fab1760158751d76bbb9ec4d2456f9d0efb6

21 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-harness.cpp
automated-tests/src/dali/dali-test-suite-utils/test-harness.h
automated-tests/src/dali/utc-Dali-Scene.cpp
dali/integration-api/scene.cpp
dali/integration-api/scene.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/common/event-thread-services.cpp
dali/internal/event/common/event-thread-services.h
dali/internal/event/common/property-notification-impl.cpp
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/event/common/thread-local-storage.cpp
dali/internal/event/common/thread-local-storage.h
dali/internal/event/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/internal/update/render-tasks/scene-graph-render-task-list.cpp
dali/internal/update/render-tasks/scene-graph-render-task-list.h
dali/public-api/dali-core-version.cpp
dali/public-api/render-tasks/render-task-list.cpp
dali/public-api/render-tasks/render-task-list.h
packaging/dali.spec

index 86874fd..31080a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -122,6 +122,18 @@ std::string TestModuleName(const char* processName)
   return oss.str();
 }
 
+std::string GetWChan(int pid)
+{
+  std::ostringstream procwchan;
+  procwchan << "/proc/" << pid << "/wchan";
+  std::ifstream ifs;
+  ifs.open(procwchan.str(), std::ifstream::in);
+  std::string line;
+  std::getline(ifs, line);
+  ifs.close();
+  return line;
+}
+
 std::string ReadAndEscape(std::string filename)
 {
   std::ostringstream os;
@@ -496,11 +508,17 @@ int32_t RunAllInParallel(const char* processName, ::testcase tc_array[], std::st
       for(auto& tc : children)
       {
         std::chrono::steady_clock::duration timeSpan = endTime - tc.second.startTime;
-        std::chrono::duration<double>       seconds  = std::chrono::duration_cast<std::chrono::duration<double>>(timeSpan);
-        if(seconds.count() > MAXIMUM_CHILD_LIFETIME)
+        double                              seconds  = double(timeSpan.count()) * std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den;
+
+        if(seconds > MAXIMUM_CHILD_LIFETIME)
         {
           // Kill the child process. A subsequent call to waitpid will process signal result below.
-          kill(tc.first, SIGKILL);
+          if(!tc.second.finished)
+          {
+            printf("Child process %s WCHAN:%s\n", tc.second.name, GetWChan(tc.first).c_str());
+            kill(tc.first, SIGKILL);
+            tc.second.finished = true; // Only send kill signal once.
+          }
         }
       }
     }
@@ -513,8 +531,9 @@ int32_t RunAllInParallel(const char* processName, ::testcase tc_array[], std::st
     {
       if(WIFEXITED(status))
       {
-        auto& testCase  = children[childPid];
-        testCase.result = WEXITSTATUS(status);
+        auto& testCase    = children[childPid];
+        testCase.result   = WEXITSTATUS(status);
+        testCase.finished = true;
         if(testCase.result)
         {
           printf("Test case %s failed: %d\n", testCase.name, testCase.result);
@@ -535,6 +554,7 @@ int32_t RunAllInParallel(const char* processName, ::testcase tc_array[], std::st
         RunningTestCases::iterator iter = children.find(childPid);
         if(iter != children.end())
         {
+          iter->second.finished = true;
           printf("Test case %s exited with signal %s\n", iter->second.name, strsignal(status));
           iter->second.result = 1;
           failedTestCases.push_back(iter->second.testCase);
index 554846f..e884c64 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_HARNESS_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -44,9 +44,10 @@ struct TestCase
   const char*                           name;
   std::chrono::steady_clock::time_point startTime;
   std::chrono::system_clock::time_point startSystemTime;
-  int32_t                               result;
+  int32_t                               result{0};
   pid_t                                 childPid{0};
   testcase*                             tctPtr;
+  bool                                  finished{false};
 
   TestCase(int32_t index, testcase* testCase)
   : testCase(index),
index 0dd5e19..959e5ee 100644 (file)
@@ -2592,3 +2592,86 @@ int UtcDaliSceneSignalInterceptKeyEventN(void)
 
   END_TEST;
 }
+
+int UtcDaliSceneGetOverlayLayer(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::Integration::Scene::GetOverlayLayer");
+
+  Dali::Integration::Scene scene = application.GetScene();
+
+  // Check we get a valid instance.
+  RenderTaskList tasks = scene.GetRenderTaskList();
+
+  // There should be 1 task by default.
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 1u, TEST_LOCATION);
+  RenderTask defaultTask = tasks.GetTask(0u);
+  DALI_TEST_EQUALS(scene.GetRootLayer(), defaultTask.GetSourceActor(), TEST_LOCATION);
+
+  Layer layer = scene.GetOverlayLayer();
+  // There should be 2 task by default.
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION);
+  RenderTask overlayTask = tasks.GetTask(1u);
+  DALI_TEST_EQUALS(overlayTask, tasks.GetOverlayTask(), TEST_LOCATION);
+  DALI_TEST_CHECK(scene.GetRootLayer() != overlayTask.GetSourceActor());
+  DALI_TEST_CHECK(overlayTask != defaultTask);
+  DALI_TEST_EQUALS(overlayTask.GetClearEnabled(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS(overlayTask.IsExclusive(), true, TEST_LOCATION);
+
+  // If new render task is created, the last task is overlayTask
+  RenderTask newTask = scene.GetRenderTaskList().CreateTask();
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 3u, TEST_LOCATION);
+  DALI_TEST_EQUALS(newTask, tasks.GetTask(1u), TEST_LOCATION);
+  DALI_TEST_EQUALS(overlayTask, tasks.GetTask(2u), TEST_LOCATION);
+
+  // Render
+  application.SendNotification();
+  application.Render();
+
+  tasks.RemoveTask(overlayTask);
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION);
+  DALI_TEST_EQUALS(tasks.GetTask(0u), defaultTask, TEST_LOCATION);
+  DALI_TEST_EQUALS(tasks.GetTask(1u), newTask, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliSceneSurfaceResizedWithOverlayLayer(void)
+{
+  tet_infoline("Ensure resizing of the surface is handled properly");
+
+  TestApplication application;
+
+  auto scene = application.GetScene();
+  DALI_TEST_CHECK(scene);
+
+  const RenderTaskList& tasks = scene.GetRenderTaskList();
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 1u, TEST_LOCATION);
+  RenderTask defaultTask = tasks.GetTask(0u);
+  DALI_TEST_EQUALS(scene.GetRootLayer(), defaultTask.GetSourceActor(), TEST_LOCATION);
+
+  // Ensure stage size matches the scene size
+  auto stage = Stage::GetCurrent();
+  Vector2 sceneSize = stage.GetSize();
+  Viewport sceneViewport(0, 0, sceneSize.x, sceneSize.y);
+  DALI_TEST_EQUALS(stage.GetSize(), scene.GetSize(), TEST_LOCATION);
+  Viewport defaultViewport = defaultTask.GetViewport();
+  DALI_TEST_EQUALS(defaultViewport, sceneViewport, TEST_LOCATION);
+
+  Layer layer = scene.GetOverlayLayer();
+  // There should be 2 task by default.
+  DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION);
+  RenderTask overlayTask = tasks.GetTask(1u);
+  Viewport overlayViewport = defaultTask.GetViewport();
+  DALI_TEST_EQUALS(defaultViewport, overlayViewport, TEST_LOCATION);
+
+  // Resize the scene
+  Vector2 newSize(1000.0f, 2000.0f);
+  DALI_TEST_CHECK(stage.GetSize() != newSize);
+  scene.SurfaceResized(newSize.width, newSize.height);
+  Viewport newViewport(0, 0, newSize.x, newSize.y);
+  DALI_TEST_EQUALS(newViewport, defaultTask.GetViewport(), TEST_LOCATION);
+  DALI_TEST_EQUALS(newViewport, defaultTask.GetViewport(), TEST_LOCATION);
+
+  END_TEST;
+}
index 20f85f2..5eedf5c 100644 (file)
@@ -103,6 +103,11 @@ Layer Scene::GetRootLayer() const
   return GetImplementation(*this).GetRootLayer();
 }
 
+Layer Scene::GetOverlayLayer()
+{
+  return GetImplementation(*this).GetOverlayLayer();
+}
+
 uint32_t Scene::GetLayerCount() const
 {
   return GetImplementation(*this).GetLayerCount();
index aac126f..51a8572 100644 (file)
@@ -207,6 +207,14 @@ public:
   Layer GetRootLayer() const;
 
   /**
+   * @brief Returns the Scene's Overlay Layer.
+   * If there is no overlay layer yet, this creates the layer and an associated render task.
+   *
+   * @return The overlay layer
+   */
+  Layer GetOverlayLayer();
+
+  /**
    * @brief Queries the number of on-stage layers.
    *
    * Note that a default layer is always provided (count >= 1).
index bf91a94..ab20929 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -1481,7 +1481,7 @@ void Actor::SetParent(ActorParent* parent, bool notify)
     Actor* parentActor = static_cast<Actor*>(parent);
     mScene             = parentActor->mScene;
 
-    if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
+    if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
        parentActor->OnScene())
     {
       // Instruct each actor to create a corresponding node in the scene graph
@@ -1497,7 +1497,7 @@ void Actor::SetParent(ActorParent* parent, bool notify)
 
     mParent = nullptr;
 
-    if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
+    if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
        OnScene())
     {
       // Disconnect the Node & its children from the scene-graph.
index 75b6c8a..87a42a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -34,5 +34,10 @@ bool EventThreadServices::IsCoreRunning()
   return ThreadLocalStorage::Created();
 }
 
+bool EventThreadServices::IsShuttingDown()
+{
+  return ThreadLocalStorage::IsShuttingDown();
+}
+
 } // namespace Internal
 } // namespace Dali
index 494a722..f2c6ae7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_EVENT_THREAD_SERVICES_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -116,8 +116,17 @@ public:
 
   /**
    * @return true if core is still running and we can send messages
+   * @note It returns false if it is called from a thread other than the main thread.
    */
   static bool IsCoreRunning();
+
+  /**
+   * @brief Check if the event thread service is shutting down.
+   *
+   * @return true if the event thread service is shutting down.
+   * @note It returns false if the core hasn't been initialised yet.
+   */
+  static bool IsShuttingDown();
 };
 
 } // namespace Internal
index 2d87787..6ffecf2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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,6 @@
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/common/object-impl.h>
 #include <dali/internal/event/common/property-notification-manager.h>
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/update/common/scene-graph-property-notification.h>
 #include <dali/internal/update/manager/update-manager.h>
@@ -122,7 +121,7 @@ PropertyNotification::~PropertyNotification()
   Disable();
 
   // Guard to disallow use of PropertyNotificationManager after Core has been destroyed
-  if(Stage::IsInstalled())
+  if(!EventThreadServices::IsShuttingDown())
   {
     // Disconnect from the property notification manager
     mPropertyNotificationManager.PropertyNotificationDestroyed(*this);
@@ -149,7 +148,7 @@ void PropertyNotification::Enable()
 void PropertyNotification::Disable()
 {
   // Guard to allow handle destruction after Core has been destroyed
-  if(Stage::IsInstalled())
+  if(!EventThreadServices::IsShuttingDown())
   {
     // Stop scene-graph from monitoring the target's properties.
     DestroySceneObject();
@@ -227,6 +226,8 @@ void PropertyNotification::DestroySceneObject()
 {
   if(mPropertyNotification != nullptr)
   {
+    DALI_ASSERT_ALWAYS(EventThreadServices::IsCoreRunning());
+
     // Remove PropertyNotification using a message to the update manager
     RemovePropertyNotificationMessage(mUpdateManager, *mPropertyNotification);
     mPropertyNotification = nullptr;
index ea5c689..56ed507 100644 (file)
@@ -85,6 +85,11 @@ Scene::~Scene()
     mRootLayer.Reset();
   }
 
+  if(mOverlayLayer)
+  {
+    mOverlayLayer.Reset();
+  }
+
   if(mRenderTaskList)
   {
     mRenderTaskList.Reset();
@@ -174,6 +179,26 @@ Dali::Layer Scene::GetRootLayer() const
   return Dali::Layer(mRootLayer.Get());
 }
 
+Dali::Layer Scene::GetOverlayLayer()
+{
+  if(!mOverlayLayer)
+  {
+    // Creates overlay layer.
+    mOverlayLayer = Layer::New();
+    mOverlayLayer->SetName("OverlayLayer");
+    mOverlayLayer->SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+    mOverlayLayer->SetParentOrigin(Dali::ParentOrigin::TOP_LEFT);
+    mOverlayLayer->SetAnchorPoint(Dali::AnchorPoint::TOP_LEFT);
+    mRootLayer->Add(*mOverlayLayer);
+
+    // Create the overlay render-task and set exclusive to true.
+    RenderTaskPtr renderTask = mRenderTaskList->CreateOverlayTask(mOverlayLayer.Get(), mDefaultCamera.Get());
+    renderTask->SetExclusive(true);
+    renderTask->SetInputEnabled(true);
+  }
+  return Dali::Layer(mOverlayLayer.Get());
+}
+
 LayerList& Scene::GetLayerList() const
 {
   return *mLayerList;
@@ -337,6 +362,12 @@ void Scene::ChangedSurface(float width, float height, int32_t windowOrientation,
   // set default render-task viewport parameters
   RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u);
   defaultRenderTask->SetViewport(newSize);
+  // set overlay render-task viewport parameters
+  RenderTaskPtr overlayRenderTask = mRenderTaskList->GetOverlayTask();
+  if(overlayRenderTask)
+  {
+    overlayRenderTask->SetViewport(newSize);
+  }
 }
 
 bool Scene::IsSurfaceRectChanged() const
index 52ea356..cda29a2 100644 (file)
@@ -105,6 +105,11 @@ public:
   Dali::Layer GetRootLayer() const;
 
   /**
+   * @copydoc Dali::Integration::Scene::GetOverlayLayer
+   */
+  Dali::Layer GetOverlayLayer();
+
+  /**
    * @copydoc Dali::Integration::Scene::GetLayerCount
    */
   uint32_t GetLayerCount() const;
@@ -380,6 +385,8 @@ private:
 
   LayerPtr mRootLayer;
 
+  LayerPtr mOverlayLayer;
+
   // Ordered list of currently on-stage layers
   OwnerPointer<LayerList> mLayerList;
 
index 6ebfc68..86e848d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -51,22 +51,25 @@ namespace Internal
 {
 namespace
 {
-thread_local ThreadLocalStorage* threadLocal = nullptr;
-}
+thread_local ThreadLocalStorage* threadLocal    = nullptr;
+thread_local bool                isShuttingDown = false;
+} // namespace
 
 ThreadLocalStorage::ThreadLocalStorage(Core* core)
 : mCore(core)
 {
   DALI_ASSERT_ALWAYS(threadLocal == nullptr && "Cannot create more than one ThreadLocalStorage object");
 
-  threadLocal = this;
+  threadLocal    = this;
+  isShuttingDown = false;
 }
 
 ThreadLocalStorage::~ThreadLocalStorage() = default;
 
 void ThreadLocalStorage::Remove()
 {
-  threadLocal = nullptr;
+  threadLocal    = nullptr;
+  isShuttingDown = true;
 }
 
 ThreadLocalStorage& ThreadLocalStorage::Get()
@@ -92,6 +95,11 @@ bool ThreadLocalStorage::Created()
   return (threadLocal != nullptr);
 }
 
+bool ThreadLocalStorage::IsShuttingDown()
+{
+  return isShuttingDown;
+}
+
 ThreadLocalStorage* ThreadLocalStorage::GetInternal()
 {
   return threadLocal;
index 16f3876..8baef7d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_THREAD_LOCAL_STORAGE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -90,6 +90,13 @@ public:
   static bool Created();
 
   /**
+   * Checks if the system is shutting down
+   * @return true if the system is shutting down
+   * @note It returns false if the core hasn't been initialised yet.
+   */
+  static bool IsShuttingDown();
+
+  /**
    * Get a pointer to the TLS or NULL if not initialized
    * @return pointer to the TLS
    */
index 39a98ba..42722b8 100644 (file)
@@ -42,6 +42,7 @@ namespace Dali
 {
 namespace Internal
 {
+
 RenderTaskListPtr RenderTaskList::New()
 {
   RenderTaskListPtr taskList = new RenderTaskList();
@@ -59,12 +60,27 @@ RenderTaskPtr RenderTaskList::CreateTask()
 RenderTaskPtr RenderTaskList::CreateTask(Actor* sourceActor, CameraActor* cameraActor)
 {
   RenderTaskPtr task = RenderTask::New(sourceActor, cameraActor, *this);
-
-  mTasks.push_back(task);
+  if(mOverlayRenderTask && mTasks.back() == mOverlayRenderTask)
+  {
+    mTasks.insert(mTasks.end() - 1, task);
+  }
+  else
+  {
+    mTasks.push_back(task);
+  }
 
   return task;
 }
 
+RenderTaskPtr RenderTaskList::CreateOverlayTask(Actor* sourceActor, CameraActor* cameraActor)
+{
+  if(!mOverlayRenderTask)
+  {
+    mOverlayRenderTask = CreateTask(sourceActor, &mDefaults.GetDefaultCameraActor());
+  }
+  return mOverlayRenderTask;
+}
+
 void RenderTaskList::RemoveTask(Internal::RenderTask& task)
 {
   for(RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter)
@@ -80,13 +96,11 @@ void RenderTaskList::RemoveTask(Internal::RenderTask& task)
       // send a message to remove the scene-graph RenderTask
       RemoveTaskMessage(mEventThreadServices, *mSceneObject, sceneObject);
 
-      for(auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt)
+      Exclusive exclusive{ptr, ActorObserver()};
+      ExclusivesContainer::iterator exclusiveIter = find(mExclusives.begin(), mExclusives.end(), exclusive);
+      if(exclusiveIter != mExclusives.end())
       {
-        if(exclusiveIt->renderTaskPtr == ptr)
-        {
-          mExclusives.erase(exclusiveIt);
-          break;
-        }
+        mExclusives.erase(exclusiveIter);
       }
       break; // we're finished
     }
@@ -105,6 +119,16 @@ RenderTaskPtr RenderTaskList::GetTask(uint32_t index) const
   return mTasks[index];
 }
 
+RenderTaskPtr RenderTaskList::GetOverlayTask() const
+{
+  RenderTaskPtr overlayRenderTask;
+  if(mOverlayRenderTask)
+  {
+    overlayRenderTask = mOverlayRenderTask;
+  }
+  return overlayRenderTask;
+}
+
 void RenderTaskList::SetExclusive(RenderTask* task, bool exclusive)
 {
   // Check to see if this rendertask has an entry?
index 6a8ed44..c01b981 100644 (file)
@@ -59,9 +59,15 @@ public:
   {
     RenderTask*   renderTaskPtr; ///< Pointer for comparison with current rendertask.
     ActorObserver actor;         ///< For comparison with current actor.
+
+    bool operator==(const Exclusive& other) const
+    {
+      return renderTaskPtr == other.renderTaskPtr;
+    }
   };
 
   using ExclusivesContainer = std::vector<Exclusive>;
+  using ExclusiveIter       = ExclusivesContainer::iterator;
 
   /**
    * Create a RenderTaskList.
@@ -86,6 +92,16 @@ public:
   RenderTaskPtr CreateTask(Actor* sourceActor, CameraActor* cameraActor);
 
   /**
+   * @brief Creates a new RenderTask for overlay.
+   * This will be appended to the end of render-task list.
+   * @param[in] sourceActor The actor and its children to be rendered for this render task.
+   * @param[in] cameraActor The actor from which the scene is viewed for this render task.
+   * @return A valid handle to a new overlay RenderTask
+   * @note The Overlay RenderTask will be rendered after all the other render tasks are rendered.
+   */
+  RenderTaskPtr CreateOverlayTask(Actor* sourceActor, CameraActor* cameraActor);
+
+  /**
    * @copydoc Dali::RenderTaskList::RemoveTask()
    */
   void RemoveTask(Internal::RenderTask& task);
@@ -101,6 +117,11 @@ public:
   RenderTaskPtr GetTask(uint32_t index) const;
 
   /**
+   * @copydoc Dali::RenderTaskList::GetOverlayTask()
+   */
+  RenderTaskPtr GetOverlayTask() const;
+
+  /**
    * Retrieve the container of render-tasks.
    * @return The container.
    */
@@ -177,6 +198,7 @@ private:
 
   RenderTaskContainer mTasks;      ///< Reference counted render-tasks
   ExclusivesContainer mExclusives; ///< List of rendertasks with exclusively owned source actors.
+  RenderTaskPtr       mOverlayRenderTask{nullptr};
 };
 
 } // namespace Internal
index 03c39fd..edbbe4a 100644 (file)
@@ -41,7 +41,8 @@ RenderTaskList* RenderTaskList::New()
 
 RenderTaskList::RenderTaskList()
 : mNotificationObject(nullptr),
-  mRenderMessageDispatcher(nullptr)
+  mRenderMessageDispatcher(nullptr),
+  mOverlayRenderTask(nullptr)
 {
 }
 
@@ -63,8 +64,21 @@ void RenderTaskList::AddTask(OwnerPointer<RenderTask>& newTask)
   DALI_ASSERT_DEBUG(mRenderMessageDispatcher != NULL && "RenderMessageDispatcher is null");
 
   newTask->Initialize(*mRenderMessageDispatcher);
-  // mRenderTasks container takes ownership
-  mRenderTasks.PushBack(newTask.Release());
+
+  if(mOverlayRenderTask && mRenderTasks[mRenderTasks.Size() - 1] == mOverlayRenderTask)
+  {
+    mRenderTasks.Insert(mRenderTasks.End() - 1, newTask.Release());
+  }
+  else
+  {
+    mRenderTasks.PushBack(newTask.Release());
+  }
+}
+
+void RenderTaskList::AddOverlayTask(OwnerPointer<RenderTask>& newTask)
+{
+  AddTask(newTask);
+  mOverlayRenderTask = mRenderTasks[mRenderTasks.Size() - 1];
 }
 
 void RenderTaskList::RemoveTask(RenderTask* task)
index 84058fc..2b7242d 100644 (file)
@@ -73,6 +73,12 @@ public:
   void AddTask(OwnerPointer<RenderTask>& newTask);
 
   /**
+   * Add a overlay RenderTask to the list.
+   * @param[in] newTask The RenderTaskList takes ownership of this overlay task.
+   */
+  void AddOverlayTask(OwnerPointer<RenderTask>& newTask);
+
+  /**
    * Remove a RenderTask from the list.
    * @param[in] task The RenderTaskList will destroy this task.
    */
@@ -129,6 +135,7 @@ private:
   CompleteNotificationInterface* mNotificationObject;      ///< object to pass in to the complete notification
   RenderMessageDispatcher*       mRenderMessageDispatcher; ///< for sending messages to render thread
   RenderTaskContainer            mRenderTasks;             ///< A container of owned RenderTasks
+  RenderTask*                    mOverlayRenderTask;       ///< OverlayRenderTask.
 };
 
 // Messages for RenderTaskList
index 53c4e01..7fae984 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 2;
-const uint32_t    CORE_MICRO_VERSION = 9;
+const uint32_t    CORE_MICRO_VERSION = 10;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index eabd958..941c6e7 100644 (file)
@@ -63,6 +63,11 @@ RenderTask RenderTaskList::GetTask(uint32_t index) const
   return RenderTask(GetImplementation(*this).GetTask(index).Get());
 }
 
+RenderTask RenderTaskList::GetOverlayTask() const
+{
+  return RenderTask(GetImplementation(*this).GetOverlayTask().Get());
+}
+
 RenderTaskList::RenderTaskList(Internal::RenderTaskList* internal)
 : BaseHandle(internal)
 {
index ad33f96..0de427c 100644 (file)
@@ -144,6 +144,14 @@ public:
    */
   RenderTask GetTask(uint32_t index) const;
 
+  /**
+   * @brief Retrieves a RenderTask for Overlay
+   * @SINCE_2_2.10
+   * @return A handle to the overlay RenderTask.
+   * If the scene has not created an overlay render task, this returns empty handle.
+   */
+  RenderTask GetOverlayTask() const;
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index 251d3a8..428cf36 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.2.9
+Version:    2.2.10
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT