Merge branch 'devel/master (1.1.16)' into tizen
[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::ConstrainCustomObjects( BufferIndex bufferIndex )
782 {
783   //Constrain custom objects (in construction order)
784   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
785   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
786   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
787   {
788     PropertyOwner& object = **iter;
789     ConstrainPropertyOwner( object, bufferIndex );
790   }
791 }
792
793 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
794 {
795   // Constrain system-level render-tasks
796   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
797   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
798   {
799     RenderTask& task = **iter;
800     ConstrainPropertyOwner( task, bufferIndex );
801   }
802
803   // Constrain render-tasks
804   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
805   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
806   {
807     RenderTask& task = **iter;
808     ConstrainPropertyOwner( task, bufferIndex );
809   }
810 }
811
812 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
813 {
814   // constrain shaders... (in construction order)
815   ShaderContainer& shaders = mImpl->shaders;
816   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
817   {
818     Shader& shader = **iter;
819     ConstrainPropertyOwner( shader, bufferIndex );
820   }
821 }
822
823 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
824 {
825   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
826   PropertyNotificationIter iter = notifications.Begin();
827
828   while ( iter != notifications.End() )
829   {
830     PropertyNotification* notification = *iter;
831     bool valid = notification->Check( bufferIndex );
832     if(valid)
833     {
834       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
835     }
836     ++iter;
837   }
838 }
839
840 void UpdateManager::PrepareMaterials( BufferIndex bufferIndex )
841 {
842   ObjectOwnerContainer<Material>::Iterator iter = mImpl->materials.GetObjectContainer().Begin();
843   const ObjectOwnerContainer<Material>::Iterator end = mImpl->materials.GetObjectContainer().End();
844   for( ; iter != end; ++iter )
845   {
846     //Apply constraints
847     ConstrainPropertyOwner( *(*iter), bufferIndex );
848
849     //Prepare material
850     (*iter)->Prepare( mImpl->resourceManager );
851   }
852 }
853
854 void UpdateManager::ForwardCompiledShadersToEventThread()
855 {
856   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
857   if( mImpl->shaderSaver )
858   {
859     // lock and swap the queues
860     {
861       // render might be attempting to send us more binaries at the same time
862       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
863       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
864     }
865
866     if( mImpl->updateCompiledShaders.size() > 0 )
867     {
868       ShaderSaver& factory = *mImpl->shaderSaver;
869       ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
870       ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
871       for( ; i != end; ++i )
872       {
873         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
874       }
875       // we don't need them in update anymore
876       mImpl->updateCompiledShaders.clear();
877     }
878   }
879 }
880
881 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
882 {
883   const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
884   unsigned int rendererCount( rendererContainer.Size() );
885   for( unsigned int i(0); i<rendererCount; ++i )
886   {
887     //Apply constraints
888     ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
889
890     if( rendererContainer[i]->IsReferenced() )
891     {
892       rendererContainer[i]->PrepareRender( bufferIndex );
893     }
894   }
895 }
896
897 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
898 {
899   mImpl->nodeDirtyFlags = NothingFlag;
900
901   if ( !mImpl->root )
902   {
903     return;
904   }
905
906   // Prepare resources, update shaders, update attachments, for each node
907   // And add the renderers to the sorted layers. Start from root, which is also a layer
908   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
909                                                      bufferIndex,
910                                                      mImpl->resourceManager,
911                                                      mImpl->renderQueue );
912
913   if ( mImpl->systemLevelRoot )
914   {
915     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
916                                                         bufferIndex,
917                                                         mImpl->resourceManager,
918                                                         mImpl->renderQueue );
919   }
920 }
921
922 unsigned int UpdateManager::Update( float elapsedSeconds,
923                                     unsigned int lastVSyncTimeMilliseconds,
924                                     unsigned int nextVSyncTimeMilliseconds )
925 {
926   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
927
928   //Clear nodes/resources which were previously discarded
929   mImpl->discardQueue.Clear( bufferIndex );
930
931   //Grab any loaded resources
932   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
933
934   //Process Touches & Gestures
935   mImpl->touchResampler.Update();
936   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
937
938   const bool updateScene =                                  // The scene-graph requires an update if..
939       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
940       IsAnimationRunning()                            ||    // ..at least one animation is running OR
941       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
942       resourceChanged                                 ||    // ..one or more resources were updated/changed OR
943       gestureUpdated;                                       // ..a gesture property was updated
944
945
946   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
947   // values if the scene was updated in the previous frame.
948   if( updateScene || mImpl->previousUpdateScene )
949   {
950     //Reset properties from the previous update
951     ResetProperties( bufferIndex );
952   }
953
954   //Process the queued scene messages
955   mImpl->messageQueue.ProcessMessages( bufferIndex );
956
957   //Post Process Ids of resources updated by renderer
958   mImpl->resourceManager.PostProcessResources( bufferIndex );
959
960   //Forward compiled shader programs to event thread for saving
961   ForwardCompiledShadersToEventThread();
962
963   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
964   // renderer lists if the scene was updated in the previous frame.
965   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
966   if( updateScene || mImpl->previousUpdateScene )
967   {
968     //Animate
969     Animate( bufferIndex, elapsedSeconds );
970
971     //Constraint custom objects
972     ConstrainCustomObjects( bufferIndex );
973
974     //Prepare materials and apply constraints to them
975     PrepareMaterials( bufferIndex );
976
977     //Clear the lists of renderable-attachments from the previous update
978     for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
979     {
980       mImpl->sortedLayers[i]->ClearRenderables();
981     }
982
983     for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
984     {
985       mImpl->systemLevelSortedLayers[i]->ClearRenderables();
986     }
987
988     //Update node hierarchy, apply constraints and perform sorting / culling.
989     //This will populate each Layer with a list of renderers which are ready.
990     UpdateNodes( bufferIndex );
991
992     //Apply constraints to RenderTasks, shaders and geometries
993     ConstrainRenderTasks( bufferIndex );
994     ConstrainShaders( bufferIndex );
995     mImpl->geometries.ConstrainObjects( bufferIndex );
996
997     //Update renderers and apply constraints
998     UpdateRenderers( bufferIndex );
999
1000     //Process Property Notifications
1001     ProcessPropertyNotifications( bufferIndex );
1002
1003     //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->taskList,
1012                            *mImpl->root,
1013                            mImpl->sortedLayers,
1014                            mImpl->renderSortingHelper,
1015                            mImpl->renderInstructions );
1016
1017       // Process the system-level RenderTasks last
1018       if ( NULL != mImpl->systemLevelRoot )
1019       {
1020         ProcessRenderTasks(  bufferIndex,
1021                              mImpl->systemLevelTaskList,
1022                              *mImpl->systemLevelRoot,
1023                              mImpl->systemLevelSortedLayers,
1024                              mImpl->renderSortingHelper,
1025                              mImpl->renderInstructions );
1026       }
1027     }
1028   }
1029
1030   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1031   bool doRenderOnceNotify = false;
1032   mImpl->renderTaskWaiting = false;
1033   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1034   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1035         endIter != iter; ++iter )
1036   {
1037     RenderTask& renderTask(*(*iter));
1038
1039     renderTask.UpdateState();
1040
1041     if( renderTask.IsWaitingToRender() &&
1042         renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1043     {
1044       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1045     }
1046
1047     if( renderTask.HasRendered() )
1048     {
1049       doRenderOnceNotify = true;
1050     }
1051   }
1052
1053   if( doRenderOnceNotify )
1054   {
1055     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1056     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1057   }
1058
1059   // Macro is undefined in release build.
1060   SNAPSHOT_NODE_LOGGING;
1061
1062   // A ResetProperties() may be required in the next frame
1063   mImpl->previousUpdateScene = updateScene;
1064
1065   // Check whether further updates are required
1066   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1067
1068   // tell the update manager that we're done so the queue can be given to event thread
1069   mImpl->notificationManager.UpdateCompleted();
1070
1071   // The update has finished; swap the double-buffering indices
1072   mSceneGraphBuffers.Swap();
1073
1074   return keepUpdating;
1075 }
1076
1077 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1078 {
1079   // Update the duration set via Stage::KeepRendering()
1080   if ( mImpl->keepRenderingSeconds > 0.0f )
1081   {
1082     mImpl->keepRenderingSeconds -= elapsedSeconds;
1083   }
1084
1085   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1086
1087   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1088   // Keep updating until no messages are received and no animations are running.
1089   // If an animation has just finished, update at least once more for Discard end-actions.
1090   // No need to check for renderQueue as there is always a render after update and if that
1091   // render needs another update it will tell the adaptor to call update again
1092
1093   if ( mImpl->keepRenderingSeconds > 0.0f )
1094   {
1095     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1096   }
1097
1098   if ( IsAnimationRunning() ||
1099        mImpl->animationFinishedDuringUpdate )
1100   {
1101     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1102   }
1103
1104   if ( mImpl->renderTaskWaiting )
1105   {
1106     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1107   }
1108
1109   return keepUpdatingRequest;
1110 }
1111
1112 void UpdateManager::SetBackgroundColor( const Vector4& color )
1113 {
1114   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1115
1116   // Reserve some memory inside the render queue
1117   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1118
1119   // Construct message in the render queue memory; note that delete should not be called on the return value
1120   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1121 }
1122
1123 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1124 {
1125   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1126
1127   // Reserve some memory inside the render queue
1128   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1129
1130   // Construct message in the render queue memory; note that delete should not be called on the return value
1131   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1132 }
1133
1134 void UpdateManager::KeepRendering( float durationSeconds )
1135 {
1136   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1137 }
1138
1139 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1140 {
1141   if ( !systemLevel )
1142   {
1143     // just copy the vector of pointers
1144     mImpl->sortedLayers = layers;
1145   }
1146   else
1147   {
1148     mImpl->systemLevelSortedLayers = layers;
1149   }
1150 }
1151
1152 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1153 {
1154   mImpl->shaderSaver = &upstream;
1155 }
1156
1157 void UpdateManager::AddSampler( Render::Sampler* sampler )
1158 {
1159   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1160
1161   // Reserve some memory inside the render queue
1162   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1163
1164   // Construct message in the render queue memory; note that delete should not be called on the return value
1165   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1166 }
1167
1168 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1169 {
1170   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1171
1172   // Reserve some memory inside the render queue
1173   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174
1175   // Construct message in the render queue memory; note that delete should not be called on the return value
1176   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1177 }
1178
1179 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1180 {
1181   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1182
1183   // Reserve some memory inside the render queue
1184   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1185
1186   // Construct message in the render queue memory; note that delete should not be called on the return value
1187   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1188 }
1189
1190 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode )
1191 {
1192   typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1193
1194   // Reserve some memory inside the render queue
1195   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1196
1197   // Construct message in the render queue memory; note that delete should not be called on the return value
1198   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, uWrapMode, vWrapMode );
1199 }
1200
1201 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1202 {
1203   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1204
1205   // Reserve some memory inside the render queue
1206   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1207
1208   // Construct message in the render queue memory; note that delete should not be called on the return value
1209   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddPropertyBuffer, propertyBuffer );
1210 }
1211
1212 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1213 {
1214   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1215
1216   // Reserve some memory inside the render queue
1217   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1218
1219   // Construct message in the render queue memory; note that delete should not be called on the return value
1220   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemovePropertyBuffer, propertyBuffer );
1221 }
1222
1223 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1224 {
1225   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1226
1227   // Reserve some memory inside the render queue
1228   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1229
1230   // Construct message in the render queue memory; note that delete should not be called on the return value
1231   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1232 }
1233
1234 void UpdateManager::SetPropertyBufferData(Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data)
1235 {
1236   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>* > DerivedType;
1237
1238   // Reserve some memory inside the render queue
1239   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1240
1241   // Construct message in the render queue memory; note that delete should not be called on the return value
1242   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferData, propertyBuffer, data );
1243 }
1244
1245 void UpdateManager::SetPropertyBufferSize(Render::PropertyBuffer* propertyBuffer, size_t size )
1246 {
1247   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, size_t > DerivedType;
1248
1249   // Reserve some memory inside the render queue
1250   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1251
1252   // Construct message in the render queue memory; note that delete should not be called on the return value
1253   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferSize, propertyBuffer, size );
1254 }
1255
1256 } // namespace SceneGraph
1257
1258 } // namespace Internal
1259
1260 } // namespace Dali