Make kart textures loading ondemand if needed
This commit is contained in:
parent
e0636495f0
commit
f777e01a21
@ -3,8 +3,10 @@
|
||||
|
||||
#include <IVideoDriver.h>
|
||||
#include <matrix4.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
@ -14,6 +16,7 @@ struct GEConfig
|
||||
bool m_disable_npot_texture;
|
||||
bool m_convert_irrlicht_mesh;
|
||||
bool m_texture_compression;
|
||||
std::unordered_set<std::string> m_ondemand_load_texture_paths;
|
||||
};
|
||||
|
||||
void setVideoDriver(irr::video::IVideoDriver* driver);
|
||||
|
@ -13,7 +13,12 @@ std::chrono::steady_clock::time_point g_mono_start =
|
||||
|
||||
void setVideoDriver(irr::video::IVideoDriver* driver)
|
||||
{
|
||||
g_driver = driver;
|
||||
if (driver != g_driver)
|
||||
{
|
||||
// Reset everytime driver is recreated
|
||||
g_config.m_ondemand_load_texture_paths.clear();
|
||||
g_driver = driver;
|
||||
}
|
||||
}
|
||||
|
||||
irr::video::IVideoDriver* getDriver()
|
||||
|
@ -43,6 +43,8 @@ GEVulkanTexture::GEVulkanTexture(const std::string& path,
|
||||
return;
|
||||
}
|
||||
|
||||
auto& paths = getGEConfig()->m_ondemand_load_texture_paths;
|
||||
m_ondemand_load = (paths.find(m_full_path.c_str()) != paths.end());
|
||||
if (m_ondemand_load)
|
||||
{
|
||||
video::IImageLoader* loader = NULL;
|
||||
|
@ -214,6 +214,10 @@ public:
|
||||
return getImageViewLive();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool useOnDemandLoad() const { return m_ondemand_load; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const io::path& getFullPath() const { return m_full_path; }
|
||||
// ------------------------------------------------------------------------
|
||||
VkFormat getInternalFormat() const { return m_internal_format; }
|
||||
}; // GEVulkanTexture
|
||||
|
||||
|
@ -204,6 +204,10 @@ public:
|
||||
virtual void reload() {}
|
||||
|
||||
virtual bool loadingFailed() const { return LoadingFailed; }
|
||||
|
||||
virtual bool useOnDemandLoad() const { return false; }
|
||||
|
||||
virtual const io::path& getFullPath() const { return NamedPath.getPath(); }
|
||||
protected:
|
||||
|
||||
//! Helper function, helps to get the desired texture creation format from the flags.
|
||||
|
@ -1132,6 +1132,8 @@ void IrrDriver::applyResolutionSettings(bool recreate_device)
|
||||
|
||||
|
||||
kart_properties_manager->loadAllKarts();
|
||||
kart_properties_manager->onDemandLoadKartTextures(
|
||||
{ UserConfigParams::m_default_kart }, false/*unload_unused*/);
|
||||
|
||||
attachment_manager->loadModels();
|
||||
file_manager->popTextureSearchPath();
|
||||
|
@ -119,6 +119,9 @@ public:
|
||||
return getTexture(filename, std::string(error_message),
|
||||
std::string(detail));
|
||||
} // getTexture
|
||||
// ------------------------------------------------------------------------
|
||||
std::unordered_map<std::string, irr::video::ITexture*>& getAllTextures()
|
||||
{ return m_all_textures; }
|
||||
|
||||
}; // STKTexManager
|
||||
|
||||
|
@ -47,6 +47,9 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ge_main.hpp>
|
||||
#endif
|
||||
|
||||
float KartProperties::UNDEFINED = -99.9f;
|
||||
|
||||
@ -116,12 +119,27 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
KartProperties::~KartProperties()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL() && m_kart_model.use_count() == 1)
|
||||
if (m_kart_model.use_count() == 1)
|
||||
{
|
||||
m_kart_model = nullptr;
|
||||
SP::SPShaderManager::get()->removeUnusedShaders();
|
||||
ShaderFilesManager::getInstance()->removeUnusedShaderFiles();
|
||||
SP::SPTextureManager::get()->removeUnusedTextures();
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
m_kart_model = nullptr;
|
||||
SP::SPShaderManager::get()->removeUnusedShaders();
|
||||
ShaderFilesManager::getInstance()->removeUnusedShaderFiles();
|
||||
SP::SPTextureManager::get()->removeUnusedTextures();
|
||||
}
|
||||
|
||||
if (GE::getDriver()->getDriverType() != video::EDT_VULKAN)
|
||||
return;
|
||||
auto& paths = GE::getGEConfig()->m_ondemand_load_texture_paths;
|
||||
auto it = paths.begin();
|
||||
while (it != paths.end())
|
||||
{
|
||||
if (StringUtils::startsWith(*it, m_root_absolute_path))
|
||||
it = paths.erase(it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // ~KartProperties
|
||||
@ -176,6 +194,33 @@ void KartProperties::copyFrom(const KartProperties *source)
|
||||
}
|
||||
} // copyFrom
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void KartProperties::handleOnDemandLoadTexture()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (GE::getDriver()->getDriverType() != video::EDT_VULKAN)
|
||||
return;
|
||||
std::set<std::string> files;
|
||||
// Remove the last /
|
||||
m_root_absolute_path = StringUtils::getPath(m_root);
|
||||
m_root_absolute_path = file_manager->getFileSystem()
|
||||
->getAbsolutePath(m_root_absolute_path.c_str()).c_str();
|
||||
|
||||
file_manager->listFiles(files, m_root_absolute_path,
|
||||
true/*make_full_path*/);
|
||||
std::set<std::string> image_extensions =
|
||||
{
|
||||
"png", "jpg", "jpeg", "jpe", "svg"
|
||||
};
|
||||
for (const std::string& f : files)
|
||||
{
|
||||
if (image_extensions.find(StringUtils::getExtension(f)) !=
|
||||
image_extensions.end())
|
||||
GE::getGEConfig()->m_ondemand_load_texture_paths.insert(f);
|
||||
}
|
||||
#endif
|
||||
} // handleOnDemandLoadTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads the kart properties from a file.
|
||||
* \param filename Filename to load.
|
||||
@ -220,6 +265,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
m_is_addon = true;
|
||||
}
|
||||
|
||||
handleOnDemandLoadTexture();
|
||||
try
|
||||
{
|
||||
if(!root || root->getName()!="kart")
|
||||
|
@ -60,7 +60,7 @@ class KartProperties
|
||||
{
|
||||
private:
|
||||
/** Base directory for this kart. */
|
||||
std::string m_root;
|
||||
std::string m_root, m_root_absolute_path;
|
||||
|
||||
/** AI Properties for this kart, as a separate object in order to
|
||||
* reduce dependencies (and therefore compile time) when changing
|
||||
@ -209,6 +209,8 @@ private:
|
||||
// closely (+-0,1%) with the specifications in kart_characteristics.xml
|
||||
m_wheel_base = fabsf(kart_length / 1.425f);
|
||||
}
|
||||
|
||||
void handleOnDemandLoadTexture();
|
||||
public:
|
||||
/** Returns the string representation of a handicap level. */
|
||||
static std::string getHandicapAsString(HandicapLevel h);
|
||||
|
@ -38,6 +38,12 @@
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ge_main.hpp>
|
||||
#include <ge_vulkan_driver.hpp>
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#endif
|
||||
|
||||
KartPropertiesManager *kart_properties_manager=0;
|
||||
|
||||
std::vector<std::string> KartPropertiesManager::m_kart_search_path;
|
||||
@ -611,4 +617,83 @@ void KartPropertiesManager::getRandomKartList(int count,
|
||||
assert(count==0);
|
||||
} // getRandomKartList
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void KartPropertiesManager::onDemandLoadKartTextures(
|
||||
const std::set<std::string>& kart_list,
|
||||
bool unload_unused)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (kart_list.empty())
|
||||
return;
|
||||
|
||||
GE::GEVulkanDriver* gevd = GE::getVKDriver();
|
||||
if (!gevd)
|
||||
return;
|
||||
gevd->waitIdle();
|
||||
gevd->setDisableWaitIdle(true);
|
||||
|
||||
std::set<std::string> karts_folder;
|
||||
for (auto& dir : m_kart_search_path)
|
||||
{
|
||||
std::string kart_dir = file_manager->getFileSystem()
|
||||
->getAbsolutePath(dir.c_str()).c_str();
|
||||
karts_folder.insert(StringUtils::getPath(kart_dir));
|
||||
}
|
||||
|
||||
std::set<std::string> ingame_karts_folder;
|
||||
for (auto& kart : kart_list)
|
||||
{
|
||||
const KartProperties* kp = getKart(kart);
|
||||
if (!kp)
|
||||
continue;
|
||||
std::string kart_dir = file_manager->getFileSystem()
|
||||
->getAbsolutePath(kp->getKartDir().c_str()).c_str();
|
||||
ingame_karts_folder.insert(StringUtils::getPath(kart_dir));
|
||||
}
|
||||
|
||||
bool unloaded_unused = false;
|
||||
for (auto tex : STKTexManager::getInstance()->getAllTextures())
|
||||
{
|
||||
if (!tex.second || !tex.second->useOnDemandLoad())
|
||||
continue;
|
||||
std::string full_path = tex.second->getFullPath().c_str();
|
||||
bool is_kart_texture = false;
|
||||
bool in_use = false;
|
||||
for (auto& dir : karts_folder)
|
||||
{
|
||||
if (StringUtils::startsWith(full_path, dir))
|
||||
{
|
||||
is_kart_texture = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_kart_texture)
|
||||
{
|
||||
for (auto& dir : ingame_karts_folder)
|
||||
{
|
||||
if (StringUtils::startsWith(full_path, dir))
|
||||
{
|
||||
in_use = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This will load the ondemand kart textures now or unload the unused
|
||||
// kart textures
|
||||
if (in_use)
|
||||
tex.second->getTextureHandler();
|
||||
else if (unload_unused)
|
||||
{
|
||||
unloaded_unused = true;
|
||||
tex.second->reload();
|
||||
}
|
||||
}
|
||||
|
||||
gevd->setDisableWaitIdle(false);
|
||||
if (unloaded_unused)
|
||||
gevd->handleDeletedTextures();
|
||||
#endif
|
||||
} // onDemandLoadKartTextures
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
@ -137,6 +138,9 @@ public:
|
||||
const unsigned int getNumberOfKarts() const {
|
||||
return (unsigned int)m_karts_properties.size();
|
||||
} // getNumberOfKarts
|
||||
// ------------------------------------------------------------------------
|
||||
void onDemandLoadKartTextures(const std::set<std::string>& kart_list,
|
||||
bool unload_unused = true);
|
||||
};
|
||||
|
||||
extern KartPropertiesManager *kart_properties_manager;
|
||||
|
@ -2282,6 +2282,8 @@ int main(int argc, char *argv[])
|
||||
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI_ICON,
|
||||
"options_video.png"));
|
||||
kart_properties_manager -> loadAllKarts ();
|
||||
kart_properties_manager->onDemandLoadKartTextures(
|
||||
{ UserConfigParams::m_default_kart }, false/*unload_unused*/);
|
||||
OfficialKarts::load();
|
||||
handleXmasMode();
|
||||
handleEasterEarMode();
|
||||
|
@ -449,6 +449,12 @@ void RaceManager::startNew(bool from_overworld)
|
||||
|
||||
Log::verbose("RaceManager", "Nb of karts=%u, ghost karts:%u ai:%lu players:%lu\n",
|
||||
(unsigned int) m_num_karts, m_num_ghost_karts, m_ai_kart_list.size(), m_player_karts.size());
|
||||
std::set<std::string> used_karts;
|
||||
for (auto& kart : m_ai_kart_list)
|
||||
used_karts.insert(kart);
|
||||
for (auto& kart : m_player_karts)
|
||||
used_karts.insert(kart.getKartName());
|
||||
kart_properties_manager->onDemandLoadKartTextures(used_karts);
|
||||
|
||||
assert((unsigned int)m_num_karts == m_num_ghost_karts+m_ai_kart_list.size()+m_player_karts.size());
|
||||
|
||||
@ -979,6 +985,7 @@ void RaceManager::exitRace(bool delete_world)
|
||||
setNumKarts(0);
|
||||
setNumPlayers(0);
|
||||
|
||||
std::set<std::string> used_karts;
|
||||
if (some_human_player_well_ranked)
|
||||
{
|
||||
startSingleRace("gpwin", 999,
|
||||
@ -987,6 +994,9 @@ void RaceManager::exitRace(bool delete_world)
|
||||
scene->push();
|
||||
scene->setKarts(winners);
|
||||
scene->setPlayerWon(some_human_player_won);
|
||||
std::set<std::string> karts;
|
||||
for (auto& kart : winners)
|
||||
used_karts.insert(kart.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -998,6 +1008,8 @@ void RaceManager::exitRace(bool delete_world)
|
||||
if (humanLosers.size() >= 1)
|
||||
{
|
||||
scene->setKarts(humanLosers);
|
||||
for (auto& kart : humanLosers)
|
||||
used_karts.insert(kart.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1005,9 +1017,11 @@ void RaceManager::exitRace(bool delete_world)
|
||||
"This should have never happened\n");
|
||||
std::vector<std::pair<std::string, float> > karts;
|
||||
karts.emplace_back(UserConfigParams::m_default_kart, 0.0f);
|
||||
used_karts.insert(UserConfigParams::m_default_kart);
|
||||
scene->setKarts(karts);
|
||||
}
|
||||
}
|
||||
kart_properties_manager->onDemandLoadKartTextures(used_karts);
|
||||
}
|
||||
|
||||
if (delete_world)
|
||||
|
Loading…
Reference in New Issue
Block a user