1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 17:59:56 +00:00

Merge branch 'async_content_load' into 'master'

Speedup loading - load content files during logo video playing

See merge request OpenMW/openmw!3249
This commit is contained in:
AnyOldName3 2023-07-24 23:42:46 +00:00
commit 6246b479ea
5 changed files with 59 additions and 23 deletions

View file

@ -38,6 +38,8 @@
#include <components/l10n/manager.hpp> #include <components/l10n/manager.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/misc/frameratelimiter.hpp> #include <components/misc/frameratelimiter.hpp>
#include <components/sceneutil/color.hpp> #include <components/sceneutil/color.hpp>
@ -736,6 +738,13 @@ void OMW::Engine::prepareEngine()
mSoundManager = std::make_unique<MWSound::SoundManager>(mVFS.get(), mUseSound); mSoundManager = std::make_unique<MWSound::SoundManager>(mVFS.get(), mUseSound);
mEnvironment.setSoundManager(*mSoundManager); mEnvironment.setSoundManager(*mSoundManager);
// Create the world
mWorld = std::make_unique<MWWorld::World>(
mResourceSystem.get(), mActivationDistanceOverride, mCellName, mCfgMgr.getUserDataPath());
std::thread loadDataThread(
[&] { mWorld->loadData(mFileCollections, mContentFiles, mGroundcoverFiles, mEncoder.get()); });
if (!mSkipMenu) if (!mSkipMenu)
{ {
std::string_view logo = Fallback::Map::getString("Movies_Company_Logo"); std::string_view logo = Fallback::Map::getString("Movies_Company_Logo");
@ -743,10 +752,12 @@ void OMW::Engine::prepareEngine()
mWindowManager->playVideo(logo, true); mWindowManager->playVideo(logo, true);
} }
// Create the world Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
mWorld = std::make_unique<MWWorld::World>(mViewer, rootNode, mResourceSystem.get(), mWorkQueue.get(), *mUnrefQueue, listener->loadingOn();
mFileCollections, mContentFiles, mGroundcoverFiles, mEncoder.get(), mActivationDistanceOverride, mCellName, loadDataThread.join();
mCfgMgr.getUserDataPath()); listener->loadingOff();
mWorld->init(mViewer, rootNode, mWorkQueue.get(), *mUnrefQueue);
mWorld->setupPlayer(); mWorld->setupPlayer();
mWorld->setRandomSeed(mRandomSeed); mWorld->setRandomSeed(mRandomSeed);
mEnvironment.setWorld(*mWorld); mEnvironment.setWorld(*mWorld);

View file

@ -76,6 +76,10 @@ namespace MWGui
void LoadingScreen::setLabel(const std::string& label, bool important) void LoadingScreen::setLabel(const std::string& label, bool important)
{ {
std::lock_guard<std::mutex> guard(mMutex);
if (!isVisible())
return;
mImportantLabel = important; mImportantLabel = important;
mLoadingText->setCaptionWithReplacing(label); mLoadingText->setCaptionWithReplacing(label);
@ -141,6 +145,8 @@ namespace MWGui
void LoadingScreen::loadingOn(bool visible) void LoadingScreen::loadingOn(bool visible)
{ {
std::lock_guard<std::mutex> guard(mMutex);
// Early-out if already on // Early-out if already on
if (mNestedLoadingCount++ > 0 && mMainWidget->getVisible()) if (mNestedLoadingCount++ > 0 && mMainWidget->getVisible())
return; return;
@ -181,6 +187,8 @@ namespace MWGui
void LoadingScreen::loadingOff() void LoadingScreen::loadingOff()
{ {
std::lock_guard<std::mutex> guard(mMutex);
if (--mNestedLoadingCount > 0) if (--mNestedLoadingCount > 0)
return; return;
mLoadingBox->setVisible(true); // restore mLoadingBox->setVisible(true); // restore
@ -239,6 +247,10 @@ namespace MWGui
void LoadingScreen::setProgress(size_t value) void LoadingScreen::setProgress(size_t value)
{ {
std::lock_guard<std::mutex> guard(mMutex);
if (!isVisible())
return;
// skip expensive update if there isn't enough visible progress // skip expensive update if there isn't enough visible progress
if (mProgressBar->getWidth() <= 0 if (mProgressBar->getWidth() <= 0
|| value - mProgress < mProgressBar->getScrollRange() / mProgressBar->getWidth()) || value - mProgress < mProgressBar->getScrollRange() / mProgressBar->getWidth())
@ -253,6 +265,10 @@ namespace MWGui
void LoadingScreen::increaseProgress(size_t increase) void LoadingScreen::increaseProgress(size_t increase)
{ {
std::lock_guard<std::mutex> guard(mMutex);
if (!isVisible())
return;
mProgressBar->setScrollPosition(0); mProgressBar->setScrollPosition(0);
size_t value = mProgress + increase; size_t value = mProgress + increase;
value = std::min(value, mProgressBar->getScrollRange() - 1); value = std::min(value, mProgressBar->getScrollRange() - 1);

View file

@ -2,6 +2,7 @@
#define MWGUI_LOADINGSCREEN_H #define MWGUI_LOADINGSCREEN_H
#include <memory> #include <memory>
#include <mutex>
#include <osg/Timer> #include <osg/Timer>
#include <osg/ref_ptr> #include <osg/ref_ptr>
@ -69,6 +70,8 @@ namespace MWGui
bool mVisible; bool mVisible;
int mNestedLoadingCount; int mNestedLoadingCount;
std::mutex mMutex;
size_t mProgress; size_t mProgress;
bool mShowWallpaper; bool mShowWallpaper;

View file

@ -244,19 +244,16 @@ namespace MWWorld
mRendering->setSkyEnabled(false); mRendering->setSkyEnabled(false);
} }
World::World(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, World::World(Resource::ResourceSystem* resourceSystem, int activationDistanceOverride, const std::string& startCell,
SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const Files::Collections& fileCollections,
const std::vector<std::string>& contentFiles, const std::vector<std::string>& groundcoverFiles,
ToUTF8::Utf8Encoder* encoder, int activationDistanceOverride, const std::string& startCell,
const std::filesystem::path& userDataPath) const std::filesystem::path& userDataPath)
: mResourceSystem(resourceSystem) : mResourceSystem(resourceSystem)
, mLocalScripts(mStore) , mLocalScripts(mStore)
, mWorldModel(mStore, mReaders) , mWorldModel(mStore, mReaders)
, mCurrentDate(std::make_unique<DateTimeManager>())
, mSky(true) , mSky(true)
, mGodMode(false) , mGodMode(false)
, mScriptsEnabled(true) , mScriptsEnabled(true)
, mDiscardMovements(true) , mDiscardMovements(true)
, mContentFiles(contentFiles)
, mUserDataPath(userDataPath) , mUserDataPath(userDataPath)
, mActivationDistanceOverride(activationDistanceOverride) , mActivationDistanceOverride(activationDistanceOverride)
, mStartCell(startCell) , mStartCell(startCell)
@ -269,19 +266,20 @@ namespace MWWorld
, mPlayerInJail(false) , mPlayerInJail(false)
, mSpellPreloadTimer(0.f) , mSpellPreloadTimer(0.f)
{ {
}
void World::loadData(const Files::Collections& fileCollections, const std::vector<std::string>& contentFiles,
const std::vector<std::string>& groundcoverFiles, ToUTF8::Utf8Encoder* encoder)
{
mContentFiles = contentFiles;
if (encoder) if (encoder)
mReaders.setStatelessEncoder(encoder->getStatelessEncoder()); mReaders.setStatelessEncoder(encoder->getStatelessEncoder());
mESMVersions.resize(mContentFiles.size(), -1); mESMVersions.resize(mContentFiles.size(), -1);
Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
listener->loadingOn();
loadContentFiles(fileCollections, contentFiles, encoder, listener); loadContentFiles(fileCollections, contentFiles, encoder, listener);
loadGroundcoverFiles(fileCollections, groundcoverFiles, encoder, listener); loadGroundcoverFiles(fileCollections, groundcoverFiles, encoder, listener);
listener->loadingOff();
mCurrentDate = std::make_unique<DateTimeManager>();
fillGlobalVariables(); fillGlobalVariables();
mStore.setUp(); mStore.setUp();
@ -289,14 +287,18 @@ namespace MWWorld
mStore.movePlayerRecord(); mStore.movePlayerRecord();
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat(); mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
}
mPhysics = std::make_unique<MWPhysics::PhysicsSystem>(resourceSystem, rootNode); void World::init(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, SceneUtil::WorkQueue* workQueue,
SceneUtil::UnrefQueue& unrefQueue)
{
mPhysics = std::make_unique<MWPhysics::PhysicsSystem>(mResourceSystem, rootNode);
if (Settings::Manager::getBool("enable", "Navigator")) if (Settings::Manager::getBool("enable", "Navigator"))
{ {
auto navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager(); auto navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager();
navigatorSettings.mRecast.mSwimHeightScale = mSwimHeightScale; navigatorSettings.mRecast.mSwimHeightScale = mSwimHeightScale;
mNavigator = DetourNavigator::makeNavigator(navigatorSettings, userDataPath); mNavigator = DetourNavigator::makeNavigator(navigatorSettings, mUserDataPath);
} }
else else
{ {
@ -304,9 +306,9 @@ namespace MWWorld
} }
mRendering = std::make_unique<MWRender::RenderingManager>( mRendering = std::make_unique<MWRender::RenderingManager>(
viewer, rootNode, resourceSystem, workQueue, *mNavigator, mGroundcoverStore, unrefQueue); viewer, rootNode, mResourceSystem, workQueue, *mNavigator, mGroundcoverStore, unrefQueue);
mProjectileManager = std::make_unique<ProjectileManager>( mProjectileManager = std::make_unique<ProjectileManager>(
mRendering->getLightRoot()->asGroup(), resourceSystem, mRendering.get(), mPhysics.get()); mRendering->getLightRoot()->asGroup(), mResourceSystem, mRendering.get(), mPhysics.get());
mRendering->preloadCommonAssets(); mRendering->preloadCommonAssets();
mWeatherManager = std::make_unique<MWWorld::WeatherManager>(*mRendering, mStore); mWeatherManager = std::make_unique<MWWorld::WeatherManager>(*mRendering, mStore);

View file

@ -195,11 +195,15 @@ namespace MWWorld
void addContainerScripts(const Ptr& reference, CellStore* cell) override; void addContainerScripts(const Ptr& reference, CellStore* cell) override;
void removeContainerScripts(const Ptr& reference) override; void removeContainerScripts(const Ptr& reference) override;
World(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem, World(Resource::ResourceSystem* resourceSystem, int activationDistanceOverride, const std::string& startCell,
SceneUtil::WorkQueue* workQueue, SceneUtil::UnrefQueue& unrefQueue, const std::filesystem::path& userDataPath);
const Files::Collections& fileCollections, const std::vector<std::string>& contentFiles,
const std::vector<std::string>& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, void loadData(const Files::Collections& fileCollections, const std::vector<std::string>& contentFiles,
int activationDistanceOverride, const std::string& startCell, const std::filesystem::path& userDataPath); const std::vector<std::string>& groundcoverFiles, ToUTF8::Utf8Encoder* encoder);
// Must be called after `loadData`.
void init(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, SceneUtil::WorkQueue* workQueue,
SceneUtil::UnrefQueue& unrefQueue);
virtual ~World(); virtual ~World();