inefficient textures

I’m writing a program that creates many small textures (all 16 by 16 picels - it’s file icons). Number of textures is about 50. It feels like “fragmentation of texture memory” happens. When program only starts it works very fast and nearly all
50 textures already exist. But during the work certain textures are deleted and others are created, total number is always approximately the same. Program works slower and slower, though initially that amount of textures fitted in memory. I use texture objects. It seems like fragmentation? Maybe somehow to “repack” texture memory?

50x16x16x4=51200, approx 50kB of data - it’s small, memory fragmentation should not cause slowdown (unless You are allocating some other big objects between small images).
I think You have bug somewhere else.
To avoid fragmentation You can use texture atlas - pack many small textures into one big texture, and choose correct images by modifying your texture coordinates.

Your problem is that you dynamically create and delete textures.
You should rather reuse the same texture objects and just replace the content with glTexSubImage. It is important to use sub image function not glTexImage as it is much more lightweight. Actually glTexImage would take roughly that time as creating a completely new texture.

You’re not totally deleting the texture handles and recreating them are you? If all your textures are 16x16, that’s wasteful. When you “free” a texture, put the texture handle on a free queue. When you need a new texture, grab the last texture handle off the free queue (or create a new texture if empty) and upload new texels to it.

Also ensure you are using glTexImage2D only once just after creating the texture handle to allocate space for the texels (can provide NULL pointer to just allocate and not fill). Then all subsequent updates of the texture with new texture data should use glTexSubImage2D, which will just change the texels and not force a free/realloc of the texel block.

Also, for even better memory organization, if you know in advance the max num of 16x16 textures, consider packing them into a single texture array (or texture atlas). Advantage of the former is you don’t need to worry about cross-map filtering, though if you’re rendering with NEAREST filtering, you likely don’t care if you’re careful with texcoords. Texture arrays also means you don’t have to play any s,t texcoord compute games to get the right texture. Just use 0…1 and be happy. Also with texture arrays you can upload new data for all subtextures (texture “slices”) with one glTexSubImage3D call.

Note also that there are faster/more efficient ways to upload new texel data, but for now you’re just trying to get something to work halfway decent so I’ll skip that.

Also, for even better memory organization, if you know in advance the max num of 16x16 textures, consider packing them into a single texture array (or texture atlas).

For textures as small as 16x16, I’d even suggest manually packing them in a larger texture and just passing the proper texture coordinates as needed. There’s some chance that textures that small would waste some video memory space. If, for example, textures were allocated in 4K chunks, a 16x16x4bpp would only be 1K, thus wasting 3K of space.

Thank you to all for such profound discussion! I’ll try proposed techniques and answer a bit later.

A few things were made. Small textures are packed into a bigger texture, its texture object is created only once and used until user
exits. Redundant calls of glBindTexture were eliminated. As for texture arrays, I didn’t use them ever (would be grateful for link/tutorial).
Performance is much better now, thanks all again.