Drawing lines in canvas is completely broken
Reported by
teo8...@gmail.com,
Dec 8
|
|||||||||
Issue descriptionUserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36 Steps to reproduce the problem: 1. See http://matteosistisette.github.io/jquery-ui-labyrinth/ What is the expected behavior? The "labyrinth" drawn on each canvas is made of several line segments all of the same lengths, on the borders between squares in a grid. Where several consecutive segments form a straight line, there should be no visible "junctions" whatsoever. For example in the attached screenshot, the circled line should look like one single long line, there should be no kind of junction visible at the spot indicated by the arrow. What went wrong? Whenever two consecutive segments from point A to point B and from point B to point C, join at point B, where A, B and C are on a straight line, an artifact is visible at point B, looking like a dot or circle, or a kind of "thickening" of the line. See the screenshot. This is a REGRESSION. I don't know when it appeared, as I hadn't tried this example for a very long time, but I'm positive that 5 years ago it worked as expected Did this work before? Yes sometime between 5 years ago and yesterday Chrome version: 71.0.3578.80 Channel: stable OS Version: Flash Version: works as expected even in Firefox. Isn't that pathetic?
,
Dec 10
,
Dec 12
teo8976@ Thanks for the issue. Able to reproduce this issue on Windows 10, Mac OS 10.13.6 and Ubuntu 17.10 on the latest Stable 71.0.3578.80 and latest Canary 73.0.3638.0. Bisect Information: ==================== Good Build: 66.0.3357.0 Bad Build : 66.0.3357.0 By running the per-revision bisect script, below is the Changelog URL. https://chromium.googlesource.com/chromium/src/+log/a2154fd14494fd1229c70e24a22ca5a325850133..e3053cdf8cfac55d0a4589a7f1fcc60796d60c41 From the above Changelog, suspecting the below Change. Reviewed-on: https://chromium-review.googlesource.com/923767 liyuqian@ Please check and confirm if this issue is related to your change, else help us in assigning to the right owner. Thanks...
,
Dec 12
//correcting the bisect information in comment #3 Bisect Information: ==================== Good Build: 66.0.3357.0 Bad Build : 66.0.3358.0
,
Dec 12
Yes, it's a known issue: skbug.com/6886 My change only affects the software rendering and Skia recently also landed CCPR (https://skia-review.googlesource.com/c/skia/+/137207) which brought the similar artifacts to GPU rendering. Since I've transferred to Flutter team and haven't worked on this issue for a while, you may ask reed@ and csmartdalton@ for more details about the progress of that bug. To fix the issue without Skia fixing skbug.com/6886, please remove the overlapping contours inside a path as much as possible.
,
Jan 14
,
Jan 14
,
Jan 14
,
Jan 14
I don't think this is likely to be skbug.com/6886. All of Chrome, Safari, Edge, and IE show this same issue, with Firefox the only exception I can find. I think maybe this is just the usual issue of successive draws conflating coverage and opacity, with successive blending causing pixels to become more and more covered. Firefox may be multisampling, which avoids this issue. It is possible to force Chrome to use multisampling in <canvas>, running the binary with --canvas-msaa-sample-count=4. That should make the thickening disappear and look more like what you're seeing in Firefox. AFAIK, Skia's never had a way to not draw like this except by using something like multisampling, so I if there's been a regression, it's not likely to be recent.
,
Jan 15
I'd like to follow up a bit more here as I mark this working-as-intended.
Reading jquery.labyrinth.js, I think what's going on is that it's drawing each horizontal segment of the labyrinth, then each vertical segment, always as a pair of moveTo()/lineTo(). Each of those moveTo()'s is starting a new contour on the path, which will be capped separately. The caps stick out a bit and overlap with each other, and the standard color blending math ends up making those darker colors in those areas.
If you're in control of jquery.labyrinth.js, there are a couple things you could perhaps play around with to get rid of these caps. If you sort the horizontal and vertical edges and skipped moveTo() where it seems logically redundant, you should see this effect go away on the interiors of walls, but you'll still have the problem in the corners. The real end game would be to find a way to draw the whole maze border as connected contours without calling moveTo(), i.e. without picking up your pen.
A simple workaround is to offset your canvas by half a pixel in both directions (ctx.translate(0.5, 0.5)) so that antialiasing, the root of this problem, goes away. You should see everything sharpen up, with none of the odd cap overlap. The caps are still there, and being drawn over each other, but every pixel will end up either fully covered or not at all, and nothing will end up adding up oddly. That could go somewhere like here:
_drawBorders: function() {
var ctx=this.drawContext;
ctx.translate(0.5, 0.5)
ctx.fillStyle=this.options.backgroundColor;
...
}
,
Jan 16
(6 days ago)
> I think what's going on is that it's drawing each horizontal segment of the labyrinth, then each vertical segment, always as a pair of moveTo()/lineTo() Yes I am, yet that is NOT the expected result. And it used to work as expected. Please reopen. By definition of what a rounded cap is supposed to be, the caps in my code shouldn't "stick out" at all.
,
Jan 16
(6 days ago)
Also note that Firefox does this right.
,
Jan 16
(6 days ago)
Oh, let me take all that back. This bug does go away when we flip gSkUseDeltaAA to false. This is definitely just the DAA bug. Still interesting that we see this in Edge, IE, and Safari too. We have no idea how those browsers draw Canvas 2D, but it's nice to know they share our bugs!
,
Jan 16
(6 days ago)
Just to clarify: > The caps stick out a bit and overlap with each other, The caps overlap with each other (or rather, each cap overlaps with a portion of the other segment) in a way that, in a perfect vectorial world with no pixels, would yield a result exactly identical to one single continuous segment. So, with a correct sampling with a correct antialiasing, the rendered result should be the same with the two overlapping segments as with the single continuous segment. Anything other than that, is the results of artifacts of an incorrect rendering. Unless the theoretically correct result is impossible to achieve; but as Firefox achieving it demonstrates, that is not the case. > and the standard color blending math ends up making those darker colors in those areas Then the standard color blending math is wrong, or not good enough.
,
Jan 16
(6 days ago)
> it's nice to know they share our bugs Or sad, depending on the point of view. |
|||||||||
►
Sign in to add a comment |
|||||||||
Comment 1 by gov...@chromium.org
, Dec 9