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