Question about texture cache

I am currently trying to figure out how to clear unused textures from the texture cache (in TextureManager) in a convenient way. Which steps do I need to take to ensure that textures are no longer in memory?



There seems to be two separate concepts concerning removing textures through the TextureManager, cleanup and release. Releasing a texture appears to simply remove it from the cache while cleaning it up frees its resources up at an OpenGL-level. Are textures which are no longer in the cache automatically cleaned up eventually, or is a specific call to registerForCleanup(…) required? In the former case, the simplest solution in my mind would be to simply make all references in the texture cache soft instead of hard references. Otherwise slightly more sophisticated routines would be necessary.



Thoughts anyone? Thanks!

Marg, see http://www.jmonkeyengine.com/jmeforum/index.php?topic=4094.0



and the newer http://www.jmonkeyengine.com/jmeforum/index.php?topic=4729.15

This area could indeed use a revisit.  Currently, all textures are registered with TextureManager for removal from the card when an opengl id is created for it.  TextureManager.doTextureCleanup() should be called before exiting your application to ensure the card releases the textures you were working with.



Aside from the above, deleting a texture from your card during application run is done via grabbing a TextureState and calling one of the delete methods.



The other methods are simply memory cache management.  We don't use weak references because we are caching for future use, not just managing working textures.  The original thought was to provide parameters to control how big the cache could get and do fallout but that was never finished.  (1.0 I'm hoping as that dovetails nicely with my 1.0 tasks)  I'm not sure we could do automatic deletion though because it seems (potentially) possible the card is still using a texture that Java is no longer managing.  I'm often wrong though :slight_smile:

Thanks! That clears things up a bit for me. I completely missed that there was a similarly themed discussion going on today. :wink: Sorry about that.



I suppose that for now I'll hack it with something like this then:

void freeTextures(Node[] freeTexturesFoundInThisNodeAndAllChildren, Node[] butNotIfFoundInThisNodeOrItsChildren)



If anyone else is interested in the code, let me know.

I ended up going the SoftReference route instead of the one I mentioned in the post above. I made a few adjustments to the TextureManager class so that when all references to a Texture object are gone except for the one in the cache and the jvm is in need of memory, it removes the texture from the cache and deletes it with TextureState.deleteTextureId(…). So far it seems to work very well, but yet another question has popped up.



In the TextureManager class, when a texture is reused, a high-level clone is made of the texture with the Texture.createSimpleClone() method, which is used instead of the actual existing texture. What is the reason for this? My method of garbage collecting the textures uses the same Texture object for all nodes instead, which so far seems to work well. Am I missing something?



<Edit>

Never mind… It's to be able to set different combine modes, etc. isn't it?

</Edit>

marqx said:

<Edit>
Never mind... It's to be able to set different combine modes, etc. isn't it?
</Edit>


Correct.  Also, please feel free to share your modifications. :)

Sure thing! I'll be out of town for a couple of days, but when I get back, I'll take a stab at rewriting it a bit for general use and not just for my specific usage.