From 673d2499e8643474576ae7937bebd6391d0ac63a Mon Sep 17 00:00:00 2001 From: cx384 Date: Sun, 17 Mar 2024 15:04:40 +0100 Subject: [PATCH] Refactor texturepaths.cpp and SourceImageCache --- src/client/imagesource.cpp | 15 ++-- src/client/imagesource.h | 24 ++--- src/client/texturesource.cpp | 169 +++++++++++++---------------------- 3 files changed, 80 insertions(+), 128 deletions(-) diff --git a/src/client/imagesource.cpp b/src/client/imagesource.cpp index 92da3ee27..d401e98ed 100644 --- a/src/client/imagesource.cpp +++ b/src/client/imagesource.cpp @@ -75,13 +75,14 @@ void SourceImageCache::insert(const std::string &name, video::IImage *img, bool toadd->grab(); m_images[name] = toadd; } + video::IImage* SourceImageCache::get(const std::string &name) { std::map::iterator n; n = m_images.find(name); if (n != m_images.end()) return n->second; - return NULL; + return nullptr; } // Primarily fetches from cache, secondarily tries to read from filesystem @@ -96,12 +97,12 @@ video::IImage* SourceImageCache::getOrLoad(const std::string &name) video::IVideoDriver *driver = RenderingEngine::get_video_driver(); std::string path = getTexturePath(name); if (path.empty()) { - infostream<<"SourceImageCache::getOrLoad(): No path found for \"" - <createImageFromFile(path.c_str()); if (img){ @@ -1970,6 +1971,6 @@ video::SColor ImageSource::getImageAverageColor(const video::IImage &image) return c; } -void ImageSource::insertImage(const std::string &name, video::IImage *img, bool prefer_local) { +void ImageSource::insertSourceImage(const std::string &name, video::IImage *img, bool prefer_local) { m_sourcecache.insert(name, img, prefer_local); } diff --git a/src/client/imagesource.h b/src/client/imagesource.h index 15c982f8a..f3a30617a 100644 --- a/src/client/imagesource.h +++ b/src/client/imagesource.h @@ -23,10 +23,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "settings.h" -// This file is only for internal generation/modification of images. -// Use texturesource.h instead to handle textures. +// This file is only used for internal generation of images. +// Use texturesource.h to handle textures. // A cache used for storing source images. +// (A "source image" is an unmodified image directly taken from the filesystem.) +// Does not contain modified images. class SourceImageCache { public: ~SourceImageCache(); @@ -35,16 +37,13 @@ public: video::IImage* get(const std::string &name); - // Primarily fetches from cache, secondarily tries to read from filesystem + // Primarily fetches from cache, secondarily tries to read from filesystem. video::IImage *getOrLoad(const std::string &name); private: std::map m_images; }; -/* - * Generates and caches images. - * The image name defines the image by filename and texture modifiers. -*/ +// Generates images using texture modifiers, and caches source images. struct ImageSource { /*! Generates an image from a full string like * "stone.png^mineral_coal.png^[crack:1:0". @@ -53,8 +52,8 @@ struct ImageSource { */ video::IImage* generateImage(std::string_view name, std::set &source_image_names); - // To add self made images. - void insertImage(const std::string &name, video::IImage *img, bool prefer_local); + // Insert a source image into the cache without touching the filesystem. + void insertSourceImage(const std::string &name, video::IImage *img, bool prefer_local); // TODO should probably be moved elsewhere static video::SColor getImageAverageColor(const video::IImage &image); @@ -69,9 +68,10 @@ struct ImageSource { private: // Generate image based on a string like "stone.png" or "[crack:1:0". - // if baseimg is NULL, it is created. Otherwise stuff is made on it. - // source_image_names is important to determine when to flush the image from a cache (dynamic media) - bool generateImagePart(std::string_view part_of_name, video::IImage *& baseimg, std::set &source_image_names); + // If baseimg is NULL, it is created. Otherwise stuff is made on it. + // source_image_names is important to determine when to flush the image from a cache (dynamic media). + bool generateImagePart(std::string_view part_of_name, video::IImage *& baseimg, + std::set &source_image_names); // Cached settings needed for making textures from meshes bool m_setting_mipmap; diff --git a/src/client/texturesource.cpp b/src/client/texturesource.cpp index 7e56a57cd..12a21771a 100644 --- a/src/client/texturesource.cpp +++ b/src/client/texturesource.cpp @@ -27,41 +27,18 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "texturepaths.h" #include "imagesource.h" -/* - Stores internal information about a texture. -*/ +// Stores internal information about a texture. struct TextureInfo { std::string name; - video::ITexture *texture; - std::set sourceImages; + video::ITexture *texture = nullptr; - TextureInfo( - const std::string &name_, - video::ITexture *texture_=NULL - ): - name(name_), - texture(texture_) - { - } - - TextureInfo( - const std::string &name_, - video::ITexture *texture_, - std::set &&sourceImages_ - ): - name(name_), - texture(texture_), - sourceImages(std::move(sourceImages_)) - { - } + // Stores source image names which ImageSource::generateImage used. + std::set sourceImages{}; }; -/* - TextureSource -*/ - +// TextureSource class TextureSource : public IWritableTextureSource { public: @@ -150,7 +127,7 @@ public: // Shall be called from the main thread. void processQueue(); - // Insert an image into the cache without touching the filesystem. + // Insert a source image into the cache without touching the filesystem. // Shall be called from the main thread. void insertSourceImage(const std::string &name, video::IImage *img); @@ -200,11 +177,8 @@ private: // Maps image file names to loaded palettes. std::unordered_map m_palettes; - // Cached settings needed for making textures from meshes - bool m_setting_mipmap; - bool m_setting_trilinear_filter; - bool m_setting_bilinear_filter; - bool m_setting_anisotropic_filter; + // Cached from settings for making textures from meshes + bool mesh_filter_needed; }; IWritableTextureSource *createTextureSource() @@ -217,16 +191,17 @@ TextureSource::TextureSource() m_main_thread = std::this_thread::get_id(); // Add a NULL TextureInfo as the first index, named "" - m_textureinfo_cache.emplace_back(""); + m_textureinfo_cache.emplace_back(TextureInfo{""}); m_name_to_id[""] = 0; // Cache some settings // Note: Since this is only done once, the game must be restarted - // for these settings to take effect - m_setting_mipmap = g_settings->getBool("mip_map"); - m_setting_trilinear_filter = g_settings->getBool("trilinear_filter"); - m_setting_bilinear_filter = g_settings->getBool("bilinear_filter"); - m_setting_anisotropic_filter = g_settings->getBool("anisotropic_filter"); + // for these settings to take effect. + mesh_filter_needed = + g_settings->getBool("mip_map") || + g_settings->getBool("trilinear_filter") || + g_settings->getBool("bilinear_filter") || + g_settings->getBool("anisotropic_filter"); } TextureSource::~TextureSource() @@ -236,45 +211,37 @@ TextureSource::~TextureSource() unsigned int textures_before = driver->getTextureCount(); for (const auto &iter : m_textureinfo_cache) { - //cleanup texture + // cleanup texture if (iter.texture) driver->removeTexture(iter.texture); } m_textureinfo_cache.clear(); for (auto t : m_texture_trash) { - //cleanup trashed texture + // cleanup trashed texture driver->removeTexture(t); } - infostream << "~TextureSource() before cleanup: "<< textures_before + infostream << "~TextureSource() before cleanup: " << textures_before << " after: " << driver->getTextureCount() << std::endl; } u32 TextureSource::getTextureId(const std::string &name) { - { - /* - See if texture already exists - */ + { // See if texture already exists MutexAutoLock lock(m_textureinfo_cache_mutex); - std::map::iterator n; - n = m_name_to_id.find(name); + auto n = m_name_to_id.find(name); if (n != m_name_to_id.end()) - { return n->second; - } } - /* - Get texture - */ + // Get texture if (std::this_thread::get_id() == m_main_thread) { return generateTexture(name); } - infostream<<"getTextureId(): Queued: name=\""< result_queue; @@ -302,34 +269,26 @@ u32 TextureSource::getTextureId(const std::string &name) return 0; } -/* - This method generates all the textures -*/ +// This method generates all the textures u32 TextureSource::generateTexture(const std::string &name) { // Empty name means texture 0 if (name.empty()) { - infostream<<"generateTexture(): name is empty"<second; - } } - /* - Calling only allowed from main thread - */ + // Calling only allowed from main thread if (std::this_thread::get_id() != m_main_thread) { - errorstream<<"TextureSource::generateTexture() " - "called not from main thread"< source_image_names; video::IImage *img = m_imagesource.generateImage(name, source_image_names); - video::ITexture *tex = NULL; + video::ITexture *tex = nullptr; - if (img != NULL) { + if (img) { img = Align2Npot2(img, driver); // Create texture from resulting image tex = driver->addTexture(name.c_str(), img); @@ -350,14 +309,12 @@ u32 TextureSource::generateTexture(const std::string &name) img->drop(); } - /* - Add texture to caches (add NULL textures too) - */ + // Add texture to caches (add NULL textures too) MutexAutoLock lock(m_textureinfo_cache_mutex); u32 id = m_textureinfo_cache.size(); - TextureInfo ti(name, tex, std::move(source_image_names)); + TextureInfo ti{name, tex, std::move(source_image_names)}; m_textureinfo_cache.emplace_back(std::move(ti)); m_name_to_id[name] = id; @@ -368,11 +325,10 @@ std::string TextureSource::getTextureName(u32 id) { MutexAutoLock lock(m_textureinfo_cache_mutex); - if (id >= m_textureinfo_cache.size()) - { - errorstream<<"TextureSource::getTextureName(): id="<= m_textureinfo_cache.size()=" - <= m_textureinfo_cache.size()) { + errorstream << "TextureSource::getTextureName(): id=" << id + << " >= m_textureinfo_cache.size()=" << m_textureinfo_cache.size() + << std::endl; return ""; } @@ -384,7 +340,7 @@ video::ITexture* TextureSource::getTexture(u32 id) MutexAutoLock lock(m_textureinfo_cache_mutex); if (id >= m_textureinfo_cache.size()) - return NULL; + return nullptr; return m_textureinfo_cache[id].texture; } @@ -392,19 +348,16 @@ video::ITexture* TextureSource::getTexture(u32 id) video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id) { u32 actual_id = getTextureId(name); - if (id){ + if (id) *id = actual_id; - } + return getTexture(actual_id); } video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id) { // Avoid duplicating texture if it won't actually change - const bool filter_needed = - m_setting_mipmap || m_setting_trilinear_filter || - m_setting_bilinear_filter || m_setting_anisotropic_filter; - if (filter_needed && !name.empty()) + if (mesh_filter_needed && !name.empty()) return getTexture(name + "^[applyfiltersformesh", id); return getTexture(name, id); } @@ -415,7 +368,7 @@ Palette* TextureSource::getPalette(const std::string &name) sanity_check(std::this_thread::get_id() == m_main_thread); if (name.empty()) - return NULL; + return nullptr; auto it = m_palettes.find(name); if (it == m_palettes.end()) { @@ -425,7 +378,7 @@ Palette* TextureSource::getPalette(const std::string &name) if (!img) { warningstream << "TextureSource::getPalette(): palette \"" << name << "\" could not be loaded." << std::endl; - return NULL; + return nullptr; } Palette new_palette; u32 w = img->getDimension().Width; @@ -433,7 +386,7 @@ Palette* TextureSource::getPalette(const std::string &name) // Real area of the image u32 area = h * w; if (area == 0) - return NULL; + return nullptr; if (area > 256) { warningstream << "TextureSource::getPalette(): the specified" << " palette image \"" << name << "\" is larger than 256" @@ -462,17 +415,14 @@ Palette* TextureSource::getPalette(const std::string &name) } if (it != m_palettes.end()) return &((*it).second); - return NULL; + return nullptr; } void TextureSource::processQueue() { - /* - Fetch textures - */ + // Fetch textures // NOTE: process outstanding requests from all mesh generation threads - while (!m_get_texture_queue.empty()) - { + while (!m_get_texture_queue.empty()) { GetRequest request = m_get_texture_queue.pop(); @@ -484,7 +434,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im { sanity_check(std::this_thread::get_id() == m_main_thread); - m_imagesource.insertImage(name, img, true); + m_imagesource.insertSourceImage(name, img, true); m_source_image_existence.set(name, true); // now we need to check for any textures that need updating @@ -505,7 +455,8 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im } } if (affected > 0) - verbosestream << "TextureSource: inserting \"" << name << "\" caused rebuild of " << affected << " textures." << std::endl; + verbosestream << "TextureSource: inserting \"" << name << "\" caused rebuild of " + << affected << " textures." << std::endl; } void TextureSource::rebuildImagesAndTextures() @@ -516,7 +467,7 @@ void TextureSource::rebuildImagesAndTextures() sanity_check(driver); infostream << "TextureSource: recreating " << m_textureinfo_cache.size() - << " textures" << std::endl; + << " textures" << std::endl; // Recreate textures for (TextureInfo &ti : m_textureinfo_cache) { @@ -529,14 +480,15 @@ void TextureSource::rebuildImagesAndTextures() void TextureSource::rebuildTexture(video::IVideoDriver *driver, TextureInfo &ti) { assert(!ti.name.empty()); + sanity_check(std::this_thread::get_id() == m_main_thread); - // replaces the previous sourceImages - // shouldn't really need to be done, but can't hurt + // Replaces the previous sourceImages. + // Shouldn't really need to be done, but can't hurt. std::set source_image_names; video::IImage *img = m_imagesource.generateImage(ti.name, source_image_names); img = Align2Npot2(img, driver); // Create texture from resulting image - video::ITexture *t = NULL; + video::ITexture *t = nullptr; if (img) { t = driver->addTexture(ti.name.c_str(), img); guiScalingCache(io::path(ti.name.c_str()), driver, img); @@ -569,23 +521,22 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name) } return getTexture(fname_base); } - return NULL; + return nullptr; } video::SColor TextureSource::getTextureAverageColor(const std::string &name) { video::IVideoDriver *driver = RenderingEngine::get_video_driver(); - video::SColor c(0, 0, 0, 0); video::ITexture *texture = getTexture(name); if (!texture) - return c; + return {0, 0, 0, 0}; video::IImage *image = driver->createImage(texture, core::position2d(0, 0), texture->getOriginalSize()); if (!image) - return c; + return {0, 0, 0, 0}; - c = ImageSource::getImageAverageColor(*image); + video::SColor c = ImageSource::getImageAverageColor(*image); image->drop(); return c; @@ -604,7 +555,7 @@ video::ITexture *TextureSource::getShaderFlagsTexture(bool normalmap_present) video::IVideoDriver *driver = RenderingEngine::get_video_driver(); video::IImage *flags_image = driver->createImage( video::ECF_A8R8G8B8, core::dimension2d(1, 1)); - sanity_check(flags_image != NULL); + sanity_check(flags_image); video::SColor c(255, normalmap_present ? 255 : 0, 0, 0); flags_image->setPixel(0, 0, c); insertSourceImage(tname, flags_image);