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:
However, a screenrecord recording (.mp4, YouTube) shows the apparent framerate to be considerably lower.
In a nutshell, my encoding & display loop does the following:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With