2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/update/manager/update-manager.h>
24 #include <dali/public-api/common/stage.h>
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/render-controller.h>
28 #include <dali/integration-api/shader-data.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/owner-container.h>
34 #include <dali/internal/common/message.h>
36 #include <dali/internal/event/common/notification-manager.h>
37 #include <dali/internal/event/common/property-notification-impl.h>
38 #include <dali/internal/event/common/property-notifier.h>
39 #include <dali/internal/event/animation/animation-finished-notifier.h>
40 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
42 #include <dali/internal/update/animation/scene-graph-animator.h>
43 #include <dali/internal/update/animation/scene-graph-animation.h>
44 #include <dali/internal/update/common/discard-queue.h>
45 #include <dali/internal/update/common/double-buffered.h>
46 #include <dali/internal/update/manager/prepare-render-algorithms.h>
47 #include <dali/internal/update/manager/process-render-tasks.h>
48 #include <dali/internal/update/resources/resource-manager.h>
49 #include <dali/internal/update/resources/complete-status-manager.h>
50 #include <dali/internal/update/common/scene-graph-buffers.h>
51 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
52 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
53 #include <dali/internal/update/manager/sorted-layers.h>
54 #include <dali/internal/update/manager/update-algorithms.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/manager/update-manager-debug.h>
57 #include <dali/internal/update/controllers/render-message-dispatcher.h>
58 #include <dali/internal/update/controllers/scene-controller-impl.h>
59 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
60 #include <dali/internal/update/modeling/scene-graph-material.h>
61 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
62 #include <dali/internal/update/nodes/node.h>
63 #include <dali/internal/update/nodes/scene-graph-layer.h>
64 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
65 #include <dali/internal/update/touch/touch-resampler.h>
67 #include <dali/internal/render/common/render-instruction-container.h>
68 #include <dali/internal/render/common/render-manager.h>
69 #include <dali/internal/render/queue/render-queue.h>
70 #include <dali/internal/render/common/performance-monitor.h>
71 #include <dali/internal/render/gl-resources/texture-cache.h>
72 #include <dali/internal/render/renderers/render-material.h>
73 #include <dali/internal/render/shaders/shader.h>
75 // Un-comment to enable node tree debug logging
76 //#define NODE_TREE_LOGGING 1
78 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
79 #define SNAPSHOT_NODE_LOGGING \
80 const int FRAME_COUNT_TRIGGER = 16;\
81 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
83 if ( NULL != mImpl->root )\
85 mImpl->frameCounter = 0;\
86 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
89 mImpl->frameCounter++;
91 #define SNAPSHOT_NODE_LOGGING
94 #if defined(DEBUG_ENABLED)
95 extern Debug::Filter* gRenderTaskLogFilter;
99 using namespace Dali::Integration;
100 using Dali::Internal::Update::MessageQueue;
114 const int DEFAULT_CAMERA_INDEX = -1;
116 void DestroyNodeSet( std::set<Node*>& nodeSet )
118 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
122 // Call Node::OnDestroy as each node is destroyed
132 typedef OwnerContainer< Shader* > ShaderContainer;
133 typedef ShaderContainer::Iterator ShaderIter;
134 typedef ShaderContainer::ConstIterator ShaderConstIter;
136 typedef AnimatableMeshContainer::Iterator AnimatableMeshIter;
137 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
138 typedef MaterialContainer::Iterator MaterialIter;
140 typedef OwnerContainer<PanGesture*> GestureContainer;
141 typedef GestureContainer::Iterator GestureIter;
142 typedef GestureContainer::ConstIterator GestureConstIter;
146 * Structure to contain UpdateManager internal data
148 struct UpdateManager::Impl
150 Impl( NotificationManager& notificationManager,
151 GlSyncAbstraction& glSyncAbstraction,
152 AnimationFinishedNotifier& animationFinishedNotifier,
153 PropertyNotifier& propertyNotifier,
154 ResourceManager& resourceManager,
155 DiscardQueue& discardQueue,
156 RenderController& renderController,
157 RenderManager& renderManager,
158 RenderQueue& renderQueue,
159 TextureCache& textureCache,
160 TouchResampler& touchResampler,
161 SceneGraphBuffers& sceneGraphBuffers )
163 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
164 notificationManager( notificationManager ),
165 animationFinishedNotifier( animationFinishedNotifier ),
166 propertyNotifier( propertyNotifier ),
167 resourceManager( resourceManager ),
168 discardQueue( discardQueue ),
169 renderController( renderController ),
170 sceneController( NULL ),
171 renderManager( renderManager ),
172 renderQueue( renderQueue ),
173 renderInstructions( renderManager.GetRenderInstructionContainer() ),
174 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
175 touchResampler( touchResampler ),
176 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
177 taskList ( completeStatusManager ),
178 systemLevelTaskList ( completeStatusManager ),
180 systemLevelRoot( NULL ),
181 defaultShader( NULL ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 dynamicsWorld( NULL ),
184 dynamicsChanged( false ),
185 keepRenderingSeconds( 0.0f ),
186 animationFinishedDuringUpdate( false ),
187 activeConstraints( 0 ),
188 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
189 previousUpdateScene( false ),
191 renderSortingHelper(),
192 renderTaskList( NULL ),
193 renderTaskWaiting( false )
195 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
200 // Disconnect render tasks from nodes, before destroying the nodes
201 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
202 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
204 (*iter)->SetSourceNode( NULL );
206 // ..repeat for system level RenderTasks
207 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
208 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
210 (*iter)->SetSourceNode( NULL );
213 // UpdateManager owns the Nodes
214 DestroyNodeSet( activeDisconnectedNodes );
215 DestroyNodeSet( connectedNodes );
216 DestroyNodeSet( disconnectedNodes );
218 // If there is root, reset it, otherwise do nothing as rendering was never started
227 if( systemLevelRoot )
229 systemLevelRoot->OnDestroy();
231 delete systemLevelRoot;
232 systemLevelRoot = NULL;
235 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
236 delete sceneController;
239 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
240 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
241 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
242 AnimationFinishedNotifier& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
243 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
244 ResourceManager& resourceManager; ///< resource manager
245 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
246 RenderController& renderController; ///< render controller
247 SceneControllerImpl* sceneController; ///< scene controller
248 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
249 RenderQueue& renderQueue; ///< Used to queue messages for the next render
250 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
251 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
252 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
254 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
256 RenderTaskList taskList; ///< The list of scene graph render-tasks
257 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
259 Layer* root; ///< The root node (root is a layer)
260 Layer* systemLevelRoot; ///< A separate root-node for system-level content
261 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
262 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
263 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
265 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
266 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
268 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
270 AnimationContainer animations; ///< A container of owned animations
271 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
273 Shader* defaultShader; ///< The default shader; owned by ShaderContainer
274 ShaderContainer shaders; ///< A container of owned shaders
275 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
276 MaterialContainer materials; ///< A container of owned materials
278 MessageQueue messageQueue; ///< The messages queued from the event-thread
280 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
281 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
283 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
284 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
286 unsigned int activeConstraints; ///< number of active constraints from previous frame
287 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
288 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
290 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
291 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
293 Internal::RenderTaskList* renderTaskList; ///< Stores a pointer to the internal implementation to the render task list.
294 GestureContainer gestures; ///< A container of owned gesture detectors
295 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
298 UpdateManager::UpdateManager( NotificationManager& notificationManager,
299 GlSyncAbstraction& glSyncAbstraction,
300 AnimationFinishedNotifier& animationFinishedNotifier,
301 PropertyNotifier& propertyNotifier,
302 ResourceManager& resourceManager,
303 DiscardQueue& discardQueue,
304 RenderController& controller,
305 RenderManager& renderManager,
306 RenderQueue& renderQueue,
307 TextureCache& textureCache,
308 TouchResampler& touchResampler )
311 mImpl = new Impl( notificationManager,
313 animationFinishedNotifier,
322 mSceneGraphBuffers );
324 textureCache.SetBufferIndices( &mSceneGraphBuffers );
327 UpdateManager::~UpdateManager()
332 void UpdateManager::SetRenderTaskList( Internal::RenderTaskList* renderTaskList )
334 mImpl->renderTaskList = renderTaskList;
337 EventToUpdate& UpdateManager::GetEventToUpdate()
339 return mImpl->messageQueue;
342 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
344 DALI_ASSERT_DEBUG( layer->IsLayer() );
345 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
349 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
354 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
355 mImpl->systemLevelRoot = layer;
358 layer->SetRoot(true);
361 void UpdateManager::AddNode( Node* node )
363 DALI_ASSERT_ALWAYS( NULL != node );
364 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
366 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
369 void UpdateManager::ConnectNode( Node* parent, Node* node )
371 DALI_ASSERT_ALWAYS( NULL != parent );
372 DALI_ASSERT_ALWAYS( NULL != node );
373 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
375 // Move from active/disconnectedNodes to connectedNodes
376 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
379 removed = mImpl->disconnectedNodes.erase( node );
380 DALI_ASSERT_ALWAYS( removed );
382 mImpl->connectedNodes.insert( node );
384 node->SetActive( true );
386 parent->ConnectChild( node );
389 void UpdateManager::DisconnectNode( Node* node )
391 Node* parent = node->GetParent();
392 DALI_ASSERT_ALWAYS( NULL != parent );
393 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
395 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
396 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
399 void UpdateManager::SetNodeActive( Node* node )
401 DALI_ASSERT_ALWAYS( NULL != node );
402 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
404 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
405 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
406 DALI_ASSERT_ALWAYS( removed );
407 mImpl->activeDisconnectedNodes.insert( node );
409 node->SetActive( true );
412 void UpdateManager::DestroyNode( Node* node )
414 DALI_ASSERT_ALWAYS( NULL != node );
415 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
417 // Transfer ownership from new/disconnectedNodes to the discard queue
418 // This keeps the nodes alive, until the render-thread has finished with them
419 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
422 removed = mImpl->disconnectedNodes.erase( node );
423 DALI_ASSERT_ALWAYS( removed );
425 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
427 // Notify the Node about impending destruction
431 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
433 DALI_ASSERT_DEBUG( node != NULL );
434 DALI_ASSERT_DEBUG( attachment != NULL );
436 // attach node to attachment first so that parent is known by the time attachment is connected
437 node->Attach( *attachment ); // node takes ownership
438 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
441 void UpdateManager::AddObject( PropertyOwner* object )
443 DALI_ASSERT_DEBUG( NULL != object );
445 mImpl->customObjects.PushBack( object );
448 void UpdateManager::RemoveObject( PropertyOwner* object )
450 DALI_ASSERT_DEBUG( NULL != object );
452 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
454 // Find the object and destroy it
455 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
457 PropertyOwner* current = *iter;
458 if ( current == object )
460 customObjects.Erase( iter );
465 // Should not reach here
466 DALI_ASSERT_DEBUG(false);
469 void UpdateManager::AddAnimation( Animation* animation )
471 mImpl->animations.PushBack( animation );
474 void UpdateManager::StopAnimation( Animation* animation )
476 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
478 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
480 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
483 void UpdateManager::RemoveAnimation( Animation* animation )
485 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
487 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
489 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
492 bool UpdateManager::IsAnimationRunning() const
494 bool isRunning(false);
495 AnimationContainer& animations = mImpl->animations;
497 // Find any animation that isn't stopped or paused
499 const AnimationIter endIter = animations.End();
500 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
502 const Animation::State state = (*iter)->GetState();
504 if (state != Animation::Stopped &&
505 state != Animation::Paused)
514 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
516 mImpl->propertyNotifications.PushBack( propertyNotification );
519 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
521 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
522 PropertyNotificationIter iter = propertyNotifications.Begin();
524 while ( iter != propertyNotifications.End() )
526 if( *iter == propertyNotification )
528 propertyNotifications.Erase(iter);
535 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
537 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
538 propertyNotification->SetNotifyMode( notifyMode );
541 Shader* UpdateManager::GetDefaultShader()
543 return mImpl->defaultShader;
546 void UpdateManager::AddShader( Shader* shader )
548 DALI_ASSERT_DEBUG( NULL != shader );
550 // Note: The first shader added becomes the default shader
551 if( NULL == mImpl->defaultShader )
553 mImpl->defaultShader = shader;
556 mImpl->shaders.PushBack( shader );
558 // Allows the shader to dispatch texture requests to the cache and "save shader"
559 // requests to the resource manager from the render thread.
560 shader->Initialize( mImpl->renderManager, mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
563 void UpdateManager::RemoveShader(Shader* shader)
565 DALI_ASSERT_DEBUG(shader != NULL);
567 ShaderContainer& shaders = mImpl->shaders;
569 // Find the shader and destroy it
570 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
572 Shader& current = **iter;
573 if ( ¤t == shader )
575 // Transfer ownership to the discard queue
576 // This keeps the shader alive, until the render-thread has finished with it
577 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
582 // Should not reach here
583 DALI_ASSERT_DEBUG(false);
586 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash )
588 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
590 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
592 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
593 shaderData->SetHashValue( shaderHash );
597 // This is done in the render thread, to allow GL program compilation
598 // Will trigger a NotifySaveRequest back to updateManager to forward onto ResourceClient
599 typedef MessageValue5< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, Context* > DerivedType;
601 // Reserve some memory inside the render queue
602 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
604 // Construct message in the render queue memory; note that delete should not be called on the return value
605 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, &(mImpl->renderManager.GetContext()) );
609 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
611 mImpl->animatableMeshes.PushBack(animatableMesh);
614 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
616 DALI_ASSERT_DEBUG(animatableMesh != NULL);
618 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
620 // Find the animatableMesh and destroy it
621 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
623 AnimatableMesh& current = **iter;
624 if ( ¤t == animatableMesh )
626 animatableMeshes.Erase( iter );
632 void UpdateManager::AddMaterial( Material* material )
634 DALI_ASSERT_DEBUG( NULL != material );
636 mImpl->materials.PushBack( material );
637 RenderMaterial* renderMaterial = new RenderMaterial();
639 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
641 // Reserve some memory inside the render queue
642 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
644 // Construct message in the render queue memory; note that delete should not be called on the return value
645 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
647 material->SetRenderMaterial( renderMaterial );
648 material->OnStageConnection( *mImpl->sceneController );
651 void UpdateManager::RemoveMaterial( Material* theMaterial )
653 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
655 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
657 const Material* aMaterial = *iter;
659 if( aMaterial == theMaterial )
661 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
663 // Reserve some memory inside the render queue
664 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
666 // Construct message in the render queue memory; note that delete should not be called on the return value
667 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
669 mImpl->materials.Erase( iter );
675 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
679 // copy the list, this is only likely to happen once in application life cycle
680 return &(mImpl->taskList);
684 // copy the list, this is only likely to happen once in application life cycle
685 return &(mImpl->systemLevelTaskList);
689 void UpdateManager::AddGesture( PanGesture* gesture )
691 DALI_ASSERT_DEBUG( NULL != gesture );
693 mImpl->gestures.PushBack( gesture );
696 void UpdateManager::RemoveGesture( PanGesture* gesture )
698 DALI_ASSERT_DEBUG( gesture != NULL );
700 GestureContainer& gestures = mImpl->gestures;
702 // Find the gesture and destroy it
703 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
705 PanGesture& current = **iter;
706 if ( ¤t == gesture )
708 mImpl->gestures.Erase( iter );
712 // Should not reach here
713 DALI_ASSERT_DEBUG(false);
716 void UpdateManager::ResetNodeProperty( Node& node )
718 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
721 void UpdateManager::ResetProperties()
723 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
725 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
726 mImpl->animationFinishedDuringUpdate = false;
728 // Animated properties have to be reset to their original value each frame
730 // Reset node properties
733 ResetNodeProperty( *mImpl->root );
736 if ( mImpl->systemLevelRoot )
738 ResetNodeProperty( *mImpl->systemLevelRoot );
741 // Reset the Connected Nodes
742 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
743 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
745 ResetNodeProperty( **iter );
748 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
749 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
752 node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
753 node->SetActive( false );
755 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
756 mImpl->activeDisconnectedNodes.erase( iter );
757 mImpl->disconnectedNodes.insert( node );
760 // Reset system-level render-task list properties to base values
761 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
763 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
765 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
768 // Reset render-task list properties to base values.
769 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
771 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
773 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
776 // Reset custom object properties to base values
777 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
779 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
782 // Reset animatable shader properties to base values
783 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
785 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
788 // Reset animatable animatable mesh properties to base values
789 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
791 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
794 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
797 void UpdateManager::ProcessGestures( unsigned int nextRenderTime )
799 // constrain gestures... (in construction order)
800 GestureContainer& gestures = mImpl->gestures;
802 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
804 PanGesture& gesture = **iter;
805 gesture.UpdateProperties( nextRenderTime );
809 void UpdateManager::Animate( float elapsedSeconds )
811 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
813 AnimationContainer &animations = mImpl->animations;
814 AnimationIter iter = animations.Begin();
815 while ( iter != animations.End() )
817 Animation* animation = *iter;
818 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
820 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
822 // Remove animations that had been destroyed but were still waiting for an update
823 if (animation->GetState() == Animation::Destroyed)
825 iter = animations.Erase(iter);
833 if ( mImpl->animationFinishedDuringUpdate )
835 // The application should be notified by NotificationManager, in another thread
836 mImpl->notificationManager.QueueMessage( AnimationFinishedMessage( mImpl->animationFinishedNotifier ) );
839 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
842 void UpdateManager::ApplyConstraints()
844 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
846 mImpl->activeConstraints = 0;
848 // constrain custom objects... (in construction order)
849 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
851 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
852 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
854 PropertyOwner& object = **iter;
855 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
858 // constrain nodes... (in Depth First traversal order)
861 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
864 if ( mImpl->systemLevelRoot )
866 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
869 // constrain other property-owners after nodes as they are more likely to depend on a node's
870 // current frame property than vice versa. They tend to be final constraints (no further
871 // constraints depend on their properties)
872 // e.g. ShaderEffect uniform a function of Actor's position.
873 // Mesh vertex a function of Actor's position or world position.
875 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
876 // they can be all processed in a super-list of property-owners.
878 // Constrain system-level render-tasks
879 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
881 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
883 RenderTask& task = **iter;
884 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
887 // Constrain render-tasks
888 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
890 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
892 RenderTask& task = **iter;
893 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
896 // constrain meshes (in construction order)
897 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
898 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
900 AnimatableMesh& mesh = **iter;
901 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
904 // constrain shaders... (in construction order)
905 ShaderContainer& shaders = mImpl->shaders;
907 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
909 Shader& shader = **iter;
910 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
913 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
916 void UpdateManager::ProcessPropertyNotifications()
918 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
919 PropertyNotificationIter iter = notifications.Begin();
921 while ( iter != notifications.End() )
923 PropertyNotification* notification = *iter;
925 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
929 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
935 void UpdateManager::UpdateNodes()
937 mImpl->nodeDirtyFlags = NothingFlag;
944 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
946 Shader* defaultShader = GetDefaultShader();
948 if ( NULL != defaultShader )
950 // Prepare resources, update shaders, update attachments, for each node
951 // And add the renderers to the sorted layers. Start from root, which is also a layer
952 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
953 mSceneGraphBuffers.GetUpdateBufferIndex(),
954 mImpl->resourceManager,
958 if ( mImpl->systemLevelRoot )
960 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
961 mSceneGraphBuffers.GetUpdateBufferIndex(),
962 mImpl->resourceManager,
968 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
971 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
973 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
975 AnimatableMesh& current = **iter;
976 current.UpdateMesh( updateBufferIndex );
980 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
982 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
984 Material* material = *iter;
985 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
989 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
991 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
993 Material* material = *iter;
994 material->PrepareRender( updateBufferIndex );
998 unsigned int UpdateManager::Update( float elapsedSeconds, unsigned int lastRenderTime, unsigned int nextRenderTime )
1000 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
1001 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
1002 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
1004 // Measure the time spent in UpdateManager::Update
1005 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
1007 // Update the frame time delta on the render thread.
1008 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1010 // 1) Clear nodes/resources which were previously discarded
1011 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1013 // 2) Grab any loaded resources
1014 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1016 const bool updateScene = // The scene-graph requires an update if..
1017 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1018 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1019 IsAnimationRunning() || // ..at least one animation is running OR
1020 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1021 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued
1022 resourceChanged; // one or more resources were updated/changed
1024 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1025 // values if the scene was updated in the previous frame.
1026 if( updateScene || mImpl->previousUpdateScene )
1028 // 3) Reset properties from the previous update
1032 // 4) Process the queued scene messages
1033 mImpl->messageQueue.ProcessMessages();
1035 // 5) Post Process Ids of resources updated by renderer
1036 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1038 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1039 // renderer lists if the scene was updated in the previous frame.
1040 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1041 if( updateScene || mImpl->previousUpdateScene )
1043 // 6) Process Touches & Gestures
1044 mImpl->touchResampler.Update();
1045 ProcessGestures( nextRenderTime );
1048 Animate( elapsedSeconds );
1050 // 8) Apply Constraints
1053 // 9) Update dynamics simulation
1054 mImpl->dynamicsChanged = false;
1055 if( mImpl->dynamicsWorld )
1057 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1060 // 10) Check Property Notifications
1061 ProcessPropertyNotifications();
1063 // 11) Clear the lists of renderable-attachments from the previous update
1064 ClearRenderables( mImpl->sortedLayers );
1065 ClearRenderables( mImpl->systemLevelSortedLayers );
1067 // 12) Update animated meshes
1068 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1070 // 13) Update materials. Prepares image resources
1071 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1073 // 14) Update node hierarchy and perform sorting / culling.
1074 // This will populate each Layer with a list of renderers which are ready.
1077 // 15) Prepare for the next render
1078 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1079 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1080 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1081 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1082 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1084 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1086 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1087 // reset the update buffer index and make sure there is enough room in the instruction container
1088 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1089 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1091 if ( NULL != mImpl->root )
1093 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1094 mImpl->completeStatusManager,
1097 mImpl->sortedLayers,
1098 mImpl->renderSortingHelper,
1099 mImpl->renderInstructions );
1101 // Process the system-level RenderTasks last
1102 if ( NULL != mImpl->systemLevelRoot )
1104 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1105 mImpl->completeStatusManager,
1106 mImpl->systemLevelTaskList,
1107 *mImpl->systemLevelRoot,
1108 mImpl->systemLevelSortedLayers,
1109 mImpl->renderSortingHelper,
1110 mImpl->renderInstructions );
1113 // if dynamics enabled and active...update matrices for debug drawing
1114 if( mImpl->dynamicsWorld && mImpl->dynamicsChanged )
1116 RenderTask* task(mImpl->taskList.GetTasks()[0]);
1119 mImpl->dynamicsWorld->UpdateMatrices( task->GetProjectionMatrix(mSceneGraphBuffers.GetUpdateBufferIndex()),
1120 task->GetViewMatrix(mSceneGraphBuffers.GetUpdateBufferIndex()) );
1126 // check the countdown and notify
1127 bool doRenderOnceNotify = false;
1128 mImpl->renderTaskWaiting = false;
1129 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1130 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1131 endIter != iter; ++iter )
1133 RenderTask& renderTask(*(*iter));
1135 if( renderTask.IsWaitingToRender() )
1137 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1140 if( renderTask.HasRendered() )
1142 doRenderOnceNotify = true;
1146 if( doRenderOnceNotify )
1148 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1149 mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
1152 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1154 // Macro is undefined in release build.
1155 SNAPSHOT_NODE_LOGGING;
1157 // A ResetProperties() may be required in the next frame
1158 mImpl->previousUpdateScene = updateScene;
1160 // Check whether further updates are required
1161 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1163 #ifdef PERFORMANCE_MONITOR_ENABLED
1164 // Always keep rendering when measuring FPS
1165 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1168 // The update has finished; swap the double-buffering indices
1169 mSceneGraphBuffers.Swap();
1171 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1173 return keepUpdating;
1176 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1178 // Update the duration set via Stage::KeepRendering()
1179 if ( mImpl->keepRenderingSeconds > 0.0f )
1181 mImpl->keepRenderingSeconds -= elapsedSeconds;
1184 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1186 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1187 // Keep updating until no messages are received and no animations are running.
1188 // If an animation has just finished, update at least once more for Discard end-actions.
1189 // No need to check for renderQueue as there is always a render after update and if that
1190 // render needs another update it will tell the adaptor to call update again
1192 if ( mImpl->keepRenderingSeconds > 0.0f )
1194 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1197 if ( !mImpl->messageQueue.WasEmpty() )
1199 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1202 if ( IsAnimationRunning() ||
1203 mImpl->animationFinishedDuringUpdate )
1205 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1208 if ( mImpl->dynamicsChanged )
1210 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1213 if ( mImpl->renderTaskWaiting )
1215 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1218 return keepUpdatingRequest;
1221 void UpdateManager::SetBackgroundColor( const Vector4& color )
1223 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1225 // Reserve some memory inside the render queue
1226 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1228 // Construct message in the render queue memory; note that delete should not be called on the return value
1229 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1232 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1234 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1236 // Reserve some memory inside the render queue
1237 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1239 // Construct message in the render queue memory; note that delete should not be called on the return value
1240 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1243 void UpdateManager::KeepRendering( float durationSeconds )
1245 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1248 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1252 // just copy the vector of pointers
1253 mImpl->sortedLayers = layers;
1257 mImpl->systemLevelSortedLayers = layers;
1261 void UpdateManager::InitializeDynamicsWorld( DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings, Shader* debugShader )
1263 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, debugShader, &mSceneGraphBuffers );
1264 mImpl->dynamicsWorld = dynamicsWorld;
1266 typedef MessageValue1< RenderManager, DynamicsDebugRenderer* > DerivedType;
1268 // Reserve some memory inside the render queue
1269 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1271 // Construct message in the render queue memory; note that delete should not be called on the return value
1272 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeDynamicsDebugRenderer, &dynamicsWorld->GetDebugRenderer() );
1275 void UpdateManager::TerminateDynamicsWorld()
1277 mImpl->dynamicsWorld.Reset();
1280 } // namespace SceneGraph
1282 } // namespace Internal