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