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 const int DEFAULT_CAMERA_INDEX = -1;
115 void DestroyNodeSet( std::set<Node*>& nodeSet )
117 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
121 // Call Node::OnDestroy as each node is destroyed
131 typedef OwnerContainer< Shader* > ShaderContainer;
132 typedef ShaderContainer::Iterator ShaderIter;
133 typedef ShaderContainer::ConstIterator ShaderConstIter;
135 typedef AnimatableMeshContainer::Iterator AnimatableMeshIter;
136 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
137 typedef MaterialContainer::Iterator MaterialIter;
139 typedef OwnerContainer<PanGesture*> GestureContainer;
140 typedef GestureContainer::Iterator GestureIter;
141 typedef GestureContainer::ConstIterator GestureConstIter;
145 * Structure to contain UpdateManager internal data
147 struct UpdateManager::Impl
149 Impl( NotificationManager& notificationManager,
150 GlSyncAbstraction& glSyncAbstraction,
151 CompleteNotificationInterface& animationFinishedNotifier,
152 PropertyNotifier& propertyNotifier,
153 ResourceManager& resourceManager,
154 DiscardQueue& discardQueue,
155 RenderController& renderController,
156 RenderManager& renderManager,
157 RenderQueue& renderQueue,
158 TextureCache& textureCache,
159 TouchResampler& touchResampler,
160 SceneGraphBuffers& sceneGraphBuffers )
162 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
163 notificationManager( notificationManager ),
164 animationFinishedNotifier( animationFinishedNotifier ),
165 propertyNotifier( propertyNotifier ),
166 resourceManager( resourceManager ),
167 discardQueue( discardQueue ),
168 renderController( renderController ),
169 sceneController( NULL ),
170 renderManager( renderManager ),
171 renderQueue( renderQueue ),
172 renderInstructions( renderManager.GetRenderInstructionContainer() ),
173 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
174 touchResampler( touchResampler ),
175 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
176 taskList ( completeStatusManager ),
177 systemLevelTaskList ( completeStatusManager ),
179 systemLevelRoot( NULL ),
180 messageQueue( renderController, sceneGraphBuffers ),
181 dynamicsChanged( false ),
182 keepRenderingSeconds( 0.0f ),
183 animationFinishedDuringUpdate( false ),
184 activeConstraints( 0 ),
185 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
186 previousUpdateScene( false ),
188 renderSortingHelper(),
189 renderTaskWaiting( false )
191 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
196 // Disconnect render tasks from nodes, before destroying the nodes
197 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
198 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
200 (*iter)->SetSourceNode( NULL );
202 // ..repeat for system level RenderTasks
203 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
204 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
206 (*iter)->SetSourceNode( NULL );
209 // UpdateManager owns the Nodes
210 DestroyNodeSet( activeDisconnectedNodes );
211 DestroyNodeSet( connectedNodes );
212 DestroyNodeSet( disconnectedNodes );
214 // If there is root, reset it, otherwise do nothing as rendering was never started
223 if( systemLevelRoot )
225 systemLevelRoot->OnDestroy();
227 delete systemLevelRoot;
228 systemLevelRoot = NULL;
231 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
232 delete sceneController;
235 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
236 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
237 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
238 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
239 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
240 ResourceManager& resourceManager; ///< resource manager
241 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
242 RenderController& renderController; ///< render controller
243 SceneControllerImpl* sceneController; ///< scene controller
244 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
245 RenderQueue& renderQueue; ///< Used to queue messages for the next render
246 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
247 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
248 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
250 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
252 RenderTaskList taskList; ///< The list of scene graph render-tasks
253 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
255 Layer* root; ///< The root node (root is a layer)
256 Layer* systemLevelRoot; ///< A separate root-node for system-level content
257 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
258 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
259 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
261 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
262 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
264 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
266 AnimationContainer animations; ///< A container of owned animations
267 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
269 ShaderContainer shaders; ///< A container of owned shaders
270 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
271 MaterialContainer materials; ///< A container of owned materials
273 MessageQueue messageQueue; ///< The messages queued from the event-thread
275 #ifdef DYNAMICS_SUPPORT
276 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
278 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
280 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
281 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
283 unsigned int activeConstraints; ///< number of active constraints from previous frame
284 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
285 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
287 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
288 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
290 GestureContainer gestures; ///< A container of owned gesture detectors
291 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
294 UpdateManager::UpdateManager( NotificationManager& notificationManager,
295 GlSyncAbstraction& glSyncAbstraction,
296 CompleteNotificationInterface& animationFinishedNotifier,
297 PropertyNotifier& propertyNotifier,
298 ResourceManager& resourceManager,
299 DiscardQueue& discardQueue,
300 RenderController& controller,
301 RenderManager& renderManager,
302 RenderQueue& renderQueue,
303 TextureCache& textureCache,
304 TouchResampler& touchResampler )
307 mImpl = new Impl( notificationManager,
309 animationFinishedNotifier,
318 mSceneGraphBuffers );
320 textureCache.SetBufferIndices( &mSceneGraphBuffers );
323 UpdateManager::~UpdateManager()
328 EventToUpdate& UpdateManager::GetEventToUpdate()
330 return mImpl->messageQueue;
333 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
335 DALI_ASSERT_DEBUG( layer->IsLayer() );
336 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
340 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
345 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
346 mImpl->systemLevelRoot = layer;
349 layer->SetRoot(true);
352 void UpdateManager::AddNode( Node* node )
354 DALI_ASSERT_ALWAYS( NULL != node );
355 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
357 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
360 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
362 DALI_ASSERT_ALWAYS( NULL != parent );
363 DALI_ASSERT_ALWAYS( NULL != node );
364 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
366 // Move from active/disconnectedNodes to connectedNodes
367 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
370 removed = mImpl->disconnectedNodes.erase( node );
371 DALI_ASSERT_ALWAYS( removed );
373 mImpl->connectedNodes.insert( node );
375 node->SetActive( true );
377 parent->ConnectChild( node, index );
380 void UpdateManager::DisconnectNode( Node* node )
382 Node* parent = node->GetParent();
383 DALI_ASSERT_ALWAYS( NULL != parent );
384 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
386 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
387 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
390 void UpdateManager::SetNodeActive( Node* node )
392 DALI_ASSERT_ALWAYS( NULL != node );
393 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
395 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
396 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
397 DALI_ASSERT_ALWAYS( removed );
398 mImpl->activeDisconnectedNodes.insert( node );
400 node->SetActive( true );
403 void UpdateManager::DestroyNode( Node* node )
405 DALI_ASSERT_ALWAYS( NULL != node );
406 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
408 // Transfer ownership from new/disconnectedNodes to the discard queue
409 // This keeps the nodes alive, until the render-thread has finished with them
410 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
413 removed = mImpl->disconnectedNodes.erase( node );
414 DALI_ASSERT_ALWAYS( removed );
416 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
418 // Notify the Node about impending destruction
422 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
424 DALI_ASSERT_DEBUG( node != NULL );
425 DALI_ASSERT_DEBUG( attachment != NULL );
427 // attach node to attachment first so that parent is known by the time attachment is connected
428 node->Attach( *attachment ); // node takes ownership
429 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
432 void UpdateManager::AddObject( PropertyOwner* object )
434 DALI_ASSERT_DEBUG( NULL != object );
436 mImpl->customObjects.PushBack( object );
439 void UpdateManager::RemoveObject( PropertyOwner* object )
441 DALI_ASSERT_DEBUG( NULL != object );
443 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
445 // Find the object and destroy it
446 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
448 PropertyOwner* current = *iter;
449 if ( current == object )
451 customObjects.Erase( iter );
456 // Should not reach here
457 DALI_ASSERT_DEBUG(false);
460 void UpdateManager::AddAnimation( Animation* animation )
462 mImpl->animations.PushBack( animation );
465 void UpdateManager::StopAnimation( Animation* animation )
467 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
469 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
471 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
474 void UpdateManager::RemoveAnimation( Animation* animation )
476 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
478 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
480 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
483 bool UpdateManager::IsAnimationRunning() const
485 bool isRunning(false);
486 AnimationContainer& animations = mImpl->animations;
488 // Find any animation that isn't stopped or paused
490 const AnimationIter endIter = animations.End();
491 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
493 const Animation::State state = (*iter)->GetState();
495 if (state != Animation::Stopped &&
496 state != Animation::Paused)
505 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
507 mImpl->propertyNotifications.PushBack( propertyNotification );
510 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
512 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
513 PropertyNotificationIter iter = propertyNotifications.Begin();
515 while ( iter != propertyNotifications.End() )
517 if( *iter == propertyNotification )
519 propertyNotifications.Erase(iter);
526 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
528 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
529 propertyNotification->SetNotifyMode( notifyMode );
532 void UpdateManager::AddShader( Shader* shader )
534 DALI_ASSERT_DEBUG( NULL != shader );
536 if( mImpl->shaders.Count() == 0 )
538 // the first added shader becomes our default shader
539 // Construct message in the render queue memory; note that delete should not be called on the return value
540 typedef MessageValue1< RenderManager, Shader* > DerivedType;
542 // Reserve some memory inside the render queue
543 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
545 // Construct message in the render queue memory; note that delete should not be called on the return value
546 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
549 mImpl->shaders.PushBack( shader );
551 // Allows the shader to dispatch texture requests to the cache
552 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
555 void UpdateManager::RemoveShader(Shader* shader)
557 DALI_ASSERT_DEBUG(shader != NULL);
559 ShaderContainer& shaders = mImpl->shaders;
561 // Find the shader and destroy it
562 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
564 Shader& current = **iter;
565 if ( ¤t == shader )
567 // Transfer ownership to the discard queue
568 // This keeps the shader alive, until the render-thread has finished with it
569 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
574 // Should not reach here
575 DALI_ASSERT_DEBUG(false);
578 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
580 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
582 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
584 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
587 shaderData->SetHashValue( shaderHash );
588 shaderData->SetResourceId( resourceId );
590 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
592 // Reserve some memory inside the render queue
593 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
595 // Construct message in the render queue memory; note that delete should not be called on the return value
596 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
600 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
602 mImpl->animatableMeshes.PushBack(animatableMesh);
605 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
607 DALI_ASSERT_DEBUG(animatableMesh != NULL);
609 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
611 // Find the animatableMesh and destroy it
612 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
614 AnimatableMesh& current = **iter;
615 if ( ¤t == animatableMesh )
617 animatableMeshes.Erase( iter );
623 void UpdateManager::AddMaterial( Material* material )
625 DALI_ASSERT_DEBUG( NULL != material );
627 mImpl->materials.PushBack( material );
628 RenderMaterial* renderMaterial = new RenderMaterial();
630 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
632 // Reserve some memory inside the render queue
633 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
635 // Construct message in the render queue memory; note that delete should not be called on the return value
636 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
638 material->SetRenderMaterial( renderMaterial );
639 material->OnStageConnection( *mImpl->sceneController );
642 void UpdateManager::RemoveMaterial( Material* theMaterial )
644 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
646 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
648 const Material* aMaterial = *iter;
650 if( aMaterial == theMaterial )
652 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
654 // Reserve some memory inside the render queue
655 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
657 // Construct message in the render queue memory; note that delete should not be called on the return value
658 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
660 mImpl->materials.Erase( iter );
666 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
670 // copy the list, this is only likely to happen once in application life cycle
671 return &(mImpl->taskList);
675 // copy the list, this is only likely to happen once in application life cycle
676 return &(mImpl->systemLevelTaskList);
680 void UpdateManager::AddGesture( PanGesture* gesture )
682 DALI_ASSERT_DEBUG( NULL != gesture );
684 mImpl->gestures.PushBack( gesture );
687 void UpdateManager::RemoveGesture( PanGesture* gesture )
689 DALI_ASSERT_DEBUG( gesture != NULL );
691 GestureContainer& gestures = mImpl->gestures;
693 // Find the gesture and destroy it
694 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
696 PanGesture& current = **iter;
697 if ( ¤t == gesture )
699 mImpl->gestures.Erase( iter );
703 // Should not reach here
704 DALI_ASSERT_DEBUG(false);
707 void UpdateManager::ResetNodeProperty( Node& node )
709 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
712 void UpdateManager::ResetProperties()
714 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
716 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
717 mImpl->animationFinishedDuringUpdate = false;
719 // Animated properties have to be reset to their original value each frame
721 // Reset node properties
724 ResetNodeProperty( *mImpl->root );
727 if ( mImpl->systemLevelRoot )
729 ResetNodeProperty( *mImpl->systemLevelRoot );
732 // Reset the Connected Nodes
733 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
734 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
736 ResetNodeProperty( **iter );
739 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
740 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
743 node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
744 node->SetActive( false );
746 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
747 mImpl->activeDisconnectedNodes.erase( iter );
748 mImpl->disconnectedNodes.insert( node );
751 // Reset system-level render-task list properties to base values
752 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
754 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
756 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
759 // Reset render-task list properties to base values.
760 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
762 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
764 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
767 // Reset custom object properties to base values
768 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
770 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
773 // Reset animatable shader properties to base values
774 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
776 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
779 // Reset animatable mesh properties to base values
780 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
782 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
785 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
788 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
790 bool gestureUpdated( false );
792 // constrain gestures... (in construction order)
793 GestureContainer& gestures = mImpl->gestures;
795 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
797 PanGesture& gesture = **iter;
798 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
799 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
802 return gestureUpdated;
805 void UpdateManager::Animate( float elapsedSeconds )
807 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
809 AnimationContainer &animations = mImpl->animations;
810 AnimationIter iter = animations.Begin();
811 while ( iter != animations.End() )
813 Animation* animation = *iter;
814 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
816 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
818 // Remove animations that had been destroyed but were still waiting for an update
819 if (animation->GetState() == Animation::Destroyed)
821 iter = animations.Erase(iter);
829 if ( mImpl->animationFinishedDuringUpdate )
831 // The application should be notified by NotificationManager, in another thread
832 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
835 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
838 void UpdateManager::ApplyConstraints()
840 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
842 mImpl->activeConstraints = 0;
844 // constrain custom objects... (in construction order)
845 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
847 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
848 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
850 PropertyOwner& object = **iter;
851 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
854 // constrain nodes... (in Depth First traversal order)
857 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
860 if ( mImpl->systemLevelRoot )
862 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
865 // constrain other property-owners after nodes as they are more likely to depend on a node's
866 // current frame property than vice versa. They tend to be final constraints (no further
867 // constraints depend on their properties)
868 // e.g. ShaderEffect uniform a function of Actor's position.
869 // Mesh vertex a function of Actor's position or world position.
871 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
872 // they can be all processed in a super-list of property-owners.
874 // Constrain system-level render-tasks
875 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
877 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
879 RenderTask& task = **iter;
880 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
883 // Constrain render-tasks
884 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
886 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
888 RenderTask& task = **iter;
889 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
892 // constrain meshes (in construction order)
893 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
894 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
896 AnimatableMesh& mesh = **iter;
897 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
900 // constrain shaders... (in construction order)
901 ShaderContainer& shaders = mImpl->shaders;
903 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
905 Shader& shader = **iter;
906 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
909 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
912 void UpdateManager::ProcessPropertyNotifications()
914 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
915 PropertyNotificationIter iter = notifications.Begin();
917 while ( iter != notifications.End() )
919 PropertyNotification* notification = *iter;
921 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
925 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
931 void UpdateManager::UpdateNodes()
933 mImpl->nodeDirtyFlags = NothingFlag;
940 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
942 // Prepare resources, update shaders, update attachments, for each node
943 // And add the renderers to the sorted layers. Start from root, which is also a layer
944 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
945 mSceneGraphBuffers.GetUpdateBufferIndex(),
946 mImpl->resourceManager,
947 mImpl->renderQueue );
949 if ( mImpl->systemLevelRoot )
951 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
952 mSceneGraphBuffers.GetUpdateBufferIndex(),
953 mImpl->resourceManager,
954 mImpl->renderQueue );
957 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
960 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
962 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
964 AnimatableMesh& current = **iter;
965 current.UpdateMesh( updateBufferIndex );
969 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
971 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
973 Material* material = *iter;
974 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
978 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
980 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
982 Material* material = *iter;
983 material->PrepareRender( updateBufferIndex );
987 unsigned int UpdateManager::Update( float elapsedSeconds,
988 unsigned int lastVSyncTimeMilliseconds,
989 unsigned int nextVSyncTimeMilliseconds )
991 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
992 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
993 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
995 // Measure the time spent in UpdateManager::Update
996 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
998 // Update the frame time delta on the render thread.
999 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1001 // 1) Clear nodes/resources which were previously discarded
1002 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1004 // 2) Grab any loaded resources
1005 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1007 // 3) Process Touches & Gestures
1008 mImpl->touchResampler.Update();
1009 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1011 const bool updateScene = // The scene-graph requires an update if..
1012 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1013 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1014 IsAnimationRunning() || // ..at least one animation is running OR
1015 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1016 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
1017 resourceChanged || // ..one or more resources were updated/changed OR
1018 gestureUpdated; // ..a gesture property was updated
1020 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1021 // values if the scene was updated in the previous frame.
1022 if( updateScene || mImpl->previousUpdateScene )
1024 // 4) Reset properties from the previous update
1028 // 5) Process the queued scene messages
1029 mImpl->messageQueue.ProcessMessages();
1031 // 6) Post Process Ids of resources updated by renderer
1032 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1034 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1035 // renderer lists if the scene was updated in the previous frame.
1036 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1037 if( updateScene || mImpl->previousUpdateScene )
1040 Animate( elapsedSeconds );
1042 // 8) Apply Constraints
1045 #ifdef DYNAMICS_SUPPORT
1046 // 9) Update dynamics simulation
1047 mImpl->dynamicsChanged = false;
1048 if( mImpl->dynamicsWorld )
1050 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1054 // 10) Check Property Notifications
1055 ProcessPropertyNotifications();
1057 // 11) Clear the lists of renderable-attachments from the previous update
1058 ClearRenderables( mImpl->sortedLayers );
1059 ClearRenderables( mImpl->systemLevelSortedLayers );
1061 // 12) Update animated meshes
1062 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1064 // 13) Update materials. Prepares image resources
1065 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1067 // 14) Update node hierarchy and perform sorting / culling.
1068 // This will populate each Layer with a list of renderers which are ready.
1071 // 15) Prepare for the next render
1072 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1073 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1074 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1075 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1076 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1078 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1080 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1081 // reset the update buffer index and make sure there is enough room in the instruction container
1082 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1083 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1085 if ( NULL != mImpl->root )
1087 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1088 mImpl->completeStatusManager,
1091 mImpl->sortedLayers,
1092 mImpl->renderSortingHelper,
1093 mImpl->renderInstructions );
1095 // Process the system-level RenderTasks last
1096 if ( NULL != mImpl->systemLevelRoot )
1098 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1099 mImpl->completeStatusManager,
1100 mImpl->systemLevelTaskList,
1101 *mImpl->systemLevelRoot,
1102 mImpl->systemLevelSortedLayers,
1103 mImpl->renderSortingHelper,
1104 mImpl->renderInstructions );
1109 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1110 bool doRenderOnceNotify = false;
1111 mImpl->renderTaskWaiting = false;
1112 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1113 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1114 endIter != iter; ++iter )
1116 RenderTask& renderTask(*(*iter));
1118 renderTask.UpdateState();
1120 if( renderTask.IsWaitingToRender() &&
1121 renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1123 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1126 if( renderTask.HasRendered() )
1128 doRenderOnceNotify = true;
1132 if( doRenderOnceNotify )
1134 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1135 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1138 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1140 // Macro is undefined in release build.
1141 SNAPSHOT_NODE_LOGGING;
1143 // A ResetProperties() may be required in the next frame
1144 mImpl->previousUpdateScene = updateScene;
1146 // Check whether further updates are required
1147 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1149 #ifdef PERFORMANCE_MONITOR_ENABLED
1150 // Always keep rendering when measuring FPS
1151 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1154 // The update has finished; swap the double-buffering indices
1155 mSceneGraphBuffers.Swap();
1157 // tell the update manager that we're done so the queue can be given to event thread
1158 mImpl->notificationManager.UpdateCompleted();
1160 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1162 return keepUpdating;
1165 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1167 // Update the duration set via Stage::KeepRendering()
1168 if ( mImpl->keepRenderingSeconds > 0.0f )
1170 mImpl->keepRenderingSeconds -= elapsedSeconds;
1173 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1175 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1176 // Keep updating until no messages are received and no animations are running.
1177 // If an animation has just finished, update at least once more for Discard end-actions.
1178 // No need to check for renderQueue as there is always a render after update and if that
1179 // render needs another update it will tell the adaptor to call update again
1181 if ( mImpl->keepRenderingSeconds > 0.0f )
1183 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1186 if ( !mImpl->messageQueue.WasEmpty() )
1188 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1191 if ( IsAnimationRunning() ||
1192 mImpl->animationFinishedDuringUpdate )
1194 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1197 if ( mImpl->dynamicsChanged )
1199 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1202 if ( mImpl->renderTaskWaiting )
1204 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1207 return keepUpdatingRequest;
1210 void UpdateManager::SetBackgroundColor( const Vector4& color )
1212 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1214 // Reserve some memory inside the render queue
1215 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1217 // Construct message in the render queue memory; note that delete should not be called on the return value
1218 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1221 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1223 typedef MessageValue1< RenderManager, Rect<int> > 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::SetDefaultSurfaceRect, rect );
1232 void UpdateManager::KeepRendering( float durationSeconds )
1234 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1237 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1241 // just copy the vector of pointers
1242 mImpl->sortedLayers = layers;
1246 mImpl->systemLevelSortedLayers = layers;
1250 #ifdef DYNAMICS_SUPPORT
1252 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1254 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1255 mImpl->dynamicsWorld = dynamicsWorld;
1258 void UpdateManager::TerminateDynamicsWorld()
1260 mImpl->dynamicsWorld.Reset();
1263 #endif // DYNAMICS_SUPPORT
1265 } // namespace SceneGraph
1267 } // namespace Internal