使用 Cairo 绘图时有什么方法可以加快/减少 CPU 使用率?
我编写了一个应用程序,它使用 Cairo 在屏幕上绘制内容(准确地说是在 Gtk::DrawingArea 上)。它需要经常重绘一切。事实证明,尽管绘制的图形非常简单,但 X 服务器在重绘时会使用大量 CPU,并且应用程序运行速度非常慢。有什么办法可以加快这个速度吗?或者也许我不应该使用 DrawingArea 和其他一些小部件?
我绘制的是一组矩形,用户可以通过用鼠标拖动它们来移动它们。整个绘图是通过 on_expose_event 完成的,但是当鼠标指针移动时(按下按钮),我调用queue_draw() 来刷新绘图。
I wrote an app that uses Cairo to draw things on screen (on a Gtk::DrawingArea, to be exact). It needs to redraw everything frequently. It turns out, that despite the draphics drawn are very simple, the X server uses LOTS of CPU when redrawing, and the applications works terribly slow. Is there any way to speed this up? Or maybe I shouldn't use DrawingArea and some other widget?
What I draw is set of rectangles, which user can move around by dragging them with mouse. The whole drawing is done withing on_expose_event, but as the mouse pointer moves around (with button pressed), I call queue_draw() to refresh drawing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只需检查几件事:
您的绘制是否在公开事件中完成?
将图像绘制到开罗表面,然后在公开事件中只需从该表面复制到小部件的表面。
您是否仅剪切和绘制必要的区域?
暴露事件为您提供需要重绘区域的
X、Y、宽度、高度
。在开罗,在表面上创建一个具有这些尺寸的矩形并调用clip
,这样您就不会浪费时间重新绘制不需要的东西。Just a couple things to check:
Is your drawing done in the expose event?
Draw your image to a Cairo Surface, and then in the expose event simply copy from that surface to the widget's surface.
Are you clipping and drawing only the region necessary?
The expose event gives you an
X, Y, width, height
of the area that needs to be redrawn. In cairo, create a rectangle on your surface with these dimensions and callclip
so that you aren't wasting time redrawing stuff that doesn't need to be.绘图是昂贵的,尤其是文本绘制已经成为 GUI 中最消耗 CPU 资源的任务。
加快速度的唯一方法是减少绘制项目的数量。检查您是否真的只绘制了必要的项目。暴露事件给你一个矩形。仅刷新小部件的这一部分。
也许可以将项目缓存在位图中。
例如,为了平滑滚动,它可以帮助将内容绘制到一个位图中,该位图例如大 500 像素,这样在大多数情况下您只需要复制图像并且根本不需要绘制任何内容(您通常会得到暴露的矩形,这些矩形是滚动期间只有 5 到 10 个像素高)。
但是您需要向我们提供更多信息您正在绘制什么以及系统负载是什么,以获得更好的答案。
Drawing is expensive, especially text drawing has become the most CPU expensive task of a GUI.
The only way to speed this up is to reduce the amount of drawn items. Check if you really only draw the items that are necessary. The expose-event is giving you a rectangle. Only refresh this part of the widget.
Maybe cache items in a bitmap.
For smooth scrolling for example it can help to draw the content into a bitmap that is for example 500 pixels larger so that in most cases you just need to copy the image and don't draw anything at all (you usually get expose rectangles that are just 5 to 10 pixels high during scrolling).
But you need to give us more information what you are drawing and what the system load is to get a better answer.
我发现这篇关于开罗线程绘图的文章来解决速度问题,也许有帮助:
http://cairgraphics.org/ threaded_animation_with_cairo/
关于高 CPU 使用率:
您是否为 X 安装了正确的硬件加速驱动程序?
I found this article about threaded drawing in cairo to solve the speed-problem, maybe that helps:
http://cairographics.org/threaded_animation_with_cairo/
About the high CPU usage:
Do you have proper hardware accelerated drivers installed for X?
我最终通过使用锁定标志强制使用最大 25 fps。
这是示例代码,但这就是想法。它将禁止重绘频率超过每 20 毫秒一次。
I finally forced to use maximally 25 fps, by using a lock flag.
This is a sample code, but that's the idea. It will disallow redraw to be done more often then once per 20 ms.