2 * Copyright (c) 2015 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>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.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/process-render-tasks.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
53 #include <dali/internal/update/nodes/node.h>
54 #include <dali/internal/update/nodes/scene-graph-layer.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
58 #include <dali/internal/update/rendering/scene-graph-material.h>
59 #include <dali/internal/update/rendering/scene-graph-geometry.h>
60 #include <dali/internal/update/resources/resource-manager.h>
61 #include <dali/internal/update/touch/touch-resampler.h>
63 #include <dali/internal/render/common/render-instruction-container.h>
64 #include <dali/internal/render/common/render-manager.h>
65 #include <dali/internal/render/queue/render-queue.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/shaders/scene-graph-shader.h>
68 #include <dali/internal/render/renderers/render-sampler.h>
70 // Un-comment to enable node tree debug logging
71 //#define NODE_TREE_LOGGING 1
73 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
74 #define SNAPSHOT_NODE_LOGGING \
75 const int FRAME_COUNT_TRIGGER = 16;\
76 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
78 if ( NULL != mImpl->root )\
80 mImpl->frameCounter = 0;\
81 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
84 mImpl->frameCounter++;
86 #define SNAPSHOT_NODE_LOGGING
89 #if defined(DEBUG_ENABLED)
90 extern Debug::Filter* gRenderTaskLogFilter;
94 using namespace Dali::Integration;
95 using Dali::Internal::Update::MessageQueue;
106 typedef OwnerContainer< Shader* > ShaderContainer;
107 typedef ShaderContainer::Iterator ShaderIter;
108 typedef ShaderContainer::ConstIterator ShaderConstIter;
110 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
112 typedef OwnerContainer<PanGesture*> GestureContainer;
113 typedef GestureContainer::Iterator GestureIter;
114 typedef GestureContainer::ConstIterator GestureConstIter;
118 * Structure to contain UpdateManager internal data
120 struct UpdateManager::Impl
122 Impl( NotificationManager& notificationManager,
123 CompleteNotificationInterface& animationFinishedNotifier,
124 PropertyNotifier& propertyNotifier,
125 ResourceManager& resourceManager,
126 DiscardQueue& discardQueue,
127 RenderController& renderController,
128 RenderManager& renderManager,
129 RenderQueue& renderQueue,
130 TextureCache& textureCache,
131 TouchResampler& touchResampler,
132 SceneGraphBuffers& sceneGraphBuffers )
134 renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
135 notificationManager( notificationManager ),
136 animationFinishedNotifier( animationFinishedNotifier ),
137 propertyNotifier( propertyNotifier ),
139 resourceManager( resourceManager ),
140 discardQueue( discardQueue ),
141 renderController( renderController ),
142 sceneController( NULL ),
143 renderManager( renderManager ),
144 renderQueue( renderQueue ),
145 renderInstructions( renderManager.GetRenderInstructionContainer() ),
146 touchResampler( touchResampler ),
147 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
148 taskList( renderMessageDispatcher, resourceManager ),
149 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
151 systemLevelRoot( NULL ),
152 renderers( sceneGraphBuffers, discardQueue ),
153 geometries( sceneGraphBuffers, discardQueue ),
154 materials( sceneGraphBuffers, discardQueue ),
155 messageQueue( renderController, sceneGraphBuffers ),
156 keepRenderingSeconds( 0.0f ),
157 animationFinishedDuringUpdate( false ),
158 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
159 previousUpdateScene( false ),
161 renderSortingHelper(),
162 renderTaskWaiting( false )
164 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache );
166 renderers.SetSceneController( *sceneController );
167 geometries.SetSceneController( *sceneController );
168 materials.SetSceneController( *sceneController );
170 // create first 'dummy' node
176 // Disconnect render tasks from nodes, before destroying the nodes
177 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
178 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
180 (*iter)->SetSourceNode( NULL );
182 // ..repeat for system level RenderTasks
183 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
184 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
186 (*iter)->SetSourceNode( NULL );
189 // UpdateManager owns the Nodes
190 Vector<Node*>::Iterator iter = nodes.Begin()+1;
191 Vector<Node*>::Iterator endIter = nodes.End();
192 for(;iter!=endIter;++iter)
194 (*iter)->OnDestroy();
198 // If there is root, reset it, otherwise do nothing as rendering was never started
207 if( systemLevelRoot )
209 systemLevelRoot->OnDestroy();
211 delete systemLevelRoot;
212 systemLevelRoot = NULL;
215 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
216 delete sceneController;
219 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
220 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
221 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
222 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
223 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
224 ShaderSaver* shaderSaver; ///< Saves shader binaries.
225 ResourceManager& resourceManager; ///< resource manager
226 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
227 RenderController& renderController; ///< render controller
228 SceneControllerImpl* sceneController; ///< scene controller
229 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
230 RenderQueue& renderQueue; ///< Used to queue messages for the next render
231 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
232 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
234 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
236 RenderTaskList taskList; ///< The list of scene graph render-tasks
237 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
239 Layer* root; ///< The root node (root is a layer)
240 Layer* systemLevelRoot; ///< A separate root-node for system-level content
242 Vector<Node*> nodes; ///< A container of all instantiated nodes
244 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
245 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
247 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
249 AnimationContainer animations; ///< A container of owned animations
250 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
252 ObjectOwnerContainer<Renderer> renderers;
253 ObjectOwnerContainer<Geometry> geometries; ///< A container of geometries
254 ObjectOwnerContainer<Material> materials; ///< A container of materials
256 ShaderContainer shaders; ///< A container of owned shaders
258 MessageQueue messageQueue; ///< The messages queued from the event-thread
259 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
260 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
261 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
263 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
264 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
266 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
267 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
269 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
270 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
272 GestureContainer gestures; ///< A container of owned gesture detectors
273 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
276 UpdateManager::UpdateManager( NotificationManager& notificationManager,
277 CompleteNotificationInterface& animationFinishedNotifier,
278 PropertyNotifier& propertyNotifier,
279 ResourceManager& resourceManager,
280 DiscardQueue& discardQueue,
281 RenderController& controller,
282 RenderManager& renderManager,
283 RenderQueue& renderQueue,
284 TextureCache& textureCache,
285 TouchResampler& touchResampler )
288 mImpl = new Impl( notificationManager,
289 animationFinishedNotifier,
298 mSceneGraphBuffers );
300 textureCache.SetBufferIndices( &mSceneGraphBuffers );
303 UpdateManager::~UpdateManager()
308 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
310 DALI_ASSERT_DEBUG( layer->IsLayer() );
311 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
315 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
320 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
321 mImpl->systemLevelRoot = layer;
324 layer->SetRoot(true);
327 void UpdateManager::AddNode( Node* node )
329 DALI_ASSERT_ALWAYS( NULL != node );
330 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
332 // Nodes must be sorted by pointer
333 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
334 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
338 mImpl->nodes.Insert((iter+1), node);
344 void UpdateManager::ConnectNode( Node* parent, Node* node )
346 DALI_ASSERT_ALWAYS( NULL != parent );
347 DALI_ASSERT_ALWAYS( NULL != node );
348 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
350 parent->ConnectChild( node );
353 void UpdateManager::DisconnectNode( Node* node )
355 Node* parent = node->GetParent();
356 DALI_ASSERT_ALWAYS( NULL != parent );
357 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
359 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
362 void UpdateManager::DestroyNode( Node* node )
364 DALI_ASSERT_ALWAYS( NULL != node );
365 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
367 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
368 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
369 for(;iter!=endIter;++iter)
373 mImpl->nodes.Erase(iter);
378 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
380 // Notify the Node about impending destruction
384 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
385 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
387 DALI_ASSERT_DEBUG( node != NULL );
388 DALI_ASSERT_DEBUG( attachment != NULL );
390 // attach node to attachment first so that parent is known by the time attachment is connected
391 node->Attach( *attachment ); // node takes ownership
394 void UpdateManager::AddObject( PropertyOwner* object )
396 DALI_ASSERT_DEBUG( NULL != object );
398 mImpl->customObjects.PushBack( object );
401 void UpdateManager::RemoveObject( PropertyOwner* object )
403 DALI_ASSERT_DEBUG( NULL != object );
405 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
407 // Find the object and destroy it
408 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
410 PropertyOwner* current = *iter;
411 if ( current == object )
413 customObjects.Erase( iter );
418 // Should not reach here
419 DALI_ASSERT_DEBUG(false);
422 void UpdateManager::AddAnimation( Animation* animation )
424 mImpl->animations.PushBack( animation );
427 void UpdateManager::StopAnimation( Animation* animation )
429 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
431 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
433 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
436 void UpdateManager::RemoveAnimation( Animation* animation )
438 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
440 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
442 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
445 bool UpdateManager::IsAnimationRunning() const
447 bool isRunning(false);
448 AnimationContainer& animations = mImpl->animations;
450 // Find any animation that isn't stopped or paused
452 const AnimationIter endIter = animations.End();
453 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
455 const Animation::State state = (*iter)->GetState();
457 if (state != Animation::Stopped &&
458 state != Animation::Paused)
467 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
469 mImpl->propertyNotifications.PushBack( propertyNotification );
472 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
474 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
475 PropertyNotificationIter iter = propertyNotifications.Begin();
477 while ( iter != propertyNotifications.End() )
479 if( *iter == propertyNotification )
481 propertyNotifications.Erase(iter);
488 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
490 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
491 propertyNotification->SetNotifyMode( notifyMode );
494 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
496 return mImpl->geometries;
499 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
501 return mImpl->renderers;
505 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
507 return mImpl->materials;
510 void UpdateManager::AddShader( Shader* shader )
512 DALI_ASSERT_DEBUG( NULL != shader );
514 if( mImpl->shaders.Count() == 0 )
516 // the first added shader becomes our default shader
517 // Construct message in the render queue memory; note that delete should not be called on the return value
518 typedef MessageValue1< RenderManager, Shader* > DerivedType;
520 // Reserve some memory inside the render queue
521 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
523 // Construct message in the render queue memory; note that delete should not be called on the return value
524 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
527 mImpl->shaders.PushBack( shader );
529 // Allows the shader to dispatch texture requests to the cache
530 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
533 void UpdateManager::RemoveShader( Shader* shader )
535 DALI_ASSERT_DEBUG(shader != NULL);
537 ShaderContainer& shaders = mImpl->shaders;
539 // Find the shader and destroy it
540 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
542 Shader& current = **iter;
543 if ( ¤t == shader )
545 // Transfer ownership to the discard queue
546 // This keeps the shader alive, until the render-thread has finished with it
547 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
552 // Should not reach here
553 DALI_ASSERT_DEBUG(false);
556 void UpdateManager::SetShaderProgram( Shader* shader,
557 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
562 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
564 // Reserve some memory inside the render queue
565 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
567 // Construct message in the render queue memory; note that delete should not be called on the return value
568 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
572 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
574 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
575 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
577 // lock as update might be sending previously compiled shaders to event thread
578 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
579 mImpl->renderCompiledShaders.push_back( shaderData );
583 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
587 // copy the list, this is only likely to happen once in application life cycle
588 return &(mImpl->taskList);
592 // copy the list, this is only likely to happen once in application life cycle
593 return &(mImpl->systemLevelTaskList);
597 void UpdateManager::AddGesture( PanGesture* gesture )
599 DALI_ASSERT_DEBUG( NULL != gesture );
601 mImpl->gestures.PushBack( gesture );
604 void UpdateManager::RemoveGesture( PanGesture* gesture )
606 DALI_ASSERT_DEBUG( gesture != NULL );
608 GestureContainer& gestures = mImpl->gestures;
610 // Find the gesture and destroy it
611 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
613 PanGesture& current = **iter;
614 if ( ¤t == gesture )
616 mImpl->gestures.Erase( iter );
620 // Should not reach here
621 DALI_ASSERT_DEBUG(false);
624 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
626 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
629 void UpdateManager::EventProcessingStarted()
631 mImpl->messageQueue.EventProcessingStarted();
634 bool UpdateManager::FlushQueue()
636 return mImpl->messageQueue.FlushQueue();
639 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
641 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
642 mImpl->animationFinishedDuringUpdate = false;
644 // Animated properties have to be reset to their original value each frame
646 // Reset root properties
649 mImpl->root->ResetToBaseValues( bufferIndex );
651 if ( mImpl->systemLevelRoot )
653 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
656 // Reset all the nodes
657 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
658 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
659 for(;iter != endIter; ++iter)
661 (*iter)->ResetToBaseValues( bufferIndex );
664 // Reset system-level render-task list properties to base values
665 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
667 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
669 (*iter)->ResetToBaseValues( bufferIndex );
672 // Reset render-task list properties to base values.
673 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
675 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
677 (*iter)->ResetToBaseValues( bufferIndex );
680 // Reset custom object properties to base values
681 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
683 (*iter)->ResetToBaseValues( bufferIndex );
686 mImpl->materials.ResetToBaseValues( bufferIndex );
687 mImpl->geometries.ResetToBaseValues( bufferIndex );
688 mImpl->renderers.ResetToBaseValues( bufferIndex );
690 // Reset animatable shader properties to base values
691 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
693 (*iter)->ResetToBaseValues( bufferIndex );
697 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
699 bool gestureUpdated( false );
701 // constrain gestures... (in construction order)
702 GestureContainer& gestures = mImpl->gestures;
704 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
706 PanGesture& gesture = **iter;
707 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
708 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
711 return gestureUpdated;
714 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
716 AnimationContainer &animations = mImpl->animations;
717 AnimationIter iter = animations.Begin();
718 while ( iter != animations.End() )
720 Animation* animation = *iter;
721 bool finished = animation->Update( bufferIndex, elapsedSeconds );
723 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
725 // Remove animations that had been destroyed but were still waiting for an update
726 if (animation->GetState() == Animation::Destroyed)
728 iter = animations.Erase(iter);
736 if ( mImpl->animationFinishedDuringUpdate )
738 // The application should be notified by NotificationManager, in another thread
739 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
743 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
745 //Constrain custom objects (in construction order)
746 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
747 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
748 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
750 PropertyOwner& object = **iter;
751 ConstrainPropertyOwner( object, bufferIndex );
755 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
757 // Constrain system-level render-tasks
758 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
759 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
761 RenderTask& task = **iter;
762 ConstrainPropertyOwner( task, bufferIndex );
765 // Constrain render-tasks
766 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
767 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
769 RenderTask& task = **iter;
770 ConstrainPropertyOwner( task, bufferIndex );
774 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
776 // constrain shaders... (in construction order)
777 ShaderContainer& shaders = mImpl->shaders;
778 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
780 Shader& shader = **iter;
781 ConstrainPropertyOwner( shader, bufferIndex );
785 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
787 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
788 PropertyNotificationIter iter = notifications.Begin();
790 while ( iter != notifications.End() )
792 PropertyNotification* notification = *iter;
793 bool valid = notification->Check( bufferIndex );
796 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
802 void UpdateManager::PrepareMaterials( BufferIndex bufferIndex )
804 ObjectOwnerContainer<Material>::Iterator iter = mImpl->materials.GetObjectContainer().Begin();
805 const ObjectOwnerContainer<Material>::Iterator end = mImpl->materials.GetObjectContainer().End();
806 for( ; iter != end; ++iter )
809 ConstrainPropertyOwner( *(*iter), bufferIndex );
812 (*iter)->Prepare( mImpl->resourceManager );
816 void UpdateManager::ForwardCompiledShadersToEventThread()
818 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
819 if( mImpl->shaderSaver )
821 // lock and swap the queues
823 // render might be attempting to send us more binaries at the same time
824 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
825 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
828 if( mImpl->updateCompiledShaders.size() > 0 )
830 ShaderSaver& factory = *mImpl->shaderSaver;
831 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
832 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
833 for( ; i != end; ++i )
835 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
837 // we don't need them in update anymore
838 mImpl->updateCompiledShaders.clear();
843 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
845 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
846 unsigned int rendererCount( rendererContainer.Size() );
847 for( unsigned int i(0); i<rendererCount; ++i )
850 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
852 if( rendererContainer[i]->IsReferenced() )
854 rendererContainer[i]->PrepareRender( bufferIndex );
859 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
861 mImpl->nodeDirtyFlags = NothingFlag;
868 // Prepare resources, update shaders, update attachments, for each node
869 // And add the renderers to the sorted layers. Start from root, which is also a layer
870 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
872 mImpl->resourceManager,
873 mImpl->renderQueue );
875 if ( mImpl->systemLevelRoot )
877 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
879 mImpl->resourceManager,
880 mImpl->renderQueue );
884 unsigned int UpdateManager::Update( float elapsedSeconds,
885 unsigned int lastVSyncTimeMilliseconds,
886 unsigned int nextVSyncTimeMilliseconds )
888 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
890 //Clear nodes/resources which were previously discarded
891 mImpl->discardQueue.Clear( bufferIndex );
893 //Grab any loaded resources
894 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
896 //Process Touches & Gestures
897 mImpl->touchResampler.Update();
898 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
900 const bool updateScene = // The scene-graph requires an update if..
901 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
902 IsAnimationRunning() || // ..at least one animation is running OR
903 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
904 resourceChanged || // ..one or more resources were updated/changed OR
905 gestureUpdated; // ..a gesture property was updated
908 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
909 // values if the scene was updated in the previous frame.
910 if( updateScene || mImpl->previousUpdateScene )
912 //Reset properties from the previous update
913 ResetProperties( bufferIndex );
916 //Process the queued scene messages
917 mImpl->messageQueue.ProcessMessages( bufferIndex );
919 //Post Process Ids of resources updated by renderer
920 mImpl->resourceManager.PostProcessResources( bufferIndex );
922 //Forward compiled shader programs to event thread for saving
923 ForwardCompiledShadersToEventThread();
925 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
926 // renderer lists if the scene was updated in the previous frame.
927 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
928 if( updateScene || mImpl->previousUpdateScene )
931 Animate( bufferIndex, elapsedSeconds );
933 //Constraint custom objects
934 ConstrainCustomObjects( bufferIndex );
936 //Prepare materials and apply constraints to them
937 PrepareMaterials( bufferIndex );
939 //Clear the lists of renderable-attachments from the previous update
940 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
942 mImpl->sortedLayers[i]->ClearRenderables();
945 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
947 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
950 //Update node hierarchy, apply constraints and perform sorting / culling.
951 //This will populate each Layer with a list of renderers which are ready.
952 UpdateNodes( bufferIndex );
954 //Apply constraints to RenderTasks, shaders and geometries
955 ConstrainRenderTasks( bufferIndex );
956 ConstrainShaders( bufferIndex );
957 mImpl->geometries.ConstrainObjects( bufferIndex );
959 //Update renderers and apply constraints
960 UpdateRenderers( bufferIndex );
962 //Process Property Notifications
963 ProcessPropertyNotifications( bufferIndex );
965 //Process the RenderTasks; this creates the instructions for rendering the next frame.
966 //reset the update buffer index and make sure there is enough room in the instruction container
967 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
968 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
970 if ( NULL != mImpl->root )
972 ProcessRenderTasks( bufferIndex,
976 mImpl->renderSortingHelper,
977 mImpl->renderInstructions );
979 // Process the system-level RenderTasks last
980 if ( NULL != mImpl->systemLevelRoot )
982 ProcessRenderTasks( bufferIndex,
983 mImpl->systemLevelTaskList,
984 *mImpl->systemLevelRoot,
985 mImpl->systemLevelSortedLayers,
986 mImpl->renderSortingHelper,
987 mImpl->renderInstructions );
992 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
993 bool doRenderOnceNotify = false;
994 mImpl->renderTaskWaiting = false;
995 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
996 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
997 endIter != iter; ++iter )
999 RenderTask& renderTask(*(*iter));
1001 renderTask.UpdateState();
1003 if( renderTask.IsWaitingToRender() &&
1004 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1006 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1009 if( renderTask.HasRendered() )
1011 doRenderOnceNotify = true;
1015 if( doRenderOnceNotify )
1017 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1018 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1021 // Macro is undefined in release build.
1022 SNAPSHOT_NODE_LOGGING;
1024 // A ResetProperties() may be required in the next frame
1025 mImpl->previousUpdateScene = updateScene;
1027 // Check whether further updates are required
1028 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1030 // tell the update manager that we're done so the queue can be given to event thread
1031 mImpl->notificationManager.UpdateCompleted();
1033 // The update has finished; swap the double-buffering indices
1034 mSceneGraphBuffers.Swap();
1036 return keepUpdating;
1039 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1041 // Update the duration set via Stage::KeepRendering()
1042 if ( mImpl->keepRenderingSeconds > 0.0f )
1044 mImpl->keepRenderingSeconds -= elapsedSeconds;
1047 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1049 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1050 // Keep updating until no messages are received and no animations are running.
1051 // If an animation has just finished, update at least once more for Discard end-actions.
1052 // No need to check for renderQueue as there is always a render after update and if that
1053 // render needs another update it will tell the adaptor to call update again
1055 if ( mImpl->keepRenderingSeconds > 0.0f )
1057 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1060 if ( IsAnimationRunning() ||
1061 mImpl->animationFinishedDuringUpdate )
1063 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1066 if ( mImpl->renderTaskWaiting )
1068 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1071 return keepUpdatingRequest;
1074 void UpdateManager::SetBackgroundColor( const Vector4& color )
1076 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1078 // Reserve some memory inside the render queue
1079 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1081 // Construct message in the render queue memory; note that delete should not be called on the return value
1082 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1085 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1087 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1089 // Reserve some memory inside the render queue
1090 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1092 // Construct message in the render queue memory; note that delete should not be called on the return value
1093 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1096 void UpdateManager::KeepRendering( float durationSeconds )
1098 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1101 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1105 // just copy the vector of pointers
1106 mImpl->sortedLayers = layers;
1110 mImpl->systemLevelSortedLayers = layers;
1114 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1116 mImpl->shaderSaver = &upstream;
1119 void UpdateManager::AddSampler( Render::Sampler* sampler )
1121 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1123 // Reserve some memory inside the render queue
1124 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1126 // Construct message in the render queue memory; note that delete should not be called on the return value
1127 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1130 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1132 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1134 // Reserve some memory inside the render queue
1135 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1137 // Construct message in the render queue memory; note that delete should not be called on the return value
1138 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1141 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1143 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1145 // Reserve some memory inside the render queue
1146 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1148 // Construct message in the render queue memory; note that delete should not be called on the return value
1149 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1152 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1154 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1156 // Reserve some memory inside the render queue
1157 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1159 // Construct message in the render queue memory; note that delete should not be called on the return value
1160 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1163 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1165 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1167 // Reserve some memory inside the render queue
1168 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1170 // Construct message in the render queue memory; note that delete should not be called on the return value
1171 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1174 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1176 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1178 // Reserve some memory inside the render queue
1179 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1181 // Construct message in the render queue memory; note that delete should not be called on the return value
1182 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1185 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1187 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1189 // Reserve some memory inside the render queue
1190 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1192 // Construct message in the render queue memory; note that delete should not be called on the return value
1193 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1196 void UpdateManager::SetPropertyBufferData(Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data)
1198 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>* > DerivedType;
1200 // Reserve some memory inside the render queue
1201 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1203 // Construct message in the render queue memory; note that delete should not be called on the return value
1204 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data );
1207 void UpdateManager::SetPropertyBufferSize(Render::PropertyBuffer* propertyBuffer, size_t size )
1209 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, size_t > DerivedType;
1211 // Reserve some memory inside the render queue
1212 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1214 // Construct message in the render queue memory; note that delete should not be called on the return value
1215 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferSize, propertyBuffer, size );
1218 } // namespace SceneGraph
1220 } // namespace Internal