[cairo] Cairo efficiency with massively long lines

Paul Davis paul at linuxaudiosystems.com
Fri Feb 23 13:43:45 PST 2007

On Fri, 2007-02-23 at 21:26 +0000, Damon Chaplin wrote:
> On Thu, 2007-02-22 at 13:09 -0500, Paul Davis wrote:
> > Greetings Cairo folks. A few people here were incredibly helpful with my
> > last questions about planning the move of Ardour (http://ardour.org) to
> > a Cairo-based canvas. We've run into another issue with our current use
> > of GnomeCanvas, and I wanted to check that Cairo would handle it
> > properly before I waste time trying to find a workaround.
> > 
> > Will Cairo efficiently render a line that has two coordinates at zero
> > and (say) 2^32-1 or 2^64-1 (on the x-axis) ?
> You might run into cairo's fixed point integers limit (internally it
> uses a 32-bit int with 16 bits for the integer value and 16-bits for the
> fractional part).

oh no. thats a disaster for us. the old GnomeCanvas used floats and we
had all kinds of icky hacks to deal with the fact that it wasn't
accurate over the full range that we actually needed. now it uses
doubles (life is good!), and we're about ready to move on to 64 bit
ranges. this could be a nasty setback. our coordinate space spans the
entire range of possible sample values from 0 .. 2^N-1 where N is
currently 32 and will move to 64.

> > The current GnomeCanvas code generates a "micro-tile array" (UTA; a list
> > of 32x32 pixel cells) to describe the areas of the image that need to be
> > re-rendered, and with a line like this, the UTA is obvously huge - it
> > correctly reflects the fact that the area to be re-rendered is enormous.
> > As a result, when our canvas has numerous of these objects on it, any
> > operations that cause a recomputation of what needs to be rendered are
> > dog slow.
> > 
> > Does Cairo's internal implementation correctly handle this kind of
> > situation? Presumably, the correct limitation is to not compute a UTA
> > that extends beyond the current visible bounds of the
> > image/canvas/pixbuf. I'd appreciate clarification on how Cairo does
> > this.
> My inclination would be to write your own custom canvas items that only
> draw what is visible. Though I hope someone who knows more can give a
> definitive answer.

I know enough about the canvas to know what is going on here. The
problem isn't drawing. The canvas has an update phase, done once per
redraw, and the update phase lets the items that will be rendered update
their data structures (e.g. after they've had a color or coordinate or
other property change). The existing line item needs to figure out what
parts of itself might need redrawing, and after we change some
properties, the answer is "everything". this means 2^N-1 pixels (at
least). the slowdown doesn't occur during rendering - in fact, the lines
in question are not even visible. the slowdown is all during this
"update" phase.

changing the canvas architecture doesn't seem like an option for us, but
what is really needed is an update phase that says "update your own
stuff, oh, and by the way, the only part of you that will be rendered
lies within the following clip path ...."

this would allow the item to do a saner evaluation of "what needs to be
re-rendered next time we are rendered" than the current design, which
says "update your own stuff, and i'll give you no hints at all about
which parts of you are visible", thus forcing an evaluation of the
entire extent of the item.

> (If you want to try to use my GooCanvas widget for ardour, I'd be
> willing to help out with that. C++ bindings are being written for it.)

GooCanvas is already the most likely canvas for us. The C++ bindings
are, IIRC, by the "other" Paul Davis :) The coordinate space limit
mentioned above sounds potentially crippling though.


More information about the cairo mailing list