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