Memory leak problem in openGL (*edited with less code)

Problems with Canvas, OpenGL, etc...

Memory leak problem in openGL (*edited with less code)

Postby Mockarutan » Sun Jan 16, 2011 11:13 pm

Hi, i have just started programming openGL on android. I normally program c++, so I'm i bit uncomfortable in java and it's GC. So i have just written a simple little helping class to draw with openGL and I checked the logging in logcat and discovered some form of memory leak, the thing is that my code is simple but i have no idea what the problem is because i'm use to new/delete. So, can somebody tell me way this is happening?

logcat message:

Code: Select all
D/dalvikvm(13789): GC_FOR_MALLOC freed 7334 objects / 524240 bytes in 61 ms


code:

package se.mockarutan.opengltest;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Date;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.util.Log;

public class GraphicsRenderer implements GLSurfaceView.Renderer {

private static final String TAG = "GraphicsRenderer";

//temp variables
private float mQuadOffset = 0;
private boolean mVertexBufferInited= false;

private static float MAXQUADS = 200;

private Date mLastTime;

Context mResContext;
int mMegaTexture;

private float mMTSize;

private float mR = 0.5f,
mG = 0.5f,
mB = 0.5f;

private int mWidth,
mHeight;

int mRes;

private boolean mContextIsSet;

private ShortBuffer mIndexBuffer;

// a raw buffer to hold the vertices
private FloatBuffer mVertexBuffer;
private FloatBuffer mTextureBuffer;

private short[] mIndicesArray = {1, 0, 2, 3};
private int mNumbOfQuads;

public GraphicsRenderer(int width, int height) {
// TODO Auto-generated constructor stub
mWidth = width;
mHeight = height;
mContextIsSet = false;
mNumbOfQuads = 0;
mLastTime = new Date();
}

@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
for(float i = -200.0f; i < 200.0f; i += 4.0f)
{
draw(0, 0, 256, 256, (i + mQuadOffset ) / 256.0f, (i + mQuadOffset ) / 256.0f);
}

mQuadOffset += 1.0f;

if(mQuadOffset > 300.0f)
mQuadOffset = 0.0f;

mVertexBufferInited = true;

mVertexBuffer.position(0);
mIndexBuffer.position(0);
mTextureBuffer.position(0);

gl.glClearColor(mR, mG, mB, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

// define the vertices we want to draw
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);

gl.glBindTexture(GL10.GL_TEXTURE_2D, mMegaTexture);

gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4 * mNumbOfQuads, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);

Date newTime = new Date();
Log.i(TAG, Long.toString(1000 / (newTime.getTime() - mLastTime.getTime())));
mLastTime = newTime;

mNumbOfQuads = 0;

mVertexBuffer.clear();

mVertexBuffer.position(0);
mIndexBuffer.position(0);
mTextureBuffer.position(0);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
mWidth = width;
mHeight = height;
gl.glViewport(0, 0, width, height);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
mMegaTexture = loadTexture(gl, mResContext, mMegaTexture);

gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio = (float)mWidth / (float)mHeight;
GLU.gluPerspective(gl, 66.67f, ratio, 0.1f, 512.0f);
gl.glViewport(0, 0, (int) mWidth, (int) mHeight);

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

gl.glEnable(GL10.GL_CULL_FACE);
gl.glFrontFace(GL10.GL_CCW);
gl.glCullFace(GL10.GL_BACK);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glClearColor(mR, mG, mB, 1.0f);
initQuad();
}

public void setColor(float r, float g, float b)
{
mR = r;
mG = g;
mB = b;
}

private void initQuad()
{
ByteBuffer vbb = ByteBuffer.allocateDirect((int)MAXQUADS * 4 * 3 * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();

// short has 2 bytes
ByteBuffer ibb = ByteBuffer.allocateDirect((int)MAXQUADS * 4 * 2);
ibb.order(ByteOrder.nativeOrder());
mIndexBuffer = ibb.asShortBuffer();

ByteBuffer tbb = ByteBuffer.allocateDirect((int)MAXQUADS * 4 * 2 * 4);
tbb.order(ByteOrder.nativeOrder());
mTextureBuffer = tbb.asFloatBuffer();
}

// Get a new texture id:
private static int newTextureID(GL10 gl) {
int[] temp = new int[1];
gl.glGenTextures(1, temp, 0);
return temp[0];
}

private int loadTexture(GL10 gl, Context context, int resource) {

int id = newTextureID(gl);

Matrix flip = new Matrix();
flip.postScale(1f, -1f);

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = false;

Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource, opts);
Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), flip, true);
temp.recycle();

gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

for(int level=0, height = bmp.getHeight(), width = bmp.getWidth(); true; level++) {
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bmp, 0);

if(height==1 && width==1) break;

width >>= 1; height >>= 1;
if(width<1) width = 1;
if(height<1) height = 1;

Bitmap bmp2 = Bitmap.createScaledBitmap(bmp, width, height, true);
bmp.recycle();
bmp = bmp2;
}

bmp.recycle();

return id;
}

public boolean draw(int x, int y, int w, int h, float xPos, float yPos)
{
if(mContextIsSet)
{
float tempX = (float)x / mMTSize;
float tempY = (float)y / mMTSize;
float tempH = (float)h / mMTSize;
float tempW = (float)w / mMTSize;
float[] coords = {
xPos, yPos, 0f, //0 bottom left
xPos, yPos + tempH, 0f, //1 top left
xPos + tempW, yPos + tempH, 0f, //2 top right
xPos + tempW, yPos, 0f //3 bottom right
};

mVertexBuffer.put(coords);

if(!mVertexBufferInited)
{

float[] texCoords = {
tempX, tempY,
tempX, tempY + tempH,
tempX + tempW, tempY + tempH,
tempX + tempW, tempY
};

short []indecis = {(short) (mIndicesArray[0] + (4 * mNumbOfQuads)),
(short) (mIndicesArray[1] + (4 * mNumbOfQuads)),
(short) (mIndicesArray[2] + (4 * mNumbOfQuads)),
(short) (mIndicesArray[3] + (4 * mNumbOfQuads))};

mIndexBuffer.put(indecis);
mTextureBuffer.put(texCoords);
}

mNumbOfQuads++;

return true;
}
return false;
}

public void setContextAndRes(Context context, int res, int size)
{
// TODO Auto-generated method stub
mResContext = context;
mMegaTexture = res;
mMTSize = size;

mContextIsSet = true;
}

}
Mockarutan
Freshman
Freshman
 
Posts: 3
Joined: Thu Jan 06, 2011 3:29 pm

Top

Re: Memory leak problem in openGL (*edited with less code)

Postby iBog » Thu Feb 10, 2011 10:33 am

iBog
Once Poster
Once Poster
 
Posts: 1
Joined: Mon Feb 01, 2010 11:32 am

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 3 guests