From 9aba55a21a0d7423b91a40ae9234144e3b823ec2 Mon Sep 17 00:00:00 2001 From: Frederic Chardon Date: Fri, 20 Nov 2020 13:11:53 +0100 Subject: [PATCH] Add the async physics worker to the profiler overlay. --- apps/openmw/engine.cpp | 10 +++++++++- apps/openmw/mwbase/world.hpp | 4 +++- apps/openmw/mwphysics/mtphysics.cpp | 17 ++++++++++++++++- apps/openmw/mwphysics/mtphysics.hpp | 10 +++++++++- apps/openmw/mwphysics/physicssystem.cpp | 5 +++-- apps/openmw/mwphysics/physicssystem.hpp | 3 ++- apps/openmw/mwworld/worldimp.cpp | 9 +++++---- apps/openmw/mwworld/worldimp.hpp | 4 ++-- 8 files changed, 49 insertions(+), 13 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 49a4b40590..0bfd67dd77 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -94,6 +94,7 @@ namespace Script, Mechanics, Physics, + PhysicsWorker, World, Gui, @@ -124,6 +125,9 @@ namespace template <> const UserStats UserStatsValue::sValue {"Phys", "physics"}; + template <> + const UserStats UserStatsValue::sValue {" -Async", "physicsworker"}; + template <> const UserStats UserStatsValue::sValue {"World", "world"}; @@ -203,6 +207,10 @@ namespace profiler.addUserStatsLine(v.mLabel, textColor, barColor, v.mTaken, multiplier, average, averageInInverseSpace, v.mBegin, v.mEnd, maxValue); }); + // the forEachUserStatsValue loop is "run" at compile time, hence the settings manager is not available. + // Unconditionnally add the async physics stats, and then remove it at runtime if necessary + if (Settings::Manager::getInt("async num threads", "Physics") == 0) + profiler.removeUserStatsLine(" -Async"); } } @@ -318,7 +326,7 @@ bool OMW::Engine::frame(float frametime) if (mEnvironment.getStateManager()->getState() != MWBase::StateManager::State_NoGame) { - mEnvironment.getWorld()->updatePhysics(frametime, guiActive); + mEnvironment.getWorld()->updatePhysics(frametime, guiActive, frameStart, frameNumber, *stats); } } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f9cbc89723..49bc76a761 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -10,6 +10,8 @@ #include +#include + #include "../mwworld/ptr.hpp" #include "../mwworld/doorstate.hpp" @@ -391,7 +393,7 @@ namespace MWBase /// \return pointer to created record virtual void update (float duration, bool paused) = 0; - virtual void updatePhysics (float duration, bool paused) = 0; + virtual void updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) = 0; virtual void updateWindowManager () = 0; diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index dbb714fac5..8c06e01403 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include "components/debug/debuglog.hpp" #include #include "components/misc/convert.hpp" @@ -154,6 +156,8 @@ namespace MWPhysics , mQuit(false) , mNextJob(0) , mNextLOS(0) + , mFrameNumber(0) + , mTimer(osg::Timer::instance()) { mNumThreads = Config::computeNumThreads(mThreadSafeBullet); @@ -192,6 +196,7 @@ namespace MWPhysics [](const LOSRequest& req) { return req.mStale; }), mLOSCache.end()); } + mTimeEnd = mTimer->tick(); }); } @@ -207,7 +212,7 @@ namespace MWPhysics thread.join(); } - const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector&& actorsData, bool skipSimulation) + const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector&& actorsData, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { // This function run in the main thread. // While the mSimulationMutex is held, background physics threads can't run. @@ -230,6 +235,16 @@ namespace MWPhysics if (mMovementResults.find(data.mPtr) != mMovementResults.end()) data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]); } + + if (mFrameNumber == frameNumber - 1) + { + stats.setAttribute(mFrameNumber, "physicsworker_time_begin", mTimer->delta_s(mFrameStart, mTimeBegin)); + stats.setAttribute(mFrameNumber, "physicsworker_time_taken", mTimer->delta_s(mTimeBegin, mTimeEnd)); + stats.setAttribute(mFrameNumber, "physicsworker_time_end", mTimer->delta_s(mFrameStart, mTimeEnd)); + } + mFrameStart = frameStart; + mTimeBegin = mTimer->tick(); + mFrameNumber = frameNumber; } // init diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp index ef1c90b873..c061fe01da 100644 --- a/apps/openmw/mwphysics/mtphysics.hpp +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -9,6 +9,8 @@ #include +#include + #include "physicssystem.hpp" #include "ptrholder.hpp" @@ -30,7 +32,7 @@ namespace MWPhysics /// @param timeAccum accumulated time from previous run to interpolate movements /// @param actorsData per actor data needed to compute new positions /// @return new position of each actor - const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector&& actorsData, bool skip); + const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector&& actorsData, bool skip, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); // Thread safe wrappers void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; @@ -87,6 +89,12 @@ namespace MWPhysics mutable std::shared_mutex mLOSCacheMutex; mutable std::mutex mUpdateAabbMutex; std::condition_variable_any mHasJob; + + unsigned int mFrameNumber; + const osg::Timer* mTimer; + osg::Timer_t mTimeBegin; + osg::Timer_t mTimeEnd; + osg::Timer_t mFrameStart; }; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 8a58919ca5..1ceba2f315 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -665,7 +666,7 @@ namespace MWPhysics mMovementQueue.clear(); } - const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation) + const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { mTimeAccum += dt; @@ -675,7 +676,7 @@ namespace MWPhysics mTimeAccum -= numSteps * mPhysicsDt; - return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation); + return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation, frameStart, frameNumber, stats); } std::vector PhysicsSystem::prepareFrameData(int numSteps) diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index ccfca5422a..379aea1dd4 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../mwworld/ptr.hpp" @@ -200,7 +201,7 @@ namespace MWPhysics void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity); /// Apply all queued movements, then clear the list. - const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation); + const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); /// Clear the queued movements list without applying. void clearQueuedMovement(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ad6c337909..54b94833e3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -1494,14 +1495,14 @@ namespace MWWorld mPhysics->updateAnimatedCollisionShape(ptr); } - void World::doPhysics(float duration) + void World::doPhysics(float duration, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { mPhysics->stepSimulation(); processDoors(duration); mProjectileManager->update(duration); - const auto results = mPhysics->applyQueuedMovement(duration, mDiscardMovements); + const auto results = mPhysics->applyQueuedMovement(duration, mDiscardMovements, frameStart, frameNumber, stats); mDiscardMovements = false; for(const auto& [actor, position]: results) @@ -1830,11 +1831,11 @@ namespace MWWorld } } - void World::updatePhysics (float duration, bool paused) + void World::updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { if (!paused) { - doPhysics (duration); + doPhysics (duration, frameStart, frameNumber, stats); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 909ac1d412..41ab9cf2ca 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -157,7 +157,7 @@ namespace MWWorld void processDoors(float duration); ///< Run physics simulation and modify \a world accordingly. - void doPhysics(float duration); + void doPhysics(float duration, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); ///< Run physics simulation and modify \a world accordingly. void updateNavigator(); @@ -493,7 +493,7 @@ namespace MWWorld /// \return pointer to created record void update (float duration, bool paused) override; - void updatePhysics (float duration, bool paused) override; + void updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) override; void updateWindowManager () override;