first call to glDrawArrays is very slow on iPad
I have an iPad app with UI written in OpenGL ES 2.0, some UI elements are hidden by default and when I need to show them there is pretty big delay before they actually shown (about 300-500 ms on a control which contains about 20 other controls inside), using Instruments.app I determined that when I render every unique object, it takes much longer to render it first time then after it was rendered at least once and the difference in rendering time is huge. Here is the code I have for rendering and this code is shown by Instruments taking all this delay:
- (void)render:(id <ESRenderer>)renderer
{
[shader useShader];
glEnableVertexAttrib开发者_如何学GoArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, _squareVertices);
glEnableVertexAttribArray(ATTRIB_TEXTCOORD);
glVertexAttribPointer(ATTRIB_TEXTCOORD, 2, GL_SHORT, 0, 0, coords);
float x1 = self.position.x;
float y1 = self.position.y;
glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_X], -x1+_squareVertices[0]);
glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_Y], -y1+_squareVertices[1]);
glUniform1f(shader.ext_uniforms[UNIFORM_ROTATE], self.rotation);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(ATTRIB_VERTEX);
glDisableVertexAttribArray(ATTRIB_TEXTCOORD);
}
When it is called at least once it works perfectly fast. My shader is very simple too:
vec4 col = texture2D(texture, coordVarying);
gl_FragColor = col;
Thanks!
I would guess it's the actual transfer of data to the GPU that occurs only once. You should be able to force the loading/compilation at some point before your first rendering to remove that performance hit. Either the vertex data transfer if it's huge, or the shader transfer/compilation.
EDIT: as noted in other answer, there is also the texture data that could be transferred.
OpenGL implementations commonly load textures 'lazily' i.e. the texture is only actually initialised at first use (pretty much what jv42 said, but not geometry data). It may be that this is what is occurring here. If you don't vary your textures between objects do you get the same slow downs?
One solution is to draw some trivial off-screen triangles with your textures bound at initialisation time to force these textures to be loaded before your main render loop.
BTW I wouldn't put much stock in measuring the length of individual draw calls on a deferred renderer like that in the iPhone.
I got it, too. For me it was an issue with the Texture. On NVIDA things worked out fast. But my optical optimisation caused an ATI card to nealy resign.
I work with a texture of size 4720 x 5600 (about) and modern cards work well with it.
I tried to optimize borders using Wrapmode=GL_CLAMP_TO_BORDER_ARB . Therefore I need to supply the border argument to glTeximage2D as at least == 1. Since the questionable Card did not support border in HW, it turned out to take 20 sec for one frame. Going back to GL_CLAMP_TO_BORDER + border param==0 made it speed up again.
精彩评论