Summary: | Canvas: Use fast, approximate dirty rects for stroke() | ||||||
---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Andreas Kling <kling> | ||||
Component: | Canvas | Assignee: | Andreas Kling <kling> | ||||
Status: | RESOLVED FIXED | ||||||
Severity: | Normal | CC: | bfulgham, eric, krit, mdelaney7, oliver, zimmermann | ||||
Priority: | P2 | Keywords: | Performance | ||||
Version: | 528+ (Nightly build) | ||||||
Hardware: | All | ||||||
OS: | All | ||||||
Attachments: |
|
Description
Andreas Kling
2011-04-28 17:35:30 PDT
Created attachment 91606 [details]
Proposed patch
What perf test shows this change? Comment on attachment 91606 [details]
Proposed patch
Does this handle acute angles with mitres correctly? I recall the the reason we didn't fix this in the past was due to potentially unbounded mitre size
(In reply to comment #3) > What perf test shows this change? Spotted it on http://grantkot.com/sine.html which divides its rendering time between CGContextReplacePathWithStrokedPath (for bounding box calculation) and CGContextStrokePath (for actual rendering.) (In reply to comment #3) > Does this handle acute angles with mitres correctly? I recall the the reason we didn't fix this in the past was due to potentially unbounded mitre size How do you end up with an unbounded miter? The CanvasRenderingContext2D.miterLimit exists to prevent exactly that, no? I believe Oliver is talking about the case where the user sets the miter limit to be huge and then has a very acute angle between two path segments and then strokes that path. Otherwise, here are a few others things I noticed. If we do end up not needing m_path.strokeBoundingRect, then we can likely get rid of it and also do the same alternative bounding rect calculation in the only other place this method (strokeBoundingRect) is used: RenderSVGPath.cpp. You mentioned it's significantly faster on CG - did you take down any performance measurements for any tests that would benefit from this? You mentioned the grantkot.com/sine.html page, but I don't see that that's a performance test. Did you instrument a local copy to get some FPS count for it or just notice that it was faster "to the eye"? (In reply to comment #5) > I believe Oliver is talking about the case where the user sets the miter limit to be huge and then has a very acute angle between two path segments and then strokes that path. Unless I'm misunderstanding something, that should be covered by the miterLimit property; if the stroke would extend outside the approximated rect, it would be drawn with a bevel join instead. > Otherwise, here are a few others things I noticed. If we do end up not needing m_path.strokeBoundingRect, then we can likely get rid of it and also do the same alternative bounding rect calculation in the only other place this method (strokeBoundingRect) is used: RenderSVGPath.cpp. RenderSVGPath needs the bounding rect to be correct, since it's used for more than invalidating the dirty region. > You mentioned it's significantly faster on CG - did you take down any performance measurements for any tests that would benefit from this? You mentioned the grantkot.com/sine.html page, but I don't see that that's a performance test. Did you instrument a local copy to get some FPS count for it or just notice that it was faster "to the eye"? I was playing around with a Mac for once, and wanted to try the "Instruments" application, so I ran this page through the time profiler tool. Like I said above, CPU time was (pretty much) equally divided by measuring the stroke and painting it. I could whip up a reduction with some human-friendly output if you like. :) This has been sitting here for a couple of months, and seems like a good idea. Can we move this along somehow? Ollie -- are your concerns addressed by Andreas' responses? (In reply to comment #6) > (In reply to comment #5) > > I believe Oliver is talking about the case where the user sets the miter limit to be huge and then has a very acute angle between two path segments and then strokes that path. > > Unless I'm misunderstanding something, that should be covered by the miterLimit property; if the stroke would extend outside the approximated rect, it would be drawn with a bevel join instead. > What's the default miterLimit? to my knowledge by default there is no limit... (In reply to comment #8) > (In reply to comment #6) > > (In reply to comment #5) > > > I believe Oliver is talking about the case where the user sets the miter limit to be huge and then has a very acute angle between two path segments and then strokes that path. > > > > Unless I'm misunderstanding something, that should be covered by the miterLimit property; if the stroke would extend outside the approximated rect, it would be drawn with a bevel join instead. > > > > What's the default miterLimit? to my knowledge by default there is no limit... In SVG the default miterLimit is 4. (In reply to comment #8) > (In reply to comment #6) > > (In reply to comment #5) > > > I believe Oliver is talking about the case where the user sets the miter limit to be huge and then has a very acute angle between two path segments and then strokes that path. > > > > Unless I'm misunderstanding something, that should be covered by the miterLimit property; if the stroke would extend outside the approximated rect, it would be drawn with a bevel join instead. > > > > What's the default miterLimit? to my knowledge by default there is no limit... The 2d canvas context has a default miterLimit of 10. ( http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-miterlimit ) Comment on attachment 91606 [details]
Proposed patch
r=me
Committed r90758: <http://trac.webkit.org/changeset/90758> |