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