2016-04-08 28 views
2

私は最近、古いギャラクシーS2の携帯電話を新品のギャラクシーS7にアップグレードしました。私が書いた古いゲームが新しい携帯電話で悪化しているように見えるのは非常に驚きでした。裸の骨プロジェクトにすべてをカットした後、私は問題を発見しました.GLES20.glFinish()コールは、すべてのonDrawFrameの最後で実行していました。これで、glClearでは描画コールがなくなり、FPSは約40周りに浮上しました。glFinishがなければ、60 FPSは安定していました。私の古いS2は、無関係に60FPSで安定していました。OpenGL es 2.0 - glFinishは、古いアンドロイド携帯電話と比較して、新しいアンドロイド携帯電話のフレームレートを低くするのはなぜですか?

私は自分のゲームに戻り、glFinishメソッド呼び出しを削除しました。そして、十分なパフォーマンスが完璧に戻ってきて、その除去に明らかな欠点はありませんでした。

なぜ、glFinishは新しい電話機でフレームレートを低下させましたが、古い電話機では減速させたのですか?

答えて

4

私は投機的な答えはそう、取得するつもりだとして良いと思います - ほぼ確実にあなたがすでに知っていることの多くを繰り返すための謝罪:

コマンドのOpenGLに送られたが、に対するという名前の3つの状態、を経ます物事のGPU側:

  • 提出したが、保留中
    1. 未送信のは
    を完了しました

    GPUを実行しているコードとの通信は、通常は高価です。だから、ほとんどのOpenGLの実装はあなたの呼び出しを受け入れ、しばらくの間あなたのメモリ空間の中で仕事を待ちます。ある時点で、コミュニケーションが正当であると判断し、すべてのコールを一度に転送するためのコストを支払って、提出された状態にそれらを昇格させます。それから、GPUはそれぞれを完成させます(潜在的に順不同、APIを壊さないことを条件とします)。

    glFinish:すべての以前に呼び出されGL コマンドの効果が完了するまで

    ...は戻りません。このような影響には、GL状態へのすべての変更、接続状態へのすべての変更、およびフレームバッファ のすべての変更が含まれます( )。

    そのCPUスレッドが何か他のことを行っていたかもしれないので、今は間違いないでしょう。しかし、glFinishが表示されない場合、出力はおそらく表示されますが、それはいつか不明です。 glFlushは、しばしば正式な転送方法です。提出するまですべてを進めますが、完了するのを待つことはありませんので、すべてが間もなく間違いなく表示されます。

    OSへのOpenGLバインディングは大きく異なります。あなたの環境がそうすることを許可すれば、ほぼ確実に終了するのではなく、むしろ終了したいと思っています。それがフラッシュしたり、終了したりすることが有効で、OSが何らかの基準に基づいて物事を推し進めていない場合は、余分なレイテンシが発生する可能性があります(例えば、1つのフレームを発行するコマンドが、次のフレームの間に再び非送信待ち行列になります)GL作業を無期限に行っている場合、出力はほぼ確実に進行します。

    AndroidはEGLに搭載されています。仕様によると、3.9.3:

    ...eglSwapBufferseglCopyBuffers

    私はので、あなたはダブルバッファリングをしている場合はフラッシュやAndroidで仕上げのいずれかを実行するために必要とされていないと信じて...コンテキストに暗黙のフラッシュ操作 を行います。バッファをスワップする呼び出しは、CPUをブロックせずに描画が完了するとすぐにバッファスワップを引き起こします。

    実際の問題として、S7にはAdreno 530 GPUがあります。 S2にはMali T760MP6 GPUが搭載されています。マリは、クアルコムのAdrenos ARMによって製造されているため、まったく異なるアーキテクチャとドライバの実装です。したがって、ブロッキングの原因となる違いはほとんど何でもあります。しかし、それは許されています。 glFinishは必須ではなく、非常に鈍い器具です。それはおそらく主要な最適化目標の1つではありません。

  • +2

    Androidグラフィックスアーキテクチャは、完了時に通知されるカーネルフェンスオブジェクトとバッファをペアにします。つまり、レンダリングし、 'eglSwapBuffers()'を呼び出し、レンダリングが開始される前にバッファをシステムコンポジタで利用できるようにすることができます。これにより、バッファリングとIPCメカニズムがレンダリングとオーバーラップすることができます。 'glFinish()'を呼び出すと、その作業ができなくなります。私はこれがフレームレートの劇的な低下に専念しているのではないかと疑いますが、完了までの同期待ちは確かに役に立たないのです。 https://source.android.com/devices/graphics/architecture.html – fadden

    +1

    「glFinish()」を呼び出すと、いくつかのベンダーが実際にすべてが終了するのを待っているわけではありません。あなたはそれが仕様に違反していると主張することができますが、それはまだそのように行われています。 –

    関連する問題