From 085fab6e87a77d6ba8b16951af65d0415b8e83c4 Mon Sep 17 00:00:00 2001 From: Kimmo Hoikka Date: Wed, 9 Sep 2015 13:10:28 +0100 Subject: [PATCH] Stability/Performance for update buffer index - use the same update buffer index rather than call getter function multiple times per update - swap index as the last thing of update Change-Id: I8507bfed16600d0b14eabf4fd052304cc0443364 --- dali/internal/update/manager/update-algorithms.cpp | 5 +- dali/internal/update/manager/update-manager.cpp | 66 +++++++++------------- dali/internal/update/manager/update-manager.h | 28 ++++----- .../internal/update/queue/update-message-queue.cpp | 4 +- dali/internal/update/queue/update-message-queue.h | 3 +- 5 files changed, 45 insertions(+), 61 deletions(-) diff --git a/dali/internal/update/manager/update-algorithms.cpp b/dali/internal/update/manager/update-algorithms.cpp index 2e296dc..b93bdfa 100644 --- a/dali/internal/update/manager/update-algorithms.cpp +++ b/dali/internal/update/manager/update-algorithms.cpp @@ -83,10 +83,7 @@ void ConstrainNodes( Node& node, BufferIndex updateBufferIndex ) if( node.HasAttachment() ) { - // @todo MESH_REWORK Remove dynamic cast. - // (Or, if RendererAttachment split into RendererPropertyOwner(?), - // do as separate pass as per other mesh objects - see also - // UpdateManager::ResetNodeProperty()) + // @todo Remove dynamic cast. NodeAttachment& attachment = node.GetAttachment(); PropertyOwner* propertyOwner = dynamic_cast< PropertyOwner* >( &attachment ); if( propertyOwner != NULL ) diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 516fa93..25d9ab3 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -694,40 +694,30 @@ bool UpdateManager::FlushQueue() return mImpl->messageQueue.FlushQueue(); } -void UpdateManager::ResetNodeProperty( Node& node ) -{ - BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - - node.ResetToBaseValues( bufferIndex ); -} - -void UpdateManager::ResetProperties() +void UpdateManager::ResetProperties( BufferIndex bufferIndex ) { PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES); - BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped mImpl->animationFinishedDuringUpdate = false; // Animated properties have to be reset to their original value each frame - // Reset node properties + // Reset root properties if ( mImpl->root ) { - ResetNodeProperty( *mImpl->root ); + mImpl->root->ResetToBaseValues( bufferIndex ); } - if ( mImpl->systemLevelRoot ) { - ResetNodeProperty( *mImpl->systemLevelRoot ); + mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex ); } // Reset the Connected Nodes const std::set::iterator endIter = mImpl->connectedNodes.end(); for( std::set::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter ) { - ResetNodeProperty( **iter ); + (*iter)->ResetToBaseValues( bufferIndex ); } // If a Node is disconnected, it may still be "active" (requires a reset in next frame) @@ -779,7 +769,7 @@ void UpdateManager::ResetProperties() PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES); } -bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) +bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) { bool gestureUpdated( false ); @@ -789,14 +779,14 @@ bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, uns for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter ) { PanGesture& gesture = **iter; - gesture.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message + gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); } return gestureUpdated; } -void UpdateManager::Animate( float elapsedSeconds ) +void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) { PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES); @@ -805,7 +795,7 @@ void UpdateManager::Animate( float elapsedSeconds ) while ( iter != animations.End() ) { Animation* animation = *iter; - bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds); + bool finished = animation->Update( bufferIndex, elapsedSeconds ); mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished; @@ -829,12 +819,10 @@ void UpdateManager::Animate( float elapsedSeconds ) PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES); } -void UpdateManager::ApplyConstraints() +void UpdateManager::ApplyConstraints( BufferIndex bufferIndex ) { PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS); - BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - // constrain custom objects... (in construction order) OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; @@ -901,13 +889,11 @@ void UpdateManager::ApplyConstraints() PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS); } -void UpdateManager::ProcessPropertyNotifications() +void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex ) { PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications; PropertyNotificationIter iter = notifications.Begin(); - BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - while ( iter != notifications.End() ) { PropertyNotification* notification = *iter; @@ -947,7 +933,7 @@ void UpdateManager::ForwardCompiledShadersToEventThread() } } -void UpdateManager::UpdateNodes() +void UpdateManager::UpdateNodes( BufferIndex bufferIndex ) { mImpl->nodeDirtyFlags = NothingFlag; @@ -961,14 +947,14 @@ void UpdateManager::UpdateNodes() // Prepare resources, update shaders, update attachments, for each node // And add the renderers to the sorted layers. Start from root, which is also a layer mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ), - mSceneGraphBuffers.GetUpdateBufferIndex(), + bufferIndex, mImpl->resourceManager, mImpl->renderQueue ); if ( mImpl->systemLevelRoot ) { mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ), - mSceneGraphBuffers.GetUpdateBufferIndex(), + bufferIndex, mImpl->resourceManager, mImpl->renderQueue ); } @@ -987,7 +973,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // Measure the time spent in UpdateManager::Update PERF_MONITOR_START(PerformanceMonitor::UPDATE); - BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); + const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); // Update the frame time delta on the render thread. mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds); @@ -1000,7 +986,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // 3) Process Touches & Gestures mImpl->touchResampler.Update(); - const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); + const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); const bool updateScene = // The scene-graph requires an update if.. (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR @@ -1014,11 +1000,11 @@ unsigned int UpdateManager::Update( float elapsedSeconds, if( updateScene || mImpl->previousUpdateScene ) { // 4) Reset properties from the previous update - ResetProperties(); + ResetProperties( bufferIndex ); } // 5) Process the queued scene messages - mImpl->messageQueue.ProcessMessages(); + mImpl->messageQueue.ProcessMessages( bufferIndex ); // 6) Post Process Ids of resources updated by renderer mImpl->resourceManager.PostProcessResources( bufferIndex ); @@ -1032,13 +1018,13 @@ unsigned int UpdateManager::Update( float elapsedSeconds, if( updateScene || mImpl->previousUpdateScene ) { // 7) Animate - Animate( elapsedSeconds ); + Animate( bufferIndex, elapsedSeconds ); // 8) Apply Constraints - ApplyConstraints(); + ApplyConstraints( bufferIndex ); // 9) Check Property Notifications - ProcessPropertyNotifications(); + ProcessPropertyNotifications( bufferIndex ); // 10) Clear the lists of renderable-attachments from the previous update ClearRenderables( mImpl->sortedLayers ); @@ -1046,7 +1032,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // 11) Update node hierarchy and perform sorting / culling. // This will populate each Layer with a list of renderers which are ready. - UpdateNodes(); + UpdateNodes( bufferIndex ); // 12) Prepare for the next render PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES); @@ -1059,7 +1045,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // 14) Process the RenderTasks; this creates the instructions for rendering the next frame. // reset the update buffer index and make sure there is enough room in the instruction container - mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(), + mImpl->renderInstructions.ResetAndReserve( bufferIndex, mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() ); if ( NULL != mImpl->root ) @@ -1131,12 +1117,12 @@ unsigned int UpdateManager::Update( float elapsedSeconds, keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE; #endif - // The update has finished; swap the double-buffering indices - mSceneGraphBuffers.Swap(); - // tell the update manager that we're done so the queue can be given to event thread mImpl->notificationManager.UpdateCompleted(); + // The update has finished; swap the double-buffering indices + mSceneGraphBuffers.Swap(); + PERF_MONITOR_END(PerformanceMonitor::UPDATE); return keepUpdating; diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 7fd446f..4cea5df 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -438,41 +438,40 @@ private: void PostProcessResources(); /** - * Helper to reset a Node properties. - * @param[in] node The node. - */ - void ResetNodeProperty( Node& node ); - - /** * Helper to reset all Node properties + * @param[in] bufferIndex to use */ - void ResetProperties(); + void ResetProperties( BufferIndex bufferIndex ); /** * Perform gesture updates. - * @param[in] lastVSyncTime The last VSync time in milliseconds. - * @param[in] nextVSyncTime The estimated time of the next VSync in milliseconds. + * @param[in] bufferIndex to use + * @param[in] lastVSyncTime The last VSync time in milliseconds. + * @param[in] nextVSyncTime The estimated time of the next VSync in milliseconds. * @return true, if any properties were updated. */ - bool ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ); + bool ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ); /** * Perform animation updates + * @param[in] bufferIndex to use * @param[in] elapsedSeconds time since last frame */ - void Animate( float elapsedSeconds ); + void Animate( BufferIndex bufferIndex, float elapsedSeconds ); /** * Perform constraint updates. * @note Applies constraints to nodes first (depth first search order). * Then shader constraints second (construction order) + * @param[in] bufferIndex to use */ - void ApplyConstraints(); + void ApplyConstraints( BufferIndex bufferIndex ); /** * Perform property notification updates + * @param[in] bufferIndex to use */ - void ProcessPropertyNotifications(); + void ProcessPropertyNotifications( BufferIndex bufferIndex ); /** * Pass shader binaries queued here on to event thread. @@ -488,8 +487,9 @@ private: /** * Update node shaders, opacity, geometry etc. + * @param[in] bufferIndex to use */ - void UpdateNodes(); + void UpdateNodes( BufferIndex bufferIndex ); private: diff --git a/dali/internal/update/queue/update-message-queue.cpp b/dali/internal/update/queue/update-message-queue.cpp index ada76a6..bf529a6 100644 --- a/dali/internal/update/queue/update-message-queue.cpp +++ b/dali/internal/update/queue/update-message-queue.cpp @@ -237,7 +237,7 @@ bool MessageQueue::FlushQueue() return messagesToProcess; } -void MessageQueue::ProcessMessages() +void MessageQueue::ProcessMessages( BufferIndex updateBufferIndex ) { PERF_MONITOR_START(PerformanceMonitor::PROCESS_MESSAGES); @@ -253,7 +253,7 @@ void MessageQueue::ProcessMessages() { MessageBase* message = reinterpret_cast< MessageBase* >( iter.Get() ); - message->Process( mImpl->sceneGraphBuffers.GetUpdateBufferIndex() ); + message->Process( updateBufferIndex ); // Call virtual destructor explictly; since delete will not be called after placement new message->~MessageBase(); diff --git a/dali/internal/update/queue/update-message-queue.h b/dali/internal/update/queue/update-message-queue.h index 954ae32..c873967 100644 --- a/dali/internal/update/queue/update-message-queue.h +++ b/dali/internal/update/queue/update-message-queue.h @@ -86,8 +86,9 @@ public: /** * Called once per update; process the previously flushed messages. + * @param updateBufferIndex to use */ - void ProcessMessages(); + void ProcessMessages( BufferIndex updateBufferIndex ); /** * Query whether the queue was empty this frame. -- 2.7.4