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