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