Created attachment 479214 [details]
We currently don't set an extend mode, and get EXTEND_NONE. I'm pretty sure this is almost never the right thing -- in particular, calling drawImage(src, 0, 0, 10, 10, 0, 0, 100, 100) for a 10x10 source image will give you translucent fringing on the edges. That's just wrong, and it makes it impossible to implement things like smooth panning around a source image with a scale using canvas.
The attached testcase demonstrates the problem. The first set uses a canvas a source, the second uses an image. (All browsers had the same behaviour in both cases.) The large squares, from left to right are:
1) straight drawImage 0,0,60,60 -> 0,0,300,300
2) stairstepped drawImage, doing 2 draws per horizontal band
3) stairstepped fill() using a no-repeat pattern source
4) 300x300 rectangle fill, but with source offset by 150,150
- Firefox: shows fringing at edges, correct linear blending in contents. Consistent behaviour for source, but unfortunately I don't think it's the consistent behaviour anyone wants.
- IE9: sharp edges, correct blending in contents. Some minor artifacts in top left of third square, but I think that's just due to my video drivers (hard to see, about a 1-2 value difference from what it should be). Most significantly, hard edges remain in fourth rendering.
- Opera: sharp edges, correct blending in contents; gets third rendering at the wrong position. Hard edges remain in fourth rendering.
- Chrome: sharp edges, totally broken inner contents. They seem to take whatever the source rectangle is and hard clamp to it, like we do when taking an image tile from an image atlas. Unfortunately it's the wrong thing to do in this case. Third rendering (using path fills) is using nearest-neighbour filling. Fourth rendering shows pad extend behaviour (with nearest-neighbour filling).
I think we should match IE9 (and Opera, mostly) here; setting EXTEND_PAD gets us there in the first three testcases, but not in the fourth. The fourth, unfortunately, is tricky. Short of pre-scaling the pattern when it's set if there's a scale, I don't really know what to do; but doing that is likely to be a huge memory issue.
Actually, our behaviour is different with D2D on vs. off -- if it's on, then I get the behaviour that I want in the first three squares, with the fourth one having a fuzzy edge. With it off (GDI/pixman), I get consistent fuzzy edges everywhere.
Unfortunately, I think that's due to a d2d bug.
So the canvas spec needs to be updated to specify all this, right?
So this is basically a dup of bug 493262, right?
*** Bug 493262 has been marked as a duplicate of this bug. ***
Yeah, bug 493262 definitely covers part of it. But I think it's more than just drawImage. I'm not actually sure how to specify the behaviour that I think is intuitively correct (that gives sharp edges even when used scaled and not aligned to an actual mask edge); when I've tried before for cairo it hasn't gone well.
So, asking blocking ? for this, though perhaps not for the full thing -- with d3d10 layers, nvidia 266.58, I still see randomness in the "white" areas for the fourth square in both. Is something just not being cleared?
The contents change upon reload.
(In reply to comment #0)
> The attached testcase demonstrates the problem. The first set uses a canvas a
> source, the second uses an image. (All browsers had the same behaviour in both
This is no longer the case -- current Fx4 beta 10-ish has white fringes around the edge of the second set (using an image as a source). Leads me to believe that EXTEND_NONE is being used there, vs. EXTEND_PAD for canvas source.
Vlad, do we think this is a blocker? If so, does it need a beta? Is it a hardblocker or softblocker?
Don't think it's a blocker, but it's "bad" (tm). I'd say we should softblock, or fix it for a 4.0.x.
Sounds good to me.
Bug 620216 seems to have superseded this.
I suppose adding the test cases would still be nice, though...