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