Remove Geometry scene object
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/update-manager.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
26
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
31
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
34
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
39
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/object-owner-container.h>
48 #include <dali/internal/update/manager/process-render-tasks.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/manager/transform-manager.h>
53 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
60 #include <dali/internal/update/resources/resource-manager.h>
61 #include <dali/internal/update/touch/touch-resampler.h>
62
63 #include <dali/internal/render/common/render-instruction-container.h>
64 #include <dali/internal/render/common/render-manager.h>
65 #include <dali/internal/render/queue/render-queue.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/shaders/scene-graph-shader.h>
68 #include <dali/internal/render/renderers/render-sampler.h>
69
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   : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
134     notificationManager( notificationManager ),
135     transformManager(),
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     textureSets( sceneGraphBuffers, discardQueue ),
154     messageQueue( renderController, sceneGraphBuffers ),
155     keepRenderingSeconds( 0.0f ),
156     animationFinishedDuringUpdate( false ),
157     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
158     previousUpdateScene( false ),
159     frameCounter( 0 ),
160     renderSortingHelper(),
161     renderTaskWaiting( false )
162   {
163     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache );
164
165     renderers.SetSceneController( *sceneController );
166     textureSets.SetSceneController( *sceneController );
167
168     // create first 'dummy' node
169     nodes.PushBack(0u);
170   }
171
172   ~Impl()
173   {
174     // Disconnect render tasks from nodes, before destroying the nodes
175     RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
176     for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
177     {
178       (*iter)->SetSourceNode( NULL );
179     }
180     // ..repeat for system level RenderTasks
181     RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
182     for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
183     {
184       (*iter)->SetSourceNode( NULL );
185     }
186
187     // UpdateManager owns the Nodes
188     Vector<Node*>::Iterator iter = nodes.Begin()+1;
189     Vector<Node*>::Iterator endIter = nodes.End();
190     for(;iter!=endIter;++iter)
191     {
192       (*iter)->OnDestroy();
193       delete(*iter);
194     }
195
196     // If there is root, reset it, otherwise do nothing as rendering was never started
197     if( root )
198     {
199       root->OnDestroy();
200
201       delete root;
202       root = NULL;
203     }
204
205     if( systemLevelRoot )
206     {
207       systemLevelRoot->OnDestroy();
208
209       delete systemLevelRoot;
210       systemLevelRoot = NULL;
211     }
212
213     sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
214     delete sceneController;
215   }
216
217   SceneGraphBuffers                   sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
218   RenderMessageDispatcher             renderMessageDispatcher;       ///< Used for passing messages to the render-thread
219   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
220   TransformManager                    transformManager;              ///< Used to update the transformation matrices of the nodes
221   CompleteNotificationInterface&      animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
222   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
223   ShaderSaver*                        shaderSaver;                   ///< Saves shader binaries.
224   ResourceManager&                    resourceManager;               ///< resource manager
225   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
226   RenderController&                   renderController;              ///< render controller
227   SceneControllerImpl*                sceneController;               ///< scene controller
228   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
229   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
230   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
231   TouchResampler&                     touchResampler;                ///< Used to resample touch events on every update.
232
233   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
234
235   RenderTaskList                      taskList;                      ///< The list of scene graph render-tasks
236   RenderTaskList                      systemLevelTaskList;           ///< Separate render-tasks for system-level content
237
238   Layer*                              root;                          ///< The root node (root is a layer)
239   Layer*                              systemLevelRoot;               ///< A separate root-node for system-level content
240
241   Vector<Node*>                       nodes;                         ///< A container of all instantiated nodes
242
243   SortedLayerPointers                 sortedLayers;                  ///< A container of Layer pointers sorted by depth
244   SortedLayerPointers                 systemLevelSortedLayers;       ///< A separate container of system-level Layers
245
246   OwnerContainer< PropertyOwner* >    customObjects;                 ///< A container of owned objects (with custom properties)
247
248   AnimationContainer                  animations;                    ///< A container of owned animations
249   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
250
251   ObjectOwnerContainer<Renderer>      renderers;
252   ObjectOwnerContainer<TextureSet>    textureSets;                     ///< A container of texture sets
253
254   ShaderContainer                     shaders;                       ///< A container of owned shaders
255
256   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
257   ShaderDataBinaryQueue               renderCompiledShaders;         ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
258   ShaderDataBinaryQueue               updateCompiledShaders;         ///< Shaders to be sent from Update to Event
259   Mutex                               compiledShaderMutex;           ///< lock to ensure no corruption on the renderCompiledShaders
260
261   float                               keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
262   bool                                animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
263
264   int                                 nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
265   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
266
267   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
268   RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
269
270   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
271   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
272 };
273
274 UpdateManager::UpdateManager( NotificationManager& notificationManager,
275                               CompleteNotificationInterface& animationFinishedNotifier,
276                               PropertyNotifier& propertyNotifier,
277                               ResourceManager& resourceManager,
278                               DiscardQueue& discardQueue,
279                               RenderController& controller,
280                               RenderManager& renderManager,
281                               RenderQueue& renderQueue,
282                               TextureCache& textureCache,
283                               TouchResampler& touchResampler )
284   : mImpl(NULL)
285 {
286   mImpl = new Impl( notificationManager,
287                     animationFinishedNotifier,
288                     propertyNotifier,
289                     resourceManager,
290                     discardQueue,
291                     controller,
292                     renderManager,
293                     renderQueue,
294                     textureCache,
295                     touchResampler,
296                     mSceneGraphBuffers );
297
298   textureCache.SetBufferIndices( &mSceneGraphBuffers );
299 }
300
301 UpdateManager::~UpdateManager()
302 {
303   delete mImpl;
304 }
305
306 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
307 {
308   DALI_ASSERT_DEBUG( layer->IsLayer() );
309   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
310
311   if ( !systemLevel )
312   {
313     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
314     mImpl->root = layer;
315     mImpl->root->CreateTransform( &mImpl->transformManager);
316   }
317   else
318   {
319     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
320     mImpl->systemLevelRoot = layer;
321     mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
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       node->CreateTransform( &mImpl->transformManager);
340       break;
341     }
342   }
343 }
344
345 void UpdateManager::ConnectNode( Node* parent, Node* node )
346 {
347   DALI_ASSERT_ALWAYS( NULL != parent );
348   DALI_ASSERT_ALWAYS( NULL != node );
349   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
350
351   parent->ConnectChild( node );
352 }
353
354 void UpdateManager::DisconnectNode( Node* node )
355 {
356   Node* parent = node->GetParent();
357   DALI_ASSERT_ALWAYS( NULL != parent );
358   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
359
360   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
361 }
362
363 void UpdateManager::DestroyNode( Node* node )
364 {
365   DALI_ASSERT_ALWAYS( NULL != node );
366   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
367
368   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
369   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
370   for(;iter!=endIter;++iter)
371   {
372     if((*iter) == node)
373     {
374       mImpl->nodes.Erase(iter);
375       break;
376     }
377   }
378
379   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
380
381   // Notify the Node about impending destruction
382   node->OnDestroy();
383 }
384
385 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
386 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
387 {
388   DALI_ASSERT_DEBUG( node != NULL );
389   DALI_ASSERT_DEBUG( attachment != NULL );
390
391   // attach node to attachment first so that parent is known by the time attachment is connected
392   node->Attach( *attachment ); // node takes ownership
393 }
394
395 void UpdateManager::AddObject( PropertyOwner* object )
396 {
397   DALI_ASSERT_DEBUG( NULL != object );
398
399   mImpl->customObjects.PushBack( object );
400 }
401
402 void UpdateManager::RemoveObject( PropertyOwner* object )
403 {
404   DALI_ASSERT_DEBUG( NULL != object );
405
406   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
407
408   // Find the object and destroy it
409   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
410   {
411     PropertyOwner* current = *iter;
412     if ( current == object )
413     {
414       customObjects.Erase( iter );
415       return;
416     }
417   }
418
419   // Should not reach here
420   DALI_ASSERT_DEBUG(false);
421 }
422
423 void UpdateManager::AddAnimation( Animation* animation )
424 {
425   mImpl->animations.PushBack( animation );
426 }
427
428 void UpdateManager::StopAnimation( Animation* animation )
429 {
430   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
431
432   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
433
434   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
435 }
436
437 void UpdateManager::RemoveAnimation( Animation* animation )
438 {
439   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
440
441   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
442
443   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
444 }
445
446 bool UpdateManager::IsAnimationRunning() const
447 {
448   bool isRunning(false);
449   AnimationContainer& animations = mImpl->animations;
450
451   // Find any animation that isn't stopped or paused
452
453   const AnimationIter endIter = animations.End();
454   for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
455   {
456     const Animation::State state = (*iter)->GetState();
457
458     if (state != Animation::Stopped &&
459         state != Animation::Paused)
460     {
461       isRunning = true;
462     }
463   }
464
465   return isRunning;
466 }
467
468 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
469 {
470   mImpl->propertyNotifications.PushBack( propertyNotification );
471 }
472
473 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
474 {
475   PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
476   PropertyNotificationIter iter = propertyNotifications.Begin();
477
478   while ( iter != propertyNotifications.End() )
479   {
480     if( *iter == propertyNotification )
481     {
482       propertyNotifications.Erase(iter);
483       break;
484     }
485     ++iter;
486   }
487 }
488
489 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
490 {
491   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
492   propertyNotification->SetNotifyMode( notifyMode );
493 }
494
495 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
496 {
497   return mImpl->renderers;
498 }
499
500
501 ObjectOwnerContainer<TextureSet>& UpdateManager::GetTexturesOwner()
502 {
503   return mImpl->textureSets;
504 }
505
506 void UpdateManager::AddShader( Shader* shader )
507 {
508   DALI_ASSERT_DEBUG( NULL != shader );
509
510   if( mImpl->shaders.Count() == 0 )
511   {
512     // the first added shader becomes our default shader
513     // Construct message in the render queue memory; note that delete should not be called on the return value
514     typedef MessageValue1< RenderManager, Shader* > DerivedType;
515
516     // Reserve some memory inside the render queue
517     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
518
519     // Construct message in the render queue memory; note that delete should not be called on the return value
520     new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
521   }
522
523   mImpl->shaders.PushBack( shader );
524 }
525
526 void UpdateManager::RemoveShader( Shader* shader )
527 {
528   DALI_ASSERT_DEBUG(shader != NULL);
529
530   ShaderContainer& shaders = mImpl->shaders;
531
532   // Find the shader and destroy it
533   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
534   {
535     Shader& current = **iter;
536     if ( &current == shader )
537     {
538       // Transfer ownership to the discard queue
539       // This keeps the shader alive, until the render-thread has finished with it
540       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
541
542       return;
543     }
544   }
545   // Should not reach here
546   DALI_ASSERT_DEBUG(false);
547 }
548
549 void UpdateManager::SetShaderProgram( Shader* shader,
550                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
551 {
552   if( shaderData )
553   {
554
555     typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
556
557     // Reserve some memory inside the render queue
558     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
559
560     // Construct message in the render queue memory; note that delete should not be called on the return value
561     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
562   }
563 }
564
565 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
566 {
567   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
568   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
569   {
570     // lock as update might be sending previously compiled shaders to event thread
571     Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
572     mImpl->renderCompiledShaders.push_back( shaderData );
573   }
574 }
575
576 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
577 {
578   if ( !systemLevel )
579   {
580     // copy the list, this is only likely to happen once in application life cycle
581     return &(mImpl->taskList);
582   }
583   else
584   {
585     // copy the list, this is only likely to happen once in application life cycle
586     return &(mImpl->systemLevelTaskList);
587   }
588 }
589
590 void UpdateManager::AddGesture( PanGesture* gesture )
591 {
592   DALI_ASSERT_DEBUG( NULL != gesture );
593
594   mImpl->gestures.PushBack( gesture );
595 }
596
597 void UpdateManager::RemoveGesture( PanGesture* gesture )
598 {
599   DALI_ASSERT_DEBUG( gesture != NULL );
600
601   GestureContainer& gestures = mImpl->gestures;
602
603   // Find the gesture and destroy it
604   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
605   {
606     PanGesture& current = **iter;
607     if ( &current == gesture )
608     {
609       mImpl->gestures.Erase( iter );
610       return;
611     }
612   }
613   // Should not reach here
614   DALI_ASSERT_DEBUG(false);
615 }
616
617 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
618 {
619   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
620 }
621
622 void UpdateManager::EventProcessingStarted()
623 {
624   mImpl->messageQueue.EventProcessingStarted();
625 }
626
627 bool UpdateManager::FlushQueue()
628 {
629   return mImpl->messageQueue.FlushQueue();
630 }
631
632 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
633 {
634   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
635   mImpl->animationFinishedDuringUpdate = false;
636
637   // Animated properties have to be reset to their original value each frame
638
639   // Reset root properties
640   if ( mImpl->root )
641   {
642     mImpl->root->ResetToBaseValues( bufferIndex );
643   }
644   if ( mImpl->systemLevelRoot )
645   {
646     mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
647   }
648
649   // Reset all the nodes
650   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
651   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
652   for(;iter != endIter; ++iter)
653   {
654     (*iter)->ResetToBaseValues( bufferIndex );
655   }
656
657   // Reset system-level render-task list properties to base values
658   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
659
660   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
661   {
662     (*iter)->ResetToBaseValues( bufferIndex );
663   }
664
665   // Reset render-task list properties to base values.
666   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
667
668   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
669   {
670     (*iter)->ResetToBaseValues( bufferIndex );
671   }
672
673   // Reset custom object properties to base values
674   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
675   {
676     (*iter)->ResetToBaseValues( bufferIndex );
677   }
678
679   mImpl->textureSets.ResetToBaseValues( bufferIndex );
680   mImpl->renderers.ResetToBaseValues( bufferIndex );
681
682   // Reset animatable shader properties to base values
683   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
684   {
685     (*iter)->ResetToBaseValues( bufferIndex );
686   }
687 }
688
689 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
690 {
691   bool gestureUpdated( false );
692
693   // constrain gestures... (in construction order)
694   GestureContainer& gestures = mImpl->gestures;
695
696   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
697   {
698     PanGesture& gesture = **iter;
699     gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
700     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
701   }
702
703   return gestureUpdated;
704 }
705
706 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
707 {
708   AnimationContainer &animations = mImpl->animations;
709   AnimationIter iter = animations.Begin();
710   bool animationLooped = false;
711   while ( iter != animations.End() )
712   {
713     Animation* animation = *iter;
714     bool finished = false;
715     bool looped = false;
716     animation->Update( bufferIndex, elapsedSeconds, looped, finished );
717
718     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
719     animationLooped = animationLooped || looped;
720
721     // Remove animations that had been destroyed but were still waiting for an update
722     if (animation->GetState() == Animation::Destroyed)
723     {
724       iter = animations.Erase(iter);
725     }
726     else
727     {
728       ++iter;
729     }
730   }
731
732   // queue the notification on finished or looped (to update loop count)
733   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
734   {
735     // The application should be notified by NotificationManager, in another thread
736     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
737   }
738 }
739
740 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
741 {
742   //Constrain custom objects (in construction order)
743   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
744   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
745   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
746   {
747     PropertyOwner& object = **iter;
748     ConstrainPropertyOwner( object, bufferIndex );
749   }
750 }
751
752 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
753 {
754   // Constrain system-level render-tasks
755   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
756   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
757   {
758     RenderTask& task = **iter;
759     ConstrainPropertyOwner( task, bufferIndex );
760   }
761
762   // Constrain render-tasks
763   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
764   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
765   {
766     RenderTask& task = **iter;
767     ConstrainPropertyOwner( task, bufferIndex );
768   }
769 }
770
771 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
772 {
773   // constrain shaders... (in construction order)
774   ShaderContainer& shaders = mImpl->shaders;
775   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
776   {
777     Shader& shader = **iter;
778     ConstrainPropertyOwner( shader, bufferIndex );
779   }
780 }
781
782 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
783 {
784   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
785   PropertyNotificationIter iter = notifications.Begin();
786
787   while ( iter != notifications.End() )
788   {
789     PropertyNotification* notification = *iter;
790     bool valid = notification->Check( bufferIndex );
791     if(valid)
792     {
793       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
794     }
795     ++iter;
796   }
797 }
798
799 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
800 {
801   ObjectOwnerContainer<TextureSet>::Iterator iter = mImpl->textureSets.GetObjectContainer().Begin();
802   const ObjectOwnerContainer<TextureSet>::Iterator end = mImpl->textureSets.GetObjectContainer().End();
803   for( ; iter != end; ++iter )
804   {
805     //Apply constraints
806     ConstrainPropertyOwner( *(*iter), bufferIndex );
807
808     //Prepare texture set
809     (*iter)->Prepare( mImpl->resourceManager );
810   }
811 }
812
813 void UpdateManager::ForwardCompiledShadersToEventThread()
814 {
815   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
816   if( mImpl->shaderSaver )
817   {
818     // lock and swap the queues
819     {
820       // render might be attempting to send us more binaries at the same time
821       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
822       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
823     }
824
825     if( mImpl->updateCompiledShaders.size() > 0 )
826     {
827       ShaderSaver& factory = *mImpl->shaderSaver;
828       ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
829       ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
830       for( ; i != end; ++i )
831       {
832         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
833       }
834       // we don't need them in update anymore
835       mImpl->updateCompiledShaders.clear();
836     }
837   }
838 }
839
840 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
841 {
842   const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
843   unsigned int rendererCount( rendererContainer.Size() );
844   for( unsigned int i(0); i<rendererCount; ++i )
845   {
846     //Apply constraints
847     ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
848
849     if( rendererContainer[i]->IsReferenced() )
850     {
851       rendererContainer[i]->PrepareRender( bufferIndex );
852     }
853   }
854 }
855
856 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
857 {
858   mImpl->nodeDirtyFlags = NothingFlag;
859
860   if ( !mImpl->root )
861   {
862     return;
863   }
864
865   // Prepare resources, update shaders, update attachments, for each node
866   // And add the renderers to the sorted layers. Start from root, which is also a layer
867   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
868                                                      bufferIndex,
869                                                      mImpl->resourceManager,
870                                                      mImpl->renderQueue );
871
872   if ( mImpl->systemLevelRoot )
873   {
874     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
875                                                         bufferIndex,
876                                                         mImpl->resourceManager,
877                                                         mImpl->renderQueue );
878   }
879 }
880
881 unsigned int UpdateManager::Update( float elapsedSeconds,
882                                     unsigned int lastVSyncTimeMilliseconds,
883                                     unsigned int nextVSyncTimeMilliseconds )
884 {
885   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
886
887   //Clear nodes/resources which were previously discarded
888   mImpl->discardQueue.Clear( bufferIndex );
889
890   //Grab any loaded resources
891   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
892
893   //Process Touches & Gestures
894   mImpl->touchResampler.Update();
895   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
896
897   const bool updateScene =                                  // The scene-graph requires an update if..
898       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
899       IsAnimationRunning()                            ||    // ..at least one animation is running OR
900       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
901       resourceChanged                                 ||    // ..one or more resources were updated/changed OR
902       gestureUpdated;                                       // ..a gesture property was updated
903
904
905   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
906   // values if the scene was updated in the previous frame.
907   if( updateScene || mImpl->previousUpdateScene )
908   {
909     //Reset properties from the previous update
910     ResetProperties( bufferIndex );
911     mImpl->transformManager.ResetToBaseValue();
912   }
913
914   //Process the queued scene messages
915   mImpl->messageQueue.ProcessMessages( bufferIndex );
916
917   //Post Process Ids of resources updated by renderer
918   mImpl->resourceManager.PostProcessResources( bufferIndex );
919
920   //Forward compiled shader programs to event thread for saving
921   ForwardCompiledShadersToEventThread();
922
923   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
924   // renderer lists if the scene was updated in the previous frame.
925   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
926   if( updateScene || mImpl->previousUpdateScene )
927   {
928     //Animate
929     Animate( bufferIndex, elapsedSeconds );
930
931     //Constraint custom objects
932     ConstrainCustomObjects( bufferIndex );
933
934     //Prepare texture sets and apply constraints to them
935     PrepareTextureSets( bufferIndex );
936
937     //Clear the lists of renderable-attachments from the previous update
938     for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
939     {
940       mImpl->sortedLayers[i]->ClearRenderables();
941     }
942
943     for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
944     {
945       mImpl->systemLevelSortedLayers[i]->ClearRenderables();
946     }
947
948     //Update node hierarchy, apply constraints and perform sorting / culling.
949     //This will populate each Layer with a list of renderers which are ready.
950     UpdateNodes( bufferIndex );
951
952     //Apply constraints to RenderTasks, shaders
953     ConstrainRenderTasks( bufferIndex );
954     ConstrainShaders( bufferIndex );
955
956     //Update renderers and apply constraints
957     UpdateRenderers( bufferIndex );
958
959     //Update the trnasformations of all the nodes
960     mImpl->transformManager.Update();
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, size_t size )
1197 {
1198   typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > 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, size );
1205 }
1206
1207 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1208 {
1209   typedef MessageValue1< RenderManager, Render::Geometry* > 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::AddGeometry, geometry );
1216 }
1217
1218 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1219 {
1220   typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1221
1222   // Reserve some memory inside the render queue
1223   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1224
1225   // Construct message in the render queue memory; note that delete should not be called on the return value
1226   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1227 }
1228
1229 void UpdateManager::SetGeometryRequiresDepthTest( Render::Geometry* geometry, bool requiresDepthTest )
1230 {
1231   typedef MessageValue2< RenderManager, Render::Geometry*, bool > DerivedType;
1232
1233   // Reserve some memory inside the render queue
1234   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1235
1236   // Construct message in the render queue memory; note that delete should not be called on the return value
1237   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryRequiresDepthTest, geometry, requiresDepthTest );
1238 }
1239
1240 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1241 {
1242   typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1243
1244   // Reserve some memory inside the render queue
1245   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1246
1247   // Construct message in the render queue memory; note that delete should not be called on the return value
1248   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1249 }
1250
1251 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1252 {
1253   typedef IndexBufferMessage< RenderManager > DerivedType;
1254
1255   // Reserve some memory inside the render queue
1256   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1257
1258   // Construct message in the render queue memory; note that delete should not be called on the return value
1259   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1260 }
1261
1262 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1263 {
1264   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1265
1266   // Reserve some memory inside the render queue
1267   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1268
1269   // Construct message in the render queue memory; note that delete should not be called on the return value
1270   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1271 }
1272
1273 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1274 {
1275   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1276
1277   // Reserve some memory inside the render queue
1278   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1279
1280   // Construct message in the render queue memory; note that delete should not be called on the return value
1281   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1282 }
1283
1284
1285 } // namespace SceneGraph
1286
1287 } // namespace Internal
1288
1289 } // namespace Dali