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/node-attachments/scene-graph-image-attachment.h>
58 #include <dali/internal/update/nodes/node.h>
59 #include <dali/internal/update/nodes/scene-graph-layer.h>
60 #include <dali/internal/update/queue/update-message-queue.h>
61 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
62 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.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, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
618 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
620 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
622 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
625 shaderData->SetHashValue( shaderHash );
626 shaderData->SetResourceId( resourceId );
628 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
630 // Reserve some memory inside the render queue
631 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
633 // Construct message in the render queue memory; note that delete should not be called on the return value
634 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
638 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
642 // copy the list, this is only likely to happen once in application life cycle
643 return &(mImpl->taskList);
647 // copy the list, this is only likely to happen once in application life cycle
648 return &(mImpl->systemLevelTaskList);
652 void UpdateManager::AddGesture( PanGesture* gesture )
654 DALI_ASSERT_DEBUG( NULL != gesture );
656 mImpl->gestures.PushBack( gesture );
659 void UpdateManager::RemoveGesture( PanGesture* gesture )
661 DALI_ASSERT_DEBUG( gesture != NULL );
663 GestureContainer& gestures = mImpl->gestures;
665 // Find the gesture and destroy it
666 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
668 PanGesture& current = **iter;
669 if ( ¤t == gesture )
671 mImpl->gestures.Erase( iter );
675 // Should not reach here
676 DALI_ASSERT_DEBUG(false);
679 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
681 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
684 void UpdateManager::EventProcessingStarted()
686 mImpl->messageQueue.EventProcessingStarted();
689 bool UpdateManager::FlushQueue()
691 return mImpl->messageQueue.FlushQueue();
694 void UpdateManager::ResetNodeProperty( Node& node )
696 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
698 node.ResetToBaseValues( bufferIndex );
700 // @todo MESH_REWORK Only perform this step for RendererAttachments - consider
701 // storing them again? Split out to separate scene graph object owned by UpdateManager
702 // It is after all, a property owner, and always requires resetting...
703 // The depth index should not be an animatable property... and probably not even
704 // a constraint input? (Double buffering will slow down the sort algorithm slightly)
705 if( node.HasAttachment() )
707 node.GetAttachment().ResetToBaseValues( bufferIndex );
711 void UpdateManager::ResetProperties()
713 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
715 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
717 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
718 mImpl->animationFinishedDuringUpdate = false;
720 // Animated properties have to be reset to their original value each frame
722 // Reset node properties
725 ResetNodeProperty( *mImpl->root );
728 if ( mImpl->systemLevelRoot )
730 ResetNodeProperty( *mImpl->systemLevelRoot );
733 // Reset the Connected Nodes
734 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
735 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
737 ResetNodeProperty( **iter );
740 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
741 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
744 node->ResetToBaseValues( bufferIndex );
745 node->SetActive( false );
747 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
748 mImpl->activeDisconnectedNodes.erase( iter );
749 mImpl->disconnectedNodes.insert( node );
752 // Reset system-level render-task list properties to base values
753 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
755 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
757 (*iter)->ResetToBaseValues( bufferIndex );
760 // Reset render-task list properties to base values.
761 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
763 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
765 (*iter)->ResetToBaseValues( bufferIndex );
768 // Reset custom object properties to base values
769 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
771 (*iter)->ResetToBaseValues( bufferIndex );
774 mImpl->materials.ResetToBaseValues( bufferIndex );
775 mImpl->geometries.ResetToBaseValues( bufferIndex );
776 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
777 mImpl->samplers.ResetToBaseValues( bufferIndex );
780 // Reset animatable shader properties to base values
781 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
783 (*iter)->ResetToBaseValues( bufferIndex );
786 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
789 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
791 bool gestureUpdated( false );
793 // constrain gestures... (in construction order)
794 GestureContainer& gestures = mImpl->gestures;
796 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
798 PanGesture& gesture = **iter;
799 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
800 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
803 return gestureUpdated;
806 void UpdateManager::Animate( float elapsedSeconds )
808 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
810 AnimationContainer &animations = mImpl->animations;
811 AnimationIter iter = animations.Begin();
812 while ( iter != animations.End() )
814 Animation* animation = *iter;
815 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
817 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
819 // Remove animations that had been destroyed but were still waiting for an update
820 if (animation->GetState() == Animation::Destroyed)
822 iter = animations.Erase(iter);
830 if ( mImpl->animationFinishedDuringUpdate )
832 // The application should be notified by NotificationManager, in another thread
833 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
836 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
839 void UpdateManager::ApplyConstraints()
841 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
843 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
845 // constrain custom objects... (in construction order)
846 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
848 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
849 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
851 PropertyOwner& object = **iter;
852 ConstrainPropertyOwner( object, bufferIndex );
855 // constrain nodes... (in Depth First traversal order)
858 ConstrainNodes( *(mImpl->root), bufferIndex );
861 if ( mImpl->systemLevelRoot )
863 ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
866 // constrain other property-owners after nodes as they are more likely to depend on a node's
867 // current frame property than vice versa. They tend to be final constraints (no further
868 // constraints depend on their properties)
869 // e.g. ShaderEffect uniform a function of Actor's position.
870 // Mesh vertex a function of Actor's position or world position.
872 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
873 // they can be all processed in a super-list of property-owners.
875 // Constrain system-level render-tasks
876 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
878 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
880 RenderTask& task = **iter;
881 ConstrainPropertyOwner( task, bufferIndex );
884 // Constrain render-tasks
885 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
887 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
889 RenderTask& task = **iter;
890 ConstrainPropertyOwner( task, bufferIndex );
893 // Constrain Materials and geometries
894 mImpl->materials.ConstrainObjects( bufferIndex );
895 mImpl->geometries.ConstrainObjects( bufferIndex );
896 mImpl->samplers.ConstrainObjects( bufferIndex );
897 mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
899 // constrain shaders... (in construction order)
900 ShaderContainer& shaders = mImpl->shaders;
902 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
904 Shader& shader = **iter;
905 ConstrainPropertyOwner( shader, bufferIndex );
908 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
911 void UpdateManager::ProcessPropertyNotifications()
913 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
914 PropertyNotificationIter iter = notifications.Begin();
916 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
918 while ( iter != notifications.End() )
920 PropertyNotification* notification = *iter;
921 bool valid = notification->Check( bufferIndex );
924 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
930 void UpdateManager::UpdateNodes()
932 mImpl->nodeDirtyFlags = NothingFlag;
939 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
941 // Prepare resources, update shaders, update attachments, for each node
942 // And add the renderers to the sorted layers. Start from root, which is also a layer
943 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
944 mSceneGraphBuffers.GetUpdateBufferIndex(),
945 mImpl->resourceManager,
946 mImpl->renderQueue );
948 if ( mImpl->systemLevelRoot )
950 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
951 mSceneGraphBuffers.GetUpdateBufferIndex(),
952 mImpl->resourceManager,
953 mImpl->renderQueue );
956 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
959 unsigned int UpdateManager::Update( float elapsedSeconds,
960 unsigned int lastVSyncTimeMilliseconds,
961 unsigned int nextVSyncTimeMilliseconds )
963 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
964 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
965 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
967 // Measure the time spent in UpdateManager::Update
968 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
970 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
972 // Update the frame time delta on the render thread.
973 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
975 // 1) Clear nodes/resources which were previously discarded
976 mImpl->discardQueue.Clear( bufferIndex );
978 // 2) Grab any loaded resources
979 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
981 // 3) Process Touches & Gestures
982 mImpl->touchResampler.Update();
983 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
985 const bool updateScene = // The scene-graph requires an update if..
986 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
987 IsAnimationRunning() || // ..at least one animation is running OR
988 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
989 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
990 resourceChanged || // ..one or more resources were updated/changed OR
991 gestureUpdated; // ..a gesture property was updated
993 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
994 // values if the scene was updated in the previous frame.
995 if( updateScene || mImpl->previousUpdateScene )
997 // 4) Reset properties from the previous update
1001 // 5) Process the queued scene messages
1002 mImpl->messageQueue.ProcessMessages();
1004 // 6) Post Process Ids of resources updated by renderer
1005 mImpl->resourceManager.PostProcessResources( bufferIndex );
1007 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1008 // renderer lists if the scene was updated in the previous frame.
1009 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1010 if( updateScene || mImpl->previousUpdateScene )
1013 Animate( elapsedSeconds );
1015 // 8) Apply Constraints
1018 #ifdef DYNAMICS_SUPPORT
1019 // 9) Update dynamics simulation
1020 mImpl->dynamicsChanged = false;
1021 if( mImpl->dynamicsWorld )
1023 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1027 // 10) Check Property Notifications
1028 ProcessPropertyNotifications();
1030 // 11) Clear the lists of renderable-attachments from the previous update
1031 ClearRenderables( mImpl->sortedLayers );
1032 ClearRenderables( mImpl->systemLevelSortedLayers );
1034 // 12) Update node hierarchy and perform sorting / culling.
1035 // This will populate each Layer with a list of renderers which are ready.
1038 // 13) Prepare for the next render
1039 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1041 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1042 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1043 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1045 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1047 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1048 // reset the update buffer index and make sure there is enough room in the instruction container
1049 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1050 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1052 if ( NULL != mImpl->root )
1054 ProcessRenderTasks( bufferIndex,
1055 mImpl->completeStatusManager,
1058 mImpl->sortedLayers,
1059 mImpl->renderSortingHelper,
1060 mImpl->renderInstructions );
1062 // Process the system-level RenderTasks last
1063 if ( NULL != mImpl->systemLevelRoot )
1065 ProcessRenderTasks( bufferIndex,
1066 mImpl->completeStatusManager,
1067 mImpl->systemLevelTaskList,
1068 *mImpl->systemLevelRoot,
1069 mImpl->systemLevelSortedLayers,
1070 mImpl->renderSortingHelper,
1071 mImpl->renderInstructions );
1076 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1077 bool doRenderOnceNotify = false;
1078 mImpl->renderTaskWaiting = false;
1079 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1080 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1081 endIter != iter; ++iter )
1083 RenderTask& renderTask(*(*iter));
1085 renderTask.UpdateState();
1087 if( renderTask.IsWaitingToRender() &&
1088 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1090 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1093 if( renderTask.HasRendered() )
1095 doRenderOnceNotify = true;
1099 if( doRenderOnceNotify )
1101 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1102 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1105 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1107 // Macro is undefined in release build.
1108 SNAPSHOT_NODE_LOGGING;
1110 // A ResetProperties() may be required in the next frame
1111 mImpl->previousUpdateScene = updateScene;
1113 // Check whether further updates are required
1114 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1116 #ifdef PERFORMANCE_MONITOR_ENABLED
1117 // Always keep rendering when measuring FPS
1118 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1121 // The update has finished; swap the double-buffering indices
1122 mSceneGraphBuffers.Swap();
1124 // tell the update manager that we're done so the queue can be given to event thread
1125 mImpl->notificationManager.UpdateCompleted();
1127 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1129 return keepUpdating;
1132 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1134 // Update the duration set via Stage::KeepRendering()
1135 if ( mImpl->keepRenderingSeconds > 0.0f )
1137 mImpl->keepRenderingSeconds -= elapsedSeconds;
1140 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1142 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1143 // Keep updating until no messages are received and no animations are running.
1144 // If an animation has just finished, update at least once more for Discard end-actions.
1145 // No need to check for renderQueue as there is always a render after update and if that
1146 // render needs another update it will tell the adaptor to call update again
1148 if ( mImpl->keepRenderingSeconds > 0.0f )
1150 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1153 if ( IsAnimationRunning() ||
1154 mImpl->animationFinishedDuringUpdate )
1156 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1159 if ( mImpl->dynamicsChanged )
1161 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1164 if ( mImpl->renderTaskWaiting )
1166 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1169 return keepUpdatingRequest;
1172 void UpdateManager::SetBackgroundColor( const Vector4& color )
1174 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1176 // Reserve some memory inside the render queue
1177 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1179 // Construct message in the render queue memory; note that delete should not be called on the return value
1180 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1183 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1185 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1187 // Reserve some memory inside the render queue
1188 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1190 // Construct message in the render queue memory; note that delete should not be called on the return value
1191 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1194 void UpdateManager::KeepRendering( float durationSeconds )
1196 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1199 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1203 // just copy the vector of pointers
1204 mImpl->sortedLayers = layers;
1208 mImpl->systemLevelSortedLayers = layers;
1212 #ifdef DYNAMICS_SUPPORT
1214 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1216 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1217 mImpl->dynamicsWorld = dynamicsWorld;
1220 void UpdateManager::TerminateDynamicsWorld()
1222 mImpl->dynamicsWorld.Reset();
1225 #endif // DYNAMICS_SUPPORT
1227 } // namespace SceneGraph
1229 } // namespace Internal