eglSwapBuffers
xlib を使用しているときに vsync を適切に有効にする方法を知りたいです。への呼び出しeglSwapInterval
は単に無視されているようです。
ウィンドウモードとフルスクリーンモードの両方で実行しています。ウィンドウモードでサポートされていない可能性はありますか? この場合、私がレンダリングする頻度を減らす良い方法は何ですか (睡眠は、目覚めたときに保証がないため、不安定な動作を引き起こす傾向があります)。
最終的に私は多くのグーグルの後にこれを見つけました:
http://lists.freedesktop.org/archives/mesa-commit/2010-May/021020.html
egl: EGL_NOK_swap_region を実装します
この拡張機能は、eglSwapBuffers の代替を提供する新しい関数を追加します。eglSwapBuffersRegionNOK は、eglSwapBuffers のパラメーターに加えて、2 つの新しいパラメーターを受け入れます。新しいパラメーターは、四角形 (x、y、幅、高さ) を定義する 4 つの整数ブロックのリストへのポインターと、リスト内の四角形の数を指定する整数で構成されます。
そして /usr/include/EGL/eglmesaext.h は宣言します
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
ここにもいくつかの使用例があります:
https://github.com/blazt/piglit/blob/master/tests/egl/egl-nok-swap-region.c
ということで、以下のように使ってみました。
EGLint dirtyRect[4] = { 0, 0, 0, 0 };
PFNEGLSWAPBUFFERSREGIONNOK swap_buffers_region = (PFNEGLSWAPBUFFERSREGIONNOK)
eglGetProcAddress("eglSwapBuffersRegionNOK");
そして、ウィンドウのサイズ変更コールバックで
dirtyRect[2] = windowWidth;
dirtyRect[3] = windowHeight;
そして私のメインループで
if (swap_buffers_region)
swap_buffers_region(egl_dpy, egl_surf, 1, dirtyRect);
else
eglSwapBuffers(egl_dpy, egl_surf);
より滑らかになり、フレーム レートが遅くなったように見えますが、180 ~ 200 FPS の範囲までしか低下しません。そのため、フレーム間で usleep を実行する必要があります。おそらく、重要な GPU 操作の短い間隔でバッファのスワップをブロックするだけでしょうか? または多分私はそれを正しくしていません。わからない。