mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-25 16:43:33 +00:00
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.
This commit is contained in:
parent
5f926bd129
commit
b4976354a5
@ -340,11 +340,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 +911,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.
|
||||||
|
@ -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