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