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>
62 #include <dali/internal/render/common/render-instruction-container.h>
63 #include <dali/internal/render/common/render-manager.h>
64 #include <dali/internal/render/queue/render-queue.h>
65 #include <dali/internal/render/gl-resources/texture-cache.h>
66 #include <dali/internal/render/shaders/scene-graph-shader.h>
67 #include <dali/internal/render/renderers/render-sampler.h>
68 #include <dali/internal/update/render-tasks/scene-graph-camera.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;
116 typedef OwnerContainer< TextureSet* > TextureSetContainer;
117 typedef TextureSetContainer::Iterator TextureSetIter;
118 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
121 * Structure to contain UpdateManager internal data
123 struct UpdateManager::Impl
125 Impl( NotificationManager& notificationManager,
126 CompleteNotificationInterface& animationFinishedNotifier,
127 PropertyNotifier& propertyNotifier,
128 ResourceManager& resourceManager,
129 DiscardQueue& discardQueue,
130 RenderController& renderController,
131 RenderManager& renderManager,
132 RenderQueue& renderQueue,
133 SceneGraphBuffers& sceneGraphBuffers )
134 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
135 notificationManager( notificationManager ),
137 animationFinishedNotifier( animationFinishedNotifier ),
138 propertyNotifier( propertyNotifier ),
140 resourceManager( resourceManager ),
141 discardQueue( discardQueue ),
142 renderController( renderController ),
143 sceneController( NULL ),
144 renderManager( renderManager ),
145 renderQueue( renderQueue ),
146 renderInstructions( renderManager.GetRenderInstructionContainer() ),
147 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
148 taskList( renderMessageDispatcher, resourceManager ),
149 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
151 systemLevelRoot( NULL ),
152 renderers( sceneGraphBuffers, discardQueue ),
154 messageQueue( renderController, sceneGraphBuffers ),
155 keepRenderingSeconds( 0.0f ),
156 animationFinishedDuringUpdate( false ),
157 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
158 previousUpdateScene( false ),
160 renderSortingHelper(),
161 renderTaskWaiting( false )
163 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
165 renderers.SetSceneController( *sceneController );
167 // create first 'dummy' node
173 // Disconnect render tasks from nodes, before destroying the nodes
174 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
175 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
177 (*iter)->SetSourceNode( NULL );
179 // ..repeat for system level RenderTasks
180 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
181 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
183 (*iter)->SetSourceNode( NULL );
186 // UpdateManager owns the Nodes
187 Vector<Node*>::Iterator iter = nodes.Begin()+1;
188 Vector<Node*>::Iterator endIter = nodes.End();
189 for(;iter!=endIter;++iter)
191 (*iter)->OnDestroy();
195 // If there is root, reset it, otherwise do nothing as rendering was never started
204 if( systemLevelRoot )
206 systemLevelRoot->OnDestroy();
208 delete systemLevelRoot;
209 systemLevelRoot = NULL;
212 delete sceneController;
215 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
216 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
217 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
218 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
219 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
220 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
221 ShaderSaver* shaderSaver; ///< Saves shader binaries.
222 ResourceManager& resourceManager; ///< resource manager
223 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
224 RenderController& renderController; ///< render controller
225 SceneControllerImpl* sceneController; ///< scene controller
226 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
227 RenderQueue& renderQueue; ///< Used to queue messages for the next render
228 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
230 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
232 RenderTaskList taskList; ///< The list of scene graph render-tasks
233 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
235 Layer* root; ///< The root node (root is a layer)
236 Layer* systemLevelRoot; ///< A separate root-node for system-level content
238 Vector<Node*> nodes; ///< A container of all instantiated nodes
240 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
241 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
243 OwnerContainer< Camera* > cameras; ///< A container of cameras
244 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
246 AnimationContainer animations; ///< A container of owned animations
247 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
249 ObjectOwnerContainer<Renderer> renderers;
250 TextureSetContainer textureSets; ///< A container of texture sets
252 ShaderContainer shaders; ///< A container of owned shaders
254 MessageQueue messageQueue; ///< The messages queued from the event-thread
255 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
256 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
257 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
259 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
260 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
262 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
263 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
265 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
266 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
268 GestureContainer gestures; ///< A container of owned gesture detectors
269 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
272 UpdateManager::UpdateManager( NotificationManager& notificationManager,
273 CompleteNotificationInterface& animationFinishedNotifier,
274 PropertyNotifier& propertyNotifier,
275 ResourceManager& resourceManager,
276 DiscardQueue& discardQueue,
277 RenderController& controller,
278 RenderManager& renderManager,
279 RenderQueue& renderQueue,
280 TextureCacheDispatcher& textureCacheDispatcher )
283 mImpl = new Impl( notificationManager,
284 animationFinishedNotifier,
291 mSceneGraphBuffers );
293 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
296 UpdateManager::~UpdateManager()
301 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
303 DALI_ASSERT_DEBUG( layer->IsLayer() );
304 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
308 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
310 mImpl->root->CreateTransform( &mImpl->transformManager);
314 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
315 mImpl->systemLevelRoot = layer;
316 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
319 layer->SetRoot(true);
322 void UpdateManager::AddNode( Node* node )
324 DALI_ASSERT_ALWAYS( NULL != node );
325 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
327 // Nodes must be sorted by pointer
328 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
329 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
333 mImpl->nodes.Insert((iter+1), node);
334 node->CreateTransform( &mImpl->transformManager);
340 void UpdateManager::ConnectNode( Node* parent, Node* node )
342 DALI_ASSERT_ALWAYS( NULL != parent );
343 DALI_ASSERT_ALWAYS( NULL != node );
344 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
346 parent->ConnectChild( node );
349 void UpdateManager::DisconnectNode( Node* node )
351 Node* parent = node->GetParent();
352 DALI_ASSERT_ALWAYS( NULL != parent );
353 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
355 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
358 void UpdateManager::DestroyNode( Node* node )
360 DALI_ASSERT_ALWAYS( NULL != node );
361 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
363 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
364 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
365 for(;iter!=endIter;++iter)
369 mImpl->nodes.Erase(iter);
374 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
376 // Notify the Node about impending destruction
380 void UpdateManager::AddCamera( Camera* camera )
382 DALI_ASSERT_DEBUG( camera != NULL );
384 mImpl->cameras.PushBack( camera ); // takes ownership
387 void UpdateManager::RemoveCamera( const Camera* camera )
390 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
391 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
392 for ( ; iter != end; ++iter )
394 Camera* value = *iter;
395 if ( camera == value )
397 // Transfer ownership to the discard queue
398 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
406 void UpdateManager::AddObject( PropertyOwner* object )
408 DALI_ASSERT_DEBUG( NULL != object );
410 mImpl->customObjects.PushBack( object );
413 void UpdateManager::RemoveObject( PropertyOwner* object )
415 DALI_ASSERT_DEBUG( NULL != object );
417 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
419 // Find the object and destroy it
420 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
422 PropertyOwner* current = *iter;
423 if ( current == object )
425 customObjects.Erase( iter );
430 // Should not reach here
431 DALI_ASSERT_DEBUG(false);
434 void UpdateManager::AddAnimation( Animation* animation )
436 mImpl->animations.PushBack( animation );
439 void UpdateManager::StopAnimation( Animation* animation )
441 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
443 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
445 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
448 void UpdateManager::RemoveAnimation( Animation* animation )
450 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
452 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
454 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
457 bool UpdateManager::IsAnimationRunning() const
459 bool isRunning(false);
460 AnimationContainer& animations = mImpl->animations;
462 // Find any animation that isn't stopped or paused
464 const AnimationIter endIter = animations.End();
465 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
467 const Animation::State state = (*iter)->GetState();
469 if (state != Animation::Stopped &&
470 state != Animation::Paused)
479 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
481 mImpl->propertyNotifications.PushBack( propertyNotification );
484 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
486 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
487 PropertyNotificationIter iter = propertyNotifications.Begin();
489 while ( iter != propertyNotifications.End() )
491 if( *iter == propertyNotification )
493 propertyNotifications.Erase(iter);
500 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
502 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
503 propertyNotification->SetNotifyMode( notifyMode );
506 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
508 return mImpl->renderers;
511 void UpdateManager::AddShader( Shader* shader )
513 DALI_ASSERT_DEBUG( NULL != shader );
515 if( mImpl->shaders.Count() == 0 )
517 // the first added shader becomes our default shader
518 // Construct message in the render queue memory; note that delete should not be called on the return value
519 typedef MessageValue1< RenderManager, Shader* > DerivedType;
521 // Reserve some memory inside the render queue
522 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
524 // Construct message in the render queue memory; note that delete should not be called on the return value
525 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
528 mImpl->shaders.PushBack( shader );
531 void UpdateManager::RemoveShader( Shader* shader )
533 DALI_ASSERT_DEBUG(shader != NULL);
535 ShaderContainer& shaders = mImpl->shaders;
537 // Find the shader and destroy it
538 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
540 Shader& current = **iter;
541 if ( ¤t == shader )
543 // Transfer ownership to the discard queue
544 // This keeps the shader alive, until the render-thread has finished with it
545 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
550 // Should not reach here
551 DALI_ASSERT_DEBUG(false);
554 void UpdateManager::SetShaderProgram( Shader* shader,
555 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
560 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
562 // Reserve some memory inside the render queue
563 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
565 // Construct message in the render queue memory; note that delete should not be called on the return value
566 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
570 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
572 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
573 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
575 // lock as update might be sending previously compiled shaders to event thread
576 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
577 mImpl->renderCompiledShaders.push_back( shaderData );
581 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
585 // copy the list, this is only likely to happen once in application life cycle
586 return &(mImpl->taskList);
590 // copy the list, this is only likely to happen once in application life cycle
591 return &(mImpl->systemLevelTaskList);
595 void UpdateManager::AddGesture( PanGesture* gesture )
597 DALI_ASSERT_DEBUG( NULL != gesture );
599 mImpl->gestures.PushBack( gesture );
602 void UpdateManager::RemoveGesture( PanGesture* gesture )
604 DALI_ASSERT_DEBUG( gesture != NULL );
606 GestureContainer& gestures = mImpl->gestures;
608 // Find the gesture and destroy it
609 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
611 PanGesture& current = **iter;
612 if ( ¤t == gesture )
614 mImpl->gestures.Erase( iter );
618 // Should not reach here
619 DALI_ASSERT_DEBUG(false);
622 void UpdateManager::AddTextureSet( TextureSet* textureSet )
624 DALI_ASSERT_DEBUG( NULL != textureSet );
625 mImpl->textureSets.PushBack( textureSet );
628 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
630 DALI_ASSERT_DEBUG(textureSet != NULL);
631 size_t textureSetCount( mImpl->textureSets.Size() );
632 for( size_t i(0); i<textureSetCount; ++i )
634 if( textureSet == mImpl->textureSets[i] )
636 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
642 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
644 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
647 void UpdateManager::EventProcessingStarted()
649 mImpl->messageQueue.EventProcessingStarted();
652 bool UpdateManager::FlushQueue()
654 return mImpl->messageQueue.FlushQueue();
657 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
659 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
660 mImpl->animationFinishedDuringUpdate = false;
662 // Animated properties have to be reset to their original value each frame
664 // Reset root properties
667 mImpl->root->ResetToBaseValues( bufferIndex );
669 if ( mImpl->systemLevelRoot )
671 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
674 // Reset all the nodes
675 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
676 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
677 for(;iter != endIter; ++iter)
679 (*iter)->ResetToBaseValues( bufferIndex );
682 // Reset system-level render-task list properties to base values
683 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
685 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
687 (*iter)->ResetToBaseValues( bufferIndex );
690 // Reset render-task list properties to base values.
691 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
693 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
695 (*iter)->ResetToBaseValues( bufferIndex );
698 // Reset custom object properties to base values
699 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
701 (*iter)->ResetToBaseValues( bufferIndex );
704 mImpl->renderers.ResetToBaseValues( bufferIndex );
706 // Reset animatable shader properties to base values
707 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
709 (*iter)->ResetToBaseValues( bufferIndex );
713 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
715 bool gestureUpdated( false );
717 // constrain gestures... (in construction order)
718 GestureContainer& gestures = mImpl->gestures;
720 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
722 PanGesture& gesture = **iter;
723 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
724 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
727 return gestureUpdated;
730 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
732 AnimationContainer &animations = mImpl->animations;
733 AnimationIter iter = animations.Begin();
734 bool animationLooped = false;
735 while ( iter != animations.End() )
737 Animation* animation = *iter;
738 bool finished = false;
740 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
742 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
743 animationLooped = animationLooped || looped;
745 // Remove animations that had been destroyed but were still waiting for an update
746 if (animation->GetState() == Animation::Destroyed)
748 iter = animations.Erase(iter);
756 // queue the notification on finished or looped (to update loop count)
757 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
759 // The application should be notified by NotificationManager, in another thread
760 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
764 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
766 //Constrain custom objects (in construction order)
767 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
768 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
769 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
771 PropertyOwner& object = **iter;
772 ConstrainPropertyOwner( object, bufferIndex );
776 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
778 // Constrain system-level render-tasks
779 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
780 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
782 RenderTask& task = **iter;
783 ConstrainPropertyOwner( task, bufferIndex );
786 // Constrain render-tasks
787 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
788 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
790 RenderTask& task = **iter;
791 ConstrainPropertyOwner( task, bufferIndex );
795 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
797 // constrain shaders... (in construction order)
798 ShaderContainer& shaders = mImpl->shaders;
799 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
801 Shader& shader = **iter;
802 ConstrainPropertyOwner( shader, bufferIndex );
806 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
808 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
809 PropertyNotificationIter iter = notifications.Begin();
811 while ( iter != notifications.End() )
813 PropertyNotification* notification = *iter;
814 bool valid = notification->Check( bufferIndex );
817 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
823 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
825 size_t textureSetCount( mImpl->textureSets.Size() );
826 for( size_t i(0); i<textureSetCount; ++i )
828 //Prepare texture set
829 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
833 void UpdateManager::ForwardCompiledShadersToEventThread()
835 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
836 if( mImpl->shaderSaver )
838 // lock and swap the queues
840 // render might be attempting to send us more binaries at the same time
841 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
842 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
845 if( mImpl->updateCompiledShaders.size() > 0 )
847 ShaderSaver& factory = *mImpl->shaderSaver;
848 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
849 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
850 for( ; i != end; ++i )
852 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
854 // we don't need them in update anymore
855 mImpl->updateCompiledShaders.clear();
860 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
862 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
863 unsigned int rendererCount( rendererContainer.Size() );
864 for( unsigned int i(0); i<rendererCount; ++i )
867 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
869 if( rendererContainer[i]->IsReferenced() )
871 rendererContainer[i]->PrepareRender( bufferIndex );
876 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
878 mImpl->nodeDirtyFlags = NothingFlag;
885 // Prepare resources, update shaders, for each node
886 // And add the renderers to the sorted layers. Start from root, which is also a layer
887 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
889 mImpl->resourceManager,
890 mImpl->renderQueue );
892 if ( mImpl->systemLevelRoot )
894 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
896 mImpl->resourceManager,
897 mImpl->renderQueue );
901 unsigned int UpdateManager::Update( float elapsedSeconds,
902 unsigned int lastVSyncTimeMilliseconds,
903 unsigned int nextVSyncTimeMilliseconds )
905 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
907 //Clear nodes/resources which were previously discarded
908 mImpl->discardQueue.Clear( bufferIndex );
910 //Grab any loaded resources
911 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
913 //Process Touches & Gestures
914 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
916 const bool updateScene = // The scene-graph requires an update if..
917 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
918 IsAnimationRunning() || // ..at least one animation is running OR
919 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
920 resourceChanged || // ..one or more resources were updated/changed OR
921 gestureUpdated; // ..a gesture property was updated
924 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
925 // values if the scene was updated in the previous frame.
926 if( updateScene || mImpl->previousUpdateScene )
928 //Reset properties from the previous update
929 ResetProperties( bufferIndex );
930 mImpl->transformManager.ResetToBaseValue();
933 //Process the queued scene messages
934 mImpl->messageQueue.ProcessMessages( bufferIndex );
936 //Post Process Ids of resources updated by renderer
937 mImpl->resourceManager.PostProcessResources( bufferIndex );
939 //Forward compiled shader programs to event thread for saving
940 ForwardCompiledShadersToEventThread();
942 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
943 // renderer lists if the scene was updated in the previous frame.
944 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
945 if( updateScene || mImpl->previousUpdateScene )
948 Animate( bufferIndex, elapsedSeconds );
950 //Constraint custom objects
951 ConstrainCustomObjects( bufferIndex );
953 //Prepare texture sets and apply constraints to them
954 PrepareTextureSets( bufferIndex );
956 //Clear the lists of renderers from the previous update
957 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
959 mImpl->sortedLayers[i]->ClearRenderables();
962 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
964 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
967 //Update node hierarchy, apply constraints and perform sorting / culling.
968 //This will populate each Layer with a list of renderers which are ready.
969 UpdateNodes( bufferIndex );
971 //Apply constraints to RenderTasks, shaders
972 ConstrainRenderTasks( bufferIndex );
973 ConstrainShaders( bufferIndex );
975 //Update renderers and apply constraints
976 UpdateRenderers( bufferIndex );
978 //Update the trnasformations of all the nodes
979 mImpl->transformManager.Update();
981 //Process Property Notifications
982 ProcessPropertyNotifications( bufferIndex );
984 //Process the RenderTasks; this creates the instructions for rendering the next frame.
985 //reset the update buffer index and make sure there is enough room in the instruction container
986 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
987 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
989 if ( NULL != mImpl->root )
991 ProcessRenderTasks( bufferIndex,
995 mImpl->renderSortingHelper,
996 mImpl->renderInstructions );
998 // Process the system-level RenderTasks last
999 if ( NULL != mImpl->systemLevelRoot )
1001 ProcessRenderTasks( bufferIndex,
1002 mImpl->systemLevelTaskList,
1003 *mImpl->systemLevelRoot,
1004 mImpl->systemLevelSortedLayers,
1005 mImpl->renderSortingHelper,
1006 mImpl->renderInstructions );
1011 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1012 bool doRenderOnceNotify = false;
1013 mImpl->renderTaskWaiting = false;
1014 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1015 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1016 endIter != iter; ++iter )
1018 RenderTask& renderTask(*(*iter));
1020 renderTask.UpdateState();
1022 if( renderTask.IsWaitingToRender() &&
1023 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1025 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1028 if( renderTask.HasRendered() )
1030 doRenderOnceNotify = true;
1034 if( doRenderOnceNotify )
1036 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1037 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1040 // Macro is undefined in release build.
1041 SNAPSHOT_NODE_LOGGING;
1043 // A ResetProperties() may be required in the next frame
1044 mImpl->previousUpdateScene = updateScene;
1046 // Check whether further updates are required
1047 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1049 // tell the update manager that we're done so the queue can be given to event thread
1050 mImpl->notificationManager.UpdateCompleted();
1052 // The update has finished; swap the double-buffering indices
1053 mSceneGraphBuffers.Swap();
1055 return keepUpdating;
1058 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1060 // Update the duration set via Stage::KeepRendering()
1061 if ( mImpl->keepRenderingSeconds > 0.0f )
1063 mImpl->keepRenderingSeconds -= elapsedSeconds;
1066 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1068 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1069 // Keep updating until no messages are received and no animations are running.
1070 // If an animation has just finished, update at least once more for Discard end-actions.
1071 // No need to check for renderQueue as there is always a render after update and if that
1072 // render needs another update it will tell the adaptor to call update again
1074 if ( mImpl->keepRenderingSeconds > 0.0f )
1076 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1079 if ( IsAnimationRunning() ||
1080 mImpl->animationFinishedDuringUpdate )
1082 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1085 if ( mImpl->renderTaskWaiting )
1087 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1090 return keepUpdatingRequest;
1093 void UpdateManager::SetBackgroundColor( const Vector4& color )
1095 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1097 // Reserve some memory inside the render queue
1098 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1100 // Construct message in the render queue memory; note that delete should not be called on the return value
1101 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1104 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1106 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1108 // Reserve some memory inside the render queue
1109 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1111 // Construct message in the render queue memory; note that delete should not be called on the return value
1112 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1115 void UpdateManager::KeepRendering( float durationSeconds )
1117 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1120 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1124 // just copy the vector of pointers
1125 mImpl->sortedLayers = layers;
1129 mImpl->systemLevelSortedLayers = layers;
1133 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1135 mImpl->shaderSaver = &upstream;
1138 void UpdateManager::AddSampler( Render::Sampler* sampler )
1140 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1142 // Reserve some memory inside the render queue
1143 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1145 // Construct message in the render queue memory; note that delete should not be called on the return value
1146 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1149 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1151 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1153 // Reserve some memory inside the render queue
1154 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1156 // Construct message in the render queue memory; note that delete should not be called on the return value
1157 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1160 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1162 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1164 // Reserve some memory inside the render queue
1165 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1167 // Construct message in the render queue memory; note that delete should not be called on the return value
1168 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1171 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1173 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1175 // Reserve some memory inside the render queue
1176 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1178 // Construct message in the render queue memory; note that delete should not be called on the return value
1179 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1182 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1184 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1186 // Reserve some memory inside the render queue
1187 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1189 // Construct message in the render queue memory; note that delete should not be called on the return value
1190 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1193 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1195 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1197 // Reserve some memory inside the render queue
1198 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1200 // Construct message in the render queue memory; note that delete should not be called on the return value
1201 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1204 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1206 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1208 // Reserve some memory inside the render queue
1209 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1211 // Construct message in the render queue memory; note that delete should not be called on the return value
1212 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1215 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1217 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1219 // Reserve some memory inside the render queue
1220 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1222 // Construct message in the render queue memory; note that delete should not be called on the return value
1223 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1226 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1228 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1230 // Reserve some memory inside the render queue
1231 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1233 // Construct message in the render queue memory; note that delete should not be called on the return value
1234 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1237 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1239 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1241 // Reserve some memory inside the render queue
1242 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1244 // Construct message in the render queue memory; note that delete should not be called on the return value
1245 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1248 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1250 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1252 // Reserve some memory inside the render queue
1253 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1255 // Construct message in the render queue memory; note that delete should not be called on the return value
1256 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1259 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1261 typedef IndexBufferMessage< RenderManager > DerivedType;
1263 // Reserve some memory inside the render queue
1264 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1266 // Construct message in the render queue memory; note that delete should not be called on the return value
1267 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1270 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1272 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1274 // Reserve some memory inside the render queue
1275 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1277 // Construct message in the render queue memory; note that delete should not be called on the return value
1278 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1281 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1283 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1285 // Reserve some memory inside the render queue
1286 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the render queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1293 } // namespace SceneGraph
1295 } // namespace Internal