shelll
shelll

Reputation: 3383

How to load OpenGL ES textures with almost no visible FPS drop?

I have around 2 GiB of textures (all are 256x256 tiles) in uncompressed RGBA 8888 format (the RGB 565 texture format is not an option, because there are lots smooth gradients and shades of gray, which have green tint with 565 format). So I load them on demand, when they should become visible and delete the old ones. The problem is, that there is an annoying FPS drop when I upload them OpenGL. Currently using OpenGL ES 1.1.

I decode the textures in a separate thread (i.e. BitmapFactory.decodeStream(...)) and then send the Bitmap to GL thread and upload it as a texture. When this happens the GL thread is sometimes slowed-down a bit for this upload. I measured the texture upload time and mostly it varys from 1-8ms, in average it is ~2ms. But from time-to-time it is 40-70ms. What can cause this drop?

I also generate mipmaps on the GPU (disabling mipmaps does not affect this behaviour) and here are all the texture parameters:

GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_MIN_FILTER, GLES11.GL_LINEAR_MIPMAP_NEAREST);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_MAG_FILTER, GLES11.GL_LINEAR);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_WRAP_S, GLES11.GL_CLAMP_TO_EDGE);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_WRAP_T, GLES11.GL_CLAMP_TO_EDGE);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_GENERATE_MIPMAP, GLES11.GL_TRUE);
GLES11.glTexEnvx(GLES11.GL_TEXTURE_ENV, GLES11.GL_TEXTURE_ENV_MODE, GLES11.GL_MODULATE);

GLUtils.texImage2D(GLES11.GL_TEXTURE_2D, 0, GLES11.GL_RGBA, bmp, 0);

How can I do this better? E.g. how are Open GL video players done, when they need to load and display many frames per second? Or current web browser which render pages as tiles? Is EGL_image a good option worth looking at? Will be OpenGL ES 2.0 different?

EDIT: The slow down of loading was because of GC-ing on the GL thread.

Upvotes: 2

Views: 1948

Answers (2)

Rodja
Rodja

Reputation: 8091

In addition to making sure the GC does not kick in, you could do all the bitmap generation and texture upload on a separate thread as described in my answer to a similar question: Threading textures load process for android opengl game

This would prevent you from small frame drops when the upload itself takes to long.

Upvotes: 1

shelll
shelll

Reputation: 3383

Finally I solved it, but not with native code, nor with EGL_image, but thanks to this video. Fortunatelly I had almost all textures in 256x256 and I am targeting Android 3.2 and newer, so for this scenario there is an easy solution:

BitmapOptions.inBitmap which will reuse one Bitmap for every new tile, so no more furios GC-ing. I had to enlarge the few bitmaps that where smaller than 256x256.

Upvotes: 0

Related Questions