SwapBuffers не занят ожиданием , он просто блокирует ваш поток в контексте драйвера, что делает Windows неверно вычисляет загрузку ЦП: Windows вычисляет загрузку ЦП, определяя, сколько времени ЦП получает процесс простоя + сколько времени программы не проводят в контексте драйвера. SwapBuffers будет блокироваться в контексте драйвера, и ваша программа, очевидно, отнимает это время ЦП у процесса простоя. Но ваш процессор ничего не делает в данный момент, планировщик с радостью ждет, чтобы передать время другим процессам. Процесс бездействия OTOH не делает ничего, кроме как сразу же уступает свое время остальной системе, поэтому планировщик возвращается обратно в ваш процесс, который блокирует в драйвере то, что Windows считает «засорением ЦП». Если вы измерите фактическое энергопотребление или тепловую мощность, для простой программы OpenGL это будет довольно низким.
Это раздражающее поведение на самом деле является FAQ по OpenGL!
Просто создайте дополнительные потоки для параллельной обработки данных. Держите OpenGL в одном потоке, обработку данных - в другом. Если вы хотите сократить использование процессора, о котором сообщалось, добавьте Sleep (0) или Sleep (1) после SwapBuffers. Sleep (1) заставит ваш процесс тратить немного времени на блокировку в пользовательском контексте, так что простаивающий процесс получает больше времени, что сравним цифры. Если вы не хотите спать, вы можете сделать следующее:
const float time_margin = ... // some margin
float display_refresh_period; // something like 1./60. or so.
void render(){
float rendertime_start = get_time();
render_scene();
glFinish();
float rendertime_finish = get_time();
float time_to_finish = rendertime_finish - rendertime_start;
float time_rest = fmod(render_finish - time_margin, display_refresh_period);
sleep(time_rest);
SwapBuffers();
}
В моих программах я использую этот тип синхронизации, но по другой причине: я позволяю SwapBuffers блокировать без каких-либо вспомогательных снов, однако я даю некоторым другим рабочим потокам о том времени, чтобы делать вещи на GPU через общий контекст (например, обновление текстур) и у меня работает сборщик мусора. Нет необходимости точно определять время, но рабочие потоки, заканчивающиеся незадолго до возврата SwapBuffers, позволяют начинать рендеринг следующего кадра практически сразу, поскольку большинство мьютексов уже разблокировано.