Cocos2dx - Clearing specific textures from the cache - c++

I am getting crashes on iPhone 4s due to "memory pressure." My game is set up like this:
Main scene sprite sheet that always stays in memory.
Individual game scene levels load from individual textures (not sprite sheets).
When a level is done and we return to the main scene, I would like those cached game scene textures to get dumped. What ends up happening is that when you play through 3-4 levels, it crashes as it runs out of memory as it never releases this memory after a level. I don't want the level textures to be cached past the lifespan of the game scene. When returning to the main scene, it needs to release this memory.
I have tried removing all of the game scene children which does nothing to memory. I have tried looking for a specific way to clear just these textures I have loaded in this game scene from the cache.
Any suggestions?

Are you using cocos2d v2? You probably have memory leaks since unused textures are removed when necessary. Try profiling your app to see if you have leaks and where they are at.
You also can call these methods yourself at the appropriate time, although I doubt you'd have to:
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
But again what you describe sounds more like memory leaks. When your application receives a memory warning the cached data is purged. During this purge the remove unused textures method is called on the texture cache, among other things. If you have 3/4 levels of data still lurking around long after you've exited those scenes, that sounds like a memory leak.
I'm assuming this only happens after visiting multiple scenes and the problem just isn't that your 4th scene is simply trying to load more data than the device can handle.

You can remove specific textures calling:
In cocos2D-x v3.x :
Director::getInstance()->getTextureCache()->removeTextureForKey(ImageKeyName)
In cocos2D-x v2.x :
CCTextureCache::sharedTextureCache()->removeTextureForKey(ImageKeyName);
Where ImageKeyName is just the path of the image (the same you used to load the texture)

Related

SDL2 trash cleanup for texture clips

I am writing an SDL2 C++ program that creates clips from large sprite sheets and has a system loop to render them. So, only a few textures but many, many derivative clips. As I understand it, these are the facts
the advantage using clips is that copying a portion of the larger original texture is more efficient
loading the texture and clipping is best done before the system loop,
memory leaks prevention/trash cleanup dictates you destroy and recreate textures with every loop cycle,
after the loop ends, you should destroy everything: windows, renderer, and textures
Obliterating everything I understand. But how does the cyclical cleanup within the loop work with clips, and what should go before, within and after my loop? Am I supposed to be destroying and recreating all the clips once every cycle, every time I render present a new batch onscreen, or cleanup after each individual clip? Am I supposed to destroy the original textures as well and then recreate the clips?

OpenSceneGraph memory usage when resetting scene

I have spent a great deal of time trying to figure out OSG's memory management.
I have a scene graph with several children (actually a LOD based on an octree).
However, when I need to reset my scene (I just want to wipe ALL nodes from de scene and also wipe the memory), I use
// Clear main osg::Group root node
m_rootNode->removeChildren(0, m_rootNode->getNumChildren());
m_rootNode->dirtyBound();
// Clear Main view scene data from osg::Viewer
m_viewer->setSceneData(nullptr);
BEFORE I do this, I check all my nodes with a NodeVisitor pattern, and found out that ALL my nodes have reference count of 1, i.e, after clearing them from the scene, I expect my memory to be freed. However, this does not happen: my scene is actually reset, all the nodes disappear from the viewer, but the memory remains occupied.
Nonetheless, when I load another scene to my viewer, the memory is rewritten somehow (i.e., the memory usage does not increase, hence there is no memory leak, but used memory is always the same)
I can't have this behaviour, as I need to closely control memory usage. How can I do this?
Looks like OSG keeps cached instances of your data, either as CPU-side or GPU-side objects.
You could have a look at osgDB's options to disable caching in first place (CACHE_NONE, CACHE_ALL & ~CACHE_ARCHIVES), but this can actually increase your memory consumption as data may not be re-used and re-loaded multiple times.
You could instruct osg::Texture to free the CPU-side texture data after it was uploaded to OpenGL - in case you don't need it any more. This can be done conveniently via the osgUtil::Optimizer::TextureVisitor which you would want to set up to change the AutoUnref for each texture to true. I think, running osgUtil::Optimizer with the OPTIMIZE_TEXTURE_SETTINGS achieves the same effect.
Then, after closing down your scene, as you did in your Question's code, you could explicitly instruct OSG's database pager to wipe its caches:
for( osgViewer::View v in AllYourViews )
{
v->getDatabasePager()->cancel();
v->getDatabasePager()->clear();
}
To finally get rid of all pre-allocated GPU-side objects and their CPU-side representations, you would need to destroy your views and GLContext's.

SDL Textures and CPU\Memory issues

I developed a game with SDL2.00 and c++. I seemed to be having memory and CPU issues. CPU usage goes up to 40% and memory usage goes up by 5mg a second.
So I think the reason is the way Im handling Textures\Sprites.
My question is should I create a different/new sprite/texture for every instance ?
For example, I have a class called Enemy which contains all the variable and methods related to enemy monsters such as HP, damage, location , image(Texture) etc. This class contains its own texture to be rendered onto the renderer.
Is this the right way? Or should I create a Sprite/Texture for all the images before hand and render them as needed?
and I'm wondering if this will render two different images onto the renderer:
RenderCopy(renderer, image);
image->SetPosition(X,Y);
RenderCopy(renderer,image);
or is it going to move the sprite to the new position?
I think my issues are caused my overloading the renderer and/or having too many textures being loaded.
Let me know what you think .
OpenGL is not a scene graph. It's a drawing API. So everytime you're allocating a new texture you're creating a new data object that consumes memory. You should reuse and share resources where possible.
My question is should I create a different/new sprite/texture for
every instance ?
No, not unless every instance of the sprite uses different textures, otherwise you should reuse them, ie only load them once and store a pointer to the texture the sprite uses.
and I'm wondering if this will render two different images onto the
renderer:
RenderCopy(renderer, image);
image->SetPosition(X,Y);
RenderCopy(renderer,image);
or is it going to move the sprite to the new position?
This will copy the image twice. First at the old position and then at the new. What you will get is a trailing image. You should probably either clear the previous position or render the background at that position (or whatever should be there).

Using CCSpriteFrameCache without CCSpriteBatchNode

I want to know if there is any benefiting caching a sprite sheet and accessing the sprite by frame without using the CCSpriteBatchNode?
In some parts of my game the sprite batch node is useful because there is a lot on the screen, however on another part its not, because there are just a few things, and there are requirements for layers so CCSpriteBatchNode wouldn't be useful. However, for the sake of consistency I would like to use Sprite Sheets for all my sprites, and so was beginning to wonder if I would still receive any benefit from it? (Or worse that it could some how be slower...)
There is defiantly a benefit to putting all your sprites into a texture atlas or sprite sheet as you called it. Textures are stored in memory in power of 2 dimensions. So if you have a sprite that is 129px by 132px it is stored in memory as 256px by 256px which is the nearest power of 2 size. If you have many sprites that is quite a lot of extra memory used up.
By using a texture atlas you only have one texture in memory and then it pulls the pieces out of it that it needs for your sprites. These sprites can be whatever size you want without having to worry about power of 2 sizes.
You can read more details about it on this tutorial
http://www.raywenderlich.com/2361/how-to-create-and-optimize-sprite-sheets-in-cocos2d-with-texture-packer-and-pixel-formats

Release all texture memory

I load my animated character with a huge texture this way:
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:#"MyFile.plist"];
And later, when I am no longer using the character, I release memory using:
[[CCSpriteFrameCache sharedSpriteFrameCache]removeSpriteFramesFromFile:#"MyFile.plist"];
And also:
[[CCTextureCache sharedTextureCache]removeTextureForKey:#"MyFile.png"];
Just to be sure.
I do that because the texture it uses consumes a lot of memory, so I make sure I dispose of it so my app doesn't crash. Is the above code correct?
Anyway, here is the actual problem: I eventually load my character again, and dispose of it again. Eventually, after a couple revives and kills, the app crashes. The log says nothing about it, so I can just suspect that it was due to memory - that's why I assumed that I wasn't disposing the texture properly.
I do need to create and dispose the character's texture. I can't afford to have it preloaded in the game.
I usually use the brute force approach as follows:
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
at specific moments in the game flow. It is not too too costly to have coco scan its arrays, in the grand scheme of things. As in your case, in my current game i must load and ditch. CCTextureCache has CCLOG'ing that permit you to witness whether the removal actually occurs when you expect it, or close to it (autorelease has its quirks). If not, you are probably retaining some handle to the texture somewhere, a sprite, batch node, an CCAnimation, or an action.
Did you also try purgeSharedTextureCache as noted here:
http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_c_texture_cache.html#ac673f75cd5418bdcecf1fb8717a40345
You can see it in work also in your App Delegate methods that release textures during memory warnings.