1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Try to reuse texture objects in TextureSource::rebuildTexture()

This commit is contained in:
sfan5 2025-04-20 11:20:11 +02:00
parent b841c23701
commit 9cb78f2dc5
2 changed files with 30 additions and 12 deletions

View file

@ -191,8 +191,7 @@ TextureSource::TextureSource()
TextureSource::~TextureSource() TextureSource::~TextureSource()
{ {
video::IVideoDriver *driver = RenderingEngine::get_video_driver(); video::IVideoDriver *driver = RenderingEngine::get_video_driver();
u32 textures_before = driver->getTextureCount();
unsigned int textures_before = driver->getTextureCount();
for (const auto &iter : m_textureinfo_cache) { for (const auto &iter : m_textureinfo_cache) {
// cleanup texture // cleanup texture
@ -474,22 +473,37 @@ void TextureSource::rebuildTexture(video::IVideoDriver *driver, TextureInfo &ti)
assert(!ti.name.empty()); assert(!ti.name.empty());
sanity_check(std::this_thread::get_id() == m_main_thread); 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.
std::set<std::string> source_image_names; std::set<std::string> source_image_names;
video::IImage *img = m_imagesource.generateImage(ti.name, source_image_names); video::IImage *img = m_imagesource.generateImage(ti.name, source_image_names);
// Create texture from resulting image // Create texture from resulting image
video::ITexture *t = nullptr; video::ITexture *t = nullptr, *t_old = ti.texture;
if (img) { if (!img) {
// new texture becomes null
} else if (t_old && t_old->getColorFormat() == img->getColorFormat() && t_old->getSize() == img->getDimension()) {
// can replace texture in-place
std::swap(t, t_old);
void *ptr = t->lock(video::ETLM_WRITE_ONLY);
if (ptr) {
memcpy(ptr, img->getData(), img->getImageDataSizeInBytes());
t->unlock();
t->regenerateMipMapLevels();
} else {
warningstream << "TextureSource::rebuildTexture(): lock failed for \""
<< ti.name << "\"" << std::endl;
}
} else {
// create new one
t = driver->addTexture(ti.name.c_str(), img); t = driver->addTexture(ti.name.c_str(), img);
guiScalingCache(io::path(ti.name.c_str()), driver, img);
img->drop();
} }
video::ITexture *t_old = ti.texture; if (img)
// Replace texture guiScalingCache(io::path(ti.name.c_str()), driver, img);
// Replace texture info
if (img)
img->drop();
ti.texture = t; ti.texture = t;
ti.sourceImages = std::move(source_image_names); ti.sourceImages = std::move(source_image_names);
if (t_old) if (t_old)
m_texture_trash.push_back(t_old); m_texture_trash.push_back(t_old);
} }

View file

@ -86,7 +86,11 @@ public:
*/ */
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0; virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
/// @brief rebuilds all textures (in case-source images have changed) /**
* Rebuilds all textures (in case-source images have changed)
* @note This won't invalidate old ITexture's, but you have to retrieve them
* again to see changes.
*/
virtual void rebuildImagesAndTextures()=0; virtual void rebuildImagesAndTextures()=0;
}; };