Hi, i’m using GLProgramState on many sprites .i tried to replace the scene but some how the memory keep getting high each time i replace the scene i follow the code and it turn that GLProgramState is the problem .
So how can i delete the GLProgramState or fix this issue .
bool Effect::initGLProgramState(const std::string &fragmentFilename)
{
auto fileUtiles = FileUtils::getInstance();
auto fragmentFullPath = fileUtiles->fullPathForFilename(fragmentFilename);
auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath);
auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str());
_glprogramstate = (glprogram == nullptr ? nullptr : GLProgramState::getOrCreateWithGLProgram(glprogram));
CC_SAFE_RETAIN(_glprogramstate);
return _glprogramstate != nullptr;
}
Effect::~Effect()
{
CC_SAFE_RELEASE_NULL(_glprogramstate);
}
Was the Effect’s destructor called at all? Log/debug the glProgramState’s ref count etc…
Effect::~Effect()
{
CC_SAFE_RELEASE_NULL(_glprogramstate);
}
yes was called .
i tried to do this .
CCLOG("count=%i", (int) _glprogramstate->getUniformCount());
CC_SAFE_RELEASE(_glprogramstate);
CCLOG("count2=%i", (int) _glprogramstate->getUniformCount());
log is the same for count and count2
What was the reference count before the CC_SAFE_RELEASE_NULL is called?
No not the uniform count … I’m talking about the node’s reference count getReferenceCount ?
CCLOG("count=%i", (int) _glprogramstate->getReferenceCount());
CC_SAFE_RELEASE(_glprogramstate);
CCLOG("count2=%i", (int) _glprogramstate->getReferenceCount());
Log
count=3
count2=2
So your node object is still in memory because the retain/release pair wasn’t called correctly.
For every retain call you must have an equivalent release call.
The retain & release calls must be balanced. Otherwise the object will be still hanging around.
How many times do you called the Effect::initGLProgramState method?
Do you call CC_SAFE_RETAIN(_glprogramstate) anywhere else?
You’re leaking memory because CC_SAFE_RELEASE_NULL does a release and then sets _glprogramstate = nullptr. But object still has a count of 2.
I see two issues at a glance:
EffectSprite::initLamp calls retain TWICE. Also the release should be before the if, otherwise it’s pointless.
EffectSprite::~EffectSprite() calls delete on _effectHolder, it should only call release
Also I think the reason why the retain count is not 0 in ~Effect() is because the same GLProgramState is used for multiple EffectSprite instances (see EffectSprite::initLamp). Therefore all your sprites must be destroyed as well before GLProgramState will destruct via release().
I’d also recommend you make use of the GLProgram cache to minimise the number of GLPrograms you generate, and maximise batching.
i fixed the issues ,but same result ,i use GLProgramState for only 1 EffectSprite .
GLProgram cache is good idea i will test out later .
@almax27 Do you know why this code count=1 ? ive test only this code and it show count=1 (the _glprogramstate is not connecting to any thing ive add this code to empty HelloWorld project ) ?
auto fileUtiles = FileUtils::getInstance();
auto fragmentFullPath = fileUtiles->fullPathForFilename("shaders/pointlight.frag");
auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath);
auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str());
auto _glprogramstate = GLProgramState::create(glprogram);
_glprogramstate->retain();
_glprogramstate->release();
CCLOG("count=%i", (int) _glprogramstate->getReferenceCount());
GLProgramState::create() returns a new autoreleased object. It’s count will be decremented at the end of the cocos2d-x main loop. This allows you to retain it if you need it, or ignore it safely so it gets cleaned up later.