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