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