【问题标题】:real time drawing performance issues with GTK/CairoGTK/Cairo 的实时绘图性能问题
【发布时间】:2018-09-20 08:04:22
【问题描述】:

我目前正在开发一种实时数据绘图解决方案,该解决方案能够频繁接收新数据(高达 1kHz)并以较低的速率(例如 50hz)执行重绘。我使用 FLTK 进行了第一个实现,但我想尝试一下 GTK,因为我以前从未使用过它,而且它看起来很有希望。

为了简单起见,我注意到与我使用 FLTK 测量的相比,调用 cairo_stroke() 需要很多时间(FLTK 中没有笔划,首先是 fl_line() 函数)。我尝试尽可能多地限制笔画,但使用 GTK 时渲染时间仍然延长了 5-7 倍。

在 DrawingArea 上绘制期间使用 GTK/Cairo 时,是否有人注意到此类性能问题?关于在哪里寻找减少绘图持续时间的任何线索?

注意:后端(计算要绘制的线条和文本)完全相同,因为它是在一个公共基类中执行的。

【问题讨论】:

  • 也许显示你的渲染代码会有所帮助,你介意吗?你是每次重画整个事情还是使用剪辑?你在用gtk_widget_queue_draw_area吗?
  • 还没写完所以还没推到Github。您已经可以找到这个repo,其中包含指向核心库和当前实现的链接。一切准备就绪后,我将在接下来的几天内添加 GTK 版本的链接。但是,是的,我每次都在重绘整个东西,因为每次重绘时一切都会发生变化(新点,新线,可能是轴的新比例)
  • 重绘整个东西很昂贵,可能不需要。如果你在高速下做太多的工作,你确实会遇到性能问题。你会调用gtk_widget_queue_draw来响应哪个信号?
  • 手动调用或一些计时器(首选解决方案),以 50Hz 最高频率运行。所以不,我不会为每个到达的数据重新绘制所有内容。

标签: c++ gtk cairo


【解决方案1】:

开罗绘图确实不是很快。有两个主要瓶颈:“draw”信号的发出频率以及 cairo 如何在后台绘制线条。

  1. 在我的工作 PC 小部件重绘大约每秒调用 25 次,即 25fps。根据我自己的经验,我看到的 fps 并没有比这多得多,可能是 30 或 40。给予重绘函数更高的优先级可能会导致其他 mainloop 函数被调用得太少。
  2. cairo_line_to 是非常聪明的绘图,它使用抗锯齿、颜色混合、透明度等以精确的像素绘制线条(坐标是 double,因此 1px 的垂直线可以占用两个像素)

据我所知,有两种方法可以加快绘图速度:

  1. 使用 OpenGL
  2. 在图像表面上自定义线条绘制(cairo_image_surface_get_data 并逐像素绘制图像)

当然,还有优化您执行的绘制次数,但这不是完全可扩展的。

【讨论】:

  • 感谢您的信息。我怀疑有一些抗锯齿,因为坐标、宽度等是浮点值,所以你可能对 cairo_line_to 比简单的线条图 FLTK 需要更多的计算是正确的。我将看看图像表面上的自定义线条绘制,但我可能不会太费心,因为我的目标是为用户提供不同的绘图后端,每个后端都有其优缺点
【解决方案2】:

我在https://github.com/pchilds/GtkPlot 有一个 Gtk/Cairo 绘图库

在我制作它的时候,我设计它是为了绘制大型数据集 (10k+)。不利的一面是,代码在被优化和令人作呕的情况下难以维护。但它完成了工作。我没有考虑刷新率,但可能取决于它。据我记得,我没有为每一行划线,但我可能是错的。如果这些点是连接的,您可以创建一条路径并一次性将它们全部描边。

我没有研究过 FLTK 进行比较。

Alexander 对 OpenGL 的提及很好。您还可以查看 cairo 的 wayland 后端。 Wayland 是 X 的替代品,它使用 OpenGL。

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 2020-02-27
    • 2012-10-23
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多