我写了一个使用Cairo在屏幕上绘制内容的应用程序(准确地说是在Gtk :: DrawingArea上)。它需要经常重绘所有内容。事实证明,尽管绘制的字形非常简单,但X服务器在重绘时使用了大量的CPU,而且应用程序运行速度非常慢。有什么方法可以加快速度吗?或者我可能不应该使用DrawingArea和其他一些小部件?
我绘制的是一组矩形,用户可以通过鼠标拖动它们来移动。整个绘图是使用on_expose_event完成的,但是当鼠标指针移动时(按下按钮),我调用queue_draw()来刷新绘图。
答案 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毫秒一次。