Created renderer objects.
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/update-manager.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/public-api/common/set-wrapper.h>
24
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/render-controller.h>
27 #include <dali/integration-api/shader-data.h>
28 #include <dali/integration-api/debug.h>
29
30 #include <dali/internal/common/core-impl.h>
31 #include <dali/internal/common/owner-container.h>
32 #include <dali/internal/common/message.h>
33
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-impl.h>
36 #include <dali/internal/event/common/property-notifier.h>
37
38 #include <dali/internal/update/animation/scene-graph-animator.h>
39 #include <dali/internal/update/animation/scene-graph-animation.h>
40 #include <dali/internal/update/common/discard-queue.h>
41 #include <dali/internal/update/common/scene-graph-buffers.h>
42 #include <dali/internal/update/controllers/render-message-dispatcher.h>
43 #include <dali/internal/update/controllers/scene-controller-impl.h>
44 #include <dali/internal/update/effects/scene-graph-material.h>
45 #include <dali/internal/update/geometry/scene-graph-geometry.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/prepare-render-algorithms.h>
48 #include <dali/internal/update/manager/process-render-tasks.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
53 #include <dali/internal/update/nodes/node.h>
54 #include <dali/internal/update/nodes/scene-graph-layer.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
58 #include <dali/internal/update/resources/resource-manager.h>
59 #include <dali/internal/update/resources/complete-status-manager.h>
60 #include <dali/internal/update/touch/touch-resampler.h>
61
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/common/performance-monitor.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/shaders/scene-graph-shader.h>
68
69 #ifdef DYNAMICS_SUPPORT
70 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
71 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
72 #endif
73
74 // Un-comment to enable node tree debug logging
75 //#define NODE_TREE_LOGGING 1
76
77 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
78 #define SNAPSHOT_NODE_LOGGING \
79 const int FRAME_COUNT_TRIGGER = 16;\
80 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
81   {\
82     if ( NULL != mImpl->root )\
83     {\
84       mImpl->frameCounter = 0;\
85       PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
86     }\
87   }\
88 mImpl->frameCounter++;
89 #else
90 #define SNAPSHOT_NODE_LOGGING
91 #endif
92
93 #if defined(DEBUG_ENABLED)
94 extern Debug::Filter* gRenderTaskLogFilter;
95 #endif
96
97
98 using namespace Dali::Integration;
99 using Dali::Internal::Update::MessageQueue;
100
101 namespace Dali
102 {
103
104 namespace Internal
105 {
106
107 namespace SceneGraph
108 {
109
110 namespace
111 {
112
113 void DestroyNodeSet( std::set<Node*>& nodeSet )
114 {
115   for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
116   {
117     Node* node( *iter );
118
119     // Call Node::OnDestroy as each node is destroyed
120     node->OnDestroy();
121
122     delete node;
123   }
124   nodeSet.clear();
125 }
126
127 } //namespace
128
129 typedef OwnerContainer< Geometry* >            GeometryContainer;
130 typedef GeometryContainer::Iterator            GeometryIter;
131 typedef GeometryContainer::ConstIterator       GeometryConstIter;
132
133 typedef OwnerContainer< Material* >            MaterialContainer;
134 typedef MaterialContainer::Iterator            MaterialIter;
135 typedef MaterialContainer::ConstIterator       MaterialConstIter;
136
137 typedef OwnerContainer< Shader* >              ShaderContainer;
138 typedef ShaderContainer::Iterator              ShaderIter;
139 typedef ShaderContainer::ConstIterator         ShaderConstIter;
140
141 typedef OwnerContainer<PanGesture*>            GestureContainer;
142 typedef GestureContainer::Iterator             GestureIter;
143 typedef GestureContainer::ConstIterator        GestureConstIter;
144
145
146 /**
147  * Structure to contain UpdateManager internal data
148  */
149 struct UpdateManager::Impl
150 {
151   Impl( NotificationManager& notificationManager,
152         GlSyncAbstraction& glSyncAbstraction,
153         CompleteNotificationInterface& animationFinishedNotifier,
154         PropertyNotifier& propertyNotifier,
155         ResourceManager& resourceManager,
156         DiscardQueue& discardQueue,
157         RenderController& renderController,
158         RenderManager& renderManager,
159         RenderQueue& renderQueue,
160         TextureCache& textureCache,
161         TouchResampler& touchResampler,
162         SceneGraphBuffers& sceneGraphBuffers )
163   :
164     renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
165     notificationManager( notificationManager ),
166     animationFinishedNotifier( animationFinishedNotifier ),
167     propertyNotifier( propertyNotifier ),
168     resourceManager( resourceManager ),
169     discardQueue( discardQueue ),
170     renderController( renderController ),
171     sceneController( NULL ),
172     renderManager( renderManager ),
173     renderQueue( renderQueue ),
174     renderInstructions( renderManager.GetRenderInstructionContainer() ),
175     completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
176     touchResampler( touchResampler ),
177     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
178     taskList ( completeStatusManager ),
179     systemLevelTaskList ( completeStatusManager ),
180     root( NULL ),
181     systemLevelRoot( NULL ),
182     messageQueue( renderController, sceneGraphBuffers ),
183     dynamicsChanged( false ),
184     keepRenderingSeconds( 0.0f ),
185     animationFinishedDuringUpdate( false ),
186     activeConstraints( 0 ),
187     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
188     previousUpdateScene( false ),
189     frameCounter( 0 ),
190     renderSortingHelper(),
191     renderTaskWaiting( false )
192   {
193     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
194   }
195
196   ~Impl()
197   {
198     // Disconnect render tasks from nodes, before destroying the nodes
199     RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
200     for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
201     {
202       (*iter)->SetSourceNode( NULL );
203     }
204     // ..repeat for system level RenderTasks
205     RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
206     for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
207     {
208       (*iter)->SetSourceNode( NULL );
209     }
210
211     // UpdateManager owns the Nodes
212     DestroyNodeSet( activeDisconnectedNodes );
213     DestroyNodeSet( connectedNodes );
214     DestroyNodeSet( disconnectedNodes );
215
216     // If there is root, reset it, otherwise do nothing as rendering was never started
217     if( root )
218     {
219       root->OnDestroy();
220
221       delete root;
222       root = NULL;
223     }
224
225     if( systemLevelRoot )
226     {
227       systemLevelRoot->OnDestroy();
228
229       delete systemLevelRoot;
230       systemLevelRoot = NULL;
231     }
232
233     sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
234     delete sceneController;
235   }
236
237   SceneGraphBuffers                   sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
238   RenderMessageDispatcher             renderMessageDispatcher;       ///< Used for passing messages to the render-thread
239   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
240   CompleteNotificationInterface&      animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
241   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
242   ResourceManager&                    resourceManager;               ///< resource manager
243   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
244   RenderController&                   renderController;              ///< render controller
245   SceneControllerImpl*                sceneController;               ///< scene controller
246   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
247   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
248   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
249   CompleteStatusManager               completeStatusManager;         ///< Complete Status Manager
250   TouchResampler&                     touchResampler;                ///< Used to resample touch events on every update.
251
252   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
253
254   RenderTaskList                      taskList;                      ///< The list of scene graph render-tasks
255   RenderTaskList                      systemLevelTaskList;           ///< Separate render-tasks for system-level content
256
257   Layer*                              root;                          ///< The root node (root is a layer)
258   Layer*                              systemLevelRoot;               ///< A separate root-node for system-level content
259   std::set< Node* >                   activeDisconnectedNodes;       ///< A container of new or modified nodes (without parent) owned by UpdateManager
260   std::set< Node* >                   connectedNodes;                ///< A container of connected (with parent) nodes owned by UpdateManager
261   std::set< Node* >                   disconnectedNodes;             ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
262
263   SortedLayerPointers                 sortedLayers;                  ///< A container of Layer pointers sorted by depth
264   SortedLayerPointers                 systemLevelSortedLayers;       ///< A separate container of system-level Layers
265
266   OwnerContainer< PropertyOwner* >    customObjects;                 ///< A container of owned objects (with custom properties)
267
268   AnimationContainer                  animations;                    ///< A container of owned animations
269   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
270
271   GeometryContainer                   geometries;                    ///< A container of geometries
272   MaterialContainer                   materials;                     ///< A container of materials
273
274   ShaderContainer                     shaders;                       ///< A container of owned shaders
275
276   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
277
278 #ifdef DYNAMICS_SUPPORT
279   OwnerPointer<DynamicsWorld>         dynamicsWorld;                 ///< Wrapper for dynamics simulation
280 #endif
281   bool                                dynamicsChanged;               ///< This is set to true if an object is changed in the dynamics simulation tick
282
283   float                               keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
284   bool                                animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
285
286   unsigned int                        activeConstraints;             ///< number of active constraints from previous frame
287   int                                 nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
288   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
289
290   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
291   RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
292
293   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
294   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
295 };
296
297 UpdateManager::UpdateManager( NotificationManager& notificationManager,
298                               GlSyncAbstraction& glSyncAbstraction,
299                               CompleteNotificationInterface& animationFinishedNotifier,
300                               PropertyNotifier& propertyNotifier,
301                               ResourceManager& resourceManager,
302                               DiscardQueue& discardQueue,
303                               RenderController& controller,
304                               RenderManager& renderManager,
305                               RenderQueue& renderQueue,
306                               TextureCache& textureCache,
307                               TouchResampler& touchResampler )
308   : mImpl(NULL)
309 {
310   mImpl = new Impl( notificationManager,
311                     glSyncAbstraction,
312                     animationFinishedNotifier,
313                     propertyNotifier,
314                     resourceManager,
315                     discardQueue,
316                     controller,
317                     renderManager,
318                     renderQueue,
319                     textureCache,
320                     touchResampler,
321                     mSceneGraphBuffers );
322
323   textureCache.SetBufferIndices( &mSceneGraphBuffers );
324 }
325
326 UpdateManager::~UpdateManager()
327 {
328   delete mImpl;
329 }
330
331 EventToUpdate& UpdateManager::GetEventToUpdate()
332 {
333   return mImpl->messageQueue;
334 }
335
336 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
337 {
338   DALI_ASSERT_DEBUG( layer->IsLayer() );
339   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
340
341   if ( !systemLevel )
342   {
343     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
344     mImpl->root = layer;
345   }
346   else
347   {
348     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
349     mImpl->systemLevelRoot = layer;
350   }
351
352   layer->SetRoot(true);
353 }
354
355 void UpdateManager::AddNode( Node* node )
356 {
357   DALI_ASSERT_ALWAYS( NULL != node );
358   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
359
360   mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
361 }
362
363 void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
364 {
365   DALI_ASSERT_ALWAYS( NULL != parent );
366   DALI_ASSERT_ALWAYS( NULL != node );
367   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
368
369   // Move from active/disconnectedNodes to connectedNodes
370   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
371   if( !removed )
372   {
373     removed = mImpl->disconnectedNodes.erase( node );
374     DALI_ASSERT_ALWAYS( removed );
375   }
376   mImpl->connectedNodes.insert( node );
377
378   node->SetActive( true );
379
380   parent->ConnectChild( node, index );
381 }
382
383 void UpdateManager::DisconnectNode( Node* node )
384 {
385   Node* parent = node->GetParent();
386   DALI_ASSERT_ALWAYS( NULL != parent );
387   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
388
389   // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
390   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
391 }
392
393 void UpdateManager::SetNodeActive( Node* node )
394 {
395   DALI_ASSERT_ALWAYS( NULL != node );
396   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
397
398   // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
399   std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
400   DALI_ASSERT_ALWAYS( removed );
401   mImpl->activeDisconnectedNodes.insert( node );
402
403   node->SetActive( true );
404 }
405
406 void UpdateManager::DestroyNode( Node* node )
407 {
408   DALI_ASSERT_ALWAYS( NULL != node );
409   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
410
411   // Transfer ownership from new/disconnectedNodes to the discard queue
412   // This keeps the nodes alive, until the render-thread has finished with them
413   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
414   if( !removed )
415   {
416     removed = mImpl->disconnectedNodes.erase( node );
417     DALI_ASSERT_ALWAYS( removed );
418   }
419   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
420
421   // Notify the Node about impending destruction
422   node->OnDestroy();
423 }
424
425 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
426 {
427   DALI_ASSERT_DEBUG( node != NULL );
428   DALI_ASSERT_DEBUG( attachment != NULL );
429
430   // attach node to attachment first so that parent is known by the time attachment is connected
431   node->Attach( *attachment ); // node takes ownership
432   attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
433 }
434
435 void UpdateManager::AddObject( PropertyOwner* object )
436 {
437   DALI_ASSERT_DEBUG( NULL != object );
438
439   mImpl->customObjects.PushBack( object );
440 }
441
442 void UpdateManager::RemoveObject( PropertyOwner* object )
443 {
444   DALI_ASSERT_DEBUG( NULL != object );
445
446   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
447
448   // Find the object and destroy it
449   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
450   {
451     PropertyOwner* current = *iter;
452     if ( current == object )
453     {
454       customObjects.Erase( iter );
455       return;
456     }
457   }
458
459   // Should not reach here
460   DALI_ASSERT_DEBUG(false);
461 }
462
463 void UpdateManager::AddAnimation( Animation* animation )
464 {
465   mImpl->animations.PushBack( animation );
466 }
467
468 void UpdateManager::StopAnimation( Animation* animation )
469 {
470   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
471
472   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
473
474   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
475 }
476
477 void UpdateManager::RemoveAnimation( Animation* animation )
478 {
479   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
480
481   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
482
483   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
484 }
485
486 bool UpdateManager::IsAnimationRunning() const
487 {
488   bool isRunning(false);
489   AnimationContainer& animations = mImpl->animations;
490
491   // Find any animation that isn't stopped or paused
492
493   const AnimationIter endIter = animations.End();
494   for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
495   {
496     const Animation::State state = (*iter)->GetState();
497
498     if (state != Animation::Stopped &&
499         state != Animation::Paused)
500     {
501       isRunning = true;
502     }
503   }
504
505   return isRunning;
506 }
507
508 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
509 {
510   mImpl->propertyNotifications.PushBack( propertyNotification );
511 }
512
513 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
514 {
515   PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
516   PropertyNotificationIter iter = propertyNotifications.Begin();
517
518   while ( iter != propertyNotifications.End() )
519   {
520     if( *iter == propertyNotification )
521     {
522       propertyNotifications.Erase(iter);
523       break;
524     }
525     ++iter;
526   }
527 }
528
529 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
530 {
531   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
532   propertyNotification->SetNotifyMode( notifyMode );
533 }
534
535
536 void UpdateManager::AddGeometry( Geometry* geometry )
537 {
538   DALI_ASSERT_DEBUG( NULL != geometry );
539   mImpl->geometries.PushBack( geometry );
540 }
541
542 void UpdateManager::RemoveGeometry( Geometry* geometry )
543 {
544   DALI_ASSERT_DEBUG(geometry != NULL);
545
546   GeometryContainer& geometries = mImpl->geometries;
547
548   // Find the geometry and destroy it
549   for ( GeometryIter iter = geometries.Begin(); iter != geometries.End(); ++iter )
550   {
551     Geometry& current = **iter;
552     if ( &current == geometry )
553     {
554       // Transfer ownership to the discard queue
555       // This keeps the geometry alive, until the render-thread has finished with it
556       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), geometries.Release( iter ) );
557
558       return;
559     }
560   }
561
562   // Should not reach here
563   DALI_ASSERT_DEBUG(false);
564 }
565
566 void UpdateManager::AddMaterial( Material* material )
567 {
568   DALI_ASSERT_DEBUG( NULL != material );
569
570   mImpl->materials.PushBack( material );
571 }
572
573 void UpdateManager::RemoveMaterial( Material* material )
574 {
575   DALI_ASSERT_DEBUG(material != NULL);
576
577   MaterialContainer& materials = mImpl->materials;
578
579   // Find the material and destroy it
580   for ( MaterialIter iter = materials.Begin(); iter != materials.End(); ++iter )
581   {
582     Material& current = **iter;
583     if ( &current == material )
584     {
585       // Transfer ownership to the discard queue
586       // This keeps the material alive, until the render-thread has finished with it
587       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), materials.Release( iter ) );
588
589       materials.Erase(iter);
590       return;
591     }
592   }
593   // Should not reach here
594   DALI_ASSERT_DEBUG(false);
595 }
596
597 void UpdateManager::AddShader( Shader* shader )
598 {
599   DALI_ASSERT_DEBUG( NULL != shader );
600
601   if( mImpl->shaders.Count() == 0 )
602   {
603     // the first added shader becomes our default shader
604     // Construct message in the render queue memory; note that delete should not be called on the return value
605     typedef MessageValue1< RenderManager, Shader* > DerivedType;
606
607     // Reserve some memory inside the render queue
608     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
609
610     // Construct message in the render queue memory; note that delete should not be called on the return value
611     new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
612   }
613
614   mImpl->shaders.PushBack( shader );
615
616   // Allows the shader to dispatch texture requests to the cache
617   shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
618 }
619
620 void UpdateManager::RemoveShader( Shader* shader )
621 {
622   DALI_ASSERT_DEBUG(shader != NULL);
623
624   ShaderContainer& shaders = mImpl->shaders;
625
626   // Find the shader and destroy it
627   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
628   {
629     Shader& current = **iter;
630     if ( &current == shader )
631     {
632       // Transfer ownership to the discard queue
633       // This keeps the shader alive, until the render-thread has finished with it
634       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
635
636       return;
637     }
638   }
639   // Should not reach here
640   DALI_ASSERT_DEBUG(false);
641 }
642
643 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
644 {
645   DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
646
647   DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
648
649   Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
650   if( shaderData )
651   {
652     shaderData->SetHashValue( shaderHash );
653     shaderData->SetResourceId( resourceId );
654
655     typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
656
657     // Reserve some memory inside the render queue
658     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
659
660     // Construct message in the render queue memory; note that delete should not be called on the return value
661     new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
662   }
663 }
664
665 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
666 {
667   if ( !systemLevel )
668   {
669     // copy the list, this is only likely to happen once in application life cycle
670     return &(mImpl->taskList);
671   }
672   else
673   {
674     // copy the list, this is only likely to happen once in application life cycle
675     return &(mImpl->systemLevelTaskList);
676   }
677 }
678
679 void UpdateManager::AddGesture( PanGesture* gesture )
680 {
681   DALI_ASSERT_DEBUG( NULL != gesture );
682
683   mImpl->gestures.PushBack( gesture );
684 }
685
686 void UpdateManager::RemoveGesture( PanGesture* gesture )
687 {
688   DALI_ASSERT_DEBUG( gesture != NULL );
689
690   GestureContainer& gestures = mImpl->gestures;
691
692   // Find the gesture and destroy it
693   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
694   {
695     PanGesture& current = **iter;
696     if ( &current == gesture )
697     {
698       mImpl->gestures.Erase( iter );
699       return;
700     }
701   }
702   // Should not reach here
703   DALI_ASSERT_DEBUG(false);
704 }
705
706 void UpdateManager::ResetNodeProperty( Node& node )
707 {
708   node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
709 }
710
711 void UpdateManager::ResetProperties()
712 {
713   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
714
715   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
716   mImpl->animationFinishedDuringUpdate = false;
717
718   // Animated properties have to be reset to their original value each frame
719
720   // Reset node properties
721   if ( mImpl->root )
722   {
723     ResetNodeProperty( *mImpl->root );
724   }
725
726   if ( mImpl->systemLevelRoot )
727   {
728     ResetNodeProperty( *mImpl->systemLevelRoot );
729   }
730
731   // Reset the Connected Nodes
732   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
733   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
734   {
735     ResetNodeProperty( **iter );
736   }
737
738   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
739   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
740   {
741     Node* node = *iter;
742     node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
743     node->SetActive( false );
744
745     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
746     mImpl->activeDisconnectedNodes.erase( iter );
747     mImpl->disconnectedNodes.insert( node );
748   }
749
750   // Reset system-level render-task list properties to base values
751   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
752
753   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
754   {
755     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
756   }
757
758   // Reset render-task list properties to base values.
759   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
760
761   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
762   {
763     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
764   }
765
766   // Reset custom object properties to base values
767   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
768   {
769     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
770   }
771
772   // Reset animatable material properties to base values
773   for (MaterialIter iter = mImpl->materials.Begin(); iter != mImpl->materials.End(); ++iter)
774   {
775     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
776   }
777
778   // Reset animatable geometry properties to base values
779   for (GeometryIter iter = mImpl->geometries.Begin(); iter != mImpl->geometries.End(); ++iter)
780   {
781     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
782   }
783
784   // Reset animatable shader properties to base values
785   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
786   {
787     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
788   }
789
790   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
791 }
792
793 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
794 {
795   bool gestureUpdated( false );
796
797   // constrain gestures... (in construction order)
798   GestureContainer& gestures = mImpl->gestures;
799
800   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
801   {
802     PanGesture& gesture = **iter;
803     gesture.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
804     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
805   }
806
807   return gestureUpdated;
808 }
809
810 void UpdateManager::Animate( float elapsedSeconds )
811 {
812   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
813
814   AnimationContainer &animations = mImpl->animations;
815   AnimationIter iter = animations.Begin();
816   while ( iter != animations.End() )
817   {
818     Animation* animation = *iter;
819     bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
820
821     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
822
823     // Remove animations that had been destroyed but were still waiting for an update
824     if (animation->GetState() == Animation::Destroyed)
825     {
826       iter = animations.Erase(iter);
827     }
828     else
829     {
830       ++iter;
831     }
832   }
833
834   if ( mImpl->animationFinishedDuringUpdate )
835   {
836     // The application should be notified by NotificationManager, in another thread
837     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
838   }
839
840   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
841 }
842
843 void UpdateManager::ApplyConstraints()
844 {
845   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
846
847   mImpl->activeConstraints = 0;
848
849   // constrain custom objects... (in construction order)
850   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
851
852   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
853   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
854   {
855     PropertyOwner& object = **iter;
856     mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
857   }
858
859   // constrain nodes... (in Depth First traversal order)
860   if ( mImpl->root )
861   {
862     mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
863   }
864
865   if ( mImpl->systemLevelRoot )
866   {
867     mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
868   }
869
870   // constrain other property-owners after nodes as they are more likely to depend on a node's
871   // current frame property than vice versa. They tend to be final constraints (no further
872   // constraints depend on their properties)
873   // e.g. ShaderEffect uniform a function of Actor's position.
874   // Mesh vertex a function of Actor's position or world position.
875
876   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
877   // they can be all processed in a super-list of property-owners.
878
879   // Constrain system-level render-tasks
880   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
881
882   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
883   {
884     RenderTask& task = **iter;
885     mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
886   }
887
888   // Constrain render-tasks
889   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
890
891   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
892   {
893     RenderTask& task = **iter;
894     mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
895   }
896
897   // Constrain Materials and geometries
898   MaterialContainer& materials = mImpl->materials;
899   for ( MaterialIter iter = materials.Begin(); iter != materials.End(); ++iter )
900   {
901     Material& material = **iter;
902     mImpl->activeConstraints += ConstrainPropertyOwner( material, mSceneGraphBuffers.GetUpdateBufferIndex() );
903   }
904
905   GeometryContainer& geometries = mImpl->geometries;
906   for ( GeometryIter iter = geometries.Begin(); iter != geometries.End(); ++iter )
907   {
908     Geometry& geometry = **iter;
909     mImpl->activeConstraints += ConstrainPropertyOwner( geometry, mSceneGraphBuffers.GetUpdateBufferIndex() );
910   }
911
912   // constrain shaders... (in construction order)
913   ShaderContainer& shaders = mImpl->shaders;
914
915   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
916   {
917     Shader& shader = **iter;
918     mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
919   }
920
921   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
922 }
923
924 void UpdateManager::ProcessPropertyNotifications()
925 {
926   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
927   PropertyNotificationIter iter = notifications.Begin();
928
929   while ( iter != notifications.End() )
930   {
931     PropertyNotification* notification = *iter;
932
933     bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
934
935     if(valid)
936     {
937       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
938     }
939     ++iter;
940   }
941 }
942
943 void UpdateManager::UpdateNodes()
944 {
945   mImpl->nodeDirtyFlags = NothingFlag;
946
947   if ( !mImpl->root )
948   {
949     return;
950   }
951
952   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
953
954   // Prepare resources, update shaders, update attachments, for each node
955   // And add the renderers to the sorted layers. Start from root, which is also a layer
956   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
957                                                      mSceneGraphBuffers.GetUpdateBufferIndex(),
958                                                      mImpl->resourceManager,
959                                                      mImpl->renderQueue );
960
961   if ( mImpl->systemLevelRoot )
962   {
963     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
964                                                         mSceneGraphBuffers.GetUpdateBufferIndex(),
965                                                         mImpl->resourceManager,
966                                                         mImpl->renderQueue );
967   }
968
969   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
970 }
971
972 unsigned int UpdateManager::Update( float elapsedSeconds,
973                                     unsigned int lastVSyncTimeMilliseconds,
974                                     unsigned int nextVSyncTimeMilliseconds )
975 {
976   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
977   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
978   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
979
980   // Measure the time spent in UpdateManager::Update
981   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
982
983   // Update the frame time delta on the render thread.
984   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
985
986   // 1) Clear nodes/resources which were previously discarded
987   mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
988
989   // 2) Grab any loaded resources
990   bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
991
992   // 3) Process Touches & Gestures
993   mImpl->touchResampler.Update();
994   const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
995
996   const bool updateScene =                                            // The scene-graph requires an update if..
997       mImpl->activeConstraints != 0 ||                                // ..constraints were active in previous frame OR
998       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
999       IsAnimationRunning() ||                                         // ..at least one animation is running OR
1000       mImpl->dynamicsChanged ||                                       // ..there was a change in the dynamics simulation OR
1001       mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued OR
1002       resourceChanged ||                                              // ..one or more resources were updated/changed OR
1003       gestureUpdated;                                                // ..a gesture property was updated
1004
1005   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1006   // values if the scene was updated in the previous frame.
1007   if( updateScene || mImpl->previousUpdateScene )
1008   {
1009     // 4) Reset properties from the previous update
1010     ResetProperties();
1011   }
1012
1013   // 5) Process the queued scene messages
1014   mImpl->messageQueue.ProcessMessages();
1015
1016   // 6) Post Process Ids of resources updated by renderer
1017   mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1018
1019   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1020   // renderer lists if the scene was updated in the previous frame.
1021   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1022   if( updateScene || mImpl->previousUpdateScene )
1023   {
1024     // 7) Animate
1025     Animate( elapsedSeconds );
1026
1027     // 8) Apply Constraints
1028     ApplyConstraints();
1029
1030 #ifdef DYNAMICS_SUPPORT
1031     // 9) Update dynamics simulation
1032     mImpl->dynamicsChanged = false;
1033     if( mImpl->dynamicsWorld )
1034     {
1035       mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1036     }
1037 #endif
1038
1039     // 10) Check Property Notifications
1040     ProcessPropertyNotifications();
1041
1042     // 11) Clear the lists of renderable-attachments from the previous update
1043     ClearRenderables( mImpl->sortedLayers );
1044     ClearRenderables( mImpl->systemLevelSortedLayers );
1045
1046     // 12) Update node hierarchy and perform sorting / culling.
1047     //     This will populate each Layer with a list of renderers which are ready.
1048     UpdateNodes();
1049
1050     // 13) Prepare for the next render
1051     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1052
1053     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1054     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1055     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1056
1057     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1058
1059     // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1060     // reset the update buffer index and make sure there is enough room in the instruction container
1061     mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1062                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1063
1064     if ( NULL != mImpl->root )
1065     {
1066       ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1067                            mImpl->completeStatusManager,
1068                            mImpl->taskList,
1069                            *mImpl->root,
1070                            mImpl->sortedLayers,
1071                            mImpl->renderSortingHelper,
1072                            mImpl->renderInstructions );
1073
1074       // Process the system-level RenderTasks last
1075       if ( NULL != mImpl->systemLevelRoot )
1076       {
1077         ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1078                              mImpl->completeStatusManager,
1079                              mImpl->systemLevelTaskList,
1080                              *mImpl->systemLevelRoot,
1081                              mImpl->systemLevelSortedLayers,
1082                              mImpl->renderSortingHelper,
1083                              mImpl->renderInstructions );
1084       }
1085     }
1086   }
1087
1088   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1089   bool doRenderOnceNotify = false;
1090   mImpl->renderTaskWaiting = false;
1091   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1092   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1093         endIter != iter; ++iter )
1094   {
1095     RenderTask& renderTask(*(*iter));
1096
1097     renderTask.UpdateState();
1098
1099     if( renderTask.IsWaitingToRender() &&
1100         renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1101     {
1102       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1103     }
1104
1105     if( renderTask.HasRendered() )
1106     {
1107       doRenderOnceNotify = true;
1108     }
1109   }
1110
1111   if( doRenderOnceNotify )
1112   {
1113     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1114     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1115   }
1116
1117   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1118
1119   // Macro is undefined in release build.
1120   SNAPSHOT_NODE_LOGGING;
1121
1122   // A ResetProperties() may be required in the next frame
1123   mImpl->previousUpdateScene = updateScene;
1124
1125   // Check whether further updates are required
1126   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1127
1128 #ifdef PERFORMANCE_MONITOR_ENABLED
1129   // Always keep rendering when measuring FPS
1130   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1131 #endif
1132
1133   // The update has finished; swap the double-buffering indices
1134   mSceneGraphBuffers.Swap();
1135
1136   // tell the update manager that we're done so the queue can be given to event thread
1137   mImpl->notificationManager.UpdateCompleted();
1138
1139   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1140
1141   return keepUpdating;
1142 }
1143
1144 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1145 {
1146   // Update the duration set via Stage::KeepRendering()
1147   if ( mImpl->keepRenderingSeconds > 0.0f )
1148   {
1149     mImpl->keepRenderingSeconds -= elapsedSeconds;
1150   }
1151
1152   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1153
1154   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1155   // Keep updating until no messages are received and no animations are running.
1156   // If an animation has just finished, update at least once more for Discard end-actions.
1157   // No need to check for renderQueue as there is always a render after update and if that
1158   // render needs another update it will tell the adaptor to call update again
1159
1160   if ( mImpl->keepRenderingSeconds > 0.0f )
1161   {
1162     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1163   }
1164
1165   if ( !mImpl->messageQueue.WasEmpty() )
1166   {
1167     keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1168   }
1169
1170   if ( IsAnimationRunning() ||
1171        mImpl->animationFinishedDuringUpdate )
1172   {
1173     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1174   }
1175
1176   if ( mImpl->dynamicsChanged )
1177   {
1178     keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1179   }
1180
1181   if ( mImpl->renderTaskWaiting )
1182   {
1183     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1184   }
1185
1186   return keepUpdatingRequest;
1187 }
1188
1189 void UpdateManager::SetBackgroundColor( const Vector4& color )
1190 {
1191   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1192
1193   // Reserve some memory inside the render queue
1194   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1195
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::SetBackgroundColor, color );
1198 }
1199
1200 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1201 {
1202   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1203
1204   // Reserve some memory inside the render queue
1205   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1206
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::SetDefaultSurfaceRect, rect );
1209 }
1210
1211 void UpdateManager::KeepRendering( float durationSeconds )
1212 {
1213   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1214 }
1215
1216 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1217 {
1218   if ( !systemLevel )
1219   {
1220     // just copy the vector of pointers
1221     mImpl->sortedLayers = layers;
1222   }
1223   else
1224   {
1225     mImpl->systemLevelSortedLayers = layers;
1226   }
1227 }
1228
1229 #ifdef DYNAMICS_SUPPORT
1230
1231 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1232 {
1233   dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1234   mImpl->dynamicsWorld = dynamicsWorld;
1235 }
1236
1237 void UpdateManager::TerminateDynamicsWorld()
1238 {
1239   mImpl->dynamicsWorld.Reset();
1240 }
1241
1242 #endif // DYNAMICS_SUPPORT
1243
1244 } // namespace SceneGraph
1245
1246 } // namespace Internal
1247
1248 } // namespace Dali