Stop heap allocating messages from UpdateManager for Animation and RenderTask complet... 42/27942/6
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Mon, 22 Sep 2014 16:26:47 +0000 (17:26 +0100)
committerKimmo Hoikka <kimmo.hoikka@samsung.com>
Thu, 25 Sep 2014 14:52:01 +0000 (15:52 +0100)
Remove the dependency between update manager and event side rendertasklist, generalize notification mechanism

[Problem] cyclic dependencies, heap allocations potentially on a frame by frame basis
[Cause] update manager needed to call API in event side to get the message to sent
[Solution] pass the interface pointer to notification manager

Change-Id: If29f3fd9fe5c972cbf19fcb34a3adf800374b33a

14 files changed:
dali/internal/common/core-impl.cpp
dali/internal/common/owner-container.h
dali/internal/event/animation/animation-finished-notifier.h [deleted file]
dali/internal/event/animation/animation-playlist.cpp
dali/internal/event/animation/animation-playlist.h
dali/internal/event/common/complete-notification-interface.h [new file with mode: 0644]
dali/internal/event/common/notification-manager.cpp
dali/internal/event/common/notification-manager.h
dali/internal/event/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/render-tasks/scene-graph-render-task-list.cpp
dali/internal/update/render-tasks/scene-graph-render-task-list.h

index a3f16c7..3dfc85a 100644 (file)
@@ -143,8 +143,6 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mStage->Initialize();
 
-  mUpdateManager->SetRenderTaskList( &mStage->GetRenderTaskList() );
-
   mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
   mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
 
index 42f410a..9131616 100644 (file)
@@ -136,24 +136,29 @@ public:
    */
   void MoveFrom( OwnerContainer& source )
   {
-    // Optimisation for the case that this is empty
-    if( IsEmpty() )
+    typename Vector< T >::SizeType sourceCount = source.Count();
+    // if source is empty, nothing to move
+    if( sourceCount > 0u )
     {
-      VectorBase::Swap( source );
-    }
-    else
-    {
-      // make space for new items
-      Vector< T >::Reserve( VectorBase::Count() + source.Count() );
-      Iterator iter = source.Begin();
-      ConstIterator end = source.End();
-      for( ; iter != end; ++iter )
+      // Optimisation for the case that this is empty
+      if( IsEmpty() )
+      {
+        VectorBase::Swap( source );
+      }
+      else
       {
-        T pointer = *iter;
-        Vector< T >::PushBack( pointer );
+        // make space for new items
+        Vector< T >::Reserve( VectorBase::Count() + sourceCount );
+        Iterator iter = source.Begin();
+        ConstIterator end = source.End();
+        for( ; iter != end; ++iter )
+        {
+          T pointer = *iter;
+          Vector< T >::PushBack( pointer );
+        }
+        // cannot call Clear on OwnerContainer as that deletes the elements
+        source.Vector< T >::Clear();
       }
-      // cannot call Clear on OwnerContainer as that deletes the elements
-      source.Vector< T >::Clear();
     }
   }
 
diff --git a/dali/internal/event/animation/animation-finished-notifier.h b/dali/internal/event/animation/animation-finished-notifier.h
deleted file mode 100644 (file)
index fa3f394..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-#define __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/internal/common/message.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-/**
- * Interface used by the update-thread to trigger animation "Finished" signals.
- */
-class AnimationFinishedNotifier
-{
-public:
-
-  /**
-   * Virtual destructor.
-   */
-  virtual ~AnimationFinishedNotifier()
-  {
-  }
-
-  /**
-   * Provide notification signals for any "Finished" animations.
-   * This method should be called in the event-thread; the update-thread must use AnimationFinishedMessage.
-   */
-  virtual void NotifyFinishedAnimations() = 0;
-};
-
-/**
- * Notification message for when 1+ animations have finished
- * @param[in] notifier This will provide the notification signals.
- */
-inline MessageBase* AnimationFinishedMessage( AnimationFinishedNotifier& notifier )
-{
-  return new Message< AnimationFinishedNotifier >( &notifier, &AnimationFinishedNotifier::NotifyFinishedAnimations );
-}
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-
index 6b5fa06..7e27e55 100644 (file)
@@ -67,7 +67,7 @@ void AnimationPlaylist::OnClear( Animation& animation )
   mPlaylist.erase( Dali::Animation(&animation) );
 }
 
-void AnimationPlaylist::NotifyFinishedAnimations()
+void AnimationPlaylist::NotifyCompleted()
 {
   std::vector< Dali::Animation > finishedAnimations;
 
index 41664da..ced67a7 100644 (file)
@@ -21,8 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/common/set-wrapper.h>
-#include <dali/internal/common/message.h>
-#include <dali/internal/event/animation/animation-finished-notifier.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
 
 namespace Dali
 {
@@ -36,7 +35,7 @@ class Animation;
  * AnimationPlaylist provides notifications to applications when animations are finished.
  * It reference-counts playing animations, to allow "fire and forget" behaviour.
  */
-class AnimationPlaylist : public AnimationFinishedNotifier
+class AnimationPlaylist : public CompleteNotificationInterface
 {
 public:
 
@@ -73,13 +72,6 @@ public:
    */
   void OnClear( Animation& animation );
 
-  /**
-   * From AnimationFinishedNotifier; emit "Finished" signal on any animations that have finished.
-   * This method should be called in the event-thread; the update-thread must use AnimationFinishedMessage.
-   * @post The "Finished" animations will no longer be referenced by AnimationPlaylist.
-   */
-  void NotifyFinishedAnimations();
-
 private:
 
   /**
@@ -93,11 +85,18 @@ private:
   // Undefined
   AnimationPlaylist& operator=(const AnimationPlaylist& rhs);
 
+private: // from CompleteNotificationInterface
+
+  /**
+   * @copydoc CompleteNotificationInterface::NotifyCompleted()
+   */
+  virtual void NotifyCompleted();
+
 private:
 
   std::set< Animation* > mAnimations; ///< All existing animations (not referenced)
-
   std::set< Dali::Animation > mPlaylist; ///< The currently playing animations (reference counted)
+
 };
 
 } // namespace Internal
diff --git a/dali/internal/event/common/complete-notification-interface.h b/dali/internal/event/common/complete-notification-interface.h
new file mode 100644 (file)
index 0000000..af43f25
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+#define __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * Provides notifications to the event-thread regarding the changes in previous update(s).
+ * For example after an animation finished, or after resources were loaded.
+ */
+class CompleteNotificationInterface
+{
+protected:
+
+  /**
+   * Constructor, not to be directly instantiated.
+   */
+  CompleteNotificationInterface()
+  {}
+
+  /**
+   * Virtual destructor as this is an interface, no deletion through this interface though.
+   */
+  virtual ~CompleteNotificationInterface()
+  {}
+
+public:
+
+  /**
+   * This method is called by Notification Manager
+   */
+  virtual void NotifyCompleted() = 0;
+
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+
index bbddf2d..0c0d30c 100644 (file)
@@ -17,8 +17,6 @@
 
 // CLASS HEADER
 #include <dali/internal/event/common/notification-manager.h>
-#include <dali/internal/common/owner-container.h>
-#include <dali/internal/common/message.h>
 
 // EXTERNAL INCLUDES
 #ifdef __clang__
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
+#include <dali/internal/common/owner-container.h>
+#include <dali/internal/common/message.h>
 #include <dali/internal/event/common/property-notification-impl.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
 
 namespace Dali
 {
@@ -44,33 +45,74 @@ namespace Dali
 namespace Internal
 {
 
+namespace
+{
+typedef Dali::Vector< CompleteNotificationInterface* > InterfaceContainer;
+
+/**
+ * helper to move elements from one container to another
+ * @param from where to move
+ * @param to move target
+ */
+void MoveElements( InterfaceContainer& from, InterfaceContainer& to )
+{
+  // check if there's something in from
+  const InterfaceContainer::SizeType fromCount = from.Count();
+  if( fromCount > 0u )
+  {
+    // check if to has some elements
+    const InterfaceContainer::SizeType toCount = to.Count();
+    if( toCount == 0u )
+    {
+      // to is empty so we can swap with from
+      to.Swap( from );
+    }
+    else
+    {
+      to.Reserve( toCount + fromCount );
+      for( InterfaceContainer::SizeType i = 0; i < fromCount; ++i )
+      {
+        to.PushBack( from[ i ] );
+      }
+      from.Clear();
+    }
+  }
+}
+}
+
 typedef boost::mutex MessageQueueMutex;
 typedef OwnerContainer< MessageBase* > MessageContainer;
 
 struct NotificationManager::Impl
 {
   Impl()
-  : notificationCount(0)
   {
     // reserve space on the vectors to avoid reallocs
-    // applications typically have upto 20-30 notifications at startup
-    updateCompletedQueue.Reserve( 32 );
-    updateWorkingQueue.Reserve( 32 );
-    eventQueue.Reserve( 32 );
+    // applications typically have up-to 20-30 notifications at startup
+    updateCompletedMessageQueue.Reserve( 32 );
+    updateWorkingMessageQueue.Reserve( 32 );
+    eventMessageQueue.Reserve( 32 );
+
+    // only a few manager objects get complete notifications (animation, render list, property notifications, ...)
+    updateCompletedInterfaceQueue.Reserve( 4 );
+    updateWorkingInterfaceQueue.Reserve( 4 );
+    eventInterfaceQueue.Reserve( 4 );
   }
 
   ~Impl()
   {
   }
 
-  // Used to skip duplicate operations during Notify()
-  unsigned int notificationCount;
-
   // queueMutex must be locked whilst accessing queue
   MessageQueueMutex queueMutex;
-  MessageContainer updateCompletedQueue;
-  MessageContainer updateWorkingQueue;
-  MessageContainer eventQueue;
+  // three queues for objects owned by notification manager
+  MessageContainer updateCompletedMessageQueue;
+  MessageContainer updateWorkingMessageQueue;
+  MessageContainer eventMessageQueue;
+  // three queues for objects referenced by notification manager
+  InterfaceContainer updateCompletedInterfaceQueue;
+  InterfaceContainer updateWorkingInterfaceQueue;
+  InterfaceContainer eventInterfaceQueue;
 };
 
 NotificationManager::NotificationManager()
@@ -83,6 +125,14 @@ NotificationManager::~NotificationManager()
   delete mImpl;
 }
 
+void NotificationManager::QueueCompleteNotification( CompleteNotificationInterface* instance )
+{
+  // queueMutex must be locked whilst accessing queues
+  MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+
+  mImpl->updateWorkingInterfaceQueue.PushBack( instance );
+}
+
 void NotificationManager::QueueMessage( MessageBase* message )
 {
   DALI_ASSERT_DEBUG( NULL != message );
@@ -90,7 +140,7 @@ void NotificationManager::QueueMessage( MessageBase* message )
   // queueMutex must be locked whilst accessing queues
   MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
 
-  mImpl->updateWorkingQueue.PushBack( message );
+  mImpl->updateWorkingMessageQueue.PushBack( message );
 }
 
 void NotificationManager::UpdateCompleted()
@@ -100,7 +150,9 @@ void NotificationManager::UpdateCompleted()
   // Move messages from update working queue to completed queue
   // note that in theory its possible for update completed to have last frames
   // events as well still hanging around. we need to keep them as well
-  mImpl->updateCompletedQueue.MoveFrom( mImpl->updateWorkingQueue );
+  mImpl->updateCompletedMessageQueue.MoveFrom( mImpl->updateWorkingMessageQueue );
+  // move pointers from interface queue
+  MoveElements( mImpl->updateWorkingInterfaceQueue, mImpl->updateCompletedInterfaceQueue );
   // finally the lock is released
 }
 
@@ -109,14 +161,12 @@ bool NotificationManager::MessagesToProcess()
   // queueMutex must be locked whilst accessing queues
   MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
 
-  return ( false == mImpl->updateCompletedQueue.IsEmpty() );
+  return ( 0u < mImpl->updateCompletedMessageQueue.Count() ||
+         ( 0u < mImpl->updateCompletedInterfaceQueue.Count() ) );
 }
 
 void NotificationManager::ProcessMessages()
 {
-  // Done before messages are processed, for notification count comparisons
-  ++mImpl->notificationCount;
-
   // queueMutex must be locked whilst accessing queues
   {
     MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
@@ -124,24 +174,32 @@ void NotificationManager::ProcessMessages()
     // Move messages from update completed queue to event queue
     // note that in theory its possible for event queue to have
     // last frames events as well still hanging around so need to keep them
-    mImpl->eventQueue.MoveFrom( mImpl->updateCompletedQueue );
+    mImpl->eventMessageQueue.MoveFrom( mImpl->updateCompletedMessageQueue );
+    MoveElements( mImpl->updateCompletedInterfaceQueue, mImpl->eventInterfaceQueue );
   }
   // end of scope, lock is released
 
-  MessageContainer::Iterator iter = mImpl->eventQueue.Begin();
-  MessageContainer::Iterator end = mImpl->eventQueue.End();
+  MessageContainer::Iterator iter = mImpl->eventMessageQueue.Begin();
+  const MessageContainer::Iterator end = mImpl->eventMessageQueue.End();
   for( ; iter != end; ++iter )
   {
     (*iter)->Process( 0u/*ignored*/ );
   }
-
   // release the processed messages from event side queue
-  mImpl->eventQueue.Clear();
-}
+  mImpl->eventMessageQueue.Clear();
 
-unsigned int NotificationManager::GetNotificationCount() const
-{
-  return mImpl->notificationCount;
+  InterfaceContainer::Iterator iter2 = mImpl->eventInterfaceQueue.Begin();
+  const InterfaceContainer::Iterator end2 = mImpl->eventInterfaceQueue.End();
+  for( ; iter2 != end2; ++iter2 )
+  {
+    CompleteNotificationInterface* interface = *iter2;
+    if( interface )
+    {
+      interface->NotifyCompleted();
+    }
+  }
+  // just clear the container, we dont own the objects
+  mImpl->eventInterfaceQueue.Clear();
 }
 
 } // namespace Internal
index 00be5d3..52775e2 100644 (file)
@@ -26,7 +26,7 @@ namespace Dali
 namespace Internal
 {
 
-class PropertyNotification;
+class CompleteNotificationInterface;
 class MessageBase;
 
 /**
@@ -50,6 +50,12 @@ public:
 /// Update side interface, can only be called from Update-thread
 
   /**
+   * Queue a scene message to an interface. This method is thread-safe.
+   * @param[in] instance to be notified about completion of the Update side event.
+   */
+  void QueueCompleteNotification( CompleteNotificationInterface* instance );
+
+  /**
    * Queue a scene message. This method is thread-safe.
    * @param[in] message A newly allocated message; NotificationManager takes ownership.
    */
@@ -73,36 +79,11 @@ public:
    */
   void ProcessMessages();
 
-  /**
-   * Retrieve the notification count; this is incremented when Notify() is called.
-   */
-  unsigned int GetNotificationCount() const;
-
 private:
 
   struct Impl;
   Impl* mImpl;
-};
-
-/**
- * A functor for querying the notification count.
- * This is useful for skipping duplicate operations during NotificationManager::Notify()
- */
-struct NotificationCountQuery
-{
-  NotificationCountQuery(const NotificationManager& manager)
-  : mNotificationManager(manager)
-  {
-  }
-
-  unsigned int operator()() const
-  {
-    return mNotificationManager.GetNotificationCount();
-  }
-
-private:
 
-  const NotificationManager& mNotificationManager;
 };
 
 } // namespace Internal
index a7e5038..ef10943 100644 (file)
@@ -113,7 +113,30 @@ Dali::RenderTask RenderTaskList::GetTask( unsigned int index ) const
   return mTasks[index];
 }
 
-void RenderTaskList::NotifyFinished()
+RenderTaskList::RenderTaskList( EventToUpdate& eventToUpdate, RenderTaskDefaults& defaults, bool systemLevel )
+: mEventToUpdate( eventToUpdate ),
+  mDefaults( defaults ),
+  mIsSystemLevel( systemLevel ),
+  mSceneObject( NULL )
+{
+}
+
+RenderTaskList::~RenderTaskList()
+{
+}
+
+void RenderTaskList::Initialize( UpdateManager& updateManager )
+{
+  // This should only be called once, with no existing scene-object
+  DALI_ASSERT_DEBUG( NULL == mSceneObject );
+
+  // Get raw-pointer to render task list
+  mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
+  // set the callback to call us back when tasks are completed
+  mSceneObject->SetCompleteNotificationInterface( this );
+}
+
+void RenderTaskList::NotifyCompleted()
 {
   DALI_LOG_TRACE_METHOD(gLogRenderList);
 
@@ -140,27 +163,6 @@ void RenderTaskList::NotifyFinished()
   }
 }
 
-RenderTaskList::RenderTaskList( EventToUpdate& eventToUpdate, RenderTaskDefaults& defaults, bool systemLevel )
-: mEventToUpdate( eventToUpdate ),
-  mDefaults( defaults ),
-  mIsSystemLevel( systemLevel ),
-  mSceneObject( NULL )
-{
-}
-
-RenderTaskList::~RenderTaskList()
-{
-}
-
-void RenderTaskList::Initialize( UpdateManager& updateManager )
-{
-  // This should only be called once, with no existing scene-object
-  DALI_ASSERT_DEBUG( NULL == mSceneObject );
-
-  // Get raw-pointer to render task list
-  mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
-}
-
 } // namespace Internal
 
 } // namespace Dali
index d3e94bf..4c2f73d 100644 (file)
@@ -23,7 +23,7 @@
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/render-tasks/render-task.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
-#include <dali/internal/common/message.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
 
 namespace Dali
 {
@@ -44,7 +44,7 @@ class UpdateManager;
  * A proxy for the scene-graph RenderTaskList.
  * A separate LayerList is maintained for actors added via the SystemLevel::Add().
  */
-class RenderTaskList : public BaseObject
+class RenderTaskList : public BaseObject, public CompleteNotificationInterface
 {
 public:
 
@@ -92,8 +92,9 @@ public:
    * Provide notification signals for a "Finished" render task.
    * This method should be called in the event-thread
    * Queue NotifyFinishedMessage() from update-thread
+   * @param object pointer to this class instance
    */
-  void NotifyFinished();
+  static void NotifyFinished( void* object );
 
 protected:
 
@@ -115,6 +116,13 @@ protected:
    */
   void Initialize( SceneGraph::UpdateManager& updateManager );
 
+private: // from CompleteNotificationInterface
+
+  /**
+   * @copydoc CompleteNotificationInterface::NotifyCompleted()
+   */
+  virtual void NotifyCompleted();
+
 private:
 
   EventToUpdate& mEventToUpdate;
@@ -127,15 +135,6 @@ private:
   RenderTaskContainer mTasks; ///< Reference counted render-tasks
 };
 
-/**
- * Notification message for when 1+ render tasks have finished
- * @param[in] renderTaskList This will provide the notification signals.
- */
-inline MessageBase* NotifyFinishedMessage( RenderTaskList& renderTaskList )
-{
-  return new Message< RenderTaskList >( &renderTaskList, &RenderTaskList::NotifyFinished );
-}
-
 } // namespace Internal
 
 // Helpers for public-api forwarding methods
index 4a37f8c..199d97c 100644 (file)
@@ -34,8 +34,6 @@
 #include <dali/internal/event/common/notification-manager.h>
 #include <dali/internal/event/common/property-notification-impl.h>
 #include <dali/internal/event/common/property-notifier.h>
-#include <dali/internal/event/animation/animation-finished-notifier.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
 
 #include <dali/internal/update/animation/scene-graph-animator.h>
 #include <dali/internal/update/animation/scene-graph-animation.h>
@@ -151,7 +149,7 @@ struct UpdateManager::Impl
 {
   Impl( NotificationManager& notificationManager,
         GlSyncAbstraction& glSyncAbstraction,
-        AnimationFinishedNotifier& animationFinishedNotifier,
+        CompleteNotificationInterface& animationFinishedNotifier,
         PropertyNotifier& propertyNotifier,
         ResourceManager& resourceManager,
         DiscardQueue& discardQueue,
@@ -190,7 +188,6 @@ struct UpdateManager::Impl
     previousUpdateScene( false ),
     frameCounter( 0 ),
     renderSortingHelper(),
-    renderTaskList( NULL ),
     renderTaskWaiting( false )
   {
     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager, defaultShader );
@@ -240,7 +237,7 @@ struct UpdateManager::Impl
   SceneGraphBuffers                   sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
   RenderMessageDispatcher             renderMessageDispatcher;       ///< Used for passing messages to the render-thread
   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
-  AnimationFinishedNotifier&          animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
+  CompleteNotificationInterface&      animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
   ResourceManager&                    resourceManager;               ///< resource manager
   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
@@ -293,14 +290,13 @@ struct UpdateManager::Impl
   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
   RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
 
-  Internal::RenderTaskList*           renderTaskList;                ///< Stores a pointer to the internal implementation to the render task list.
   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
 };
 
 UpdateManager::UpdateManager( NotificationManager& notificationManager,
                               GlSyncAbstraction& glSyncAbstraction,
-                              AnimationFinishedNotifier& animationFinishedNotifier,
+                              CompleteNotificationInterface& animationFinishedNotifier,
                               PropertyNotifier& propertyNotifier,
                               ResourceManager& resourceManager,
                               DiscardQueue& discardQueue,
@@ -332,11 +328,6 @@ UpdateManager::~UpdateManager()
   delete mImpl;
 }
 
-void UpdateManager::SetRenderTaskList( Internal::RenderTaskList* renderTaskList )
-{
-  mImpl->renderTaskList = renderTaskList;
-}
-
 EventToUpdate& UpdateManager::GetEventToUpdate()
 {
   return mImpl->messageQueue;
@@ -841,7 +832,7 @@ void UpdateManager::Animate( float elapsedSeconds )
   if ( mImpl->animationFinishedDuringUpdate )
   {
     // The application should be notified by NotificationManager, in another thread
-    mImpl->notificationManager.QueueMessage( AnimationFinishedMessage( mImpl->animationFinishedNotifier ) );
+    mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
   }
 
   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
@@ -1118,7 +1109,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
     }
   }
 
-  // check the countdown and notify
+  // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
   bool doRenderOnceNotify = false;
   mImpl->renderTaskWaiting = false;
   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
@@ -1144,7 +1135,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
   if( doRenderOnceNotify )
   {
     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
-    mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
+    mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
   }
 
   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
index 80e80eb..410396b 100644 (file)
@@ -50,13 +50,12 @@ struct DynamicsWorldSettings;
 namespace Internal
 {
 
-class AnimationFinishedNotifier;
 class PropertyNotifier;
 class EventToUpdate;
 struct DynamicsWorldSettings;
 class NotificationManager;
+class CompleteNotificationInterface;
 class ResourceManager;
-class RenderTaskList;
 class TouchResampler;
 
 // value types used by messages
@@ -92,7 +91,7 @@ public:
    * Construct a new UpdateManager.
    * @param[in] notificationManager This should be notified when animations have finished.
    * @param[in] glSyncAbstraction Used to determine when framebuffers are ready
-   * @param[in] animationFinishedNotifier The AnimationFinishedNotifier
+   * @param[in] animationFinishedNotifier The CompleteNotificationInterface that handles animation completions
    * @param[in] propertyNotifier The PropertyNotifier
    * @param[in] resourceManager The resource manager used to load textures etc.
    * @param[in] discardQueue Nodes are added here when disconnected from the scene-graph.
@@ -104,7 +103,7 @@ public:
    */
   UpdateManager( NotificationManager& notificationManager,
                  Integration::GlSyncAbstraction& glSyncAbstraction,
-                 AnimationFinishedNotifier& animationFinishedNotifier,
+                 CompleteNotificationInterface& animationFinishedNotifier,
                  PropertyNotifier& propertyNotifier,
                  ResourceManager& resourceManager,
                  DiscardQueue& discardQueue,
@@ -120,15 +119,6 @@ public:
   ~UpdateManager();
 
   /**
-   * Sets a pointer to the internal render task list.
-   *
-   * The render task list is used to notify which render tasks with refresh rate REFRESH_ONCE have finished.
-   *
-   * @param[in] renderTaskList A pointer to the internal render task list.
-   */
-  void SetRenderTaskList( Internal::RenderTaskList* renderTaskList );
-
-  /**
    * The event-thread uses this interface to queue messages for the next update.
    * @return The event-to-update interface.
    */
index 268346f..ba1a682 100644 (file)
@@ -74,6 +74,18 @@ const RenderTaskList::RenderTaskContainer& RenderTaskList::GetTasks() const
   return mRenderTasks;
 }
 
+void RenderTaskList::SetCompleteNotificationInterface( CompleteNotificationInterface* object )
+{
+
+  mNotificationObject = object;
+}
+
+CompleteNotificationInterface* RenderTaskList::GetCompleteNotificationInterface()
+{
+
+  return mNotificationObject;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 31f81ab..3df3281 100644 (file)
@@ -29,6 +29,7 @@ namespace Dali
 namespace Internal
 {
 class CompleteStatusManager;
+class CompleteNotificationInterface;
 
 namespace SceneGraph
 {
@@ -78,6 +79,17 @@ public:
    */
   const RenderTaskContainer& GetTasks() const;
 
+  /**
+   * Set the notification method to package in the NotifyFinishedMessage
+   * @param object to store in notification managers queue
+   */
+  void SetCompleteNotificationInterface( CompleteNotificationInterface* object );
+
+  /**
+   * Get the Notification interface for when 1+ render tasks have finished
+   */
+  CompleteNotificationInterface* GetCompleteNotificationInterface();
+
 private:
 
   // Undefined
@@ -87,8 +99,11 @@ private:
   RenderTaskList& operator=(const RenderTaskList&);
 
 private:
+
+  CompleteNotificationInterface* mNotificationObject; ///< object to pass in to the complete notification
   RenderTaskContainer mRenderTasks; ///< A container of owned RenderTasks
   CompleteStatusManager& mCompleteStatusManager; ///< The complete status tracker (render tasks need this)
+
 };
 
 // Messages for RenderTaskList