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