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()
產生的輸出,我得到不同的值的所有方式:
(: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以上)
如果別人能複製這個問題,我將非常高興。
嗯,我不確定這是不是真的。我已經使用你的方法做了,現在得到這個圖表(大約一分鐘捕獲): http://s14.directupload.net/images/131026/m7bg6dd8.png – 1FpGLLjZSZMx6k
我唯一的想法是看你的設備是否在做垃圾收集之間的幀。 – levis501
我已經從日誌輸出中刪除了過濾器,並將其設置爲「詳細」。在整個運行期間沒有關於GC的單個消息。 – 1FpGLLjZSZMx6k