問題タブ [vsync]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - SFML vsync は常にオンですか?
私はゲームループと物理学をいじっています。先日、デバッグ ステートメントを追加して、ゲーム ループの各フレームにかかる時間を確認しました。予想通り、結果は 16 ミリ秒台でした。ただし、vsync を無効にしてみましたが、これらの結果は変わりませんでした。明らかに vsync がまだ発生していました。SFML の表示呼び出しをコメント アウトしたところ、フレームが高速化されました。
では、なぜ vsync が動かなくなったのでしょうか? 最初は、DSFML (D 言語の SFML バインディング) のバグに違いないと思いました。SFML を直接使用する C++ で簡単なテスト ケースを作成しましたが、パフォーマンス特性はまったく同じです。
私のシステムは次のとおりです。
$ inxi -SMG
システム: ホスト: c7カーネル: 3.16.4-1-ARCH x86_64 (64 ビット)デスクトップ: i3 4.8 ディストリビューション: Arch Linux マシン: システム: Google 製品: オウム v: 1.0
モボ: 該当なし モデル: N /A Bios: coreboot v: 4.0-4744-gac16405-dirty 日付: 10/23/2013
グラフィック: カード: Intel 第 2 世代コア プロセッサ ファミリ Integrated Graphics Controller
ディスプレイ サーバー: X.Org 1.16.1 ドライバー: intel解像度: 1366x768@ 60.02hz
GLX レンダラー: Mesa DRI Intel Sandybridge Mobile GLX バージョン: 3.0 Mesa 10.3.1
SFML vsync テスト ケースを以下に示します。vsync はオンになっています。
この問題をグーグルで検索すると、グラフィックス ドライバーが vsync を強制的にオンにしていることを示唆する結果が表示されます。しかし、なぜ vsync がシステム上の他のプログラムで機能するのか疑問に思いました。
今回はSDL2を使用して、別のテストケースを作成しました。
このテスト ケースで vsync を無効にすると、予想どおり、0 ミリ秒の範囲のフレーム時間が表示されます。そのため、SFML が vsync を実装する方法は私のシステムではバグがありますが、SDL は適切に処理しているようです。
この異なる動作を引き起こしている 2 つのライブラリの実装の違いは何ですか? また、それを解決できますか? SFML で正しい動作を得るにはどうすればよいですか?
directx - DirectX VSYNC の不正確さ
D3D アプリで安定した固定 60 fps を達成しようとしており、それを行うには vsync を実行します。次のようにループをセットアップしました。
「ms」変数は常に同じであると予想されますが、実際には約 16.1 ミリ秒から 17 ミリ秒を超えて変化しています。私が行っている間違った仮定や単純なコーディング エラーはありますか? 事前に助けてくれてありがとう。
android - systrace で BufferQueue の状態を取得する
アプリケーションが Android のバッファリング システムとどのように相互作用しているかをよりよく理解しようとしています。具体的には、Vsync 信号に関連して、フレームが SurfaceFlinger の BufferQueue に追加されるタイミングを最適化したいと考えています。
SurfaceView を使用する場合、BufferQueue 情報が SurfaceView 内に含まれることを理解しています。
TextureView を使用している場合はどうなりますか? これらの場合、SurfaceView カウンターはありません。SurfaceView を使用していないときのバッファ状態の他のインジケータはありますか? アプリケーション カウンターは BufferQueue の状態も示しますか?
BufferQueueProducer.cpp と BufferQueueConsumer.cpp の両方の次の行はこれを示唆しているように見えますが、可能であれば信頼投票を使用できます。
android - Android VSYNC 信号の必要性を理解する
私は Android ディスプレイ サブシステムをよりよく理解しようとしていますが、VSYNC 信号がどのように処理されるか、そもそもなぜこれほど多くの信号が存在するのかということは、まだわかりにくい点の 1 つです。
Android は、そのコアで VSYNC を使用するように設計されていますが、複数の VSYNC 信号が採用されています。https://source.android.com/devices/graphics/implement.htmlの「VSYNC オフセット」セクションには、 HW_VSYNC_0 、VSYNC、および SF-VSYNC の 3 つの VSYNC 信号を示すフロー図があります。HW_VSYNC が DispSync のタイミングを更新するために使用されること、および VSYNC と SF-VSYNC がアプリと surfaceflinger によって使用されることは理解していますが、なぜこれらの個々の信号が必要なのですか? さらに、オフセットはこれらの信号にどのように影響しますか? これをよりよく説明するタイミング図はどこにありますか?
ご協力いただきありがとうございます。
opengl - 可能な限り最後の瞬間までゲームループで計算する方法
3D ゲーム/シミュレーション エンジンの最適化の一環として、エンジンを自己最適化しようとしています。
基本的に、私の計画はこれです。まず、エンジンでフレームごとの CPU サイクル数を測定します。次に、さまざまなサブシステムが消費する CPU サイクル数 (最小、平均、最大) を測定します。
この情報が与えられると、フレーム ループの特定のいくつかのポイントで、エンジンは現在実行するのに効率的な「オプションの処理」を実行するために利用できる「余分な CPU サイクル」の数を推定できます (関連するデータは現在キャッシュにあります)。 )、ただし、現在のフレームが CPU サイクルが不足する危険がある場合は、後続のフレームまで遅延する可能性があります。
アイデアは、単調な作業でゲームを可能な限り先取りすることです。そのため、「要求の厳しいフレーム」(「単一フレーム中の多くの衝突」など)を処理するために可能なすべての CPU サイクルを利用でき、glXSwapBuffers( ) vsync の最新の可能な瞬間の前にバック/フロント バッファーを交換するのに間に合うように)。
上記の分析では、一定のフレーム レートを確保するための基本的な要件として、バック/フロント バッファーの交換が想定されています。これが唯一のアプローチではないという主張を見てきましたが、論理がわかりません。
glXSwapBuffers() の直前と直後の 64 ビット CPU クロック サイクル タイムをキャプチャしたところ、フレームが約 2,000,000 クロック サイクル異なることがわかりました。これは、glXSwapBuffers()がvsync (バッファーを交換できるとき) までブロックせず、代わりにすぐに戻るという事実によるものと思われます。
次に、glXSwapBuffers() の直前に glFinish() を追加しました。これにより、変動が約 100,000 CPU クロック サイクルに減少しました... しかし、glFinish() は 100,000 から 900,000 CPU クロック サイクルのどこかでブロックされました (おそらく、nvidia ドライバーの作業量に依存します)。バッファーをスワップする前に完了する必要がありました)。glXSwapBuffers() が処理を完了してバッファーをスワップするのにかかる時間のこの種の変動により、「スマートなアプローチ」に希望があるかどうか疑問に思います。
肝心なのは、私の目標を達成する方法がわからないということです。これはかなり単純に見え、基礎となるサブシステム (たとえば、OpenGL ドライバー) にあまり多くを要求していないようです。ただし、glXSwapBuffers() の直前に glFinish() を使用しても、「フレーム時間」に約 1,600,000 サイクルの変動が見られます。測定された「フレームあたりの CPU クロック サイクル」レートを平均し、その平均値が実際のフレーム レートであると仮定できますが、その変動が大きいと、これらの値に依存する可能性があると誤って仮定して、実際にエンジンがフレームをスキップする可能性があります。
関連するさまざまなGLX/OpenGL関数の詳細、または私が試みているよりも実際にうまく機能する可能性のある一般的なアプローチについての洞察をいただければ幸いです。
PS: 私の CPU の CPU クロック レートは、コアが遅くなったり速くなったりしても変化しません。したがって、それは私の問題の原因ではありません。
performance - OpenGL アプリケーションのプロファイリング - ドライバーが CPU 側をブロックしている場合
ゲーム内グラフィカル プロファイラー (CPU および GPU) を作成しましたが、Nvidia ドライバーで奇妙な動作が 1 つあります。
通常の場合のスクリーンショットを次に示し
ます。ここに表示されているのは、3 つの連続したフレームで、上部が GPU、下部が CPU です。両方のグラフが同期されます。
「END FRAME」バーには、への呼び出しのみが含まれますSwapBuffers
。GPU がすべての作業を完了するまでブロックしているのは奇妙に思えるかもしれませんが、vsync がオンで、すべての作業 (CPU と GPU) が 16ms に収まる場合にドライバーが選択することがあります (AMD も同じです)。私の推測では、入力の遅れを最小限に抑えるためにそれを行うということです。
今私の問題は、それが常にそうであるとは限らないということです。フレーム内で何が起こるかによって、グラフは次のようになることがあります:
ここで実際に起こることは、
SwapBuffers
. この特定のケースでは、ブロッキング コールはglBufferData
. それを行うダミーコードを追加すると、はるかに目立ちます(均一なバッファを作成し、ランダムな値をロードして破棄します):
これは、明らかな理由もなくグラフのバーが非常に大きくなる可能性があることを意味するため、問題です。これを見た人は、一部のコードが遅いという誤った結論を導き出す可能性があります。
私の質問は、このケースをどのように処理できますか? 意味のある CPU タイミングを常に表示する方法が必要です。
ユニフォーム バッファをロードするダミー コードを追加するのはあまり洗練されておらず、ドライバーの将来のバージョンでは機能しない可能性があります (ドライバーが代わりにドローコールのみをブロックするとしたらどうなるでしょうか?)。
フレームレートが低下すると、ドライバーはブロックを停止してCPUとGPUフレームを並行してglClientWaitSync
実行できるようにするため、呼び出しを停止するにはそれを検出する必要があるためですglClientWaitSync
(ただし、どうすればよいかわかりません。)
(より良いタイトルの提案は大歓迎です。)
編集: GPU がボトルネックである場合、vsync なしで何が起こるか:
GPU フレームは CPU フレームよりも時間がかかるため、ドライバー
glBufferData
は GPU が追いつくまで CPU をブロックすることにしました。
条件は同じではありませんが、問題は、ドライバーが OpenGL 関数ブロックの一部を作成するため、CPU タイミングが「間違っている」ことです。これは実際には、vsync をオンにしたものよりも理解しやすい例かもしれません。
frame-rate - ラップトップの外部電源を抜いた後、Direct2D が 30 FPS でしか実行されないのはなぜですか?
私は Direct2D を初めて使用し、最近奇妙な問題を発見しました。外部電源が接続されている場合、私のプログラムは 60 の安定した FPS で実行されます。これは VSync の結果である可能性があります。しかし、しばらく外部電源を抜いた後、私のプログラムは 30 の安定した FPS に落ちました (2 回のレンダリングごとに時間間隔を出力したところ、32ms と表示されました)。
また、電源を再度接続しても、コンピューターを再起動するまで 30 FPS のままです。
FPS を半分に削減するバッテリーで電力を供給しているときに、ラップトップが何かをシャットダウンしたためでしょうか? もし本当なら、私はそれのために何ができますか?
私のラップトップのOSはWindows 8.1です。
役に立つかもしれないいくつかのコードを次に示します。
メインループは次のようになります。
確かに時間Update()
もかからないし、安定したフレームレート60で走れるので問題なさそうOnRender()
です。
ありがとうございました!
opengl - OpenGL の GLFW で 2 つのビューポートを使用すると 30 fps でスタックする
vsync は glfwSwapInterval(1) または glfwSwapInterval(0) でオンとオフを切り替えます
単一のビューポートは glClear --> glViewport(0, 0, win_w,win_h) --> drawscene() --> レンダリング ループの glfwSwapBuffers です。
ダブル ビューポートは glClear --> glViewport(0, 0, win_w/2,win_h) --> drawscene() --> glViewport(win_w/2, 0, win_w/2,win_h) --> drawscene() -- >レンダリングループのglfwSwapBuffers
vsync のないシーンの単一ビューポート --> 140 fps
vsync のないシーンのダブル ビューポート --> 70 fps (同じシーンを 2 回描画しているため、予想通り)
vsync を使用したシーンの単一ビューポート --> 60 fps (モニターのリフレッシュ レートが 60 Hz であるため、予想どおり)
vsync を使用した私のシーン ダブル ビューポート --> 30 fps (??? vsync なしで 70 > 60 fps を達成しているため、ここでは 60 fps を期待しています。呼び出す必要がある追加の GLFW 関数はありますか?)