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/common/double-buffered.h>
42 #include <dali/internal/update/manager/prepare-render-algorithms.h>
43 #include <dali/internal/update/manager/process-render-tasks.h>
44 #include <dali/internal/update/resources/resource-manager.h>
45 #include <dali/internal/update/resources/complete-status-manager.h>
46 #include <dali/internal/update/common/scene-graph-buffers.h>
47 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
48 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/queue/update-message-queue.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/controllers/render-message-dispatcher.h>
54 #include <dali/internal/update/controllers/scene-controller-impl.h>
55 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
56 #include <dali/internal/update/modeling/scene-graph-material.h>
57 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
58 #include <dali/internal/update/nodes/node.h>
59 #include <dali/internal/update/nodes/scene-graph-layer.h>
60 #include <dali/internal/update/touch/touch-resampler.h>
62 #include <dali/internal/render/common/render-instruction-container.h>
63 #include <dali/internal/render/common/render-manager.h>
64 #include <dali/internal/render/queue/render-queue.h>
65 #include <dali/internal/render/common/performance-monitor.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/renderers/render-material.h>
68 #include <dali/internal/render/shaders/shader.h>
70 #ifdef DYNAMICS_SUPPORT
71 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
72 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.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 CompleteNotificationInterface& 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 messageQueue( renderController, sceneGraphBuffers ),
182 dynamicsChanged( false ),
183 keepRenderingSeconds( 0.0f ),
184 animationFinishedDuringUpdate( false ),
185 activeConstraints( 0 ),
186 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
187 previousUpdateScene( false ),
189 renderSortingHelper(),
190 renderTaskWaiting( false )
192 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
197 // Disconnect render tasks from nodes, before destroying the nodes
198 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
199 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
201 (*iter)->SetSourceNode( NULL );
203 // ..repeat for system level RenderTasks
204 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
205 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
207 (*iter)->SetSourceNode( NULL );
210 // UpdateManager owns the Nodes
211 DestroyNodeSet( activeDisconnectedNodes );
212 DestroyNodeSet( connectedNodes );
213 DestroyNodeSet( disconnectedNodes );
215 // If there is root, reset it, otherwise do nothing as rendering was never started
224 if( systemLevelRoot )
226 systemLevelRoot->OnDestroy();
228 delete systemLevelRoot;
229 systemLevelRoot = NULL;
232 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
233 delete sceneController;
236 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
237 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
238 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
239 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
240 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
241 ResourceManager& resourceManager; ///< resource manager
242 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
243 RenderController& renderController; ///< render controller
244 SceneControllerImpl* sceneController; ///< scene controller
245 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
246 RenderQueue& renderQueue; ///< Used to queue messages for the next render
247 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
248 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
249 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
251 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
253 RenderTaskList taskList; ///< The list of scene graph render-tasks
254 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
256 Layer* root; ///< The root node (root is a layer)
257 Layer* systemLevelRoot; ///< A separate root-node for system-level content
258 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
259 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
260 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
262 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
263 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
265 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
267 AnimationContainer animations; ///< A container of owned animations
268 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
270 ShaderContainer shaders; ///< A container of owned shaders
271 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
272 MaterialContainer materials; ///< A container of owned materials
274 MessageQueue messageQueue; ///< The messages queued from the event-thread
276 #ifdef DYNAMICS_SUPPORT
277 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
279 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
281 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
282 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
284 unsigned int activeConstraints; ///< number of active constraints from previous frame
285 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
286 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
288 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
289 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
291 GestureContainer gestures; ///< A container of owned gesture detectors
292 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
295 UpdateManager::UpdateManager( NotificationManager& notificationManager,
296 GlSyncAbstraction& glSyncAbstraction,
297 CompleteNotificationInterface& animationFinishedNotifier,
298 PropertyNotifier& propertyNotifier,
299 ResourceManager& resourceManager,
300 DiscardQueue& discardQueue,
301 RenderController& controller,
302 RenderManager& renderManager,
303 RenderQueue& renderQueue,
304 TextureCache& textureCache,
305 TouchResampler& touchResampler )
308 mImpl = new Impl( notificationManager,
310 animationFinishedNotifier,
319 mSceneGraphBuffers );
321 textureCache.SetBufferIndices( &mSceneGraphBuffers );
324 UpdateManager::~UpdateManager()
329 EventToUpdate& UpdateManager::GetEventToUpdate()
331 return mImpl->messageQueue;
334 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
336 DALI_ASSERT_DEBUG( layer->IsLayer() );
337 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
341 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
346 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
347 mImpl->systemLevelRoot = layer;
350 layer->SetRoot(true);
353 void UpdateManager::AddNode( Node* node )
355 DALI_ASSERT_ALWAYS( NULL != node );
356 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
358 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
361 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
363 DALI_ASSERT_ALWAYS( NULL != parent );
364 DALI_ASSERT_ALWAYS( NULL != node );
365 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
367 // Move from active/disconnectedNodes to connectedNodes
368 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
371 removed = mImpl->disconnectedNodes.erase( node );
372 DALI_ASSERT_ALWAYS( removed );
374 mImpl->connectedNodes.insert( node );
376 node->SetActive( true );
378 parent->ConnectChild( node, index );
381 void UpdateManager::DisconnectNode( Node* node )
383 Node* parent = node->GetParent();
384 DALI_ASSERT_ALWAYS( NULL != parent );
385 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
387 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
388 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
391 void UpdateManager::SetNodeActive( Node* node )
393 DALI_ASSERT_ALWAYS( NULL != node );
394 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
396 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
397 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
398 DALI_ASSERT_ALWAYS( removed );
399 mImpl->activeDisconnectedNodes.insert( node );
401 node->SetActive( true );
404 void UpdateManager::DestroyNode( Node* node )
406 DALI_ASSERT_ALWAYS( NULL != node );
407 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
409 // Transfer ownership from new/disconnectedNodes to the discard queue
410 // This keeps the nodes alive, until the render-thread has finished with them
411 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
414 removed = mImpl->disconnectedNodes.erase( node );
415 DALI_ASSERT_ALWAYS( removed );
417 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
419 // Notify the Node about impending destruction
423 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
425 DALI_ASSERT_DEBUG( node != NULL );
426 DALI_ASSERT_DEBUG( attachment != NULL );
428 // attach node to attachment first so that parent is known by the time attachment is connected
429 node->Attach( *attachment ); // node takes ownership
430 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
433 void UpdateManager::AddObject( PropertyOwner* object )
435 DALI_ASSERT_DEBUG( NULL != object );
437 mImpl->customObjects.PushBack( object );
440 void UpdateManager::RemoveObject( PropertyOwner* object )
442 DALI_ASSERT_DEBUG( NULL != object );
444 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
446 // Find the object and destroy it
447 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
449 PropertyOwner* current = *iter;
450 if ( current == object )
452 customObjects.Erase( iter );
457 // Should not reach here
458 DALI_ASSERT_DEBUG(false);
461 void UpdateManager::AddAnimation( Animation* animation )
463 mImpl->animations.PushBack( animation );
466 void UpdateManager::StopAnimation( Animation* animation )
468 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
470 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
472 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
475 void UpdateManager::RemoveAnimation( Animation* animation )
477 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
479 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
481 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
484 bool UpdateManager::IsAnimationRunning() const
486 bool isRunning(false);
487 AnimationContainer& animations = mImpl->animations;
489 // Find any animation that isn't stopped or paused
491 const AnimationIter endIter = animations.End();
492 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
494 const Animation::State state = (*iter)->GetState();
496 if (state != Animation::Stopped &&
497 state != Animation::Paused)
506 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
508 mImpl->propertyNotifications.PushBack( propertyNotification );
511 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
513 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
514 PropertyNotificationIter iter = propertyNotifications.Begin();
516 while ( iter != propertyNotifications.End() )
518 if( *iter == propertyNotification )
520 propertyNotifications.Erase(iter);
527 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
529 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
530 propertyNotification->SetNotifyMode( notifyMode );
533 void UpdateManager::AddShader( Shader* shader )
535 DALI_ASSERT_DEBUG( NULL != shader );
537 if( mImpl->shaders.Count() == 0 )
539 // the first added shader becomes our default shader
540 // Construct message in the render queue memory; note that delete should not be called on the return value
541 typedef MessageValue1< RenderManager, Shader* > DerivedType;
543 // Reserve some memory inside the render queue
544 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
546 // Construct message in the render queue memory; note that delete should not be called on the return value
547 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
550 mImpl->shaders.PushBack( shader );
552 // Allows the shader to dispatch texture requests to the cache and "save shader"
553 // requests to the resource manager from the render thread.
554 shader->Initialize( mImpl->renderManager, mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
557 void UpdateManager::RemoveShader(Shader* shader)
559 DALI_ASSERT_DEBUG(shader != NULL);
561 ShaderContainer& shaders = mImpl->shaders;
563 // Find the shader and destroy it
564 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
566 Shader& current = **iter;
567 if ( ¤t == shader )
569 // Transfer ownership to the discard queue
570 // This keeps the shader alive, until the render-thread has finished with it
571 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
576 // Should not reach here
577 DALI_ASSERT_DEBUG(false);
580 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
582 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
584 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
586 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
587 shaderData->SetHashValue( shaderHash );
591 // This is done in the render thread, to allow GL program compilation
592 // Will trigger a NotifySaveRequest back to updateManager to forward onto ResourceClient
593 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, Context*, bool> DerivedType;
595 // Reserve some memory inside the render queue
596 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
598 // Construct message in the render queue memory; note that delete should not be called on the return value
599 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, &(mImpl->renderManager.GetContext()), modifiesGeometry );
603 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
605 mImpl->animatableMeshes.PushBack(animatableMesh);
608 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
610 DALI_ASSERT_DEBUG(animatableMesh != NULL);
612 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
614 // Find the animatableMesh and destroy it
615 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
617 AnimatableMesh& current = **iter;
618 if ( ¤t == animatableMesh )
620 animatableMeshes.Erase( iter );
626 void UpdateManager::AddMaterial( Material* material )
628 DALI_ASSERT_DEBUG( NULL != material );
630 mImpl->materials.PushBack( material );
631 RenderMaterial* renderMaterial = new RenderMaterial();
633 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
635 // Reserve some memory inside the render queue
636 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
638 // Construct message in the render queue memory; note that delete should not be called on the return value
639 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
641 material->SetRenderMaterial( renderMaterial );
642 material->OnStageConnection( *mImpl->sceneController );
645 void UpdateManager::RemoveMaterial( Material* theMaterial )
647 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
649 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
651 const Material* aMaterial = *iter;
653 if( aMaterial == theMaterial )
655 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
657 // Reserve some memory inside the render queue
658 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
660 // Construct message in the render queue memory; note that delete should not be called on the return value
661 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
663 mImpl->materials.Erase( iter );
669 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
673 // copy the list, this is only likely to happen once in application life cycle
674 return &(mImpl->taskList);
678 // copy the list, this is only likely to happen once in application life cycle
679 return &(mImpl->systemLevelTaskList);
683 void UpdateManager::AddGesture( PanGesture* gesture )
685 DALI_ASSERT_DEBUG( NULL != gesture );
687 mImpl->gestures.PushBack( gesture );
690 void UpdateManager::RemoveGesture( PanGesture* gesture )
692 DALI_ASSERT_DEBUG( gesture != NULL );
694 GestureContainer& gestures = mImpl->gestures;
696 // Find the gesture and destroy it
697 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
699 PanGesture& current = **iter;
700 if ( ¤t == gesture )
702 mImpl->gestures.Erase( iter );
706 // Should not reach here
707 DALI_ASSERT_DEBUG(false);
710 void UpdateManager::ResetNodeProperty( Node& node )
712 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
715 void UpdateManager::ResetProperties()
717 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
719 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
720 mImpl->animationFinishedDuringUpdate = false;
722 // Animated properties have to be reset to their original value each frame
724 // Reset node properties
727 ResetNodeProperty( *mImpl->root );
730 if ( mImpl->systemLevelRoot )
732 ResetNodeProperty( *mImpl->systemLevelRoot );
735 // Reset the Connected Nodes
736 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
737 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
739 ResetNodeProperty( **iter );
742 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
743 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
746 node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
747 node->SetActive( false );
749 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
750 mImpl->activeDisconnectedNodes.erase( iter );
751 mImpl->disconnectedNodes.insert( node );
754 // Reset system-level render-task list properties to base values
755 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
757 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
759 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
762 // Reset render-task list properties to base values.
763 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
765 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
767 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
770 // Reset custom object properties to base values
771 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
773 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
776 // Reset animatable shader properties to base values
777 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
779 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
782 // Reset animatable mesh properties to base values
783 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
785 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
788 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
791 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
793 bool gestureUpdated( false );
795 // constrain gestures... (in construction order)
796 GestureContainer& gestures = mImpl->gestures;
798 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
800 PanGesture& gesture = **iter;
801 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
802 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
805 return gestureUpdated;
808 void UpdateManager::Animate( float elapsedSeconds )
810 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
812 AnimationContainer &animations = mImpl->animations;
813 AnimationIter iter = animations.Begin();
814 while ( iter != animations.End() )
816 Animation* animation = *iter;
817 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
819 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
821 // Remove animations that had been destroyed but were still waiting for an update
822 if (animation->GetState() == Animation::Destroyed)
824 iter = animations.Erase(iter);
832 if ( mImpl->animationFinishedDuringUpdate )
834 // The application should be notified by NotificationManager, in another thread
835 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
838 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
841 void UpdateManager::ApplyConstraints()
843 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
845 mImpl->activeConstraints = 0;
847 // constrain custom objects... (in construction order)
848 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
850 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
851 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
853 PropertyOwner& object = **iter;
854 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
857 // constrain nodes... (in Depth First traversal order)
860 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
863 if ( mImpl->systemLevelRoot )
865 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
868 // constrain other property-owners after nodes as they are more likely to depend on a node's
869 // current frame property than vice versa. They tend to be final constraints (no further
870 // constraints depend on their properties)
871 // e.g. ShaderEffect uniform a function of Actor's position.
872 // Mesh vertex a function of Actor's position or world position.
874 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
875 // they can be all processed in a super-list of property-owners.
877 // Constrain system-level render-tasks
878 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
880 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
882 RenderTask& task = **iter;
883 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
886 // Constrain render-tasks
887 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
889 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
891 RenderTask& task = **iter;
892 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
895 // constrain meshes (in construction order)
896 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
897 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
899 AnimatableMesh& mesh = **iter;
900 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
903 // constrain shaders... (in construction order)
904 ShaderContainer& shaders = mImpl->shaders;
906 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
908 Shader& shader = **iter;
909 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
912 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
915 void UpdateManager::ProcessPropertyNotifications()
917 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
918 PropertyNotificationIter iter = notifications.Begin();
920 while ( iter != notifications.End() )
922 PropertyNotification* notification = *iter;
924 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
928 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
934 void UpdateManager::UpdateNodes()
936 mImpl->nodeDirtyFlags = NothingFlag;
943 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
945 // Prepare resources, update shaders, update attachments, for each node
946 // And add the renderers to the sorted layers. Start from root, which is also a layer
947 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
948 mSceneGraphBuffers.GetUpdateBufferIndex(),
949 mImpl->resourceManager,
950 mImpl->renderQueue );
952 if ( mImpl->systemLevelRoot )
954 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
955 mSceneGraphBuffers.GetUpdateBufferIndex(),
956 mImpl->resourceManager,
957 mImpl->renderQueue );
960 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
963 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
965 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
967 AnimatableMesh& current = **iter;
968 current.UpdateMesh( updateBufferIndex );
972 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
974 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
976 Material* material = *iter;
977 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
981 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
983 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
985 Material* material = *iter;
986 material->PrepareRender( updateBufferIndex );
990 unsigned int UpdateManager::Update( float elapsedSeconds,
991 unsigned int lastVSyncTimeMilliseconds,
992 unsigned int nextVSyncTimeMilliseconds )
994 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
995 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
996 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
998 // Measure the time spent in UpdateManager::Update
999 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
1001 // Update the frame time delta on the render thread.
1002 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1004 // 1) Clear nodes/resources which were previously discarded
1005 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1007 // 2) Grab any loaded resources
1008 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1010 // 3) Process Touches & Gestures
1011 mImpl->touchResampler.Update();
1012 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1014 const bool updateScene = // The scene-graph requires an update if..
1015 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1016 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1017 IsAnimationRunning() || // ..at least one animation is running OR
1018 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1019 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
1020 resourceChanged || // ..one or more resources were updated/changed OR
1021 gestureUpdated; // ..a gesture property was updated
1023 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1024 // values if the scene was updated in the previous frame.
1025 if( updateScene || mImpl->previousUpdateScene )
1027 // 4) Reset properties from the previous update
1031 // 5) Process the queued scene messages
1032 mImpl->messageQueue.ProcessMessages();
1034 // 6) Post Process Ids of resources updated by renderer
1035 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1037 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1038 // renderer lists if the scene was updated in the previous frame.
1039 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1040 if( updateScene || mImpl->previousUpdateScene )
1043 Animate( elapsedSeconds );
1045 // 8) Apply Constraints
1048 #ifdef DYNAMICS_SUPPORT
1049 // 9) Update dynamics simulation
1050 mImpl->dynamicsChanged = false;
1051 if( mImpl->dynamicsWorld )
1053 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1057 // 10) Check Property Notifications
1058 ProcessPropertyNotifications();
1060 // 11) Clear the lists of renderable-attachments from the previous update
1061 ClearRenderables( mImpl->sortedLayers );
1062 ClearRenderables( mImpl->systemLevelSortedLayers );
1064 // 12) Update animated meshes
1065 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1067 // 13) Update materials. Prepares image resources
1068 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1070 // 14) Update node hierarchy and perform sorting / culling.
1071 // This will populate each Layer with a list of renderers which are ready.
1074 // 15) Prepare for the next render
1075 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1076 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1077 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1078 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1079 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1081 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1083 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1084 // reset the update buffer index and make sure there is enough room in the instruction container
1085 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1086 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1088 if ( NULL != mImpl->root )
1090 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1091 mImpl->completeStatusManager,
1094 mImpl->sortedLayers,
1095 mImpl->renderSortingHelper,
1096 mImpl->renderInstructions );
1098 // Process the system-level RenderTasks last
1099 if ( NULL != mImpl->systemLevelRoot )
1101 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1102 mImpl->completeStatusManager,
1103 mImpl->systemLevelTaskList,
1104 *mImpl->systemLevelRoot,
1105 mImpl->systemLevelSortedLayers,
1106 mImpl->renderSortingHelper,
1107 mImpl->renderInstructions );
1112 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1113 bool doRenderOnceNotify = false;
1114 mImpl->renderTaskWaiting = false;
1115 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1116 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1117 endIter != iter; ++iter )
1119 RenderTask& renderTask(*(*iter));
1121 renderTask.UpdateState();
1123 if( renderTask.IsWaitingToRender() &&
1124 renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1126 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1129 if( renderTask.HasRendered() )
1131 doRenderOnceNotify = true;
1135 if( doRenderOnceNotify )
1137 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1138 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1141 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1143 // Macro is undefined in release build.
1144 SNAPSHOT_NODE_LOGGING;
1146 // A ResetProperties() may be required in the next frame
1147 mImpl->previousUpdateScene = updateScene;
1149 // Check whether further updates are required
1150 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1152 #ifdef PERFORMANCE_MONITOR_ENABLED
1153 // Always keep rendering when measuring FPS
1154 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1157 // The update has finished; swap the double-buffering indices
1158 mSceneGraphBuffers.Swap();
1160 // tell the update manager that we're done so the queue can be given to event thread
1161 mImpl->notificationManager.UpdateCompleted();
1163 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1165 return keepUpdating;
1168 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1170 // Update the duration set via Stage::KeepRendering()
1171 if ( mImpl->keepRenderingSeconds > 0.0f )
1173 mImpl->keepRenderingSeconds -= elapsedSeconds;
1176 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1178 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1179 // Keep updating until no messages are received and no animations are running.
1180 // If an animation has just finished, update at least once more for Discard end-actions.
1181 // No need to check for renderQueue as there is always a render after update and if that
1182 // render needs another update it will tell the adaptor to call update again
1184 if ( mImpl->keepRenderingSeconds > 0.0f )
1186 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1189 if ( !mImpl->messageQueue.WasEmpty() )
1191 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1194 if ( IsAnimationRunning() ||
1195 mImpl->animationFinishedDuringUpdate )
1197 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1200 if ( mImpl->dynamicsChanged )
1202 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1205 if ( mImpl->renderTaskWaiting )
1207 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1210 return keepUpdatingRequest;
1213 void UpdateManager::SetBackgroundColor( const Vector4& color )
1215 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1217 // Reserve some memory inside the render queue
1218 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1220 // Construct message in the render queue memory; note that delete should not be called on the return value
1221 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1224 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1226 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1228 // Reserve some memory inside the render queue
1229 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1231 // Construct message in the render queue memory; note that delete should not be called on the return value
1232 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1235 void UpdateManager::KeepRendering( float durationSeconds )
1237 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1240 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1244 // just copy the vector of pointers
1245 mImpl->sortedLayers = layers;
1249 mImpl->systemLevelSortedLayers = layers;
1253 #ifdef DYNAMICS_SUPPORT
1255 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1257 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1258 mImpl->dynamicsWorld = dynamicsWorld;
1261 void UpdateManager::TerminateDynamicsWorld()
1263 mImpl->dynamicsWorld.Reset();
1266 #endif // DYNAMICS_SUPPORT
1268 } // namespace SceneGraph
1270 } // namespace Internal