Linux OpenGL nVidia
Некоторое время назад обнаружыл, что glxgears, запущенные через честный nvidia glx — т.е. на удалённом хосте. Или на локальном, но через tcp/ip, а не unix domain и с export __GL_FORCE_INDIRECT=1 — так вот, запущенные безо всякого dri и shm — стоят на месте и вообще от них практически ничего не добьёшся. Притом пишут один раз какое-то невменяемо большое число fps. А вся система как-то ощутимо тормозит.
Сегодня разобрался детальней.
Во-первых, они -не тормоз, а медленный газ- не стоят на месте, а весьма медленно крутятся. Притом только новые, у которых видимо угол поворота вычисляется в зависимости от скорости в fps, чтобы они не крутились слишком быстро — у старых всё лучшэ с этим.
Во-вторых, вставленная отладочная печать обнаружыла следующую вещь: эта хрень пишэт в какие-то буфера (ну, в буфер приёма/передачи иксов, очевидно) сразу пачку команд на отрисовку фрэйма — пока не заткнётся. Около 15 тысяч фрэймов помещается.
Эти фрэймы рисуются со скоростью, определённой synctovblank. Т.е. около 60 fps. То есть минут 5 по-хорошэму.
При этом почему-то через несколько секунд проскакивает ещё один фрэйм, потому glxgears получает возможность написать свою дикую скорость да ещё и скорректировать скорость вращения.
И потом всё, на несколько минут оно затыкается.
Очевидный вариант решэния — XSync() или хотя бы XFlush() после каждого фрэйма. В общем, XFlush() почему-то работает дажэ лучшэ — в смысле — с ним — скорость 60 fps, а с XSync() — 30. Но это работает.
Ещё вариант — через nvidia-settings поставить nvidia-settings -a SyncToVBlank=0, тогда будет выдавать свои максимальные fps (у меня около 3000 при варианте через ssh на localhost), и особо не затыкаться, поскольку некогда.
Кстати, скорость через tcp/ip причти одинакова независимо от того, замаплено окно или нет — отличается вроде на 10%. Притом оно на 20% медленнее, чем через direct rendering если окно замаплено и в 3 по-моему раз медленнее если окно незамаплено.
Но вообще — надо с этим что-то делать, поскольку opengl-приложэния привыкли, что если SwapBuffers() прошло, то всё, пользователь ужэ видит на экране картинку — а тут такая херня творится.