2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/internal/event/common/event-thread-services.h>
24 #include <dali/internal/event/common/thread-local-storage.h>
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/event/render-tasks/render-task-defaults.h>
27 #include <dali/internal/event/render-tasks/render-task-impl.h>
28 #include <dali/internal/event/actors/camera-actor-impl.h>
29 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
30 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
31 #include <dali/internal/update/manager/update-manager.h>
33 using Dali::Internal::SceneGraph::UpdateManager;
35 #if defined(DEBUG_ENABLED)
38 Debug::Filter* gLogRenderList = Debug::Filter::New(Debug::Concise, false, "LOG_RENDER_TASK_LIST");
47 RenderTaskListPtr RenderTaskList::New()
49 RenderTaskListPtr taskList = new RenderTaskList();
51 taskList->Initialize();
56 Dali::RenderTask RenderTaskList::CreateTask()
58 return CreateTask( &mDefaults.GetDefaultRootActor(), &mDefaults.GetDefaultCameraActor() );
61 Dali::RenderTask RenderTaskList::CreateTask( Actor* sourceActor, CameraActor* cameraActor)
63 RenderTask* taskImpl = RenderTask::New();
65 Dali::RenderTask newTask( taskImpl );
66 mTasks.push_back( newTask );
70 SceneGraph::RenderTask* sceneObject = taskImpl->CreateSceneObject();
72 OwnerPointer< SceneGraph::RenderTask > transferOwnership( sceneObject );
73 AddTaskMessage( mEventThreadServices, *mSceneObject, transferOwnership );
76 // Set the default source & camera actors
77 taskImpl->SetSourceActor( sourceActor );
78 taskImpl->SetCameraActor( cameraActor );
83 void RenderTaskList::RemoveTask( Dali::RenderTask task )
85 for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
89 RenderTask& taskImpl = GetImplementation( task );
92 SceneGraph::RenderTask* sceneObject = taskImpl.GetRenderTaskSceneObject();
93 DALI_ASSERT_DEBUG( NULL != sceneObject );
95 // Send a message to remove the scene-graph RenderTask
96 RemoveTaskMessage( mEventThreadServices, *mSceneObject, *sceneObject );
98 // The scene-graph RenderTask will be destroyed soon; discard the raw-pointer
99 taskImpl.DiscardSceneObject();
102 mTasks.erase( iter );
104 for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
106 if ( exclusiveIt->renderTaskPtr == &taskImpl )
108 mExclusives.Erase( exclusiveIt );
112 break; // we're finished
117 uint32_t RenderTaskList::GetTaskCount() const
119 return static_cast<uint32_t>( mTasks.size() ); // only 4,294,967,295 render tasks supported
122 Dali::RenderTask RenderTaskList::GetTask( uint32_t index ) const
124 DALI_ASSERT_ALWAYS( ( index < mTasks.size() ) && "RenderTask index out-of-range" );
126 return mTasks[index];
129 void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive )
131 // Check to see if this rendertask has an entry?
132 for ( Vector< Exclusive >::Iterator exclusiveIt = mExclusives.Begin(); exclusiveIt != mExclusives.End(); ++exclusiveIt )
134 if ( exclusiveIt->renderTaskPtr == task )
138 mExclusives.Erase( exclusiveIt );
143 exclusiveIt->actorPtr = task->GetSourceActor();
151 Exclusive exclusiveSlot;
152 exclusiveSlot.renderTaskPtr = task;
153 exclusiveSlot.actorPtr = task->GetSourceActor();
154 mExclusives.PushBack( exclusiveSlot );
158 RenderTaskList::RenderTaskList()
159 : mEventThreadServices( *Stage::GetCurrent() ),
160 mDefaults( *Stage::GetCurrent() ),
165 RenderTaskList::~RenderTaskList()
167 if( EventThreadServices::IsCoreRunning() )
169 DestroySceneObject();
173 void RenderTaskList::Initialize()
175 // This should only be called once, with no existing scene-object
176 DALI_ASSERT_DEBUG( NULL == mSceneObject );
180 // set the callback to call us back when tasks are completed
181 mSceneObject->SetCompleteNotificationInterface( this );
184 void RenderTaskList::CreateSceneObject()
186 DALI_ASSERT_DEBUG( mSceneObject == NULL );
188 // Create a new render task list, Keep a const pointer to the render task list.
189 mSceneObject = SceneGraph::RenderTaskList::New();
191 OwnerPointer< SceneGraph::RenderTaskList > transferOwnership( const_cast< SceneGraph::RenderTaskList* >( mSceneObject ) );
192 AddRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), transferOwnership );
195 void RenderTaskList::DestroySceneObject()
197 if ( mSceneObject != NULL )
199 // Remove the render task list using a message to the update manager
200 RemoveRenderTaskListMessage( mEventThreadServices.GetUpdateManager(), *mSceneObject );
205 void RenderTaskList::NotifyCompleted()
207 DALI_LOG_TRACE_METHOD(gLogRenderList);
209 std::vector< Dali::RenderTask > finishedRenderTasks;
211 // Since render tasks can be unreferenced during the signal emissions, iterators into render tasks pointers may be invalidated.
212 // First copy the finished render tasks, then emit signals
213 for ( std::vector<Dali::RenderTask>::iterator it = mTasks.begin(), endIt = mTasks.end(); it != endIt; ++it )
215 Dali::RenderTask& renderTask( *it );
217 if( GetImplementation( renderTask ).HasFinished() )
219 finishedRenderTasks.push_back( Dali::RenderTask( renderTask ) );
223 // Now it's safe to emit the signals
224 for ( std::vector<Dali::RenderTask>::iterator it = finishedRenderTasks.begin(), endIt = finishedRenderTasks.end(); it != endIt; ++it )
226 Dali::RenderTask& handle( *it );
228 GetImplementation(handle).EmitSignalFinish();
232 void RenderTaskList::RecoverFromContextLoss()
234 for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
236 Dali::RenderTask task = *iter;
238 // If the render target renders only once to an offscreen, re-render the render task
239 if( task.GetRefreshRate() == Dali::RenderTask::REFRESH_ONCE && task.GetTargetFrameBuffer() )
241 task.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
246 } // namespace Internal