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