Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2018 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/devel-api/common/owner-container.h>
24 #include <dali/devel-api/threading/mutex.h>
25
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/render-controller.h>
28 #include <dali/internal/common/shader-data.h>
29 #include <dali/integration-api/debug.h>
30
31 #include <dali/internal/common/core-impl.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 #include <dali/internal/event/effects/shader-factory.h>
38 #include <dali/internal/event/animation/animation-playlist.h>
39
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/render-task-processor.h>
48 #include <dali/internal/update/manager/sorted-layers.h>
49 #include <dali/internal/update/manager/update-algorithms.h>
50 #include <dali/internal/update/manager/update-manager-debug.h>
51 #include <dali/internal/update/manager/transform-manager.h>
52 #include <dali/internal/update/nodes/node.h>
53 #include <dali/internal/update/nodes/scene-graph-layer.h>
54 #include <dali/internal/update/queue/update-message-queue.h>
55 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
57 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
58
59 #include <dali/internal/render/common/render-instruction-container.h>
60 #include <dali/internal/render/common/render-manager.h>
61 #include <dali/internal/render/queue/render-queue.h>
62 #include <dali/internal/render/shaders/scene-graph-shader.h>
63
64 // Un-comment to enable node tree debug logging
65 //#define NODE_TREE_LOGGING 1
66
67 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
68 #define SNAPSHOT_NODE_LOGGING \
69 const int FRAME_COUNT_TRIGGER = 16;\
70 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
71   {\
72     if ( NULL != mImpl->root )\
73     {\
74       mImpl->frameCounter = 0;\
75       PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
76     }\
77   }\
78 mImpl->frameCounter++;
79 #else
80 #define SNAPSHOT_NODE_LOGGING
81 #endif
82
83 #if defined(DEBUG_ENABLED)
84 extern Debug::Filter* gRenderTaskLogFilter;
85 #endif
86
87
88 using namespace Dali::Integration;
89 using Dali::Internal::Update::MessageQueue;
90
91 namespace Dali
92 {
93
94 namespace Internal
95 {
96
97 namespace SceneGraph
98 {
99
100 namespace
101 {
102 /**
103  * Helper to reset animate-able objects to base values
104  * @param container to iterate over
105  * @param updateBufferIndex to use
106  */
107 template< class T >
108 inline void ResetToBaseValues( OwnerContainer<T*>& container, BufferIndex updateBufferIndex )
109 {
110   // Reset animatable properties to base values
111   // use reference to avoid extra copies of the iterator
112   for( auto&& iter : container )
113   {
114     iter->ResetToBaseValues( updateBufferIndex );
115   }
116 }
117
118 /**
119  * Helper to Erase an object from OwnerContainer using discard queue
120  * @param container to remove from
121  * @param object to remove
122  * @param discardQueue to put the object to
123  * @param updateBufferIndex to use
124  */
125 template < class T >
126 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
127 {
128   DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
129
130   // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
131   for( auto&& iter : container )
132   {
133     if ( iter == object )
134     {
135       // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
136       discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
137       return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
138     }
139   }
140 }
141
142 /**
143  * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
144  * @param[in] node The node whose hierarchy to descend
145  */
146 void SortSiblingNodesRecursively( Node& node )
147 {
148   NodeContainer& container = node.GetChildren();
149   std::sort( container.Begin(), container.End(),
150              []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
151
152   // Descend tree and sort as well
153   for( auto&& iter : container )
154   {
155     SortSiblingNodesRecursively( *iter );
156   }
157 }
158
159 } // unnamed namespace
160
161 /**
162  * Structure to contain UpdateManager internal data
163  */
164 struct UpdateManager::Impl
165 {
166   Impl( NotificationManager& notificationManager,
167         CompleteNotificationInterface& animationPlaylist,
168         PropertyNotifier& propertyNotifier,
169         DiscardQueue& discardQueue,
170         RenderController& renderController,
171         RenderManager& renderManager,
172         RenderQueue& renderQueue,
173         SceneGraphBuffers& sceneGraphBuffers,
174         RenderTaskProcessor& renderTaskProcessor )
175   : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
176     notificationManager( notificationManager ),
177     transformManager(),
178     animationPlaylist( animationPlaylist ),
179     propertyNotifier( propertyNotifier ),
180     shaderSaver( NULL ),
181     discardQueue( discardQueue ),
182     renderController( renderController ),
183     sceneController( NULL ),
184     renderManager( renderManager ),
185     renderQueue( renderQueue ),
186     renderInstructions( renderManager.GetRenderInstructionContainer() ),
187     renderTaskProcessor( renderTaskProcessor ),
188     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
189     taskList( renderMessageDispatcher ),
190     systemLevelTaskList( renderMessageDispatcher ),
191     root( NULL ),
192     systemLevelRoot( NULL ),
193     renderers(),
194     textureSets(),
195     shaders(),
196     panGestureProcessor( NULL ),
197     messageQueue( renderController, sceneGraphBuffers ),
198     keepRenderingSeconds( 0.0f ),
199     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
200     frameCounter( 0 ),
201     animationFinishedDuringUpdate( false ),
202     previousUpdateScene( false ),
203     renderTaskWaiting( false ),
204     renderersAdded( false )
205   {
206     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
207
208     // create first 'dummy' node
209     nodes.PushBack(0u);
210   }
211
212   ~Impl()
213   {
214     // Disconnect render tasks from nodes, before destroying the nodes
215     RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
216     for ( auto&& iter : tasks )
217     {
218       iter->SetSourceNode( NULL );
219     }
220     // ..repeat for system level RenderTasks
221     RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
222     for ( auto&& iter : systemLevelTasks )
223     {
224       iter->SetSourceNode( NULL );
225     }
226
227     // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
228     // like custom properties, which get released here
229     Vector<Node*>::Iterator iter = nodes.Begin()+1;
230     Vector<Node*>::Iterator endIter = nodes.End();
231     for(;iter!=endIter;++iter)
232     {
233       (*iter)->OnDestroy();
234       Node::Delete(*iter);
235     }
236
237     // If there is root, reset it, otherwise do nothing as rendering was never started
238     if( root )
239     {
240       root->OnDestroy();
241
242       Node::Delete( root );
243       root = NULL;
244     }
245
246     if( systemLevelRoot )
247     {
248       systemLevelRoot->OnDestroy();
249
250       Node::Delete( systemLevelRoot );
251       systemLevelRoot = NULL;
252     }
253
254     delete sceneController;
255   }
256
257   SceneGraphBuffers                    sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
258   RenderMessageDispatcher              renderMessageDispatcher;       ///< Used for passing messages to the render-thread
259   NotificationManager&                 notificationManager;           ///< Queues notification messages for the event-thread.
260   TransformManager                     transformManager;              ///< Used to update the transformation matrices of the nodes
261   CompleteNotificationInterface&       animationPlaylist;             ///< Holds handles to all the animations
262   PropertyNotifier&                    propertyNotifier;              ///< Provides notification to applications when properties are modified.
263   ShaderSaver*                         shaderSaver;                   ///< Saves shader binaries.
264   DiscardQueue&                        discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
265   RenderController&                    renderController;              ///< render controller
266   SceneControllerImpl*                 sceneController;               ///< scene controller
267   RenderManager&                       renderManager;                 ///< This is responsible for rendering the results of each "update"
268   RenderQueue&                         renderQueue;                   ///< Used to queue messages for the next render
269   RenderInstructionContainer&          renderInstructions;            ///< Used to prepare the render instructions
270   RenderTaskProcessor&                 renderTaskProcessor;           ///< Handles RenderTasks and RenderInstrucitons
271
272   Vector4                              backgroundColor;               ///< The glClear color used at the beginning of each frame.
273
274   RenderTaskList                       taskList;                      ///< The list of scene graph render-tasks
275   RenderTaskList                       systemLevelTaskList;           ///< Separate render-tasks for system-level content
276
277   Layer*                               root;                          ///< The root node (root is a layer)
278   Layer*                               systemLevelRoot;               ///< A separate root-node for system-level content
279
280   Vector<Node*>                        nodes;                         ///< A container of all instantiated nodes
281
282   SortedLayerPointers                  sortedLayers;                  ///< A container of Layer pointers sorted by depth
283   SortedLayerPointers                  systemLevelSortedLayers;       ///< A separate container of system-level Layers
284
285   OwnerContainer< Camera* >            cameras;                       ///< A container of cameras
286   OwnerContainer< PropertyOwner* >     customObjects;                 ///< A container of owned objects (with custom properties)
287
288   OwnerContainer< PropertyResetterBase* > propertyResetters;          ///< A container of property resetters
289   AnimationContainer                   animations;                    ///< A container of owned animations
290   PropertyNotificationContainer        propertyNotifications;         ///< A container of owner property notifications.
291   OwnerContainer< Renderer* >          renderers;                     ///< A container of owned renderers
292   OwnerContainer< TextureSet* >        textureSets;                   ///< A container of owned texture sets
293   OwnerContainer< Shader* >            shaders;                       ///< A container of owned shaders
294   OwnerPointer< PanGesture >           panGestureProcessor;           ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
295
296   MessageQueue                         messageQueue;                  ///< The messages queued from the event-thread
297   std::vector<Internal::ShaderDataPtr> renderCompiledShaders;         ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
298   std::vector<Internal::ShaderDataPtr> updateCompiledShaders;         ///< Shaders to be sent from Update to Event
299   Mutex                                compiledShaderMutex;           ///< lock to ensure no corruption on the renderCompiledShaders
300
301   float                                keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
302   int                                  nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
303   int                                  frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
304
305   bool                                 animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
306   bool                                 previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
307   bool                                 renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
308   bool                                 renderersAdded;                ///< Flag to keep track when renderers have been added to avoid unnecessary processing
309
310 private:
311
312   Impl( const Impl& ); ///< Undefined
313   Impl& operator=( const Impl& ); ///< Undefined
314 };
315
316 UpdateManager::UpdateManager( NotificationManager& notificationManager,
317                               CompleteNotificationInterface& animationFinishedNotifier,
318                               PropertyNotifier& propertyNotifier,
319                               DiscardQueue& discardQueue,
320                               RenderController& controller,
321                               RenderManager& renderManager,
322                               RenderQueue& renderQueue,
323                               RenderTaskProcessor& renderTaskProcessor )
324   : mImpl(NULL)
325 {
326   mImpl = new Impl( notificationManager,
327                     animationFinishedNotifier,
328                     propertyNotifier,
329                     discardQueue,
330                     controller,
331                     renderManager,
332                     renderQueue,
333                     mSceneGraphBuffers,
334                     renderTaskProcessor );
335
336 }
337
338 UpdateManager::~UpdateManager()
339 {
340   delete mImpl;
341 }
342
343 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer, bool systemLevel )
344 {
345   DALI_ASSERT_DEBUG( layer->IsLayer() );
346   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
347
348   if ( !systemLevel )
349   {
350     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
351     mImpl->root = layer.Release();
352     mImpl->root->CreateTransform( &mImpl->transformManager );
353     mImpl->root->SetRoot(true);
354   }
355   else
356   {
357     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
358     mImpl->systemLevelRoot = layer.Release();
359     mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
360     mImpl->systemLevelRoot->SetRoot(true);
361   }
362
363 }
364
365 void UpdateManager::AddNode( OwnerPointer<Node>& node )
366 {
367   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
368
369   // Nodes must be sorted by pointer
370   Node* rawNode = node.Release();
371   Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
372   for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
373   {
374     if( rawNode > (*iter) )
375     {
376       mImpl->nodes.Insert((iter+1), rawNode );
377       rawNode->CreateTransform( &mImpl->transformManager );
378       return;
379     }
380   }
381 }
382
383 void UpdateManager::ConnectNode( Node* parent, Node* node )
384 {
385   DALI_ASSERT_ALWAYS( NULL != parent );
386   DALI_ASSERT_ALWAYS( NULL != node );
387   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
388
389   parent->ConnectChild( node );
390 }
391
392 void UpdateManager::DisconnectNode( Node* node )
393 {
394   Node* parent = node->GetParent();
395   DALI_ASSERT_ALWAYS( NULL != parent );
396   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
397
398   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
399 }
400
401 void UpdateManager::DestroyNode( Node* node )
402 {
403   DALI_ASSERT_ALWAYS( NULL != node );
404   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
405
406   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
407   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
408   for(;iter!=endIter;++iter)
409   {
410     if((*iter) == node)
411     {
412       mImpl->nodes.Erase(iter);
413       break;
414     }
415   }
416
417   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
418
419   // Notify the Node about impending destruction
420   node->OnDestroy();
421 }
422
423 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
424 {
425   mImpl->cameras.PushBack( camera.Release() ); // takes ownership
426 }
427
428 void UpdateManager::RemoveCamera( const Camera* camera )
429 {
430   // Find the camera and destroy it
431   EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
432 }
433
434 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
435 {
436   mImpl->customObjects.PushBack( object.Release() );
437 }
438
439 void UpdateManager::RemoveObject( PropertyOwner* object )
440 {
441   mImpl->customObjects.EraseObject( object );
442 }
443
444 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
445 {
446   mImpl->animations.PushBack( animation.Release() );
447 }
448
449 void UpdateManager::StopAnimation( Animation* animation )
450 {
451   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
452
453   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
454
455   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
456 }
457
458 void UpdateManager::RemoveAnimation( Animation* animation )
459 {
460   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
461
462   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
463
464   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
465 }
466
467 bool UpdateManager::IsAnimationRunning() const
468 {
469   // Find any animation that isn't stopped or paused
470   for ( auto&& iter : mImpl->animations )
471   {
472     const Animation::State state = iter->GetState();
473
474     if (state != Animation::Stopped &&
475         state != Animation::Paused)
476     {
477       return true; // stop iteration as soon as first one is found
478     }
479   }
480
481   return false;
482 }
483
484 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
485 {
486   propertyResetter->Initialize();
487   mImpl->propertyResetters.PushBack( propertyResetter.Release() );
488 }
489
490 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
491 {
492   mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
493 }
494
495 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
496 {
497   mImpl->propertyNotifications.EraseObject( propertyNotification );
498 }
499
500 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
501 {
502   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
503   propertyNotification->SetNotifyMode( notifyMode );
504 }
505
506 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
507 {
508   mImpl->shaders.PushBack( shader.Release() );
509 }
510
511 void UpdateManager::RemoveShader( Shader* shader )
512 {
513   // Find the shader and destroy it
514   EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
515 }
516
517 void UpdateManager::SetShaderProgram( Shader* shader,
518                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
519 {
520   if( shaderData )
521   {
522
523     typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
524
525     // Reserve some memory inside the render queue
526     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
527
528     // Construct message in the render queue memory; note that delete should not be called on the return value
529     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
530   }
531 }
532
533 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
534 {
535   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
536   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
537   {
538     // lock as update might be sending previously compiled shaders to event thread
539     Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
540     mImpl->renderCompiledShaders.push_back( shaderData );
541   }
542 }
543
544 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
545 {
546   mImpl->shaderSaver = &upstream;
547 }
548
549 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
550 {
551   renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
552   mImpl->renderers.PushBack( renderer.Release() );
553   mImpl->renderersAdded = true;
554 }
555
556 void UpdateManager::RemoveRenderer( Renderer* renderer )
557 {
558   // Find the renderer and destroy it
559   EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
560   // Need to remove the render object as well
561   renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
562 }
563
564 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
565 {
566   DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
567
568   mImpl->panGestureProcessor = panGestureProcessor;
569 }
570
571 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
572 {
573   mImpl->textureSets.PushBack( textureSet.Release() );
574 }
575
576 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
577 {
578   mImpl->textureSets.EraseObject( textureSet );
579 }
580
581 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
582 {
583   if ( !systemLevel )
584   {
585     // copy the list, this is only likely to happen once in application life cycle
586     return &(mImpl->taskList);
587   }
588   else
589   {
590     // copy the list, this is only likely to happen once in application life cycle
591     return &(mImpl->systemLevelTaskList);
592   }
593 }
594
595 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
596 {
597   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
598 }
599
600 void UpdateManager::EventProcessingStarted()
601 {
602   mImpl->messageQueue.EventProcessingStarted();
603 }
604
605 bool UpdateManager::FlushQueue()
606 {
607   return mImpl->messageQueue.FlushQueue();
608 }
609
610 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
611 {
612   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
613   mImpl->animationFinishedDuringUpdate = false;
614
615   // Reset all animating / constrained properties
616   std::vector<PropertyResetterBase*>toDelete;
617   for( auto&& element : mImpl->propertyResetters )
618   {
619     element->ResetToBaseValue( bufferIndex );
620     if( element->IsFinished() )
621     {
622       toDelete.push_back( element );
623     }
624   }
625
626   // If a resetter is no longer required (the animator or constraint has been removed), delete it.
627   for( auto&& elementPtr : toDelete )
628   {
629     mImpl->propertyResetters.EraseObject( elementPtr );
630   }
631
632   // Clear node dirty flags
633   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
634   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
635   for( ;iter != endIter; ++iter )
636   {
637     (*iter)->ResetDirtyFlags( bufferIndex );
638   }
639 }
640
641 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
642 {
643   bool gestureUpdated( false );
644
645   if( mImpl->panGestureProcessor )
646   {
647     // gesture processor only supports default properties
648     mImpl->panGestureProcessor->ResetDefaultProperties( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
649     gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
650   }
651
652   return gestureUpdated;
653 }
654
655 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
656 {
657   AnimationContainer &animations = mImpl->animations;
658   AnimationIter iter = animations.Begin();
659   bool animationLooped = false;
660
661   while ( iter != animations.End() )
662   {
663     Animation* animation = *iter;
664     bool finished = false;
665     bool looped = false;
666     bool progressMarkerReached = false;
667     animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
668
669     if ( progressMarkerReached )
670     {
671       mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
672     }
673
674     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
675     animationLooped = animationLooped || looped;
676
677     // Remove animations that had been destroyed but were still waiting for an update
678     if (animation->GetState() == Animation::Destroyed)
679     {
680       iter = animations.Erase(iter);
681     }
682     else
683     {
684       ++iter;
685     }
686   }
687
688   // queue the notification on finished or looped (to update loop count)
689   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
690   {
691     // The application should be notified by NotificationManager, in another thread
692     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
693   }
694 }
695
696 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
697 {
698   //Constrain custom objects (in construction order)
699   for ( auto&& object : mImpl->customObjects )
700   {
701     ConstrainPropertyOwner( *object, bufferIndex );
702   }
703 }
704
705 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
706 {
707   // Constrain system-level render-tasks
708   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
709   for ( auto&& task : systemLevelTasks )
710   {
711     ConstrainPropertyOwner( *task, bufferIndex );
712   }
713
714   // Constrain render-tasks
715   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
716   for ( auto&& task : tasks )
717   {
718     ConstrainPropertyOwner( *task, bufferIndex );
719   }
720 }
721
722 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
723 {
724   // constrain shaders... (in construction order)
725   for ( auto&& shader : mImpl->shaders )
726   {
727     ConstrainPropertyOwner( *shader, bufferIndex );
728   }
729 }
730
731 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
732 {
733   for( auto&& notification : mImpl->propertyNotifications )
734   {
735     bool valid = notification->Check( bufferIndex );
736     if(valid)
737     {
738       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
739     }
740   }
741 }
742
743 void UpdateManager::ForwardCompiledShadersToEventThread()
744 {
745   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
746   if( mImpl->shaderSaver )
747   {
748     // lock and swap the queues
749     {
750       // render might be attempting to send us more binaries at the same time
751       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
752       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
753     }
754
755     if( mImpl->updateCompiledShaders.size() > 0 )
756     {
757       ShaderSaver& factory = *mImpl->shaderSaver;
758       for( auto&& shader : mImpl->updateCompiledShaders )
759       {
760         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
761       }
762       // we don't need them in update anymore
763       mImpl->updateCompiledShaders.clear();
764     }
765   }
766 }
767
768 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
769 {
770   const unsigned int rendererCount = mImpl->renderers.Count();
771   for( unsigned int i = 0; i < rendererCount; ++i )
772   {
773     //Apply constraints
774     ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
775
776     mImpl->renderers[i]->PrepareRender( bufferIndex );
777   }
778 }
779
780 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
781 {
782   mImpl->nodeDirtyFlags = NothingFlag;
783
784   if ( !mImpl->root )
785   {
786     return;
787   }
788
789   // Prepare resources, update shaders, for each node
790   // And add the renderers to the sorted layers. Start from root, which is also a layer
791   mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
792                                           bufferIndex,
793                                           mImpl->renderQueue );
794
795   if ( mImpl->systemLevelRoot )
796   {
797     mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
798                                              bufferIndex,
799                                              mImpl->renderQueue );
800   }
801 }
802
803 unsigned int UpdateManager::Update( float elapsedSeconds,
804                                     unsigned int lastVSyncTimeMilliseconds,
805                                     unsigned int nextVSyncTimeMilliseconds,
806                                     bool renderToFboEnabled,
807                                     bool isRenderingToFbo )
808 {
809   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
810
811   //Clear nodes/resources which were previously discarded
812   mImpl->discardQueue.Clear( bufferIndex );
813
814   //Process Touches & Gestures
815   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
816
817   bool updateScene = // The scene-graph requires an update if..
818       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
819       IsAnimationRunning()                            ||    // ..at least one animation is running OR
820       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
821       gestureUpdated;                                       // ..a gesture property was updated
822
823
824   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
825   // values if the scene was updated in the previous frame.
826   if( updateScene || mImpl->previousUpdateScene )
827   {
828     //Reset properties from the previous update
829     ResetProperties( bufferIndex );
830     mImpl->transformManager.ResetToBaseValue();
831   }
832
833   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
834   // between calling IsSceneUpdateRequired() above and here, so updateScene should
835   // be set again
836   updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
837
838   //Forward compiled shader programs to event thread for saving
839   ForwardCompiledShadersToEventThread();
840
841   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
842   // renderer lists if the scene was updated in the previous frame.
843   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
844   if( updateScene || mImpl->previousUpdateScene )
845   {
846     //Animate
847     Animate( bufferIndex, elapsedSeconds );
848
849     //Constraint custom objects
850     ConstrainCustomObjects( bufferIndex );
851
852     //Clear the lists of renderers from the previous update
853     for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
854     {
855       mImpl->sortedLayers[i]->ClearRenderables();
856     }
857
858     for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
859     {
860       mImpl->systemLevelSortedLayers[i]->ClearRenderables();
861     }
862
863     //Update node hierarchy, apply constraints and perform sorting / culling.
864     //This will populate each Layer with a list of renderers which are ready.
865     UpdateNodes( bufferIndex );
866
867     //Apply constraints to RenderTasks, shaders
868     ConstrainRenderTasks( bufferIndex );
869     ConstrainShaders( bufferIndex );
870
871     //Update renderers and apply constraints
872     UpdateRenderers( bufferIndex );
873
874     //Update the transformations of all the nodes
875     mImpl->transformManager.Update();
876
877     //Process Property Notifications
878     ProcessPropertyNotifications( bufferIndex );
879
880     //Update cameras
881     for( auto&& cameraIterator : mImpl->cameras )
882     {
883       cameraIterator->Update( bufferIndex );
884     }
885
886     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
887     //reset the update buffer index and make sure there is enough room in the instruction container
888     if( mImpl->renderersAdded )
889     {
890       mImpl->renderInstructions.ResetAndReserve( bufferIndex,
891                                                  mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
892
893       if ( NULL != mImpl->root )
894       {
895         mImpl->renderTaskProcessor.Process( bufferIndex,
896                                             mImpl->taskList,
897                                             *mImpl->root,
898                                             mImpl->sortedLayers,
899                                             mImpl->renderInstructions,
900                                             renderToFboEnabled,
901                                             isRenderingToFbo );
902
903         // Process the system-level RenderTasks last
904         if ( NULL != mImpl->systemLevelRoot )
905         {
906           mImpl->renderTaskProcessor.Process( bufferIndex,
907                                               mImpl->systemLevelTaskList,
908                                               *mImpl->systemLevelRoot,
909                                               mImpl->systemLevelSortedLayers,
910                                               mImpl->renderInstructions,
911                                               renderToFboEnabled,
912                                               isRenderingToFbo );
913         }
914       }
915     }
916   }
917
918   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
919   bool doRenderOnceNotify = false;
920   mImpl->renderTaskWaiting = false;
921   for ( auto&& renderTask : mImpl->taskList.GetTasks() )
922   {
923     renderTask->UpdateState();
924
925     if( renderTask->IsWaitingToRender() &&
926         renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
927     {
928       mImpl->renderTaskWaiting = true; // keep update/render threads alive
929     }
930
931     if( renderTask->HasRendered() )
932     {
933       doRenderOnceNotify = true;
934     }
935   }
936
937   if( doRenderOnceNotify )
938   {
939     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
940     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
941   }
942
943   // Macro is undefined in release build.
944   SNAPSHOT_NODE_LOGGING;
945
946   // A ResetProperties() may be required in the next frame
947   mImpl->previousUpdateScene = updateScene;
948
949   // Check whether further updates are required
950   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
951
952   // tell the update manager that we're done so the queue can be given to event thread
953   mImpl->notificationManager.UpdateCompleted();
954
955   // The update has finished; swap the double-buffering indices
956   mSceneGraphBuffers.Swap();
957
958   return keepUpdating;
959 }
960
961 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
962 {
963   // Update the duration set via Stage::KeepRendering()
964   if ( mImpl->keepRenderingSeconds > 0.0f )
965   {
966     mImpl->keepRenderingSeconds -= elapsedSeconds;
967   }
968
969   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
970
971   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
972   // Keep updating until no messages are received and no animations are running.
973   // If an animation has just finished, update at least once more for Discard end-actions.
974   // No need to check for renderQueue as there is always a render after update and if that
975   // render needs another update it will tell the adaptor to call update again
976
977   if ( mImpl->keepRenderingSeconds > 0.0f )
978   {
979     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
980   }
981
982   if ( IsAnimationRunning() ||
983        mImpl->animationFinishedDuringUpdate )
984   {
985     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
986   }
987
988   if ( mImpl->renderTaskWaiting )
989   {
990     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
991   }
992
993   return keepUpdatingRequest;
994 }
995
996 void UpdateManager::SetBackgroundColor( const Vector4& color )
997 {
998   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
999
1000   // Reserve some memory inside the render queue
1001   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1002
1003   // Construct message in the render queue memory; note that delete should not be called on the return value
1004   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1005 }
1006
1007 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1008 {
1009   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1010
1011   // Reserve some memory inside the render queue
1012   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1013
1014   // Construct message in the render queue memory; note that delete should not be called on the return value
1015   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1016 }
1017
1018 void UpdateManager::KeepRendering( float durationSeconds )
1019 {
1020   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1021 }
1022
1023 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1024 {
1025   if ( !systemLevel )
1026   {
1027     // just copy the vector of pointers
1028     mImpl->sortedLayers = layers;
1029   }
1030   else
1031   {
1032     mImpl->systemLevelSortedLayers = layers;
1033   }
1034 }
1035
1036 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1037 {
1038   // note,this vector is already in depth order. It could be used as-is to
1039   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1040   for( auto&& iter : nodeDepths->nodeDepths )
1041   {
1042     iter.node->SetDepthIndex( iter.sortedDepth );
1043   }
1044
1045   // Go through node hierarchy and rearrange siblings according to depth-index
1046   SortSiblingNodesRecursively( *( mImpl->root ) );
1047 }
1048
1049 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1050 {
1051   // Message has ownership of Sampler while in transit from update to render
1052   typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1053
1054   // Reserve some memory inside the render queue
1055   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1056
1057   // Construct message in the render queue memory; note that delete should not be called on the return value
1058   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1059 }
1060
1061 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1062 {
1063   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1064
1065   // Reserve some memory inside the render queue
1066   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1067
1068   // Construct message in the render queue memory; note that delete should not be called on the return value
1069   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1070 }
1071
1072 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1073 {
1074   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1075
1076   // Reserve some memory inside the render queue
1077   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1078
1079   // Construct message in the render queue memory; note that delete should not be called on the return value
1080   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1081 }
1082
1083 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1084 {
1085   typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1086
1087   // Reserve some memory inside the render queue
1088   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1089
1090   // Construct message in the render queue memory; note that delete should not be called on the return value
1091   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1092 }
1093
1094 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1095 {
1096   // Message has ownership of format while in transit from update -> render
1097   typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1098
1099   // Reserve some memory inside the render queue
1100   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1101
1102   // Construct message in the render queue memory; note that delete should not be called on the return value
1103   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddPropertyBuffer, propertyBuffer );
1104 }
1105
1106 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1107 {
1108   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1109
1110   // Reserve some memory inside the render queue
1111   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1112
1113   // Construct message in the render queue memory; note that delete should not be called on the return value
1114   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemovePropertyBuffer, propertyBuffer );
1115 }
1116
1117 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1118 {
1119   // Message has ownership of format while in transit from update -> render
1120   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1121
1122   // Reserve some memory inside the render queue
1123   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1124
1125   // Construct message in the render queue memory; note that delete should not be called on the return value
1126   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1127 }
1128
1129 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<char> >& data, size_t size )
1130 {
1131   // Message has ownership of format while in transit from update -> render
1132   typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > DerivedType;
1133
1134   // Reserve some memory inside the render queue
1135   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1136
1137   // Construct message in the render queue memory; note that delete should not be called on the return value
1138   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1139 }
1140
1141 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1142 {
1143   // Message has ownership of format while in transit from update -> render
1144   typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1145
1146   // Reserve some memory inside the render queue
1147   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1148
1149   // Construct message in the render queue memory; note that delete should not be called on the return value
1150   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1151 }
1152
1153 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1154 {
1155   typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1156
1157   // Reserve some memory inside the render queue
1158   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1159
1160   // Construct message in the render queue memory; note that delete should not be called on the return value
1161   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1162 }
1163
1164 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1165 {
1166   typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1167
1168   // Reserve some memory inside the render queue
1169   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1170
1171   // Construct message in the render queue memory; note that delete should not be called on the return value
1172   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1173 }
1174
1175 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1176 {
1177   typedef IndexBufferMessage< RenderManager > DerivedType;
1178
1179   // Reserve some memory inside the render queue
1180   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1181
1182   // Construct message in the render queue memory; note that delete should not be called on the return value
1183   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1184 }
1185
1186 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1187 {
1188   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1189
1190   // Reserve some memory inside the render queue
1191   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1192
1193   // Construct message in the render queue memory; note that delete should not be called on the return value
1194   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1195 }
1196
1197 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1198 {
1199   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1200
1201   // Reserve some memory inside the render queue
1202   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1203
1204   // Construct message in the render queue memory; note that delete should not be called on the return value
1205   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1206 }
1207
1208 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1209 {
1210   // Message has ownership of Texture while in transit from update -> render
1211   typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1212
1213   // Reserve some memory inside the render queue
1214   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1215
1216   // Construct message in the render queue memory; note that delete should not be called on the return value
1217   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1218 }
1219
1220 void UpdateManager::RemoveTexture( Render::Texture* texture)
1221 {
1222   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1223
1224   // Reserve some memory inside the render queue
1225   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1226
1227   // Construct message in the render queue memory; note that delete should not be called on the return value
1228   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1229 }
1230
1231 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1232 {
1233   typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1234
1235   // Reserve some memory inside the message queue
1236   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1237
1238   // Construct message in the message queue memory; note that delete should not be called on the return value
1239   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1240 }
1241
1242 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1243 {
1244   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1245
1246   // Reserve some memory inside the render queue
1247   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1248
1249   // Construct message in the render queue memory; note that delete should not be called on the return value
1250   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1251 }
1252
1253 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1254 {
1255   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1256
1257   // Reserve some memory inside the render queue
1258   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1259
1260   // Construct message in the render queue memory; note that delete should not be called on the return value
1261   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1262 }
1263
1264 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1265 {
1266   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1267
1268   // Reserve some memory inside the render queue
1269   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1270
1271   // Construct message in the render queue memory; note that delete should not be called on the return value
1272   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1273 }
1274
1275 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1276 {
1277   typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1278
1279   // Reserve some memory inside the render queue
1280   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1281
1282   // Construct message in the render queue memory; note that delete should not be called on the return value
1283   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1284 }
1285
1286 } // namespace SceneGraph
1287
1288 } // namespace Internal
1289
1290 } // namespace Dali