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>
37 #include <dali/internal/event/animation/animation-finished-notifier.h>
38 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/double-buffered.h>
44 #include <dali/internal/update/manager/prepare-render-algorithms.h>
45 #include <dali/internal/update/manager/process-render-tasks.h>
46 #include <dali/internal/update/resources/resource-manager.h>
47 #include <dali/internal/update/resources/complete-status-manager.h>
48 #include <dali/internal/update/common/scene-graph-buffers.h>
49 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
50 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
51 #include <dali/internal/update/manager/sorted-layers.h>
52 #include <dali/internal/update/manager/update-algorithms.h>
53 #include <dali/internal/update/queue/update-message-queue.h>
54 #include <dali/internal/update/manager/update-manager-debug.h>
55 #include <dali/internal/update/controllers/render-message-dispatcher.h>
56 #include <dali/internal/update/controllers/scene-controller-impl.h>
57 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
58 #include <dali/internal/update/modeling/scene-graph-material.h>
59 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
60 #include <dali/internal/update/nodes/node.h>
61 #include <dali/internal/update/nodes/scene-graph-layer.h>
62 #include <dali/internal/update/touch/touch-resampler.h>
64 #include <dali/internal/render/common/render-instruction-container.h>
65 #include <dali/internal/render/common/render-manager.h>
66 #include <dali/internal/render/queue/render-queue.h>
67 #include <dali/internal/render/common/performance-monitor.h>
68 #include <dali/internal/render/gl-resources/texture-cache.h>
69 #include <dali/internal/render/renderers/render-material.h>
70 #include <dali/internal/render/shaders/shader.h>
72 #ifdef DYNAMICS_SUPPORT
73 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
74 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
77 // Un-comment to enable node tree debug logging
78 //#define NODE_TREE_LOGGING 1
80 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
81 #define SNAPSHOT_NODE_LOGGING \
82 const int FRAME_COUNT_TRIGGER = 16;\
83 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
85 if ( NULL != mImpl->root )\
87 mImpl->frameCounter = 0;\
88 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
91 mImpl->frameCounter++;
93 #define SNAPSHOT_NODE_LOGGING
96 #if defined(DEBUG_ENABLED)
97 extern Debug::Filter* gRenderTaskLogFilter;
101 using namespace Dali::Integration;
102 using Dali::Internal::Update::MessageQueue;
116 const int DEFAULT_CAMERA_INDEX = -1;
118 void DestroyNodeSet( std::set<Node*>& nodeSet )
120 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
124 // Call Node::OnDestroy as each node is destroyed
134 typedef OwnerContainer< Shader* > ShaderContainer;
135 typedef ShaderContainer::Iterator ShaderIter;
136 typedef ShaderContainer::ConstIterator ShaderConstIter;
138 typedef AnimatableMeshContainer::Iterator AnimatableMeshIter;
139 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
140 typedef MaterialContainer::Iterator MaterialIter;
142 typedef OwnerContainer<PanGesture*> GestureContainer;
143 typedef GestureContainer::Iterator GestureIter;
144 typedef GestureContainer::ConstIterator GestureConstIter;
148 * Structure to contain UpdateManager internal data
150 struct UpdateManager::Impl
152 Impl( NotificationManager& notificationManager,
153 GlSyncAbstraction& glSyncAbstraction,
154 AnimationFinishedNotifier& animationFinishedNotifier,
155 PropertyNotifier& propertyNotifier,
156 ResourceManager& resourceManager,
157 DiscardQueue& discardQueue,
158 RenderController& renderController,
159 RenderManager& renderManager,
160 RenderQueue& renderQueue,
161 TextureCache& textureCache,
162 TouchResampler& touchResampler,
163 SceneGraphBuffers& sceneGraphBuffers )
165 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
166 notificationManager( notificationManager ),
167 animationFinishedNotifier( animationFinishedNotifier ),
168 propertyNotifier( propertyNotifier ),
169 resourceManager( resourceManager ),
170 discardQueue( discardQueue ),
171 renderController( renderController ),
172 sceneController( NULL ),
173 renderManager( renderManager ),
174 renderQueue( renderQueue ),
175 renderInstructions( renderManager.GetRenderInstructionContainer() ),
176 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
177 touchResampler( touchResampler ),
178 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
179 taskList ( completeStatusManager ),
180 systemLevelTaskList ( completeStatusManager ),
182 systemLevelRoot( NULL ),
183 defaultShader( NULL ),
184 messageQueue( renderController, sceneGraphBuffers ),
185 dynamicsChanged( false ),
186 keepRenderingSeconds( 0.0f ),
187 animationFinishedDuringUpdate( false ),
188 activeConstraints( 0 ),
189 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
190 previousUpdateScene( false ),
192 renderSortingHelper(),
193 renderTaskList( NULL ),
194 renderTaskWaiting( false )
196 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
201 // Disconnect render tasks from nodes, before destroying the nodes
202 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
203 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
205 (*iter)->SetSourceNode( NULL );
207 // ..repeat for system level RenderTasks
208 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
209 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
211 (*iter)->SetSourceNode( NULL );
214 // UpdateManager owns the Nodes
215 DestroyNodeSet( activeDisconnectedNodes );
216 DestroyNodeSet( connectedNodes );
217 DestroyNodeSet( disconnectedNodes );
219 // If there is root, reset it, otherwise do nothing as rendering was never started
228 if( systemLevelRoot )
230 systemLevelRoot->OnDestroy();
232 delete systemLevelRoot;
233 systemLevelRoot = NULL;
236 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
237 delete sceneController;
240 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
241 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
242 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
243 AnimationFinishedNotifier& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
244 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
245 ResourceManager& resourceManager; ///< resource manager
246 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
247 RenderController& renderController; ///< render controller
248 SceneControllerImpl* sceneController; ///< scene controller
249 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
250 RenderQueue& renderQueue; ///< Used to queue messages for the next render
251 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
252 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
253 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
255 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
257 RenderTaskList taskList; ///< The list of scene graph render-tasks
258 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
260 Layer* root; ///< The root node (root is a layer)
261 Layer* systemLevelRoot; ///< A separate root-node for system-level content
262 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
263 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
264 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
266 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
267 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
269 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
271 AnimationContainer animations; ///< A container of owned animations
272 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
274 Shader* defaultShader; ///< The default shader; owned by ShaderContainer
275 ShaderContainer shaders; ///< A container of owned shaders
276 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
277 MaterialContainer materials; ///< A container of owned materials
279 MessageQueue messageQueue; ///< The messages queued from the event-thread
281 #ifdef DYNAMICS_SUPPORT
282 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
284 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
286 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
287 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
289 unsigned int activeConstraints; ///< number of active constraints from previous frame
290 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
291 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
293 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
294 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
296 Internal::RenderTaskList* renderTaskList; ///< Stores a pointer to the internal implementation to the render task list.
297 GestureContainer gestures; ///< A container of owned gesture detectors
298 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
301 UpdateManager::UpdateManager( NotificationManager& notificationManager,
302 GlSyncAbstraction& glSyncAbstraction,
303 AnimationFinishedNotifier& animationFinishedNotifier,
304 PropertyNotifier& propertyNotifier,
305 ResourceManager& resourceManager,
306 DiscardQueue& discardQueue,
307 RenderController& controller,
308 RenderManager& renderManager,
309 RenderQueue& renderQueue,
310 TextureCache& textureCache,
311 TouchResampler& touchResampler )
314 mImpl = new Impl( notificationManager,
316 animationFinishedNotifier,
325 mSceneGraphBuffers );
327 textureCache.SetBufferIndices( &mSceneGraphBuffers );
330 UpdateManager::~UpdateManager()
335 void UpdateManager::SetRenderTaskList( Internal::RenderTaskList* renderTaskList )
337 mImpl->renderTaskList = renderTaskList;
340 EventToUpdate& UpdateManager::GetEventToUpdate()
342 return mImpl->messageQueue;
345 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
347 DALI_ASSERT_DEBUG( layer->IsLayer() );
348 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
352 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
357 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
358 mImpl->systemLevelRoot = layer;
361 layer->SetRoot(true);
364 void UpdateManager::AddNode( Node* node )
366 DALI_ASSERT_ALWAYS( NULL != node );
367 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
369 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
372 void UpdateManager::ConnectNode( Node* parent, Node* node )
374 DALI_ASSERT_ALWAYS( NULL != parent );
375 DALI_ASSERT_ALWAYS( NULL != node );
376 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
378 // Move from active/disconnectedNodes to connectedNodes
379 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
382 removed = mImpl->disconnectedNodes.erase( node );
383 DALI_ASSERT_ALWAYS( removed );
385 mImpl->connectedNodes.insert( node );
387 node->SetActive( true );
389 parent->ConnectChild( node );
392 void UpdateManager::DisconnectNode( Node* node )
394 Node* parent = node->GetParent();
395 DALI_ASSERT_ALWAYS( NULL != parent );
396 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
398 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
399 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
402 void UpdateManager::SetNodeActive( Node* node )
404 DALI_ASSERT_ALWAYS( NULL != node );
405 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
407 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
408 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
409 DALI_ASSERT_ALWAYS( removed );
410 mImpl->activeDisconnectedNodes.insert( node );
412 node->SetActive( true );
415 void UpdateManager::DestroyNode( Node* node )
417 DALI_ASSERT_ALWAYS( NULL != node );
418 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
420 // Transfer ownership from new/disconnectedNodes to the discard queue
421 // This keeps the nodes alive, until the render-thread has finished with them
422 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
425 removed = mImpl->disconnectedNodes.erase( node );
426 DALI_ASSERT_ALWAYS( removed );
428 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
430 // Notify the Node about impending destruction
434 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
436 DALI_ASSERT_DEBUG( node != NULL );
437 DALI_ASSERT_DEBUG( attachment != NULL );
439 // attach node to attachment first so that parent is known by the time attachment is connected
440 node->Attach( *attachment ); // node takes ownership
441 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
444 void UpdateManager::AddObject( PropertyOwner* object )
446 DALI_ASSERT_DEBUG( NULL != object );
448 mImpl->customObjects.PushBack( object );
451 void UpdateManager::RemoveObject( PropertyOwner* object )
453 DALI_ASSERT_DEBUG( NULL != object );
455 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
457 // Find the object and destroy it
458 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
460 PropertyOwner* current = *iter;
461 if ( current == object )
463 customObjects.Erase( iter );
468 // Should not reach here
469 DALI_ASSERT_DEBUG(false);
472 void UpdateManager::AddAnimation( Animation* animation )
474 mImpl->animations.PushBack( animation );
477 void UpdateManager::StopAnimation( Animation* animation )
479 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
481 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
483 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
486 void UpdateManager::RemoveAnimation( Animation* animation )
488 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
490 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
492 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
495 bool UpdateManager::IsAnimationRunning() const
497 bool isRunning(false);
498 AnimationContainer& animations = mImpl->animations;
500 // Find any animation that isn't stopped or paused
502 const AnimationIter endIter = animations.End();
503 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
505 const Animation::State state = (*iter)->GetState();
507 if (state != Animation::Stopped &&
508 state != Animation::Paused)
517 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
519 mImpl->propertyNotifications.PushBack( propertyNotification );
522 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
524 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
525 PropertyNotificationIter iter = propertyNotifications.Begin();
527 while ( iter != propertyNotifications.End() )
529 if( *iter == propertyNotification )
531 propertyNotifications.Erase(iter);
538 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
540 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
541 propertyNotification->SetNotifyMode( notifyMode );
544 Shader* UpdateManager::GetDefaultShader()
546 return mImpl->defaultShader;
549 void UpdateManager::AddShader( Shader* shader )
551 DALI_ASSERT_DEBUG( NULL != shader );
553 // Note: The first shader added becomes the default shader
554 if( NULL == mImpl->defaultShader )
556 mImpl->defaultShader = shader;
559 mImpl->shaders.PushBack( shader );
561 // Allows the shader to dispatch texture requests to the cache and "save shader"
562 // requests to the resource manager from the render thread.
563 shader->Initialize( mImpl->renderManager, mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
566 void UpdateManager::RemoveShader(Shader* shader)
568 DALI_ASSERT_DEBUG(shader != NULL);
570 ShaderContainer& shaders = mImpl->shaders;
572 // Find the shader and destroy it
573 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
575 Shader& current = **iter;
576 if ( ¤t == shader )
578 // Transfer ownership to the discard queue
579 // This keeps the shader alive, until the render-thread has finished with it
580 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
585 // Should not reach here
586 DALI_ASSERT_DEBUG(false);
589 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool fixed )
591 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
593 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
595 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
596 shaderData->SetHashValue( shaderHash );
600 // This is done in the render thread, to allow GL program compilation
601 // Will trigger a NotifySaveRequest back to updateManager to forward onto ResourceClient
602 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, Context*, bool> DerivedType;
604 // Reserve some memory inside the render queue
605 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
607 // Construct message in the render queue memory; note that delete should not be called on the return value
608 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, &(mImpl->renderManager.GetContext()), fixed );
612 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
614 mImpl->animatableMeshes.PushBack(animatableMesh);
617 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
619 DALI_ASSERT_DEBUG(animatableMesh != NULL);
621 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
623 // Find the animatableMesh and destroy it
624 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
626 AnimatableMesh& current = **iter;
627 if ( ¤t == animatableMesh )
629 animatableMeshes.Erase( iter );
635 void UpdateManager::AddMaterial( Material* material )
637 DALI_ASSERT_DEBUG( NULL != material );
639 mImpl->materials.PushBack( material );
640 RenderMaterial* renderMaterial = new RenderMaterial();
642 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
644 // Reserve some memory inside the render queue
645 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
647 // Construct message in the render queue memory; note that delete should not be called on the return value
648 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
650 material->SetRenderMaterial( renderMaterial );
651 material->OnStageConnection( *mImpl->sceneController );
654 void UpdateManager::RemoveMaterial( Material* theMaterial )
656 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
658 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
660 const Material* aMaterial = *iter;
662 if( aMaterial == theMaterial )
664 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
666 // Reserve some memory inside the render queue
667 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
669 // Construct message in the render queue memory; note that delete should not be called on the return value
670 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
672 mImpl->materials.Erase( iter );
678 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
682 // copy the list, this is only likely to happen once in application life cycle
683 return &(mImpl->taskList);
687 // copy the list, this is only likely to happen once in application life cycle
688 return &(mImpl->systemLevelTaskList);
692 void UpdateManager::AddGesture( PanGesture* gesture )
694 DALI_ASSERT_DEBUG( NULL != gesture );
696 mImpl->gestures.PushBack( gesture );
699 void UpdateManager::RemoveGesture( PanGesture* gesture )
701 DALI_ASSERT_DEBUG( gesture != NULL );
703 GestureContainer& gestures = mImpl->gestures;
705 // Find the gesture and destroy it
706 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
708 PanGesture& current = **iter;
709 if ( ¤t == gesture )
711 mImpl->gestures.Erase( iter );
715 // Should not reach here
716 DALI_ASSERT_DEBUG(false);
719 void UpdateManager::ResetNodeProperty( Node& node )
721 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
724 void UpdateManager::ResetProperties()
726 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
728 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
729 mImpl->animationFinishedDuringUpdate = false;
731 // Animated properties have to be reset to their original value each frame
733 // Reset node properties
736 ResetNodeProperty( *mImpl->root );
739 if ( mImpl->systemLevelRoot )
741 ResetNodeProperty( *mImpl->systemLevelRoot );
744 // Reset the Connected Nodes
745 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
746 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
748 ResetNodeProperty( **iter );
751 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
752 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
755 node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
756 node->SetActive( false );
758 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
759 mImpl->activeDisconnectedNodes.erase( iter );
760 mImpl->disconnectedNodes.insert( node );
763 // Reset system-level render-task list properties to base values
764 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
766 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
768 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
771 // Reset render-task list properties to base values.
772 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
774 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
776 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
779 // Reset custom object properties to base values
780 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
782 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
785 // Reset animatable shader properties to base values
786 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
788 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
791 // Reset animatable mesh properties to base values
792 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
794 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
797 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
800 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTime, unsigned int nextVSyncTime )
802 bool gestureUpdated( false );
804 // constrain gestures... (in construction order)
805 GestureContainer& gestures = mImpl->gestures;
807 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
809 PanGesture& gesture = **iter;
810 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
811 gestureUpdated |= gesture.UpdateProperties( lastVSyncTime, nextVSyncTime );
814 return gestureUpdated;
817 void UpdateManager::Animate( float elapsedSeconds )
819 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
821 AnimationContainer &animations = mImpl->animations;
822 AnimationIter iter = animations.Begin();
823 while ( iter != animations.End() )
825 Animation* animation = *iter;
826 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
828 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
830 // Remove animations that had been destroyed but were still waiting for an update
831 if (animation->GetState() == Animation::Destroyed)
833 iter = animations.Erase(iter);
841 if ( mImpl->animationFinishedDuringUpdate )
843 // The application should be notified by NotificationManager, in another thread
844 mImpl->notificationManager.QueueMessage( AnimationFinishedMessage( mImpl->animationFinishedNotifier ) );
847 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
850 void UpdateManager::ApplyConstraints()
852 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
854 mImpl->activeConstraints = 0;
856 // constrain custom objects... (in construction order)
857 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
859 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
860 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
862 PropertyOwner& object = **iter;
863 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
866 // constrain nodes... (in Depth First traversal order)
869 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
872 if ( mImpl->systemLevelRoot )
874 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
877 // constrain other property-owners after nodes as they are more likely to depend on a node's
878 // current frame property than vice versa. They tend to be final constraints (no further
879 // constraints depend on their properties)
880 // e.g. ShaderEffect uniform a function of Actor's position.
881 // Mesh vertex a function of Actor's position or world position.
883 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
884 // they can be all processed in a super-list of property-owners.
886 // Constrain system-level render-tasks
887 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
889 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
891 RenderTask& task = **iter;
892 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
895 // Constrain render-tasks
896 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
898 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
900 RenderTask& task = **iter;
901 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
904 // constrain meshes (in construction order)
905 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
906 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
908 AnimatableMesh& mesh = **iter;
909 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
912 // constrain shaders... (in construction order)
913 ShaderContainer& shaders = mImpl->shaders;
915 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
917 Shader& shader = **iter;
918 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
921 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
924 void UpdateManager::ProcessPropertyNotifications()
926 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
927 PropertyNotificationIter iter = notifications.Begin();
929 while ( iter != notifications.End() )
931 PropertyNotification* notification = *iter;
933 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
937 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
943 void UpdateManager::UpdateNodes()
945 mImpl->nodeDirtyFlags = NothingFlag;
952 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
954 Shader* defaultShader = GetDefaultShader();
956 if ( NULL != defaultShader )
958 // Prepare resources, update shaders, update attachments, for each node
959 // And add the renderers to the sorted layers. Start from root, which is also a layer
960 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
961 mSceneGraphBuffers.GetUpdateBufferIndex(),
962 mImpl->resourceManager,
966 if ( mImpl->systemLevelRoot )
968 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
969 mSceneGraphBuffers.GetUpdateBufferIndex(),
970 mImpl->resourceManager,
976 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
979 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
981 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
983 AnimatableMesh& current = **iter;
984 current.UpdateMesh( updateBufferIndex );
988 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
990 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
992 Material* material = *iter;
993 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
997 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
999 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
1001 Material* material = *iter;
1002 material->PrepareRender( updateBufferIndex );
1006 unsigned int UpdateManager::Update( float elapsedSeconds, unsigned int lastVSyncTime, unsigned int nextVSyncTime )
1008 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
1009 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
1010 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
1012 // Measure the time spent in UpdateManager::Update
1013 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
1015 // Update the frame time delta on the render thread.
1016 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1018 // 1) Clear nodes/resources which were previously discarded
1019 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1021 // 2) Grab any loaded resources
1022 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1024 // 3) Process Touches & Gestures
1025 mImpl->touchResampler.Update();
1026 const bool gestureUpdated = ProcessGestures( lastVSyncTime, nextVSyncTime );
1028 const bool updateScene = // The scene-graph requires an update if..
1029 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1030 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1031 IsAnimationRunning() || // ..at least one animation is running OR
1032 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1033 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
1034 resourceChanged || // ..one or more resources were updated/changed OR
1035 gestureUpdated; // ..a gesture property was updated
1037 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1038 // values if the scene was updated in the previous frame.
1039 if( updateScene || mImpl->previousUpdateScene )
1041 // 4) Reset properties from the previous update
1045 // 5) Process the queued scene messages
1046 mImpl->messageQueue.ProcessMessages();
1048 // 6) Post Process Ids of resources updated by renderer
1049 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1051 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1052 // renderer lists if the scene was updated in the previous frame.
1053 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1054 if( updateScene || mImpl->previousUpdateScene )
1057 Animate( elapsedSeconds );
1059 // 8) Apply Constraints
1062 #ifdef DYNAMICS_SUPPORT
1063 // 9) Update dynamics simulation
1064 mImpl->dynamicsChanged = false;
1065 if( mImpl->dynamicsWorld )
1067 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1071 // 10) Check Property Notifications
1072 ProcessPropertyNotifications();
1074 // 11) Clear the lists of renderable-attachments from the previous update
1075 ClearRenderables( mImpl->sortedLayers );
1076 ClearRenderables( mImpl->systemLevelSortedLayers );
1078 // 12) Update animated meshes
1079 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1081 // 13) Update materials. Prepares image resources
1082 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1084 // 14) Update node hierarchy and perform sorting / culling.
1085 // This will populate each Layer with a list of renderers which are ready.
1088 // 15) Prepare for the next render
1089 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1090 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1091 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1092 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1093 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1095 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1097 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1098 // reset the update buffer index and make sure there is enough room in the instruction container
1099 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1100 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1102 if ( NULL != mImpl->root )
1104 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1105 mImpl->completeStatusManager,
1108 mImpl->sortedLayers,
1109 mImpl->renderSortingHelper,
1110 mImpl->renderInstructions );
1112 // Process the system-level RenderTasks last
1113 if ( NULL != mImpl->systemLevelRoot )
1115 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1116 mImpl->completeStatusManager,
1117 mImpl->systemLevelTaskList,
1118 *mImpl->systemLevelRoot,
1119 mImpl->systemLevelSortedLayers,
1120 mImpl->renderSortingHelper,
1121 mImpl->renderInstructions );
1126 // check the countdown and notify
1127 bool doRenderOnceNotify = false;
1128 mImpl->renderTaskWaiting = false;
1129 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1130 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1131 endIter != iter; ++iter )
1133 RenderTask& renderTask(*(*iter));
1135 if( renderTask.IsWaitingToRender() &&
1136 renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1138 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1141 if( renderTask.HasRendered() )
1143 doRenderOnceNotify = true;
1147 if( doRenderOnceNotify )
1149 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1150 mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
1153 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1155 // Macro is undefined in release build.
1156 SNAPSHOT_NODE_LOGGING;
1158 // A ResetProperties() may be required in the next frame
1159 mImpl->previousUpdateScene = updateScene;
1161 // Check whether further updates are required
1162 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1164 #ifdef PERFORMANCE_MONITOR_ENABLED
1165 // Always keep rendering when measuring FPS
1166 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1169 // The update has finished; swap the double-buffering indices
1170 mSceneGraphBuffers.Swap();
1172 // tell the update manager that we're done so the queue can be given to event thread
1173 mImpl->notificationManager.UpdateCompleted();
1175 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1177 return keepUpdating;
1180 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1182 // Update the duration set via Stage::KeepRendering()
1183 if ( mImpl->keepRenderingSeconds > 0.0f )
1185 mImpl->keepRenderingSeconds -= elapsedSeconds;
1188 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1190 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1191 // Keep updating until no messages are received and no animations are running.
1192 // If an animation has just finished, update at least once more for Discard end-actions.
1193 // No need to check for renderQueue as there is always a render after update and if that
1194 // render needs another update it will tell the adaptor to call update again
1196 if ( mImpl->keepRenderingSeconds > 0.0f )
1198 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1201 if ( !mImpl->messageQueue.WasEmpty() )
1203 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1206 if ( IsAnimationRunning() ||
1207 mImpl->animationFinishedDuringUpdate )
1209 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1212 if ( mImpl->dynamicsChanged )
1214 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1217 if ( mImpl->renderTaskWaiting )
1219 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1222 return keepUpdatingRequest;
1225 void UpdateManager::SetBackgroundColor( const Vector4& color )
1227 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1229 // Reserve some memory inside the render queue
1230 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1232 // Construct message in the render queue memory; note that delete should not be called on the return value
1233 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1236 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1238 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1240 // Reserve some memory inside the render queue
1241 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1243 // Construct message in the render queue memory; note that delete should not be called on the return value
1244 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1247 void UpdateManager::KeepRendering( float durationSeconds )
1249 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1252 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1256 // just copy the vector of pointers
1257 mImpl->sortedLayers = layers;
1261 mImpl->systemLevelSortedLayers = layers;
1265 #ifdef DYNAMICS_SUPPORT
1267 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1269 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1270 mImpl->dynamicsWorld = dynamicsWorld;
1273 void UpdateManager::TerminateDynamicsWorld()
1275 mImpl->dynamicsWorld.Reset();
1278 #endif // DYNAMICS_SUPPORT
1280 } // namespace SceneGraph
1282 } // namespace Internal