次の 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 です。
助けてください。