(android - Opengl-es) GlTexSubImage2D Hiccup The First Time Called After The First Draw
i have implemented a tile based layer in my game, but after the first time that it was drawn, just the first time i try to update it (to add tiny decals, like blood splats, craters, etc. thingies that are added to the map and that i don't want to draw separately every loop) i have a huge hiccup of 3~ seconds.
after some test, i have find the only call that hangs.
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, x, y, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer);
the decal is really tiny(32 * 32 pixel), there is no opengl error after this call, and i really don't get the whole thing (i mean.....the creation of the whole tile layer actually takes much lesser than 1 second, and is done by a thousand of glTexSubImage2D command on a large blank texture.....3 seconds is pretty huge).
i already have a workaround (a "fake" update just before the splash screen goes off) but i really want to understand this odd(for me, at least) behaviour.. :|
(i'm deeply sorry for my enGrish, i hope that's understandable)
METHOD:
public static void replaceSubImg(GL10 gl, int hwdId , int x,int y,int width, int height,Buffer pixelBuffer) {
g开发者_运维技巧l.glFinish();
gl.glBindTexture(GL10.GL_TEXTURE_2D, hwdId);
long time = System.currentTimeMillis();
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, x, y, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer);
Log.d("testApps","openglUtil,@@@@@@@@@@@@@@@@@@@@@@@@@ subImg replaced in "+(System.currentTimeMillis()-time)+" ms");
}
LOG:
DEBUG/testApps(3809): openglUtil,@@@@@@@@@@@@@@@@@@@@@@@@@ subImg replaced in 2811 ms
DEBUG/testApps(3809): openglUtil,@@@@@@@@@@@@@@@@@@@@@@@@@ subImg replaced in 1 ms(this is the 2d run)
after a ton of tests, i have isolated the whole thing and this looks like just a bug in the implementation of the opengl in the last cyanogenmod(or just gingerbread, i don't have tested this yet....) :
cyanogen(gingerbread, 7rc2) :
- uploading the texture, ~1ms,
- altering the texture, ~1ms,
- drawin the texture, ~1ms,
- any edit, even 1px for 1px, for every texture,a huge delay( depending on how much is big the texture), in my case ~3000ms
- any further edit,regardless of the size, back to ~1ms
on froyo ( stock, frf91) :
- uploading the texture, ~1ms,
- altering the texture, ~1ms
- drawing the texture, ~1ms
- any edit, even 1px for 1px, for every texture, a little delay( depending on how much is big the texture), in my case ~80ms
- any further edit,regardless of the size, back to ~0ms
there is anyway a little delay, but understandable this time.
I'm not sure if I'm understanding you correctly, but:
Do you have gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, x, y, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer);
code in every iteration? That call is pretty expensive and it shouldn't be iterated every frame (it's like you're creating the texture every time you draw).
You need to load your textures in the onSurfaceCreated
callback, store your GL pointer
and assign that pointer to a Texture
object (an object that just holds the pointer into OpenGL
memory).
After that you can just bind it using glBindTexture(GL10.GL_TEXTURE_2D, yourPointer);
.
OpenGL instructions can be pipelined and may not be executed immediately. It seems likely that the glTexSubImage2D
call itself is fast, but has to wait for some other operation to complete.
To figure this out, it might be instructive to call glFinish
after some major operations, and see when that takes a long time. You may find that the actual time is spent elsewhere... for example, in a thousand glTexSubImage2D
calls?
精彩评论