Merge "Add @DEPRECATED to all public symbols of ImageActor & ShaderEffect" into devel...
[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   bool animationLooped = false;
719   while ( iter != animations.End() )
720   {
721     Animation* animation = *iter;
722     bool finished = false;
723     bool looped = false;
724     animation->Update( bufferIndex, elapsedSeconds, looped, finished );
725
726     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
727     animationLooped = animationLooped || looped;
728
729     // Remove animations that had been destroyed but were still waiting for an update
730     if (animation->GetState() == Animation::Destroyed)
731     {
732       iter = animations.Erase(iter);
733     }
734     else
735     {
736       ++iter;
737     }
738   }
739
740   // queue the notification on finished or looped (to update loop count)
741   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
742   {
743     // The application should be notified by NotificationManager, in another thread
744     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
745   }
746 }
747
748 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
749 {
750   //Constrain custom objects (in construction order)
751   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
752   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
753   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
754   {
755     PropertyOwner& object = **iter;
756     ConstrainPropertyOwner( object, bufferIndex );
757   }
758 }
759
760 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
761 {
762   // Constrain system-level render-tasks
763   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
764   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
765   {
766     RenderTask& task = **iter;
767     ConstrainPropertyOwner( task, bufferIndex );
768   }
769
770   // Constrain render-tasks
771   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
772   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
773   {
774     RenderTask& task = **iter;
775     ConstrainPropertyOwner( task, bufferIndex );
776   }
777 }
778
779 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
780 {
781   // constrain shaders... (in construction order)
782   ShaderContainer& shaders = mImpl->shaders;
783   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
784   {
785     Shader& shader = **iter;
786     ConstrainPropertyOwner( shader, bufferIndex );
787   }
788 }
789
790 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
791 {
792   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
793   PropertyNotificationIter iter = notifications.Begin();
794
795   while ( iter != notifications.End() )
796   {
797     PropertyNotification* notification = *iter;
798     bool valid = notification->Check( bufferIndex );
799     if(valid)
800     {
801       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
802     }
803     ++iter;
804   }
805 }
806
807 void UpdateManager::PrepareMaterials( BufferIndex bufferIndex )
808 {
809   ObjectOwnerContainer<Material>::Iterator iter = mImpl->materials.GetObjectContainer().Begin();
810   const ObjectOwnerContainer<Material>::Iterator end = mImpl->materials.GetObjectContainer().End();
811   for( ; iter != end; ++iter )
812   {
813     //Apply constraints
814     ConstrainPropertyOwner( *(*iter), bufferIndex );
815
816     //Prepare material
817     (*iter)->Prepare( mImpl->resourceManager );
818   }
819 }
820
821 void UpdateManager::ForwardCompiledShadersToEventThread()
822 {
823   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
824   if( mImpl->shaderSaver )
825   {
826     // lock and swap the queues
827     {
828       // render might be attempting to send us more binaries at the same time
829       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
830       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
831     }
832
833     if( mImpl->updateCompiledShaders.size() > 0 )
834     {
835       ShaderSaver& factory = *mImpl->shaderSaver;
836       ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
837       ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
838       for( ; i != end; ++i )
839       {
840         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
841       }
842       // we don't need them in update anymore
843       mImpl->updateCompiledShaders.clear();
844     }
845   }
846 }
847
848 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
849 {
850   const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
851   unsigned int rendererCount( rendererContainer.Size() );
852   for( unsigned int i(0); i<rendererCount; ++i )
853   {
854     //Apply constraints
855     ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
856
857     if( rendererContainer[i]->IsReferenced() )
858     {
859       rendererContainer[i]->PrepareRender( bufferIndex );
860     }
861   }
862 }
863
864 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
865 {
866   mImpl->nodeDirtyFlags = NothingFlag;
867
868   if ( !mImpl->root )
869   {
870     return;
871   }
872
873   // Prepare resources, update shaders, update attachments, for each node
874   // And add the renderers to the sorted layers. Start from root, which is also a layer
875   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
876                                                      bufferIndex,
877                                                      mImpl->resourceManager,
878                                                      mImpl->renderQueue );
879
880   if ( mImpl->systemLevelRoot )
881   {
882     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
883                                                         bufferIndex,
884                                                         mImpl->resourceManager,
885                                                         mImpl->renderQueue );
886   }
887 }
888
889 unsigned int UpdateManager::Update( float elapsedSeconds,
890                                     unsigned int lastVSyncTimeMilliseconds,
891                                     unsigned int nextVSyncTimeMilliseconds )
892 {
893   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
894
895   //Clear nodes/resources which were previously discarded
896   mImpl->discardQueue.Clear( bufferIndex );
897
898   //Grab any loaded resources
899   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
900
901   //Process Touches & Gestures
902   mImpl->touchResampler.Update();
903   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
904
905   const bool updateScene =                                  // The scene-graph requires an update if..
906       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
907       IsAnimationRunning()                            ||    // ..at least one animation is running OR
908       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
909       resourceChanged                                 ||    // ..one or more resources were updated/changed OR
910       gestureUpdated;                                       // ..a gesture property was updated
911
912
913   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
914   // values if the scene was updated in the previous frame.
915   if( updateScene || mImpl->previousUpdateScene )
916   {
917     //Reset properties from the previous update
918     ResetProperties( bufferIndex );
919   }
920
921   //Process the queued scene messages
922   mImpl->messageQueue.ProcessMessages( bufferIndex );
923
924   //Post Process Ids of resources updated by renderer
925   mImpl->resourceManager.PostProcessResources( bufferIndex );
926
927   //Forward compiled shader programs to event thread for saving
928   ForwardCompiledShadersToEventThread();
929
930   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
931   // renderer lists if the scene was updated in the previous frame.
932   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
933   if( updateScene || mImpl->previousUpdateScene )
934   {
935     //Animate
936     Animate( bufferIndex, elapsedSeconds );
937
938     //Constraint custom objects
939     ConstrainCustomObjects( bufferIndex );
940
941     //Prepare materials and apply constraints to them
942     PrepareMaterials( bufferIndex );
943
944     //Clear the lists of renderable-attachments from the previous update
945     for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
946     {
947       mImpl->sortedLayers[i]->ClearRenderables();
948     }
949
950     for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
951     {
952       mImpl->systemLevelSortedLayers[i]->ClearRenderables();
953     }
954
955     //Update node hierarchy, apply constraints and perform sorting / culling.
956     //This will populate each Layer with a list of renderers which are ready.
957     UpdateNodes( bufferIndex );
958
959     //Apply constraints to RenderTasks, shaders and geometries
960     ConstrainRenderTasks( bufferIndex );
961     ConstrainShaders( bufferIndex );
962     mImpl->geometries.ConstrainObjects( bufferIndex );
963
964     //Update renderers and apply constraints
965     UpdateRenderers( bufferIndex );
966
967     //Process Property Notifications
968     ProcessPropertyNotifications( bufferIndex );
969
970     //Process the RenderTasks; this creates the instructions for rendering the next frame.
971     //reset the update buffer index and make sure there is enough room in the instruction container
972     mImpl->renderInstructions.ResetAndReserve( bufferIndex,
973                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
974
975     if ( NULL != mImpl->root )
976     {
977       ProcessRenderTasks(  bufferIndex,
978                            mImpl->taskList,
979                            *mImpl->root,
980                            mImpl->sortedLayers,
981                            mImpl->renderSortingHelper,
982                            mImpl->renderInstructions );
983
984       // Process the system-level RenderTasks last
985       if ( NULL != mImpl->systemLevelRoot )
986       {
987         ProcessRenderTasks(  bufferIndex,
988                              mImpl->systemLevelTaskList,
989                              *mImpl->systemLevelRoot,
990                              mImpl->systemLevelSortedLayers,
991                              mImpl->renderSortingHelper,
992                              mImpl->renderInstructions );
993       }
994     }
995   }
996
997   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
998   bool doRenderOnceNotify = false;
999   mImpl->renderTaskWaiting = false;
1000   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1001   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1002         endIter != iter; ++iter )
1003   {
1004     RenderTask& renderTask(*(*iter));
1005
1006     renderTask.UpdateState();
1007
1008     if( renderTask.IsWaitingToRender() &&
1009         renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1010     {
1011       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1012     }
1013
1014     if( renderTask.HasRendered() )
1015     {
1016       doRenderOnceNotify = true;
1017     }
1018   }
1019
1020   if( doRenderOnceNotify )
1021   {
1022     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1023     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1024   }
1025
1026   // Macro is undefined in release build.
1027   SNAPSHOT_NODE_LOGGING;
1028
1029   // A ResetProperties() may be required in the next frame
1030   mImpl->previousUpdateScene = updateScene;
1031
1032   // Check whether further updates are required
1033   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1034
1035   // tell the update manager that we're done so the queue can be given to event thread
1036   mImpl->notificationManager.UpdateCompleted();
1037
1038   // The update has finished; swap the double-buffering indices
1039   mSceneGraphBuffers.Swap();
1040
1041   return keepUpdating;
1042 }
1043
1044 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1045 {
1046   // Update the duration set via Stage::KeepRendering()
1047   if ( mImpl->keepRenderingSeconds > 0.0f )
1048   {
1049     mImpl->keepRenderingSeconds -= elapsedSeconds;
1050   }
1051
1052   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1053
1054   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1055   // Keep updating until no messages are received and no animations are running.
1056   // If an animation has just finished, update at least once more for Discard end-actions.
1057   // No need to check for renderQueue as there is always a render after update and if that
1058   // render needs another update it will tell the adaptor to call update again
1059
1060   if ( mImpl->keepRenderingSeconds > 0.0f )
1061   {
1062     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1063   }
1064
1065   if ( IsAnimationRunning() ||
1066        mImpl->animationFinishedDuringUpdate )
1067   {
1068     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1069   }
1070
1071   if ( mImpl->renderTaskWaiting )
1072   {
1073     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1074   }
1075
1076   return keepUpdatingRequest;
1077 }
1078
1079 void UpdateManager::SetBackgroundColor( const Vector4& color )
1080 {
1081   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1082
1083   // Reserve some memory inside the render queue
1084   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1085
1086   // Construct message in the render queue memory; note that delete should not be called on the return value
1087   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1088 }
1089
1090 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1091 {
1092   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1093
1094   // Reserve some memory inside the render queue
1095   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1096
1097   // Construct message in the render queue memory; note that delete should not be called on the return value
1098   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1099 }
1100
1101 void UpdateManager::KeepRendering( float durationSeconds )
1102 {
1103   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1104 }
1105
1106 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1107 {
1108   if ( !systemLevel )
1109   {
1110     // just copy the vector of pointers
1111     mImpl->sortedLayers = layers;
1112   }
1113   else
1114   {
1115     mImpl->systemLevelSortedLayers = layers;
1116   }
1117 }
1118
1119 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1120 {
1121   mImpl->shaderSaver = &upstream;
1122 }
1123
1124 void UpdateManager::AddSampler( Render::Sampler* sampler )
1125 {
1126   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1127
1128   // Reserve some memory inside the render queue
1129   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1130
1131   // Construct message in the render queue memory; note that delete should not be called on the return value
1132   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1133 }
1134
1135 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1136 {
1137   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1138
1139   // Reserve some memory inside the render queue
1140   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1141
1142   // Construct message in the render queue memory; note that delete should not be called on the return value
1143   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1144 }
1145
1146 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1147 {
1148   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1149
1150   // Reserve some memory inside the render queue
1151   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1152
1153   // Construct message in the render queue memory; note that delete should not be called on the return value
1154   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1155 }
1156
1157 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1158 {
1159   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1160
1161   // Reserve some memory inside the render queue
1162   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1163
1164   // Construct message in the render queue memory; note that delete should not be called on the return value
1165   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1166 }
1167
1168 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1169 {
1170   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1171
1172   // Reserve some memory inside the render queue
1173   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174
1175   // Construct message in the render queue memory; note that delete should not be called on the return value
1176   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddPropertyBuffer, propertyBuffer );
1177 }
1178
1179 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1180 {
1181   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1182
1183   // Reserve some memory inside the render queue
1184   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1185
1186   // Construct message in the render queue memory; note that delete should not be called on the return value
1187   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemovePropertyBuffer, propertyBuffer );
1188 }
1189
1190 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1191 {
1192   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1193
1194   // Reserve some memory inside the render queue
1195   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1196
1197   // Construct message in the render queue memory; note that delete should not be called on the return value
1198   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1199 }
1200
1201 void UpdateManager::SetPropertyBufferData(Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data)
1202 {
1203   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>* > DerivedType;
1204
1205   // Reserve some memory inside the render queue
1206   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1207
1208   // Construct message in the render queue memory; note that delete should not be called on the return value
1209   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferData, propertyBuffer, data );
1210 }
1211
1212 void UpdateManager::SetPropertyBufferSize(Render::PropertyBuffer* propertyBuffer, size_t size )
1213 {
1214   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, size_t > DerivedType;
1215
1216   // Reserve some memory inside the render queue
1217   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1218
1219   // Construct message in the render queue memory; note that delete should not be called on the return value
1220   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferSize, propertyBuffer, size );
1221 }
1222
1223 } // namespace SceneGraph
1224
1225 } // namespace Internal
1226
1227 } // namespace Dali