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