Attempting to iterate through a large directory of images and preload them all causes SDL to run out of memory

I’ve got a bit of demo code available. But the basic jist is that if I attempt to load a large directory of 900+ images, SDL will run “out of memory” eventually at some point while it’s iterating. However if I destroy the texture after creating it, everything works fine.

Was wondering if someone knew what might be causing this? IS there some texture cap that I’m unaware of? thanks!

std::vector<SDL_Texture*> textures;

for (auto folder : folders)
{
	std::vector<std::string> filesToLoad;

	for (auto& entry : std::filesystem::recursive_directory_iterator(this->getAssetPath() + folder))
	{
		auto name = entry.path().stem().string();
		auto extension = entry.path().extension().string();

		if (extension == ".png")
		{
			auto path = entry.path();
			if (this->textures.count(path) == 0)
			{
				filesToLoad.push_back(path.string());
			}
		}
	}

	for (auto strPath : filesToLoad)
	{
		auto surface = IMG_Load(strPath.c_str());
		if (surface)
		{
			auto renderer = GraphClass::Instance()->getRenderer();
			auto texture = SDL_CreateTextureFromSurface(renderer, surface);
			SDL_FreeSurface(surface);
			if (texture)
			{
				//SDL_DestroyTexture(texture); //doesn't cause a crash
				textures.push_back(texture); //causes a crash
			}
			else
			{
				printf(SDL_GetError() + '\n');
			}
		}
		else
		{
			printf(SDL_GetError() + '\n');
		}
	}
}

Textures are stored in GPU memory so there is inevitably a limit. How big are your images?

I have 3 GB of GPU memory, and the assets of all my folders is around 300 MBs. That being said, some of the images are around the size of 3000x3000 pixels.

You would probably be able to store only about 80 textures of that size. Even at 1000x1000 pixels you would still not be able to store all 900.

You could possibly store them all as surfaces, because they reside in main memory, and then only convert to textures as required.

Interesting, I’ll give that a shot to see if that works out. One of the weird things, is that if I switch to loading textures into the assets manager on demand rather than preloading all of them, it seems to work fine.

Even if these are JPG or PNG files, they will live on the GPU uncompressed, at probably 4 bytes per pixel…so a 3000x3000 image is around 34.3 megabytes of space, even if it’s significantly less as a JPG file.

Can we add SDL_SurfaceRamSize() and SDL_TextureRamSize() to help us manage memory usage? I’ve often needed something like this.