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/manager/transform-manager.h>
53 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.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/rendering/scene-graph-geometry.h>
61 #include <dali/internal/update/resources/resource-manager.h>
62 #include <dali/internal/update/touch/touch-resampler.h>
64 #include <dali/internal/render/common/render-instruction-container.h>
65 #include <dali/internal/render/common/render-manager.h>
66 #include <dali/internal/render/queue/render-queue.h>
67 #include <dali/internal/render/gl-resources/texture-cache.h>
68 #include <dali/internal/render/shaders/scene-graph-shader.h>
69 #include <dali/internal/render/renderers/render-sampler.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;
119 * Structure to contain UpdateManager internal data
121 struct UpdateManager::Impl
123 Impl( NotificationManager& notificationManager,
124 CompleteNotificationInterface& animationFinishedNotifier,
125 PropertyNotifier& propertyNotifier,
126 ResourceManager& resourceManager,
127 DiscardQueue& discardQueue,
128 RenderController& renderController,
129 RenderManager& renderManager,
130 RenderQueue& renderQueue,
131 TextureCache& textureCache,
132 TouchResampler& touchResampler,
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 touchResampler( touchResampler ),
148 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
149 taskList( renderMessageDispatcher, resourceManager ),
150 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
152 systemLevelRoot( NULL ),
153 renderers( sceneGraphBuffers, discardQueue ),
154 geometries( sceneGraphBuffers, discardQueue ),
155 textureSets( sceneGraphBuffers, discardQueue ),
156 messageQueue( renderController, sceneGraphBuffers ),
157 keepRenderingSeconds( 0.0f ),
158 animationFinishedDuringUpdate( false ),
159 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
160 previousUpdateScene( false ),
162 renderSortingHelper(),
163 renderTaskWaiting( false )
165 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache );
167 renderers.SetSceneController( *sceneController );
168 geometries.SetSceneController( *sceneController );
169 textureSets.SetSceneController( *sceneController );
171 // create first 'dummy' node
177 // Disconnect render tasks from nodes, before destroying the nodes
178 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
179 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
181 (*iter)->SetSourceNode( NULL );
183 // ..repeat for system level RenderTasks
184 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
185 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
187 (*iter)->SetSourceNode( NULL );
190 // UpdateManager owns the Nodes
191 Vector<Node*>::Iterator iter = nodes.Begin()+1;
192 Vector<Node*>::Iterator endIter = nodes.End();
193 for(;iter!=endIter;++iter)
195 (*iter)->OnDestroy();
199 // If there is root, reset it, otherwise do nothing as rendering was never started
208 if( systemLevelRoot )
210 systemLevelRoot->OnDestroy();
212 delete systemLevelRoot;
213 systemLevelRoot = NULL;
216 sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
217 delete sceneController;
220 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
221 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
222 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
223 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
224 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
225 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
226 ShaderSaver* shaderSaver; ///< Saves shader binaries.
227 ResourceManager& resourceManager; ///< resource manager
228 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
229 RenderController& renderController; ///< render controller
230 SceneControllerImpl* sceneController; ///< scene controller
231 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
232 RenderQueue& renderQueue; ///< Used to queue messages for the next render
233 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
234 TouchResampler& touchResampler; ///< Used to resample touch events on every update.
236 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
238 RenderTaskList taskList; ///< The list of scene graph render-tasks
239 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
241 Layer* root; ///< The root node (root is a layer)
242 Layer* systemLevelRoot; ///< A separate root-node for system-level content
244 Vector<Node*> nodes; ///< A container of all instantiated nodes
246 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
247 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
249 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
251 AnimationContainer animations; ///< A container of owned animations
252 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
254 ObjectOwnerContainer<Renderer> renderers;
255 ObjectOwnerContainer<Geometry> geometries; ///< A container of geometries
256 ObjectOwnerContainer<TextureSet> textureSets; ///< A container of texture sets
258 ShaderContainer shaders; ///< A container of owned shaders
260 MessageQueue messageQueue; ///< The messages queued from the event-thread
261 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
262 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
263 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
265 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
266 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
268 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
269 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
271 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
272 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
274 GestureContainer gestures; ///< A container of owned gesture detectors
275 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
278 UpdateManager::UpdateManager( NotificationManager& notificationManager,
279 CompleteNotificationInterface& animationFinishedNotifier,
280 PropertyNotifier& propertyNotifier,
281 ResourceManager& resourceManager,
282 DiscardQueue& discardQueue,
283 RenderController& controller,
284 RenderManager& renderManager,
285 RenderQueue& renderQueue,
286 TextureCache& textureCache,
287 TouchResampler& touchResampler )
290 mImpl = new Impl( notificationManager,
291 animationFinishedNotifier,
300 mSceneGraphBuffers );
302 textureCache.SetBufferIndices( &mSceneGraphBuffers );
305 UpdateManager::~UpdateManager()
310 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
312 DALI_ASSERT_DEBUG( layer->IsLayer() );
313 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
317 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
319 mImpl->root->CreateTransform( &mImpl->transformManager);
323 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
324 mImpl->systemLevelRoot = layer;
325 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
328 layer->SetRoot(true);
331 void UpdateManager::AddNode( Node* node )
333 DALI_ASSERT_ALWAYS( NULL != node );
334 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
336 // Nodes must be sorted by pointer
337 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
338 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
342 mImpl->nodes.Insert((iter+1), node);
343 node->CreateTransform( &mImpl->transformManager);
349 void UpdateManager::ConnectNode( Node* parent, Node* node )
351 DALI_ASSERT_ALWAYS( NULL != parent );
352 DALI_ASSERT_ALWAYS( NULL != node );
353 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
355 parent->ConnectChild( node );
358 void UpdateManager::DisconnectNode( Node* node )
360 Node* parent = node->GetParent();
361 DALI_ASSERT_ALWAYS( NULL != parent );
362 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
364 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
367 void UpdateManager::DestroyNode( Node* node )
369 DALI_ASSERT_ALWAYS( NULL != node );
370 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
372 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
373 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
374 for(;iter!=endIter;++iter)
378 mImpl->nodes.Erase(iter);
383 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
385 // Notify the Node about impending destruction
389 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
390 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
392 DALI_ASSERT_DEBUG( node != NULL );
393 DALI_ASSERT_DEBUG( attachment != NULL );
395 // attach node to attachment first so that parent is known by the time attachment is connected
396 node->Attach( *attachment ); // node takes ownership
399 void UpdateManager::AddObject( PropertyOwner* object )
401 DALI_ASSERT_DEBUG( NULL != object );
403 mImpl->customObjects.PushBack( object );
406 void UpdateManager::RemoveObject( PropertyOwner* object )
408 DALI_ASSERT_DEBUG( NULL != object );
410 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
412 // Find the object and destroy it
413 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
415 PropertyOwner* current = *iter;
416 if ( current == object )
418 customObjects.Erase( iter );
423 // Should not reach here
424 DALI_ASSERT_DEBUG(false);
427 void UpdateManager::AddAnimation( Animation* animation )
429 mImpl->animations.PushBack( animation );
432 void UpdateManager::StopAnimation( Animation* animation )
434 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
436 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
438 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
441 void UpdateManager::RemoveAnimation( Animation* animation )
443 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
445 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
447 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
450 bool UpdateManager::IsAnimationRunning() const
452 bool isRunning(false);
453 AnimationContainer& animations = mImpl->animations;
455 // Find any animation that isn't stopped or paused
457 const AnimationIter endIter = animations.End();
458 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
460 const Animation::State state = (*iter)->GetState();
462 if (state != Animation::Stopped &&
463 state != Animation::Paused)
472 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
474 mImpl->propertyNotifications.PushBack( propertyNotification );
477 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
479 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
480 PropertyNotificationIter iter = propertyNotifications.Begin();
482 while ( iter != propertyNotifications.End() )
484 if( *iter == propertyNotification )
486 propertyNotifications.Erase(iter);
493 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
495 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
496 propertyNotification->SetNotifyMode( notifyMode );
499 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
501 return mImpl->geometries;
504 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
506 return mImpl->renderers;
510 ObjectOwnerContainer<TextureSet>& UpdateManager::GetTexturesOwner()
512 return mImpl->textureSets;
515 void UpdateManager::AddShader( Shader* shader )
517 DALI_ASSERT_DEBUG( NULL != shader );
519 if( mImpl->shaders.Count() == 0 )
521 // the first added shader becomes our default shader
522 // Construct message in the render queue memory; note that delete should not be called on the return value
523 typedef MessageValue1< RenderManager, Shader* > DerivedType;
525 // Reserve some memory inside the render queue
526 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
528 // Construct message in the render queue memory; note that delete should not be called on the return value
529 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
532 mImpl->shaders.PushBack( shader );
534 // Allows the shader to dispatch texture requests to the cache
535 shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
538 void UpdateManager::RemoveShader( Shader* shader )
540 DALI_ASSERT_DEBUG(shader != NULL);
542 ShaderContainer& shaders = mImpl->shaders;
544 // Find the shader and destroy it
545 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
547 Shader& current = **iter;
548 if ( ¤t == shader )
550 // Transfer ownership to the discard queue
551 // This keeps the shader alive, until the render-thread has finished with it
552 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
557 // Should not reach here
558 DALI_ASSERT_DEBUG(false);
561 void UpdateManager::SetShaderProgram( Shader* shader,
562 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
567 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
569 // Reserve some memory inside the render queue
570 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
572 // Construct message in the render queue memory; note that delete should not be called on the return value
573 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
577 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
579 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
580 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
582 // lock as update might be sending previously compiled shaders to event thread
583 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
584 mImpl->renderCompiledShaders.push_back( shaderData );
588 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
592 // copy the list, this is only likely to happen once in application life cycle
593 return &(mImpl->taskList);
597 // copy the list, this is only likely to happen once in application life cycle
598 return &(mImpl->systemLevelTaskList);
602 void UpdateManager::AddGesture( PanGesture* gesture )
604 DALI_ASSERT_DEBUG( NULL != gesture );
606 mImpl->gestures.PushBack( gesture );
609 void UpdateManager::RemoveGesture( PanGesture* gesture )
611 DALI_ASSERT_DEBUG( gesture != NULL );
613 GestureContainer& gestures = mImpl->gestures;
615 // Find the gesture and destroy it
616 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
618 PanGesture& current = **iter;
619 if ( ¤t == gesture )
621 mImpl->gestures.Erase( iter );
625 // Should not reach here
626 DALI_ASSERT_DEBUG(false);
629 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
631 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
634 void UpdateManager::EventProcessingStarted()
636 mImpl->messageQueue.EventProcessingStarted();
639 bool UpdateManager::FlushQueue()
641 return mImpl->messageQueue.FlushQueue();
644 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
646 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
647 mImpl->animationFinishedDuringUpdate = false;
649 // Animated properties have to be reset to their original value each frame
651 // Reset root properties
654 mImpl->root->ResetToBaseValues( bufferIndex );
656 if ( mImpl->systemLevelRoot )
658 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
661 // Reset all the nodes
662 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
663 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
664 for(;iter != endIter; ++iter)
666 (*iter)->ResetToBaseValues( bufferIndex );
669 // Reset system-level render-task list properties to base values
670 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
672 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
674 (*iter)->ResetToBaseValues( bufferIndex );
677 // Reset render-task list properties to base values.
678 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
680 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
682 (*iter)->ResetToBaseValues( bufferIndex );
685 // Reset custom object properties to base values
686 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
688 (*iter)->ResetToBaseValues( bufferIndex );
691 mImpl->textureSets.ResetToBaseValues( bufferIndex );
692 mImpl->geometries.ResetToBaseValues( bufferIndex );
693 mImpl->renderers.ResetToBaseValues( bufferIndex );
695 // Reset animatable shader properties to base values
696 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
698 (*iter)->ResetToBaseValues( bufferIndex );
702 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
704 bool gestureUpdated( false );
706 // constrain gestures... (in construction order)
707 GestureContainer& gestures = mImpl->gestures;
709 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
711 PanGesture& gesture = **iter;
712 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
713 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
716 return gestureUpdated;
719 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
721 AnimationContainer &animations = mImpl->animations;
722 AnimationIter iter = animations.Begin();
723 bool animationLooped = false;
724 while ( iter != animations.End() )
726 Animation* animation = *iter;
727 bool finished = false;
729 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
731 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
732 animationLooped = animationLooped || looped;
734 // Remove animations that had been destroyed but were still waiting for an update
735 if (animation->GetState() == Animation::Destroyed)
737 iter = animations.Erase(iter);
745 // queue the notification on finished or looped (to update loop count)
746 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
748 // The application should be notified by NotificationManager, in another thread
749 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
753 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
755 //Constrain custom objects (in construction order)
756 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
757 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
758 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
760 PropertyOwner& object = **iter;
761 ConstrainPropertyOwner( object, bufferIndex );
765 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
767 // Constrain system-level render-tasks
768 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
769 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
771 RenderTask& task = **iter;
772 ConstrainPropertyOwner( task, bufferIndex );
775 // Constrain render-tasks
776 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
777 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
779 RenderTask& task = **iter;
780 ConstrainPropertyOwner( task, bufferIndex );
784 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
786 // constrain shaders... (in construction order)
787 ShaderContainer& shaders = mImpl->shaders;
788 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
790 Shader& shader = **iter;
791 ConstrainPropertyOwner( shader, bufferIndex );
795 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
797 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
798 PropertyNotificationIter iter = notifications.Begin();
800 while ( iter != notifications.End() )
802 PropertyNotification* notification = *iter;
803 bool valid = notification->Check( bufferIndex );
806 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
812 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
814 ObjectOwnerContainer<TextureSet>::Iterator iter = mImpl->textureSets.GetObjectContainer().Begin();
815 const ObjectOwnerContainer<TextureSet>::Iterator end = mImpl->textureSets.GetObjectContainer().End();
816 for( ; iter != end; ++iter )
819 ConstrainPropertyOwner( *(*iter), bufferIndex );
821 //Prepare texture set
822 (*iter)->Prepare( mImpl->resourceManager );
826 void UpdateManager::ForwardCompiledShadersToEventThread()
828 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
829 if( mImpl->shaderSaver )
831 // lock and swap the queues
833 // render might be attempting to send us more binaries at the same time
834 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
835 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
838 if( mImpl->updateCompiledShaders.size() > 0 )
840 ShaderSaver& factory = *mImpl->shaderSaver;
841 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
842 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
843 for( ; i != end; ++i )
845 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
847 // we don't need them in update anymore
848 mImpl->updateCompiledShaders.clear();
853 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
855 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
856 unsigned int rendererCount( rendererContainer.Size() );
857 for( unsigned int i(0); i<rendererCount; ++i )
860 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
862 if( rendererContainer[i]->IsReferenced() )
864 rendererContainer[i]->PrepareRender( bufferIndex );
869 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
871 mImpl->nodeDirtyFlags = NothingFlag;
878 // Prepare resources, update shaders, update attachments, for each node
879 // And add the renderers to the sorted layers. Start from root, which is also a layer
880 mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
882 mImpl->resourceManager,
883 mImpl->renderQueue );
885 if ( mImpl->systemLevelRoot )
887 mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
889 mImpl->resourceManager,
890 mImpl->renderQueue );
894 unsigned int UpdateManager::Update( float elapsedSeconds,
895 unsigned int lastVSyncTimeMilliseconds,
896 unsigned int nextVSyncTimeMilliseconds )
898 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
900 //Clear nodes/resources which were previously discarded
901 mImpl->discardQueue.Clear( bufferIndex );
903 //Grab any loaded resources
904 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
906 //Process Touches & Gestures
907 mImpl->touchResampler.Update();
908 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
910 const bool updateScene = // The scene-graph requires an update if..
911 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
912 IsAnimationRunning() || // ..at least one animation is running OR
913 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
914 resourceChanged || // ..one or more resources were updated/changed OR
915 gestureUpdated; // ..a gesture property was updated
918 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
919 // values if the scene was updated in the previous frame.
920 if( updateScene || mImpl->previousUpdateScene )
922 //Reset properties from the previous update
923 ResetProperties( bufferIndex );
924 mImpl->transformManager.ResetToBaseValue();
927 //Process the queued scene messages
928 mImpl->messageQueue.ProcessMessages( bufferIndex );
930 //Post Process Ids of resources updated by renderer
931 mImpl->resourceManager.PostProcessResources( bufferIndex );
933 //Forward compiled shader programs to event thread for saving
934 ForwardCompiledShadersToEventThread();
936 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
937 // renderer lists if the scene was updated in the previous frame.
938 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
939 if( updateScene || mImpl->previousUpdateScene )
942 Animate( bufferIndex, elapsedSeconds );
944 //Constraint custom objects
945 ConstrainCustomObjects( bufferIndex );
947 //Prepare texture sets and apply constraints to them
948 PrepareTextureSets( bufferIndex );
950 //Clear the lists of renderable-attachments from the previous update
951 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
953 mImpl->sortedLayers[i]->ClearRenderables();
956 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
958 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
961 //Update node hierarchy, apply constraints and perform sorting / culling.
962 //This will populate each Layer with a list of renderers which are ready.
963 UpdateNodes( bufferIndex );
965 //Apply constraints to RenderTasks, shaders and geometries
966 ConstrainRenderTasks( bufferIndex );
967 ConstrainShaders( bufferIndex );
968 mImpl->geometries.ConstrainObjects( bufferIndex );
970 //Update renderers and apply constraints
971 UpdateRenderers( bufferIndex );
973 //Update the trnasformations of all the nodes
974 mImpl->transformManager.Update();
976 //Process Property Notifications
977 ProcessPropertyNotifications( bufferIndex );
979 //Process the RenderTasks; this creates the instructions for rendering the next frame.
980 //reset the update buffer index and make sure there is enough room in the instruction container
981 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
982 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
984 if ( NULL != mImpl->root )
986 ProcessRenderTasks( bufferIndex,
990 mImpl->renderSortingHelper,
991 mImpl->renderInstructions );
993 // Process the system-level RenderTasks last
994 if ( NULL != mImpl->systemLevelRoot )
996 ProcessRenderTasks( bufferIndex,
997 mImpl->systemLevelTaskList,
998 *mImpl->systemLevelRoot,
999 mImpl->systemLevelSortedLayers,
1000 mImpl->renderSortingHelper,
1001 mImpl->renderInstructions );
1006 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1007 bool doRenderOnceNotify = false;
1008 mImpl->renderTaskWaiting = false;
1009 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1010 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1011 endIter != iter; ++iter )
1013 RenderTask& renderTask(*(*iter));
1015 renderTask.UpdateState();
1017 if( renderTask.IsWaitingToRender() &&
1018 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1020 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1023 if( renderTask.HasRendered() )
1025 doRenderOnceNotify = true;
1029 if( doRenderOnceNotify )
1031 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1032 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1035 // Macro is undefined in release build.
1036 SNAPSHOT_NODE_LOGGING;
1038 // A ResetProperties() may be required in the next frame
1039 mImpl->previousUpdateScene = updateScene;
1041 // Check whether further updates are required
1042 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1044 // tell the update manager that we're done so the queue can be given to event thread
1045 mImpl->notificationManager.UpdateCompleted();
1047 // The update has finished; swap the double-buffering indices
1048 mSceneGraphBuffers.Swap();
1050 return keepUpdating;
1053 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1055 // Update the duration set via Stage::KeepRendering()
1056 if ( mImpl->keepRenderingSeconds > 0.0f )
1058 mImpl->keepRenderingSeconds -= elapsedSeconds;
1061 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1063 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1064 // Keep updating until no messages are received and no animations are running.
1065 // If an animation has just finished, update at least once more for Discard end-actions.
1066 // No need to check for renderQueue as there is always a render after update and if that
1067 // render needs another update it will tell the adaptor to call update again
1069 if ( mImpl->keepRenderingSeconds > 0.0f )
1071 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1074 if ( IsAnimationRunning() ||
1075 mImpl->animationFinishedDuringUpdate )
1077 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1080 if ( mImpl->renderTaskWaiting )
1082 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1085 return keepUpdatingRequest;
1088 void UpdateManager::SetBackgroundColor( const Vector4& color )
1090 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1092 // Reserve some memory inside the render queue
1093 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1095 // Construct message in the render queue memory; note that delete should not be called on the return value
1096 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1099 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1101 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1103 // Reserve some memory inside the render queue
1104 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1106 // Construct message in the render queue memory; note that delete should not be called on the return value
1107 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1110 void UpdateManager::KeepRendering( float durationSeconds )
1112 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1115 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1119 // just copy the vector of pointers
1120 mImpl->sortedLayers = layers;
1124 mImpl->systemLevelSortedLayers = layers;
1128 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1130 mImpl->shaderSaver = &upstream;
1133 void UpdateManager::AddSampler( Render::Sampler* sampler )
1135 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1137 // Reserve some memory inside the render queue
1138 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1140 // Construct message in the render queue memory; note that delete should not be called on the return value
1141 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1144 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1146 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1148 // Reserve some memory inside the render queue
1149 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1151 // Construct message in the render queue memory; note that delete should not be called on the return value
1152 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1155 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1157 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1159 // Reserve some memory inside the render queue
1160 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1162 // Construct message in the render queue memory; note that delete should not be called on the return value
1163 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1166 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1168 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1170 // Reserve some memory inside the render queue
1171 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1173 // Construct message in the render queue memory; note that delete should not be called on the return value
1174 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1177 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1179 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1181 // Reserve some memory inside the render queue
1182 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1184 // Construct message in the render queue memory; note that delete should not be called on the return value
1185 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1188 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1190 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1192 // Reserve some memory inside the render queue
1193 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1195 // Construct message in the render queue memory; note that delete should not be called on the return value
1196 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1199 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1201 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1203 // Reserve some memory inside the render queue
1204 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1206 // Construct message in the render queue memory; note that delete should not be called on the return value
1207 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1210 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1212 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1214 // Reserve some memory inside the render queue
1215 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1217 // Construct message in the render queue memory; note that delete should not be called on the return value
1218 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1221 } // namespace SceneGraph
1223 } // namespace Internal