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/devel-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/gestures/scene-graph-pan-gesture.h>
46 #include <dali/internal/update/manager/object-owner-container.h>
47 #include <dali/internal/update/manager/prepare-render-algorithms.h>
48 #include <dali/internal/update/manager/process-render-tasks.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
53 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
54 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
55 #include <dali/internal/update/nodes/node.h>
56 #include <dali/internal/update/nodes/scene-graph-layer.h>
57 #include <dali/internal/update/queue/update-message-queue.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
59 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
60 #include <dali/internal/update/rendering/scene-graph-material.h>
61 #include <dali/internal/update/rendering/scene-graph-sampler.h>
62 #include <dali/internal/update/rendering/scene-graph-geometry.h>
63 #include <dali/internal/update/resources/resource-manager.h>
64 #include <dali/internal/update/resources/complete-status-manager.h>
65 #include <dali/internal/update/touch/touch-resampler.h>
67 #include <dali/internal/render/common/render-instruction-container.h>
68 #include <dali/internal/render/common/render-manager.h>
69 #include <dali/internal/render/queue/render-queue.h>
70 #include <dali/internal/render/common/performance-monitor.h>
71 #include <dali/internal/render/gl-resources/texture-cache.h>
72 #include <dali/internal/render/shaders/scene-graph-shader.h>
74 #ifdef DYNAMICS_SUPPORT
75 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
76 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
79 // Un-comment to enable node tree debug logging
80 //#define NODE_TREE_LOGGING 1
82 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
83 #define SNAPSHOT_NODE_LOGGING \
84 const int FRAME_COUNT_TRIGGER = 16;\
85 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
87 if ( NULL != mImpl->root )\
89 mImpl->frameCounter = 0;\
90 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
93 mImpl->frameCounter++;
95 #define SNAPSHOT_NODE_LOGGING
98 #if defined(DEBUG_ENABLED)
99 extern Debug::Filter* gRenderTaskLogFilter;
103 using namespace Dali::Integration;
104 using Dali::Internal::Update::MessageQueue;
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 OwnerContainer<PanGesture*> GestureContainer;
139 typedef GestureContainer::Iterator GestureIter;
140 typedef GestureContainer::ConstIterator GestureConstIter;
144 * Structure to contain UpdateManager internal data
146 struct UpdateManager::Impl
148 Impl( NotificationManager& notificationManager,
149 GlSyncAbstraction& glSyncAbstraction,
150 CompleteNotificationInterface& animationFinishedNotifier,
151 PropertyNotifier& propertyNotifier,
152 ResourceManager& resourceManager,
153 DiscardQueue& discardQueue,
154 RenderController& renderController,
155 RenderManager& renderManager,
156 RenderQueue& renderQueue,
157 TextureCache& textureCache,
158 TouchResampler& touchResampler,
159 SceneGraphBuffers& sceneGraphBuffers )
161 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
162 notificationManager( notificationManager ),
163 animationFinishedNotifier( animationFinishedNotifier ),
164 propertyNotifier( propertyNotifier ),
165 resourceManager( resourceManager ),
166 discardQueue( discardQueue ),
167 renderController( renderController ),
168 sceneController( NULL ),
169 renderManager( renderManager ),
170 renderQueue( renderQueue ),
171 renderInstructions( renderManager.GetRenderInstructionContainer() ),
172 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
173 touchResampler( touchResampler ),
174 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
175 taskList ( completeStatusManager ),
176 systemLevelTaskList ( completeStatusManager ),
178 systemLevelRoot( NULL ),
179 geometries( sceneGraphBuffers, discardQueue ),
180 materials( sceneGraphBuffers, discardQueue ),
181 samplers( sceneGraphBuffers, discardQueue ),
182 propertyBuffers( sceneGraphBuffers, discardQueue ),
183 messageQueue( renderController, sceneGraphBuffers ),
184 dynamicsChanged( false ),
185 keepRenderingSeconds( 0.0f ),
186 animationFinishedDuringUpdate( false ),
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 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
294 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
296 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
297 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
299 GestureContainer gestures; ///< A container of owned gesture detectors
300 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
303 UpdateManager::UpdateManager( NotificationManager& notificationManager,
304 GlSyncAbstraction& glSyncAbstraction,
305 CompleteNotificationInterface& animationFinishedNotifier,
306 PropertyNotifier& propertyNotifier,
307 ResourceManager& resourceManager,
308 DiscardQueue& discardQueue,
309 RenderController& controller,
310 RenderManager& renderManager,
311 RenderQueue& renderQueue,
312 TextureCache& textureCache,
313 TouchResampler& touchResampler )
316 mImpl = new Impl( notificationManager,
318 animationFinishedNotifier,
327 mSceneGraphBuffers );
329 textureCache.SetBufferIndices( &mSceneGraphBuffers );
332 UpdateManager::~UpdateManager()
337 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
339 DALI_ASSERT_DEBUG( layer->IsLayer() );
340 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
344 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
349 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
350 mImpl->systemLevelRoot = layer;
353 layer->SetRoot(true);
356 void UpdateManager::AddNode( Node* node )
358 DALI_ASSERT_ALWAYS( NULL != node );
359 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
361 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
364 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
366 DALI_ASSERT_ALWAYS( NULL != parent );
367 DALI_ASSERT_ALWAYS( NULL != node );
368 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
370 // Move from active/disconnectedNodes to connectedNodes
371 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
374 removed = mImpl->disconnectedNodes.erase( node );
375 DALI_ASSERT_ALWAYS( removed );
377 mImpl->connectedNodes.insert( node );
379 node->SetActive( true );
381 parent->ConnectChild( node, index );
384 void UpdateManager::DisconnectNode( Node* node )
386 Node* parent = node->GetParent();
387 DALI_ASSERT_ALWAYS( NULL != parent );
388 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
390 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
391 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
394 void UpdateManager::SetNodeActive( Node* node )
396 DALI_ASSERT_ALWAYS( NULL != node );
397 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
399 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
400 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
401 DALI_ASSERT_ALWAYS( removed );
402 mImpl->activeDisconnectedNodes.insert( node );
404 node->SetActive( true );
407 void UpdateManager::DestroyNode( Node* node )
409 DALI_ASSERT_ALWAYS( NULL != node );
410 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
412 // Transfer ownership from new/disconnectedNodes to the discard queue
413 // This keeps the nodes alive, until the render-thread has finished with them
414 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
417 removed = mImpl->disconnectedNodes.erase( node );
418 DALI_ASSERT_ALWAYS( removed );
420 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
422 // Notify the Node about impending destruction
426 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
427 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
429 DALI_ASSERT_DEBUG( node != NULL );
430 DALI_ASSERT_DEBUG( attachment != NULL );
432 // attach node to attachment first so that parent is known by the time attachment is connected
433 node->Attach( *attachment ); // node takes ownership
435 // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
436 if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL )
438 attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
442 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
444 // @todo MESH_REWORK Take ownership of this object after merge with SceneGraph::RenderableAttachment
446 SceneGraph::NodeAttachment* attachment = static_cast<SceneGraph::NodeAttachment*>(renderer);
447 attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
450 void UpdateManager::AddObject( PropertyOwner* object )
452 DALI_ASSERT_DEBUG( NULL != object );
454 mImpl->customObjects.PushBack( object );
457 void UpdateManager::RemoveObject( PropertyOwner* object )
459 DALI_ASSERT_DEBUG( NULL != object );
461 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
463 // Find the object and destroy it
464 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
466 PropertyOwner* current = *iter;
467 if ( current == object )
469 customObjects.Erase( iter );
474 // Should not reach here
475 DALI_ASSERT_DEBUG(false);
478 void UpdateManager::AddAnimation( Animation* animation )
480 mImpl->animations.PushBack( animation );
483 void UpdateManager::StopAnimation( Animation* animation )
485 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
487 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
489 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
492 void UpdateManager::RemoveAnimation( Animation* animation )
494 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
496 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
498 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
501 bool UpdateManager::IsAnimationRunning() const
503 bool isRunning(false);
504 AnimationContainer& animations = mImpl->animations;
506 // Find any animation that isn't stopped or paused
508 const AnimationIter endIter = animations.End();
509 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
511 const Animation::State state = (*iter)->GetState();
513 if (state != Animation::Stopped &&
514 state != Animation::Paused)
523 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
525 mImpl->propertyNotifications.PushBack( propertyNotification );
528 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
530 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
531 PropertyNotificationIter iter = propertyNotifications.Begin();
533 while ( iter != propertyNotifications.End() )
535 if( *iter == propertyNotification )
537 propertyNotifications.Erase(iter);
544 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
546 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
547 propertyNotification->SetNotifyMode( notifyMode );
550 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
552 return mImpl->geometries;
555 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
557 return mImpl->materials;
560 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
562 return mImpl->samplers;
565 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
567 return mImpl->propertyBuffers;
570 void UpdateManager::AddShader( Shader* shader )
572 DALI_ASSERT_DEBUG( NULL != shader );
574 if( mImpl->shaders.Count() == 0 )
576 // the first added shader becomes our default shader
577 // Construct message in the render queue memory; note that delete should not be called on the return value
578 typedef MessageValue1< RenderManager, Shader* > DerivedType;
580 // Reserve some memory inside the render queue
581 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
583 // Construct message in the render queue memory; note that delete should not be called on the return value
584 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
587 mImpl->shaders.PushBack( shader );
589 // Allows the shader to dispatch texture requests to the cache
590 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
593 void UpdateManager::RemoveShader( Shader* shader )
595 DALI_ASSERT_DEBUG(shader != NULL);
597 ShaderContainer& shaders = mImpl->shaders;
599 // Find the shader and destroy it
600 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
602 Shader& current = **iter;
603 if ( ¤t == shader )
605 // Transfer ownership to the discard queue
606 // This keeps the shader alive, until the render-thread has finished with it
607 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
612 // Should not reach here
613 DALI_ASSERT_DEBUG(false);
616 void UpdateManager::SetShaderProgram( Shader* shader,
617 ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
619 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (id:%d hash:%d)\n", resourceId, shaderHash);
621 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
623 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
626 shaderData->SetHashValue( shaderHash );
627 shaderData->SetResourceId( resourceId );
629 typedef MessageValue4< Shader, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
631 // Reserve some memory inside the render queue
632 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
634 // Construct message in the render queue memory; note that delete should not be called on the return value
635 new (slot) DerivedType( shader, &Shader::SetProgram, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
639 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
643 // copy the list, this is only likely to happen once in application life cycle
644 return &(mImpl->taskList);
648 // copy the list, this is only likely to happen once in application life cycle
649 return &(mImpl->systemLevelTaskList);
653 void UpdateManager::AddGesture( PanGesture* gesture )
655 DALI_ASSERT_DEBUG( NULL != gesture );
657 mImpl->gestures.PushBack( gesture );
660 void UpdateManager::RemoveGesture( PanGesture* gesture )
662 DALI_ASSERT_DEBUG( gesture != NULL );
664 GestureContainer& gestures = mImpl->gestures;
666 // Find the gesture and destroy it
667 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
669 PanGesture& current = **iter;
670 if ( ¤t == gesture )
672 mImpl->gestures.Erase( iter );
676 // Should not reach here
677 DALI_ASSERT_DEBUG(false);
680 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
682 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
685 void UpdateManager::EventProcessingStarted()
687 mImpl->messageQueue.EventProcessingStarted();
690 bool UpdateManager::FlushQueue()
692 return mImpl->messageQueue.FlushQueue();
695 void UpdateManager::ResetNodeProperty( Node& node )
697 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
699 node.ResetToBaseValues( bufferIndex );
702 void UpdateManager::ResetProperties()
704 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
706 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
708 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
709 mImpl->animationFinishedDuringUpdate = false;
711 // Animated properties have to be reset to their original value each frame
713 // Reset node properties
716 ResetNodeProperty( *mImpl->root );
719 if ( mImpl->systemLevelRoot )
721 ResetNodeProperty( *mImpl->systemLevelRoot );
724 // Reset the Connected Nodes
725 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
726 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
728 ResetNodeProperty( **iter );
731 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
732 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
735 node->ResetToBaseValues( bufferIndex );
736 node->SetActive( false );
738 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
739 mImpl->activeDisconnectedNodes.erase( iter );
740 mImpl->disconnectedNodes.insert( node );
743 // Reset system-level render-task list properties to base values
744 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
746 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
748 (*iter)->ResetToBaseValues( bufferIndex );
751 // Reset render-task list properties to base values.
752 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
754 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
756 (*iter)->ResetToBaseValues( bufferIndex );
759 // Reset custom object properties to base values
760 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
762 (*iter)->ResetToBaseValues( bufferIndex );
765 mImpl->materials.ResetToBaseValues( bufferIndex );
766 mImpl->geometries.ResetToBaseValues( bufferIndex );
767 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
768 mImpl->samplers.ResetToBaseValues( bufferIndex );
771 // Reset animatable shader properties to base values
772 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
774 (*iter)->ResetToBaseValues( bufferIndex );
777 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
780 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
782 bool gestureUpdated( false );
784 // constrain gestures... (in construction order)
785 GestureContainer& gestures = mImpl->gestures;
787 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
789 PanGesture& gesture = **iter;
790 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
791 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
794 return gestureUpdated;
797 void UpdateManager::Animate( float elapsedSeconds )
799 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
801 AnimationContainer &animations = mImpl->animations;
802 AnimationIter iter = animations.Begin();
803 while ( iter != animations.End() )
805 Animation* animation = *iter;
806 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
808 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
810 // Remove animations that had been destroyed but were still waiting for an update
811 if (animation->GetState() == Animation::Destroyed)
813 iter = animations.Erase(iter);
821 if ( mImpl->animationFinishedDuringUpdate )
823 // The application should be notified by NotificationManager, in another thread
824 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
827 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
830 void UpdateManager::ApplyConstraints()
832 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
834 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
836 // constrain custom objects... (in construction order)
837 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
839 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
840 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
842 PropertyOwner& object = **iter;
843 ConstrainPropertyOwner( object, bufferIndex );
846 // constrain nodes... (in Depth First traversal order)
849 ConstrainNodes( *(mImpl->root), bufferIndex );
852 if ( mImpl->systemLevelRoot )
854 ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
857 // constrain other property-owners after nodes as they are more likely to depend on a node's
858 // current frame property than vice versa. They tend to be final constraints (no further
859 // constraints depend on their properties)
860 // e.g. ShaderEffect uniform a function of Actor's position.
861 // Mesh vertex a function of Actor's position or world position.
863 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
864 // they can be all processed in a super-list of property-owners.
866 // Constrain system-level render-tasks
867 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
869 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
871 RenderTask& task = **iter;
872 ConstrainPropertyOwner( task, bufferIndex );
875 // Constrain render-tasks
876 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
878 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
880 RenderTask& task = **iter;
881 ConstrainPropertyOwner( task, bufferIndex );
884 // Constrain Materials and geometries
885 mImpl->materials.ConstrainObjects( bufferIndex );
886 mImpl->geometries.ConstrainObjects( bufferIndex );
887 mImpl->samplers.ConstrainObjects( bufferIndex );
888 mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
890 // constrain shaders... (in construction order)
891 ShaderContainer& shaders = mImpl->shaders;
893 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
895 Shader& shader = **iter;
896 ConstrainPropertyOwner( shader, bufferIndex );
899 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
902 void UpdateManager::ProcessPropertyNotifications()
904 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
905 PropertyNotificationIter iter = notifications.Begin();
907 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
909 while ( iter != notifications.End() )
911 PropertyNotification* notification = *iter;
912 bool valid = notification->Check( bufferIndex );
915 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
921 void UpdateManager::UpdateNodes()
923 mImpl->nodeDirtyFlags = NothingFlag;
930 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
932 // Prepare resources, update shaders, update attachments, for each node
933 // And add the renderers to the sorted layers. Start from root, which is also a layer
934 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
935 mSceneGraphBuffers.GetUpdateBufferIndex(),
936 mImpl->resourceManager,
937 mImpl->renderQueue );
939 if ( mImpl->systemLevelRoot )
941 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
942 mSceneGraphBuffers.GetUpdateBufferIndex(),
943 mImpl->resourceManager,
944 mImpl->renderQueue );
947 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
950 unsigned int UpdateManager::Update( float elapsedSeconds,
951 unsigned int lastVSyncTimeMilliseconds,
952 unsigned int nextVSyncTimeMilliseconds )
954 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
955 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
956 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
958 // Measure the time spent in UpdateManager::Update
959 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
961 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
963 // Update the frame time delta on the render thread.
964 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
966 // 1) Clear nodes/resources which were previously discarded
967 mImpl->discardQueue.Clear( bufferIndex );
969 // 2) Grab any loaded resources
970 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
972 // 3) Process Touches & Gestures
973 mImpl->touchResampler.Update();
974 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
976 const bool updateScene = // The scene-graph requires an update if..
977 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
978 IsAnimationRunning() || // ..at least one animation is running OR
979 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
980 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
981 resourceChanged || // ..one or more resources were updated/changed OR
982 gestureUpdated; // ..a gesture property was updated
984 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
985 // values if the scene was updated in the previous frame.
986 if( updateScene || mImpl->previousUpdateScene )
988 // 4) Reset properties from the previous update
992 // 5) Process the queued scene messages
993 mImpl->messageQueue.ProcessMessages();
995 // 6) Post Process Ids of resources updated by renderer
996 mImpl->resourceManager.PostProcessResources( bufferIndex );
998 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
999 // renderer lists if the scene was updated in the previous frame.
1000 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1001 if( updateScene || mImpl->previousUpdateScene )
1004 Animate( elapsedSeconds );
1006 // 8) Apply Constraints
1009 #ifdef DYNAMICS_SUPPORT
1010 // 9) Update dynamics simulation
1011 mImpl->dynamicsChanged = false;
1012 if( mImpl->dynamicsWorld )
1014 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1018 // 10) Check Property Notifications
1019 ProcessPropertyNotifications();
1021 // 11) Clear the lists of renderable-attachments from the previous update
1022 ClearRenderables( mImpl->sortedLayers );
1023 ClearRenderables( mImpl->systemLevelSortedLayers );
1025 // 12) Update node hierarchy and perform sorting / culling.
1026 // This will populate each Layer with a list of renderers which are ready.
1029 // 13) Prepare for the next render
1030 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1032 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1033 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1034 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1036 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1038 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1039 // reset the update buffer index and make sure there is enough room in the instruction container
1040 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1041 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1043 if ( NULL != mImpl->root )
1045 ProcessRenderTasks( bufferIndex,
1046 mImpl->completeStatusManager,
1049 mImpl->sortedLayers,
1050 mImpl->renderSortingHelper,
1051 mImpl->renderInstructions );
1053 // Process the system-level RenderTasks last
1054 if ( NULL != mImpl->systemLevelRoot )
1056 ProcessRenderTasks( bufferIndex,
1057 mImpl->completeStatusManager,
1058 mImpl->systemLevelTaskList,
1059 *mImpl->systemLevelRoot,
1060 mImpl->systemLevelSortedLayers,
1061 mImpl->renderSortingHelper,
1062 mImpl->renderInstructions );
1067 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1068 bool doRenderOnceNotify = false;
1069 mImpl->renderTaskWaiting = false;
1070 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1071 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1072 endIter != iter; ++iter )
1074 RenderTask& renderTask(*(*iter));
1076 renderTask.UpdateState();
1078 if( renderTask.IsWaitingToRender() &&
1079 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1081 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1084 if( renderTask.HasRendered() )
1086 doRenderOnceNotify = true;
1090 if( doRenderOnceNotify )
1092 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1093 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1096 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1098 // Macro is undefined in release build.
1099 SNAPSHOT_NODE_LOGGING;
1101 // A ResetProperties() may be required in the next frame
1102 mImpl->previousUpdateScene = updateScene;
1104 // Check whether further updates are required
1105 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1107 #ifdef PERFORMANCE_MONITOR_ENABLED
1108 // Always keep rendering when measuring FPS
1109 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1112 // The update has finished; swap the double-buffering indices
1113 mSceneGraphBuffers.Swap();
1115 // tell the update manager that we're done so the queue can be given to event thread
1116 mImpl->notificationManager.UpdateCompleted();
1118 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1120 return keepUpdating;
1123 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1125 // Update the duration set via Stage::KeepRendering()
1126 if ( mImpl->keepRenderingSeconds > 0.0f )
1128 mImpl->keepRenderingSeconds -= elapsedSeconds;
1131 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1133 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1134 // Keep updating until no messages are received and no animations are running.
1135 // If an animation has just finished, update at least once more for Discard end-actions.
1136 // No need to check for renderQueue as there is always a render after update and if that
1137 // render needs another update it will tell the adaptor to call update again
1139 if ( mImpl->keepRenderingSeconds > 0.0f )
1141 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1144 if ( IsAnimationRunning() ||
1145 mImpl->animationFinishedDuringUpdate )
1147 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1150 if ( mImpl->dynamicsChanged )
1152 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1155 if ( mImpl->renderTaskWaiting )
1157 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1160 return keepUpdatingRequest;
1163 void UpdateManager::SetBackgroundColor( const Vector4& color )
1165 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1167 // Reserve some memory inside the render queue
1168 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1170 // Construct message in the render queue memory; note that delete should not be called on the return value
1171 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1174 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1176 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1178 // Reserve some memory inside the render queue
1179 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1181 // Construct message in the render queue memory; note that delete should not be called on the return value
1182 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1185 void UpdateManager::KeepRendering( float durationSeconds )
1187 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1190 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1194 // just copy the vector of pointers
1195 mImpl->sortedLayers = layers;
1199 mImpl->systemLevelSortedLayers = layers;
1203 #ifdef DYNAMICS_SUPPORT
1205 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1207 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1208 mImpl->dynamicsWorld = dynamicsWorld;
1211 void UpdateManager::TerminateDynamicsWorld()
1213 mImpl->dynamicsWorld.Reset();
1216 #endif // DYNAMICS_SUPPORT
1218 } // namespace SceneGraph
1220 } // namespace Internal