【问题标题】:Low performance when execute eglSwapBuffer and eglMakeCurrent执行 eglSwapBuffer 和 eglMakeCurrent 时性能低下
【发布时间】:2014-10-20 12:30:33
【问题描述】:

我正在开发一个 Android Unity 插件,允许用户记录他/她的游戏玩法
我的解决方案概述:

  • 使用 OpenGl FrameBufferObject (FBO) 使 Unity 在屏幕外渲染到此 FBO
  • 获取此 FBO 的屏幕外纹理,然后用于 2 个目的:
    • 渲染到视频表面
    • 重绘到设备屏幕
  • 每帧执行流程:
    • 绑定我的FBO
    • 将场景渲染到 FBO(Unity 代码)
    • 解除绑定我的 FBO
    • 设置视频表面
      • 配置表面大小(仅第一次执行)
      • 保存 egl 状态
      • 使视频表面电流化
    • 使用我的 FBO 的屏幕外纹理绘制到视频表面
    • 恢复到默认表面
      • 将演示时间设置为视频帧
      • 将缓冲区从视频表面交换到默认窗口
      • 恢复 egl 状态
      • 设置默认表面电流
    • 通知编码器线程数据已准备好写入

我的问题是录制时性能不佳。三星 Galaxy S4 的 FPS 从 60 下降到 40。我试图记录渲染操作的执行时间,并认识到最影响性能的操作是使视频表面成为当前操作并将缓冲区从视频表面交换到默认窗口操作。下面是他们的代码

public void makeCurrent()
{
 if (!EGL14.eglMakeCurrent(this.mEGLDisplay, this.mEGLSurface, this.mEGLSurface, this.mEGLContext))
  throw new RuntimeException("eglMakeCurrent failed");
}

public boolean swapBuffers()
{
 return EGL14.eglSwapBuffers(this.mEGLDisplay, this.mEGLSurface);
}

make current 操作的执行时间为 1 ~ 18 ms
交换缓冲区操作的执行时间为 4 ~ 14 ms
其他操作的执行时间通常为 0 ~ 1 ms
如何提高这些操作的性能?
任何帮助将不胜感激!

【问题讨论】:

  • 我目前正在为 Unity for Android 进行屏幕录制。我对您在将场景渲染到 FBO(Unity 代码)的事件方面从 Unity 方面使用的内容感兴趣您是否使用了 OnPostRender? WaitForEndofFrame?还是 GL.IssuePluginEvent?您在什么阶段绑定了 FBO,我从 http://forum.unity3d.com/threads/screen-recorder-android-plugin.213466/ 查看了您的原始代码,但从 4.3 开始,我相信他们已经更改了 UnityPlayer 的功能和访问权限到 OnDrawFrame 不可用。任何帮助都会很棒,谢谢。
  • 我也有与@user819640 相同的问题。在 Grafika 中,绘制一帧的是 doFrame 回调。我不知道在 Unity3D 中绘制动作发生在哪里。

标签: android opengl-es unity3d opengl-es-2.0 android-mediarecorder


【解决方案1】:

很多 OpenGL 调用是异步的,有些调用可能会导致 OpenGL 等待排队的操作执行。所以看到你的时间是因为在你实际调用之前执行的其他调用。

【讨论】:

  • 如何检查导致 OpenGL 等待排队操作执行的调用?
  • @knighthedspi 您需要使用 GPU 分析工具。 Apple 在 Instruments for iOS 中包含了一个,我还没有在 Android 上使用过一个,但我想如果你搜索一个,你会找到的。
猜你喜欢
  • 2014-01-21
  • 2015-11-30
  • 2011-06-15
  • 2011-11-03
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多