【问题标题】:Using GdkFrameClock to synchronize a GtkDrawingArea with the screen refresh rate使用 GdkFrameClock 将 GtkDrawingArea 与屏幕刷新率同步
【发布时间】:2013-10-13 05:13:49
【问题描述】:
背景
我想使用GdkFrameClock 将小部件的更新与屏幕刷新率同步。这是用于 LCD 屏幕外的视觉刺激响应测量(因此需要尽可能接近精确的帧同步以保证信号的纯度)。
我已阅读该课程的文档,但范围有限;我缺少对 GdkFrameClock 在 GTK 世界中的地位的一些总体理解。在 GitHub 上阅读 GTK 源代码树中的演示对我来说毫无结果。
问题
假设我可以,如何使用GdkFrameClock 将GtkDrawingArea(假设是开罗)的屏幕表示更新同步到屏幕刷新率?
如果我不能,GdkFrameClock 的目的是什么?
【问题讨论】:
标签:
gtk
screen
gtk3
gdk
vsync
【解决方案1】:
我没有在愤怒中使用GdkFrameClock,只是为了进行一点测试,但以下似乎很容易并且对我有用:
- 调用
gtk_widget_add_tick_callback(),传递您希望在每次刷新时运行的函数
- 大约每秒 60 次(或根据您的系统而定),您的回调将被调用
- 完成后,请致电
gtk_widget_remove_tick_callback() 或从回调中返回 FALSE 以停止接收更新。
在第 2 步中,您传递了正在使用的 GdkFrameClock,因此您可以调用 gdk_frame_clock_get_frame_time() 来获取确切的帧时间戳,或者使用 gdk_frame_clock_get_timings() 和 GdkFrameTimings API 来做更多有趣的事情。
以下 Vala 代码(我敢肯定很容易转换为 D :-))显示了这一点:
private static bool on_frame_tick(Gtk.Widget widget, Gdk.FrameClock frame_clock)
{
print("Got frame tick with timestamp %lld\n", frame_clock.get_frame_time());
return true; // Keep going
}
void main(string[] args)
{
Gtk.init(ref args);
var w = new Gtk.Window(Gtk.WindowType.TOPLEVEL);
w.add_tick_callback(on_frame_tick, null);
w.show_all();
Gtk.main();
}
请注意,根据the docs,您需要在处理程序中调用gtk_widget_queue_draw()(或queue_draw_area())才能让GTK 实际执行重绘。这将依次调用相关小部件的draw() 函数。
因此,我要做的是将帧计时信息保存在我的滴答回调中,调用queue_redraw(),然后在我的GtkDrawingArea 的draw() 实现中使用保存的计时信息。