[cairo] Painting an image surface into itself in order to scroll it
siarhei.siamashka at gmail.com
Sun Dec 30 14:45:24 PST 2012
On Sun, 30 Dec 2012 15:54:56 +0100
Uli Schlachter <psychon at znc.in> wrote:
> On 27.12.2012 09:26, Nicholas Allen wrote:
> > If I create an image surface and then try to scroll it by painting it
> > into itself then it works as long as I scroll it left, right, or up but
> > not if I scroll it down.
> Having the same surface as both target and source of a drawing operation in
> cairo is not allowed. This invokes undefined behavior and will not be supported.
> (However, I cannot find a reference for this right now)
> So this is not a bug in cairo.
Well, the issue is a bit tricky and has some history. Cairo seems
to be handling overlapped copies for xlib backend by preferring
It also has self-copy.c and self-copy-overlap.c tests specifically to
test for this functionality:
But the image backend (hence adding pixman to CC) does not support this
yet. There were some attempts at implementing this functionality.
The older one from me for just pixman_blt function (which is
actually used for XCopyArea function in X server):
The patches are not available in the mailing list archives,
but looks like they (and some of the others) had been carried
by the openembedded distro:
The other patchset was from Mozilla:
In my opinion it went a bit overboard by implementing the overlapped
compositing functionality for all the compositing operations, even
those where it makes little sense. For example, the compositing
operators where the result depends on the pixel data from the
destination image (for example OVER operator) or when we have
non-identity transformation matrix set. Those cases were handled by
allocating an internal temporary copy of the whole image.
Also unfortunately this patchset did not provide the tests for such
complex new functionality to the pixman test suite to cover all the
compositing operators including both transformed and non-transformed
cases and also complex clipping. The missing tests happened to be the
main blocker as far as I remember, and Mozilla people just did not have
time to implement them.
> > It seems cairo has a bug that this is not possible with just one image
> > surface if you scroll the contents downwards. I can work around it by
> > creating 2 image surfaces and copying one to the other but I would
> > expect cairo to be able to handle this with just one surface.
> If you don't do the copy to an extra surface, cairo would have to do it for you.
> This means that the resulting performance is equally bad. Yes, there could be
> shortcuts for the image backend, but I think most other (raster) backends would
> have to do the extra copy.
> So it is a good thing that this does not actually work. This way you notice that
> the results are wrong and can fix it in your code. For example, using two image
> surfaces which are swapped avoids one copy and thus saves time in a way that
> cairo wouldn't be able to do by itself.
Yes, it's a good idea to make sure that the library realize that some
functionality may be not free and requires something as inefficient as
internal temporary image copies (which may need extra CPU cycles and
sometimes a lot of memory).
But one really good practical use, which can be implemented efficiently
by the image backend, is simple scrolling. This means SOURCE operator
only and no transformation matrix. Though complex clipping and different
types of repeat may be still funny to handle correctly even with this
More information about the cairo