[cairo] API proposal: Damage Tracking
Behdad Esfahbod
behdad at behdad.org
Thu May 8 13:58:50 PDT 2008
On Thu, 2008-05-08 at 16:55 -0400, Behdad Esfahbod wrote:
> Hi Soeren,
>
> This is all very interesting. But I think we should think a bit more
> about it and definitely improve the naming. A very similar
> functionality is to be able to compute the bounds of drawing operations.
> So we have:
>
> - actual drawing
> - bounds
> - update region
> - hit testing?
>
> The way OpenGL does it is that you can switch between drawing and hit
> testing. In cairo, may be better to be able to turn each on/off. So
> you can do all of:
>
> - Draw to a local buffer, get update region and push that to your
> remote. It can be used internally to improve xlib fallback backend as
> well as directfb kind of backends. We were talking about this recently.
>
> - Don't draw, just compute bounds. Right now for this kind of needs
> you have to create a similar surface and draw to it. You have to use a
> similar surface to get the same font options, etc. Though most of the
> times when you need the bounds you need it to create a surface of the
> right size. So I'm not sure how useful this will be.
Forgot to say. I do need this in user-fonts. The way I do it now is
that I added a "null" surface. One that does nothing. Then I replay
back my meta-surface to an analysis surface connected to a null surface,
then ask the analysis surface for extents. Would have been much easier
if I could simply ask my cairo_t for the extents.
One complexity of this all to keep in mind is the space that the
region/bounds are kept in. Simplest would be to track in device space.
But in user-font and in PS/PDF we do need extents in a different space.
Right now analysis surface converts extents of individual operations to
the target space and takes the union of those. That's quite suboptimal
for something like rotated text...
behdad
> - No draw, just get update region for purposes like yours?
>
> And tracking bounds/region per cairo_save() level would be really cool,
> yeah.
>
> Cheers,
>
> behdad
>
> On Thu, 2008-05-01 at 02:58 +0200, Soeren Sandmann wrote:
> > Hi,
> >
> > In a canvas/toolkit type project I am playing around with, I need the
> > ability to track the 'damage' done by painting with a cairo context.
> >
> > This is useful to generate repaint areas, ie., the area that the
> > application needs to repaint. When something happens that causes a
> > canvas item to change it appearance, damage tracking would allow the
> > application to simply do this:
> >
> > static void
> > invalidate (Item *item, cairo_t *cr)
> > {
> > cairo_begin_damage_tracking (cr);
> >
> > <paint the item>
> >
> > damaged = cairo_end_damage_tracking (cr);
> >
> > add_to_repaint_region (damaged);
> >
> > free (damaged);
> > }
> >
> > void
> > on_event ()
> > {
> > cairo_t *cr = create_cr();
> >
> > /* Invalidate old position */
> > invalidate (item, cr);
> >
> > <update item information>
> >
> > /* Invalidate new position */
> > invalidate (item, cr);
> >
> > cairo_destroy();
> > }
> >
> > The big benefit is that this frees the application from keeping track
> > of the exact region that is covering the item. Instead it can just
> > compute it as needed.
> >
> > Currently the best an application can do is call
> > cairo_stroke/fill_extents() after before each paint operation, but (a)
> > this is inconvenient, (b) the extent rectangles are too pessimistic in
> > many cases, and (c) it may not be possible to do if the painting is
> > being done by a library.
> >
> > So I am proposing this new API:
> >
> > void cairo_begin_damage_tracking (cr);
> > cairo_rectangle_list_t * cairo_end_damage_tracking (cr);
> >
> > Cairo would keep track of a stack of rectangle lists corresponding to
> > the nesting level. Whenever cairo_end_damage_tracking() is called, a
> > the topmost list is returned after a copy of it was unioned with the
> > next list on the stack.
> >
> > Open question: In the proposal above, nothing is actually painted when
> > tracking damage. I think it could potentially be useful to allow
> > damage tracking and painting to go on at the same time, say for
> > applications that would like to keep track of the last thing they
> > painted.
> >
> > A way to accomplish that would be to simply have
> > begin_damage_tracking() not turn off painting, but then also provide
> > begin/end_disable_painting() calls.
> >
> >
> > Soren
> > _______________________________________________
> > cairo mailing list
> > cairo at cairographics.org
> > http://lists.cairographics.org/mailman/listinfo/cairo
--
behdad
http://behdad.org/
"Those who would give up Essential Liberty to purchase a little
Temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin, 1759
More information about the cairo
mailing list