Fullscreen background texture with OpenGL performance issue (iPad)

I am very puzzled by the poor performance that I see when drawing a full-screen background using a textured triangular mesh in OpenGL: only drawing the background and nothing else comes out at a speed of 40 frames per second using the most basic shader and 50 frames per second using the default pipeline .

While 40 frames per second doesn't seem too bad, adding anything else on top of it makes the fps drop, and given that I need to make another 100-200 other meshes, I get a negligible 15 frames per second, which is just not applicable .

I highlighted the appropriate code in the Xcode project available here , but its essence is an example of a canonical texture map:

static const GLfloat squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; static const GLfloat texCoords[] = { 0.125, 1.0, 0.875, 1.0, 0.125, 0.0, 0.875, 0.0 }; glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); if ([context API] == kEAGLRenderingAPIOpenGLES2) { // Use shader program. glUseProgram(program); glActiveTexture(GL_TEXTURE0); glUniform1i(uniforms[UNIFORM_TEXTURE], 0); glBindTexture(GL_TEXTURE_2D, texture); // Update attribute values. glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); glEnableVertexAttribArray(ATTRIB_TEXCOORD); } else { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable( GL_TEXTURE_2D ); glBindTexture(GL_TEXTURE_2D, texture); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glVertexPointer(2, GL_FLOAT, 0, squareVertices); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

Vertex Shader:

 attribute lowp vec4 position; attribute lowp vec2 tex; varying lowp vec2 texCoord; uniform float translate; void main() { gl_Position = position; texCoord = tex; } 

Fragment Shader:

 varying lowp vec2 texCoord; uniform sampler2D texture; void main() { gl_FragColor = texture2D(texture, texCoord); } 

Dividing the size of the rectangle by two doubles the frame rate, so the rendering time clearly depends on the real estate that it draws on the screen. This is completely reasonable, but for me it makes no sense that it is not possible to cover the entire screen with networks displaying OpenGL textures at a speed of more than 15 frames per second.

But there are hundreds of games that do this, so it’s possible, and I have to do something wrong, but what is it?

+6
source share
2 answers

Unfortunately, all I have is my iPad 2 to test it right now (my test unit iPad 1 is sitting at home), and it has ridiculously fast fragment handling. It is tied to 60 FPS, with 1,400 theoretical FPS in your logging.

However, I ran it using tools using the OpenGL ES Driver and Time Profiler tools, as well as the new new OpenGL ES analyzer (which comes with Xcode 4). Here's what the OpenGL ES analyzer looks like:

OpenGL ES Analyzer

Looking at the statistics of Tiler usage in the OpenGL ES driver, it shows that there are almost no plates, but rendering has some advantage (again, only 5% on my iPad 2). This indicates that suggestions for using VBOs and indexes for your geometry will probably not help you.

The one that sticks out is a warning of redundant calls:

OpenGL ES redundant calls

You save the framebuffer binding and configure the viewing window for each frame, which, according to Time Profiler, is 10% of the workload of your application. Commenting out a line

 [(EAGLView *)self.view setFramebuffer]; 

near the beginning of your frame drawing made the theoretical frame rate jump from 1400 FPS to 27000 FPS on my iPad 2 (aside, you probably should measure using milliseconds for your rendering ).

Again, these are my tests on a really powerful GPU in iPad 2, but you should repeat these steps on the original iPad or any other device to check this performance bottleneck and potentially highlight others. I found that the new OpenGL ES analyzer is very convenient in solving performance problems associated with shaders.

+7
source

Surprisingly, I have no iPad experience:

According to this benchmark , you can count on a fill factor of 214 frames per second with background resolution.

Have you tried disabling texturing to check if your texture is limited?

Is your texture “weakness of two textures”? In this case, did you try to remove GL_REPEAT from GL_TEXTURE_WRAP_* by replacing with GL_CLAMP(_TO_EDGE) ? Repeating NPOT may cost some performance on some hardware.

Ultimately, you can try setting the min / max filters to GL_NEAREST too.

0
source

Source: https://habr.com/ru/post/885507/


All Articles