[cairo] pattern/glitz update merge
Owen Taylor
otaylor at redhat.com
Mon Feb 7 11:01:48 PST 2005
On Mon, 2005-02-07 at 17:57 +0100, David Reveman wrote:
> On Sun, 2005-02-06 at 23:16 -0500, Owen Taylor wrote:
> > On Mon, 2005-02-07 at 04:55 +0100, David Reveman wrote:
> > > I did some work today to get my updates to the pattern system and to the
> > > glitz backend merged with current cvs. The patch is actually too big for
> > > the list so I put it here:
> > > http://www.cs.umu.se/~c99drn/cairo-pattern-merge-1.diff
> > >
> > > It modifies the new fall-back system slightly. I moved some of the
> > > fall-back stuff into the cairo_image_surface struct, it cleaned up
> > > things quite nicely and made the merge a lot easier.
> >
> > You know, at one point last weekend, I had it pretty much as you
> > have it in your patch, then rewrote it all because there were
> > some very difficult to deal with memory management problems.
>
> I don't think there's any general memory management problem with this
> solution. acquire_source/dest returns an image surface and when this
> surface is destroyed the backend is allowed to push these bits to the
> real target surface. That's the way we want this fall-back system to
> work, right? However, this means that a backend that wants to push bits
> back to a target surface (by using the release_image call-back) have to
> return a new cairo_image_surface from acquire_dest and not just a
> reference, as the image surface will otherwise never be destroyed and
> release_image will not be called correctly.
If I understand your argument, what you are saying is that:
- In the case where we are creating a new win32_surface/image_surface
pair, the image_surface needs to reference the win32_surface, but
not vice-versa since the win32_surface is never exposed.
- In the case where we returning the image_surface for an existing
win32_surface/image_surface pair, the win32_surface already
references the image surface, but we don't need the reverse link
since the win32_surface is going to be kept around until the
image_surface is freed.
While that is true, it introduces to very ugly things:
In the backend:
Whether or not win32_surface->image should be destroyed when the
win32_surface is destroyed will depend on how the win32_surface
was created.
In the calling code:
The caller must make sure that all references to the acquired
image are dropped before it returns (and the win32_surface might
be destroyed.) So the "freedom" of having replacing
acquire/release_source_image() with a get_image() is largely
illusory, but it's much easier to slip up.
That's something I don't want to see. If you badly need a
get_source_image() rather than acquire/release_source_image()
pair, I do know how to implement it in the win32 backend. What
you do is replace
=> image_surface
win32_surface
=> HDC,DIB
With:
win32_surface => image_surface => HDC,DIB
That is, you attach the DIB to the image_surface using
cairo_surface_set_data (or your ad-hoc system), so that we
can free the win32 surface but keep the image_surface around.
That actually allows you to have a get_source_image() which really
delivers the promise of "here is an image, do what you want with
it". On the other hand, it is some rewriting to change things
to work that way. What
particular problems did acquire/release_source_image cause for you?
[...]
> I don't think we should avoid this solution. Having to pass around the
> "extra" pointer with the image and to track if it should be released
> with release_source or cairo_surface_destroy is just too painful.
The pain is largely intentional ... it forces the discipline needed
to get the memory management right. We can get rid of the extra
pointer easily enough by introducing cairo_surface_set_data(), but
the need for rigorous pairing of acquire/release is still there unless
we change the win32 backend (and similar backends, though there are
none currently) as outlined above.
> > How can we reduce the size of the diff between your working tree and
> > CVS? Are there patches you can merge in independently of the rest?
>
> I'm afraid not :(
> I actually left some things out of it already, like the overall surface
> alpha acceleration using a mask surface...
> I can merge some small updates to cairo_gstate.c separately, but the big
> pattern update thing needs to go in at once. I could also move out some
> updates to the glitz backend and commit them separately but I don't see
> any point in that.
Well, the advantage would be that it would be easier to review your
patch and see what it is doing. Right now, I look at it, and have
thoughts like "Oh yeah, this is the gstate pattern initialization stuff
we discussed earlier".
The problem with just accumulating patches is that I'm afraid that
we're in a situation where we go from
XXXXXXXXXYYYYYYYYYYY
^^^^^^^^^-----------
OK NOT OK
To:
XXXXXXXXXYYYYYYYYYYZZZZZZZZZZZ
^^^^^^^^^^^^^^^^^^^
OK NOT OK
That we'll never come to a consensus. It would be a lot easier if
there was a patch that was only XXXXXXX even if the YYYYYYY patch
depended upon it.
Regards,
Owen
More information about the cairo
mailing list