<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>59764</bug_id>
          
          <creation_ts>2011-04-28 17:35:30 -0700</creation_ts>
          <short_desc>Canvas: Use fast, approximate dirty rects for stroke()</short_desc>
          <delta_ts>2011-07-11 09:48:03 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Canvas</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>Performance</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Andreas Kling">kling</reporter>
          <assigned_to name="Andreas Kling">kling</assigned_to>
          <cc>bfulgham</cc>
    
    <cc>eric</cc>
    
    <cc>krit</cc>
    
    <cc>mdelaney7</cc>
    
    <cc>oliver</cc>
    
    <cc>zimmermann</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>394978</commentid>
    <comment_count>0</comment_count>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-04-28 17:35:30 -0700</bug_when>
    <thetext>Qt already has an optimization in place for CanvasRenderingContext2D::stroke() where we take the QPainterPath::controlPointRect() and grow it by the miterLimit and the lineWidth to create an approximate dirty rect which is significantly faster than rasterizing the path and calculating the exact bounding rect.

We should share this optimization with other ports, using the inflated Path::boundingRect(), which is significantly faster on CG, and likely on other rendering libraries as well.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>394985</commentid>
    <comment_count>1</comment_count>
      <attachid>91606</attachid>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-04-28 17:40:00 -0700</bug_when>
    <thetext>Created attachment 91606
Proposed patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>395918</commentid>
    <comment_count>2</comment_count>
    <who name="Eric Seidel (no email)">eric</who>
    <bug_when>2011-05-01 09:42:17 -0700</bug_when>
    <thetext>What perf test shows this change?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>395977</commentid>
    <comment_count>3</comment_count>
      <attachid>91606</attachid>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2011-05-01 11:52:34 -0700</bug_when>
    <thetext>Comment on attachment 91606
Proposed patch

Does this handle acute angles with mitres correctly?  I recall the the reason we didn&apos;t fix this in the past was due to potentially unbounded mitre size</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>396298</commentid>
    <comment_count>4</comment_count>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-05-02 01:48:30 -0700</bug_when>
    <thetext>(In reply to comment #3)
&gt; 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)
&gt; Does this handle acute angles with mitres correctly?  I recall the the reason we didn&apos;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?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>396818</commentid>
    <comment_count>5</comment_count>
    <who name="Matthew Delaney">mdelaney7</who>
    <bug_when>2011-05-02 17:16:35 -0700</bug_when>
    <thetext>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&apos;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&apos;t see that that&apos;s a performance test. Did you instrument a local copy to get some FPS count for it or just notice that it was faster &quot;to the eye&quot;?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>398693</commentid>
    <comment_count>6</comment_count>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-05-05 06:42:25 -0700</bug_when>
    <thetext>(In reply to comment #5)
&gt; 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&apos;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.

&gt; 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&apos;s used for more than invalidating the dirty region.

&gt; You mentioned it&apos;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&apos;t see that that&apos;s a performance test. Did you instrument a local copy to get some FPS count for it or just notice that it was faster &quot;to the eye&quot;?

I was playing around with a Mac for once, and wanted to try the &quot;Instruments&quot; 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. :)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434654</commentid>
    <comment_count>7</comment_count>
    <who name="Brent Fulgham">bfulgham</who>
    <bug_when>2011-07-10 19:48:58 -0700</bug_when>
    <thetext>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&apos; responses?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434910</commentid>
    <comment_count>8</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2011-07-11 09:00:51 -0700</bug_when>
    <thetext>(In reply to comment #6)
&gt; (In reply to comment #5)
&gt; &gt; 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.
&gt; 
&gt; Unless I&apos;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.
&gt; 

What&apos;s the default miterLimit? to my knowledge by default there is no limit...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434918</commentid>
    <comment_count>9</comment_count>
    <who name="Nikolas Zimmermann">zimmermann</who>
    <bug_when>2011-07-11 09:12:12 -0700</bug_when>
    <thetext>(In reply to comment #8)
&gt; (In reply to comment #6)
&gt; &gt; (In reply to comment #5)
&gt; &gt; &gt; 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.
&gt; &gt; 
&gt; &gt; Unless I&apos;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.
&gt; &gt; 
&gt; 
&gt; What&apos;s the default miterLimit? to my knowledge by default there is no limit...

In SVG the default miterLimit is 4.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434931</commentid>
    <comment_count>10</comment_count>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-07-11 09:35:52 -0700</bug_when>
    <thetext>(In reply to comment #8)
&gt; (In reply to comment #6)
&gt; &gt; (In reply to comment #5)
&gt; &gt; &gt; 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.
&gt; &gt; 
&gt; &gt; Unless I&apos;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.
&gt; &gt; 
&gt; 
&gt; What&apos;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 )</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434934</commentid>
    <comment_count>11</comment_count>
      <attachid>91606</attachid>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2011-07-11 09:39:00 -0700</bug_when>
    <thetext>Comment on attachment 91606
Proposed patch

r=me</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>434940</commentid>
    <comment_count>12</comment_count>
    <who name="Andreas Kling">kling</who>
    <bug_when>2011-07-11 09:48:03 -0700</bug_when>
    <thetext>Committed r90758: &lt;http://trac.webkit.org/changeset/90758&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>91606</attachid>
            <date>2011-04-28 17:40:00 -0700</date>
            <delta_ts>2011-07-11 09:39:00 -0700</delta_ts>
            <desc>Proposed patch</desc>
            <filename>bug-59764.diff</filename>
            <type>text/plain</type>
            <size>2129</size>
            <attacher name="Andreas Kling">kling</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1NvdXJjZS9XZWJDb3JlL0NoYW5nZUxvZyBiL1NvdXJjZS9XZWJDb3JlL0No
YW5nZUxvZwppbmRleCBmNjAyOTg4Li5iZjJkNzBmIDEwMDY0NAotLS0gYS9Tb3VyY2UvV2ViQ29y
ZS9DaGFuZ2VMb2cKKysrIGIvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCkBAIC0xLDMgKzEsMTkg
QEAKKzIwMTEtMDQtMjggIEFuZHJlYXMgS2xpbmcgIDxrbGluZ0B3ZWJraXQub3JnPgorCisgICAg
ICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIENhbnZhczogVXNlIGZh
c3QsIGFwcHJveGltYXRlIGRpcnR5IHJlY3RzIGZvciBzdHJva2UoKQorICAgICAgICBodHRwczov
L2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NTk3NjQKKworICAgICAgICBObyBuZXcg
dGVzdHMsIHRoaXMgaXMgYW4gb3B0aW1pemF0aW9uLgorCisgICAgICAgICogaHRtbC9jYW52YXMv
Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJELmNwcDoKKyAgICAgICAgKFdlYkNvcmU6OkNhbnZhc1Jl
bmRlcmluZ0NvbnRleHQyRDo6c3Ryb2tlKTogSW5zdGVhZCBvZiB1c2luZworICAgICAgICBQYXRo
OjpzdHJva2VCb3VuZGluZ1JlY3QoKSB0byBjYWxjdWxhdGUgdGhlIGV4YWN0IGJvdW5kaW5nIHJl
Y3QKKyAgICAgICAgZm9yIGEgcGF0aCBzdHJva2UsIGdldCB0aGUgUGF0aDo6Ym91bmRpbmdSZWN0
KCkgYW5kIGluZmxhdGUgaXQgYnkKKyAgICAgICAgbWl0ZXJMaW1pdCArIGxpbmVXaWR0aCB0byBn
ZXQgYSBzbGlnaHRseSBvdmVyc2l6ZWQgZGlydHkgcmVjdAorICAgICAgICBpbiBhIGZyYWN0aW9u
IG9mIHRoZSB0aW1lLgorCiAyMDExLTA0LTI4ICBBcm5vIFJlbmV2aWVyICA8YXJub0ByZW5ldmll
ci5uZXQ+CiAKICAgICAgICAgUmV2aWV3ZWQgYnkgR3VzdGF2byBOb3JvbmhhIFNpbHZhLgpkaWZm
IC0tZ2l0IGEvU291cmNlL1dlYkNvcmUvaHRtbC9jYW52YXMvQ2FudmFzUmVuZGVyaW5nQ29udGV4
dDJELmNwcCBiL1NvdXJjZS9XZWJDb3JlL2h0bWwvY2FudmFzL0NhbnZhc1JlbmRlcmluZ0NvbnRl
eHQyRC5jcHAKaW5kZXggZmYxMjE2OC4uYjA5MzNkZCAxMDA2NDQKLS0tIGEvU291cmNlL1dlYkNv
cmUvaHRtbC9jYW52YXMvQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELmNwcAorKysgYi9Tb3VyY2Uv
V2ViQ29yZS9odG1sL2NhbnZhcy9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQuY3BwCkBAIC05NTQs
MTcgKzk1NCwxNyBAQCB2b2lkIENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDo6c3Ryb2tlKCkKIAog
ICAgIGlmICghbV9wYXRoLmlzRW1wdHkoKSkgewogI2lmIFBMQVRGT1JNKFFUKQorICAgICAgICBG
bG9hdFJlY3QgZGlydHlSZWN0ID0gbV9wYXRoLnBsYXRmb3JtUGF0aCgpLmNvbnRyb2xQb2ludFJl
Y3QoKTsKKyNlbHNlCisgICAgICAgIEZsb2F0UmVjdCBkaXJ0eVJlY3QgPSBtX3BhdGguYm91bmRp
bmdSZWN0KCk7CisjZW5kaWYKICAgICAgICAgLy8gRmFzdCBhcHByb3hpbWF0aW9uIG9mIHRoZSBz
dHJva2UncyBib3VuZGluZyByZWN0LgogICAgICAgICAvLyBUaGlzIHlpZWxkcyBhIHNsaWdodGx5
IG92ZXJzaXplZCByZWN0IGJ1dCBpcyB2ZXJ5IGZhc3QKICAgICAgICAgLy8gY29tcGFyZWQgdG8g
UGF0aDo6c3Ryb2tlQm91bmRpbmdSZWN0KCkuCi0gICAgICAgIEZsb2F0UmVjdCBib3VuZGluZ1Jl
Y3QgPSBtX3BhdGgucGxhdGZvcm1QYXRoKCkuY29udHJvbFBvaW50UmVjdCgpOwotICAgICAgICBi
b3VuZGluZ1JlY3QuaW5mbGF0ZShzdGF0ZSgpLm1fbWl0ZXJMaW1pdCArIHN0YXRlKCkubV9saW5l
V2lkdGgpOwotI2Vsc2UKLSAgICAgICAgQ2FudmFzU3Ryb2tlU3R5bGVBcHBsaWVyIHN0cm9rZUFw
cGxpZXIodGhpcyk7Ci0gICAgICAgIEZsb2F0UmVjdCBib3VuZGluZ1JlY3QgPSBtX3BhdGguc3Ry
b2tlQm91bmRpbmdSZWN0KCZzdHJva2VBcHBsaWVyKTsKLSNlbmRpZgorICAgICAgICBkaXJ0eVJl
Y3QuaW5mbGF0ZShzdGF0ZSgpLm1fbWl0ZXJMaW1pdCArIHN0YXRlKCkubV9saW5lV2lkdGgpOwor
CiAgICAgICAgIGMtPnN0cm9rZVBhdGgobV9wYXRoKTsKLSAgICAgICAgZGlkRHJhdyhib3VuZGlu
Z1JlY3QpOworICAgICAgICBkaWREcmF3KGRpcnR5UmVjdCk7CiAgICAgfQogCiAjaWYgRU5BQkxF
KERBU0hCT0FSRF9TVVBQT1JUKQo=
</data>
<flag name="review"
          id="84457"
          type_id="1"
          status="+"
          setter="oliver"
    />
          </attachment>
      

    </bug>

</bugzilla>