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