Skip to content

Commit f777e01

Browse files
committed
Make kart textures loading ondemand if needed
1 parent e063649 commit f777e01

File tree

13 files changed

+183
-7
lines changed

13 files changed

+183
-7
lines changed

lib/graphics_engine/include/ge_main.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
#include <IVideoDriver.h>
55
#include <matrix4.h>
6+
67
#include <cstdint>
78
#include <string>
9+
#include <unordered_set>
810

911
namespace GE
1012
{
@@ -14,6 +16,7 @@ struct GEConfig
1416
bool m_disable_npot_texture;
1517
bool m_convert_irrlicht_mesh;
1618
bool m_texture_compression;
19+
std::unordered_set<std::string> m_ondemand_load_texture_paths;
1720
};
1821

1922
void setVideoDriver(irr::video::IVideoDriver* driver);

lib/graphics_engine/src/ge_main.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ std::chrono::steady_clock::time_point g_mono_start =
1313

1414
void setVideoDriver(irr::video::IVideoDriver* driver)
1515
{
16-
g_driver = driver;
16+
if (driver != g_driver)
17+
{
18+
// Reset everytime driver is recreated
19+
g_config.m_ondemand_load_texture_paths.clear();
20+
g_driver = driver;
21+
}
1722
}
1823

1924
irr::video::IVideoDriver* getDriver()

lib/graphics_engine/src/ge_vulkan_texture.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ GEVulkanTexture::GEVulkanTexture(const std::string& path,
4343
return;
4444
}
4545

46+
auto& paths = getGEConfig()->m_ondemand_load_texture_paths;
47+
m_ondemand_load = (paths.find(m_full_path.c_str()) != paths.end());
4648
if (m_ondemand_load)
4749
{
4850
video::IImageLoader* loader = NULL;

lib/graphics_engine/src/ge_vulkan_texture.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ class GEVulkanTexture : public video::ITexture
214214
return getImageViewLive();
215215
}
216216
// ------------------------------------------------------------------------
217+
virtual bool useOnDemandLoad() const { return m_ondemand_load; }
218+
// ------------------------------------------------------------------------
219+
virtual const io::path& getFullPath() const { return m_full_path; }
220+
// ------------------------------------------------------------------------
217221
VkFormat getInternalFormat() const { return m_internal_format; }
218222
}; // GEVulkanTexture
219223

lib/irrlicht/include/ITexture.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ class ITexture : public virtual IReferenceCounted
204204
virtual void reload() {}
205205

206206
virtual bool loadingFailed() const { return LoadingFailed; }
207+
208+
virtual bool useOnDemandLoad() const { return false; }
209+
210+
virtual const io::path& getFullPath() const { return NamedPath.getPath(); }
207211
protected:
208212

209213
//! Helper function, helps to get the desired texture creation format from the flags.

src/graphics/irr_driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,8 @@ void IrrDriver::applyResolutionSettings(bool recreate_device)
11321132

11331133

11341134
kart_properties_manager->loadAllKarts();
1135+
kart_properties_manager->onDemandLoadKartTextures(
1136+
{ UserConfigParams::m_default_kart }, false/*unload_unused*/);
11351137

11361138
attachment_manager->loadModels();
11371139
file_manager->popTextureSearchPath();

src/graphics/stk_tex_manager.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ class STKTexManager : public Singleton<STKTexManager>, NoCopy
119119
return getTexture(filename, std::string(error_message),
120120
std::string(detail));
121121
} // getTexture
122+
// ------------------------------------------------------------------------
123+
std::unordered_map<std::string, irr::video::ITexture*>& getAllTextures()
124+
{ return m_all_textures; }
122125

123126
}; // STKTexManager
124127

src/karts/kart_properties.cpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
#include <stdexcept>
4848
#include <string>
4949

50+
#ifndef SERVER_ONLY
51+
#include <ge_main.hpp>
52+
#endif
5053

5154
float KartProperties::UNDEFINED = -99.9f;
5255

@@ -116,12 +119,27 @@ KartProperties::KartProperties(const std::string &filename)
116119
KartProperties::~KartProperties()
117120
{
118121
#ifndef SERVER_ONLY
119-
if (CVS->isGLSL() && m_kart_model.use_count() == 1)
122+
if (m_kart_model.use_count() == 1)
120123
{
121-
m_kart_model = nullptr;
122-
SP::SPShaderManager::get()->removeUnusedShaders();
123-
ShaderFilesManager::getInstance()->removeUnusedShaderFiles();
124-
SP::SPTextureManager::get()->removeUnusedTextures();
124+
if (CVS->isGLSL())
125+
{
126+
m_kart_model = nullptr;
127+
SP::SPShaderManager::get()->removeUnusedShaders();
128+
ShaderFilesManager::getInstance()->removeUnusedShaderFiles();
129+
SP::SPTextureManager::get()->removeUnusedTextures();
130+
}
131+
132+
if (GE::getDriver()->getDriverType() != video::EDT_VULKAN)
133+
return;
134+
auto& paths = GE::getGEConfig()->m_ondemand_load_texture_paths;
135+
auto it = paths.begin();
136+
while (it != paths.end())
137+
{
138+
if (StringUtils::startsWith(*it, m_root_absolute_path))
139+
it = paths.erase(it);
140+
else
141+
it++;
142+
}
125143
}
126144
#endif
127145
} // ~KartProperties
@@ -176,6 +194,33 @@ void KartProperties::copyFrom(const KartProperties *source)
176194
}
177195
} // copyFrom
178196

197+
//-----------------------------------------------------------------------------
198+
void KartProperties::handleOnDemandLoadTexture()
199+
{
200+
#ifndef SERVER_ONLY
201+
if (GE::getDriver()->getDriverType() != video::EDT_VULKAN)
202+
return;
203+
std::set<std::string> files;
204+
// Remove the last /
205+
m_root_absolute_path = StringUtils::getPath(m_root);
206+
m_root_absolute_path = file_manager->getFileSystem()
207+
->getAbsolutePath(m_root_absolute_path.c_str()).c_str();
208+
209+
file_manager->listFiles(files, m_root_absolute_path,
210+
true/*make_full_path*/);
211+
std::set<std::string> image_extensions =
212+
{
213+
"png", "jpg", "jpeg", "jpe", "svg"
214+
};
215+
for (const std::string& f : files)
216+
{
217+
if (image_extensions.find(StringUtils::getExtension(f)) !=
218+
image_extensions.end())
219+
GE::getGEConfig()->m_ondemand_load_texture_paths.insert(f);
220+
}
221+
#endif
222+
} // handleOnDemandLoadTexture
223+
179224
//-----------------------------------------------------------------------------
180225
/** Loads the kart properties from a file.
181226
* \param filename Filename to load.
@@ -220,6 +265,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
220265
m_is_addon = true;
221266
}
222267

268+
handleOnDemandLoadTexture();
223269
try
224270
{
225271
if(!root || root->getName()!="kart")

src/karts/kart_properties.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class KartProperties
6060
{
6161
private:
6262
/** Base directory for this kart. */
63-
std::string m_root;
63+
std::string m_root, m_root_absolute_path;
6464

6565
/** AI Properties for this kart, as a separate object in order to
6666
* reduce dependencies (and therefore compile time) when changing
@@ -209,6 +209,8 @@ class KartProperties
209209
// closely (+-0,1%) with the specifications in kart_characteristics.xml
210210
m_wheel_base = fabsf(kart_length / 1.425f);
211211
}
212+
213+
void handleOnDemandLoadTexture();
212214
public:
213215
/** Returns the string representation of a handicap level. */
214216
static std::string getHandicapAsString(HandicapLevel h);

src/karts/kart_properties_manager.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
#include <stdexcept>
3939
#include <iostream>
4040

41+
#ifndef SERVER_ONLY
42+
#include <ge_main.hpp>
43+
#include <ge_vulkan_driver.hpp>
44+
#include "graphics/stk_tex_manager.hpp"
45+
#endif
46+
4147
KartPropertiesManager *kart_properties_manager=0;
4248

4349
std::vector<std::string> KartPropertiesManager::m_kart_search_path;
@@ -611,4 +617,83 @@ void KartPropertiesManager::getRandomKartList(int count,
611617
assert(count==0);
612618
} // getRandomKartList
613619

620+
//-----------------------------------------------------------------------------
621+
void KartPropertiesManager::onDemandLoadKartTextures(
622+
const std::set<std::string>& kart_list,
623+
bool unload_unused)
624+
{
625+
#ifndef SERVER_ONLY
626+
if (kart_list.empty())
627+
return;
628+
629+
GE::GEVulkanDriver* gevd = GE::getVKDriver();
630+
if (!gevd)
631+
return;
632+
gevd->waitIdle();
633+
gevd->setDisableWaitIdle(true);
634+
635+
std::set<std::string> karts_folder;
636+
for (auto& dir : m_kart_search_path)
637+
{
638+
std::string kart_dir = file_manager->getFileSystem()
639+
->getAbsolutePath(dir.c_str()).c_str();
640+
karts_folder.insert(StringUtils::getPath(kart_dir));
641+
}
642+
643+
std::set<std::string> ingame_karts_folder;
644+
for (auto& kart : kart_list)
645+
{
646+
const KartProperties* kp = getKart(kart);
647+
if (!kp)
648+
continue;
649+
std::string kart_dir = file_manager->getFileSystem()
650+
->getAbsolutePath(kp->getKartDir().c_str()).c_str();
651+
ingame_karts_folder.insert(StringUtils::getPath(kart_dir));
652+
}
653+
654+
bool unloaded_unused = false;
655+
for (auto tex : STKTexManager::getInstance()->getAllTextures())
656+
{
657+
if (!tex.second || !tex.second->useOnDemandLoad())
658+
continue;
659+
std::string full_path = tex.second->getFullPath().c_str();
660+
bool is_kart_texture = false;
661+
bool in_use = false;
662+
for (auto& dir : karts_folder)
663+
{
664+
if (StringUtils::startsWith(full_path, dir))
665+
{
666+
is_kart_texture = true;
667+
break;
668+
}
669+
}
670+
if (is_kart_texture)
671+
{
672+
for (auto& dir : ingame_karts_folder)
673+
{
674+
if (StringUtils::startsWith(full_path, dir))
675+
{
676+
in_use = true;
677+
break;
678+
}
679+
}
680+
}
681+
// This will load the ondemand kart textures now or unload the unused
682+
// kart textures
683+
if (in_use)
684+
tex.second->getTextureHandler();
685+
else if (unload_unused)
686+
{
687+
unloaded_unused = true;
688+
tex.second->reload();
689+
}
690+
}
691+
692+
gevd->setDisableWaitIdle(false);
693+
if (unloaded_unused)
694+
gevd->handleDeletedTextures();
695+
#endif
696+
} // onDemandLoadKartTextures
697+
698+
614699
/* EOF */

0 commit comments

Comments
 (0)