Framebuffer Causing memory leak

Started by CodeBunny, June 01, 2011, 16:26:50

Previous topic - Next topic

CodeBunny

I'm using this code in conjunction with an AWTGLCanvas:

public static boolean drawTo(int target, int width, int height) // target = texture ID.
	{
		if(renderToTextureCapable())
		{
			IntBuffer buffer = ByteBuffer.allocateDirect(4).order(
					ByteOrder.nativeOrder()).asIntBuffer();
			
			EXTFramebufferObject.glGenFramebuffersEXT(buffer);
			
			int fbo =  buffer.get();
			
			EXTFramebufferObject.glBindFramebufferEXT(
					EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
					fbo);
			
			EXTFramebufferObject.glFramebufferTexture2DEXT(
					EXTFramebufferObject.GL_FRAMEBUFFER_EXT,
					EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, 
					GL11.GL_TEXTURE_2D, 
					target,
					0);

			checkFBO(fbo);

			GL11.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT);
			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
			GL11.glColor4f(1f, 1f, 1f, 1f);
			
			GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
			GL11.glViewport(0, 0, width, height);
			
			GL11.glMatrixMode(GL11.GL_PROJECTION);
			GL11.glPushMatrix();
			GL11.glLoadIdentity();
			GL11.glOrtho(0, width, 0, height, -1, 1);
			
			GL11.glMatrixMode(GL11.GL_MODELVIEW);
			GL11.glPushMatrix();
			GL11.glLoadIdentity();
			
			return true;
		}
		return false;
	}

	public static boolean finishDrawing()
	{
		if(renderToTextureCapable() && renderingToTexture())
		{
			GL11.glMatrixMode(GL11.GL_PROJECTION);
			GL11.glPopMatrix();
			
			GL11.glMatrixMode(GL11.GL_MODELVIEW);
			GL11.glPopMatrix();
			
			GL11.glPopAttrib();
			GL11.glPopAttrib();
			
			EXTFramebufferObject.glBindFramebufferEXT(
					EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
			return true;
		}
		return false;
	}

	public static void checkFBO(int FBOID)
	{
		int status = EXTFramebufferObject.glCheckFramebufferStatusEXT( 
				EXTFramebufferObject.GL_FRAMEBUFFER_EXT); 
		
		switch(status)
		{
			case EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT:
				break;
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID + ", " +
						"has caused a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMEN" +
						"T_EXT exception" );
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID
						+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_MISSI" +
								"NG_ATTACHMENT_EXT exception" );
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID
						+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DIMEN" +
								"SIONS_EXT exception" );
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID
						+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DRAW_" +
								"BUFFER_EXT exception" );
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID
						+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_FORMA" +
								"TS_EXT exception" );
			case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
				throw new RuntimeException( "FrameBuffer: " + FBOID
						+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_READ_" +
								"BUFFER_EXT exception" );
			default:
				throw new RuntimeException( "Unexpected reply from glCheckFr" +
						"amebufferStatusEXT: " + status );
		}
	}


On the AWTGLCanvas, I have an image that I render to and then display on the canvas. I render-to-texture every frame.

This causes a memory leak, where for some reason more and more page file memory starts being used. The rate of increase is significant - it's taken about 200 megs in 20-30 seconds.

Has anyone had this happen before?

spasi

It looks like you're creating a new FBO every frame. That would explain it.

CodeBunny


Fool Running

Quote from: CodeBunny on June 01, 2011, 20:38:23
How should I delete the FBO?
I would think it would be better and faster to just re-use the FBO you create.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

CodeBunny

Good point.

Thanks, this was kind of a dumb bug of mine but the advice helped a lot.