2015-12-28 3 views
0

В целях тестирования мне бы очень хотелось иметь возможность вручную управлять частотой обновления фрейма моего приложения GTK3. Переход медленнее, я просто сплю в функции рендеринга. Однако максимальная частота кадров, которую я могу достичь, - это частота обновления моего монитора 60 Гц.Вручную контроль над виджетами GTK с изменением скорости обновления

Я обнаружил, что я могу добавить неиспользуемый слот обновления в основной цикл, используя gdk_threads_add_idle, однако даже если я вызываю gtk_gl_area_queue_render изнутри этой функции, фактическая функция рендеринга работает только на частоте обновления моего монитора.

Есть ли способ принудительного повторного рендеринга быть «немедленным» по запросу? Я пробовал вручную вызывать слот рендеринга, и это приводит к немедленной активации функции повторного рендеринга, но она вообще не обновляет экран.

void update_auto(gpointer user_data) 
{ 
    // ... do some update stuff 
    // somehow get the appropriate GtkGLArea from user_data 
    GtkGLArea* area = get_area(user_data); 
    gtk_gl_area_queue_render(area); 
    // capped at 60Hz 
} 

void update_manual(gpointer user_data) 
{ 
    // ... do some update stuff 
    // somehow get the appropriate GtkGLArea from user_data 
    GtkGLArea* area = get_area(user_data); 
    gtk_gl_area_make_current(area); 
    render(area,gtk_gl_area_get_context(area), user_data); 
    // even though render was called, screen never updates 
} 

void render(GtkGLArea* area, GdkGLContext* context, gpointer user_data) 
{ 
    // ... render 
} 

void setup_widget() 
{ 
    // ... some init stuff 
    // only one of these is used at a time 
#if TEST_FLAG == 0 
    gdk_threads_add_idle(update_manual, user_data); 
#elif TEST_FLAG == 1 
    gdk_threads_add_idle(update_auto, user_data); 
#elif TEST_FLAG == 2 
    gtk_widget_add_tick_callback((GtkWidget*) area, update_auto, user_data, NULL); 
#else 
    gtk_widget_add_tick_callback((GtkWidget*) area, update_manual, user_data, NULL); 
#endif 
} 
+0

Какова точка рендеринга быстрее, чем частота обновления монитора? –

+0

Одной из причин для меня сейчас является тестирование производительности. Меня интересует, как различные изменения кода в цикле рендеринга влияют на производительность, и я бы предпочёл не использовать сцены достаточно большие, чтобы значительно замедлить цикл рендеринга. Я также хочу отлаживать некоторые нерегулярные проблемы заикания кадров, возникающие при больших сценах. – helloworld922

+0

Возможно, механизм рендеринга * не будет * обновляться быстрее. Я не знаю, относится ли это к светодиодным/ЖК-дисплеям, но со старыми ЭЛТ обновление было сделано в период обратного хода для создания плавного перехода кадра. –

ответ

0

Я нашел хак для форсирования немедленного перерисовать:

GtkGLArea расширяет GtkWidget класс, так что я могу использовать функцию отрисовки для немедленного повторного розыгрыша.

// inside update 
// get the proper clipping so we don't draw over other widgets 
GtkAllocation reg; 
gtk_widget_get_allocation((GtkWidget*)area, &reg); 
cairo_region_t *creg = cairo_region_create_rectangle(&reg); 
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window((GtkWidget*)area)); 
gdk_cairo_region(cr, creg); 
cairo_clip(cr); 

gtk_widget_draw((GtkWidget*)area, cr); 
cairo_destroy(cr); 
cairo_region_destroy(creg); 

можно затем использовать функцию при желании gdk_threads_add_idle, которая будет счастливо вызывать функцию обновления как можно быстрее.

Даже без использования gdk_threads_add_idle, я заметил, что даже использование этого метода с gtk_widget_add_tick_callback имеет значительно более согласованные частоты кадров. Прежде, чем я заметил, что частота кадров спорадически перепрыгивает между 15/30/60 fps, кажется, указывает на то, что ей не хватало один или два цикла обновления. Эта проблема полностью исчезла сейчас, и я получаю почти постоянный N fps, где N ограничено 60 для небольших сцен.

Я не сталкивался с какими-либо проблемами, но делаю это так, но это, похоже, работает с окнами, содержащими больше, чем просто один GtkWidget. Я не пробовал совмещенные виджеты, хотя я подозреваю, что единственным решением здесь является также перерисовать все перекрывающиеся виджеты.

Смежные вопросы