Merge pull request #794 from dumganhar/gles20

issue #1056: Fixed a bug about double free memory and glDrawElements caused crash.
This commit is contained in:
James Chen 2012-03-21 07:00:57 -07:00
commit 7d073c4807
8 changed files with 47 additions and 45 deletions

View File

@ -70,7 +70,7 @@ public:
CCTextureAtlas();
virtual ~CCTextureAtlas();
char * description();
const char* description();
/** creates a TextureAtlas with an filename and with an initial capacity for Quads.
* The TextureAtlas capacity can be increased in runtime.

View File

@ -76,8 +76,8 @@ CCParticleSystemQuad::CCParticleSystemQuad()
CCParticleSystemQuad::~CCParticleSystemQuad()
{
CC_SAFE_DELETE_ARRAY(m_pQuads);
CC_SAFE_DELETE_ARRAY(m_pIndices);
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2, &m_pBuffersVBO[0]);
glDeleteVertexArrays(1, &m_uVAOname);
}
@ -301,7 +301,10 @@ void CCParticleSystemQuad::draw()
glBindVertexArray( m_uVAOname );
glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0);
/* FIXME: It will cause crash on some devices if the last parameter is zero.
I'm not familiar with opengles, but my change works. --By James Chen.
*/
glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, m_pIndices /*0*/);
glBindVertexArray( 0 );
@ -408,17 +411,15 @@ bool CCParticleSystemQuad::allocMemory()
CCAssert( ( !m_pQuads && !m_pIndices), "Memory already alloced");
CCAssert( !m_pBatchNode, "Memory should not be alloced when not using batchNode");
m_pQuads = new ccV3F_C4B_T2F_Quad[m_uTotalParticles];
m_pIndices = new GLushort[m_uTotalParticles * 6];
m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc(m_uTotalParticles * sizeof(ccV3F_C4B_T2F_Quad));
m_pIndices = (GLushort*)malloc(m_uTotalParticles * 6 * sizeof(GLushort));
if( !m_pQuads || !m_pIndices)
{
CCLOG("cocos2d: Particle system: not enough memory");
if( m_pQuads )
delete [] m_pQuads;
if(m_pIndices)
delete [] m_pIndices;
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
return false;
}
return true;
@ -448,8 +449,8 @@ void CCParticleSystemQuad::setBatchNode(CCParticleBatchNode * batchNode)
ccV3F_C4B_T2F_Quad *quad = &(batchQuads[m_uAtlasIndex] );
memcpy( quad, m_pQuads, m_uTotalParticles * sizeof(m_pQuads[0]) );
CC_SAFE_DELETE_ARRAY(m_pQuads);
CC_SAFE_DELETE_ARRAY(m_pIndices);
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2, &m_pBuffersVBO[0]);
glDeleteVertexArrays(1, &m_uVAOname);

View File

@ -87,7 +87,7 @@ void CCEGLView::create(int width, int height)
CCEGLView::~CCEGLView()
{
CC_SAFE_DELETE(m_pDelegate);
}
CCSize CCEGLView::getSize()

View File

@ -209,7 +209,6 @@ CCEGLView::~CCEGLView()
release();
CC_SAFE_DELETE(m_pSet);
CC_SAFE_DELETE(m_pTouch);
CC_SAFE_DELETE(m_pDelegate);
CC_SAFE_DELETE(m_pEGL);
CC_SAFE_DELETE(m_pKeypad);
}

View File

@ -121,7 +121,6 @@ CCEGLView::~CCEGLView()
{
IW_CALLSTACK("CCEGLView::~CCEGLView");
CC_SAFE_DELETE(m_pDelegate);
CC_SAFE_DELETE(m_pSet);
CC_SAFE_DELETE(m_pTouch);

View File

@ -120,8 +120,6 @@ CCEGLView::CCEGLView()
CCEGLView::~CCEGLView()
{
release();
CC_SAFE_DELETE(m_pDelegate);
}
void CCEGLView::initEGLFunctions()

View File

@ -433,7 +433,6 @@ void CCEGLView::release()
CC_SAFE_DELETE(m_pSet);
CC_SAFE_DELETE(m_pTouch);
CC_SAFE_DELETE(m_pDelegate);
CC_SAFE_DELETE(m_pEGL);
delete this;
}

View File

@ -32,7 +32,7 @@ THE SOFTWARE.
#include "ccGLStateCache.h"
// support
#include "CCTexture2D.h"
#include "CCString.h"
#include <stdlib.h>
//According to some tests GL_TRIANGLE_STRIP is slower, MUCH slower. Probably I'm doing something very wrong
@ -152,8 +152,8 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity
// Re-initialization is not allowed
CCAssert(m_pQuads == NULL && m_pIndices == NULL, "");
m_pQuads = (ccV3F_C4B_T2F_Quad*)calloc( sizeof(ccV3F_C4B_T2F_Quad) * m_uCapacity, 1 );
m_pIndices = (GLushort *)calloc( sizeof(GLushort) * m_uCapacity * 6, 1 );
m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc( m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) );
m_pIndices = (GLushort *)malloc( m_uCapacity * 6 * sizeof(GLushort) );
if( ! ( m_pQuads && m_pIndices) && m_uCapacity > 0) {
//CCLOG("cocos2d: CCTextureAtlas: not enough memory");
@ -174,11 +174,14 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity
return true;
}
char * CCTextureAtlas::description()
const char* CCTextureAtlas::description()
{
char *ret = new char[100];
sprintf(ret, "<CCTextureAtlas | totalQuads = %u>", m_uTotalQuads);
return ret;
char* pszDescription = (char*)malloc(100*sizeof(char));
sprintf(pszDescription, "<CCTextureAtlas | totalQuads = %u>", m_uTotalQuads);
CCString* pRet = new CCString(pszDescription);
pRet->autorelease();
CC_SAFE_FREE(pszDescription);
return pRet->c_str();
}
@ -413,29 +416,29 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity)
// when calling initWithTexture(fileName, 0) on bada device, calloc(0, 1) will fail and return NULL,
// so here must judge whether m_pQuads and m_pIndices is NULL.
if (m_pQuads == NULL)
tmpQuads = calloc(sizeof(m_pQuads[0]) * m_uCapacity, 1);
else
{
tmpQuads = malloc(m_uCapacity * sizeof(m_pQuads[0]));
}
else
{
tmpQuads = realloc( m_pQuads, sizeof(m_pQuads[0]) * m_uCapacity );
}
if (m_pIndices == NULL)
tmpIndices = calloc(sizeof(m_pIndices[0]) * m_uCapacity * 6, 1);
else
{
tmpIndices = malloc( m_uCapacity * 6 * sizeof(m_pIndices[0]));
}
else
{
tmpIndices = realloc( m_pIndices, sizeof(m_pIndices[0]) * m_uCapacity * 6 );
}
if( ! ( tmpQuads && tmpIndices) ) {
//CCLOG("cocos2d: CCTextureAtlas: not enough memory");
if( tmpQuads )
free(tmpQuads);
else
free(m_pQuads);
if( tmpIndices )
free(tmpIndices);
else
free(m_pIndices);
m_pQuads = NULL;
m_pIndices = NULL;
CCLOG("cocos2d: CCTextureAtlas: not enough memory");
CC_SAFE_FREE(tmpQuads);
CC_SAFE_FREE(tmpIndices);
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
m_uCapacity = m_uTotalQuads = 0;
return false;
}
@ -539,10 +542,13 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
glBindVertexArray( m_uVAOname );
/* FIXME: Because start always is zero, the result of (start*6*sizeof(m_pIndices[0])) will always be zero too. And crash will appear on some devices.
I'm not familiar with opengles, but my change works. --By James Chen.
*/
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (m_pIndices)/*(start*6*sizeof(m_pIndices[0]))*/ );
#else
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (m_pIndices)/*(start*6*sizeof(m_pIndices[0]))*/ );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP