From: Kimmo Hoikka Date: Mon, 22 Sep 2014 16:26:47 +0000 (+0100) Subject: Stop heap allocating messages from UpdateManager for Animation and RenderTask complet... X-Git-Tag: dali_1.0.11~5^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ea44603e057c6ae3b62495117ad6a530285da53;p=platform%2Fcore%2Fuifw%2Fdali-core.git Stop heap allocating messages from UpdateManager for Animation and RenderTask completions. 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 --- diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index a3f16c7..3dfc85a 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -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); diff --git a/dali/internal/common/owner-container.h b/dali/internal/common/owner-container.h index 42f410a..9131616 100644 --- a/dali/internal/common/owner-container.h +++ b/dali/internal/common/owner-container.h @@ -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 index fa3f394..0000000 --- a/dali/internal/event/animation/animation-finished-notifier.h +++ /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 - -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 >( ¬ifier, &AnimationFinishedNotifier::NotifyFinishedAnimations ); -} - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__ - diff --git a/dali/internal/event/animation/animation-playlist.cpp b/dali/internal/event/animation/animation-playlist.cpp index 6b5fa06..7e27e55 100644 --- a/dali/internal/event/animation/animation-playlist.cpp +++ b/dali/internal/event/animation/animation-playlist.cpp @@ -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; diff --git a/dali/internal/event/animation/animation-playlist.h b/dali/internal/event/animation/animation-playlist.h index 41664da..ced67a7 100644 --- a/dali/internal/event/animation/animation-playlist.h +++ b/dali/internal/event/animation/animation-playlist.h @@ -21,8 +21,7 @@ // INTERNAL INCLUDES #include #include -#include -#include +#include 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 index 0000000..af43f25 --- /dev/null +++ b/dali/internal/event/common/complete-notification-interface.h @@ -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__ + diff --git a/dali/internal/event/common/notification-manager.cpp b/dali/internal/event/common/notification-manager.cpp index bbddf2d..0c0d30c 100644 --- a/dali/internal/event/common/notification-manager.cpp +++ b/dali/internal/event/common/notification-manager.cpp @@ -17,8 +17,6 @@ // CLASS HEADER #include -#include -#include // EXTERNAL INCLUDES #ifdef __clang__ @@ -36,7 +34,10 @@ // INTERNAL INCLUDES #include +#include +#include #include +#include 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 diff --git a/dali/internal/event/common/notification-manager.h b/dali/internal/event/common/notification-manager.h index 00be5d3..52775e2 100644 --- a/dali/internal/event/common/notification-manager.h +++ b/dali/internal/event/common/notification-manager.h @@ -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 diff --git a/dali/internal/event/render-tasks/render-task-list-impl.cpp b/dali/internal/event/render-tasks/render-task-list-impl.cpp index a7e5038..ef10943 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.cpp +++ b/dali/internal/event/render-tasks/render-task-list-impl.cpp @@ -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 diff --git a/dali/internal/event/render-tasks/render-task-list-impl.h b/dali/internal/event/render-tasks/render-task-list-impl.h index d3e94bf..4c2f73d 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.h +++ b/dali/internal/event/render-tasks/render-task-list-impl.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include 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 diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 4a37f8c..199d97c 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include @@ -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); diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 80e80eb..410396b 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -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. */ diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp index 268346f..ba1a682 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp @@ -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 diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.h b/dali/internal/update/render-tasks/scene-graph-render-task-list.h index 31f81ab..3df3281 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.h +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.h @@ -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