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/internal/common/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>
37 #include <dali/internal/event/effects/shader-factory.h>
39 #include <dali/internal/update/animation/scene-graph-animator.h>
40 #include <dali/internal/update/animation/scene-graph-animation.h>
41 #include <dali/internal/update/common/discard-queue.h>
42 #include <dali/internal/update/common/scene-graph-buffers.h>
43 #include <dali/internal/update/common/scene-graph-property-buffer.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/object-owner-container.h>
48 #include <dali/internal/update/manager/prepare-render-algorithms.h>
49 #include <dali/internal/update/manager/process-render-tasks.h>
50 #include <dali/internal/update/manager/sorted-layers.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
54 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
55 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
56 #include <dali/internal/update/nodes/node.h>
57 #include <dali/internal/update/nodes/scene-graph-layer.h>
58 #include <dali/internal/update/queue/update-message-queue.h>
59 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
60 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
61 #include <dali/internal/update/rendering/scene-graph-material.h>
62 #include <dali/internal/update/rendering/scene-graph-sampler.h>
63 #include <dali/internal/update/rendering/scene-graph-geometry.h>
64 #include <dali/internal/update/resources/resource-manager.h>
65 #include <dali/internal/update/resources/complete-status-manager.h>
66 #include <dali/internal/update/touch/touch-resampler.h>
68 #include <dali/internal/render/common/render-instruction-container.h>
69 #include <dali/internal/render/common/render-manager.h>
70 #include <dali/internal/render/queue/render-queue.h>
71 #include <dali/internal/render/common/performance-monitor.h>
72 #include <dali/internal/render/gl-resources/texture-cache.h>
73 #include <dali/internal/render/shaders/scene-graph-shader.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 void DestroyNodeSet( std::set<Node*>& nodeSet )
116 for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
120 // Call Node::OnDestroy as each node is destroyed
130 typedef OwnerContainer< Shader* > ShaderContainer;
131 typedef ShaderContainer::Iterator ShaderIter;
132 typedef ShaderContainer::ConstIterator ShaderConstIter;
134 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBatchedQueue;
135 typedef ShaderDataBatchedQueue::iterator ShaderDataBatchedQueueIterator;
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 ),
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 keepRenderingSeconds( 0.0f ),
185 animationFinishedDuringUpdate( false ),
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 );
194 geometries.SetSceneController( *sceneController );
195 materials.SetSceneController( *sceneController );
196 propertyBuffers.SetSceneController( *sceneController );
197 samplers.SetSceneController( *sceneController );
202 // Disconnect render tasks from nodes, before destroying the nodes
203 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
204 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
206 (*iter)->SetSourceNode( NULL );
208 // ..repeat for system level RenderTasks
209 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
210 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
212 (*iter)->SetSourceNode( NULL );
215 // UpdateManager owns the Nodes
216 DestroyNodeSet( activeDisconnectedNodes );
217 DestroyNodeSet( connectedNodes );
218 DestroyNodeSet( disconnectedNodes );
220 // If there is root, reset it, otherwise do nothing as rendering was never started
229 if( systemLevelRoot )
231 systemLevelRoot->OnDestroy();
233 delete systemLevelRoot;
234 systemLevelRoot = NULL;
237 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
238 delete sceneController;
241 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
242 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
243 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
244 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
245 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
246 ShaderSaver* shaderSaver; ///< Saves shader binaries.
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
284 ShaderDataBatchedQueue compiledShaders[2]; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
286 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
287 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
289 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
290 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
292 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
293 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
295 GestureContainer gestures; ///< A container of owned gesture detectors
296 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
299 UpdateManager::UpdateManager( NotificationManager& notificationManager,
300 GlSyncAbstraction& glSyncAbstraction,
301 CompleteNotificationInterface& animationFinishedNotifier,
302 PropertyNotifier& propertyNotifier,
303 ResourceManager& resourceManager,
304 DiscardQueue& discardQueue,
305 RenderController& controller,
306 RenderManager& renderManager,
307 RenderQueue& renderQueue,
308 TextureCache& textureCache,
309 TouchResampler& touchResampler )
312 mImpl = new Impl( notificationManager,
314 animationFinishedNotifier,
323 mSceneGraphBuffers );
325 textureCache.SetBufferIndices( &mSceneGraphBuffers );
328 UpdateManager::~UpdateManager()
333 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
335 DALI_ASSERT_DEBUG( layer->IsLayer() );
336 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
340 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
345 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
346 mImpl->systemLevelRoot = layer;
349 layer->SetRoot(true);
352 void UpdateManager::AddNode( Node* node )
354 DALI_ASSERT_ALWAYS( NULL != node );
355 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
357 mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
360 void UpdateManager::ConnectNode( Node* parent, Node* node )
362 DALI_ASSERT_ALWAYS( NULL != parent );
363 DALI_ASSERT_ALWAYS( NULL != node );
364 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
366 // Move from active/disconnectedNodes to connectedNodes
367 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
370 removed = mImpl->disconnectedNodes.erase( node );
371 DALI_ASSERT_ALWAYS( removed );
373 mImpl->connectedNodes.insert( node );
375 node->SetActive( true );
377 parent->ConnectChild( node );
380 void UpdateManager::DisconnectNode( Node* node )
382 Node* parent = node->GetParent();
383 DALI_ASSERT_ALWAYS( NULL != parent );
384 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
386 // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
387 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
390 void UpdateManager::SetNodeActive( Node* node )
392 DALI_ASSERT_ALWAYS( NULL != node );
393 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
395 // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
396 std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
397 DALI_ASSERT_ALWAYS( removed );
398 mImpl->activeDisconnectedNodes.insert( node );
400 node->SetActive( true );
403 void UpdateManager::DestroyNode( Node* node )
405 DALI_ASSERT_ALWAYS( NULL != node );
406 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
408 // Transfer ownership from new/disconnectedNodes to the discard queue
409 // This keeps the nodes alive, until the render-thread has finished with them
410 std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
413 removed = mImpl->disconnectedNodes.erase( node );
414 DALI_ASSERT_ALWAYS( removed );
416 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
418 // Notify the Node about impending destruction
422 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
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
431 // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
432 if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL )
434 attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
438 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
440 // @todo MESH_REWORK Take ownership of this object after merge with SceneGraph::RenderableAttachment
442 SceneGraph::NodeAttachment* attachment = static_cast<SceneGraph::NodeAttachment*>(renderer);
443 attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
446 void UpdateManager::AddObject( PropertyOwner* object )
448 DALI_ASSERT_DEBUG( NULL != object );
450 mImpl->customObjects.PushBack( object );
453 void UpdateManager::RemoveObject( PropertyOwner* object )
455 DALI_ASSERT_DEBUG( NULL != object );
457 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
459 // Find the object and destroy it
460 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
462 PropertyOwner* current = *iter;
463 if ( current == object )
465 customObjects.Erase( iter );
470 // Should not reach here
471 DALI_ASSERT_DEBUG(false);
474 void UpdateManager::AddAnimation( Animation* animation )
476 mImpl->animations.PushBack( animation );
479 void UpdateManager::StopAnimation( Animation* animation )
481 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
483 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
485 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
488 void UpdateManager::RemoveAnimation( Animation* animation )
490 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
492 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
494 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
497 bool UpdateManager::IsAnimationRunning() const
499 bool isRunning(false);
500 AnimationContainer& animations = mImpl->animations;
502 // Find any animation that isn't stopped or paused
504 const AnimationIter endIter = animations.End();
505 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
507 const Animation::State state = (*iter)->GetState();
509 if (state != Animation::Stopped &&
510 state != Animation::Paused)
519 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
521 mImpl->propertyNotifications.PushBack( propertyNotification );
524 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
526 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
527 PropertyNotificationIter iter = propertyNotifications.Begin();
529 while ( iter != propertyNotifications.End() )
531 if( *iter == propertyNotification )
533 propertyNotifications.Erase(iter);
540 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
542 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
543 propertyNotification->SetNotifyMode( notifyMode );
546 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
548 return mImpl->geometries;
551 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
553 return mImpl->materials;
556 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
558 return mImpl->samplers;
561 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
563 return mImpl->propertyBuffers;
566 void UpdateManager::AddShader( Shader* shader )
568 DALI_ASSERT_DEBUG( NULL != shader );
570 if( mImpl->shaders.Count() == 0 )
572 // the first added shader becomes our default shader
573 // Construct message in the render queue memory; note that delete should not be called on the return value
574 typedef MessageValue1< RenderManager, Shader* > DerivedType;
576 // Reserve some memory inside the render queue
577 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
579 // Construct message in the render queue memory; note that delete should not be called on the return value
580 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
583 mImpl->shaders.PushBack( shader );
585 // Allows the shader to dispatch texture requests to the cache
586 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
589 void UpdateManager::RemoveShader( Shader* shader )
591 DALI_ASSERT_DEBUG(shader != NULL);
593 ShaderContainer& shaders = mImpl->shaders;
595 // Find the shader and destroy it
596 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
598 Shader& current = **iter;
599 if ( ¤t == shader )
601 // Transfer ownership to the discard queue
602 // This keeps the shader alive, until the render-thread has finished with it
603 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
608 // Should not reach here
609 DALI_ASSERT_DEBUG(false);
612 void UpdateManager::SetShaderProgram( Shader* shader,
613 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
618 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
620 // Reserve some memory inside the render queue
621 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
623 // Construct message in the render queue memory; note that delete should not be called on the return value
624 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
628 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
630 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
631 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
632 mImpl->compiledShaders[mSceneGraphBuffers.GetUpdateBufferIndex() > 0 ? 0 : 1].push_back( shaderData );
635 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
639 // copy the list, this is only likely to happen once in application life cycle
640 return &(mImpl->taskList);
644 // copy the list, this is only likely to happen once in application life cycle
645 return &(mImpl->systemLevelTaskList);
649 void UpdateManager::AddGesture( PanGesture* gesture )
651 DALI_ASSERT_DEBUG( NULL != gesture );
653 mImpl->gestures.PushBack( gesture );
656 void UpdateManager::RemoveGesture( PanGesture* gesture )
658 DALI_ASSERT_DEBUG( gesture != NULL );
660 GestureContainer& gestures = mImpl->gestures;
662 // Find the gesture and destroy it
663 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
665 PanGesture& current = **iter;
666 if ( ¤t == gesture )
668 mImpl->gestures.Erase( iter );
672 // Should not reach here
673 DALI_ASSERT_DEBUG(false);
676 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
678 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
681 void UpdateManager::EventProcessingStarted()
683 mImpl->messageQueue.EventProcessingStarted();
686 bool UpdateManager::FlushQueue()
688 return mImpl->messageQueue.FlushQueue();
691 void UpdateManager::ResetNodeProperty( Node& node )
693 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
695 node.ResetToBaseValues( bufferIndex );
698 void UpdateManager::ResetProperties()
700 PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
702 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
704 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
705 mImpl->animationFinishedDuringUpdate = false;
707 // Animated properties have to be reset to their original value each frame
709 // Reset node properties
712 ResetNodeProperty( *mImpl->root );
715 if ( mImpl->systemLevelRoot )
717 ResetNodeProperty( *mImpl->systemLevelRoot );
720 // Reset the Connected Nodes
721 const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
722 for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
724 ResetNodeProperty( **iter );
727 // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
728 for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
731 node->ResetToBaseValues( bufferIndex );
732 node->SetActive( false );
734 // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
735 mImpl->activeDisconnectedNodes.erase( iter );
736 mImpl->disconnectedNodes.insert( node );
739 // Reset system-level render-task list properties to base values
740 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
742 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
744 (*iter)->ResetToBaseValues( bufferIndex );
747 // Reset render-task list properties to base values.
748 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
750 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
752 (*iter)->ResetToBaseValues( bufferIndex );
755 // Reset custom object properties to base values
756 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
758 (*iter)->ResetToBaseValues( bufferIndex );
761 mImpl->materials.ResetToBaseValues( bufferIndex );
762 mImpl->geometries.ResetToBaseValues( bufferIndex );
763 mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
764 mImpl->samplers.ResetToBaseValues( bufferIndex );
767 // Reset animatable shader properties to base values
768 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
770 (*iter)->ResetToBaseValues( bufferIndex );
773 PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
776 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
778 bool gestureUpdated( false );
780 // constrain gestures... (in construction order)
781 GestureContainer& gestures = mImpl->gestures;
783 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
785 PanGesture& gesture = **iter;
786 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
787 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
790 return gestureUpdated;
793 void UpdateManager::Animate( float elapsedSeconds )
795 PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
797 AnimationContainer &animations = mImpl->animations;
798 AnimationIter iter = animations.Begin();
799 while ( iter != animations.End() )
801 Animation* animation = *iter;
802 bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
804 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
806 // Remove animations that had been destroyed but were still waiting for an update
807 if (animation->GetState() == Animation::Destroyed)
809 iter = animations.Erase(iter);
817 if ( mImpl->animationFinishedDuringUpdate )
819 // The application should be notified by NotificationManager, in another thread
820 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
823 PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
826 void UpdateManager::ApplyConstraints()
828 PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
830 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
832 // constrain custom objects... (in construction order)
833 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
835 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
836 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
838 PropertyOwner& object = **iter;
839 ConstrainPropertyOwner( object, bufferIndex );
842 // constrain nodes... (in Depth First traversal order)
845 ConstrainNodes( *(mImpl->root), bufferIndex );
848 if ( mImpl->systemLevelRoot )
850 ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
853 // constrain other property-owners after nodes as they are more likely to depend on a node's
854 // current frame property than vice versa. They tend to be final constraints (no further
855 // constraints depend on their properties)
856 // e.g. ShaderEffect uniform a function of Actor's position.
857 // Mesh vertex a function of Actor's position or world position.
859 // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
860 // they can be all processed in a super-list of property-owners.
862 // Constrain system-level render-tasks
863 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
865 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
867 RenderTask& task = **iter;
868 ConstrainPropertyOwner( task, bufferIndex );
871 // Constrain render-tasks
872 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
874 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
876 RenderTask& task = **iter;
877 ConstrainPropertyOwner( task, bufferIndex );
880 // Constrain Materials and geometries
881 mImpl->materials.ConstrainObjects( bufferIndex );
882 mImpl->geometries.ConstrainObjects( bufferIndex );
883 mImpl->samplers.ConstrainObjects( bufferIndex );
884 mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
886 // constrain shaders... (in construction order)
887 ShaderContainer& shaders = mImpl->shaders;
889 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
891 Shader& shader = **iter;
892 ConstrainPropertyOwner( shader, bufferIndex );
895 PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
898 void UpdateManager::ProcessPropertyNotifications()
900 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
901 PropertyNotificationIter iter = notifications.Begin();
903 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
905 while ( iter != notifications.End() )
907 PropertyNotification* notification = *iter;
908 bool valid = notification->Check( bufferIndex );
911 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
917 void UpdateManager::ForwardCompiledShadersToEventThread()
919 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
920 if( mImpl->shaderSaver )
922 ShaderDataBatchedQueue& compiledShaders = mImpl->compiledShaders[mSceneGraphBuffers.GetUpdateBufferIndex()];
923 if( compiledShaders.size() > 0 )
925 ShaderSaver& factory = *mImpl->shaderSaver;
926 ShaderDataBatchedQueueIterator i = compiledShaders.begin();
927 ShaderDataBatchedQueueIterator end = compiledShaders.end();
928 for( ; i != end; ++i )
930 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
936 void UpdateManager::UpdateNodes()
938 mImpl->nodeDirtyFlags = NothingFlag;
945 PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
947 // Prepare resources, update shaders, update attachments, for each node
948 // And add the renderers to the sorted layers. Start from root, which is also a layer
949 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
950 mSceneGraphBuffers.GetUpdateBufferIndex(),
951 mImpl->resourceManager,
952 mImpl->renderQueue );
954 if ( mImpl->systemLevelRoot )
956 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
957 mSceneGraphBuffers.GetUpdateBufferIndex(),
958 mImpl->resourceManager,
959 mImpl->renderQueue );
962 PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
965 unsigned int UpdateManager::Update( float elapsedSeconds,
966 unsigned int lastVSyncTimeMilliseconds,
967 unsigned int nextVSyncTimeMilliseconds )
969 PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
970 PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
971 PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
973 // Measure the time spent in UpdateManager::Update
974 PERF_MONITOR_START(PerformanceMonitor::UPDATE);
976 BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
978 // Update the frame time delta on the render thread.
979 mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
981 // 1) Clear nodes/resources which were previously discarded
982 mImpl->discardQueue.Clear( bufferIndex );
984 // 2) Grab any loaded resources
985 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
987 // 3) Process Touches & Gestures
988 mImpl->touchResampler.Update();
989 const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
991 const bool updateScene = // The scene-graph requires an update if..
992 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
993 IsAnimationRunning() || // ..at least one animation is running OR
994 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
995 resourceChanged || // ..one or more resources were updated/changed OR
996 gestureUpdated; // ..a gesture property was updated
998 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
999 // values if the scene was updated in the previous frame.
1000 if( updateScene || mImpl->previousUpdateScene )
1002 // 4) Reset properties from the previous update
1006 // 5) Process the queued scene messages
1007 mImpl->messageQueue.ProcessMessages();
1009 // 6) Post Process Ids of resources updated by renderer
1010 mImpl->resourceManager.PostProcessResources( bufferIndex );
1012 // 6.1) Forward a batch of compiled shader programs to event thread for saving
1013 ForwardCompiledShadersToEventThread();
1015 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1016 // renderer lists if the scene was updated in the previous frame.
1017 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1018 if( updateScene || mImpl->previousUpdateScene )
1021 Animate( elapsedSeconds );
1023 // 8) Apply Constraints
1026 // 9) Check Property Notifications
1027 ProcessPropertyNotifications();
1029 // 10) Clear the lists of renderable-attachments from the previous update
1030 ClearRenderables( mImpl->sortedLayers );
1031 ClearRenderables( mImpl->systemLevelSortedLayers );
1033 // 11) Update node hierarchy and perform sorting / culling.
1034 // This will populate each Layer with a list of renderers which are ready.
1037 // 12) Prepare for the next render
1038 PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1040 PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1041 PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1042 PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1044 PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1046 // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1047 // reset the update buffer index and make sure there is enough room in the instruction container
1048 mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1049 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1051 if ( NULL != mImpl->root )
1053 ProcessRenderTasks( bufferIndex,
1054 mImpl->completeStatusManager,
1057 mImpl->sortedLayers,
1058 mImpl->renderSortingHelper,
1059 mImpl->renderInstructions );
1061 // Process the system-level RenderTasks last
1062 if ( NULL != mImpl->systemLevelRoot )
1064 ProcessRenderTasks( bufferIndex,
1065 mImpl->completeStatusManager,
1066 mImpl->systemLevelTaskList,
1067 *mImpl->systemLevelRoot,
1068 mImpl->systemLevelSortedLayers,
1069 mImpl->renderSortingHelper,
1070 mImpl->renderInstructions );
1075 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1076 bool doRenderOnceNotify = false;
1077 mImpl->renderTaskWaiting = false;
1078 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1079 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1080 endIter != iter; ++iter )
1082 RenderTask& renderTask(*(*iter));
1084 renderTask.UpdateState();
1086 if( renderTask.IsWaitingToRender() &&
1087 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1089 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1092 if( renderTask.HasRendered() )
1094 doRenderOnceNotify = true;
1098 if( doRenderOnceNotify )
1100 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1101 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1104 PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1106 // Macro is undefined in release build.
1107 SNAPSHOT_NODE_LOGGING;
1109 // A ResetProperties() may be required in the next frame
1110 mImpl->previousUpdateScene = updateScene;
1112 // Check whether further updates are required
1113 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1115 #ifdef PERFORMANCE_MONITOR_ENABLED
1116 // Always keep rendering when measuring FPS
1117 keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1120 // The update has finished; swap the double-buffering indices
1121 mSceneGraphBuffers.Swap();
1123 // tell the update manager that we're done so the queue can be given to event thread
1124 mImpl->notificationManager.UpdateCompleted();
1126 PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1128 return keepUpdating;
1131 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1133 // Update the duration set via Stage::KeepRendering()
1134 if ( mImpl->keepRenderingSeconds > 0.0f )
1136 mImpl->keepRenderingSeconds -= elapsedSeconds;
1139 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1141 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1142 // Keep updating until no messages are received and no animations are running.
1143 // If an animation has just finished, update at least once more for Discard end-actions.
1144 // No need to check for renderQueue as there is always a render after update and if that
1145 // render needs another update it will tell the adaptor to call update again
1147 if ( mImpl->keepRenderingSeconds > 0.0f )
1149 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1152 if ( IsAnimationRunning() ||
1153 mImpl->animationFinishedDuringUpdate )
1155 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1158 if ( mImpl->renderTaskWaiting )
1160 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1163 return keepUpdatingRequest;
1166 void UpdateManager::SetBackgroundColor( const Vector4& color )
1168 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1170 // Reserve some memory inside the render queue
1171 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1173 // Construct message in the render queue memory; note that delete should not be called on the return value
1174 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1177 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1179 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1181 // Reserve some memory inside the render queue
1182 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1184 // Construct message in the render queue memory; note that delete should not be called on the return value
1185 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1188 void UpdateManager::KeepRendering( float durationSeconds )
1190 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1193 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1197 // just copy the vector of pointers
1198 mImpl->sortedLayers = layers;
1202 mImpl->systemLevelSortedLayers = layers;
1206 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1208 mImpl->shaderSaver = &upstream;
1211 } // namespace SceneGraph
1213 } // namespace Internal