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/double-buffered.h>
42 #include <dali/internal/update/manager/prepare-render-algorithms.h>
43 #include <dali/internal/update/manager/process-render-tasks.h>
44 #include <dali/internal/update/resources/resource-manager.h>
45 #include <dali/internal/update/resources/complete-status-manager.h>
46 #include <dali/internal/update/common/scene-graph-buffers.h>
47 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
48 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/queue/update-message-queue.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/controllers/render-message-dispatcher.h>
54 #include <dali/internal/update/controllers/scene-controller-impl.h>
55 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
56 #include <dali/internal/update/modeling/scene-graph-material.h>
57 #include <dali/internal/update/node-attachments/scene-graph-camera-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/touch/touch-resampler.h>
62 #include <dali/internal/render/common/render-instruction-container.h>
63 #include <dali/internal/render/common/render-manager.h>
64 #include <dali/internal/render/queue/render-queue.h>
65 #include <dali/internal/render/common/performance-monitor.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/renderers/render-material.h>
68 #include <dali/internal/render/shaders/shader.h>
70 #ifdef DYNAMICS_SUPPORT
71 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
72 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
75 // Un-comment to enable node tree debug logging
76 //#define NODE_TREE_LOGGING 1
78 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
79 #define SNAPSHOT_NODE_LOGGING \
80 const int FRAME_COUNT_TRIGGER = 16;\
81 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
83 if ( NULL != mImpl->root )\
85 mImpl->frameCounter = 0;\
86 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
89 mImpl->frameCounter++;
91 #define SNAPSHOT_NODE_LOGGING
94 #if defined(DEBUG_ENABLED)
95 extern Debug::Filter* gRenderTaskLogFilter;
99 using namespace Dali::Integration;
100 using Dali::Internal::Update::MessageQueue;
114 const int DEFAULT_CAMERA_INDEX = -1;
116 void DestroyNodeSet( std::set<Node*>& nodeSet )
118 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
122 // Call Node::OnDestroy as each node is destroyed
132 typedef OwnerContainer< Shader* > ShaderContainer;
133 typedef ShaderContainer::Iterator ShaderIter;
134 typedef ShaderContainer::ConstIterator ShaderConstIter;
136 typedef AnimatableMeshContainer::Iterator AnimatableMeshIter;
137 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
138 typedef MaterialContainer::Iterator MaterialIter;
140 typedef OwnerContainer<PanGesture*> GestureContainer;
141 typedef GestureContainer::Iterator GestureIter;
142 typedef GestureContainer::ConstIterator GestureConstIter;
146 * Structure to contain UpdateManager internal data
148 struct UpdateManager::Impl
150 Impl( NotificationManager& notificationManager,
151 GlSyncAbstraction& glSyncAbstraction,
152 CompleteNotificationInterface& animationFinishedNotifier,
153 PropertyNotifier& propertyNotifier,
154 ResourceManager& resourceManager,
155 DiscardQueue& discardQueue,
156 RenderController& renderController,
157 RenderManager& renderManager,
158 RenderQueue& renderQueue,
159 TextureCache& textureCache,
160 TouchResampler& touchResampler,
161 SceneGraphBuffers& sceneGraphBuffers )
163 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
164 notificationManager( notificationManager ),
165 animationFinishedNotifier( animationFinishedNotifier ),
166 propertyNotifier( propertyNotifier ),
167 resourceManager( resourceManager ),
168 discardQueue( discardQueue ),
169 renderController( renderController ),
170 sceneController( NULL ),
171 renderManager( renderManager ),
172 renderQueue( renderQueue ),
173 renderInstructions( renderManager.GetRenderInstructionContainer() ),
174 completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
175 touchResampler( touchResampler ),
176 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
177 taskList ( completeStatusManager ),
178 systemLevelTaskList ( completeStatusManager ),
180 systemLevelRoot( NULL ),
181 messageQueue( renderController, sceneGraphBuffers ),
182 dynamicsChanged( false ),
183 keepRenderingSeconds( 0.0f ),
184 animationFinishedDuringUpdate( false ),
185 activeConstraints( 0 ),
186 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
187 previousUpdateScene( false ),
189 renderSortingHelper(),
190 renderTaskWaiting( false )
192 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
197 // Disconnect render tasks from nodes, before destroying the nodes
198 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
199 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
201 (*iter)->SetSourceNode( NULL );
203 // ..repeat for system level RenderTasks
204 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
205 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
207 (*iter)->SetSourceNode( NULL );
210 // UpdateManager owns the Nodes
211 DestroyNodeSet( activeDisconnectedNodes );
212 DestroyNodeSet( connectedNodes );
213 DestroyNodeSet( disconnectedNodes );
215 // If there is root, reset it, otherwise do nothing as rendering was never started
224 if( systemLevelRoot )
226 systemLevelRoot->OnDestroy();
228 delete systemLevelRoot;
229 systemLevelRoot = NULL;
232 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
233 delete sceneController;
236 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
237 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
238 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
239 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
240 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
241 ResourceManager& resourceManager; ///< resource manager
242 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
243 RenderController& renderController; ///< render controller
244 SceneControllerImpl* sceneController; ///< scene controller
245 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
246 RenderQueue& renderQueue; ///< Used to queue messages for the next render
247 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
248 CompleteStatusManager completeStatusManager; ///< Complete Status Manager
249 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
251 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
253 RenderTaskList taskList; ///< The list of scene graph render-tasks
254 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
256 Layer* root; ///< The root node (root is a layer)
257 Layer* systemLevelRoot; ///< A separate root-node for system-level content
258 std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
259 std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
260 std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
262 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
263 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
265 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
267 AnimationContainer animations; ///< A container of owned animations
268 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
270 ShaderContainer shaders; ///< A container of owned shaders
271 AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes
272 MaterialContainer materials; ///< A container of owned materials
274 MessageQueue messageQueue; ///< The messages queued from the event-thread
276 #ifdef DYNAMICS_SUPPORT
277 OwnerPointer<DynamicsWorld> dynamicsWorld; ///< Wrapper for dynamics simulation
279 bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick
281 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
282 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
284 unsigned int activeConstraints; ///< number of active constraints from previous frame
285 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
286 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
288 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
289 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
291 GestureContainer gestures; ///< A container of owned gesture detectors
292 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
295 UpdateManager::UpdateManager( NotificationManager& notificationManager,
296 GlSyncAbstraction& glSyncAbstraction,
297 CompleteNotificationInterface& animationFinishedNotifier,
298 PropertyNotifier& propertyNotifier,
299 ResourceManager& resourceManager,
300 DiscardQueue& discardQueue,
301 RenderController& controller,
302 RenderManager& renderManager,
303 RenderQueue& renderQueue,
304 TextureCache& textureCache,
305 TouchResampler& touchResampler )
308 mImpl = new Impl( notificationManager,
310 animationFinishedNotifier,
319 mSceneGraphBuffers );
321 textureCache.SetBufferIndices( &mSceneGraphBuffers );
324 UpdateManager::~UpdateManager()
329 EventToUpdate& UpdateManager::GetEventToUpdate()
331 return mImpl->messageQueue;
334 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
336 DALI_ASSERT_DEBUG( layer->IsLayer() );
337 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
341 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
346 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
347 mImpl->systemLevelRoot = layer;
350 layer->SetRoot(true);
353 void UpdateManager::AddNode( Node* node )
355 DALI_ASSERT_ALWAYS( NULL != node );
356 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
358 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
361 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
363 DALI_ASSERT_ALWAYS( NULL != parent );
364 DALI_ASSERT_ALWAYS( NULL != node );
365 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
367 // Move from active/disconnectedNodes to connectedNodes
368 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
371 removed = mImpl->disconnectedNodes.erase( node );
372 DALI_ASSERT_ALWAYS( removed );
374 mImpl->connectedNodes.insert( node );
376 node->SetActive( true );
378 parent->ConnectChild( node, index );
381 void UpdateManager::DisconnectNode( Node* node )
383 Node* parent = node->GetParent();
384 DALI_ASSERT_ALWAYS( NULL != parent );
385 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
387 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
388 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
391 void UpdateManager::SetNodeActive( Node* node )
393 DALI_ASSERT_ALWAYS( NULL != node );
394 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
396 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
397 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
398 DALI_ASSERT_ALWAYS( removed );
399 mImpl->activeDisconnectedNodes.insert( node );
401 node->SetActive( true );
404 void UpdateManager::DestroyNode( Node* node )
406 DALI_ASSERT_ALWAYS( NULL != node );
407 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
409 // Transfer ownership from new/disconnectedNodes to the discard queue
410 // This keeps the nodes alive, until the render-thread has finished with them
411 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
414 removed = mImpl->disconnectedNodes.erase( node );
415 DALI_ASSERT_ALWAYS( removed );
417 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
419 // Notify the Node about impending destruction
423 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
425 DALI_ASSERT_DEBUG( node != NULL );
426 DALI_ASSERT_DEBUG( attachment != NULL );
428 // attach node to attachment first so that parent is known by the time attachment is connected
429 node->Attach( *attachment ); // node takes ownership
430 attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
433 void UpdateManager::AddObject( PropertyOwner* object )
435 DALI_ASSERT_DEBUG( NULL != object );
437 mImpl->customObjects.PushBack( object );
440 void UpdateManager::RemoveObject( PropertyOwner* object )
442 DALI_ASSERT_DEBUG( NULL != object );
444 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
446 // Find the object and destroy it
447 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
449 PropertyOwner* current = *iter;
450 if ( current == object )
452 customObjects.Erase( iter );
457 // Should not reach here
458 DALI_ASSERT_DEBUG(false);
461 void UpdateManager::AddAnimation( Animation* animation )
463 mImpl->animations.PushBack( animation );
466 void UpdateManager::StopAnimation( Animation* animation )
468 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
470 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
472 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
475 void UpdateManager::RemoveAnimation( Animation* animation )
477 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
479 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
481 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
484 bool UpdateManager::IsAnimationRunning() const
486 bool isRunning(false);
487 AnimationContainer& animations = mImpl->animations;
489 // Find any animation that isn't stopped or paused
491 const AnimationIter endIter = animations.End();
492 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
494 const Animation::State state = (*iter)->GetState();
496 if (state != Animation::Stopped &&
497 state != Animation::Paused)
506 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
508 mImpl->propertyNotifications.PushBack( propertyNotification );
511 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
513 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
514 PropertyNotificationIter iter = propertyNotifications.Begin();
516 while ( iter != propertyNotifications.End() )
518 if( *iter == propertyNotification )
520 propertyNotifications.Erase(iter);
527 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
529 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
530 propertyNotification->SetNotifyMode( notifyMode );
533 void UpdateManager::AddShader( Shader* shader )
535 DALI_ASSERT_DEBUG( NULL != shader );
537 if( mImpl->shaders.Count() == 0 )
539 // the first added shader becomes our default shader
540 // Construct message in the render queue memory; note that delete should not be called on the return value
541 typedef MessageValue1< RenderManager, Shader* > DerivedType;
543 // Reserve some memory inside the render queue
544 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
546 // Construct message in the render queue memory; note that delete should not be called on the return value
547 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
550 mImpl->shaders.PushBack( shader );
552 // Allows the shader to dispatch texture requests to the cache
553 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
556 void UpdateManager::RemoveShader(Shader* shader)
558 DALI_ASSERT_DEBUG(shader != NULL);
560 ShaderContainer& shaders = mImpl->shaders;
562 // Find the shader and destroy it
563 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
565 Shader& current = **iter;
566 if ( ¤t == shader )
568 // Transfer ownership to the discard queue
569 // This keeps the shader alive, until the render-thread has finished with it
570 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
575 // Should not reach here
576 DALI_ASSERT_DEBUG(false);
579 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
581 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
583 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
585 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
588 shaderData->SetHashValue( shaderHash );
589 shaderData->SetResourceId( resourceId );
591 typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
593 // Reserve some memory inside the render queue
594 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
596 // Construct message in the render queue memory; note that delete should not be called on the return value
597 new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
601 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
603 mImpl->animatableMeshes.PushBack(animatableMesh);
606 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
608 DALI_ASSERT_DEBUG(animatableMesh != NULL);
610 AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
612 // Find the animatableMesh and destroy it
613 for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
615 AnimatableMesh& current = **iter;
616 if ( ¤t == animatableMesh )
618 animatableMeshes.Erase( iter );
624 void UpdateManager::AddMaterial( Material* material )
626 DALI_ASSERT_DEBUG( NULL != material );
628 mImpl->materials.PushBack( material );
629 RenderMaterial* renderMaterial = new RenderMaterial();
631 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
633 // Reserve some memory inside the render queue
634 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
636 // Construct message in the render queue memory; note that delete should not be called on the return value
637 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
639 material->SetRenderMaterial( renderMaterial );
640 material->OnStageConnection( *mImpl->sceneController );
643 void UpdateManager::RemoveMaterial( Material* theMaterial )
645 // Caused by last reference to material being released (e.g. app or internal mesh-actor)
647 for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
649 const Material* aMaterial = *iter;
651 if( aMaterial == theMaterial )
653 typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
655 // Reserve some memory inside the render queue
656 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
658 // Construct message in the render queue memory; note that delete should not be called on the return value
659 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
661 mImpl->materials.Erase( iter );
667 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
671 // copy the list, this is only likely to happen once in application life cycle
672 return &(mImpl->taskList);
676 // copy the list, this is only likely to happen once in application life cycle
677 return &(mImpl->systemLevelTaskList);
681 void UpdateManager::AddGesture( PanGesture* gesture )
683 DALI_ASSERT_DEBUG( NULL != gesture );
685 mImpl->gestures.PushBack( gesture );
688 void UpdateManager::RemoveGesture( PanGesture* gesture )
690 DALI_ASSERT_DEBUG( gesture != NULL );
692 GestureContainer& gestures = mImpl->gestures;
694 // Find the gesture and destroy it
695 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
697 PanGesture& current = **iter;
698 if ( ¤t == gesture )
700 mImpl->gestures.Erase( iter );
704 // Should not reach here
705 DALI_ASSERT_DEBUG(false);
708 void UpdateManager::ResetNodeProperty( Node& node )
710 node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
713 void UpdateManager::ResetProperties()
715 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
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( mSceneGraphBuffers.GetUpdateBufferIndex() );
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( mSceneGraphBuffers.GetUpdateBufferIndex() );
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( mSceneGraphBuffers.GetUpdateBufferIndex() );
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( mSceneGraphBuffers.GetUpdateBufferIndex() );
774 // Reset animatable shader properties to base values
775 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
777 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
780 // Reset animatable mesh properties to base values
781 for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
783 (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
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 mImpl->activeConstraints = 0;
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 mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
855 // constrain nodes... (in Depth First traversal order)
858 mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
861 if ( mImpl->systemLevelRoot )
863 mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
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 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
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 mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
893 // constrain meshes (in construction order)
894 AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
895 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
897 AnimatableMesh& mesh = **iter;
898 mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
901 // constrain shaders... (in construction order)
902 ShaderContainer& shaders = mImpl->shaders;
904 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
906 Shader& shader = **iter;
907 mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
910 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
913 void UpdateManager::ProcessPropertyNotifications()
915 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
916 PropertyNotificationIter iter = notifications.Begin();
918 while ( iter != notifications.End() )
920 PropertyNotification* notification = *iter;
922 bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
926 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
932 void UpdateManager::UpdateNodes()
934 mImpl->nodeDirtyFlags = NothingFlag;
941 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
943 // Prepare resources, update shaders, update attachments, for each node
944 // And add the renderers to the sorted layers. Start from root, which is also a layer
945 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
946 mSceneGraphBuffers.GetUpdateBufferIndex(),
947 mImpl->resourceManager,
948 mImpl->renderQueue );
950 if ( mImpl->systemLevelRoot )
952 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
953 mSceneGraphBuffers.GetUpdateBufferIndex(),
954 mImpl->resourceManager,
955 mImpl->renderQueue );
958 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
961 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
963 for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
965 AnimatableMesh& current = **iter;
966 current.UpdateMesh( updateBufferIndex );
970 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
972 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
974 Material* material = *iter;
975 material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
979 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
981 for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
983 Material* material = *iter;
984 material->PrepareRender( updateBufferIndex );
988 unsigned int UpdateManager::Update( float elapsedSeconds,
989 unsigned int lastVSyncTimeMilliseconds,
990 unsigned int nextVSyncTimeMilliseconds )
992 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
993 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
994 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
996 // Measure the time spent in UpdateManager::Update
997 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
999 // Update the frame time delta on the render thread.
1000 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1002 // 1) Clear nodes/resources which were previously discarded
1003 mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1005 // 2) Grab any loaded resources
1006 bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1008 // 3) Process Touches & Gestures
1009 mImpl->touchResampler.Update();
1010 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1012 const bool updateScene = // The scene-graph requires an update if..
1013 mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR
1014 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1015 IsAnimationRunning() || // ..at least one animation is running OR
1016 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
1017 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
1018 resourceChanged || // ..one or more resources were updated/changed OR
1019 gestureUpdated; // ..a gesture property was updated
1021 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1022 // values if the scene was updated in the previous frame.
1023 if( updateScene || mImpl->previousUpdateScene )
1025 // 4) Reset properties from the previous update
1029 // 5) Process the queued scene messages
1030 mImpl->messageQueue.ProcessMessages();
1032 // 6) Post Process Ids of resources updated by renderer
1033 mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1035 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1036 // renderer lists if the scene was updated in the previous frame.
1037 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1038 if( updateScene || mImpl->previousUpdateScene )
1041 Animate( elapsedSeconds );
1043 // 8) Apply Constraints
1046 #ifdef DYNAMICS_SUPPORT
1047 // 9) Update dynamics simulation
1048 mImpl->dynamicsChanged = false;
1049 if( mImpl->dynamicsWorld )
1051 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1055 // 10) Check Property Notifications
1056 ProcessPropertyNotifications();
1058 // 11) Clear the lists of renderable-attachments from the previous update
1059 ClearRenderables( mImpl->sortedLayers );
1060 ClearRenderables( mImpl->systemLevelSortedLayers );
1062 // 12) Update animated meshes
1063 UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1065 // 13) Update materials. Prepares image resources
1066 UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1068 // 14) Update node hierarchy and perform sorting / culling.
1069 // This will populate each Layer with a list of renderers which are ready.
1072 // 15) Prepare for the next render
1073 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1074 PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1075 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1076 PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1077 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1079 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1081 // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1082 // reset the update buffer index and make sure there is enough room in the instruction container
1083 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1084 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1086 if ( NULL != mImpl->root )
1088 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1089 mImpl->completeStatusManager,
1092 mImpl->sortedLayers,
1093 mImpl->renderSortingHelper,
1094 mImpl->renderInstructions );
1096 // Process the system-level RenderTasks last
1097 if ( NULL != mImpl->systemLevelRoot )
1099 ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(),
1100 mImpl->completeStatusManager,
1101 mImpl->systemLevelTaskList,
1102 *mImpl->systemLevelRoot,
1103 mImpl->systemLevelSortedLayers,
1104 mImpl->renderSortingHelper,
1105 mImpl->renderInstructions );
1110 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1111 bool doRenderOnceNotify = false;
1112 mImpl->renderTaskWaiting = false;
1113 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1114 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1115 endIter != iter; ++iter )
1117 RenderTask& renderTask(*(*iter));
1119 renderTask.UpdateState();
1121 if( renderTask.IsWaitingToRender() &&
1122 renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1124 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1127 if( renderTask.HasRendered() )
1129 doRenderOnceNotify = true;
1133 if( doRenderOnceNotify )
1135 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1136 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1139 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1141 // Macro is undefined in release build.
1142 SNAPSHOT_NODE_LOGGING;
1144 // A ResetProperties() may be required in the next frame
1145 mImpl->previousUpdateScene = updateScene;
1147 // Check whether further updates are required
1148 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1150 #ifdef PERFORMANCE_MONITOR_ENABLED
1151 // Always keep rendering when measuring FPS
1152 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1155 // The update has finished; swap the double-buffering indices
1156 mSceneGraphBuffers.Swap();
1158 // tell the update manager that we're done so the queue can be given to event thread
1159 mImpl->notificationManager.UpdateCompleted();
1161 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1163 return keepUpdating;
1166 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1168 // Update the duration set via Stage::KeepRendering()
1169 if ( mImpl->keepRenderingSeconds > 0.0f )
1171 mImpl->keepRenderingSeconds -= elapsedSeconds;
1174 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1176 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1177 // Keep updating until no messages are received and no animations are running.
1178 // If an animation has just finished, update at least once more for Discard end-actions.
1179 // No need to check for renderQueue as there is always a render after update and if that
1180 // render needs another update it will tell the adaptor to call update again
1182 if ( mImpl->keepRenderingSeconds > 0.0f )
1184 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1187 if ( !mImpl->messageQueue.WasEmpty() )
1189 keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1192 if ( IsAnimationRunning() ||
1193 mImpl->animationFinishedDuringUpdate )
1195 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1198 if ( mImpl->dynamicsChanged )
1200 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1203 if ( mImpl->renderTaskWaiting )
1205 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1208 return keepUpdatingRequest;
1211 void UpdateManager::SetBackgroundColor( const Vector4& color )
1213 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1215 // Reserve some memory inside the render queue
1216 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1218 // Construct message in the render queue memory; note that delete should not be called on the return value
1219 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1222 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1224 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1226 // Reserve some memory inside the render queue
1227 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1229 // Construct message in the render queue memory; note that delete should not be called on the return value
1230 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1233 void UpdateManager::KeepRendering( float durationSeconds )
1235 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1238 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1242 // just copy the vector of pointers
1243 mImpl->sortedLayers = layers;
1247 mImpl->systemLevelSortedLayers = layers;
1251 #ifdef DYNAMICS_SUPPORT
1253 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1255 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1256 mImpl->dynamicsWorld = dynamicsWorld;
1259 void UpdateManager::TerminateDynamicsWorld()
1261 mImpl->dynamicsWorld.Reset();
1264 #endif // DYNAMICS_SUPPORT
1266 } // namespace SceneGraph
1268 } // namespace Internal