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