In the GooCanvas demo if I set the zoom to 5.0 and scroll around I am
getting painting artifacts on the image items (e.g. the big pixmap under
This problem occurs in 1.4.0/1.4.2 but not in 1.2.4. (The GTK+ version
is the same.)
It could be a bug in my code, but it is a fairly simple fill operation:
cairo_set_source (cr, image_data->pattern);
cairo_matrix_init_translate (&matrix, -image_data->x, -image_data->y);
cairo_pattern_set_matrix (image_data->pattern, &matrix);
cairo_rectangle (cr, image_data->x, image_data->y,
I'll attach a screenshot in a minute.
Created attachment 9441 [details]
Comment on attachment 9441 [details]
The screenshot shows the results of scrolling the canvas vertically slowly.
So it is only redrawing a few rows of pixels at a time as the canvas is
scrolled, and it seems to be messing up one or two of the rows.
What if you call cairo_pattern_set_matrix() before cairo_set_source()? The pattern CTM is locked when you call set_source(), as opposed to when you call fill(). So I'd not be surprised if the same happens about pattern matrix.
No, calling cairo_pattern_set_matrix() before cairo_set_source() doesn't seem to help.
The problem was introduced in 1.3.12. (1.3.10 is OK)
I might try a git bisect later, though I'm not familiar with git.
Damon, any progress? We'd like to fix this in 1.4.4 which will be out on Monday. Can you do the bisect and let us know where this was introduced? Alternatively, if you can write a simple test showing the problem, we can do the rest, but I guess bisecting would be easier for you.
This is what I got with git-bisect. This is the first time I've used that
so there is a slight chance I messed it up.
But it is the result I expected - the change that restricted the painting
seems to have restricted it a bit too much:
c96a71e709e537f690da6d4a184aa4c64fe11028 is first bad commit
Author: Carl Worth <firstname.lastname@example.org>
Date: Fri Jan 5 15:56:06 2007 -0800
Restrict _clip_and_composite_trapezoids to destination extents
This is a fix for a huge performance bug (as measured by perf/long-lines).
Previously, if no explicit clip was set, _clip_and_composite_trapezoids
would allocate a mask as large as the trapezoids and rasterize into it.
With this fix, it restricts the mask by the extents of the destination
This doesn't address the identical performance problem with the xlib
backend, which is due to a very similar bug in the X server.
image-rgb long-lines-uncropped-100 465.42 -> 5.03: 92.66x speedup
image-rgba long-lines-uncropped-100 460.80 -> 5.02: 91.87x speedup
:040000 040000 e883e75a0c6d25dcf65ec2f97752de537d2b8ab2 beb7a548759406fc19348476b701c292d8f44fa6 M src
Carl, your stuff.
Note that the problem only occurs when images are scaled by cairo. It may be
a bug in the image scaling code that was triggered by the performance
improvements. (Maybe it has trouble handling only one row/column of output.)
Actually it isn't just a scaled image problem. I can also see the problem if
I place an unscaled image at a non-integer position, e.g. (100.5,100.5).
(Probably the same code though.)
OK, I've replicated this with the goocanvas demo. Smells like a rounding bug somewhere. I'll look closer now.
(In reply to comment #10)
> Actually it isn't just a scaled image problem. I can also see the problem if
> I place an unscaled image at a non-integer position, e.g. (100.5,100.5).
> (Probably the same code though.)
That's encouraging. Do you have minimal program to demonstrate the bug?
I'm fine if it uses goocanvas, but if it can demonstrate the bug without any user interaction that would be ideal.
Created attachment 9499 [details]
To use the test case run it and then drag another window around on top of it,
so that the image needs to be partially redrawn.
You should see painting errors.
Adding some details to the bug title, (the bug only affects code targeting the xlib backend, and only with an image-surface source that is transformed).
Created attachment 9595 [details]
xlib test case
Here's a slightly more minimal test case. It uses only cairo and Xlib, not GTK+. And it continuously redraws so there's no need to drag another window over the program's window to see the bug.
Note: Dragging windows, or otherwise keeping your X server busy, does make the bug manifest itself more regularly. If I leave my X server pretty much alone, this test case stops triggering the bug, (instead of sweeping, miscolored lines, the window contents become static).
Created attachment 9596 [details]
workaround version of test case
I don't have a fix for the bug yet, but I do have one workaround to suggest.
Instead of using an image surface as the source pattern, copy the unscaled image contents to an xlib surface, and then use that as the pattern to be transformed.
This attachment is the same as the previous test case, but with this workaround applied, demonstrating that it is effective at eliminating the bug.
Oh, I fixed this right before 1.4.4 btw.
Author: Behdad Esfahbod <email@example.com>
Date: Fri Apr 13 16:33:07 2007 -0400
[cairo-pattern] Slightly hackish fix for bug #10508
The so-attributed-to-X-server bug was that cairo maps the drawing
region to the pattern space, rounds the box, and uploads only that
part of the source surface to the X server. Well, this only works for
NEAREST filter as any more sophisticated filter needs to sneak a peek
at the neighboring pixels around the edges too.
The right fix involves taking into account the filter used, and the
pattern matrix, but for most cases, a single pixel should be enough.
Not sure about scaling down...
Anyway, this is just a workaround to get 1.4.4 out of the door. I'll
commit a proper fix soon.