[cairo] Using pre-existing textures
matt.hoosier at gmail.com
Fri Feb 8 06:35:20 PST 2008
Thanks, Robert and Carl. I've pieced together a version of what I had
in mind by using raw Xlib and XRender calls, but doing it with Cairo
would certainly be much less error-prone and more general. A couple
small followups to your replies follow.
> On Fri, 08 Feb 2008 07:04:51 +1100, Robert Norris wrote:
> > Is there a way to use existing image data as a texture/pattern? I'd
> > like to exploit Cairo's nice XRender backend to do accelerated blits
> > of those from a Gtk program.
Well, yes and no. There are plenty of ways to get Gtk to display raw
image data, but all which support alpha blending require re-uploading
the image data to X every time you expose.
On Feb 7, 2008 5:09 PM, Carl Worth <cworth at cworth.org> wrote:
> > You want cairo_image_surface_create_for_data().
> Yes, but there's also more to it than that.
> If you want a Render-accelerated blit, then you'll need to get data to
> an xlib surface and the Render blit will be painting from one cairo
> xlib surface to another.
Right, the part which wasn't clear was how to get the data resident on
an underlying X drawable/picture so that it wasn't transported again
every time that I paint the cairo_t.
> And just like with any other backend, the best way to create that
> intermediate surface is with cairo_surface_create_similar, (that is,
> if you've got one cairo xlib surface 'surface' then
> 'cairo_surface_create_similar (surface, ...);' will create another one
> for you.
> So then you've got a cairo xlib surface that will work efficiently as
> a source, but you have your existing image data that you want to
> upload to it. This is where cairo_image_surface_create_for_data comes
> in. So an entire sequence might be:
> /* Create an intermediate surface with data from "image"
> * and of an appropriate type to work efficiently with "other"
> cairo_surface_t *
> create_intermediate_surface (cairo_surface_t *other,
> unsigned char *data,
> cairo_format_t format,
> int width, int height,
> int stride)
A small point about which I've never been sure: the normal idiom that
one seems in example Gtk code which draws using Cairo, is
expose_event (GtkWidget *w, GdkEventExpose *event)
cairo_t *cr = gdk_cairo_create (...);
/* draw */
But that would require you to toss away any X backend state
accumulated at the end of the expose handler. Is it legal to keep a
cairo surface like the intermediate one returned by your function
above, alive beyond the immediate expose cycle? E.g., is it referring
to the double-buffered short-lived X pixmaps that back the GdkDrawable
during expose cycles?
It would be extremely nice to just hold this surface and do a simple
fills from it in successive expose handlers.
More information about the cairo