Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSurfaceView framerate issues on Nexus 5

I have an example application (full source) that encodes camera frames with MediaCodec while displaying them on a GLSurfaceView.

Systrace confirms 30 drawing calls are made each second:

Systrace screenshot

However, a screenrecord recording (.mp4, YouTube) shows the apparent framerate to be considerably lower.

In a nutshell, my encoding & display loop does the following:

  • Makes a MediaCodec Surface input EGL Context current
  • Draws a camera frame to the MediaCodec EGL surface
  • Makes the GLSurfaceView EGL Context current
  • Draws the same camera frame to the GLSurfaceView

On a Galaxy Nexus LTE and Nexus 7 (both with AOSP 4.4), the application performs as expected. So far only the Nexus 5 experiences this discrepancy between the number of frames drawn to the screen and the number of frames apparent...

I pray I'm not insane.

like image 335
dbro Avatar asked Jan 12 '23 18:01

dbro


1 Answers

I was able to replicate the behavior, and my GL wizard office-mate figured out the problem.

Basically, one of the EGL contexts isn't noticing that the texture contents have changed, so it keeps rendering older data. We think it's getting occasional updates because it has a set of buffers that it cycles through, so eventually it re-uses the buffer you're looking at.

I was able to fix the problem in my code by updating the texture renderer class, changing this:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);

to this:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);

The un-bind and re-bind causes the driver to pick up the right buffer.

like image 138
fadden Avatar answered Jan 14 '23 07:01

fadden