9

I am very new to OpenGL.

I am trying to draw textured quads (2 triangles). The size of texture is 900x900px. I have no problems with one quad but when I trying to draw 5-10 quads I see noticable slow down.

Maybe I'm doing something wrong...

Code:

public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    ... matrix calculation ...
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}

Vertex shaders:

uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
void main() {
  gl_Position = uMVPMatrix*vPosition;
  v_TexCoordinate = a_TexCoordinate;
}

Fragment shader:

    precision mediump float;
    uniform sampler2D u_PreviewTexture;
    varying vec2 v_TexCoordinate;

    void main() {
      vec4 color = texture2D(u_PreviewTexture, v_TexCoordinate);
      gl_FragColor = color;
    }

Testing platform is Galaxy S3. In profiler I see that about 60ms takes eglSwapBuffers call.

How can I draw quads with big textures fast?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
mik_os
  • 670
  • 1
  • 6
  • 10

3 Answers3

4

This could be due to the size of your textures and on the OpenGL driver implementation of the devices you are using.

Most of the modern GPUs do a quite good job with NPOT (no power of two) textures but this causes a rescaling of the texture every time it needs to be drawn to the nearest power of 2 (in your case 1024X1024).

Try to use the following 2 solutions:

1- Convert your textures to 1024x1024 and use the coordinates in your geometries to only draw what you need (900x900)

2- Try to generate mipmaps, if you have a lot of zooming this is a performance savior in many scenarios.

Maurizio Benedetti
  • 3,557
  • 19
  • 26
  • If texture is static compression could also reduce memory bandwich. ETC1 compression is abailable probably on all mobile devices. It supports only RGB format, without alpha channel. – marekb Feb 24 '13 at 09:01
  • Thank you for the answers. I tried to scale textures to 1024x1024 but it does not give any difference. And I can't use ETC1 because I getting bitmaps in runtime. I tried to profile gpu calls and it looks like all calls takes less than 2ms... – mik_os Feb 25 '13 at 05:15
  • another test: 10 quads, each with two 1024x1024 textures (mix() is used): eglSwapBuffers call takes abiut 35-40ms but in GPU profiler all drawing process take less than 3ms. – mik_os Feb 25 '13 at 05:40
1

Your S3 probably has about 600M texels/sec fillrate (see GLBenchmark). If you're rendering full-screen quads - ten double-texture quads give 20M texels per frame. Assuming GLBenchmark does what it says(measure texturing throughput) 20M texels is 1/30 of the fillrate, giving 33ms the best the hw can process one frame. Framebuffer blending I'm sure actively competes for the fillrate - 10M pixels blended is quite a lot so I can guess the bottleneck could also be there.

What you can try to make sure what is the slow part - reduce texture size to say, 512x512, and see how it affects performance. Reduce screen size of the rendered quads(considerably, as with textures - e.g. make it half/quarter of the screen).

kerim
  • 2,412
  • 18
  • 16
1

In my experience, texture performance problems usually stem from how the MIPMAP filtering is setup. A lot of performance can be lost with the following parameters not set optimally (minimal settings shown):

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

If possible, try to disable depth testing. @marekb's advice on texture compression also provides a lot of performance benefit.

kineticfocus
  • 492
  • 4
  • 16