【问题标题】:GLSurfaceView framerate issues on Nexus 5Nexus 5 上的 GLSurfaceView 帧率问题
【发布时间】:2013-12-21 14:20:34
【问题描述】:

我有一个示例应用程序 (full source),它使用 MediaCodec 对相机帧进行编码,同时在 GLSurfaceView 上显示它们。

Systrace 确认每秒进行 30 次绘图调用:

但是,屏幕录制(.mp4YouTube)显示明显的帧速率要低得多。

简而言之,我的编码和显示循环执行以下操作:

  • 将 MediaCodec Surface 输入 EGL 上下文设为当前
  • 将相机帧绘制到 MediaCodec EGL 表面
  • 使 GLSurfaceView EGL 上下文成为当前状态
  • 将相同的相机帧绘制到 GLSurfaceView

在 Galaxy Nexus LTE 和 Nexus 7(均采用 AOSP 4.4)上,应用程序按预期运行。到目前为止,只有 Nexus 5 在绘制到屏幕的帧数和明显的帧数之间存在这种差异......

我祈祷我没有疯。

【问题讨论】:

  • screenrecord 命令增加了相当大的开销——surfaceflinger 需要使用 GLES 为虚拟显示合成所有层——这会对你的帧速率产生不利影响。在 screenrecord 运行时查看 systrace。
  • 我也遇到了没有屏幕记录的问题。 N5 和我尝试过的其他设备之间完全是白天和黑夜。
  • 类似问题(可能的解决方法):stackoverflow.com/questions/20396515/…
  • 谢谢!我正在调查那个。 FWIW 我有systrace of my application on the N5(16MB。当我从该网址加载时,Chrome 会崩溃,但当我在本地打开它时不会……)。另外值得注意的是,我所有的测试设备都是 4.4,只有 N5 在我的应用程序中产生了这个问题。
  • 查看大约 1.5 秒...如果您查看顶部附近的 SurfaceView 行,您可以随时看到其队列中有多少缓冲区。缓冲区源没有保持队列馈送,所以 SurfaceFlinger 没有绘制任何东西——在 SurfaceFlinger 线上,您可以看到它是合成的,等待 vsync (17ms),合成,等待 3x vsync,然后重复。有很多 CPU 在运行,但其中大部分似乎是 PackageManager。 Thread-445 显示调用 awaitImage() 之间的时间为 30-40 毫秒,这通常需要 20 毫秒才能返回。肯定有什么东西搞砸了。

标签: android glsurfaceview android-mediacodec


【解决方案1】:

我能够复制该行为,我的 GL 向导办公室伙伴发现了问题。

基本上,其中一个 EGL 上下文不会注意到纹理内容已更改,因此它会继续渲染较旧的数据。我们认为它会偶尔更新,因为它有一组循环使用的缓冲区,因此最终它会重新使用您正在查看的缓冲区。

我能够通过更新纹理渲染器类来解决我的代码中的问题,改变这个:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);

到这里:

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

取消绑定和重新绑定会导致驱动程序拾取正确的缓冲区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2011-01-25
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多