1

I'm writing an alternative widget library for AwesomeWM. In this project, I would like to give the user some functions for manipulating nodes, but some operations are easier to optimize than others.

For example, if someone scales an element down, then maybe the element has to be redrawn, and I'll have to mark the dirty areas for redraw on the parent, so not much I can optimize.

But if translate an element in the layout, especially an element on which something very expensive was drawn, for example a trigonometric math function that I used to graph a bunch of points on the surface, then it would be much nicer to store the surface somewhere, tell cairo to use that when redrawing, and mark the dirty areas for redraw on the parent.

My question is: can I cache a surface and make cairo use it later instead of redrawing it every time?
(Example code would be much appreciated. I'm new to cairo.)

  • I just want to say that I agree with Emmanuel's answer below: I think you over-estimate the expensiveness of things. Copying pixels from one buffer to another is also expensive, so I guess redrawing your trigonometric function every time will be fine. – Uli Schlachter Sep 02 '22 at 13:15
  • @UliSchlachter the problem I have is that sometimes I have to draw very many expensive elements (like graphed out mathematical functions). So my thought was that caching this for certain operations like translating those elements (for scrolling for example) would be much more efficient in certain cases. Another use case is: let's say a user wants to add the functionality of translating a node containing the entire UI (with very many elements) by click and dragging. I thought I could maybe let the user of the library "mark" certain nodes to be drawn from a cache instead of redrawn every time. – DesertCarMechanic Sep 03 '22 at 09:28
  • Maybe you could store the Cairo path instead of the whole surface? Uli (who you replied to) implemented a lot of optimizations over the years which makes storing surfaces rarely worth it. Back in v3.5.0, it was much, much faster to do caching, but as of v4.3, it became slower most of the time. We don't have use GPU acceleration in the wiboxes, so all composition happen in the CPU, which is not exactly fast at doing this kind of operations. – Emmanuel Lepage Vallee Sep 04 '22 at 01:13
  • @EmmanuelLepageVallee Could you give me a small example showing me how I could store just the path? If I knew how, I would try it. Thank you both for the replies, I'll try your suggestions. – DesertCarMechanic Sep 12 '22 at 15:56
  • A cairo recording surface is the easiest way. – Emmanuel Lepage Vallee Sep 21 '22 at 05:34

1 Answers1

1

Yes, it can be done. Look at the lib/wibox/container/background.lua from the main codebase for how to do it with a recording surface. Look in my old github (github.com/elv13) modules for how to do it with set_source_surface. Keep in mind that a widget has to be very expensive to redraw for this to be worth it. Normally, it causes more problems than it solves. If you manually paint, also make sure your origin is aligned to a pixel, otherwise it looks blurry.