[cairo] Using pre-existing textures

Carl Worth cworth at cworth.org
Thu Feb 7 15:09:15 PST 2008


On Fri, 08 Feb 2008 07:04:51 +1100, Robert Norris wrote:
> On Wed, 6 Feb 2008 11:46:45 -0600, Matt Hoosier 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.
>
> 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.

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)
{
    cairo_surface_t *surface, *image;
    cairo_t *cr;
    cairo_status_t status;

    surface = cairo_surface_create_similar (other,
					    content_from_format (format),
    					    width, height);

    image = cairo_image_surface_create_for_data (data, format,
						 width, height, stride);

    cr = cairo_create (surface);
    cairo_set_source_surface (cr, image, 0, 0);
    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint (cr);

    status = cairo_status (cr);

    cairo_destroy (cr);

    if (status) {
	/* Do error handling here. */
    }

    return surface;
}

And then the surface returned from this function holds the content
from "data" and will work efficiently with "other".

Now, the data copying happening in this function, (from an image
buffer to an xlib surface), could perhaps before performed more
efficiently by using XShm, (which cairo isn't currently doing). So
some people have recently been exploring extending cairo to provide
that kind of functionality.

Also, the content_from_format function mentioned above actually needs
to be fleshed out. There is a version of this within cairo already
that looks about like this:

cairo_content_t
_cairo_content_from_format (cairo_format_t format)
{
    switch (format) {
    case CAIRO_FORMAT_ARGB32:
        return CAIRO_CONTENT_COLOR_ALPHA;
    case CAIRO_FORMAT_RGB24:
        return CAIRO_CONTENT_COLOR;
    case CAIRO_FORMAT_A8:
    case CAIRO_FORMAT_A1:
        return CAIRO_CONTENT_ALPHA;
    }

    /* Error case here. Should not be reached. */
    return CAIRO_CONTENT_COLOR_ALPHA;
}

We should probably just go ahead and export that functionality. I
suppose it deserves a cairo_format prefix, (alongside the new
cairo_format_stride_for_width). Perhaps it should just be named
cairo_format_content ? cairo_format_to_content?

Anyway, Matt, I hope that helps,

-Carl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20080207/ff443805/attachment.pgp 


More information about the cairo mailing list