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