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