0

次のような単純な Android アプリケーションを作成しました。

アクティビティ:

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 スケールは単なるフレームです。フレームごとに 1 つの値。Y スケールは、で計算されたデルタ時間 (dt)onDrawFrame()です。これは、前のフレームの描画にかかったマイクロ秒単位の時間です。

これで、次の理由により、値が 16666 にとどまらないことが完全にわかりました。

  • デルタ タイムを完全に決定することはできません。また、nanotime を 1000 で割って a にキャストすると、long計算エラーが発生します。
  • システムは待機する必要がありますeglSwapBuffers()
  • 関数onDrawFrame()が終了すると、これは OpenGL コマンドがパイプラインに送信されたことを意味するだけです。ただし、コマンドが処理されたことを意味するわけではありません。

しかし、基本的に何も計算していないのに、なぜこんなに高いジッター結果が得られるのか、まだ理解できないようです。

問題の原因は何ですか?

テスト環境:

  • HTC ワン
  • CyanogenMod 10.2 (アンドロイド 4.3)

他の誰かがこれを再現できれば、私はとてもうれしいです。

4

1 に答える 1

-1

一貫性のないフレーム レートは、Log ステートメントが原因であることがわかります。データ ポイントを保存し、一度にすべてログに記録すると、フレームレートがより一貫していることがわかります。次のようなものを使用して、データをログに記録します。1000 フレームごとに実行したところ、dt は約 16500 ~ 18500 になりました。

    mDt[mStoredDtCount] = dt;
    mStoredDtCount++;
    if (mStoredDtCount == DT_MAX_COUNT) {
        while (mStoredDtCount > 0) {
            mStoredDtCount--;
            Log.e("test2", "dt: "+mDt[mStoredDtCount]);
        }
    }
于 2013-10-26T17:15:47.850 に答える