Hybrid View

Attaching texture to framebuffer for reading causes slow rendering later

Some context: I have a project which creates thumbnails of textures when they are loaded to be used in the GUI. This is achieved by attaching the texture to a framebuffer and using glReadPixels. It works perfectly, but: If a texture from which a thumbnail was generated is then used later on during rendering, the frame rate drops dramatically. I got rid of all the relevant code except for the part that attaches the texture to the framebuffer, and the same slow-down persists.

So the problem boils down to: I call the following code during initialization, after the texture with name "texID" is created and no longer bound, and after an FBO is bound:

Now I render a bunch of stuff, none of which uses "texID", at about 95 fps. If instead I render the stuff using the texture "texID", the frame rate drops to about 50. If I render the stuff using the texture "texID", but do not do the code snippet above, then it renders at about 95 fps.

Am I missing something obvious?

Extra info: The project is written in Java, using JOGL 2.0, running on Ubuntu 10.04 LTS; graphics card is AMD Radeon HD 6700, Catalyst version 11.12.

Thanks for the suggestion; I did try gl.glReadBuffer(GL2.GL_NONE) before and/or after the "detach texture" line. It has no observable effect.

Also, I tried running this project in Windows 7 (with Catalyst version 12.3), and the same thing happens--using a previously-attached texture yields about 50 fps, and using a different texture yields about 180 fps (for some reason running this project in Windows has always gotten much higher frame rates--I haven't tried figuring out why and anyway it's probably unrelated to this issue--but it's interesting that both drop to around the same frame rate).

It a bit difficult to root the performance problem but from what you describe you may have this situation:

1. Render to texture 0
2. Switch to another FBO and readpixels from texture 0

The (2) will have to flush the previous FBO which means that the readpixels will stop and wait until the rendering to the texture 0 is finished. A good way to avoid this is to put other computation intensive tasks between (1) and (2).

It a bit difficult to root the performance problem but from what you describe you may have this situation:

1. Render to texture 0
2. Switch to another FBO and readpixels from texture 0

The (2) will have to flush the previous FBO which means that the readpixels will stop and wait until the rendering to the texture 0 is finished. A good way to avoid this is to put other computation intensive tasks between (1) and (2).

Hope this is relevant and that will help you.

Hmm, I'm still thinking about this answer--it doesn't quite match up with what I'm doing, but maybe you are on to something. Just to be clear, I'm never rendering to a texture which is attached to an FBO for reading. Also, attaching the texture to the FBO happens only initially, and is never done again.

Try using two FBOs: one with the normal texture attached and one with a renderbuffer of the same format attached. Don't call glReadPixels on the texture-FBO. Instead, use glBlitFramebuffer to blit the image into the renderbuffer, then use glReadpixels on that instead.