2 * Copyright (c) 2014 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/public-api/common/set-wrapper.h>
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/render-controller.h>
27 #include <dali/integration-api/shader-data.h>
28 #include <dali/integration-api/debug.h>
30 #include <dali/internal/common/core-impl.h>
31 #include <dali/internal/common/owner-container.h>
32 #include <dali/internal/common/message.h>
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-impl.h>
36 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/update/animation/scene-graph-animator.h>
39 #include <dali/internal/update/animation/scene-graph-animation.h>
40 #include <dali/internal/update/common/discard-queue.h>
41 #include <dali/internal/update/manager/prepare-render-algorithms.h>
42 #include <dali/internal/update/manager/process-render-tasks.h>
43 #include <dali/internal/update/resources/resource-manager.h>
44 #include <dali/internal/update/resources/complete-status-manager.h>
45 #include <dali/internal/update/common/scene-graph-buffers.h>
46 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
47 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
48 #include <dali/internal/update/manager/sorted-layers.h>
49 #include <dali/internal/update/manager/update-algorithms.h>
50 #include <dali/internal/update/queue/update-message-queue.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/controllers/render-message-dispatcher.h>
53 #include <dali/internal/update/controllers/scene-controller-impl.h>
54 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
55 #include <dali/internal/update/modeling/scene-graph-material.h>
56 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
57 #include <dali/internal/update/nodes/node.h>
58 #include <dali/internal/update/nodes/scene-graph-layer.h>
59 #include <dali/internal/update/touch/touch-resampler.h>
61 #include <dali/internal/render/common/render-instruction-container.h>
62 #include <dali/internal/render/common/render-manager.h>
63 #include <dali/internal/render/queue/render-queue.h>
64 #include <dali/internal/render/common/performance-monitor.h>
65 #include <dali/internal/render/gl-resources/texture-cache.h>
66 #include <dali/internal/render/renderers/render-material.h>
67 #include <dali/internal/render/shaders/shader.h>
69 #ifdef DYNAMICS_SUPPORT
70 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
71 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
74 // Un-comment to enable node tree debug logging
75 //#define NODE_TREE_LOGGING 1
77 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
78 #define SNAPSHOT_NODE_LOGGING \
79 const int FRAME_COUNT_TRIGGER = 16;\
80 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
82 if ( NULL != mImpl->root )\
84 mImpl->frameCounter = 0;\
85 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
88 mImpl->frameCounter++;
90 #define SNAPSHOT_NODE_LOGGING
93 #if defined(DEBUG_ENABLED)
94 extern Debug::Filter* gRenderTaskLogFilter;
98 using namespace Dali::Integration;
99 using Dali::Internal::Update::MessageQueue;
113 void DestroyNodeSet( std::set<Node*>& nodeSet )
115 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
119 // Call Node::OnDestroy as each node is destroyed
129 typedef OwnerContainer< Shader* > ShaderContainer;
130 typedef ShaderContainer::Iterator ShaderIter;
131 typedef ShaderContainer::ConstIterator ShaderConstIter;
133 typedef AnimatableMeshContainer::Iterator AnimatableMeshIter;
134 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
135 typedef MaterialContainer::Iterator MaterialIter;
137 typedef OwnerContainer<PanGesture*> GestureContainer;
138 typedef GestureContainer::Iterator GestureIter;
139 typedef GestureContainer::ConstIterator GestureConstIter;
143 * Structure to contain UpdateManager internal data
145 struct UpdateManager::Impl
147 Impl( NotificationManager& notificationManager,
148 GlSyncAbstraction& glSyncAbstraction,
149 CompleteNotificationInterface& animationFinishedNotifier,
150 PropertyNotifier& propertyNotifier,
151 ResourceManager& resourceManager,
152 DiscardQueue& discardQueue,
153 RenderController& renderController,
154 RenderManager& renderManager,
155 RenderQueue& renderQueue,
156 TextureCache& textureCache,
157 TouchResampler& touchResampler,
158 SceneGraphBuffers& sceneGraphBuffers )
160 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
161 notificationManager( notificationManager ),
162 animationFinishedNotifier( animationFinishedNotifier ),
163 propertyNotifier( propertyNotifier ),
164 resourceManager( resourceManager ),
165 discardQueue( discardQueue ),
166 renderController( renderController ),
167 sceneController( NULL ),
168 renderManager( renderManager ),
169 renderQueue( renderQueue ),
170 renderInstructions( renderManager.GetRenderInstructionContainer() ),
171 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
172 touchResampler( touchResampler ),
173 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
174 taskList ( completeStatusManager ),
175 systemLevelTaskList ( completeStatusManager ),
177 systemLevelRoot( NULL ),
178 messageQueue( renderController, sceneGraphBuffers ),
179 dynamicsChanged( false ),
180 keepRenderingSeconds( 0.0f ),
181 animationFinishedDuringUpdate( false ),
182 activeConstraints( 0 ),
183 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
184 previousUpdateScene( false ),
186 renderSortingHelper(),
187 renderTaskWaiting( false )
189 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
194 // Disconnect render tasks from nodes, before destroying the nodes
195 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
196 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
198 (*iter)->SetSourceNode( NULL );
200 // ..repeat for system level RenderTasks
201 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
202 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
204 (*iter)->SetSourceNode( NULL );
207 // UpdateManager owns the Nodes
208 DestroyNodeSet( activeDisconnectedNodes );
209 DestroyNodeSet( connectedNodes );
210 DestroyNodeSet( disconnectedNodes );
212 // If there is root, reset it, otherwise do nothing as rendering was never started
221 if( systemLevelRoot )
223 systemLevelRoot->OnDestroy();
225 delete systemLevelRoot;
226 systemLevelRoot = NULL;
229 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
230 delete sceneController;
233 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
234 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
235 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
236 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
237 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
238 ResourceManager& resourceManager; ///< resource manager
239 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
240 RenderController& renderController; ///< render controller
241 SceneControllerImpl* sceneController; ///< scene controller
242 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
243 RenderQueue& renderQueue; ///< Used to queue messages for the next render
244 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
245 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
246 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
248 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
250 RenderTaskList taskList; ///< The list of scene graph render-tasks
251 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
253 Layer* root; ///< The root node (root is a layer)
254 Layer* systemLevelRoot; ///< A separate root-node for system-level content
255 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
256 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
257 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
259 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
260 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
262 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
264 AnimationContainer animations; ///< A container of owned animations
265 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
267 ShaderContainer shaders; ///< A container of owned shaders
268 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
269 MaterialContainer materials; ///< A container of owned materials
271 MessageQueue messageQueue; ///< The messages queued from the event-thread
273 #ifdef DYNAMICS_SUPPORT
274 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
276 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
278 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
279 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
281 unsigned int activeConstraints; ///< number of active constraints from previous frame
282 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
283 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
285 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
286 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
288 GestureContainer gestures; ///< A container of owned gesture detectors
289 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
292 UpdateManager::UpdateManager( NotificationManager& notificationManager,
293 GlSyncAbstraction& glSyncAbstraction,
294 CompleteNotificationInterface& animationFinishedNotifier,
295 PropertyNotifier& propertyNotifier,
296 ResourceManager& resourceManager,
297 DiscardQueue& discardQueue,
298 RenderController& controller,
299 RenderManager& renderManager,
300 RenderQueue& renderQueue,
301 TextureCache& textureCache,
302 TouchResampler& touchResampler )
305 mImpl = new Impl( notificationManager,
307 animationFinishedNotifier,
316 mSceneGraphBuffers );
318 textureCache.SetBufferIndices( &mSceneGraphBuffers );
321 UpdateManager::~UpdateManager()
326 EventToUpdate& UpdateManager::GetEventToUpdate()
328 return mImpl->messageQueue;
331 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
333 DALI_ASSERT_DEBUG( layer->IsLayer() );
334 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
338 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
343 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
344 mImpl->systemLevelRoot = layer;
347 layer->SetRoot(true);
350 void UpdateManager::AddNode( Node* node )
352 DALI_ASSERT_ALWAYS( NULL != node );
353 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
355 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
358 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
360 DALI_ASSERT_ALWAYS( NULL != parent );
361 DALI_ASSERT_ALWAYS( NULL != node );
362 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
364 // Move from active/disconnectedNodes to connectedNodes
365 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
368 removed = mImpl->disconnectedNodes.erase( node );
369 DALI_ASSERT_ALWAYS( removed );
371 mImpl->connectedNodes.insert( node );
373 node->SetActive( true );
375 parent->ConnectChild( node, index );
378 void UpdateManager::DisconnectNode( Node* node )
380 Node* parent = node->GetParent();
381 DALI_ASSERT_ALWAYS( NULL != parent );
382 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
384 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
385 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
388 void UpdateManager::SetNodeActive( Node* node )
390 DALI_ASSERT_ALWAYS( NULL != node );
391 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
393 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
394 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
395 DALI_ASSERT_ALWAYS( removed );
396 mImpl->activeDisconnectedNodes.insert( node );
398 node->SetActive( true );
401 void UpdateManager::DestroyNode( Node* node )
403 DALI_ASSERT_ALWAYS( NULL != node );
404 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
406 // Transfer ownership from new/disconnectedNodes to the discard queue
407 // This keeps the nodes alive, until the render-thread has finished with them
408 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
411 removed = mImpl->disconnectedNodes.erase( node );
412 DALI_ASSERT_ALWAYS( removed );
414 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
416 // Notify the Node about impending destruction
420 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
422 DALI_ASSERT_DEBUG( node != NULL );
423 DALI_ASSERT_DEBUG( attachment != NULL );
425 // attach node to attachment first so that parent is known by the time attachment is connected
426 node->Attach( *attachment ); // node takes ownership
427 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
430 void UpdateManager::AddObject( PropertyOwner* object )
432 DALI_ASSERT_DEBUG( NULL != object );
434 mImpl->customObjects.PushBack( object );
437 void UpdateManager::RemoveObject( PropertyOwner* object )
439 DALI_ASSERT_DEBUG( NULL != object );
441 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
443 // Find the object and destroy it
444 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
446 PropertyOwner* current = *iter;
447 if ( current == object )
449 customObjects.Erase( iter );
454 // Should not reach here
455 DALI_ASSERT_DEBUG(false);
458 void UpdateManager::AddAnimation( Animation* animation )
460 mImpl->animations.PushBack( animation );
463 void UpdateManager::StopAnimation( Animation* animation )
465 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
467 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
469 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
472 void UpdateManager::RemoveAnimation( Animation* animation )
474 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
476 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
478 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
481 bool UpdateManager::IsAnimationRunning() const
483 bool isRunning(false);
484 AnimationContainer& animations = mImpl->animations;
486 // Find any animation that isn't stopped or paused
488 const AnimationIter endIter = animations.End();
489 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
491 const Animation::State state = (*iter)->GetState();
493 if (state != Animation::Stopped &&
494 state != Animation::Paused)
503 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
505 mImpl->propertyNotifications.PushBack( propertyNotification );
508 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
510 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
511 PropertyNotificationIter iter = propertyNotifications.Begin();
513 while ( iter != propertyNotifications.End() )
515 if( *iter == propertyNotification )
517 propertyNotifications.Erase(iter);
524 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
526 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
527 propertyNotification->SetNotifyMode( notifyMode );
530 void UpdateManager::AddShader( Shader* shader )
532 DALI_ASSERT_DEBUG( NULL != shader );
534 if( mImpl->shaders.Count() == 0 )
536 // the first added shader becomes our default shader
537 // Construct message in the render queue memory; note that delete should not be called on the return value
538 typedef MessageValue1< RenderManager, Shader* > DerivedType;
540 // Reserve some memory inside the render queue
541 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
543 // Construct message in the render queue memory; note that delete should not be called on the return value
544 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
547 mImpl->shaders.PushBack( shader );
549 // Allows the shader to dispatch texture requests to the cache
550 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
553 void UpdateManager::RemoveShader(Shader* shader)
555 DALI_ASSERT_DEBUG(shader != NULL);
557 ShaderContainer& shaders = mImpl->shaders;
559 // Find the shader and destroy it
560 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
562 Shader& current = **iter;
563 if ( ¤t == shader )
565 // Transfer ownership to the discard queue
566 // This keeps the shader alive, until the render-thread has finished with it
567 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
572 // Should not reach here
573 DALI_ASSERT_DEBUG(false);
576 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
578 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
580 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
582 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
585 shaderData->SetHashValue( shaderHash );
586 shaderData->SetResourceId( resourceId );
588 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::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, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
598 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
600 mImpl->animatableMeshes.PushBack(animatableMesh);
603 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
605 DALI_ASSERT_DEBUG(animatableMesh != NULL);
607 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
609 // Find the animatableMesh and destroy it
610 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
612 AnimatableMesh& current = **iter;
613 if ( ¤t == animatableMesh )
615 animatableMeshes.Erase( iter );
621 void UpdateManager::AddMaterial( Material* material )
623 DALI_ASSERT_DEBUG( NULL != material );
625 mImpl->materials.PushBack( material );
626 RenderMaterial* renderMaterial = new RenderMaterial();
628 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
630 // Reserve some memory inside the render queue
631 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
633 // Construct message in the render queue memory; note that delete should not be called on the return value
634 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
636 material->SetRenderMaterial( renderMaterial );
637 material->OnStageConnection( *mImpl->sceneController );
640 void UpdateManager::RemoveMaterial( Material* theMaterial )
642 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
644 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
646 const Material* aMaterial = *iter;
648 if( aMaterial == theMaterial )
650 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
652 // Reserve some memory inside the render queue
653 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
655 // Construct message in the render queue memory; note that delete should not be called on the return value
656 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
658 mImpl->materials.Erase( iter );
664 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
668 // copy the list, this is only likely to happen once in application life cycle
669 return &(mImpl->taskList);
673 // copy the list, this is only likely to happen once in application life cycle
674 return &(mImpl->systemLevelTaskList);
678 void UpdateManager::AddGesture( PanGesture* gesture )
680 DALI_ASSERT_DEBUG( NULL != gesture );
682 mImpl->gestures.PushBack( gesture );
685 void UpdateManager::RemoveGesture( PanGesture* gesture )
687 DALI_ASSERT_DEBUG( gesture != NULL );
689 GestureContainer& gestures = mImpl->gestures;
691 // Find the gesture and destroy it
692 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
694 PanGesture& current = **iter;
695 if ( ¤t == gesture )
697 mImpl->gestures.Erase( iter );
701 // Should not reach here
702 DALI_ASSERT_DEBUG(false);
705 void UpdateManager::ResetNodeProperty( Node& node )
707 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
710 void UpdateManager::ResetProperties()
712 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
714 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
715 mImpl->animationFinishedDuringUpdate = false;
717 // Animated properties have to be reset to their original value each frame
719 // Reset node properties
722 ResetNodeProperty( *mImpl->root );
725 if ( mImpl->systemLevelRoot )
727 ResetNodeProperty( *mImpl->systemLevelRoot );
730 // Reset the Connected Nodes
731 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
732 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
734 ResetNodeProperty( **iter );
737 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
738 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
741 node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
742 node->SetActive( false );
744 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
745 mImpl->activeDisconnectedNodes.erase( iter );
746 mImpl->disconnectedNodes.insert( node );
749 // Reset system-level render-task list properties to base values
750 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
752 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
754 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
757 // Reset render-task list properties to base values.
758 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
760 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
762 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
765 // Reset custom object properties to base values
766 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
768 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
771 // Reset animatable shader properties to base values
772 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
774 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
777 // Reset animatable mesh properties to base values
778 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
780 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
783 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
786 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
788 bool gestureUpdated( false );
790 // constrain gestures... (in construction order)
791 GestureContainer& gestures = mImpl->gestures;
793 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
795 PanGesture& gesture = **iter;
796 gesture.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
797 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
800 return gestureUpdated;
803 void UpdateManager::Animate( float elapsedSeconds )
805 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
807 AnimationContainer &animations = mImpl->animations;
808 AnimationIter iter = animations.Begin();
809 while ( iter != animations.End() )
811 Animation* animation = *iter;
812 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
814 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
816 // Remove animations that had been destroyed but were still waiting for an update
817 if (animation->GetState() == Animation::Destroyed)
819 iter = animations.Erase(iter);
827 if ( mImpl->animationFinishedDuringUpdate )
829 // The application should be notified by NotificationManager, in another thread
830 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
833 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
836 void UpdateManager::ApplyConstraints()
838 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
840 mImpl->activeConstraints = 0;
842 // constrain custom objects... (in construction order)
843 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
845 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
846 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
848 PropertyOwner& object = **iter;
849 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
852 // constrain nodes... (in Depth First traversal order)
855 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
858 if ( mImpl->systemLevelRoot )
860 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
863 // constrain other property-owners after nodes as they are more likely to depend on a node's
864 // current frame property than vice versa. They tend to be final constraints (no further
865 // constraints depend on their properties)
866 // e.g. ShaderEffect uniform a function of Actor's position.
867 // Mesh vertex a function of Actor's position or world position.
869 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
870 // they can be all processed in a super-list of property-owners.
872 // Constrain system-level render-tasks
873 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
875 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
877 RenderTask& task = **iter;
878 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
881 // Constrain render-tasks
882 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
884 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
886 RenderTask& task = **iter;
887 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
890 // constrain meshes (in construction order)
891 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
892 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
894 AnimatableMesh& mesh = **iter;
895 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
898 // constrain shaders... (in construction order)
899 ShaderContainer& shaders = mImpl->shaders;
901 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
903 Shader& shader = **iter;
904 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
907 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
910 void UpdateManager::ProcessPropertyNotifications()
912 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
913 PropertyNotificationIter iter = notifications.Begin();
915 while ( iter != notifications.End() )
917 PropertyNotification* notification = *iter;
919 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
923 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
929 void UpdateManager::UpdateNodes()
931 mImpl->nodeDirtyFlags = NothingFlag;
938 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
940 // Prepare resources, update shaders, update attachments, for each node
941 // And add the renderers to the sorted layers. Start from root, which is also a layer
942 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
943 mSceneGraphBuffers.GetUpdateBufferIndex(),
944 mImpl->resourceManager,
945 mImpl->renderQueue );
947 if ( mImpl->systemLevelRoot )
949 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
950 mSceneGraphBuffers.GetUpdateBufferIndex(),
951 mImpl->resourceManager,
952 mImpl->renderQueue );
955 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
958 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
960 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
962 AnimatableMesh& current = **iter;
963 current.UpdateMesh( updateBufferIndex );
967 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
969 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
971 Material* material = *iter;
972 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
976 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
978 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
980 Material* material = *iter;
981 material->PrepareRender( updateBufferIndex );
985 unsigned int UpdateManager::Update( float elapsedSeconds,
986 unsigned int lastVSyncTimeMilliseconds,
987 unsigned int nextVSyncTimeMilliseconds )
989 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
990 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
991 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
993 // Measure the time spent in UpdateManager::Update
994 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
996 // Update the frame time delta on the render thread.
997 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
999 // 1) Clear nodes/resources which were previously discarded
1000 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1002 // 2) Grab any loaded resources
1003 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1005 // 3) Process Touches & Gestures
1006 mImpl->touchResampler.Update();
1007 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1009 const bool updateScene = // The scene-graph requires an update if..
1010 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1011 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1012 IsAnimationRunning() || // ..at least one animation is running OR
1013 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1014 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
1015 resourceChanged || // ..one or more resources were updated/changed OR
1016 gestureUpdated; // ..a gesture property was updated
1018 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1019 // values if the scene was updated in the previous frame.
1020 if( updateScene || mImpl->previousUpdateScene )
1022 // 4) Reset properties from the previous update
1026 // 5) Process the queued scene messages
1027 mImpl->messageQueue.ProcessMessages();
1029 // 6) Post Process Ids of resources updated by renderer
1030 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1032 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1033 // renderer lists if the scene was updated in the previous frame.
1034 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1035 if( updateScene || mImpl->previousUpdateScene )
1038 Animate( elapsedSeconds );
1040 // 8) Apply Constraints
1043 #ifdef DYNAMICS_SUPPORT
1044 // 9) Update dynamics simulation
1045 mImpl->dynamicsChanged = false;
1046 if( mImpl->dynamicsWorld )
1048 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1052 // 10) Check Property Notifications
1053 ProcessPropertyNotifications();
1055 // 11) Clear the lists of renderable-attachments from the previous update
1056 ClearRenderables( mImpl->sortedLayers );
1057 ClearRenderables( mImpl->systemLevelSortedLayers );
1059 // 12) Update animated meshes
1060 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1062 // 13) Update materials. Prepares image resources
1063 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1065 // 14) Update node hierarchy and perform sorting / culling.
1066 // This will populate each Layer with a list of renderers which are ready.
1069 // 15) Prepare for the next render
1070 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1071 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1072 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1073 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1074 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1076 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1078 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1079 // reset the update buffer index and make sure there is enough room in the instruction container
1080 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1081 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1083 if ( NULL != mImpl->root )
1085 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1086 mImpl->completeStatusManager,
1089 mImpl->sortedLayers,
1090 mImpl->renderSortingHelper,
1091 mImpl->renderInstructions );
1093 // Process the system-level RenderTasks last
1094 if ( NULL != mImpl->systemLevelRoot )
1096 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1097 mImpl->completeStatusManager,
1098 mImpl->systemLevelTaskList,
1099 *mImpl->systemLevelRoot,
1100 mImpl->systemLevelSortedLayers,
1101 mImpl->renderSortingHelper,
1102 mImpl->renderInstructions );
1107 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1108 bool doRenderOnceNotify = false;
1109 mImpl->renderTaskWaiting = false;
1110 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1111 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1112 endIter != iter; ++iter )
1114 RenderTask& renderTask(*(*iter));
1116 renderTask.UpdateState();
1118 if( renderTask.IsWaitingToRender() &&
1119 renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1121 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1124 if( renderTask.HasRendered() )
1126 doRenderOnceNotify = true;
1130 if( doRenderOnceNotify )
1132 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1133 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1136 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1138 // Macro is undefined in release build.
1139 SNAPSHOT_NODE_LOGGING;
1141 // A ResetProperties() may be required in the next frame
1142 mImpl->previousUpdateScene = updateScene;
1144 // Check whether further updates are required
1145 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1147 #ifdef PERFORMANCE_MONITOR_ENABLED
1148 // Always keep rendering when measuring FPS
1149 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1152 // The update has finished; swap the double-buffering indices
1153 mSceneGraphBuffers.Swap();
1155 // tell the update manager that we're done so the queue can be given to event thread
1156 mImpl->notificationManager.UpdateCompleted();
1158 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1160 return keepUpdating;
1163 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1165 // Update the duration set via Stage::KeepRendering()
1166 if ( mImpl->keepRenderingSeconds > 0.0f )
1168 mImpl->keepRenderingSeconds -= elapsedSeconds;
1171 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1173 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1174 // Keep updating until no messages are received and no animations are running.
1175 // If an animation has just finished, update at least once more for Discard end-actions.
1176 // No need to check for renderQueue as there is always a render after update and if that
1177 // render needs another update it will tell the adaptor to call update again
1179 if ( mImpl->keepRenderingSeconds > 0.0f )
1181 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1184 if ( !mImpl->messageQueue.WasEmpty() )
1186 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1189 if ( IsAnimationRunning() ||
1190 mImpl->animationFinishedDuringUpdate )
1192 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1195 if ( mImpl->dynamicsChanged )
1197 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1200 if ( mImpl->renderTaskWaiting )
1202 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1205 return keepUpdatingRequest;
1208 void UpdateManager::SetBackgroundColor( const Vector4& color )
1210 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1212 // Reserve some memory inside the render queue
1213 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1215 // Construct message in the render queue memory; note that delete should not be called on the return value
1216 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1219 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1221 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1223 // Reserve some memory inside the render queue
1224 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1226 // Construct message in the render queue memory; note that delete should not be called on the return value
1227 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1230 void UpdateManager::KeepRendering( float durationSeconds )
1232 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1235 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1239 // just copy the vector of pointers
1240 mImpl->sortedLayers = layers;
1244 mImpl->systemLevelSortedLayers = layers;
1248 #ifdef DYNAMICS_SUPPORT
1250 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1252 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1253 mImpl->dynamicsWorld = dynamicsWorld;
1256 void UpdateManager::TerminateDynamicsWorld()
1258 mImpl->dynamicsWorld.Reset();
1261 #endif // DYNAMICS_SUPPORT
1263 } // namespace SceneGraph
1265 } // namespace Internal