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