author | Kevin Hsieh <kevin.hsieh@ucla.edu> |
Fri, 28 Jul 2017 23:57:04 -0700 | |
changeset 371938 | 6df0dd7948ada7f73e7583d10d35778419bc038d |
parent 371937 | 5566083502700db4fde066b0c299c4589087bca2 |
child 371939 | 3bcd8efdd376d4d3dfcc5dda64631f048417c661 |
push id | 47626 |
push user | dholbert@mozilla.com |
push date | Mon, 31 Jul 2017 05:57:49 +0000 |
treeherder | autoland@6df0dd7948ad [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bas |
bugs | 1322537 |
milestone | 56.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/2d/Path.cpp +++ b/gfx/2d/Path.cpp @@ -253,32 +253,40 @@ FlattenBezierCurveSegment(const BezierCo * The basic premise is that for a small t the third order term in the * equation of a cubic bezier curve is insignificantly small. This can * then be approximated by a quadratic equation for which the maximum * difference from a linear approximation can be much more easily determined. */ BezierControlPoints currentCP = aControlPoints; double t = 0; + double currentTolerance = aTolerance; while (t < 1.0) { PointD cp21 = currentCP.mCP2 - currentCP.mCP1; PointD cp31 = currentCP.mCP3 - currentCP.mCP1; /* To remove divisions and check for divide-by-zero, this is optimized from: * Float s3 = (cp31.x * cp21.y - cp31.y * cp21.x) / hypotf(cp21.x, cp21.y); * t = 2 * Float(sqrt(aTolerance / (3. * std::abs(s3)))); */ double cp21x31 = cp31.x * cp21.y - cp31.y * cp21.x; double h = hypot(cp21.x, cp21.y); if (cp21x31 * h == 0) { break; } double s3inv = h / cp21x31; - t = 2 * sqrt(aTolerance * std::abs(s3inv) / 3.); + t = 2 * sqrt(currentTolerance * std::abs(s3inv) / 3.); + currentTolerance *= 1 + aTolerance; + // Increase tolerance every iteration to prevent this loop from executing + // too many times. This approximates the length of large curves more + // roughly. In practice, aTolerance is the constant kFlatteningTolerance + // which has value 0.0001. With this value, it takes 6,932 splits to double + // currentTolerance (to 0.0002) and 23,028 splits to increase + // currentTolerance by an order of magnitude (to 0.001). if (t >= 1.0) { break; } SplitBezier(currentCP, nullptr, ¤tCP, t); aSink->LineTo(currentCP.mCP1.ToPoint()); }
new file mode 100644 --- /dev/null +++ b/layout/svg/crashtests/1322537-1.html @@ -0,0 +1,2 @@ +<svg> +<animateMotion path='M8,0l69,97m45,-17592186044414A71,23 46,0,0 16382,98Q50,10 48,72T21,0Z'/> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/layout/svg/crashtests/1322537-2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<head> + <script> + function go() { + var path = document.getElementById("myPath"); + var len = path.getTotalLength(); + console.log(len); + } + </script> +</head> +<body onload="go()"> + <svg> + <path id="myPath" d="M45,-17592186044414A71,23 46,0,0 16382,98"/> + </svg> +</body>
--- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -193,11 +193,13 @@ load 993443.svg load 1016145.svg load 1028512.svg load 1140080-1.svg load 1149542-1.svg load 1156581-1.svg load 1182496-1.html load 1209525-1.svg load 1223281-1.svg +load 1322537-1.html +load 1322537-2.html load 1348564.svg load conditional-outer-svg-nondirty-reflow-assert.xhtml load extref-test-1.xhtml