Bug 27187

Summary: Match Gecko behaviour for canvas path mutation APIs on an empty path
Product: WebKit Reporter: Oliver Hunt <oliver>
Component: DOMAssignee: Oliver Hunt <oliver>
Status: RESOLVED FIXED    
Severity: Normal CC: deanm, dimich
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
URL: http://www.blahbleh.com/clock.php
Attachments:
Description Flags
fixeration! simon.fraser: review+

Oliver Hunt
Reported 2009-07-11 21:06:03 PDT
Gecko treats lineTo, etc as planting a new point in the canvas path if the current path is empty. Failure to do this results in a significant performance penalty (due to CGs incessant logging) and site breakages like the one linked in this bug.
Attachments
fixeration! (5.70 KB, patch)
2009-07-11 21:38 PDT, Oliver Hunt
simon.fraser: review+
Oliver Hunt
Comment 1 2009-07-11 21:38:10 PDT
Created attachment 32623 [details] fixeration!
Simon Fraser (smfr)
Comment 2 2009-07-11 22:15:05 PDT
Comment on attachment 32623 [details] fixeration! > + Simple API change, check for the mpty path and add appropriate point if necessary. Typo here. r=me
Oliver Hunt
Comment 3 2009-07-11 22:18:09 PDT
Committed r45759
Dean McNamee
Comment 4 2009-07-14 02:56:56 PDT
(In reply to comment #3) > Committed r45759 This broke a bunch of <canvas> stuff. Part of the bug is that for quadraticCurveTo and bezierCurveTo you move to the control point, which I don't think makes a lot of sense, since the control point does not lie on the path. I am digging into the other things that broke now. Thanks
Dean McNamee
Comment 5 2009-07-14 03:08:54 PDT
(In reply to comment #4) > (In reply to comment #3) > > Committed r45759 > > This broke a bunch of <canvas> stuff. > > Part of the bug is that for quadraticCurveTo and bezierCurveTo you move to the > control point, which I don't think makes a lot of sense, since the control > point does not lie on the path. > > I am digging into the other things that broke now. > > Thanks Ok, so here is the problem, it might be Skia specific: From Skia: bool SkPath::isEmpty() const { SkDEBUGCODE(this->validate();) int count = fVerbs.count(); return count == 0 || (count == 1 && fVerbs[0] == kMove_Verb); } And the documentation specifically states that isEmpty returns whether there is any lines or curves, not whether there is a move to point. There are no comments for WebCore::Path::isEmpty(), so I don't know what the expected behavior is. I can understand going both ways with isEmpty(), and in fact it seems like there should be two separate methods, one which asks if there are any points in the path, and one which asks if there are any lines or curves in the path. An additional option, if it is decided that isEmpty should mean there are no points at all in the path, would be to change the Skia backend to reflect this. However, that will probably break some other things, and additionally after a brief skim I cannot see how to get that information out of Skia. This is something I could add to Skia. In the mean time, it would be nice not to have our <canvas> tag completely broken :( Thanks -- dean
Dean McNamee
Comment 6 2009-07-14 03:19:21 PDT
After digging a bit more, cairo does this with cairo_has_current_point. I think this is a more accurate name, hasCurrentPoint(), and it is not necessarily the same as the path being empty. Does it make sense to add hasCurrentPoint() to WebCore::Path? (In reply to comment #5) > (In reply to comment #4) > > (In reply to comment #3) > > > Committed r45759 > > > > This broke a bunch of <canvas> stuff. > > > > Part of the bug is that for quadraticCurveTo and bezierCurveTo you move to the > > control point, which I don't think makes a lot of sense, since the control > > point does not lie on the path. > > > > I am digging into the other things that broke now. > > > > Thanks > > Ok, so here is the problem, it might be Skia specific: > > From Skia: > > bool SkPath::isEmpty() const { > SkDEBUGCODE(this->validate();) > > int count = fVerbs.count(); > return count == 0 || (count == 1 && fVerbs[0] == kMove_Verb); > } > > And the documentation specifically states that isEmpty returns whether there is > any lines or curves, not whether there is a move to point. > > There are no comments for WebCore::Path::isEmpty(), so I don't know what the > expected behavior is. I can understand going both ways with isEmpty(), and in > fact it seems like there should be two separate methods, one which asks if > there are any points in the path, and one which asks if there are any lines or > curves in the path. > > An additional option, if it is decided that isEmpty should mean there are no > points at all in the path, would be to change the Skia backend to reflect this. > However, that will probably break some other things, and additionally after a > brief skim I cannot see how to get that information out of Skia. This is > something I could add to Skia. > > In the mean time, it would be nice not to have our <canvas> tag completely > broken :( > > Thanks > -- dean
Oliver Hunt
Comment 7 2009-07-14 09:38:50 PDT
(In reply to comment #6) > After digging a bit more, cairo does this with cairo_has_current_point. I > think this is a more accurate name, hasCurrentPoint(), and it is not > necessarily the same as the path being empty. > > Does it make sense to add hasCurrentPoint() to WebCore::Path? Seems reasonable -- but we'll want a different bug to track that
Dmitry Titov
Comment 8 2009-07-14 10:17:30 PDT
Created separate bug to track the proposed hasCurrentPoint() addition: https://bugs.webkit.org/show_bug.cgi?id=27266
Dean McNamee
Comment 9 2009-07-14 11:00:41 PDT
(In reply to comment #8) > Created separate bug to track the proposed hasCurrentPoint() addition: > https://bugs.webkit.org/show_bug.cgi?id=27266 On more thinking I don't actually think this patch is correct: From http://dev.w3.org/html5/spec/Overview.html: The lineTo(x, y) method must do nothing if the context has no subpaths. Otherwise, it must connect the last point in the subpath to the given point (x, y) using a straight line, and must then add the given point (x, y) to the subpath. This means if I do lineTo(10, 10); lineTo(20, 20); I should get no lines, since I never started the path with a moveTo(). With this patch you get the second line.
Oliver Hunt
Comment 10 2009-07-14 11:20:27 PDT
Yes, unfortunately firefox violates the spec in a way that people seem to depend on. I've already emailed whatwg about this. It's safe to move to the firefox behaviour as it's a relaxation of existing API.
Note You need to log in before you can comment on or make changes to this bug.