How to load huge bitmap in Android using Open GL ES?

754 Views Asked by At

I have a image view in my app, and I want to load big bitmap on it, but when I'm setting "android:hardwareAccelerated="true", I got an error

(Bitmap too large to be uploaded into a texture (2368x4208, max=4096x4096))

I worked around this by setting flag to false. This caused another issue, while scrolling/zooming the image in ImageView, the performance was extremely bad.

Questions:

  1. Can I have a lot of textures?
  2. Can the total texture size exceed 4096x4096?
1

There are 1 best solutions below

0
On BEST ANSWER

The texture limitation you are hitting is one imposed by your GPU driver, and can be different from device to device. Using hardware acceleration, ImageView will use the OpenGL ES driver, presumably using the glTexImage2D function to upload the image to the GPU. From its documentation:

GL_INVALID_VALUE may be generated if level is greater than log 2 ⁡ max , where max is the returned value of GL_MAX_TEXTURE_SIZE when target is GL_TEXTURE_2D or GL_MAX_CUBE_MAP_TEXTURE_SIZE when target is not GL_TEXTURE_2D.

If you look at the documentation for glGet with GL_MAX_TEXTURE_SIZE:

GL_MAX_TEXTURE_SIZE params returns one value. The value gives a rough estimate of the largest texture that the GL can handle. The value must be at least 64. See glTexImage2D.

So, you are only guaranteed that you can upload a 64x64 texture on every ES 2.0 capable device. In practice this number is 2048x2048 for many current devices, but you should always know that the image size can be accommodated before attempting to upload a large image, by querying this value. Generally, a small number here means a less powerful GPU, and thus, lower screen resolution requiring less detailed textures. You could differentiate your assets based on this value - eg. have lower resolution textures for lower resolution screens.

To answer your other questions, there is no limitation in GL on the number of textures you create, eg. with glGenTextures. However, technically any command you call in OpenGL ES could generate a GL_OUT_OF_MEMORY error. Unfortunately, there is no standard way to query whether the driver will be able to handle any required allocations for a given command. The only practical way to handle this, is to test your app on many devices with different GPU capabilities.