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 EventToUpdate& UpdateManager::GetEventToUpdate()
340 return mImpl->messageQueue;
343 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
345 DALI_ASSERT_DEBUG( layer->IsLayer() );
346 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
350 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
355 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
356 mImpl->systemLevelRoot = layer;
359 layer->SetRoot(true);
362 void UpdateManager::AddNode( Node* node )
364 DALI_ASSERT_ALWAYS( NULL != node );
365 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
367 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
370 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
372 DALI_ASSERT_ALWAYS( NULL != parent );
373 DALI_ASSERT_ALWAYS( NULL != node );
374 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
376 // Move from active/disconnectedNodes to connectedNodes
377 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
380 removed = mImpl->disconnectedNodes.erase( node );
381 DALI_ASSERT_ALWAYS( removed );
383 mImpl->connectedNodes.insert( node );
385 node->SetActive( true );
387 parent->ConnectChild( node, index );
390 void UpdateManager::DisconnectNode( Node* node )
392 Node* parent = node->GetParent();
393 DALI_ASSERT_ALWAYS( NULL != parent );
394 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
396 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
397 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
400 void UpdateManager::SetNodeActive( Node* node )
402 DALI_ASSERT_ALWAYS( NULL != node );
403 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
405 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
406 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
407 DALI_ASSERT_ALWAYS( removed );
408 mImpl->activeDisconnectedNodes.insert( node );
410 node->SetActive( true );
413 void UpdateManager::DestroyNode( Node* node )
415 DALI_ASSERT_ALWAYS( NULL != node );
416 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
418 // Transfer ownership from new/disconnectedNodes to the discard queue
419 // This keeps the nodes alive, until the render-thread has finished with them
420 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
423 removed = mImpl->disconnectedNodes.erase( node );
424 DALI_ASSERT_ALWAYS( removed );
426 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
428 // Notify the Node about impending destruction
432 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
433 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
435 DALI_ASSERT_DEBUG( node != NULL );
436 DALI_ASSERT_DEBUG( attachment != NULL );
438 // attach node to attachment first so that parent is known by the time attachment is connected
439 node->Attach( *attachment ); // node takes ownership
440 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
443 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
445 renderer->AttachToSceneGraph( *(mImpl->sceneController), mSceneGraphBuffers.GetUpdateBufferIndex() );
448 void UpdateManager::AddObject( PropertyOwner* object )
450 DALI_ASSERT_DEBUG( NULL != object );
452 mImpl->customObjects.PushBack( object );
455 void UpdateManager::RemoveObject( PropertyOwner* object )
457 DALI_ASSERT_DEBUG( NULL != object );
459 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
461 // Find the object and destroy it
462 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
464 PropertyOwner* current = *iter;
465 if ( current == object )
467 customObjects.Erase( iter );
472 // Should not reach here
473 DALI_ASSERT_DEBUG(false);
476 void UpdateManager::AddAnimation( Animation* animation )
478 mImpl->animations.PushBack( animation );
481 void UpdateManager::StopAnimation( Animation* animation )
483 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
485 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
487 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
490 void UpdateManager::RemoveAnimation( Animation* animation )
492 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
494 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
496 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
499 bool UpdateManager::IsAnimationRunning() const
501 bool isRunning(false);
502 AnimationContainer& animations = mImpl->animations;
504 // Find any animation that isn't stopped or paused
506 const AnimationIter endIter = animations.End();
507 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
509 const Animation::State state = (*iter)->GetState();
511 if (state != Animation::Stopped &&
512 state != Animation::Paused)
521 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
523 mImpl->propertyNotifications.PushBack( propertyNotification );
526 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
528 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
529 PropertyNotificationIter iter = propertyNotifications.Begin();
531 while ( iter != propertyNotifications.End() )
533 if( *iter == propertyNotification )
535 propertyNotifications.Erase(iter);
542 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
544 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
545 propertyNotification->SetNotifyMode( notifyMode );
548 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
550 return mImpl->geometries;
553 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
555 return mImpl->materials;
558 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
560 return mImpl->samplers;
563 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
565 return mImpl->propertyBuffers;
568 void UpdateManager::AddShader( Shader* shader )
570 DALI_ASSERT_DEBUG( NULL != shader );
572 if( mImpl->shaders.Count() == 0 )
574 // the first added shader becomes our default shader
575 // Construct message in the render queue memory; note that delete should not be called on the return value
576 typedef MessageValue1< RenderManager, Shader* > DerivedType;
578 // Reserve some memory inside the render queue
579 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
581 // Construct message in the render queue memory; note that delete should not be called on the return value
582 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
585 mImpl->shaders.PushBack( shader );
587 // Allows the shader to dispatch texture requests to the cache
588 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
591 void UpdateManager::RemoveShader( Shader* shader )
593 DALI_ASSERT_DEBUG(shader != NULL);
595 ShaderContainer& shaders = mImpl->shaders;
597 // Find the shader and destroy it
598 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
600 Shader& current = **iter;
601 if ( ¤t == shader )
603 // Transfer ownership to the discard queue
604 // This keeps the shader alive, until the render-thread has finished with it
605 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
610 // Should not reach here
611 DALI_ASSERT_DEBUG(false);
614 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
616 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
618 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
620 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
623 shaderData->SetHashValue( shaderHash );
624 shaderData->SetResourceId( resourceId );
626 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
628 // Reserve some memory inside the render queue
629 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
631 // Construct message in the render queue memory; note that delete should not be called on the return value
632 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
636 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
640 // copy the list, this is only likely to happen once in application life cycle
641 return &(mImpl->taskList);
645 // copy the list, this is only likely to happen once in application life cycle
646 return &(mImpl->systemLevelTaskList);
650 void UpdateManager::AddGesture( PanGesture* gesture )
652 DALI_ASSERT_DEBUG( NULL != gesture );
654 mImpl->gestures.PushBack( gesture );
657 void UpdateManager::RemoveGesture( PanGesture* gesture )
659 DALI_ASSERT_DEBUG( gesture != NULL );
661 GestureContainer& gestures = mImpl->gestures;
663 // Find the gesture and destroy it
664 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
666 PanGesture& current = **iter;
667 if ( ¤t == gesture )
669 mImpl->gestures.Erase( iter );
673 // Should not reach here
674 DALI_ASSERT_DEBUG(false);
677 void UpdateManager::ResetNodeProperty( Node& node )
679 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
682 void UpdateManager::ResetProperties()
684 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
686 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
688 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
689 mImpl->animationFinishedDuringUpdate = false;
691 // Animated properties have to be reset to their original value each frame
693 // Reset node properties
696 ResetNodeProperty( *mImpl->root );
699 if ( mImpl->systemLevelRoot )
701 ResetNodeProperty( *mImpl->systemLevelRoot );
704 // Reset the Connected Nodes
705 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
706 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
708 ResetNodeProperty( **iter );
711 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
712 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
715 node->ResetToBaseValues( bufferIndex );
716 node->SetActive( false );
718 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
719 mImpl->activeDisconnectedNodes.erase( iter );
720 mImpl->disconnectedNodes.insert( node );
723 // Reset system-level render-task list properties to base values
724 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
726 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
728 (*iter)->ResetToBaseValues( bufferIndex );
731 // Reset render-task list properties to base values.
732 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
734 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
736 (*iter)->ResetToBaseValues( bufferIndex );
739 // Reset custom object properties to base values
740 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
742 (*iter)->ResetToBaseValues( bufferIndex );
745 mImpl->materials.ResetToBaseValues( bufferIndex );
746 mImpl->geometries.ResetToBaseValues( bufferIndex );
747 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
748 mImpl->samplers.ResetToBaseValues( bufferIndex );
751 // Reset animatable shader properties to base values
752 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
754 (*iter)->ResetToBaseValues( bufferIndex );
757 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
760 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
762 bool gestureUpdated( false );
764 // constrain gestures... (in construction order)
765 GestureContainer& gestures = mImpl->gestures;
767 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
769 PanGesture& gesture = **iter;
770 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
771 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
774 return gestureUpdated;
777 void UpdateManager::Animate( float elapsedSeconds )
779 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
781 AnimationContainer &animations = mImpl->animations;
782 AnimationIter iter = animations.Begin();
783 while ( iter != animations.End() )
785 Animation* animation = *iter;
786 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
788 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
790 // Remove animations that had been destroyed but were still waiting for an update
791 if (animation->GetState() == Animation::Destroyed)
793 iter = animations.Erase(iter);
801 if ( mImpl->animationFinishedDuringUpdate )
803 // The application should be notified by NotificationManager, in another thread
804 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
807 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
810 void UpdateManager::ApplyConstraints()
812 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
814 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
816 mImpl->activeConstraints = 0;
818 // constrain custom objects... (in construction order)
819 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
821 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
822 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
824 PropertyOwner& object = **iter;
825 mImpl->activeConstraints += ConstrainPropertyOwner( object, bufferIndex );
828 // constrain nodes... (in Depth First traversal order)
831 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), bufferIndex );
834 if ( mImpl->systemLevelRoot )
836 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
839 // constrain other property-owners after nodes as they are more likely to depend on a node's
840 // current frame property than vice versa. They tend to be final constraints (no further
841 // constraints depend on their properties)
842 // e.g. ShaderEffect uniform a function of Actor's position.
843 // Mesh vertex a function of Actor's position or world position.
845 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
846 // they can be all processed in a super-list of property-owners.
848 // Constrain system-level render-tasks
849 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
851 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
853 RenderTask& task = **iter;
854 mImpl->activeConstraints += ConstrainPropertyOwner( task, bufferIndex );
857 // Constrain render-tasks
858 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
860 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
862 RenderTask& task = **iter;
863 mImpl->activeConstraints += ConstrainPropertyOwner( task, bufferIndex );
866 // Constrain Materials and geometries
867 mImpl->activeConstraints += mImpl->materials.ConstrainObjects( bufferIndex );
868 mImpl->activeConstraints += mImpl->geometries.ConstrainObjects( bufferIndex );
869 mImpl->activeConstraints += mImpl->samplers.ConstrainObjects( bufferIndex );
870 mImpl->activeConstraints += mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
872 // constrain shaders... (in construction order)
873 ShaderContainer& shaders = mImpl->shaders;
875 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
877 Shader& shader = **iter;
878 mImpl->activeConstraints += ConstrainPropertyOwner( shader, bufferIndex );
881 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
884 void UpdateManager::ProcessPropertyNotifications()
886 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
887 PropertyNotificationIter iter = notifications.Begin();
889 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
891 while ( iter != notifications.End() )
893 PropertyNotification* notification = *iter;
894 bool valid = notification->Check( bufferIndex );
897 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
903 void UpdateManager::UpdateNodes()
905 mImpl->nodeDirtyFlags = NothingFlag;
912 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
914 // Prepare resources, update shaders, update attachments, for each node
915 // And add the renderers to the sorted layers. Start from root, which is also a layer
916 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
917 mSceneGraphBuffers.GetUpdateBufferIndex(),
918 mImpl->resourceManager,
919 mImpl->renderQueue );
921 if ( mImpl->systemLevelRoot )
923 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
924 mSceneGraphBuffers.GetUpdateBufferIndex(),
925 mImpl->resourceManager,
926 mImpl->renderQueue );
929 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
932 unsigned int UpdateManager::Update( float elapsedSeconds,
933 unsigned int lastVSyncTimeMilliseconds,
934 unsigned int nextVSyncTimeMilliseconds )
936 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
937 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
938 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
940 // Measure the time spent in UpdateManager::Update
941 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
943 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
945 // Update the frame time delta on the render thread.
946 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
948 // 1) Clear nodes/resources which were previously discarded
949 mImpl->discardQueue.Clear( bufferIndex );
951 // 2) Grab any loaded resources
952 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
954 // 3) Process Touches & Gestures
955 mImpl->touchResampler.Update();
956 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
958 const bool updateScene = // The scene-graph requires an update if..
959 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
960 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
961 IsAnimationRunning() || // ..at least one animation is running OR
962 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
963 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
964 resourceChanged || // ..one or more resources were updated/changed OR
965 gestureUpdated; // ..a gesture property was updated
967 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
968 // values if the scene was updated in the previous frame.
969 if( updateScene || mImpl->previousUpdateScene )
971 // 4) Reset properties from the previous update
975 // 5) Process the queued scene messages
976 mImpl->messageQueue.ProcessMessages();
978 // 6) Post Process Ids of resources updated by renderer
979 mImpl->resourceManager.PostProcessResources( bufferIndex );
981 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
982 // renderer lists if the scene was updated in the previous frame.
983 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
984 if( updateScene || mImpl->previousUpdateScene )
987 Animate( elapsedSeconds );
989 // 8) Apply Constraints
992 #ifdef DYNAMICS_SUPPORT
993 // 9) Update dynamics simulation
994 mImpl->dynamicsChanged = false;
995 if( mImpl->dynamicsWorld )
997 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1001 // 10) Check Property Notifications
1002 ProcessPropertyNotifications();
1004 // 11) Clear the lists of renderable-attachments from the previous update
1005 ClearRenderables( mImpl->sortedLayers );
1006 ClearRenderables( mImpl->systemLevelSortedLayers );
1008 // 12) Update node hierarchy and perform sorting / culling.
1009 // This will populate each Layer with a list of renderers which are ready.
1012 // 13) Prepare for the next render
1013 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1015 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1016 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1017 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1019 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1021 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1022 // reset the update buffer index and make sure there is enough room in the instruction container
1023 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1024 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1026 if ( NULL != mImpl->root )
1028 ProcessRenderTasks( bufferIndex,
1029 mImpl->completeStatusManager,
1032 mImpl->sortedLayers,
1033 mImpl->renderSortingHelper,
1034 mImpl->renderInstructions );
1036 // Process the system-level RenderTasks last
1037 if ( NULL != mImpl->systemLevelRoot )
1039 ProcessRenderTasks( bufferIndex,
1040 mImpl->completeStatusManager,
1041 mImpl->systemLevelTaskList,
1042 *mImpl->systemLevelRoot,
1043 mImpl->systemLevelSortedLayers,
1044 mImpl->renderSortingHelper,
1045 mImpl->renderInstructions );
1050 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1051 bool doRenderOnceNotify = false;
1052 mImpl->renderTaskWaiting = false;
1053 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1054 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1055 endIter != iter; ++iter )
1057 RenderTask& renderTask(*(*iter));
1059 renderTask.UpdateState();
1061 if( renderTask.IsWaitingToRender() &&
1062 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1064 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1067 if( renderTask.HasRendered() )
1069 doRenderOnceNotify = true;
1073 if( doRenderOnceNotify )
1075 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1076 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1079 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1081 // Macro is undefined in release build.
1082 SNAPSHOT_NODE_LOGGING;
1084 // A ResetProperties() may be required in the next frame
1085 mImpl->previousUpdateScene = updateScene;
1087 // Check whether further updates are required
1088 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1090 #ifdef PERFORMANCE_MONITOR_ENABLED
1091 // Always keep rendering when measuring FPS
1092 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1095 // The update has finished; swap the double-buffering indices
1096 mSceneGraphBuffers.Swap();
1098 // tell the update manager that we're done so the queue can be given to event thread
1099 mImpl->notificationManager.UpdateCompleted();
1101 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1103 return keepUpdating;
1106 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1108 // Update the duration set via Stage::KeepRendering()
1109 if ( mImpl->keepRenderingSeconds > 0.0f )
1111 mImpl->keepRenderingSeconds -= elapsedSeconds;
1114 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1116 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1117 // Keep updating until no messages are received and no animations are running.
1118 // If an animation has just finished, update at least once more for Discard end-actions.
1119 // No need to check for renderQueue as there is always a render after update and if that
1120 // render needs another update it will tell the adaptor to call update again
1122 if ( mImpl->keepRenderingSeconds > 0.0f )
1124 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1127 if ( !mImpl->messageQueue.WasEmpty() )
1129 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1132 if ( IsAnimationRunning() ||
1133 mImpl->animationFinishedDuringUpdate )
1135 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1138 if ( mImpl->dynamicsChanged )
1140 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1143 if ( mImpl->renderTaskWaiting )
1145 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1148 return keepUpdatingRequest;
1151 void UpdateManager::SetBackgroundColor( const Vector4& color )
1153 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1155 // Reserve some memory inside the render queue
1156 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1158 // Construct message in the render queue memory; note that delete should not be called on the return value
1159 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1162 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1164 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1166 // Reserve some memory inside the render queue
1167 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1169 // Construct message in the render queue memory; note that delete should not be called on the return value
1170 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1173 void UpdateManager::KeepRendering( float durationSeconds )
1175 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1178 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1182 // just copy the vector of pointers
1183 mImpl->sortedLayers = layers;
1187 mImpl->systemLevelSortedLayers = layers;
1191 #ifdef DYNAMICS_SUPPORT
1193 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1195 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1196 mImpl->dynamicsWorld = dynamicsWorld;
1199 void UpdateManager::TerminateDynamicsWorld()
1201 mImpl->dynamicsWorld.Reset();
1204 #endif // DYNAMICS_SUPPORT
1206 } // namespace SceneGraph
1208 } // namespace Internal