9

次の Vsync 間隔までの秒数を浮動小数点値として返す C++ 関数を作成する必要があります。

なんで?

マウス カーソルに追従する四角形を表示するプログラムを作成しています。表向きは、OpenGL は glXSwapBuffers 関数で vsync メカニズムを提供しますが、これは信頼できないことがわかりました。一部のカード ドライバでは、vsync が得られます。あなたがしない他の人と。一部では vsync が得られますが、余分な 2 フレームのレイテンシも得られます。

しかし、これは OpenGL のバグではありません。仕様は意図的にあいまいです。「その後、バック バッファーの内容は未定義になります。更新は通常、glXSwapBuffers が呼び出された直後ではなく、モニターの垂直リトレース中に行われます。」キーワードは「通常」です...基本的にglXSwapBuffersは、vsyncに関してスクワットを約束しません。図に行きます。

この基本的な問題を解決するための私の現在の試みでは、現在、初期の vsync 時間を推測しており、その後、位相が現在のモニターと同期しているように見える経過時間 MOD 1/(59.85Hz) に等しいと仮定しています。しかし、私は実際に初期段階を知らないため、これはうまく機能しません。だから涙が一粒出ます。少なくとも動きません。しかし、私が本当に必要としているのは、現在の vsync フェーズを何らかの方法で測定することです。

いいえ、OpenGL 呼び出しに依存して vsync を実行したくありません。仕様が曖昧なため、これにより OpenGL の実装に必要なだけのレイテンシを追加することができます。

いいえ、SGI 拡張機能や、動作させるためにインストールしなければならないその他のものに依存したくありません。これはグラフィックス 101 です。その状態を照会する方法が必要なだけです。組み込みの常にインストールされる API には、これが必要です。

どうにかして Vsync を待機し、これが発生した時間を記録するセカンダリ スレッドを作成できますか? ただし、次のシーケンスに注意してください。

#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
  int fb = open("/dev/fb0", O_RDWR);
  assert(fb != -1);
  int zero = 0;
  if (ioctl(fb, FBIO_WAITFORVSYNC, &zero) == -1)
    printf("fb ioctl failed: %s\n", strerror(errno));
}

Debian では動作しません。結果:

% ./a.out
fb ioctl failed: Inappropriate ioctl for device
% ls -l /dev/fb0
crw-rw-rw- 1 root video 29, 0 Sep  1 20:52 /dev/fb0

デバイスからフェーズを読み取る方法、またはその他の OpenGL 呼び出しを行う方法が必要です。OpenGL は、グラフィックのためのものです。Vsync はグラフィックス 101 です。

助けてください。

4

4 に答える 4

0

これはグラフィックス 101 です。その状態を照会する方法が必要なだけです。組み込みの常にインストールされる API には、これが必要です。

いいえ、それを行う方法はありません。少なくとも、あなたにさらされるものは何もありませ。そして確かにクロスプラットフォームではありません。

結局のところ、あなたは画面を所有していません。システムが画面を所有します。あなたはそれの一部を借りているだけなので、システムに翻弄されています。システムは vsync を処理します。あなたの仕事は、そこに表示される画像を埋めることです。

Vulkan について考えてみましょう。Vulkan は、実際グラフィックス ドライバーでなくても、最近入手できるほど低レベルです。その WSI インターフェイスは、「次の vsync まで待機する」などの操作を許可しないように明示的に設計されています。

そのプレゼンテーション システムはさまざまなモードを提供しますが、実装がサポートする必要がある唯一のモードは FIFO です。厳密な vsync ですが、ティアリングはありません。もちろん、Vulkan の WSI では、少なくとも必要な画像バッファリングの量を選択できます。しかし、ダブルバッファのみで FIFO を使用し、そのイメージの提供が遅れた場合、スワップは次の vsync まで表示されません。

于 2016-09-02T20:32:13.617 に答える
0

簡単な答えは次のとおりです。ビデオのバッファリングが高価だったとき、vsync はコンピューターで一般的でした。最近では、ダブル バッファ アニメーションが一般的に使用されているため、それほど重要ではありません。Windowing システムを使用する前は、IBM-PC のグラフィックス カードから vsync にアクセスしていましたが、今でも VSYNC を取得することを気にしません。ダブル バッファリングを使用すると、バッファをビデオ メモリに bltting している間にラスター スキャンが発生する可能性があるため、それを同期することをお勧めします。ただし、ダブル バッファリングを使用すると、個々のピクセル操作ではなく線形 blt を実行するため、直接のビデオ描画から多くの「きらめき」効果やその他のアーティファクトを排除できます。

また、(前のポスターが暗示したように) 両方のバッファーがビデオ メモリに存在するという事実と、ディスプレイ マネージャーが画面への blt を慎重に管理できるという考え (合成) の両方が、存在しない効果をレンダリングする可能性があります。

これをどう処理すればよいですか?バッファを反転するために使用する、たとえば 1 秒あたり 30 回のフレーム タイマーを保持します。グラフィックス カードの実際のフレーム時間と特に同期しているわけではありません。

于 2021-05-03T23:13:35.927 に答える