2 * Copyright (c) 2015 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/update/manager/update-manager.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/object-owner-container.h>
48 #include <dali/internal/update/manager/process-render-tasks.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
53 #include <dali/internal/update/nodes/node.h>
54 #include <dali/internal/update/nodes/scene-graph-layer.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
58 #include <dali/internal/update/rendering/scene-graph-material.h>
59 #include <dali/internal/update/rendering/scene-graph-geometry.h>
60 #include <dali/internal/update/resources/resource-manager.h>
61 #include <dali/internal/update/touch/touch-resampler.h>
63 #include <dali/internal/render/common/render-instruction-container.h>
64 #include <dali/internal/render/common/render-manager.h>
65 #include <dali/internal/render/queue/render-queue.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/shaders/scene-graph-shader.h>
68 #include <dali/internal/render/renderers/render-sampler.h>
70 // Un-comment to enable node tree debug logging
71 //#define NODE_TREE_LOGGING 1
73 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
74 #define SNAPSHOT_NODE_LOGGING \
75 const int FRAME_COUNT_TRIGGER = 16;\
76 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
78 if ( NULL != mImpl->root )\
80 mImpl->frameCounter = 0;\
81 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
84 mImpl->frameCounter++;
86 #define SNAPSHOT_NODE_LOGGING
89 #if defined(DEBUG_ENABLED)
90 extern Debug::Filter* gRenderTaskLogFilter;
94 using namespace Dali::Integration;
95 using Dali::Internal::Update::MessageQueue;
109 void DestroyNodeSet( std::set<Node*>& nodeSet )
111 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
115 // Call Node::OnDestroy as each node is destroyed
125 typedef OwnerContainer< Shader* > ShaderContainer;
126 typedef ShaderContainer::Iterator ShaderIter;
127 typedef ShaderContainer::ConstIterator ShaderConstIter;
129 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
131 typedef OwnerContainer<PanGesture*> GestureContainer;
132 typedef GestureContainer::Iterator GestureIter;
133 typedef GestureContainer::ConstIterator GestureConstIter;
137 * Structure to contain UpdateManager internal data
139 struct UpdateManager::Impl
141 Impl( NotificationManager& notificationManager,
142 CompleteNotificationInterface& animationFinishedNotifier,
143 PropertyNotifier& propertyNotifier,
144 ResourceManager& resourceManager,
145 DiscardQueue& discardQueue,
146 RenderController& renderController,
147 RenderManager& renderManager,
148 RenderQueue& renderQueue,
149 TextureCache& textureCache,
150 TouchResampler& touchResampler,
151 SceneGraphBuffers& sceneGraphBuffers )
153 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
154 notificationManager( notificationManager ),
155 animationFinishedNotifier( animationFinishedNotifier ),
156 propertyNotifier( propertyNotifier ),
158 resourceManager( resourceManager ),
159 discardQueue( discardQueue ),
160 renderController( renderController ),
161 sceneController( NULL ),
162 renderManager( renderManager ),
163 renderQueue( renderQueue ),
164 renderInstructions( renderManager.GetRenderInstructionContainer() ),
165 touchResampler( touchResampler ),
166 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
167 taskList( renderMessageDispatcher, resourceManager ),
168 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
170 systemLevelRoot( NULL ),
171 renderers( sceneGraphBuffers, discardQueue ),
172 geometries( sceneGraphBuffers, discardQueue ),
173 materials( sceneGraphBuffers, discardQueue ),
174 messageQueue( renderController, sceneGraphBuffers ),
175 keepRenderingSeconds( 0.0f ),
176 animationFinishedDuringUpdate( false ),
177 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
178 previousUpdateScene( false ),
180 renderSortingHelper(),
181 renderTaskWaiting( false )
183 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache );
185 renderers.SetSceneController( *sceneController );
186 geometries.SetSceneController( *sceneController );
187 materials.SetSceneController( *sceneController );
192 // Disconnect render tasks from nodes, before destroying the nodes
193 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
194 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
196 (*iter)->SetSourceNode( NULL );
198 // ..repeat for system level RenderTasks
199 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
200 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
202 (*iter)->SetSourceNode( NULL );
205 // UpdateManager owns the Nodes
206 DestroyNodeSet( activeDisconnectedNodes );
207 DestroyNodeSet( connectedNodes );
208 DestroyNodeSet( disconnectedNodes );
210 // If there is root, reset it, otherwise do nothing as rendering was never started
219 if( systemLevelRoot )
221 systemLevelRoot->OnDestroy();
223 delete systemLevelRoot;
224 systemLevelRoot = NULL;
227 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
228 delete sceneController;
231 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
232 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
233 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
234 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
235 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
236 ShaderSaver* shaderSaver; ///< Saves shader binaries.
237 ResourceManager& resourceManager; ///< resource manager
238 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
239 RenderController& renderController; ///< render controller
240 SceneControllerImpl* sceneController; ///< scene controller
241 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
242 RenderQueue& renderQueue; ///< Used to queue messages for the next render
243 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
244 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
246 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
248 RenderTaskList taskList; ///< The list of scene graph render-tasks
249 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
251 Layer* root; ///< The root node (root is a layer)
252 Layer* systemLevelRoot; ///< A separate root-node for system-level content
253 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
254 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
255 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
257 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
258 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
260 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
262 AnimationContainer animations; ///< A container of owned animations
263 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
265 ObjectOwnerContainer<Renderer> renderers;
266 ObjectOwnerContainer<Geometry> geometries; ///< A container of geometries
267 ObjectOwnerContainer<Material> materials; ///< A container of materials
269 ShaderContainer shaders; ///< A container of owned shaders
271 MessageQueue messageQueue; ///< The messages queued from the event-thread
272 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
273 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
274 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
276 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
277 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
279 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
280 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
282 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
283 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
285 GestureContainer gestures; ///< A container of owned gesture detectors
286 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
289 UpdateManager::UpdateManager( NotificationManager& notificationManager,
290 CompleteNotificationInterface& animationFinishedNotifier,
291 PropertyNotifier& propertyNotifier,
292 ResourceManager& resourceManager,
293 DiscardQueue& discardQueue,
294 RenderController& controller,
295 RenderManager& renderManager,
296 RenderQueue& renderQueue,
297 TextureCache& textureCache,
298 TouchResampler& touchResampler )
301 mImpl = new Impl( notificationManager,
302 animationFinishedNotifier,
311 mSceneGraphBuffers );
313 textureCache.SetBufferIndices( &mSceneGraphBuffers );
316 UpdateManager::~UpdateManager()
321 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
323 DALI_ASSERT_DEBUG( layer->IsLayer() );
324 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
328 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
333 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
334 mImpl->systemLevelRoot = layer;
337 layer->SetRoot(true);
340 void UpdateManager::AddNode( Node* node )
342 DALI_ASSERT_ALWAYS( NULL != node );
343 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
345 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
348 void UpdateManager::ConnectNode( Node* parent, Node* node )
350 DALI_ASSERT_ALWAYS( NULL != parent );
351 DALI_ASSERT_ALWAYS( NULL != node );
352 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
354 // Move from active/disconnectedNodes to connectedNodes
355 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
358 removed = mImpl->disconnectedNodes.erase( node );
359 DALI_ASSERT_ALWAYS( removed );
361 mImpl->connectedNodes.insert( node );
363 node->SetActive( true );
365 parent->ConnectChild( node );
368 void UpdateManager::DisconnectNode( Node* node )
370 Node* parent = node->GetParent();
371 DALI_ASSERT_ALWAYS( NULL != parent );
372 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
374 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
375 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
378 void UpdateManager::SetNodeActive( Node* node )
380 DALI_ASSERT_ALWAYS( NULL != node );
381 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
383 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
384 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
385 DALI_ASSERT_ALWAYS( removed );
386 mImpl->activeDisconnectedNodes.insert( node );
388 node->SetActive( true );
391 void UpdateManager::DestroyNode( Node* node )
393 DALI_ASSERT_ALWAYS( NULL != node );
394 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
396 // Transfer ownership from new/disconnectedNodes to the discard queue
397 // This keeps the nodes alive, until the render-thread has finished with them
398 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
401 removed = mImpl->disconnectedNodes.erase( node );
402 DALI_ASSERT_ALWAYS( removed );
404 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
406 // Notify the Node about impending destruction
410 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
411 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
413 DALI_ASSERT_DEBUG( node != NULL );
414 DALI_ASSERT_DEBUG( attachment != NULL );
416 // attach node to attachment first so that parent is known by the time attachment is connected
417 node->Attach( *attachment ); // node takes ownership
420 void UpdateManager::AddObject( PropertyOwner* object )
422 DALI_ASSERT_DEBUG( NULL != object );
424 mImpl->customObjects.PushBack( object );
427 void UpdateManager::RemoveObject( PropertyOwner* object )
429 DALI_ASSERT_DEBUG( NULL != object );
431 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
433 // Find the object and destroy it
434 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
436 PropertyOwner* current = *iter;
437 if ( current == object )
439 customObjects.Erase( iter );
444 // Should not reach here
445 DALI_ASSERT_DEBUG(false);
448 void UpdateManager::AddAnimation( Animation* animation )
450 mImpl->animations.PushBack( animation );
453 void UpdateManager::StopAnimation( Animation* animation )
455 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
457 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
459 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
462 void UpdateManager::RemoveAnimation( Animation* animation )
464 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
466 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
468 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
471 bool UpdateManager::IsAnimationRunning() const
473 bool isRunning(false);
474 AnimationContainer& animations = mImpl->animations;
476 // Find any animation that isn't stopped or paused
478 const AnimationIter endIter = animations.End();
479 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
481 const Animation::State state = (*iter)->GetState();
483 if (state != Animation::Stopped &&
484 state != Animation::Paused)
493 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
495 mImpl->propertyNotifications.PushBack( propertyNotification );
498 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
500 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
501 PropertyNotificationIter iter = propertyNotifications.Begin();
503 while ( iter != propertyNotifications.End() )
505 if( *iter == propertyNotification )
507 propertyNotifications.Erase(iter);
514 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
516 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
517 propertyNotification->SetNotifyMode( notifyMode );
520 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
522 return mImpl->geometries;
525 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
527 return mImpl->renderers;
531 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
533 return mImpl->materials;
536 void UpdateManager::AddShader( Shader* shader )
538 DALI_ASSERT_DEBUG( NULL != shader );
540 if( mImpl->shaders.Count() == 0 )
542 // the first added shader becomes our default shader
543 // Construct message in the render queue memory; note that delete should not be called on the return value
544 typedef MessageValue1< RenderManager, Shader* > DerivedType;
546 // Reserve some memory inside the render queue
547 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
549 // Construct message in the render queue memory; note that delete should not be called on the return value
550 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
553 mImpl->shaders.PushBack( shader );
555 // Allows the shader to dispatch texture requests to the cache
556 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
559 void UpdateManager::RemoveShader( Shader* shader )
561 DALI_ASSERT_DEBUG(shader != NULL);
563 ShaderContainer& shaders = mImpl->shaders;
565 // Find the shader and destroy it
566 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
568 Shader& current = **iter;
569 if ( ¤t == shader )
571 // Transfer ownership to the discard queue
572 // This keeps the shader alive, until the render-thread has finished with it
573 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
578 // Should not reach here
579 DALI_ASSERT_DEBUG(false);
582 void UpdateManager::SetShaderProgram( Shader* shader,
583 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
588 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
590 // Reserve some memory inside the render queue
591 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
593 // Construct message in the render queue memory; note that delete should not be called on the return value
594 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
598 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
600 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
601 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
603 // lock as update might be sending previously compiled shaders to event thread
604 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
605 mImpl->renderCompiledShaders.push_back( shaderData );
609 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
613 // copy the list, this is only likely to happen once in application life cycle
614 return &(mImpl->taskList);
618 // copy the list, this is only likely to happen once in application life cycle
619 return &(mImpl->systemLevelTaskList);
623 void UpdateManager::AddGesture( PanGesture* gesture )
625 DALI_ASSERT_DEBUG( NULL != gesture );
627 mImpl->gestures.PushBack( gesture );
630 void UpdateManager::RemoveGesture( PanGesture* gesture )
632 DALI_ASSERT_DEBUG( gesture != NULL );
634 GestureContainer& gestures = mImpl->gestures;
636 // Find the gesture and destroy it
637 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
639 PanGesture& current = **iter;
640 if ( ¤t == gesture )
642 mImpl->gestures.Erase( iter );
646 // Should not reach here
647 DALI_ASSERT_DEBUG(false);
650 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
652 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
655 void UpdateManager::EventProcessingStarted()
657 mImpl->messageQueue.EventProcessingStarted();
660 bool UpdateManager::FlushQueue()
662 return mImpl->messageQueue.FlushQueue();
665 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
667 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
668 mImpl->animationFinishedDuringUpdate = false;
670 // Animated properties have to be reset to their original value each frame
672 // Reset root properties
675 mImpl->root->ResetToBaseValues( bufferIndex );
677 if ( mImpl->systemLevelRoot )
679 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
682 // Reset the Connected Nodes
683 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
684 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
686 (*iter)->ResetToBaseValues( bufferIndex );
689 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
690 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
693 node->ResetToBaseValues( bufferIndex );
694 node->SetActive( false );
696 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
697 mImpl->activeDisconnectedNodes.erase( iter );
698 mImpl->disconnectedNodes.insert( node );
701 // Reset system-level render-task list properties to base values
702 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
704 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
706 (*iter)->ResetToBaseValues( bufferIndex );
709 // Reset render-task list properties to base values.
710 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
712 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
714 (*iter)->ResetToBaseValues( bufferIndex );
717 // Reset custom object properties to base values
718 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
720 (*iter)->ResetToBaseValues( bufferIndex );
723 mImpl->materials.ResetToBaseValues( bufferIndex );
724 mImpl->geometries.ResetToBaseValues( bufferIndex );
725 mImpl->renderers.ResetToBaseValues( bufferIndex );
728 // Reset animatable shader properties to base values
729 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
731 (*iter)->ResetToBaseValues( bufferIndex );
735 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
737 bool gestureUpdated( false );
739 // constrain gestures... (in construction order)
740 GestureContainer& gestures = mImpl->gestures;
742 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
744 PanGesture& gesture = **iter;
745 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
746 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
749 return gestureUpdated;
752 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
754 AnimationContainer &animations = mImpl->animations;
755 AnimationIter iter = animations.Begin();
756 while ( iter != animations.End() )
758 Animation* animation = *iter;
759 bool finished = animation->Update( bufferIndex, elapsedSeconds );
761 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
763 // Remove animations that had been destroyed but were still waiting for an update
764 if (animation->GetState() == Animation::Destroyed)
766 iter = animations.Erase(iter);
774 if ( mImpl->animationFinishedDuringUpdate )
776 // The application should be notified by NotificationManager, in another thread
777 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
781 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
783 //Constrain custom objects (in construction order)
784 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
785 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
786 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
788 PropertyOwner& object = **iter;
789 ConstrainPropertyOwner( object, bufferIndex );
793 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
795 // Constrain system-level render-tasks
796 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
797 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
799 RenderTask& task = **iter;
800 ConstrainPropertyOwner( task, bufferIndex );
803 // Constrain render-tasks
804 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
805 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
807 RenderTask& task = **iter;
808 ConstrainPropertyOwner( task, bufferIndex );
812 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
814 // constrain shaders... (in construction order)
815 ShaderContainer& shaders = mImpl->shaders;
816 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
818 Shader& shader = **iter;
819 ConstrainPropertyOwner( shader, bufferIndex );
823 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
825 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
826 PropertyNotificationIter iter = notifications.Begin();
828 while ( iter != notifications.End() )
830 PropertyNotification* notification = *iter;
831 bool valid = notification->Check( bufferIndex );
834 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
840 void UpdateManager::PrepareMaterials( BufferIndex bufferIndex )
842 ObjectOwnerContainer<Material>::Iterator iter = mImpl->materials.GetObjectContainer().Begin();
843 const ObjectOwnerContainer<Material>::Iterator end = mImpl->materials.GetObjectContainer().End();
844 for( ; iter != end; ++iter )
847 ConstrainPropertyOwner( *(*iter), bufferIndex );
850 (*iter)->Prepare( mImpl->resourceManager );
854 void UpdateManager::ForwardCompiledShadersToEventThread()
856 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
857 if( mImpl->shaderSaver )
859 // lock and swap the queues
861 // render might be attempting to send us more binaries at the same time
862 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
863 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
866 if( mImpl->updateCompiledShaders.size() > 0 )
868 ShaderSaver& factory = *mImpl->shaderSaver;
869 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
870 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
871 for( ; i != end; ++i )
873 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
875 // we don't need them in update anymore
876 mImpl->updateCompiledShaders.clear();
881 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
883 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
884 unsigned int rendererCount( rendererContainer.Size() );
885 for( unsigned int i(0); i<rendererCount; ++i )
888 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
890 if( rendererContainer[i]->IsReferenced() )
892 rendererContainer[i]->PrepareRender( bufferIndex );
897 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
899 mImpl->nodeDirtyFlags = NothingFlag;
906 // Prepare resources, update shaders, update attachments, for each node
907 // And add the renderers to the sorted layers. Start from root, which is also a layer
908 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
910 mImpl->resourceManager,
911 mImpl->renderQueue );
913 if ( mImpl->systemLevelRoot )
915 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
917 mImpl->resourceManager,
918 mImpl->renderQueue );
922 unsigned int UpdateManager::Update( float elapsedSeconds,
923 unsigned int lastVSyncTimeMilliseconds,
924 unsigned int nextVSyncTimeMilliseconds )
926 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
928 //Clear nodes/resources which were previously discarded
929 mImpl->discardQueue.Clear( bufferIndex );
931 //Grab any loaded resources
932 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
934 //Process Touches & Gestures
935 mImpl->touchResampler.Update();
936 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
938 const bool updateScene = // The scene-graph requires an update if..
939 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
940 IsAnimationRunning() || // ..at least one animation is running OR
941 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
942 resourceChanged || // ..one or more resources were updated/changed OR
943 gestureUpdated; // ..a gesture property was updated
946 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
947 // values if the scene was updated in the previous frame.
948 if( updateScene || mImpl->previousUpdateScene )
950 //Reset properties from the previous update
951 ResetProperties( bufferIndex );
954 //Process the queued scene messages
955 mImpl->messageQueue.ProcessMessages( bufferIndex );
957 //Post Process Ids of resources updated by renderer
958 mImpl->resourceManager.PostProcessResources( bufferIndex );
960 //Forward compiled shader programs to event thread for saving
961 ForwardCompiledShadersToEventThread();
963 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
964 // renderer lists if the scene was updated in the previous frame.
965 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
966 if( updateScene || mImpl->previousUpdateScene )
969 Animate( bufferIndex, elapsedSeconds );
971 //Constraint custom objects
972 ConstrainCustomObjects( bufferIndex );
974 //Prepare materials and apply constraints to them
975 PrepareMaterials( bufferIndex );
977 //Clear the lists of renderable-attachments from the previous update
978 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
980 mImpl->sortedLayers[i]->ClearRenderables();
983 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
985 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
988 //Update node hierarchy, apply constraints and perform sorting / culling.
989 //This will populate each Layer with a list of renderers which are ready.
990 UpdateNodes( bufferIndex );
992 //Apply constraints to RenderTasks, shaders and geometries
993 ConstrainRenderTasks( bufferIndex );
994 ConstrainShaders( bufferIndex );
995 mImpl->geometries.ConstrainObjects( bufferIndex );
997 //Update renderers and apply constraints
998 UpdateRenderers( bufferIndex );
1000 //Process Property Notifications
1001 ProcessPropertyNotifications( bufferIndex );
1003 //Process the RenderTasks; this creates the instructions for rendering the next frame.
1004 //reset the update buffer index and make sure there is enough room in the instruction container
1005 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
1006 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1008 if ( NULL != mImpl->root )
1010 ProcessRenderTasks( bufferIndex,
1013 mImpl->sortedLayers,
1014 mImpl->renderSortingHelper,
1015 mImpl->renderInstructions );
1017 // Process the system-level RenderTasks last
1018 if ( NULL != mImpl->systemLevelRoot )
1020 ProcessRenderTasks( bufferIndex,
1021 mImpl->systemLevelTaskList,
1022 *mImpl->systemLevelRoot,
1023 mImpl->systemLevelSortedLayers,
1024 mImpl->renderSortingHelper,
1025 mImpl->renderInstructions );
1030 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1031 bool doRenderOnceNotify = false;
1032 mImpl->renderTaskWaiting = false;
1033 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1034 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1035 endIter != iter; ++iter )
1037 RenderTask& renderTask(*(*iter));
1039 renderTask.UpdateState();
1041 if( renderTask.IsWaitingToRender() &&
1042 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1044 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1047 if( renderTask.HasRendered() )
1049 doRenderOnceNotify = true;
1053 if( doRenderOnceNotify )
1055 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1056 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1059 // Macro is undefined in release build.
1060 SNAPSHOT_NODE_LOGGING;
1062 // A ResetProperties() may be required in the next frame
1063 mImpl->previousUpdateScene = updateScene;
1065 // Check whether further updates are required
1066 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1068 // tell the update manager that we're done so the queue can be given to event thread
1069 mImpl->notificationManager.UpdateCompleted();
1071 // The update has finished; swap the double-buffering indices
1072 mSceneGraphBuffers.Swap();
1074 return keepUpdating;
1077 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1079 // Update the duration set via Stage::KeepRendering()
1080 if ( mImpl->keepRenderingSeconds > 0.0f )
1082 mImpl->keepRenderingSeconds -= elapsedSeconds;
1085 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1087 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1088 // Keep updating until no messages are received and no animations are running.
1089 // If an animation has just finished, update at least once more for Discard end-actions.
1090 // No need to check for renderQueue as there is always a render after update and if that
1091 // render needs another update it will tell the adaptor to call update again
1093 if ( mImpl->keepRenderingSeconds > 0.0f )
1095 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1098 if ( IsAnimationRunning() ||
1099 mImpl->animationFinishedDuringUpdate )
1101 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1104 if ( mImpl->renderTaskWaiting )
1106 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1109 return keepUpdatingRequest;
1112 void UpdateManager::SetBackgroundColor( const Vector4& color )
1114 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1116 // Reserve some memory inside the render queue
1117 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1119 // Construct message in the render queue memory; note that delete should not be called on the return value
1120 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1123 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1125 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1127 // Reserve some memory inside the render queue
1128 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1130 // Construct message in the render queue memory; note that delete should not be called on the return value
1131 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1134 void UpdateManager::KeepRendering( float durationSeconds )
1136 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1139 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1143 // just copy the vector of pointers
1144 mImpl->sortedLayers = layers;
1148 mImpl->systemLevelSortedLayers = layers;
1152 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1154 mImpl->shaderSaver = &upstream;
1157 void UpdateManager::AddSampler( Render::Sampler* sampler )
1159 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1161 // Reserve some memory inside the render queue
1162 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1164 // Construct message in the render queue memory; note that delete should not be called on the return value
1165 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1168 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1170 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1172 // Reserve some memory inside the render queue
1173 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1175 // Construct message in the render queue memory; note that delete should not be called on the return value
1176 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1179 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1181 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1183 // Reserve some memory inside the render queue
1184 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1186 // Construct message in the render queue memory; note that delete should not be called on the return value
1187 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1190 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1192 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1194 // Reserve some memory inside the render queue
1195 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1197 // Construct message in the render queue memory; note that delete should not be called on the return value
1198 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1201 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1203 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1205 // Reserve some memory inside the render queue
1206 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1208 // Construct message in the render queue memory; note that delete should not be called on the return value
1209 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1212 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1214 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1216 // Reserve some memory inside the render queue
1217 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1219 // Construct message in the render queue memory; note that delete should not be called on the return value
1220 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1223 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1225 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1227 // Reserve some memory inside the render queue
1228 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1230 // Construct message in the render queue memory; note that delete should not be called on the return value
1231 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1234 void UpdateManager::SetPropertyBufferData(Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data)
1236 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>* > DerivedType;
1238 // Reserve some memory inside the render queue
1239 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1241 // Construct message in the render queue memory; note that delete should not be called on the return value
1242 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data );
1245 void UpdateManager::SetPropertyBufferSize(Render::PropertyBuffer* propertyBuffer, size_t size )
1247 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, size_t > DerivedType;
1249 // Reserve some memory inside the render queue
1250 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1252 // Construct message in the render queue memory; note that delete should not be called on the return value
1253 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferSize, propertyBuffer, size );
1256 } // namespace SceneGraph
1258 } // namespace Internal