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