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:
commit
6246b479ea
5 changed files with 59 additions and 23 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue