2012-09-01 13 views
8

私はレンダラーをプロファイルしようとしています。私は説明できない奇妙なプロファイリングの動作を見ています。なぜglClearはOpenGLESでブロックされていますか?

私はglSurfaceViewを使用しています。これは、レンダリングを連続して行うように設定しています。私onDrawFrame()

public void onDrawFrame(GL10 unused) { 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    executeAllDrawCommands(); 
} 

を構造化する方法を

これはこれは、軽負荷の下でゆっくりと動作したので、私はTimerクラスを作成し、この一部をプロファイルするために始めました。私は私が見たものにはかなり驚いていました。

public void onDrawFrame(GL10 unused) { 
    swapTimer.end(); 

    clearTimer.start(); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    clearTimer.end(); 

    drawTimer.start(); 
    executeAllDrawCommands(); 
    drawTimer.end(); 

    swapTimer.start(); 
} 

clearTimer対策、それはそれはすべて私の描画呼び出しを実行するのにかかる時間にglClear、drawTimer対策を呼び出すのにかかる時間、およびswapTimer対策時間:

私はそうのような私のonDrawFrame方法にいくつかのプローブを置きますonDrawFrameが終了してから返される時刻(eglSwapBuffersを呼び出すのにかかる時間)から取得します。

私は非常に負荷の軽いシーンを実行したとき、私は私が説明することはできませんいくつかの本当に奇妙な数字だ:私は、デバイスはvsyncの強制を持っていると信じて、私は、スワップ時間はやや大きめであることが予想

swapTimer : 20ms (average) 
clearTimer : 11ms (average) 
drawTimer : 2ms (average) 

を実際の「クリア」コールが11ミリ秒間ブロックされている理由はわかりませんが、約30fpsで有効にしていますか?私はそれがちょうど非同期コマンドを発行し、返すと考えられていたと思った?このシーンで

swapTimer : 2ms (average) 
clearTimer : 0ms (average) 
drawTimer : 44ms (average) 

私の描画呼び出しは、そのは、VSYNC期間の多くを隠すようになっていることに多くの時間を取っている:

私はずっと忙しいシーンを描くときは、数字はかなりの変更クリアコールのブロックは完全に消えてしまいます。

軽くロードされたシーンでglClearがブロックされている理由は何ですか?私の「Timerのクラスのソースコードへ

リンク誰かが私の測定技術の不審である場合には:http://pastebin.com/bhXt368W

+0

clearTimer.start()メソッドの前にGLES20.glFinish()を呼び出して時間の変化を確認できますか? –

+0

私は 'glFinish'(とその周りにfinishTimer.start()/ end()を置く)、それはglClearから常に離れています。代わりにglFinishは数ミリ秒かかるので、glClearは即座になります。これはvsyncに関連しているようですが、vsyncの時刻がglClearの内部に表示されるのは驚きました。 – Tim

答えて

10

私はglFinish(およびfinishTimer.start()/終了()、その周囲を)入れ、それはglClearからずっと離れています。代わりにglFinishは数ミリ秒かかるので、glClearは即座になります。

それがそれです。

シーンが非常に明るく、図面が非常に速くレンダリングされると、新しい色でピクセルをクリアして塗りつぶすのに時間がかかります(常に時間がかかります)。そうでなければレンダラーが遅れており、新しいもの)。新しいAndroid搭載デバイスには塗りつぶしの制限があります。たとえば、Nexus Oneには30 Hzでの塗りつぶしロックがあります。実際の描画がどのくらい速く行われても、その周波数で画面が同期されます。図面が30Hz未満で終了すると、レンダラーは画面と同期します。このため、この遅延に気づくのは、glClear()コールを削除しても気付くはずです。レンダラーは、画面の更新よりも早く、速くなります。

レンダラーに描画するオブジェクトが多数ある場合、レンダラーが画面の更新後になっ​​ているため、同期は中断されます(ビジーシーンのプロファイルデータを使用)。

あなたがglFinish()を使用

が、それは、fillrateロジックに従うことによって、 glFinish()は今、画面との同期を確保している機能であることを意味 glClear()関数はそうでない原因となる時間を、削除します。

計算

F = 1/T

簡単シーン

F = 1/T = 1 /((20 + 11 + 2)×10^- 3)=〜30 Hz

同期の遅延時間がプロファイラに表示されます。レンダラーが画面と同期しています。つまり、glClear()またはglFinish()コールを削除すると、の遅延が他の場所に表示されます。

重シーン

F = 1/T = 1 /((2 + 0 + 44)×10^-3))=〜22ヘルツ

同期の遅延時間がない

プロファイラに表示されます。レンダラーは画面の更新頻度の後にあります。

これはすべて正しいと思わ

をVsyncに関連しているように思えます。

関連する問題