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