Hw Accelerated Activity - How to Get Opengl Texture Size Limit

HW accelerated activity - how to get OpenGL texture size limit?

Currently the minimum limit is 2048px (i.e. the hardware must support textures at least 2048x2048.) In ICS we will introduce a new API on the Canvas class that will give you this information:

Canvas.getMaximumBitmapWidth() and Canvas.getMaximumBitmapHeight().

Get Maximum OpenGL ES 2.0 Texture Size Limit in Android

PBUFFER max size is unfortunately not related to max texture size (but may be the same).

I believe the best way to obtain max texture size is to create GL context (on the same context as one on which You will actually use this textures) and ask for GL_MAX_TEXTURE_SIZE.

There is strong reason behind this: the ogl driver is not initialized for current process before surface (and context) creation. Some drivers perform underlying HW/SKU detection on initialization and calculate max surface sizes depending on HW capabilities.

Furthermore, max texture size is permitted to vary depending on context (and EGLConfig context was created on).

And one more thing: eglGetConfigs will get You all EGLconfigs, even these from default, software android renderer, or theese from OpenGL ES 1.1CM HW driver (if there are separate drivers for 1.1 and 2.0 on target platform). Drivers are sort of independent in graphics stack and can return different max-es.

Opengl ES 2.0 : Get texture size and other info

Not in ES 2.0. It's actually kind of surprising that the functionality is not there. You can get the size of a renderbuffer, but not the size of a texture, which seems inconsistent.

The only thing available are the values you can get with glGetTexParameteriv(), which are the FILTER and WRAP parameters for the texture.

It's still not in ES 3.0 either. Only in ES 3.1, glGetTexLevelParameteriv() was added, which gives you access to all the values you're looking for. For example to get the width and height of the currently bound texture:

int[] texDims = new int[2];
GLES31.glGetTexLevelParameteriv(GLES31.GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, texDims, 0);
GLES31.glGetTexLevelParameteriv(GLES31.GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, texDims, 1);

Check GPU OpenGL Limits

glGet() is your friend, with:

  • GL_MAX_3D_TEXTURE_SIZE
  • GL_MAX_TEXTURE_SIZE
  • GL_MAX_VERTEX_ATTRIBS
  • GL_MAX_VARYING_FLOATS
  • GL_MAX_TEXTURE_UNITS
  • GL_MAX_DRAW_BUFFERS

e.g.:

GLint result;
glGetIntegerv(GL_MAX_VARYING_FLOATS, &result);

Not quite sure what your project is setting out to achieve, but you might be interested in OpenCL if it's general purpose computing and you weren't already aware of it. In particular Cl/GL interop if there is a graphics element too and your hardware supports it.

As Damon pointed out in the comments in practice it may be more complex than this for texture sizes. The problems arise because rendering may fallback from hardware to software for some sizes of textures, and also because the size of a texture varies depending upon the pixel format used. To work around this it is possible to use GL_PROXY_TEXTURE_* with glTexImage*.

Bitmap too large to be uploaded into a texture

All rendering is based on OpenGL, so no you can't go over this limit (GL_MAX_TEXTURE_SIZE depends on the device, but the minimum is 2048x2048, so any image lower than 2048x2048 will fit).

With such big images, if you want to zoom in out, and in a mobile, you should setup a system similar to what you see in google maps for example. With the image split in several pieces, and several definitions.

Or you could scale down the image before displaying it (see user1352407's answer on this question).

And also, be careful to which folder you put the image into, Android can automatically scale up images. Have a look at Pilot_51's answer below on this question.

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

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.

OpenGL Video RAM Limits

If you want to use a software renderer, link against Mesa.

You can get an estimate of the maximum texture size using these methods:

21.130 What's the maximum size texture map my device will render hardware accelerated?

A good OpenGL implementation will render with hardware acceleration whenever possible. However, the implementation is free to not render hardware accelerated. OpenGL doesn't provide a mechanism to ensure that an application is using hardware acceleration, nor to query that it's using hardware acceleration. With this information in mind, the following may still be useful:

You can obtain an estimate of the maximum texture size your implementation supports with the following call:

GLint texSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);

If your texture isn't hardware accelerated, but still within the size restrictions returned by GL_MAX_TEXTURE_SIZE, it should still render correctly.

This is only an estimate, because the glGet*() function doesn't know what format, internalformat, type, and other parameters you'll be using for any given texture. OpenGL 1.1 and greater solves this problem by allowing texture proxy.

Here's an example of using texture proxy:

glTexImage2D(GL_PROXY_TEXTURE_2D, level, internalFormat, width, height, border, format, type, NULL);

Note the pixels parameter is NULL, because OpenGL doesn't load texel data when the target parameter is GL_PROXY_TEXTURE_2D. Instead, OpenGL merely considers whether it can accommodate a texture of the specified size and description. If the specified texture can't be accommodated, the width and height texture values will be set to zero. After making a texture proxy call, you'll want to query these values as follows:

GLint width;
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);

if (width==0) {
/* Can't use that texture */
}


Related Topics



Leave a reply



Submit