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