Add a mechanism to specify a callback on every frame
[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 int 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( TransformFlag ), // 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, *root );
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   int                                  nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
321   int                                  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
413 void UpdateManager::DisconnectNode( Node* node )
414 {
415   Node* parent = node->GetParent();
416   DALI_ASSERT_ALWAYS( NULL != parent );
417   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
418
419   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
420 }
421
422 void UpdateManager::DestroyNode( Node* node )
423 {
424   DALI_ASSERT_ALWAYS( NULL != node );
425   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
426
427   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
428   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
429   for(;iter!=endIter;++iter)
430   {
431     if((*iter) == node)
432     {
433       mImpl->nodes.Erase(iter);
434       break;
435     }
436   }
437
438   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
439
440   // Notify the Node about impending destruction
441   node->OnDestroy();
442 }
443
444 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
445 {
446   mImpl->cameras.PushBack( camera.Release() ); // takes ownership
447 }
448
449 void UpdateManager::RemoveCamera( const Camera* camera )
450 {
451   // Find the camera and destroy it
452   EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
453 }
454
455 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
456 {
457   mImpl->customObjects.PushBack( object.Release() );
458 }
459
460 void UpdateManager::RemoveObject( PropertyOwner* object )
461 {
462   mImpl->customObjects.EraseObject( object );
463 }
464
465 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
466 {
467   mImpl->animations.PushBack( animation.Release() );
468 }
469
470 void UpdateManager::StopAnimation( Animation* animation )
471 {
472   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
473
474   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
475
476   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
477 }
478
479 void UpdateManager::RemoveAnimation( Animation* animation )
480 {
481   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
482
483   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
484
485   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
486 }
487
488 bool UpdateManager::IsAnimationRunning() const
489 {
490   // Find any animation that isn't stopped or paused
491   for ( auto&& iter : mImpl->animations )
492   {
493     const Animation::State state = iter->GetState();
494
495     if (state != Animation::Stopped &&
496         state != Animation::Paused)
497     {
498       return true; // stop iteration as soon as first one is found
499     }
500   }
501
502   return false;
503 }
504
505 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
506 {
507   propertyResetter->Initialize();
508   mImpl->propertyResetters.PushBack( propertyResetter.Release() );
509 }
510
511 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
512 {
513   mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
514 }
515
516 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
517 {
518   mImpl->propertyNotifications.EraseObject( propertyNotification );
519 }
520
521 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
522 {
523   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
524   propertyNotification->SetNotifyMode( notifyMode );
525 }
526
527 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
528 {
529   mImpl->shaders.PushBack( shader.Release() );
530 }
531
532 void UpdateManager::RemoveShader( Shader* shader )
533 {
534   // Find the shader and destroy it
535   EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
536 }
537
538 void UpdateManager::SetShaderProgram( Shader* shader,
539                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
540 {
541   if( shaderData )
542   {
543
544     typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
545
546     // Reserve some memory inside the render queue
547     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
548
549     // Construct message in the render queue memory; note that delete should not be called on the return value
550     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
551   }
552 }
553
554 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
555 {
556   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
557   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
558   {
559     // lock as update might be sending previously compiled shaders to event thread
560     Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
561     mImpl->renderCompiledShaders.push_back( shaderData );
562   }
563 }
564
565 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
566 {
567   mImpl->shaderSaver = &upstream;
568 }
569
570 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
571 {
572   renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
573   mImpl->renderers.PushBack( renderer.Release() );
574   mImpl->renderersAdded = true;
575 }
576
577 void UpdateManager::RemoveRenderer( Renderer* renderer )
578 {
579   // Find the renderer and destroy it
580   EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
581   // Need to remove the render object as well
582   renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
583 }
584
585 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
586 {
587   DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
588
589   mImpl->panGestureProcessor = panGestureProcessor;
590 }
591
592 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
593 {
594   mImpl->textureSets.PushBack( textureSet.Release() );
595 }
596
597 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
598 {
599   mImpl->textureSets.EraseObject( textureSet );
600 }
601
602 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
603 {
604   if ( !systemLevel )
605   {
606     // copy the list, this is only likely to happen once in application life cycle
607     return &(mImpl->taskList);
608   }
609   else
610   {
611     // copy the list, this is only likely to happen once in application life cycle
612     return &(mImpl->systemLevelTaskList);
613   }
614 }
615
616 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
617 {
618   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
619 }
620
621 void UpdateManager::EventProcessingStarted()
622 {
623   mImpl->messageQueue.EventProcessingStarted();
624 }
625
626 bool UpdateManager::FlushQueue()
627 {
628   return mImpl->messageQueue.FlushQueue();
629 }
630
631 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
632 {
633   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
634   mImpl->animationFinishedDuringUpdate = false;
635
636   // Reset all animating / constrained properties
637   std::vector<PropertyResetterBase*>toDelete;
638   for( auto&& element : mImpl->propertyResetters )
639   {
640     element->ResetToBaseValue( bufferIndex );
641     if( element->IsFinished() )
642     {
643       toDelete.push_back( element );
644     }
645   }
646
647   // If a resetter is no longer required (the animator or constraint has been removed), delete it.
648   for( auto&& elementPtr : toDelete )
649   {
650     mImpl->propertyResetters.EraseObject( elementPtr );
651   }
652
653   // Clear node dirty flags
654   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
655   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
656   for( ;iter != endIter; ++iter )
657   {
658     (*iter)->ResetDirtyFlags( bufferIndex );
659   }
660 }
661
662 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
663 {
664   bool gestureUpdated( false );
665
666   if( mImpl->panGestureProcessor )
667   {
668     // gesture processor only supports default properties
669     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
670     gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
671   }
672
673   return gestureUpdated;
674 }
675
676 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
677 {
678   AnimationContainer &animations = mImpl->animations;
679   AnimationIter iter = animations.Begin();
680   bool animationLooped = false;
681
682   while ( iter != animations.End() )
683   {
684     Animation* animation = *iter;
685     bool finished = false;
686     bool looped = false;
687     bool progressMarkerReached = false;
688     animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
689
690     if ( progressMarkerReached )
691     {
692       mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
693     }
694
695     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
696     animationLooped = animationLooped || looped;
697
698     // Remove animations that had been destroyed but were still waiting for an update
699     if (animation->GetState() == Animation::Destroyed)
700     {
701       iter = animations.Erase(iter);
702     }
703     else
704     {
705       ++iter;
706     }
707   }
708
709   // queue the notification on finished or looped (to update loop count)
710   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
711   {
712     // The application should be notified by NotificationManager, in another thread
713     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
714   }
715 }
716
717 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
718 {
719   //Constrain custom objects (in construction order)
720   for ( auto&& object : mImpl->customObjects )
721   {
722     ConstrainPropertyOwner( *object, bufferIndex );
723   }
724 }
725
726 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
727 {
728   // Constrain system-level render-tasks
729   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
730   for ( auto&& task : systemLevelTasks )
731   {
732     ConstrainPropertyOwner( *task, bufferIndex );
733   }
734
735   // Constrain render-tasks
736   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
737   for ( auto&& task : tasks )
738   {
739     ConstrainPropertyOwner( *task, bufferIndex );
740   }
741 }
742
743 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
744 {
745   // constrain shaders... (in construction order)
746   for ( auto&& shader : mImpl->shaders )
747   {
748     ConstrainPropertyOwner( *shader, bufferIndex );
749   }
750 }
751
752 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
753 {
754   for( auto&& notification : mImpl->propertyNotifications )
755   {
756     bool valid = notification->Check( bufferIndex );
757     if(valid)
758     {
759       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
760     }
761   }
762 }
763
764 void UpdateManager::ForwardCompiledShadersToEventThread()
765 {
766   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
767   if( mImpl->shaderSaver )
768   {
769     // lock and swap the queues
770     {
771       // render might be attempting to send us more binaries at the same time
772       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
773       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
774     }
775
776     if( mImpl->updateCompiledShaders.size() > 0 )
777     {
778       ShaderSaver& factory = *mImpl->shaderSaver;
779       for( auto&& shader : mImpl->updateCompiledShaders )
780       {
781         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
782       }
783       // we don't need them in update anymore
784       mImpl->updateCompiledShaders.clear();
785     }
786   }
787 }
788
789 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
790 {
791   const unsigned int rendererCount = mImpl->renderers.Count();
792   for( unsigned int i = 0; i < rendererCount; ++i )
793   {
794     //Apply constraints
795     ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
796
797     mImpl->renderers[i]->PrepareRender( bufferIndex );
798   }
799 }
800
801 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
802 {
803   mImpl->nodeDirtyFlags = NothingFlag;
804
805   if ( !mImpl->root )
806   {
807     return;
808   }
809
810   // Prepare resources, update shaders, for each node
811   // And add the renderers to the sorted layers. Start from root, which is also a layer
812   mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
813                                           bufferIndex,
814                                           mImpl->renderQueue );
815
816   if ( mImpl->systemLevelRoot )
817   {
818     mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
819                                              bufferIndex,
820                                              mImpl->renderQueue );
821   }
822 }
823
824 unsigned int UpdateManager::Update( float elapsedSeconds,
825                                     unsigned int lastVSyncTimeMilliseconds,
826                                     unsigned int nextVSyncTimeMilliseconds,
827                                     bool renderToFboEnabled,
828                                     bool isRenderingToFbo )
829 {
830   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
831
832   //Clear nodes/resources which were previously discarded
833   mImpl->discardQueue.Clear( bufferIndex );
834
835   //Process Touches & Gestures
836   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
837
838   bool updateScene = // The scene-graph requires an update if..
839       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
840       IsAnimationRunning()                            ||    // ..at least one animation is running OR
841       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
842       gestureUpdated;                                       // ..a gesture property was updated
843
844
845   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
846   // values if the scene was updated in the previous frame.
847   if( updateScene || mImpl->previousUpdateScene )
848   {
849     //Reset properties from the previous update
850     ResetProperties( bufferIndex );
851     mImpl->transformManager.ResetToBaseValue();
852   }
853
854   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
855   // between calling IsSceneUpdateRequired() above and here, so updateScene should
856   // be set again
857   updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
858
859   //Forward compiled shader programs to event thread for saving
860   ForwardCompiledShadersToEventThread();
861
862   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
863   // renderer lists if the scene was updated in the previous frame.
864   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
865   if( updateScene || mImpl->previousUpdateScene )
866   {
867     //Animate
868     Animate( bufferIndex, elapsedSeconds );
869
870     //Constraint custom objects
871     ConstrainCustomObjects( bufferIndex );
872
873     //Clear the lists of renderers from the previous update
874     for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
875     {
876       mImpl->sortedLayers[i]->ClearRenderables();
877     }
878
879     for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
880     {
881       mImpl->systemLevelSortedLayers[i]->ClearRenderables();
882     }
883
884     //Update node hierarchy, apply constraints and perform sorting / culling.
885     //This will populate each Layer with a list of renderers which are ready.
886     UpdateNodes( bufferIndex );
887
888     //Apply constraints to RenderTasks, shaders
889     ConstrainRenderTasks( bufferIndex );
890     ConstrainShaders( bufferIndex );
891
892     //Update renderers and apply constraints
893     UpdateRenderers( bufferIndex );
894
895     //Update the transformations of all the nodes
896     mImpl->transformManager.Update();
897
898     // Call the frame-callback-processor if set
899     if( mImpl->frameCallbackProcessor )
900     {
901       mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
902     }
903
904     //Process Property Notifications
905     ProcessPropertyNotifications( bufferIndex );
906
907     //Update cameras
908     for( auto&& cameraIterator : mImpl->cameras )
909     {
910       cameraIterator->Update( bufferIndex );
911     }
912
913     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
914     //reset the update buffer index and make sure there is enough room in the instruction container
915     if( mImpl->renderersAdded )
916     {
917       mImpl->renderInstructions.ResetAndReserve( bufferIndex,
918                                                  mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
919
920       if ( NULL != mImpl->root )
921       {
922         mImpl->renderTaskProcessor.Process( bufferIndex,
923                                             mImpl->taskList,
924                                             *mImpl->root,
925                                             mImpl->sortedLayers,
926                                             mImpl->renderInstructions,
927                                             renderToFboEnabled,
928                                             isRenderingToFbo );
929
930         // Process the system-level RenderTasks last
931         if ( NULL != mImpl->systemLevelRoot )
932         {
933           mImpl->renderTaskProcessor.Process( bufferIndex,
934                                               mImpl->systemLevelTaskList,
935                                               *mImpl->systemLevelRoot,
936                                               mImpl->systemLevelSortedLayers,
937                                               mImpl->renderInstructions,
938                                               renderToFboEnabled,
939                                               isRenderingToFbo );
940         }
941       }
942     }
943   }
944
945   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
946   bool doRenderOnceNotify = false;
947   mImpl->renderTaskWaiting = false;
948   for ( auto&& renderTask : mImpl->taskList.GetTasks() )
949   {
950     renderTask->UpdateState();
951
952     if( renderTask->IsWaitingToRender() &&
953         renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
954     {
955       mImpl->renderTaskWaiting = true; // keep update/render threads alive
956     }
957
958     if( renderTask->HasRendered() )
959     {
960       doRenderOnceNotify = true;
961     }
962   }
963
964   if( doRenderOnceNotify )
965   {
966     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
967     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
968   }
969
970   // Macro is undefined in release build.
971   SNAPSHOT_NODE_LOGGING;
972
973   // A ResetProperties() may be required in the next frame
974   mImpl->previousUpdateScene = updateScene;
975
976   // Check whether further updates are required
977   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
978
979   // tell the update manager that we're done so the queue can be given to event thread
980   mImpl->notificationManager.UpdateCompleted();
981
982   // The update has finished; swap the double-buffering indices
983   mSceneGraphBuffers.Swap();
984
985   return keepUpdating;
986 }
987
988 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
989 {
990   // Update the duration set via Stage::KeepRendering()
991   if ( mImpl->keepRenderingSeconds > 0.0f )
992   {
993     mImpl->keepRenderingSeconds -= elapsedSeconds;
994   }
995
996   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
997
998   // If the rendering behavior is set to continuously render, then continue to render.
999   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1000   // Keep updating until no messages are received and no animations are running.
1001   // If an animation has just finished, update at least once more for Discard end-actions.
1002   // No need to check for renderQueue as there is always a render after update and if that
1003   // render needs another update it will tell the adaptor to call update again
1004
1005   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1006        ( mImpl->keepRenderingSeconds > 0.0f ) )
1007   {
1008     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1009   }
1010
1011   if ( IsAnimationRunning() ||
1012        mImpl->animationFinishedDuringUpdate )
1013   {
1014     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1015   }
1016
1017   if ( mImpl->renderTaskWaiting )
1018   {
1019     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1020   }
1021
1022   return keepUpdatingRequest;
1023 }
1024
1025 void UpdateManager::SetBackgroundColor( const Vector4& color )
1026 {
1027   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1028
1029   // Reserve some memory inside the render queue
1030   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1031
1032   // Construct message in the render queue memory; note that delete should not be called on the return value
1033   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1034 }
1035
1036 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1037 {
1038   mImpl->surfaceRectChanged = true;
1039
1040   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1041
1042   // Reserve some memory inside the render queue
1043   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1044
1045   // Construct message in the render queue memory; note that delete should not be called on the return value
1046   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1047 }
1048
1049 void UpdateManager::KeepRendering( float durationSeconds )
1050 {
1051   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1052 }
1053
1054 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1055 {
1056   mImpl->renderingBehavior = renderingBehavior;
1057 }
1058
1059 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1060 {
1061   if ( !systemLevel )
1062   {
1063     // just copy the vector of pointers
1064     mImpl->sortedLayers = layers;
1065   }
1066   else
1067   {
1068     mImpl->systemLevelSortedLayers = layers;
1069   }
1070 }
1071
1072 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1073 {
1074   // note,this vector is already in depth order. It could be used as-is to
1075   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1076   for( auto&& iter : nodeDepths->nodeDepths )
1077   {
1078     iter.node->SetDepthIndex( iter.sortedDepth );
1079   }
1080
1081   // Go through node hierarchy and rearrange siblings according to depth-index
1082   SortSiblingNodesRecursively( *( mImpl->root ) );
1083 }
1084
1085 bool UpdateManager::IsDefaultSurfaceRectChanged()
1086 {
1087   bool surfaceRectChanged = mImpl->surfaceRectChanged;
1088
1089   // Reset the flag
1090   mImpl->surfaceRectChanged = false;
1091
1092   return surfaceRectChanged;
1093 }
1094
1095 void UpdateManager::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
1096 {
1097   mImpl->GetFrameCallbackProcessor().AddFrameCallback( frameCallback, rootNode );
1098 }
1099
1100 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1101 {
1102   mImpl->GetFrameCallbackProcessor().RemoveFrameCallback( frameCallback );
1103 }
1104
1105 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1106 {
1107   // Message has ownership of Sampler while in transit from update to render
1108   typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1109
1110   // Reserve some memory inside the render queue
1111   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1112
1113   // Construct message in the render queue memory; note that delete should not be called on the return value
1114   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1115 }
1116
1117 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1118 {
1119   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1120
1121   // Reserve some memory inside the render queue
1122   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1123
1124   // Construct message in the render queue memory; note that delete should not be called on the return value
1125   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1126 }
1127
1128 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1129 {
1130   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1131
1132   // Reserve some memory inside the render queue
1133   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1134
1135   // Construct message in the render queue memory; note that delete should not be called on the return value
1136   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1137 }
1138
1139 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1140 {
1141   typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1142
1143   // Reserve some memory inside the render queue
1144   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1145
1146   // Construct message in the render queue memory; note that delete should not be called on the return value
1147   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1148 }
1149
1150 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1151 {
1152   // Message has ownership of format while in transit from update -> render
1153   typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1154
1155   // Reserve some memory inside the render queue
1156   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1157
1158   // Construct message in the render queue memory; note that delete should not be called on the return value
1159   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddPropertyBuffer, propertyBuffer );
1160 }
1161
1162 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1163 {
1164   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1165
1166   // Reserve some memory inside the render queue
1167   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1168
1169   // Construct message in the render queue memory; note that delete should not be called on the return value
1170   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemovePropertyBuffer, propertyBuffer );
1171 }
1172
1173 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1174 {
1175   // Message has ownership of format while in transit from update -> render
1176   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1177
1178   // Reserve some memory inside the render queue
1179   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1180
1181   // Construct message in the render queue memory; note that delete should not be called on the return value
1182   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1183 }
1184
1185 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<char> >& data, size_t size )
1186 {
1187   // Message has ownership of format while in transit from update -> render
1188   typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > DerivedType;
1189
1190   // Reserve some memory inside the render queue
1191   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1192
1193   // Construct message in the render queue memory; note that delete should not be called on the return value
1194   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1195 }
1196
1197 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1198 {
1199   // Message has ownership of format while in transit from update -> render
1200   typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > 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::AddGeometry, geometry );
1207 }
1208
1209 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1210 {
1211   typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1212
1213   // Reserve some memory inside the render queue
1214   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1215
1216   // Construct message in the render queue memory; note that delete should not be called on the return value
1217   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1218 }
1219
1220 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1221 {
1222   typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > 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::SetGeometryType, geometry, geometryType );
1229 }
1230
1231 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1232 {
1233   typedef IndexBufferMessage< RenderManager > 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, geometry, indices );
1240 }
1241
1242 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1243 {
1244   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > 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::RemoveVertexBuffer, geometry, propertyBuffer );
1251 }
1252
1253 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1254 {
1255   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > 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::AttachVertexBuffer, geometry, propertyBuffer );
1262 }
1263
1264 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1265 {
1266   // Message has ownership of Texture while in transit from update -> render
1267   typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1268
1269   // Reserve some memory inside the render queue
1270   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1271
1272   // Construct message in the render queue memory; note that delete should not be called on the return value
1273   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1274 }
1275
1276 void UpdateManager::RemoveTexture( Render::Texture* texture)
1277 {
1278   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1279
1280   // Reserve some memory inside the render queue
1281   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1282
1283   // Construct message in the render queue memory; note that delete should not be called on the return value
1284   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1285 }
1286
1287 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1288 {
1289   typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1290
1291   // Reserve some memory inside the message queue
1292   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1293
1294   // Construct message in the message queue memory; note that delete should not be called on the return value
1295   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1296 }
1297
1298 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1299 {
1300   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1301
1302   // Reserve some memory inside the render queue
1303   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1304
1305   // Construct message in the render queue memory; note that delete should not be called on the return value
1306   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1307 }
1308
1309 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1310 {
1311   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1312
1313   // Reserve some memory inside the render queue
1314   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1315
1316   // Construct message in the render queue memory; note that delete should not be called on the return value
1317   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1318 }
1319
1320 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1321 {
1322   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1323
1324   // Reserve some memory inside the render queue
1325   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1326
1327   // Construct message in the render queue memory; note that delete should not be called on the return value
1328   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1329 }
1330
1331 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1332 {
1333   typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1334
1335   // Reserve some memory inside the render queue
1336   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1337
1338   // Construct message in the render queue memory; note that delete should not be called on the return value
1339   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1340 }
1341
1342 } // namespace SceneGraph
1343
1344 } // namespace Internal
1345
1346 } // namespace Dali