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/scene-graph-buffers.h>
42 #include <dali/internal/update/common/scene-graph-property-buffer.h>
43 #include <dali/internal/update/controllers/render-message-dispatcher.h>
44 #include <dali/internal/update/controllers/scene-controller-impl.h>
45 #include <dali/internal/update/effects/scene-graph-material.h>
46 #include <dali/internal/update/effects/scene-graph-sampler.h>
47 #include <dali/internal/update/geometry/scene-graph-geometry.h>
48 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
49 #include <dali/internal/update/manager/object-owner-container.h>
50 #include <dali/internal/update/manager/prepare-render-algorithms.h>
51 #include <dali/internal/update/manager/process-render-tasks.h>
52 #include <dali/internal/update/manager/sorted-layers.h>
53 #include <dali/internal/update/manager/update-algorithms.h>
54 #include <dali/internal/update/manager/update-manager-debug.h>
55 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
56 #include <dali/internal/update/node-attachments/scene-graph-renderer-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/queue/update-message-queue.h>
60 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
61 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
62 #include <dali/internal/update/resources/resource-manager.h>
63 #include <dali/internal/update/resources/complete-status-manager.h>
64 #include <dali/internal/update/touch/touch-resampler.h>
66 #include <dali/internal/render/common/render-instruction-container.h>
67 #include <dali/internal/render/common/render-manager.h>
68 #include <dali/internal/render/queue/render-queue.h>
69 #include <dali/internal/render/common/performance-monitor.h>
70 #include <dali/internal/render/gl-resources/texture-cache.h>
71 #include <dali/internal/render/shaders/scene-graph-shader.h>
73 #ifdef DYNAMICS_SUPPORT
74 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
75 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
78 // Un-comment to enable node tree debug logging
79 //#define NODE_TREE_LOGGING 1
81 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
82 #define SNAPSHOT_NODE_LOGGING \
83 const int FRAME_COUNT_TRIGGER = 16;\
84 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
86 if ( NULL != mImpl->root )\
88 mImpl->frameCounter = 0;\
89 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
92 mImpl->frameCounter++;
94 #define SNAPSHOT_NODE_LOGGING
97 #if defined(DEBUG_ENABLED)
98 extern Debug::Filter* gRenderTaskLogFilter;
102 using namespace Dali::Integration;
103 using Dali::Internal::Update::MessageQueue;
117 void DestroyNodeSet( std::set<Node*>& nodeSet )
119 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
123 // Call Node::OnDestroy as each node is destroyed
133 typedef OwnerContainer< Shader* > ShaderContainer;
134 typedef ShaderContainer::Iterator ShaderIter;
135 typedef ShaderContainer::ConstIterator ShaderConstIter;
137 typedef OwnerContainer<PanGesture*> GestureContainer;
138 typedef GestureContainer::Iterator GestureIter;
139 typedef GestureContainer::ConstIterator GestureConstIter;
143 * Structure to contain UpdateManager internal data
145 struct UpdateManager::Impl
147 Impl( NotificationManager& notificationManager,
148 GlSyncAbstraction& glSyncAbstraction,
149 CompleteNotificationInterface& animationFinishedNotifier,
150 PropertyNotifier& propertyNotifier,
151 ResourceManager& resourceManager,
152 DiscardQueue& discardQueue,
153 RenderController& renderController,
154 RenderManager& renderManager,
155 RenderQueue& renderQueue,
156 TextureCache& textureCache,
157 TouchResampler& touchResampler,
158 SceneGraphBuffers& sceneGraphBuffers )
160 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
161 notificationManager( notificationManager ),
162 animationFinishedNotifier( animationFinishedNotifier ),
163 propertyNotifier( propertyNotifier ),
164 resourceManager( resourceManager ),
165 discardQueue( discardQueue ),
166 renderController( renderController ),
167 sceneController( NULL ),
168 renderManager( renderManager ),
169 renderQueue( renderQueue ),
170 renderInstructions( renderManager.GetRenderInstructionContainer() ),
171 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
172 touchResampler( touchResampler ),
173 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
174 taskList ( completeStatusManager ),
175 systemLevelTaskList ( completeStatusManager ),
177 systemLevelRoot( NULL ),
178 geometries( sceneGraphBuffers, discardQueue ),
179 materials( sceneGraphBuffers, discardQueue ),
180 samplers( sceneGraphBuffers, discardQueue ),
181 propertyBuffers( sceneGraphBuffers, discardQueue ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 dynamicsChanged( false ),
184 keepRenderingSeconds( 0.0f ),
185 animationFinishedDuringUpdate( false ),
186 activeConstraints( 0 ),
187 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
188 previousUpdateScene( false ),
190 renderSortingHelper(),
191 renderTaskWaiting( false )
193 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
195 geometries.SetSceneController( *sceneController );
196 materials.SetSceneController( *sceneController );
197 propertyBuffers.SetSceneController( *sceneController );
198 samplers.SetSceneController( *sceneController );
203 // Disconnect render tasks from nodes, before destroying the nodes
204 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
205 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
207 (*iter)->SetSourceNode( NULL );
209 // ..repeat for system level RenderTasks
210 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
211 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
213 (*iter)->SetSourceNode( NULL );
216 // UpdateManager owns the Nodes
217 DestroyNodeSet( activeDisconnectedNodes );
218 DestroyNodeSet( connectedNodes );
219 DestroyNodeSet( disconnectedNodes );
221 // If there is root, reset it, otherwise do nothing as rendering was never started
230 if( systemLevelRoot )
232 systemLevelRoot->OnDestroy();
234 delete systemLevelRoot;
235 systemLevelRoot = NULL;
238 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
239 delete sceneController;
242 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
243 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
244 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
245 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
246 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
247 ResourceManager& resourceManager; ///< resource manager
248 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
249 RenderController& renderController; ///< render controller
250 SceneControllerImpl* sceneController; ///< scene controller
251 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
252 RenderQueue& renderQueue; ///< Used to queue messages for the next render
253 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
254 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
255 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
257 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
259 RenderTaskList taskList; ///< The list of scene graph render-tasks
260 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
262 Layer* root; ///< The root node (root is a layer)
263 Layer* systemLevelRoot; ///< A separate root-node for system-level content
264 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
265 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
266 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
268 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
269 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
271 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
273 AnimationContainer animations; ///< A container of owned animations
274 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
276 ObjectOwnerContainer<Geometry> geometries; ///< A container of geometries
277 ObjectOwnerContainer<Material> materials; ///< A container of materials
278 ObjectOwnerContainer<Sampler> samplers; ///< A container of samplers
279 ObjectOwnerContainer<PropertyBuffer> propertyBuffers; ///< A container of property buffers
281 ShaderContainer shaders; ///< A container of owned shaders
283 MessageQueue messageQueue; ///< The messages queued from the event-thread
285 #ifdef DYNAMICS_SUPPORT
286 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
288 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
290 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
291 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
293 unsigned int activeConstraints; ///< number of active constraints from previous frame
294 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
295 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
297 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
298 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
300 GestureContainer gestures; ///< A container of owned gesture detectors
301 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
304 UpdateManager::UpdateManager( NotificationManager& notificationManager,
305 GlSyncAbstraction& glSyncAbstraction,
306 CompleteNotificationInterface& animationFinishedNotifier,
307 PropertyNotifier& propertyNotifier,
308 ResourceManager& resourceManager,
309 DiscardQueue& discardQueue,
310 RenderController& controller,
311 RenderManager& renderManager,
312 RenderQueue& renderQueue,
313 TextureCache& textureCache,
314 TouchResampler& touchResampler )
317 mImpl = new Impl( notificationManager,
319 animationFinishedNotifier,
328 mSceneGraphBuffers );
330 textureCache.SetBufferIndices( &mSceneGraphBuffers );
333 UpdateManager::~UpdateManager()
338 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
340 DALI_ASSERT_DEBUG( layer->IsLayer() );
341 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
345 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
350 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
351 mImpl->systemLevelRoot = layer;
354 layer->SetRoot(true);
357 void UpdateManager::AddNode( Node* node )
359 DALI_ASSERT_ALWAYS( NULL != node );
360 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
362 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
365 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
367 DALI_ASSERT_ALWAYS( NULL != parent );
368 DALI_ASSERT_ALWAYS( NULL != node );
369 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
371 // Move from active/disconnectedNodes to connectedNodes
372 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
375 removed = mImpl->disconnectedNodes.erase( node );
376 DALI_ASSERT_ALWAYS( removed );
378 mImpl->connectedNodes.insert( node );
380 node->SetActive( true );
382 parent->ConnectChild( node, index );
385 void UpdateManager::DisconnectNode( Node* node )
387 Node* parent = node->GetParent();
388 DALI_ASSERT_ALWAYS( NULL != parent );
389 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
391 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
392 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
395 void UpdateManager::SetNodeActive( Node* node )
397 DALI_ASSERT_ALWAYS( NULL != node );
398 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
400 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
401 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
402 DALI_ASSERT_ALWAYS( removed );
403 mImpl->activeDisconnectedNodes.insert( node );
405 node->SetActive( true );
408 void UpdateManager::DestroyNode( Node* node )
410 DALI_ASSERT_ALWAYS( NULL != node );
411 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
413 // Transfer ownership from new/disconnectedNodes to the discard queue
414 // This keeps the nodes alive, until the render-thread has finished with them
415 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
418 removed = mImpl->disconnectedNodes.erase( node );
419 DALI_ASSERT_ALWAYS( removed );
421 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
423 // Notify the Node about impending destruction
427 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
428 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
430 DALI_ASSERT_DEBUG( node != NULL );
431 DALI_ASSERT_DEBUG( attachment != NULL );
433 // attach node to attachment first so that parent is known by the time attachment is connected
434 node->Attach( *attachment ); // node takes ownership
435 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
438 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
440 renderer->AttachToSceneGraph( *(mImpl->sceneController), mSceneGraphBuffers.GetUpdateBufferIndex() );
443 void UpdateManager::AddObject( PropertyOwner* object )
445 DALI_ASSERT_DEBUG( NULL != object );
447 mImpl->customObjects.PushBack( object );
450 void UpdateManager::RemoveObject( PropertyOwner* object )
452 DALI_ASSERT_DEBUG( NULL != object );
454 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
456 // Find the object and destroy it
457 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
459 PropertyOwner* current = *iter;
460 if ( current == object )
462 customObjects.Erase( iter );
467 // Should not reach here
468 DALI_ASSERT_DEBUG(false);
471 void UpdateManager::AddAnimation( Animation* animation )
473 mImpl->animations.PushBack( animation );
476 void UpdateManager::StopAnimation( Animation* animation )
478 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
480 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
482 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
485 void UpdateManager::RemoveAnimation( Animation* animation )
487 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
489 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
491 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
494 bool UpdateManager::IsAnimationRunning() const
496 bool isRunning(false);
497 AnimationContainer& animations = mImpl->animations;
499 // Find any animation that isn't stopped or paused
501 const AnimationIter endIter = animations.End();
502 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
504 const Animation::State state = (*iter)->GetState();
506 if (state != Animation::Stopped &&
507 state != Animation::Paused)
516 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
518 mImpl->propertyNotifications.PushBack( propertyNotification );
521 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
523 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
524 PropertyNotificationIter iter = propertyNotifications.Begin();
526 while ( iter != propertyNotifications.End() )
528 if( *iter == propertyNotification )
530 propertyNotifications.Erase(iter);
537 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
539 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
540 propertyNotification->SetNotifyMode( notifyMode );
543 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
545 return mImpl->geometries;
548 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
550 return mImpl->materials;
553 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
555 return mImpl->samplers;
558 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
560 return mImpl->propertyBuffers;
563 void UpdateManager::AddShader( Shader* shader )
565 DALI_ASSERT_DEBUG( NULL != shader );
567 if( mImpl->shaders.Count() == 0 )
569 // the first added shader becomes our default shader
570 // Construct message in the render queue memory; note that delete should not be called on the return value
571 typedef MessageValue1< RenderManager, Shader* > DerivedType;
573 // Reserve some memory inside the render queue
574 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
576 // Construct message in the render queue memory; note that delete should not be called on the return value
577 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
580 mImpl->shaders.PushBack( shader );
582 // Allows the shader to dispatch texture requests to the cache
583 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
586 void UpdateManager::RemoveShader( Shader* shader )
588 DALI_ASSERT_DEBUG(shader != NULL);
590 ShaderContainer& shaders = mImpl->shaders;
592 // Find the shader and destroy it
593 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
595 Shader& current = **iter;
596 if ( ¤t == shader )
598 // Transfer ownership to the discard queue
599 // This keeps the shader alive, until the render-thread has finished with it
600 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
605 // Should not reach here
606 DALI_ASSERT_DEBUG(false);
609 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
611 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
613 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
615 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
618 shaderData->SetHashValue( shaderHash );
619 shaderData->SetResourceId( resourceId );
621 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
623 // Reserve some memory inside the render queue
624 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
626 // Construct message in the render queue memory; note that delete should not be called on the return value
627 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
631 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
635 // copy the list, this is only likely to happen once in application life cycle
636 return &(mImpl->taskList);
640 // copy the list, this is only likely to happen once in application life cycle
641 return &(mImpl->systemLevelTaskList);
645 void UpdateManager::AddGesture( PanGesture* gesture )
647 DALI_ASSERT_DEBUG( NULL != gesture );
649 mImpl->gestures.PushBack( gesture );
652 void UpdateManager::RemoveGesture( PanGesture* gesture )
654 DALI_ASSERT_DEBUG( gesture != NULL );
656 GestureContainer& gestures = mImpl->gestures;
658 // Find the gesture and destroy it
659 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
661 PanGesture& current = **iter;
662 if ( ¤t == gesture )
664 mImpl->gestures.Erase( iter );
668 // Should not reach here
669 DALI_ASSERT_DEBUG(false);
672 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
674 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
677 void UpdateManager::EventProcessingStarted()
679 mImpl->messageQueue.EventProcessingStarted();
682 bool UpdateManager::FlushQueue()
684 return mImpl->messageQueue.FlushQueue();
687 void UpdateManager::ResetNodeProperty( Node& node )
689 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
692 void UpdateManager::ResetProperties()
694 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
696 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
698 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
699 mImpl->animationFinishedDuringUpdate = false;
701 // Animated properties have to be reset to their original value each frame
703 // Reset node properties
706 ResetNodeProperty( *mImpl->root );
709 if ( mImpl->systemLevelRoot )
711 ResetNodeProperty( *mImpl->systemLevelRoot );
714 // Reset the Connected Nodes
715 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
716 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
718 ResetNodeProperty( **iter );
721 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
722 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
725 node->ResetToBaseValues( bufferIndex );
726 node->SetActive( false );
728 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
729 mImpl->activeDisconnectedNodes.erase( iter );
730 mImpl->disconnectedNodes.insert( node );
733 // Reset system-level render-task list properties to base values
734 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
736 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
738 (*iter)->ResetToBaseValues( bufferIndex );
741 // Reset render-task list properties to base values.
742 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
744 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
746 (*iter)->ResetToBaseValues( bufferIndex );
749 // Reset custom object properties to base values
750 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
752 (*iter)->ResetToBaseValues( bufferIndex );
755 mImpl->materials.ResetToBaseValues( bufferIndex );
756 mImpl->geometries.ResetToBaseValues( bufferIndex );
757 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
758 mImpl->samplers.ResetToBaseValues( bufferIndex );
761 // Reset animatable shader properties to base values
762 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
764 (*iter)->ResetToBaseValues( bufferIndex );
767 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
770 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
772 bool gestureUpdated( false );
774 // constrain gestures... (in construction order)
775 GestureContainer& gestures = mImpl->gestures;
777 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
779 PanGesture& gesture = **iter;
780 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
781 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
784 return gestureUpdated;
787 void UpdateManager::Animate( float elapsedSeconds )
789 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
791 AnimationContainer &animations = mImpl->animations;
792 AnimationIter iter = animations.Begin();
793 while ( iter != animations.End() )
795 Animation* animation = *iter;
796 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
798 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
800 // Remove animations that had been destroyed but were still waiting for an update
801 if (animation->GetState() == Animation::Destroyed)
803 iter = animations.Erase(iter);
811 if ( mImpl->animationFinishedDuringUpdate )
813 // The application should be notified by NotificationManager, in another thread
814 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
817 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
820 void UpdateManager::ApplyConstraints()
822 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
824 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
826 mImpl->activeConstraints = 0;
828 // constrain custom objects... (in construction order)
829 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
831 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
832 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
834 PropertyOwner& object = **iter;
835 mImpl->activeConstraints += ConstrainPropertyOwner( object, bufferIndex );
838 // constrain nodes... (in Depth First traversal order)
841 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), bufferIndex );
844 if ( mImpl->systemLevelRoot )
846 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
849 // constrain other property-owners after nodes as they are more likely to depend on a node's
850 // current frame property than vice versa. They tend to be final constraints (no further
851 // constraints depend on their properties)
852 // e.g. ShaderEffect uniform a function of Actor's position.
853 // Mesh vertex a function of Actor's position or world position.
855 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
856 // they can be all processed in a super-list of property-owners.
858 // Constrain system-level render-tasks
859 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
861 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
863 RenderTask& task = **iter;
864 mImpl->activeConstraints += ConstrainPropertyOwner( task, bufferIndex );
867 // Constrain render-tasks
868 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
870 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
872 RenderTask& task = **iter;
873 mImpl->activeConstraints += ConstrainPropertyOwner( task, bufferIndex );
876 // Constrain Materials and geometries
877 mImpl->activeConstraints += mImpl->materials.ConstrainObjects( bufferIndex );
878 mImpl->activeConstraints += mImpl->geometries.ConstrainObjects( bufferIndex );
879 mImpl->activeConstraints += mImpl->samplers.ConstrainObjects( bufferIndex );
880 mImpl->activeConstraints += mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
882 // constrain shaders... (in construction order)
883 ShaderContainer& shaders = mImpl->shaders;
885 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
887 Shader& shader = **iter;
888 mImpl->activeConstraints += ConstrainPropertyOwner( shader, bufferIndex );
891 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
894 void UpdateManager::ProcessPropertyNotifications()
896 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
897 PropertyNotificationIter iter = notifications.Begin();
899 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
901 while ( iter != notifications.End() )
903 PropertyNotification* notification = *iter;
904 bool valid = notification->Check( bufferIndex );
907 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
913 void UpdateManager::UpdateNodes()
915 mImpl->nodeDirtyFlags = NothingFlag;
922 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
924 // Prepare resources, update shaders, update attachments, for each node
925 // And add the renderers to the sorted layers. Start from root, which is also a layer
926 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
927 mSceneGraphBuffers.GetUpdateBufferIndex(),
928 mImpl->resourceManager,
929 mImpl->renderQueue );
931 if ( mImpl->systemLevelRoot )
933 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
934 mSceneGraphBuffers.GetUpdateBufferIndex(),
935 mImpl->resourceManager,
936 mImpl->renderQueue );
939 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
942 unsigned int UpdateManager::Update( float elapsedSeconds,
943 unsigned int lastVSyncTimeMilliseconds,
944 unsigned int nextVSyncTimeMilliseconds )
946 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
947 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
948 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
950 // Measure the time spent in UpdateManager::Update
951 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
953 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
955 // Update the frame time delta on the render thread.
956 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
958 // 1) Clear nodes/resources which were previously discarded
959 mImpl->discardQueue.Clear( bufferIndex );
961 // 2) Grab any loaded resources
962 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
964 // 3) Process Touches & Gestures
965 mImpl->touchResampler.Update();
966 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
968 const bool updateScene = // The scene-graph requires an update if..
969 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
970 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
971 IsAnimationRunning() || // ..at least one animation is running OR
972 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
973 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
974 resourceChanged || // ..one or more resources were updated/changed OR
975 gestureUpdated; // ..a gesture property was updated
977 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
978 // values if the scene was updated in the previous frame.
979 if( updateScene || mImpl->previousUpdateScene )
981 // 4) Reset properties from the previous update
985 // 5) Process the queued scene messages
986 mImpl->messageQueue.ProcessMessages();
988 // 6) Post Process Ids of resources updated by renderer
989 mImpl->resourceManager.PostProcessResources( bufferIndex );
991 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
992 // renderer lists if the scene was updated in the previous frame.
993 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
994 if( updateScene || mImpl->previousUpdateScene )
997 Animate( elapsedSeconds );
999 // 8) Apply Constraints
1002 #ifdef DYNAMICS_SUPPORT
1003 // 9) Update dynamics simulation
1004 mImpl->dynamicsChanged = false;
1005 if( mImpl->dynamicsWorld )
1007 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1011 // 10) Check Property Notifications
1012 ProcessPropertyNotifications();
1014 // 11) Clear the lists of renderable-attachments from the previous update
1015 ClearRenderables( mImpl->sortedLayers );
1016 ClearRenderables( mImpl->systemLevelSortedLayers );
1018 // 12) Update node hierarchy and perform sorting / culling.
1019 // This will populate each Layer with a list of renderers which are ready.
1022 // 13) Prepare for the next render
1023 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1025 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1026 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1027 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1029 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1031 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1032 // reset the update buffer index and make sure there is enough room in the instruction container
1033 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1034 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1036 if ( NULL != mImpl->root )
1038 ProcessRenderTasks( bufferIndex,
1039 mImpl->completeStatusManager,
1042 mImpl->sortedLayers,
1043 mImpl->renderSortingHelper,
1044 mImpl->renderInstructions );
1046 // Process the system-level RenderTasks last
1047 if ( NULL != mImpl->systemLevelRoot )
1049 ProcessRenderTasks( bufferIndex,
1050 mImpl->completeStatusManager,
1051 mImpl->systemLevelTaskList,
1052 *mImpl->systemLevelRoot,
1053 mImpl->systemLevelSortedLayers,
1054 mImpl->renderSortingHelper,
1055 mImpl->renderInstructions );
1060 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1061 bool doRenderOnceNotify = false;
1062 mImpl->renderTaskWaiting = false;
1063 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1064 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1065 endIter != iter; ++iter )
1067 RenderTask& renderTask(*(*iter));
1069 renderTask.UpdateState();
1071 if( renderTask.IsWaitingToRender() &&
1072 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1074 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1077 if( renderTask.HasRendered() )
1079 doRenderOnceNotify = true;
1083 if( doRenderOnceNotify )
1085 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1086 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1089 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1091 // Macro is undefined in release build.
1092 SNAPSHOT_NODE_LOGGING;
1094 // A ResetProperties() may be required in the next frame
1095 mImpl->previousUpdateScene = updateScene;
1097 // Check whether further updates are required
1098 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1100 #ifdef PERFORMANCE_MONITOR_ENABLED
1101 // Always keep rendering when measuring FPS
1102 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1105 // The update has finished; swap the double-buffering indices
1106 mSceneGraphBuffers.Swap();
1108 // tell the update manager that we're done so the queue can be given to event thread
1109 mImpl->notificationManager.UpdateCompleted();
1111 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1113 return keepUpdating;
1116 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1118 // Update the duration set via Stage::KeepRendering()
1119 if ( mImpl->keepRenderingSeconds > 0.0f )
1121 mImpl->keepRenderingSeconds -= elapsedSeconds;
1124 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1126 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1127 // Keep updating until no messages are received and no animations are running.
1128 // If an animation has just finished, update at least once more for Discard end-actions.
1129 // No need to check for renderQueue as there is always a render after update and if that
1130 // render needs another update it will tell the adaptor to call update again
1132 if ( mImpl->keepRenderingSeconds > 0.0f )
1134 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1137 if ( IsAnimationRunning() ||
1138 mImpl->animationFinishedDuringUpdate )
1140 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1143 if ( mImpl->dynamicsChanged )
1145 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1148 if ( mImpl->renderTaskWaiting )
1150 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1153 return keepUpdatingRequest;
1156 void UpdateManager::SetBackgroundColor( const Vector4& color )
1158 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1160 // Reserve some memory inside the render queue
1161 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1163 // Construct message in the render queue memory; note that delete should not be called on the return value
1164 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1167 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1169 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1171 // Reserve some memory inside the render queue
1172 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174 // Construct message in the render queue memory; note that delete should not be called on the return value
1175 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1178 void UpdateManager::KeepRendering( float durationSeconds )
1180 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1183 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1187 // just copy the vector of pointers
1188 mImpl->sortedLayers = layers;
1192 mImpl->systemLevelSortedLayers = layers;
1196 #ifdef DYNAMICS_SUPPORT
1198 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1200 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1201 mImpl->dynamicsWorld = dynamicsWorld;
1204 void UpdateManager::TerminateDynamicsWorld()
1206 mImpl->dynamicsWorld.Reset();
1209 #endif // DYNAMICS_SUPPORT
1211 } // namespace SceneGraph
1213 } // namespace Internal