mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 16:20:21 +00:00
Merge branch 'fix_osg_stats_report' into 'master'
Report osg stats for frames with loading screens (#7737) Closes #7737 See merge request OpenMW/openmw!4053
This commit is contained in:
commit
5b25435260
@ -145,6 +145,7 @@
|
|||||||
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
|
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
|
||||||
Bug #7724: Guards don't help vs werewolves
|
Bug #7724: Guards don't help vs werewolves
|
||||||
Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name
|
Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name
|
||||||
|
Bug #7737: OSG stats are missing some data on loading screens
|
||||||
Bug #7742: Governing attribute training limit should use the modified attribute
|
Bug #7742: Governing attribute training limit should use the modified attribute
|
||||||
Bug #7753: Editor: Actors Don't Scale According to Their Race
|
Bug #7753: Editor: Actors Don't Scale According to Their Race
|
||||||
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
||||||
|
@ -165,6 +165,15 @@ namespace
|
|||||||
private:
|
private:
|
||||||
int mMaxTextureImageUnits = 0;
|
int mMaxTextureImageUnits = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void reportStats(unsigned frameNumber, osgViewer::Viewer& viewer, std::ostream& stream)
|
||||||
|
{
|
||||||
|
viewer.getViewerStats()->report(stream, frameNumber);
|
||||||
|
osgViewer::Viewer::Cameras cameras;
|
||||||
|
viewer.getCameras(cameras);
|
||||||
|
for (osg::Camera* camera : cameras)
|
||||||
|
camera->getStats()->report(stream, frameNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::executeLocalScripts()
|
void OMW::Engine::executeLocalScripts()
|
||||||
@ -180,10 +189,9 @@ void OMW::Engine::executeLocalScripts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OMW::Engine::frame(float frametime)
|
bool OMW::Engine::frame(unsigned frameNumber, float frametime)
|
||||||
{
|
{
|
||||||
const osg::Timer_t frameStart = mViewer->getStartTick();
|
const osg::Timer_t frameStart = mViewer->getStartTick();
|
||||||
const unsigned int frameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
|
||||||
const osg::Timer* const timer = osg::Timer::instance();
|
const osg::Timer* const timer = osg::Timer::instance();
|
||||||
osg::Stats* const stats = mViewer->getViewerStats();
|
osg::Stats* const stats = mViewer->getViewerStats();
|
||||||
|
|
||||||
@ -340,11 +348,12 @@ bool OMW::Engine::frame(float frametime)
|
|||||||
mWorld->updateWindowManager();
|
mWorld->updateWindowManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
mLuaWorker->allowUpdate(); // if there is a separate Lua thread, it starts the update now
|
// if there is a separate Lua thread, it starts the update now
|
||||||
|
mLuaWorker->allowUpdate(frameStart, frameNumber, *stats);
|
||||||
|
|
||||||
mViewer->renderingTraversals();
|
mViewer->renderingTraversals();
|
||||||
|
|
||||||
mLuaWorker->finishUpdate();
|
mLuaWorker->finishUpdate(frameStart, frameNumber, *stats);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -910,7 +919,7 @@ void OMW::Engine::prepareEngine()
|
|||||||
mLuaManager->init();
|
mLuaManager->init();
|
||||||
|
|
||||||
// starts a separate lua thread if "lua num threads" > 0
|
// starts a separate lua thread if "lua num threads" > 0
|
||||||
mLuaWorker = std::make_unique<MWLua::Worker>(*mLuaManager, *mViewer);
|
mLuaWorker = std::make_unique<MWLua::Worker>(*mLuaManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise and enter main loop.
|
// Initialise and enter main loop.
|
||||||
@ -1020,7 +1029,9 @@ void OMW::Engine::go()
|
|||||||
|
|
||||||
mViewer->advance(timeManager.getRenderingSimulationTime());
|
mViewer->advance(timeManager.getRenderingSimulationTime());
|
||||||
|
|
||||||
if (!frame(dt))
|
const unsigned frameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
||||||
|
|
||||||
|
if (!frame(frameNumber, dt))
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
continue;
|
continue;
|
||||||
@ -1034,16 +1045,16 @@ void OMW::Engine::go()
|
|||||||
|
|
||||||
if (stats)
|
if (stats)
|
||||||
{
|
{
|
||||||
|
// The delay is required because rendering happens in parallel to the main thread and stats from there is
|
||||||
|
// available with delay.
|
||||||
constexpr unsigned statsReportDelay = 3;
|
constexpr unsigned statsReportDelay = 3;
|
||||||
const auto frameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
|
||||||
if (frameNumber >= statsReportDelay)
|
if (frameNumber >= statsReportDelay)
|
||||||
{
|
{
|
||||||
const unsigned reportFrameNumber = frameNumber - statsReportDelay;
|
// Viewer frame number can be different from frameNumber because of loading screens which render new
|
||||||
mViewer->getViewerStats()->report(stats, reportFrameNumber);
|
// frames inside a simulation frame.
|
||||||
osgViewer::Viewer::Cameras cameras;
|
const unsigned currentFrameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
||||||
mViewer->getCameras(cameras);
|
for (unsigned i = frameNumber; i <= currentFrameNumber; ++i)
|
||||||
for (auto camera : cameras)
|
reportStats(i - statsReportDelay, *mViewer, stats);
|
||||||
camera->getStats()->report(stats, reportFrameNumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ namespace OMW
|
|||||||
|
|
||||||
void executeLocalScripts();
|
void executeLocalScripts();
|
||||||
|
|
||||||
bool frame(float dt);
|
bool frame(unsigned frameNumber, float dt);
|
||||||
|
|
||||||
/// Prepare engine for game play
|
/// Prepare engine for game play
|
||||||
void prepareEngine();
|
void prepareEngine();
|
||||||
|
@ -7,13 +7,12 @@
|
|||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/settings/values.hpp>
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
#include <osgViewer/Viewer>
|
#include <cassert>
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
Worker::Worker(LuaManager& manager, osgViewer::Viewer& viewer)
|
Worker::Worker(LuaManager& manager)
|
||||||
: mManager(manager)
|
: mManager(manager)
|
||||||
, mViewer(viewer)
|
|
||||||
{
|
{
|
||||||
if (Settings::lua().mLuaNumThreads > 0)
|
if (Settings::lua().mLuaNumThreads > 0)
|
||||||
mThread = std::thread([this] { run(); });
|
mThread = std::thread([this] { run(); });
|
||||||
@ -29,26 +28,26 @@ namespace MWLua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::allowUpdate()
|
void Worker::allowUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
||||||
{
|
{
|
||||||
if (!mThread)
|
if (!mThread)
|
||||||
return;
|
return;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(mMutex);
|
std::lock_guard<std::mutex> lk(mMutex);
|
||||||
mUpdateRequest = true;
|
mUpdateRequest = UpdateRequest{ .mFrameStart = frameStart, .mFrameNumber = frameNumber, .mStats = &stats };
|
||||||
}
|
}
|
||||||
mCV.notify_one();
|
mCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::finishUpdate()
|
void Worker::finishUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
||||||
{
|
{
|
||||||
if (mThread)
|
if (mThread)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(mMutex);
|
std::unique_lock<std::mutex> lk(mMutex);
|
||||||
mCV.wait(lk, [&] { return !mUpdateRequest; });
|
mCV.wait(lk, [&] { return !mUpdateRequest.has_value(); });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
update();
|
update(frameStart, frameNumber, stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::join()
|
void Worker::join()
|
||||||
@ -64,12 +63,10 @@ namespace MWLua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::update()
|
void Worker::update(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
||||||
{
|
{
|
||||||
const osg::Timer_t frameStart = mViewer.getStartTick();
|
const osg::Timer* const timer = osg::Timer::instance();
|
||||||
const unsigned int frameNumber = mViewer.getFrameStamp()->getFrameNumber();
|
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(frameStart, frameNumber, *timer, stats);
|
||||||
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(
|
|
||||||
frameStart, frameNumber, *osg::Timer::instance(), *mViewer.getViewerStats());
|
|
||||||
|
|
||||||
mManager.update();
|
mManager.update();
|
||||||
}
|
}
|
||||||
@ -79,20 +76,22 @@ namespace MWLua
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(mMutex);
|
std::unique_lock<std::mutex> lk(mMutex);
|
||||||
mCV.wait(lk, [&] { return mUpdateRequest || mJoinRequest; });
|
mCV.wait(lk, [&] { return mUpdateRequest.has_value() || mJoinRequest; });
|
||||||
if (mJoinRequest)
|
if (mJoinRequest)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
assert(mUpdateRequest.has_value());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
update();
|
update(mUpdateRequest->mFrameStart, mUpdateRequest->mFrameNumber, *mUpdateRequest->mStats);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Failed to update LuaManager: " << e.what();
|
Log(Debug::Error) << "Failed to update LuaManager: " << e.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
mUpdateRequest = false;
|
mUpdateRequest.reset();
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
mCV.notify_one();
|
mCV.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
#ifndef OPENMW_MWLUA_WORKER_H
|
#ifndef OPENMW_MWLUA_WORKER_H
|
||||||
#define OPENMW_MWLUA_WORKER_H
|
#define OPENMW_MWLUA_WORKER_H
|
||||||
|
|
||||||
|
#include <osg/Timer>
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace osgViewer
|
namespace osg
|
||||||
{
|
{
|
||||||
class Viewer;
|
class Stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
@ -18,26 +21,32 @@ namespace MWLua
|
|||||||
class Worker
|
class Worker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Worker(LuaManager& manager, osgViewer::Viewer& viewer);
|
explicit Worker(LuaManager& manager);
|
||||||
|
|
||||||
~Worker();
|
~Worker();
|
||||||
|
|
||||||
void allowUpdate();
|
void allowUpdate(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
void finishUpdate();
|
void finishUpdate(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
void join();
|
void join();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update();
|
struct UpdateRequest
|
||||||
|
{
|
||||||
|
osg::Timer_t mFrameStart;
|
||||||
|
unsigned mFrameNumber;
|
||||||
|
osg::ref_ptr<osg::Stats> mStats;
|
||||||
|
};
|
||||||
|
|
||||||
|
void update(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
void run() noexcept;
|
void run() noexcept;
|
||||||
|
|
||||||
LuaManager& mManager;
|
LuaManager& mManager;
|
||||||
osgViewer::Viewer& mViewer;
|
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
std::condition_variable mCV;
|
std::condition_variable mCV;
|
||||||
bool mUpdateRequest = false;
|
std::optional<UpdateRequest> mUpdateRequest;
|
||||||
bool mJoinRequest = false;
|
bool mJoinRequest = false;
|
||||||
std::optional<std::thread> mThread;
|
std::optional<std::thread> mThread;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user