2013-10-26 37 views
0

我創建這樣一個簡單的Android應用程序:OpenGL E.S. 2.0:非常不一致的幀率

活動:

public class MainActivity extends Activity { 
    private GLSurfaceView mGLView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mGLView = new MyGLSurfaceView(this); 
     setContentView(mGLView); 
    } 
} 

OpenGL的表面:

class MyGLSurfaceView extends GLSurfaceView { 

    public MyGLSurfaceView(Context context){ 
     super(context); 

     // Create an OpenGL ES 2.0 context 
     setEGLContextClientVersion(2); 

     // Set the Renderer for drawing on the GLSurfaceView 
     setRenderer(new MyGL20Renderer()); 
    } 
} 

渲染:

public class MyGL20Renderer implements GLSurfaceView.Renderer { 

    private long mCurrentTime; 

    public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
     // Set the background frame color 
     GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
    } 

    @Override 
    public void onDrawFrame(GL10 unused) { 

     final long newTime = getSystemTime(); 
     final long dt = newTime - mCurrentTime; 
     mCurrentTime = newTime; 

     Log.e("test", "dt: "+dt); 

     // Redraw background color 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 unused, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
    } 

    private long getSystemTime() { 
     return System.nanoTime()/1000L; 
    } 

} 

正如您所看到的,對於每個幀,我採用nanoTime並將其除以1000以獲得微秒時間。

現在,當我看到在onDrawFrame()產生的輸出,我得到不同的值的所有方式:

Image (:http://s14.directupload.net/images/131026/97pse5wo.png原稿尺寸在這裏)。

x-scale簡直是框架。每幀一個值。 y尺度是delta-time,dt在onDrawFrame()中計算。這是以前幀畫出的時間(以微秒爲單位)。

現在我完全理解,該值不會停留在16666由於以下原因:

  • 三角洲時間不能完全確定。此外,通過1000除以nanotime並強制轉換爲long導致一些計算錯誤
  • 該系統,以等待eglSwapBuffers()
  • 一旦功能onDrawFrame()已經完成,但這只是意味着OpenGL命令已經發送到管道。但這並不意味着這些命令已經被處理。

但我似乎無法理解爲什麼我得到這麼高的抖動結果,而我基本上沒有計算任何東西。

什麼可能是問題的根源?

測試環境:

  • 的HTC One
  • 的CyanogenMod 10.2(Android 4.3以上)

如果別人能複製這個問題,我將非常高興。

回答

-1

你會發現不一致的幀率是由於Log語句造成的。如果您存儲數據點,然後一次記錄所有數據點,則會看到幀率更加一致。使用類似下面的內容來記錄數據。我每1000幀做了一次,得到了大約16500-18500的dt。

mDt[mStoredDtCount] = dt; 
    mStoredDtCount++; 
    if (mStoredDtCount == DT_MAX_COUNT) { 
     while (mStoredDtCount > 0) { 
      mStoredDtCount--; 
      Log.e("test2", "dt: "+mDt[mStoredDtCount]); 
     } 
    } 
+0

嗯,我不確定這是不是真的。我已經使用你的方法做了,現在得到這個圖表(大約一分鐘捕獲): http://s14.directupload.net/images/131026/m7bg6dd8.png – 1FpGLLjZSZMx6k

+0

我唯一的想法是看你的設備是否在做垃圾收集之間的幀。 – levis501

+0

我已經從日誌輸出中刪除了過濾器,並將其設置爲「詳細」。在整個運行期間沒有關於GC的單個消息。 – 1FpGLLjZSZMx6k