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