0

I have written a game in which when onDrawFrame() is called I update the game state first (game logic and the buffers for drawing) and then proceed to do the actual drawings. On the Moto G and Nexus 7 everything works smoothly and each onDrawFrame() call takes only between 1-5ms. However, on the Samsung Galaxy S3, 90% of the time the onDrawFrame() call takes as long as 30-50ms to update.

Further investigating the issue I found the problem wholly lies on the first render method which I attach below:- (Edit: the block is now on glclear(); having removed the unnecessary calls to get the handles, please refer to the comments)

public void render(float[] m, FloatBuffer vertex, FloatBuffer texture, ShortBuffer indices, int TextureNumber) {
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertex);            
        GLES20.glEnableVertexAttribArray(mPositionHandle);            

        GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, texture);            
        GLES20.glEnableVertexAttribArray(mTexCoordLoc);            

        GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);            

        int mSamplerLoc = GLES20.glGetUniformLocation(fhGraphicTools.sp_Image, "s_texture");            

        GLES20.glUniform1i(mSamplerLoc, TextureNumber);            

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices);            
        // Disable vertex arrays used
        GLES20.glDisableVertexAttribArray(mPositionHandle);            
        GLES20.glDisableVertexAttribArray(mTexCoordLoc);            
    }

The above method is called 5 times in each onDrawFrame() to draw things on different texture atlas. (the first 4 are actually the game's background which is 1 long rectangle). Having logged the time it takes in each line of the code I found that the lag I am having on the S3 always reside in one of the below lines:

int mPositionHandle = GLES20.glGetAttribLocation(fhGraphicTools.sp_Image, "vPosition");

or

GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.capacity(), GLES20.GL_UNSIGNED_SHORT, indices);

The lag only occurs in the first call of render() as the subsequent calls takes about 1-2ms each. I have tried disabling the first render() call but then the second which before only take 1-2ms now become the source of the lag, under the same lines.

Does anyone have an idea of what is wrong in my code which the S3 could not handle? It seem that the S3 have problem commencing GL calls at the beginning of each onDrawFrame(), but why is there such behavior is puzzling me. What can be done to decrease the "startup" delay?

Many thanks for your patience in reading.

Edited code to take Selvin's recommendation.

  • why are you getting attrib locations and uniforms in onDrawFrame? instead of this store it in fx `fhGraphicTools.sp_Image_mPositionHandle` just after you compile `fhGraphicTools.sp_Image` shader – Selvin Sep 23 '14 at 09:42
  • I have as you said stored the handles after I compile. Now the "block" comes from the glClear() which is taking between 18- 50ms. I did some search and found this post http://stackoverflow.com/questions/12224230/why-is-glclear-blocking-in-openglesbut Having read it I'm still not entirely understanding the issue in my case... – user3846551 Sep 23 '14 at 10:58

1 Answers1

0

I have fixed the issue when I moved all my png image files from /drawable to /drawable-nodpi the game speed goes back to normal on the S3. I assume the auto-scaling done by Android causes the raw bitmap I supplied to opengl in "bad" sizes causing unnecessary texture filtering work on each onDrawFrame, causing the call to miss out vsync and giving a long delay for the glClear while waiting for next vsync. Please correct me if I am wrong, still a newbie to graphics.