2 * Copyright (c) 2016 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/common/texture-cache-dispatcher.h>
45 #include <dali/internal/update/controllers/render-message-dispatcher.h>
46 #include <dali/internal/update/controllers/scene-controller-impl.h>
47 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
48 #include <dali/internal/update/manager/object-owner-container.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/manager/transform-manager.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/rendering/scene-graph-texture-set.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>
69 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
71 // Un-comment to enable node tree debug logging
72 //#define NODE_TREE_LOGGING 1
74 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
75 #define SNAPSHOT_NODE_LOGGING \
76 const int FRAME_COUNT_TRIGGER = 16;\
77 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
79 if ( NULL != mImpl->root )\
81 mImpl->frameCounter = 0;\
82 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
85 mImpl->frameCounter++;
87 #define SNAPSHOT_NODE_LOGGING
90 #if defined(DEBUG_ENABLED)
91 extern Debug::Filter* gRenderTaskLogFilter;
95 using namespace Dali::Integration;
96 using Dali::Internal::Update::MessageQueue;
107 typedef OwnerContainer< Shader* > ShaderContainer;
108 typedef ShaderContainer::Iterator ShaderIter;
109 typedef ShaderContainer::ConstIterator ShaderConstIter;
111 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
113 typedef OwnerContainer<PanGesture*> GestureContainer;
114 typedef GestureContainer::Iterator GestureIter;
115 typedef GestureContainer::ConstIterator GestureConstIter;
117 typedef OwnerContainer< TextureSet* > TextureSetContainer;
118 typedef TextureSetContainer::Iterator TextureSetIter;
119 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
122 * Structure to contain UpdateManager internal data
124 struct UpdateManager::Impl
126 Impl( NotificationManager& notificationManager,
127 CompleteNotificationInterface& animationFinishedNotifier,
128 PropertyNotifier& propertyNotifier,
129 ResourceManager& resourceManager,
130 DiscardQueue& discardQueue,
131 RenderController& renderController,
132 RenderManager& renderManager,
133 RenderQueue& renderQueue,
134 TouchResampler& touchResampler,
135 SceneGraphBuffers& sceneGraphBuffers )
136 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
137 notificationManager( notificationManager ),
139 animationFinishedNotifier( animationFinishedNotifier ),
140 propertyNotifier( propertyNotifier ),
142 resourceManager( resourceManager ),
143 discardQueue( discardQueue ),
144 renderController( renderController ),
145 sceneController( NULL ),
146 renderManager( renderManager ),
147 renderQueue( renderQueue ),
148 renderInstructions( renderManager.GetRenderInstructionContainer() ),
149 touchResampler( touchResampler ),
150 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
151 taskList( renderMessageDispatcher, resourceManager ),
152 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
154 systemLevelRoot( NULL ),
155 renderers( sceneGraphBuffers, discardQueue ),
157 messageQueue( renderController, sceneGraphBuffers ),
158 keepRenderingSeconds( 0.0f ),
159 animationFinishedDuringUpdate( false ),
160 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
161 previousUpdateScene( false ),
163 renderSortingHelper(),
164 renderTaskWaiting( false )
166 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
168 renderers.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 delete sceneController;
218 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
219 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
220 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
221 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
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< Camera* > cameras; ///< A container of cameras
248 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
250 AnimationContainer animations; ///< A container of owned animations
251 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
253 ObjectOwnerContainer<Renderer> renderers;
254 TextureSetContainer textureSets; ///< A container of texture sets
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 TextureCacheDispatcher& textureCacheDispatcher,
285 TouchResampler& touchResampler )
288 mImpl = new Impl( notificationManager,
289 animationFinishedNotifier,
297 mSceneGraphBuffers );
299 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
302 UpdateManager::~UpdateManager()
307 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
309 DALI_ASSERT_DEBUG( layer->IsLayer() );
310 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
314 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
316 mImpl->root->CreateTransform( &mImpl->transformManager);
320 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
321 mImpl->systemLevelRoot = layer;
322 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
325 layer->SetRoot(true);
328 void UpdateManager::AddNode( Node* node )
330 DALI_ASSERT_ALWAYS( NULL != node );
331 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
333 // Nodes must be sorted by pointer
334 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
335 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
339 mImpl->nodes.Insert((iter+1), node);
340 node->CreateTransform( &mImpl->transformManager);
346 void UpdateManager::ConnectNode( Node* parent, Node* node )
348 DALI_ASSERT_ALWAYS( NULL != parent );
349 DALI_ASSERT_ALWAYS( NULL != node );
350 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
352 parent->ConnectChild( node );
355 void UpdateManager::DisconnectNode( Node* node )
357 Node* parent = node->GetParent();
358 DALI_ASSERT_ALWAYS( NULL != parent );
359 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
361 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
364 void UpdateManager::DestroyNode( Node* node )
366 DALI_ASSERT_ALWAYS( NULL != node );
367 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
369 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
370 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
371 for(;iter!=endIter;++iter)
375 mImpl->nodes.Erase(iter);
380 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
382 // Notify the Node about impending destruction
386 void UpdateManager::AddCamera( Camera* camera )
388 DALI_ASSERT_DEBUG( camera != NULL );
390 mImpl->cameras.PushBack( camera ); // takes ownership
393 void UpdateManager::RemoveCamera( const Camera* camera )
396 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
397 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
398 for ( ; iter != end; ++iter )
400 Camera* value = *iter;
401 if ( camera == value )
403 // Transfer ownership to the discard queue
404 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
412 void UpdateManager::AddObject( PropertyOwner* object )
414 DALI_ASSERT_DEBUG( NULL != object );
416 mImpl->customObjects.PushBack( object );
419 void UpdateManager::RemoveObject( PropertyOwner* object )
421 DALI_ASSERT_DEBUG( NULL != object );
423 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
425 // Find the object and destroy it
426 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
428 PropertyOwner* current = *iter;
429 if ( current == object )
431 customObjects.Erase( iter );
436 // Should not reach here
437 DALI_ASSERT_DEBUG(false);
440 void UpdateManager::AddAnimation( Animation* animation )
442 mImpl->animations.PushBack( animation );
445 void UpdateManager::StopAnimation( Animation* animation )
447 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
449 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
451 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
454 void UpdateManager::RemoveAnimation( Animation* animation )
456 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
458 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
460 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
463 bool UpdateManager::IsAnimationRunning() const
465 bool isRunning(false);
466 AnimationContainer& animations = mImpl->animations;
468 // Find any animation that isn't stopped or paused
470 const AnimationIter endIter = animations.End();
471 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
473 const Animation::State state = (*iter)->GetState();
475 if (state != Animation::Stopped &&
476 state != Animation::Paused)
485 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
487 mImpl->propertyNotifications.PushBack( propertyNotification );
490 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
492 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
493 PropertyNotificationIter iter = propertyNotifications.Begin();
495 while ( iter != propertyNotifications.End() )
497 if( *iter == propertyNotification )
499 propertyNotifications.Erase(iter);
506 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
508 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
509 propertyNotification->SetNotifyMode( notifyMode );
512 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
514 return mImpl->renderers;
517 void UpdateManager::AddShader( Shader* shader )
519 DALI_ASSERT_DEBUG( NULL != shader );
521 if( mImpl->shaders.Count() == 0 )
523 // the first added shader becomes our default shader
524 // Construct message in the render queue memory; note that delete should not be called on the return value
525 typedef MessageValue1< RenderManager, Shader* > DerivedType;
527 // Reserve some memory inside the render queue
528 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
530 // Construct message in the render queue memory; note that delete should not be called on the return value
531 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
534 mImpl->shaders.PushBack( shader );
537 void UpdateManager::RemoveShader( Shader* shader )
539 DALI_ASSERT_DEBUG(shader != NULL);
541 ShaderContainer& shaders = mImpl->shaders;
543 // Find the shader and destroy it
544 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
546 Shader& current = **iter;
547 if ( ¤t == shader )
549 // Transfer ownership to the discard queue
550 // This keeps the shader alive, until the render-thread has finished with it
551 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
556 // Should not reach here
557 DALI_ASSERT_DEBUG(false);
560 void UpdateManager::SetShaderProgram( Shader* shader,
561 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
566 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
568 // Reserve some memory inside the render queue
569 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
571 // Construct message in the render queue memory; note that delete should not be called on the return value
572 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
576 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
578 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
579 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
581 // lock as update might be sending previously compiled shaders to event thread
582 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
583 mImpl->renderCompiledShaders.push_back( shaderData );
587 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
591 // copy the list, this is only likely to happen once in application life cycle
592 return &(mImpl->taskList);
596 // copy the list, this is only likely to happen once in application life cycle
597 return &(mImpl->systemLevelTaskList);
601 void UpdateManager::AddGesture( PanGesture* gesture )
603 DALI_ASSERT_DEBUG( NULL != gesture );
605 mImpl->gestures.PushBack( gesture );
608 void UpdateManager::RemoveGesture( PanGesture* gesture )
610 DALI_ASSERT_DEBUG( gesture != NULL );
612 GestureContainer& gestures = mImpl->gestures;
614 // Find the gesture and destroy it
615 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
617 PanGesture& current = **iter;
618 if ( ¤t == gesture )
620 mImpl->gestures.Erase( iter );
624 // Should not reach here
625 DALI_ASSERT_DEBUG(false);
628 void UpdateManager::AddTextureSet( TextureSet* textureSet )
630 DALI_ASSERT_DEBUG( NULL != textureSet );
631 mImpl->textureSets.PushBack( textureSet );
634 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
636 DALI_ASSERT_DEBUG(textureSet != NULL);
637 size_t textureSetCount( mImpl->textureSets.Size() );
638 for( size_t i(0); i<textureSetCount; ++i )
640 if( textureSet == mImpl->textureSets[i] )
642 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
648 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
650 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
653 void UpdateManager::EventProcessingStarted()
655 mImpl->messageQueue.EventProcessingStarted();
658 bool UpdateManager::FlushQueue()
660 return mImpl->messageQueue.FlushQueue();
663 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
665 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
666 mImpl->animationFinishedDuringUpdate = false;
668 // Animated properties have to be reset to their original value each frame
670 // Reset root properties
673 mImpl->root->ResetToBaseValues( bufferIndex );
675 if ( mImpl->systemLevelRoot )
677 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
680 // Reset all the nodes
681 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
682 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
683 for(;iter != endIter; ++iter)
685 (*iter)->ResetToBaseValues( bufferIndex );
688 // Reset system-level render-task list properties to base values
689 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
691 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
693 (*iter)->ResetToBaseValues( bufferIndex );
696 // Reset render-task list properties to base values.
697 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
699 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
701 (*iter)->ResetToBaseValues( bufferIndex );
704 // Reset custom object properties to base values
705 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
707 (*iter)->ResetToBaseValues( bufferIndex );
710 mImpl->renderers.ResetToBaseValues( bufferIndex );
712 // Reset animatable shader properties to base values
713 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
715 (*iter)->ResetToBaseValues( bufferIndex );
719 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
721 bool gestureUpdated( false );
723 // constrain gestures... (in construction order)
724 GestureContainer& gestures = mImpl->gestures;
726 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
728 PanGesture& gesture = **iter;
729 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
730 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
733 return gestureUpdated;
736 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
738 AnimationContainer &animations = mImpl->animations;
739 AnimationIter iter = animations.Begin();
740 bool animationLooped = false;
741 while ( iter != animations.End() )
743 Animation* animation = *iter;
744 bool finished = false;
746 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
748 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
749 animationLooped = animationLooped || looped;
751 // Remove animations that had been destroyed but were still waiting for an update
752 if (animation->GetState() == Animation::Destroyed)
754 iter = animations.Erase(iter);
762 // queue the notification on finished or looped (to update loop count)
763 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
765 // The application should be notified by NotificationManager, in another thread
766 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
770 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
772 //Constrain custom objects (in construction order)
773 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
774 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
775 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
777 PropertyOwner& object = **iter;
778 ConstrainPropertyOwner( object, bufferIndex );
782 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
784 // Constrain system-level render-tasks
785 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
786 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
788 RenderTask& task = **iter;
789 ConstrainPropertyOwner( task, bufferIndex );
792 // Constrain render-tasks
793 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
794 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
796 RenderTask& task = **iter;
797 ConstrainPropertyOwner( task, bufferIndex );
801 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
803 // constrain shaders... (in construction order)
804 ShaderContainer& shaders = mImpl->shaders;
805 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
807 Shader& shader = **iter;
808 ConstrainPropertyOwner( shader, bufferIndex );
812 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
814 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
815 PropertyNotificationIter iter = notifications.Begin();
817 while ( iter != notifications.End() )
819 PropertyNotification* notification = *iter;
820 bool valid = notification->Check( bufferIndex );
823 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
829 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
831 size_t textureSetCount( mImpl->textureSets.Size() );
832 for( size_t i(0); i<textureSetCount; ++i )
834 //Prepare texture set
835 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
839 void UpdateManager::ForwardCompiledShadersToEventThread()
841 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
842 if( mImpl->shaderSaver )
844 // lock and swap the queues
846 // render might be attempting to send us more binaries at the same time
847 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
848 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
851 if( mImpl->updateCompiledShaders.size() > 0 )
853 ShaderSaver& factory = *mImpl->shaderSaver;
854 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
855 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
856 for( ; i != end; ++i )
858 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
860 // we don't need them in update anymore
861 mImpl->updateCompiledShaders.clear();
866 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
868 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
869 unsigned int rendererCount( rendererContainer.Size() );
870 for( unsigned int i(0); i<rendererCount; ++i )
873 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
875 if( rendererContainer[i]->IsReferenced() )
877 rendererContainer[i]->PrepareRender( bufferIndex );
882 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
884 mImpl->nodeDirtyFlags = NothingFlag;
891 // Prepare resources, update shaders, for each node
892 // And add the renderers to the sorted layers. Start from root, which is also a layer
893 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
895 mImpl->resourceManager,
896 mImpl->renderQueue );
898 if ( mImpl->systemLevelRoot )
900 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
902 mImpl->resourceManager,
903 mImpl->renderQueue );
907 unsigned int UpdateManager::Update( float elapsedSeconds,
908 unsigned int lastVSyncTimeMilliseconds,
909 unsigned int nextVSyncTimeMilliseconds )
911 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
913 //Clear nodes/resources which were previously discarded
914 mImpl->discardQueue.Clear( bufferIndex );
916 //Grab any loaded resources
917 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
919 //Process Touches & Gestures
920 mImpl->touchResampler.Update();
921 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
923 const bool updateScene = // The scene-graph requires an update if..
924 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
925 IsAnimationRunning() || // ..at least one animation is running OR
926 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
927 resourceChanged || // ..one or more resources were updated/changed OR
928 gestureUpdated; // ..a gesture property was updated
931 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
932 // values if the scene was updated in the previous frame.
933 if( updateScene || mImpl->previousUpdateScene )
935 //Reset properties from the previous update
936 ResetProperties( bufferIndex );
937 mImpl->transformManager.ResetToBaseValue();
940 //Process the queued scene messages
941 mImpl->messageQueue.ProcessMessages( bufferIndex );
943 //Post Process Ids of resources updated by renderer
944 mImpl->resourceManager.PostProcessResources( bufferIndex );
946 //Forward compiled shader programs to event thread for saving
947 ForwardCompiledShadersToEventThread();
949 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
950 // renderer lists if the scene was updated in the previous frame.
951 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
952 if( updateScene || mImpl->previousUpdateScene )
955 Animate( bufferIndex, elapsedSeconds );
957 //Constraint custom objects
958 ConstrainCustomObjects( bufferIndex );
960 //Prepare texture sets and apply constraints to them
961 PrepareTextureSets( bufferIndex );
963 //Clear the lists of renderers from the previous update
964 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
966 mImpl->sortedLayers[i]->ClearRenderables();
969 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
971 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
974 //Update node hierarchy, apply constraints and perform sorting / culling.
975 //This will populate each Layer with a list of renderers which are ready.
976 UpdateNodes( bufferIndex );
978 //Apply constraints to RenderTasks, shaders
979 ConstrainRenderTasks( bufferIndex );
980 ConstrainShaders( bufferIndex );
982 //Update renderers and apply constraints
983 UpdateRenderers( bufferIndex );
985 //Update the trnasformations of all the nodes
986 mImpl->transformManager.Update();
988 //Process Property Notifications
989 ProcessPropertyNotifications( bufferIndex );
991 //Process the RenderTasks; this creates the instructions for rendering the next frame.
992 //reset the update buffer index and make sure there is enough room in the instruction container
993 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
994 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
996 if ( NULL != mImpl->root )
998 ProcessRenderTasks( bufferIndex,
1001 mImpl->sortedLayers,
1002 mImpl->renderSortingHelper,
1003 mImpl->renderInstructions );
1005 // Process the system-level RenderTasks last
1006 if ( NULL != mImpl->systemLevelRoot )
1008 ProcessRenderTasks( bufferIndex,
1009 mImpl->systemLevelTaskList,
1010 *mImpl->systemLevelRoot,
1011 mImpl->systemLevelSortedLayers,
1012 mImpl->renderSortingHelper,
1013 mImpl->renderInstructions );
1018 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1019 bool doRenderOnceNotify = false;
1020 mImpl->renderTaskWaiting = false;
1021 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1022 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1023 endIter != iter; ++iter )
1025 RenderTask& renderTask(*(*iter));
1027 renderTask.UpdateState();
1029 if( renderTask.IsWaitingToRender() &&
1030 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1032 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1035 if( renderTask.HasRendered() )
1037 doRenderOnceNotify = true;
1041 if( doRenderOnceNotify )
1043 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1044 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1047 // Macro is undefined in release build.
1048 SNAPSHOT_NODE_LOGGING;
1050 // A ResetProperties() may be required in the next frame
1051 mImpl->previousUpdateScene = updateScene;
1053 // Check whether further updates are required
1054 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1056 // tell the update manager that we're done so the queue can be given to event thread
1057 mImpl->notificationManager.UpdateCompleted();
1059 // The update has finished; swap the double-buffering indices
1060 mSceneGraphBuffers.Swap();
1062 return keepUpdating;
1065 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1067 // Update the duration set via Stage::KeepRendering()
1068 if ( mImpl->keepRenderingSeconds > 0.0f )
1070 mImpl->keepRenderingSeconds -= elapsedSeconds;
1073 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1075 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1076 // Keep updating until no messages are received and no animations are running.
1077 // If an animation has just finished, update at least once more for Discard end-actions.
1078 // No need to check for renderQueue as there is always a render after update and if that
1079 // render needs another update it will tell the adaptor to call update again
1081 if ( mImpl->keepRenderingSeconds > 0.0f )
1083 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1086 if ( IsAnimationRunning() ||
1087 mImpl->animationFinishedDuringUpdate )
1089 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1092 if ( mImpl->renderTaskWaiting )
1094 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1097 return keepUpdatingRequest;
1100 void UpdateManager::SetBackgroundColor( const Vector4& color )
1102 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1104 // Reserve some memory inside the render queue
1105 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1107 // Construct message in the render queue memory; note that delete should not be called on the return value
1108 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1111 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1113 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1115 // Reserve some memory inside the render queue
1116 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1118 // Construct message in the render queue memory; note that delete should not be called on the return value
1119 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1122 void UpdateManager::KeepRendering( float durationSeconds )
1124 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1127 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1131 // just copy the vector of pointers
1132 mImpl->sortedLayers = layers;
1136 mImpl->systemLevelSortedLayers = layers;
1140 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1142 mImpl->shaderSaver = &upstream;
1145 void UpdateManager::AddSampler( Render::Sampler* sampler )
1147 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1149 // Reserve some memory inside the render queue
1150 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1152 // Construct message in the render queue memory; note that delete should not be called on the return value
1153 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1156 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1158 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1160 // Reserve some memory inside the render queue
1161 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1163 // Construct message in the render queue memory; note that delete should not be called on the return value
1164 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1167 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1169 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1171 // Reserve some memory inside the render queue
1172 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174 // Construct message in the render queue memory; note that delete should not be called on the return value
1175 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1178 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1180 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1182 // Reserve some memory inside the render queue
1183 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1185 // Construct message in the render queue memory; note that delete should not be called on the return value
1186 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1189 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1191 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1193 // Reserve some memory inside the render queue
1194 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1196 // Construct message in the render queue memory; note that delete should not be called on the return value
1197 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1200 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1202 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1204 // Reserve some memory inside the render queue
1205 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1207 // Construct message in the render queue memory; note that delete should not be called on the return value
1208 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1211 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1213 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1215 // Reserve some memory inside the render queue
1216 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1218 // Construct message in the render queue memory; note that delete should not be called on the return value
1219 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1222 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1224 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1226 // Reserve some memory inside the render queue
1227 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1229 // Construct message in the render queue memory; note that delete should not be called on the return value
1230 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1233 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1235 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1237 // Reserve some memory inside the render queue
1238 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1240 // Construct message in the render queue memory; note that delete should not be called on the return value
1241 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1244 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1246 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1248 // Reserve some memory inside the render queue
1249 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1251 // Construct message in the render queue memory; note that delete should not be called on the return value
1252 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1255 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1257 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1259 // Reserve some memory inside the render queue
1260 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1262 // Construct message in the render queue memory; note that delete should not be called on the return value
1263 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1266 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1268 typedef IndexBufferMessage< RenderManager > DerivedType;
1270 // Reserve some memory inside the render queue
1271 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1273 // Construct message in the render queue memory; note that delete should not be called on the return value
1274 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1277 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1279 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1281 // Reserve some memory inside the render queue
1282 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1284 // Construct message in the render queue memory; note that delete should not be called on the return value
1285 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1288 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1290 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1292 // Reserve some memory inside the render queue
1293 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1295 // Construct message in the render queue memory; note that delete should not be called on the return value
1296 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1300 } // namespace SceneGraph
1302 } // namespace Internal