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