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