Re: pixbuf<->cairo_surface_t conversion



Hi,

I thought of another approach to this problem. Don't expose the pixbuf
format at all; keep it as-is. However, add:

 gdk_pixbuf_get_cairo_surface()
 gdk_pixbuf_new_from_cairo_surface(cairo_surface_t *surface);

Now, keep the cairo surface internally, strong-ref'd by the pixbuf.
The pixbuf would have pixels == NULL. If someone does
gdk_pixbuf_get_pixels(), then lazily create the old pixbuf format and
keep that copy of the pixels around. Otherwise, never create the old
format.

If you create a pixbuf NOT from a cairo surface, then the reverse
occurs. pixels != NULL, and a surface is lazily created and kept
around if anyone does gdk_pixbuf_get_cairo_surface().

There are various APIs in gdk-pixbuf that call get_pixels() in the
implementation. These would all be modified to use cairo_surface_t
operations instead if the cairo_surface was set, and use the existing
pixbuf code otherwise.

So basically a GdkPixbuf can be either the old stuff internally, or a
cairo surface internally, or have both cached, but with the same API
either way.

Some downsides:
 - two copies of the pixels would be kept for the two formats, in the
case where we create a pixbuf in old format and then draw it.
 - APIs that modify the pixels might have to either modify both
copies, or discard one of them to be lazily recreated - but wouldn't
know which to toss
 - if you modified the surface pixels or the old-style pixels by hand,
it would not affect the other format - this could be VERY surprising.

The main upside would be zero new API, other than to/from cairo surface.

The downside is that if something dumb is happening that ends up
repeatedly converting pixels or keeping both pixel representations
around eating memory, it would not necessarily be obvious.

In this scheme, perhaps get_pixels, get_n_channels, get_colorspace,
etc. (all the internal representation APIs) would be deprecated. You
are supposed to port that code to get the surface and then mess with
the cairo surface. Conceptually, GdkPixbuf's exposed pixel buffer
representation becomes cairo_surface_t instead of colorspace,
n_channels, get_pixels, etc.; GdkPixbuf is a cairo_surface_t wrapper
instead of a guchar* wrapper.

If/when get_pixels can be removed entirely, then the internal
representation could always be cairo_surface_t _only_. The old
constructors would immediately convert to cairo format. get_pixels()
is the only reason external code would ever care about pixbuf internal
representation.

Havoc


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]