使用GdkFrameClock将GtkDrawingArea与屏幕刷新率同步

时间:2013-10-13 05:13:49

标签: gtk screen gtk3 gdk vsync

背景

我想使用GdkFrameClock将窗口小部件的更新同步到屏幕刷新率。这是用于LCD屏幕上的视觉刺激响应测量(因此需要尽可能接近精确的帧同步以获得信号的纯度)。

我已经阅读了该课程的文档,但其范围有限;我错过了对GdkFrameClock在GTK世界中的地位的一些总体理解。在GitHub上浏览GTK源代码树中的演示对我来说毫无结果。

问题

假设我可以,如何使用GdkFrameClock同步更新GtkDrawingArea(假设开罗)的屏幕表示与屏幕刷新率?< / p>

如果我不能GdkFrameClock的目的是什么?

1 个答案:

答案 0 :(得分:5)

我没有在愤怒中使用GdkFrameClock,只是为了进行一些测试,但以下内容似乎非常简单并适用于我:

  1. 调用gtk_widget_add_tick_callback(),在每次刷新时传递要运行的功能
  2. 每秒大约60次(或适合您的系统),您的回调将被称为
  3. 完成后,请致电gtk_widget_remove_tick_callback()或从回叫中返回FALSE以停止接收更新。
  4. 在第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()功能。

    因此,我要做的是在我的tick回调中保存帧定时信息,调用queue_redraw(),然后在我draw()的{​​{1}}实现中使用保存的时序信息}。