[cairo] Patch improving fallbacks

David Reveman davidr at novell.com
Mon Jan 31 05:32:02 PST 2005


On Sun, 2005-01-30 at 18:52 -0500, Owen Taylor wrote:
> After a number of rewrites, I've come up with a patch I'm pretty happy
> with to handle fallbacks. The old setup had
> had two virtualized functions in the surface backend:
> 
>   cairo_private cairo_image_surface_t *
>   _cairo_surface_get_image (cairo_surface_t *surface);
> 
>   cairo_private cairo_status_t
>   _cairo_surface_set_image (cairo_surface_t	     *surface,
> 			    cairo_image_surface_t  *image);
> 
> The semantics of these functions wasn't fully specified, but basically
> they allow getting the entire surface as an image or setting an image
> over the entire surface. When working on the Win32 backend, I ran
> into various problems with these. Getting the entire image was hugely
> expensive. There was no way of associating extra information with
> the returned image to be used when it was freed (for example, a DIB
> wrapping the image.) Different usages ... as source or as dest
> weren't clearly distinguished and needed different handling in the backend.
> 
> My patch replaces these two functions with 5:
> 
>   /* Get the entire surface as an image to use as a source */
>   cairo_private cairo_status_t
>   _cairo_surface_acquire_source_image (cairo_surface_t         *urface,
> 				       cairo_image_surface_t  **image_out,
> 				       void                   **image_extra);
> 
>   /* Release surface from acquire_source_image() */
>   cairo_private void
>   _cairo_surface_release_source_image (cairo_surface_t        *surface,
> 				       cairo_image_surface_t  *image,
> 				       void                   *image_extra);
> 
>   /* Get a portion of the surface to use as the destination */
>   cairo_private cairo_status_t
>   _cairo_surface_acquire_dest_image (cairo_surface_t         *surface,
> 				     cairo_rectangle_t       *interest_rect,
> 				     cairo_image_surface_t  **image_out,
> 				     cairo_rectangle_t       *image_rect,
> 				     void                   **image_extra);
> 
>   /* Write-back and release surface from acquire_dest_image() */
>   cairo_private void
>   _cairo_surface_release_dest_image (cairo_surface_t        *surface,
> 				     cairo_rectangle_t      *interest_rect,
> 				     cairo_image_surface_t  *image,
> 				     cairo_rectangle_t      *image_rect,
> 				     void                   *image_extra);
> 
>   /* Make a copy of @src compatible with @surface */    
>   cairo_private cairo_status_t
>   _cairo_surface_clone_similar (cairo_surface_t  *surface,
> 				cairo_surface_t  *src,
> 				cairo_surface_t **clone_out);
> 
> I tested this with image backend, and with the Xlib backend both with
> and without RENDER (the without RENDER-case tests out the fallback
> operations).  And it seemed to work pretty well in all cases. I haven't
> updated the XCB, Quartz, or Glitz backends for the backend API changes,
> but I don't expect problems; if you could implement the old interfaces,
> you can implement the new ones, and there is a good possibility for 
> consirable performance improvements.

It's going to be a great performance improvement to the glitz backend,
especially when used with older hardware. I'll implement the new backend
functions once this gets into cvs.

> 
> I've merged the part of David Reveman's patch that conflicts with
> these changes to CVS to avoid later merge problems. But there are
> still chunks of that that aren't committed yet.

I hope my new patch doesn't give us too much trouble.

> 
> Comments and possible issues:
> 
>  - The source and dest operations are clearly similar, I decided to
>    keep them separate because their behavior is enough different
>    that implementation became a big if () {} else {} mess if
>    they were combined. Backends can use separate helper functions
>    internally.
> 
>  - We might want eventually to have area arguments on the source image
>    as there are on the dest image. It's tricky to get right,
>    especially when repeat or a transformation is involved. But could be a 
>    big win when displaying a small portion of a large source image.
> 
>  - The code doesn't properly fail when a Window is used as a source.
>    And if it does, it is going to leak CAIRO_INT_STATUS_UNSUPPORTED
>    back to the user.
> 
>  - The no-RENDER Xlib backend still needs a lot of work. It BadMatches
>    regularly (needs to use a temporary pixmap when copying from a window),
>    doesn't handle format-conversion when the display format doesn't match
>    a Cairo format, and so forth. But it's certainly better with these
>    changes than before.
> 
>  - There are a few fixes for the XLib backend (text didn't work for non-RENDER,
>    and after testing out using server-side temporary images, I switched
>    _cairo_xlib_surface create_similar() to use image surfaces for 
>    the non-RENDER case.)
> 
>  - There is a change to the image backend to keep the format around
>    in image->format. It doesn't work perfectly because you can have
>    images that don't match any Cairo format, so I hacked around that
>    using (cairo_format_t)-1. Not sure what the right long-term solution is;
>    we may want a CAIRO_FORMAT_OTHER.
> 
> 
> _______________________________________________
> cairo mailing list
> cairo at cairographics.org
> http://lists.freedesktop.org/mailman/listinfo/cairo

-David




More information about the cairo mailing list