If a RenderTask's exclusive actor is destoryed, then ensure the RenderTaskList of...
[platform/core/uifw/dali-core.git] / dali / internal / event / render-tasks / render-task-list-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 90bef34..2ae57e8
@@ -1,26 +1,27 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2019 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // CLASS HEADER
 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
-#include <dali/internal/common/event-to-update.h>
-#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/render-tasks/render-task-defaults.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 #include <dali/internal/event/actors/camera-actor-impl.h>
@@ -42,122 +43,164 @@ namespace Dali
 namespace Internal
 {
 
-RenderTaskList* RenderTaskList::New( UpdateManager& updateManager, RenderTaskDefaults& defaults, bool systemLevel )
+RenderTaskListPtr RenderTaskList::New()
 {
-  RenderTaskList* taskList = new RenderTaskList( updateManager.GetEventToUpdate(), defaults, systemLevel );
+  RenderTaskListPtr taskList = new RenderTaskList();
 
-  taskList->Initialize( updateManager );
+  taskList->Initialize();
 
   return taskList;
 }
 
-Dali::RenderTask RenderTaskList::CreateTask()
+RenderTaskPtr RenderTaskList::CreateTask()
 {
-  RenderTask* taskImpl = RenderTask::New( mIsSystemLevel );
-
-  Dali::RenderTask newTask( taskImpl );
-  mTasks.push_back( newTask );
-
-  if ( mSceneObject )
-  {
-    SceneGraph::RenderTask* sceneObject = taskImpl->CreateSceneObject();
-    DALI_ASSERT_DEBUG( NULL != sceneObject );
+  return CreateTask( &mDefaults.GetDefaultRootActor(), &mDefaults.GetDefaultCameraActor() );
+}
 
-    // Pass ownership to SceneGraph::RenderTaskList
-    AddTaskMessage( mEventToUpdate, *mSceneObject, *sceneObject );
-  }
+RenderTaskPtr RenderTaskList::CreateTask( Actor* sourceActor, CameraActor* cameraActor)
+{
+  RenderTaskPtr task = RenderTask::New( sourceActor, cameraActor, *this );
 
-  // Set the default source & camera actors
-  taskImpl->SetSourceActor( &mDefaults.GetDefaultRootActor() );
-  taskImpl->SetCameraActor( &mDefaults.GetDefaultCameraActor() );
+  mTasks.push_back( task );
 
-  return newTask;
+  return task;
 }
 
-void RenderTaskList::RemoveTask( Dali::RenderTask task )
+void RenderTaskList::RemoveTask( Internal::RenderTask& task )
 {
   for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
   {
-    if ( *iter == task )
-    {
-      if ( mSceneObject )
-      {
-        RenderTask& taskImpl = GetImplementation( task );
+    RenderTask *ptr = iter->Get();
 
-        SceneGraph::RenderTask* sceneObject = taskImpl.GetRenderTaskSceneObject();
-        DALI_ASSERT_DEBUG( NULL != sceneObject );
+    if ( ptr == &task )
+    {
+      const SceneGraph::RenderTask& sceneObject = task.GetRenderTaskSceneObject();
 
-        // Send a message to remove the scene-graph RenderTask
-        RemoveTaskMessage( mEventToUpdate, *mSceneObject, *sceneObject );
+      // delete the task
+      mTasks.erase( iter );
+      // send a message to remove the scene-graph RenderTask
+      RemoveTaskMessage( mEventThreadServices, *mSceneObject, sceneObject );
 
-        // The scene-graph RenderTask will be destroyed soon; discard the raw-pointer
-        taskImpl.DiscardSceneObject();
+      for ( auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt )
+      {
+        if ( exclusiveIt->renderTaskPtr == ptr )
+        {
+          mExclusives.erase( exclusiveIt );
+          break;
+        }
       }
-
-      mTasks.erase( iter );
       break; // we're finished
     }
   }
 }
 
-unsigned int RenderTaskList::GetTaskCount() const
+uint32_t RenderTaskList::GetTaskCount() const
 {
-  return mTasks.size();
+  return static_cast<uint32_t>( mTasks.size() ); // only 4,294,967,295 render tasks supported
 }
 
-Dali::RenderTask RenderTaskList::GetTask( unsigned int index ) const
+RenderTaskPtr RenderTaskList::GetTask( uint32_t index ) const
 {
   DALI_ASSERT_ALWAYS( ( index < mTasks.size() ) && "RenderTask index out-of-range" );
 
-  return mTasks[index];
+  return mTasks[ index ];
+}
+
+void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive )
+{
+  // Check to see if this rendertask has an entry?
+  for ( auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt )
+  {
+    if ( exclusiveIt->renderTaskPtr == task )
+    {
+      if ( !exclusive )
+      {
+        mExclusives.erase( exclusiveIt );
+        break;
+      }
+      else
+      {
+        exclusiveIt->actor.SetActor( task->GetSourceActor() );
+        exclusive = false;
+        break;
+      }
+    }
+  }
+  if ( exclusive )
+  {
+    Exclusive exclusiveSlot;
+    exclusiveSlot.renderTaskPtr = task;
+    exclusiveSlot.actor.SetActor( task->GetSourceActor() );
+    mExclusives.emplace_back( std::move( exclusiveSlot ) );
+  }
 }
 
-void RenderTaskList::NotifyFinished()
+RenderTaskList::RenderTaskList()
+: mEventThreadServices( EventThreadServices::Get() ),
+  mDefaults( *Stage::GetCurrent() ),
+  mSceneObject( nullptr )
+{
+}
+
+RenderTaskList::~RenderTaskList()
+{
+  if( EventThreadServices::IsCoreRunning() && mSceneObject )
+  {
+    // Remove the render task list using a message to the update manager
+    RemoveRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), *mSceneObject );
+  }
+}
+
+void RenderTaskList::Initialize()
+{
+  // Create a new render task list, Keep a const pointer to the render task list.
+  mSceneObject = SceneGraph::RenderTaskList::New();
+
+  OwnerPointer< SceneGraph::RenderTaskList > transferOwnership( const_cast< SceneGraph::RenderTaskList* >( mSceneObject ) );
+  AddRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), transferOwnership );
+
+  // set the callback to call us back when tasks are completed
+  mSceneObject->SetCompleteNotificationInterface( this );
+}
+
+void RenderTaskList::NotifyCompleted()
 {
   DALI_LOG_TRACE_METHOD(gLogRenderList);
 
-  std::vector< Dali::RenderTask > finishedRenderTasks;
+  RenderTaskContainer finishedRenderTasks;
 
   // Since render tasks can be unreferenced during the signal emissions, iterators into render tasks pointers may be invalidated.
   // First copy the finished render tasks, then emit signals
-  for ( std::vector<Dali::RenderTask>::iterator it = mTasks.begin(), endIt = mTasks.end(); it != endIt; ++it )
+  for ( RenderTaskContainer::iterator iter = mTasks.begin(), endIt = mTasks.end(); iter != endIt; ++iter )
   {
-    Dali::RenderTask& renderTask( *it );
-
-    if( GetImplementation( renderTask ).HasFinished() )
+    if( (*iter)->HasFinished() )
     {
-      finishedRenderTasks.push_back( Dali::RenderTask( renderTask ) );
+      finishedRenderTasks.push_back( *iter );
     }
   }
 
   // Now it's safe to emit the signals
-  for ( std::vector<Dali::RenderTask>::iterator it = finishedRenderTasks.begin(), endIt = finishedRenderTasks.end(); it != endIt; ++it )
+  for ( auto&& item : finishedRenderTasks )
   {
-    Dali::RenderTask& handle( *it );
-
-    GetImplementation(handle).EmitSignalFinish();
+    item->EmitSignalFinish();
   }
 }
 
-RenderTaskList::RenderTaskList( EventToUpdate& eventToUpdate, RenderTaskDefaults& defaults, bool systemLevel )
-: mEventToUpdate( eventToUpdate ),
-  mDefaults( defaults ),
-  mIsSystemLevel( systemLevel ),
-  mSceneObject( NULL )
-{
-}
-
-RenderTaskList::~RenderTaskList()
+void RenderTaskList::RecoverFromContextLoss()
 {
+  for ( auto&& item : mTasks )
+  {
+    // If the render target renders only once to an offscreen, re-render the render task
+    if( item->GetRefreshRate() == Dali::RenderTask::REFRESH_ONCE && item->GetTargetFrameBuffer() )
+    {
+      item->SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
+    }
+  }
 }
 
-void RenderTaskList::Initialize( UpdateManager& updateManager )
+const SceneGraph::RenderTaskList& RenderTaskList::GetSceneObject() const
 {
-  // This should only be called once, with no existing scene-object
-  DALI_ASSERT_DEBUG( NULL == mSceneObject );
-
-  // Get raw-pointer to render task list
-  mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
+  return *mSceneObject;
 }
 
 } // namespace Internal