小さなテストプログラム (以下を参照) はぎくしゃくした出力を示します。これは、OpenGL glutSwapBuffer() 中の奇妙なタイミング ジッターが原因であると思われます。テストプログラムは、平均に比べて単一フレームのレンダリング時間が非常に長いことを示すことがよくあります (私のマシンでは ~330 マイクロ秒に対して ~5.8 ミリ秒)。プログラムの出力は次のように表示されます。
[...]
render time: 330us
render time: 372us
render time: 330us
render time: 331us
render time: 5820us
render time: 335us
render time: 332us
render time: 324us
render time: 346us
[...]
セットアップ: Fast PC (Intel i7 CPU @3.2GHz)、Ubuntu 12.04、NVIDIA GTS450 ボード、最新の GL ドライバー: OpenGL レンダラー文字列: GeForce GTS 450/PCIe/SSE2 OpenGL バージョン文字列: 4.3.0 NVIDIA 310.19 Samsung Display (23" @それらはすべて60Hzであるため、60Hzと思います)
上記のテストケースでは、__GL_SYNC_TO_VBLANK=0 によって vblank 同期を明示的に却下しました。
vblank を有効にすると、タイミングも非常に不安定になります。
__GL_SYNC_TO_VBLANK=1
[...]
render time: 9169us
render time: 14548us
render time: 14613us
render time: 16057us
render time: 18075us
[...]
また、Xサーバーを高い優先度にする( sudo schedtool -p 0 -n -20 -N pgrep X
)、またはプログラム自体を高い優先度にする( chrt -p -a --fifo 99 ... )など、他のパラメーターも試しました。 )
まだぎくしゃくしたアニメーションが残っています - これは (これは私の仮定です) 奇妙なタイミングが原因です.
「glutSwapBuffers();」なしのタイミング コードは非常に安定した出力を示しています。
[...]
render time: 2us
render time: 2us
render time: 2us
render time: 1us
render time: 2us
[...]
そのため、外部 (他のプロセス) の影響を排除できます。
誰でもこの動作を説明できますか?
改善する方法はありますか?
プログラム:
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <time.h>
GLfloat gfPosX = 0.0;
GLfloat gfDeltaX = .01;
#define TS_TOUSEC(x) (x.tv_sec * 1000000L + (x.tv_nsec / 1000))
struct timespec t1, t2;
void Draw() {
int x = 0;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
clock_gettime(CLOCK_REALTIME, &t1);
glBegin(GL_LINES);
glVertex3f(gfPosX, 0.25, 0.0);
glVertex3f(gfPosX, 0.75,0.0);
glEnd();
clock_gettime(CLOCK_REALTIME, &t2);
glutSwapBuffers();
printf("render time: %5uus\n", TS_TOUSEC(t2) - TS_TOUSEC(t1));
gfPosX += gfDeltaX;
if (gfPosX >= 1.0 || gfPosX <= 0.0) {
gfDeltaX = -gfDeltaX;
}
}
void Timer(int iUnused)
{
glutPostRedisplay();
glutTimerFunc(5, Timer, 0);
}
void Initialize() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(250, 250);
glutInitWindowPosition(200, 200);
glutCreateWindow("XoaX.net");
Initialize();
glutDisplayFunc(Draw);
Timer(0);
glutMainLoop();
return 0;
}