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