2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/render-controller.h>
27 #include <dali/integration-api/shader-data.h>
28 #include <dali/integration-api/debug.h>
30 #include <dali/internal/common/core-impl.h>
31 #include <dali/internal/common/owner-container.h>
32 #include <dali/internal/common/message.h>
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-impl.h>
36 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/update/animation/scene-graph-animator.h>
39 #include <dali/internal/update/animation/scene-graph-animation.h>
40 #include <dali/internal/update/common/discard-queue.h>
41 #include <dali/internal/update/common/scene-graph-buffers.h>
42 #include <dali/internal/update/common/scene-graph-property-buffer.h>
43 #include <dali/internal/update/controllers/render-message-dispatcher.h>
44 #include <dali/internal/update/controllers/scene-controller-impl.h>
45 #include <dali/internal/update/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,
617 ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
619 DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (id:%d hash:%d)\n", resourceId, shaderHash);
621 DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
623 Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
626 shaderData->SetHashValue( shaderHash );
627 shaderData->SetResourceId( resourceId );
629 typedef MessageValue4< Shader, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
631 // Reserve some memory inside the render queue
632 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
634 // Construct message in the render queue memory; note that delete should not be called on the return value
635 new (slot) DerivedType( shader, &Shader::SetProgram, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
639 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
643 // copy the list, this is only likely to happen once in application life cycle
644 return &(mImpl->taskList);
648 // copy the list, this is only likely to happen once in application life cycle
649 return &(mImpl->systemLevelTaskList);
653 void UpdateManager::AddGesture( PanGesture* gesture )
655 DALI_ASSERT_DEBUG( NULL != gesture );
657 mImpl->gestures.PushBack( gesture );
660 void UpdateManager::RemoveGesture( PanGesture* gesture )
662 DALI_ASSERT_DEBUG( gesture != NULL );
664 GestureContainer& gestures = mImpl->gestures;
666 // Find the gesture and destroy it
667 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
669 PanGesture& current = **iter;
670 if ( ¤t == gesture )
672 mImpl->gestures.Erase( iter );
676 // Should not reach here
677 DALI_ASSERT_DEBUG(false);
680 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
682 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
685 void UpdateManager::EventProcessingStarted()
687 mImpl->messageQueue.EventProcessingStarted();
690 bool UpdateManager::FlushQueue()
692 return mImpl->messageQueue.FlushQueue();
695 void UpdateManager::ResetNodeProperty( Node& node )
697 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
699 node.ResetToBaseValues( bufferIndex );
701 // @todo MESH_REWORK Only perform this step for RendererAttachments - consider
702 // storing them again? Split out to separate scene graph object (called e.g. RendererPropertyOwner) owned by UpdateManager
703 // It is after all, a property owner, and always requires resetting...
704 // The depth index should not be an animatable property... and probably not even
705 // a constraint input? (Double buffering will slow down the sort algorithm slightly)
706 if( node.HasAttachment() )
708 node.GetAttachment().ResetToBaseValues( bufferIndex );
712 void UpdateManager::ResetProperties()
714 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
716 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
718 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
719 mImpl->animationFinishedDuringUpdate = false;
721 // Animated properties have to be reset to their original value each frame
723 // Reset node properties
726 ResetNodeProperty( *mImpl->root );
729 if ( mImpl->systemLevelRoot )
731 ResetNodeProperty( *mImpl->systemLevelRoot );
734 // Reset the Connected Nodes
735 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
736 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
738 ResetNodeProperty( **iter );
741 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
742 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
745 node->ResetToBaseValues( bufferIndex );
746 node->SetActive( false );
748 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
749 mImpl->activeDisconnectedNodes.erase( iter );
750 mImpl->disconnectedNodes.insert( node );
753 // Reset system-level render-task list properties to base values
754 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
756 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
758 (*iter)->ResetToBaseValues( bufferIndex );
761 // Reset render-task list properties to base values.
762 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
764 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
766 (*iter)->ResetToBaseValues( bufferIndex );
769 // Reset custom object properties to base values
770 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
772 (*iter)->ResetToBaseValues( bufferIndex );
775 mImpl->materials.ResetToBaseValues( bufferIndex );
776 mImpl->geometries.ResetToBaseValues( bufferIndex );
777 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
778 mImpl->samplers.ResetToBaseValues( bufferIndex );
781 // Reset animatable shader properties to base values
782 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
784 (*iter)->ResetToBaseValues( bufferIndex );
787 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
790 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
792 bool gestureUpdated( false );
794 // constrain gestures... (in construction order)
795 GestureContainer& gestures = mImpl->gestures;
797 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
799 PanGesture& gesture = **iter;
800 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
801 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
804 return gestureUpdated;
807 void UpdateManager::Animate( float elapsedSeconds )
809 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
811 AnimationContainer &animations = mImpl->animations;
812 AnimationIter iter = animations.Begin();
813 while ( iter != animations.End() )
815 Animation* animation = *iter;
816 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
818 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
820 // Remove animations that had been destroyed but were still waiting for an update
821 if (animation->GetState() == Animation::Destroyed)
823 iter = animations.Erase(iter);
831 if ( mImpl->animationFinishedDuringUpdate )
833 // The application should be notified by NotificationManager, in another thread
834 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
837 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
840 void UpdateManager::ApplyConstraints()
842 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
844 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
846 // constrain custom objects... (in construction order)
847 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
849 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
850 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
852 PropertyOwner& object = **iter;
853 ConstrainPropertyOwner( object, bufferIndex );
856 // constrain nodes... (in Depth First traversal order)
859 ConstrainNodes( *(mImpl->root), bufferIndex );
862 if ( mImpl->systemLevelRoot )
864 ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
867 // constrain other property-owners after nodes as they are more likely to depend on a node's
868 // current frame property than vice versa. They tend to be final constraints (no further
869 // constraints depend on their properties)
870 // e.g. ShaderEffect uniform a function of Actor's position.
871 // Mesh vertex a function of Actor's position or world position.
873 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
874 // they can be all processed in a super-list of property-owners.
876 // Constrain system-level render-tasks
877 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
879 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
881 RenderTask& task = **iter;
882 ConstrainPropertyOwner( task, bufferIndex );
885 // Constrain render-tasks
886 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
888 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
890 RenderTask& task = **iter;
891 ConstrainPropertyOwner( task, bufferIndex );
894 // Constrain Materials and geometries
895 mImpl->materials.ConstrainObjects( bufferIndex );
896 mImpl->geometries.ConstrainObjects( bufferIndex );
897 mImpl->samplers.ConstrainObjects( bufferIndex );
898 mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
900 // constrain shaders... (in construction order)
901 ShaderContainer& shaders = mImpl->shaders;
903 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
905 Shader& shader = **iter;
906 ConstrainPropertyOwner( shader, bufferIndex );
909 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
912 void UpdateManager::ProcessPropertyNotifications()
914 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
915 PropertyNotificationIter iter = notifications.Begin();
917 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
919 while ( iter != notifications.End() )
921 PropertyNotification* notification = *iter;
922 bool valid = notification->Check( bufferIndex );
925 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
931 void UpdateManager::UpdateNodes()
933 mImpl->nodeDirtyFlags = NothingFlag;
940 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
942 // Prepare resources, update shaders, update attachments, for each node
943 // And add the renderers to the sorted layers. Start from root, which is also a layer
944 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
945 mSceneGraphBuffers.GetUpdateBufferIndex(),
946 mImpl->resourceManager,
947 mImpl->renderQueue );
949 if ( mImpl->systemLevelRoot )
951 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
952 mSceneGraphBuffers.GetUpdateBufferIndex(),
953 mImpl->resourceManager,
954 mImpl->renderQueue );
957 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
960 unsigned int UpdateManager::Update( float elapsedSeconds,
961 unsigned int lastVSyncTimeMilliseconds,
962 unsigned int nextVSyncTimeMilliseconds )
964 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
965 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
966 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
968 // Measure the time spent in UpdateManager::Update
969 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
971 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
973 // Update the frame time delta on the render thread.
974 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
976 // 1) Clear nodes/resources which were previously discarded
977 mImpl->discardQueue.Clear( bufferIndex );
979 // 2) Grab any loaded resources
980 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
982 // 3) Process Touches & Gestures
983 mImpl->touchResampler.Update();
984 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
986 const bool updateScene = // The scene-graph requires an update if..
987 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
988 IsAnimationRunning() || // ..at least one animation is running OR
989 mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR
990 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
991 resourceChanged || // ..one or more resources were updated/changed OR
992 gestureUpdated; // ..a gesture property was updated
994 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
995 // values if the scene was updated in the previous frame.
996 if( updateScene || mImpl->previousUpdateScene )
998 // 4) Reset properties from the previous update
1002 // 5) Process the queued scene messages
1003 mImpl->messageQueue.ProcessMessages();
1005 // 6) Post Process Ids of resources updated by renderer
1006 mImpl->resourceManager.PostProcessResources( bufferIndex );
1008 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1009 // renderer lists if the scene was updated in the previous frame.
1010 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1011 if( updateScene || mImpl->previousUpdateScene )
1014 Animate( elapsedSeconds );
1016 // 8) Apply Constraints
1019 #ifdef DYNAMICS_SUPPORT
1020 // 9) Update dynamics simulation
1021 mImpl->dynamicsChanged = false;
1022 if( mImpl->dynamicsWorld )
1024 mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1028 // 10) Check Property Notifications
1029 ProcessPropertyNotifications();
1031 // 11) Clear the lists of renderable-attachments from the previous update
1032 ClearRenderables( mImpl->sortedLayers );
1033 ClearRenderables( mImpl->systemLevelSortedLayers );
1035 // 12) Update node hierarchy and perform sorting / culling.
1036 // This will populate each Layer with a list of renderers which are ready.
1039 // 13) Prepare for the next render
1040 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1042 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1043 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1044 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1046 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1048 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1049 // reset the update buffer index and make sure there is enough room in the instruction container
1050 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1051 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1053 if ( NULL != mImpl->root )
1055 ProcessRenderTasks( bufferIndex,
1056 mImpl->completeStatusManager,
1059 mImpl->sortedLayers,
1060 mImpl->renderSortingHelper,
1061 mImpl->renderInstructions );
1063 // Process the system-level RenderTasks last
1064 if ( NULL != mImpl->systemLevelRoot )
1066 ProcessRenderTasks( bufferIndex,
1067 mImpl->completeStatusManager,
1068 mImpl->systemLevelTaskList,
1069 *mImpl->systemLevelRoot,
1070 mImpl->systemLevelSortedLayers,
1071 mImpl->renderSortingHelper,
1072 mImpl->renderInstructions );
1077 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1078 bool doRenderOnceNotify = false;
1079 mImpl->renderTaskWaiting = false;
1080 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1081 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1082 endIter != iter; ++iter )
1084 RenderTask& renderTask(*(*iter));
1086 renderTask.UpdateState();
1088 if( renderTask.IsWaitingToRender() &&
1089 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1091 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1094 if( renderTask.HasRendered() )
1096 doRenderOnceNotify = true;
1100 if( doRenderOnceNotify )
1102 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1103 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1106 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1108 // Macro is undefined in release build.
1109 SNAPSHOT_NODE_LOGGING;
1111 // A ResetProperties() may be required in the next frame
1112 mImpl->previousUpdateScene = updateScene;
1114 // Check whether further updates are required
1115 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1117 #ifdef PERFORMANCE_MONITOR_ENABLED
1118 // Always keep rendering when measuring FPS
1119 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1122 // The update has finished; swap the double-buffering indices
1123 mSceneGraphBuffers.Swap();
1125 // tell the update manager that we're done so the queue can be given to event thread
1126 mImpl->notificationManager.UpdateCompleted();
1128 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1130 return keepUpdating;
1133 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1135 // Update the duration set via Stage::KeepRendering()
1136 if ( mImpl->keepRenderingSeconds > 0.0f )
1138 mImpl->keepRenderingSeconds -= elapsedSeconds;
1141 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1143 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1144 // Keep updating until no messages are received and no animations are running.
1145 // If an animation has just finished, update at least once more for Discard end-actions.
1146 // No need to check for renderQueue as there is always a render after update and if that
1147 // render needs another update it will tell the adaptor to call update again
1149 if ( mImpl->keepRenderingSeconds > 0.0f )
1151 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1154 if ( IsAnimationRunning() ||
1155 mImpl->animationFinishedDuringUpdate )
1157 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1160 if ( mImpl->dynamicsChanged )
1162 keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1165 if ( mImpl->renderTaskWaiting )
1167 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1170 return keepUpdatingRequest;
1173 void UpdateManager::SetBackgroundColor( const Vector4& color )
1175 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1177 // Reserve some memory inside the render queue
1178 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1180 // Construct message in the render queue memory; note that delete should not be called on the return value
1181 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1184 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1186 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1188 // Reserve some memory inside the render queue
1189 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1191 // Construct message in the render queue memory; note that delete should not be called on the return value
1192 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1195 void UpdateManager::KeepRendering( float durationSeconds )
1197 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1200 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1204 // just copy the vector of pointers
1205 mImpl->sortedLayers = layers;
1209 mImpl->systemLevelSortedLayers = layers;
1213 #ifdef DYNAMICS_SUPPORT
1215 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1217 dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1218 mImpl->dynamicsWorld = dynamicsWorld;
1221 void UpdateManager::TerminateDynamicsWorld()
1223 mImpl->dynamicsWorld.Reset();
1226 #endif // DYNAMICS_SUPPORT
1228 } // namespace SceneGraph
1230 } // namespace Internal