Low performance when execute eglSwapBuffer and eglMakeCurrent
Asked Answered
C

1

13

I'm developing an Android Unity Plugin that allows user to record his/her gameplay
Overview of my solution:

  • Using OpenGl FrameBufferObject (FBO) to make Unity render offscreen to this FBO
  • Get the offscreen texture of this FBO then using for 2 purposes:
    • Render to video surface
    • Redraw to device screen
  • Execute flow per frame:
    • bind my FBO
    • render scene to FBO (Unity code)
    • unbind my FBO
    • set up video surface
      • configure surface size (execute first time only)
      • save egl state
      • make video surface current
    • draw to video surface using offscreen texture of my FBO
    • restore to default surface
      • set presentation time to video frame
      • swap buffer from video surface to default window
      • restore egl state
      • make default surface current
    • notify encoder thread that data is ready to write

My issue is performance while recording is not good. FPS downs from 60 to 40 on Samsung Galaxy S4. I tried to record execute time of render operations and recognize that the most affect performance operations are make video surface current operation and swap buffer from video surface to default window operation. Below is their code

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);
}

Execute time of make current operation is 1 ~ 18 ms
Execute time of swap buffers operation is 4 ~ 14 ms
Execute time of other operations is usually 0 ~ 1 ms
How to improve performance of these operations?
Any help will be greatly appreciated!

Conway answered 27/8, 2014 at 3:16 Comment(2)
I am currently working on Screen Recording for Unity for Android. I'm interested in what you used from the Unity side in terms of events to render scene to FBO (Unity code) Did you use OnPostRender? WaitForEndofFrame? or GL.IssuePluginEvent? At what stage did you bind the FBO, I look at your original code fromhttp://forum.unity3d.com/threads/screen-recorder-android-plugin.213466/ but since 4.3 I believe they have changed the UnityPlayer functionality and access to OnDrawFrame is not available. Any help would be amazing, thanks.Chiao
I also have the same question as @Chiao . In Grafika, it is the doFrame callback where draw one frame. I don't know where the draw action happens in Unity3D.Bivins
S
0

A lot of OpenGL calls are assync, and some calls may cause the OpenGL wait the queued operations to execute. So the times you are seen are because of the other calls that execute before the actual call you are doing.

Satori answered 7/9, 2014 at 20:31 Comment(2)
How do I check what calls cause the OpenGl wait to queued operations to execute?Conway
@Conway You need to use a GPU profiling tool. Apple have one included on Instruments for iOS, I haven't used one on Android yet, but I think you will find if you search for one.Satori

© 2022 - 2024 — McMap. All rights reserved.