Use correct frame and stats for lua worker

When a loading screen appears during the frame processing, the frame number
returned by the viewer is incremented and the stats reporting goes into the
wrong frame. Pass frame number and stats object from the main thread to avoid
this.
pull/3235/head
elsid 3 weeks ago
parent 5f926bd129
commit b4976354a5
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -340,11 +340,12 @@ bool OMW::Engine::frame(float frametime)
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();
mLuaWorker->finishUpdate();
mLuaWorker->finishUpdate(frameStart, frameNumber, *stats);
return true;
}
@ -910,7 +911,7 @@ void OMW::Engine::prepareEngine()
mLuaManager->init();
// 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.

@ -7,13 +7,12 @@
#include <components/debug/debuglog.hpp>
#include <components/settings/values.hpp>
#include <osgViewer/Viewer>
#include <cassert>
namespace MWLua
{
Worker::Worker(LuaManager& manager, osgViewer::Viewer& viewer)
Worker::Worker(LuaManager& manager)
: mManager(manager)
, mViewer(viewer)
{
if (Settings::lua().mLuaNumThreads > 0)
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)
return;
{
std::lock_guard<std::mutex> lk(mMutex);
mUpdateRequest = true;
mUpdateRequest = UpdateRequest{ .mFrameStart = frameStart, .mFrameNumber = frameNumber, .mStats = &stats };
}
mCV.notify_one();
}
void Worker::finishUpdate()
void Worker::finishUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
{
if (mThread)
{
std::unique_lock<std::mutex> lk(mMutex);
mCV.wait(lk, [&] { return !mUpdateRequest; });
mCV.wait(lk, [&] { return !mUpdateRequest.has_value(); });
}
else
update();
update(frameStart, frameNumber, stats);
}
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 unsigned int frameNumber = mViewer.getFrameStamp()->getFrameNumber();
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(
frameStart, frameNumber, *osg::Timer::instance(), *mViewer.getViewerStats());
const osg::Timer* const timer = osg::Timer::instance();
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(frameStart, frameNumber, *timer, stats);
mManager.update();
}
@ -79,20 +76,22 @@ namespace MWLua
while (true)
{
std::unique_lock<std::mutex> lk(mMutex);
mCV.wait(lk, [&] { return mUpdateRequest || mJoinRequest; });
mCV.wait(lk, [&] { return mUpdateRequest.has_value() || mJoinRequest; });
if (mJoinRequest)
break;
assert(mUpdateRequest.has_value());
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();
}
mUpdateRequest = false;
mUpdateRequest.reset();
lk.unlock();
mCV.notify_one();
}

@ -1,14 +1,17 @@
#ifndef OPENMW_MWLUA_WORKER_H
#define OPENMW_MWLUA_WORKER_H
#include <osg/Timer>
#include <osg/ref_ptr>
#include <condition_variable>
#include <mutex>
#include <optional>
#include <thread>
namespace osgViewer
namespace osg
{
class Viewer;
class Stats;
}
namespace MWLua
@ -18,26 +21,32 @@ namespace MWLua
class Worker
{
public:
explicit Worker(LuaManager& manager, osgViewer::Viewer& viewer);
explicit Worker(LuaManager& manager);
~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();
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;
LuaManager& mManager;
osgViewer::Viewer& mViewer;
std::mutex mMutex;
std::condition_variable mCV;
bool mUpdateRequest = false;
std::optional<UpdateRequest> mUpdateRequest;
bool mJoinRequest = false;
std::optional<std::thread> mThread;
};

Loading…
Cancel
Save