[cairo] API proposal: Damage Tracking

Soeren Sandmann sandmann at daimi.au.dk
Wed Dec 10 09:57:41 PST 2008


Behdad Esfahbod <behdad at behdad.org> writes:

> 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.
> 
>   - No draw, just get update region for purposes like yours?

Another thing we may want to track:

    - Keep track of "solid" areas that are guaranteed to be completely
      covered with an alpha=1 source, and therefore obscure the
      underlying pixels.

This is useful because such an area can by moved around using
XCopyArea() rather than having to be repaint it. Scrolling is the
obvious usecase, but there are many others, such as dragging the
columns of a tree widget.

It seems that the things you might want to track are all orthogonal:

    BOUNDING_BOX   /* Track bounding box */
    UDPATES        /* Track region covering updates */
    HIT_MASK       /* Track input region */
    SOLID          /* Track solid painting */

We wouldn't have to implement all of these initially, but it probably
makes sense to make the interface extensible.

At the summit, Carl suggested that we could make cairo_region_t
public, then have API like this:

    cairo_tracking_id_t 
    cairo_begin_tracking (cairo_t *cr,
                          tracking_type_t type,
                          cairo_region_t *region);

    void
    cairo_end_tracking (cairo_tracking_id_t id);

Allowing the user to pass in the region solves both the hierarchy
problem and allows the application to keep one update region around
and have it updated several times. This is similar in spirit to the
X11 Damage extension.

A separate 

    cairo_set_updates (cairo_t *cr, cairo_bool_t updates); 

would be required so that you could get the regions without actually
painting anything.

A couple of questions:

    - Does this approach makes sense?

    - What coordinate system do you get updates in? For my purposes
      device coordinates are the most useful since that's the space I
      get input and expose events in.

    - Currently cairo_region_t is a user allocated structure that is
      initialized with cairo_region_init(). It almost certainly makes
      sense to make at least the exposed version a malloc()ed object
      since we don't want to expose the pixman_region_t, let alone set
      that representation in stone.

I do want this feature in 1.10, so any feedback is much appreciated.


Thanks,
Soren


More information about the cairo mailing list