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 bool animationLooped = false;
719 while ( iter != animations.End() )
721 Animation* animation = *iter;
722 bool finished = false;
724 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
726 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
727 animationLooped = animationLooped || looped;
729 // Remove animations that had been destroyed but were still waiting for an update
730 if (animation->GetState() == Animation::Destroyed)
732 iter = animations.Erase(iter);
740 // queue the notification on finished or looped (to update loop count)
741 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
743 // The application should be notified by NotificationManager, in another thread
744 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
748 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
750 //Constrain custom objects (in construction order)
751 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
752 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
753 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
755 PropertyOwner& object = **iter;
756 ConstrainPropertyOwner( object, bufferIndex );
760 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
762 // Constrain system-level render-tasks
763 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
764 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
766 RenderTask& task = **iter;
767 ConstrainPropertyOwner( task, bufferIndex );
770 // Constrain render-tasks
771 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
772 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
774 RenderTask& task = **iter;
775 ConstrainPropertyOwner( task, bufferIndex );
779 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
781 // constrain shaders... (in construction order)
782 ShaderContainer& shaders = mImpl->shaders;
783 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
785 Shader& shader = **iter;
786 ConstrainPropertyOwner( shader, bufferIndex );
790 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
792 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
793 PropertyNotificationIter iter = notifications.Begin();
795 while ( iter != notifications.End() )
797 PropertyNotification* notification = *iter;
798 bool valid = notification->Check( bufferIndex );
801 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
807 void UpdateManager::PrepareMaterials( BufferIndex bufferIndex )
809 ObjectOwnerContainer<Material>::Iterator iter = mImpl->materials.GetObjectContainer().Begin();
810 const ObjectOwnerContainer<Material>::Iterator end = mImpl->materials.GetObjectContainer().End();
811 for( ; iter != end; ++iter )
814 ConstrainPropertyOwner( *(*iter), bufferIndex );
817 (*iter)->Prepare( mImpl->resourceManager );
821 void UpdateManager::ForwardCompiledShadersToEventThread()
823 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
824 if( mImpl->shaderSaver )
826 // lock and swap the queues
828 // render might be attempting to send us more binaries at the same time
829 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
830 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
833 if( mImpl->updateCompiledShaders.size() > 0 )
835 ShaderSaver& factory = *mImpl->shaderSaver;
836 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
837 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
838 for( ; i != end; ++i )
840 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
842 // we don't need them in update anymore
843 mImpl->updateCompiledShaders.clear();
848 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
850 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
851 unsigned int rendererCount( rendererContainer.Size() );
852 for( unsigned int i(0); i<rendererCount; ++i )
855 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
857 if( rendererContainer[i]->IsReferenced() )
859 rendererContainer[i]->PrepareRender( bufferIndex );
864 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
866 mImpl->nodeDirtyFlags = NothingFlag;
873 // Prepare resources, update shaders, update attachments, for each node
874 // And add the renderers to the sorted layers. Start from root, which is also a layer
875 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
877 mImpl->resourceManager,
878 mImpl->renderQueue );
880 if ( mImpl->systemLevelRoot )
882 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
884 mImpl->resourceManager,
885 mImpl->renderQueue );
889 unsigned int UpdateManager::Update( float elapsedSeconds,
890 unsigned int lastVSyncTimeMilliseconds,
891 unsigned int nextVSyncTimeMilliseconds )
893 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
895 //Clear nodes/resources which were previously discarded
896 mImpl->discardQueue.Clear( bufferIndex );
898 //Grab any loaded resources
899 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
901 //Process Touches & Gestures
902 mImpl->touchResampler.Update();
903 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
905 const bool updateScene = // The scene-graph requires an update if..
906 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
907 IsAnimationRunning() || // ..at least one animation is running OR
908 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
909 resourceChanged || // ..one or more resources were updated/changed OR
910 gestureUpdated; // ..a gesture property was updated
913 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
914 // values if the scene was updated in the previous frame.
915 if( updateScene || mImpl->previousUpdateScene )
917 //Reset properties from the previous update
918 ResetProperties( bufferIndex );
921 //Process the queued scene messages
922 mImpl->messageQueue.ProcessMessages( bufferIndex );
924 //Post Process Ids of resources updated by renderer
925 mImpl->resourceManager.PostProcessResources( bufferIndex );
927 //Forward compiled shader programs to event thread for saving
928 ForwardCompiledShadersToEventThread();
930 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
931 // renderer lists if the scene was updated in the previous frame.
932 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
933 if( updateScene || mImpl->previousUpdateScene )
936 Animate( bufferIndex, elapsedSeconds );
938 //Constraint custom objects
939 ConstrainCustomObjects( bufferIndex );
941 //Prepare materials and apply constraints to them
942 PrepareMaterials( bufferIndex );
944 //Clear the lists of renderable-attachments from the previous update
945 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
947 mImpl->sortedLayers[i]->ClearRenderables();
950 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
952 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
955 //Update node hierarchy, apply constraints and perform sorting / culling.
956 //This will populate each Layer with a list of renderers which are ready.
957 UpdateNodes( bufferIndex );
959 //Apply constraints to RenderTasks, shaders and geometries
960 ConstrainRenderTasks( bufferIndex );
961 ConstrainShaders( bufferIndex );
962 mImpl->geometries.ConstrainObjects( bufferIndex );
964 //Update renderers and apply constraints
965 UpdateRenderers( bufferIndex );
967 //Process Property Notifications
968 ProcessPropertyNotifications( bufferIndex );
970 //Process the RenderTasks; this creates the instructions for rendering the next frame.
971 //reset the update buffer index and make sure there is enough room in the instruction container
972 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
973 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
975 if ( NULL != mImpl->root )
977 ProcessRenderTasks( bufferIndex,
981 mImpl->renderSortingHelper,
982 mImpl->renderInstructions );
984 // Process the system-level RenderTasks last
985 if ( NULL != mImpl->systemLevelRoot )
987 ProcessRenderTasks( bufferIndex,
988 mImpl->systemLevelTaskList,
989 *mImpl->systemLevelRoot,
990 mImpl->systemLevelSortedLayers,
991 mImpl->renderSortingHelper,
992 mImpl->renderInstructions );
997 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
998 bool doRenderOnceNotify = false;
999 mImpl->renderTaskWaiting = false;
1000 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1001 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1002 endIter != iter; ++iter )
1004 RenderTask& renderTask(*(*iter));
1006 renderTask.UpdateState();
1008 if( renderTask.IsWaitingToRender() &&
1009 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1011 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1014 if( renderTask.HasRendered() )
1016 doRenderOnceNotify = true;
1020 if( doRenderOnceNotify )
1022 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1023 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1026 // Macro is undefined in release build.
1027 SNAPSHOT_NODE_LOGGING;
1029 // A ResetProperties() may be required in the next frame
1030 mImpl->previousUpdateScene = updateScene;
1032 // Check whether further updates are required
1033 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1035 // tell the update manager that we're done so the queue can be given to event thread
1036 mImpl->notificationManager.UpdateCompleted();
1038 // The update has finished; swap the double-buffering indices
1039 mSceneGraphBuffers.Swap();
1041 return keepUpdating;
1044 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1046 // Update the duration set via Stage::KeepRendering()
1047 if ( mImpl->keepRenderingSeconds > 0.0f )
1049 mImpl->keepRenderingSeconds -= elapsedSeconds;
1052 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1054 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1055 // Keep updating until no messages are received and no animations are running.
1056 // If an animation has just finished, update at least once more for Discard end-actions.
1057 // No need to check for renderQueue as there is always a render after update and if that
1058 // render needs another update it will tell the adaptor to call update again
1060 if ( mImpl->keepRenderingSeconds > 0.0f )
1062 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1065 if ( IsAnimationRunning() ||
1066 mImpl->animationFinishedDuringUpdate )
1068 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1071 if ( mImpl->renderTaskWaiting )
1073 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1076 return keepUpdatingRequest;
1079 void UpdateManager::SetBackgroundColor( const Vector4& color )
1081 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1083 // Reserve some memory inside the render queue
1084 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1086 // Construct message in the render queue memory; note that delete should not be called on the return value
1087 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1090 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1092 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1094 // Reserve some memory inside the render queue
1095 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1097 // Construct message in the render queue memory; note that delete should not be called on the return value
1098 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1101 void UpdateManager::KeepRendering( float durationSeconds )
1103 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1106 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1110 // just copy the vector of pointers
1111 mImpl->sortedLayers = layers;
1115 mImpl->systemLevelSortedLayers = layers;
1119 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1121 mImpl->shaderSaver = &upstream;
1124 void UpdateManager::AddSampler( Render::Sampler* sampler )
1126 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1128 // Reserve some memory inside the render queue
1129 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1131 // Construct message in the render queue memory; note that delete should not be called on the return value
1132 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1135 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1137 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1139 // Reserve some memory inside the render queue
1140 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1142 // Construct message in the render queue memory; note that delete should not be called on the return value
1143 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1146 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1148 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1150 // Reserve some memory inside the render queue
1151 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1153 // Construct message in the render queue memory; note that delete should not be called on the return value
1154 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1157 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1159 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1161 // Reserve some memory inside the render queue
1162 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1164 // Construct message in the render queue memory; note that delete should not be called on the return value
1165 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1168 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1170 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1172 // Reserve some memory inside the render queue
1173 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1175 // Construct message in the render queue memory; note that delete should not be called on the return value
1176 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1179 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1181 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1183 // Reserve some memory inside the render queue
1184 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1186 // Construct message in the render queue memory; note that delete should not be called on the return value
1187 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1190 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1192 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1194 // Reserve some memory inside the render queue
1195 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1197 // Construct message in the render queue memory; note that delete should not be called on the return value
1198 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1201 void UpdateManager::SetPropertyBufferData(Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data)
1203 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>* > DerivedType;
1205 // Reserve some memory inside the render queue
1206 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1208 // Construct message in the render queue memory; note that delete should not be called on the return value
1209 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data );
1212 void UpdateManager::SetPropertyBufferSize(Render::PropertyBuffer* propertyBuffer, size_t size )
1214 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, size_t > DerivedType;
1216 // Reserve some memory inside the render queue
1217 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1219 // Construct message in the render queue memory; note that delete should not be called on the return value
1220 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferSize, propertyBuffer, size );
1223 } // namespace SceneGraph
1225 } // namespace Internal