Summary: | Transformed image source surfaces sometimes misrender to xlib surface target | ||
---|---|---|---|
Product: | cairo | Reporter: | Damon Chaplin <damon> |
Component: | general | Assignee: | Carl Worth <cworth> |
Status: | RESOLVED FIXED | QA Contact: | cairo-bugs mailing list <cairo-bugs> |
Severity: | blocker | ||
Priority: | medium | ||
Version: | 1.4.2 | ||
Hardware: | Other | ||
OS: | Linux (All) | ||
Whiteboard: | |||
i915 platform: | i915 features: | ||
Attachments: |
screenshot
test case xlib test case workaround version of test case |
Description
Damon Chaplin
2007-04-02 12:58:27 UTC
Created attachment 9441 [details]
screenshot
Comment on attachment 9441 [details]
screenshot
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. Thanks, 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 commit c96a71e709e537f690da6d4a184aa4c64fe11028 Author: Carl Worth <cworth@cworth.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 surface. 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. -Carl (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. Thanks, -Carl Created attachment 9499 [details]
test case
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).
-Carl
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.
-Carl
Oh, I fixed this right before 1.4.4 btw. commit 84c10a79ffd233a953434bd787dcfe57787552f8 Author: Behdad Esfahbod <behdad@behdad.org> 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. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.