1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 14:45:37 +00:00

Add the async physics worker to the profiler overlay.

This commit is contained in:
Frederic Chardon 2020-11-20 13:11:53 +01:00 committed by fredzio
parent 881bc49e0b
commit 9aba55a21a
8 changed files with 49 additions and 13 deletions

View file

@ -94,6 +94,7 @@ namespace
Script,
Mechanics,
Physics,
PhysicsWorker,
World,
Gui,
@ -124,6 +125,9 @@ namespace
template <>
const UserStats UserStatsValue<UserStatsType::Physics>::sValue {"Phys", "physics"};
template <>
const UserStats UserStatsValue<UserStatsType::PhysicsWorker>::sValue {" -Async", "physicsworker"};
template <>
const UserStats UserStatsValue<UserStatsType::World>::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);
}
}

View file

@ -10,6 +10,8 @@
#include <components/esm/cellid.hpp>
#include <osg/Timer>
#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;

View file

@ -1,6 +1,8 @@
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
#include <osg/Stats>
#include "components/debug/debuglog.hpp"
#include <components/misc/barrier.hpp>
#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<ActorFrameData>&& actorsData, bool skipSimulation)
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& 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

View file

@ -9,6 +9,8 @@
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <osg/Timer>
#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<ActorFrameData>&& actorsData, bool skip);
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& 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;
};
}

View file

@ -5,6 +5,7 @@
#include <memory>
#include <osg/Group>
#include <osg/Stats>
#include <osg/Timer>
#include <BulletCollision/CollisionShapes/btConeShape.h>
#include <BulletCollision/CollisionShapes/btSphereShape.h>
@ -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<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)

View file

@ -10,6 +10,7 @@
#include <osg/Quat>
#include <osg/BoundingBox>
#include <osg/ref_ptr>
#include <osg/Timer>
#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();

View file

@ -2,6 +2,7 @@
#include <osg/Group>
#include <osg/ComputeBoundsVisitor>
#include <osg/Timer>
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
@ -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);
}
}

View file

@ -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;