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