使用Cairo绘图时,有什么方法可以加快/减少CPU使用率?

时间:2011-07-31 10:46:34

标签: c++ gtk cairo gtkmm

我写了一个使用Cairo在屏幕上绘制内容的应用程序(准确地说是在Gtk :: DrawingArea上)。它需要经常重绘所有内容。事实证明,尽管绘制的字形非常简单,但X服务器在重绘时使用了大量的CPU,而且应用程序运行速度非常慢。有什么方法可以加快速度吗?或者我可能不应该使用DrawingArea和其他一些小部件?

我绘制的是一组矩形,用户可以通过鼠标拖动它们来移动。整个绘图是使用on_expose_event完成的,但是当鼠标指针移动时(按下按钮),我调用queue_draw()来刷新绘图。

4 个答案:

答案 0 :(得分:9)

只需要检查几件事:

您的绘图是在曝光事件中完成的吗?

将图像绘制到开罗表面,然后在曝光事件中,只需从该表面复制到窗口小部件的表面。

您是否只剪裁和绘制必要的区域?

公开事件会为您提供需要重绘的区域X, Y, width, height。在cairo中,使用这些尺寸在曲面上创建一个矩形并调用clip,这样您就不会浪费时间重绘不需要的东西。

答案 1 :(得分:3)

绘图很昂贵,尤其是文本绘图已经成为GUI中CPU成本最高的任务。

加快这一速度的唯一方法是减少绘制项目的数量。检查您是否真的只绘制了必要的项目。 expose-event给你一个矩形。仅刷新小部件的这一部分。

可能在位图中缓存项目。

例如,对于平滑滚动,它可以帮助将内容绘制到例如500像素更大的位图中,这样在大多数情况下,您只需要复制图像并且根本不绘制任何内容(通常会暴露出来)滚动期间高度仅为5到10像素的矩形。

但是你需要向我们提供更多信息,告诉我们你正在绘制什么以及系统负载是什么来获得更好的答案。

答案 2 :(得分:0)

我发现这篇文章关于cairo中的线程绘图来解决速度问题,这可能有所帮助:

http://cairographics.org/threaded_animation_with_cairo/

关于高CPU使用率:

您是否为X安装了适当的硬件加速驱动程序?

答案 3 :(得分:0)

我最终通过使用锁定标志强制使用最大25 fps。

bool lock = 0;
bool needs_redraw = 0;

void Redraw(){
    if(lock){
        needs_redraw = 1;
        return;
    }

    //draw image to a surface

    needs_redraw = 0;
    lock = 1;
    Glib::signal_timeout().connect(Unlock, 20);

    queue_draw();
}

bool Unlock(){
    lock = 0;
    if(needs_redraw) Redraw();
    return false;
}

void on_expose_event(something){
    //copy image from surface to widget's context
}

这是一个示例代码,但这就是主意。它将禁止重绘更频繁,然后每20毫秒一次。