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