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