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