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