Improve texture cache code to use precise subpaths instead of hashes
This commit is contained in:
@@ -956,7 +956,7 @@ void IrrDriver::applyResolutionSettings()
|
||||
->getAsset(FileManager::GUI,"options_video.png"))
|
||||
);
|
||||
|
||||
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""));
|
||||
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""), "models");
|
||||
const std::string materials_file =
|
||||
file_manager->getAssetChecked(FileManager::MODEL, "materials.xml");
|
||||
if (materials_file != "")
|
||||
@@ -1576,6 +1576,7 @@ void IrrDriver::unsetTextureErrorMessage()
|
||||
} // unsetTextureErrorMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#if 0
|
||||
/** Retrieve all textures in the specified directory, generate a smaller
|
||||
* version for each of them and save them in the cache. Smaller textures are
|
||||
* generated only if they do not already exist or if their original version
|
||||
@@ -1642,7 +1643,7 @@ std::string IrrDriver::getSmallerTexture(const std::string& filename)
|
||||
} // if !file_manager->fileExists(cached_file)
|
||||
return cached_file;
|
||||
} // getSmallerTexture
|
||||
|
||||
#endif
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a texture from a file and returns the texture object. This is just
|
||||
* a convenient wrapper which loads the texture from a STK asset directory.
|
||||
|
||||
@@ -220,8 +220,10 @@ public:
|
||||
bool OnEvent(const irr::SEvent &event);
|
||||
void setAmbientLight(const video::SColorf &light,
|
||||
bool force_SH_computation = true);
|
||||
#if 0
|
||||
std::string generateSmallerTextures(const std::string& dir);
|
||||
std::string getSmallerTexture(const std::string& texture);
|
||||
#endif
|
||||
video::ITexture *getTexture(FileManager::AssetType type,
|
||||
const std::string &filename,
|
||||
bool is_premul=false,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/stk_texture.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
@@ -79,15 +80,41 @@ void STKTexture::reload(bool no_upload, video::IImage* pre_loaded_tex)
|
||||
if (!no_upload && m_mesh_texture && CVS->isTextureCompressionEnabled())
|
||||
{
|
||||
std::string orig_file = NamedPath.getPtr();
|
||||
compressed_texture = getHashedName(orig_file);
|
||||
if (!file_manager->fileIsNewer(orig_file, compressed_texture))
|
||||
|
||||
std::string basename = StringUtils::getBasename(orig_file);
|
||||
//Log::info("STKTexture", "Basename: <%s> / <%s>", basename.c_str(), orig_file.c_str());
|
||||
|
||||
std::string container_id;
|
||||
if (file_manager->searchTextureContainerId(container_id, basename))
|
||||
{
|
||||
//Log::info("STKTexture", "container_id: %s", container_id.c_str());
|
||||
|
||||
std::string cache_subdir = "hd/";
|
||||
if ((UserConfigParams::m_high_definition_textures & 0x01) == 0x01)
|
||||
{
|
||||
cache_subdir = "hd/";
|
||||
}
|
||||
else
|
||||
{
|
||||
cache_subdir = StringUtils::insertValues("resized_%i/",
|
||||
(int)UserConfigParams::m_max_texture_size);
|
||||
}
|
||||
|
||||
std::string cache_dir = file_manager->getCachedTexturesDir() + cache_subdir + container_id;
|
||||
compressed_texture = cache_dir + "/" + basename + ".stktz";
|
||||
|
||||
if (loadCompressedTexture(compressed_texture))
|
||||
{
|
||||
Log::info("STKTexture", "Compressed %s for texture %s",
|
||||
compressed_texture.c_str(), orig_file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
file_manager->checkAndCreateDirectoryP(cache_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("STKTexture", "Cannot find container_id for texture '%s'", orig_file.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -402,20 +429,6 @@ void STKTexture::saveCompressedTexture(const std::string& compressed_tex)
|
||||
#endif
|
||||
} // saveCompressedTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string STKTexture::getHashedName(const std::string& orig_file)
|
||||
{
|
||||
std::string result = file_manager->getCachedTexturesDir();
|
||||
std::stringstream hash;
|
||||
size_t hash_1 = std::hash<std::string>{}(StringUtils::getPath(orig_file));
|
||||
size_t hash_2 =
|
||||
std::hash<std::string>{}(StringUtils::getBasename(orig_file));
|
||||
const core::dimension2du& max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
hash << std::hex << hash_1 << hash_2 << max_size.Height;
|
||||
return result + hash.str() + ".stktz";
|
||||
} // getHashedName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool STKTexture::hasMipMaps() const
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void saveCompressedTexture(const std::string& file_name);
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getHashedName(const std::string& orig_file);
|
||||
//std::string getHashedName(const std::string& orig_file);
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -309,11 +309,11 @@ void FileManager::init()
|
||||
// Note that we can't push the texture search path in the constructor
|
||||
// since this also adds a file archive to the file system - and
|
||||
// m_file_system is deleted (in irr_driver)
|
||||
pushTextureSearchPath(m_subdir_name[TEXTURE]);
|
||||
if(fileExists(m_subdir_name[TEXTURE]+"deprecated/"))
|
||||
pushTextureSearchPath(m_subdir_name[TEXTURE]+"deprecated/");
|
||||
pushTextureSearchPath(m_subdir_name[TEXTURE], "textures");
|
||||
if (fileExists(m_subdir_name[TEXTURE]+"deprecated/"))
|
||||
pushTextureSearchPath(m_subdir_name[TEXTURE]+"deprecated/", "deprecatedtex");
|
||||
|
||||
pushTextureSearchPath(m_subdir_name[GUI]);
|
||||
pushTextureSearchPath(m_subdir_name[GUI], "gui");
|
||||
|
||||
pushModelSearchPath (m_subdir_name[MODEL]);
|
||||
pushMusicSearchPath (m_subdir_name[MUSIC]);
|
||||
@@ -517,9 +517,9 @@ void FileManager::pushModelSearchPath(const std::string& path)
|
||||
/** Adds a texture search path to the list of texture search paths.
|
||||
* This path will be searched before any other existing paths.
|
||||
*/
|
||||
void FileManager::pushTextureSearchPath(const std::string& path)
|
||||
void FileManager::pushTextureSearchPath(const std::string& path, const std::string& container_id)
|
||||
{
|
||||
m_texture_search_path.push_back(path);
|
||||
m_texture_search_path.push_back(TextureSearchPath(path, container_id));
|
||||
const int n=m_file_system->getFileArchiveCount();
|
||||
m_file_system->addFileArchive(createAbsoluteFilename(path),
|
||||
/*ignoreCase*/false,
|
||||
@@ -548,9 +548,9 @@ void FileManager::popTextureSearchPath()
|
||||
{
|
||||
if(!m_texture_search_path.empty())
|
||||
{
|
||||
std::string dir = m_texture_search_path.back();
|
||||
TextureSearchPath dir = m_texture_search_path.back();
|
||||
m_texture_search_path.pop_back();
|
||||
m_file_system->removeFileArchive(createAbsoluteFilename(dir));
|
||||
m_file_system->removeFileArchive(createAbsoluteFilename(dir.m_texture_search_path));
|
||||
}
|
||||
} // popTextureSearchPath
|
||||
|
||||
@@ -601,6 +601,29 @@ bool FileManager::findFile(std::string& full_path,
|
||||
return false;
|
||||
} // findFile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Tries to find the specified file in any of the given search paths.
|
||||
* \param full_path On return contains the full path of the file, or
|
||||
* "" if the file is not found.
|
||||
* \param file_name The name of the file to look for.
|
||||
* \param search_path The list of paths to search for the file.
|
||||
* \return True if the file is found, false otherwise.
|
||||
*/
|
||||
bool FileManager::findFile(std::string& full_path,
|
||||
const std::string& file_name,
|
||||
const std::vector<TextureSearchPath>& search_path) const
|
||||
{
|
||||
for (std::vector<TextureSearchPath>::const_reverse_iterator
|
||||
i = search_path.rbegin();
|
||||
i != search_path.rend(); ++i)
|
||||
{
|
||||
full_path = i->m_texture_search_path + file_name;
|
||||
if (m_file_system->existFile(full_path.c_str())) return true;
|
||||
}
|
||||
full_path = "";
|
||||
return false;
|
||||
} // findFile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string FileManager::getAssetChecked(FileManager::AssetType type,
|
||||
const std::string& name,
|
||||
@@ -693,6 +716,27 @@ std::string FileManager::searchTexture(const std::string& file_name) const
|
||||
return path;
|
||||
} // searchTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool FileManager::searchTextureContainerId(std::string& container_id,
|
||||
const std::string& file_name) const
|
||||
{
|
||||
std::string full_path;
|
||||
for (std::vector<TextureSearchPath>::const_reverse_iterator
|
||||
i = m_texture_search_path.rbegin();
|
||||
i != m_texture_search_path.rend(); ++i)
|
||||
{
|
||||
full_path = i->m_texture_search_path + file_name;
|
||||
if (m_file_system->existFile(full_path.c_str()))
|
||||
{
|
||||
container_id = i->m_container_id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
full_path = "";
|
||||
return false;
|
||||
} // findFile
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the list of all directories in which music files are searched.
|
||||
*/
|
||||
@@ -1137,35 +1181,6 @@ void FileManager::redirectOutput()
|
||||
Log::openOutputFiles(logoutfile);
|
||||
} // redirectOutput
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the theoretical location of the cached version of a texture
|
||||
* depending of the current config. (This function also works for directories:
|
||||
* in this case the returned directory will be the cache location for all
|
||||
* textures that you will find in the specified directory. The specified
|
||||
* directory must end with '/')
|
||||
* \note The returned location is where the cached data should be read or
|
||||
* written but the file itseft does not necessarity exist. However, the
|
||||
* directory structure is automatically created if it does not exist.
|
||||
*/
|
||||
std::string FileManager::getTextureCacheLocation(const std::string& filename)
|
||||
{
|
||||
std::string file = StringUtils::getBasename(filename);
|
||||
|
||||
std::string parent_dir = StringUtils::getPath(filename);
|
||||
if (StringUtils::hasSuffix(parent_dir, "/"))
|
||||
parent_dir = parent_dir.substr(0, parent_dir.size() - 1);
|
||||
parent_dir = StringUtils::getBasename(parent_dir);
|
||||
|
||||
std::string cache_subdir = (UserConfigParams::m_high_definition_textures & 0x01) == 0x01
|
||||
? "hd/"
|
||||
: "resized/";
|
||||
std::string cached_file =
|
||||
getCachedTexturesDir() + cache_subdir + parent_dir + "/";
|
||||
checkAndCreateDirectoryP(cached_file);
|
||||
cached_file += file;
|
||||
return cached_file;
|
||||
} // getTextureCacheLocation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the directory for addon files. */
|
||||
const std::string &FileManager::getAddonsDir() const
|
||||
|
||||
@@ -37,6 +37,17 @@ using namespace irr;
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
struct TextureSearchPath
|
||||
{
|
||||
std::string m_texture_search_path;
|
||||
std::string m_container_id;
|
||||
|
||||
TextureSearchPath(std::string path, std::string container_id) :
|
||||
m_texture_search_path(path), m_container_id(container_id)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief class handling files and paths
|
||||
* \ingroup io
|
||||
@@ -52,6 +63,7 @@ public:
|
||||
SCRIPT, SFX, SHADER, SKIN, TEXTURE, TTF,
|
||||
TRANSLATION, ASSET_MAX = TRANSLATION,
|
||||
ASSET_COUNT};
|
||||
|
||||
private:
|
||||
|
||||
/** The names of the various subdirectories of the asset types. */
|
||||
@@ -84,14 +96,19 @@ private:
|
||||
/** Directory where user-defined grand prix are stored. */
|
||||
std::string m_gp_dir;
|
||||
|
||||
std::vector<TextureSearchPath> m_texture_search_path;
|
||||
|
||||
std::vector<std::string>
|
||||
m_texture_search_path,
|
||||
m_model_search_path,
|
||||
m_music_search_path;
|
||||
bool findFile(std::string& full_path,
|
||||
const std::string& fname,
|
||||
const std::vector<std::string>& search_path)
|
||||
const;
|
||||
bool findFile(std::string& full_path,
|
||||
const std::string& fname,
|
||||
const std::vector<TextureSearchPath>& search_path)
|
||||
const;
|
||||
void makePath(std::string& path, const std::string& dir,
|
||||
const std::string& fname) const;
|
||||
bool checkAndCreateDirectory(const std::string &path);
|
||||
@@ -124,7 +141,6 @@ public:
|
||||
std::string getReplayDir() const;
|
||||
std::string getCachedTexturesDir() const;
|
||||
std::string getGPDir() const;
|
||||
std::string getTextureCacheLocation(const std::string& filename);
|
||||
bool checkAndCreateDirectoryP(const std::string &path);
|
||||
const std::string &getAddonsDir() const;
|
||||
std::string getAddonsFile(const std::string &name);
|
||||
@@ -157,6 +173,9 @@ public:
|
||||
return fileExists(std::string(prefix) + path);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
bool searchTextureContainerId(std::string& container_id,
|
||||
const std::string& file_name) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the stdout file for log messages. */
|
||||
static const std::string& getStdoutName() { return m_stdout_filename; }
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -165,7 +184,7 @@ public:
|
||||
bool make_full_path=false) const;
|
||||
|
||||
|
||||
void pushTextureSearchPath(const std::string& path);
|
||||
void pushTextureSearchPath(const std::string& path, const std::string& container_id);
|
||||
void pushModelSearchPath(const std::string& path);
|
||||
void popTextureSearchPath();
|
||||
void popModelSearchPath();
|
||||
|
||||
@@ -225,8 +225,9 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
|
||||
// Load material
|
||||
std::string materials_file = m_root+"materials.xml";
|
||||
file_manager->pushModelSearchPath (m_root);
|
||||
file_manager->pushTextureSearchPath(m_root);
|
||||
std::string unique_id = StringUtils::insertValues("karts/%s", m_ident.c_str());
|
||||
file_manager->pushModelSearchPath(m_root);
|
||||
file_manager->pushTextureSearchPath(m_root, unique_id);
|
||||
|
||||
irr_driver->setTextureErrorMessage("Error while loading kart '%s':",
|
||||
m_name);
|
||||
|
||||
@@ -1574,7 +1574,7 @@ int main(int argc, char *argv[] )
|
||||
// Both item_manager and powerup_manager load models and therefore
|
||||
// textures from the model directory. To avoid reading the
|
||||
// materials.xml twice, we do this here once for both:
|
||||
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""));
|
||||
file_manager->pushTextureSearchPath(file_manager->getAsset(FileManager::MODEL,""), "models");
|
||||
const std::string materials_file =
|
||||
file_manager->getAsset(FileManager::MODEL,"materials.xml");
|
||||
if(materials_file!="")
|
||||
|
||||
@@ -1627,9 +1627,11 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
m_sky_type = SKY_NONE;
|
||||
m_track_object_manager = new TrackObjectManager();
|
||||
|
||||
std::string unique_id = StringUtils::insertValues("tracks/%s", m_ident.c_str());
|
||||
|
||||
// Add the track directory to the texture search path
|
||||
file_manager->pushTextureSearchPath(m_root);
|
||||
file_manager->pushModelSearchPath (m_root);
|
||||
file_manager->pushTextureSearchPath(m_root, unique_id);
|
||||
file_manager->pushModelSearchPath(m_root);
|
||||
|
||||
// For now ignore the resize cache, since atm it only handles texturs in
|
||||
// the track directory.
|
||||
|
||||
@@ -232,7 +232,8 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
|
||||
return;
|
||||
}
|
||||
|
||||
file_manager->pushTextureSearchPath(lib_path + "/");
|
||||
std::string unique_id = StringUtils::insertValues("library/%s", name.c_str());
|
||||
file_manager->pushTextureSearchPath(lib_path + "/", unique_id);
|
||||
file_manager->pushModelSearchPath(lib_path);
|
||||
material_manager->pushTempMaterial(lib_path + "/materials.xml");
|
||||
model_def_loader.addToLibrary(name, libroot);
|
||||
@@ -438,7 +439,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
|
||||
World::getWorld()->getIdent() == IDENT_CUTSCENE);
|
||||
|
||||
m_model_file = model_file;
|
||||
file_manager->pushTextureSearchPath(StringUtils::getPath(model_file));
|
||||
//file_manager->pushTextureSearchPath(StringUtils::getPath(model_file));
|
||||
#ifndef SERVER_ONLY
|
||||
if (file_manager->fileExists(model_file))
|
||||
{
|
||||
@@ -466,7 +467,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
|
||||
throw std::runtime_error("Model '" + model_file + "' cannot be found");
|
||||
}
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
//file_manager->popTextureSearchPath();
|
||||
init(NULL, NULL, true);
|
||||
} // TrackObjectPresentationMesh
|
||||
|
||||
|
||||
Reference in New Issue
Block a user