mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-10 06:34:01 +00:00
sw_engine/math: fine-tuning optimization
Try to minimize the use of sqrt() and arctan() calls when possible. These calls can be relatively expensive when accumulated within a single frame. Also repalce the division with shift operation. since split cubic function is one of the significant hot-spots in the data processing, we could earn a noticable enhancement. Tested on single thread local machine: Lottie: 0.080 -> 0.052s (-0.028s) Performance: 0.023 -> 0.022 (-0.001s) Binary: +34
This commit is contained in:
parent
7cccabad40
commit
35ddc5fe56
1 changed files with 28 additions and 15 deletions
|
@ -50,11 +50,17 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
|
|||
auto d2 = base[1] - base[2];
|
||||
auto d3 = base[0] - base[1];
|
||||
|
||||
if (d1 == d2 || d2 == d3) {
|
||||
if (d3.small()) angleIn = angleMid = angleOut = 0;
|
||||
else angleIn = angleMid = angleOut = mathAtan(d3);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (d1.small()) {
|
||||
if (d2.small()) {
|
||||
if (d3.small()) {
|
||||
//basically a point.
|
||||
//do nothing to retain original direction
|
||||
angleIn = angleMid = angleOut = 0;
|
||||
return true;
|
||||
} else {
|
||||
angleIn = angleMid = angleOut = mathAtan(d3);
|
||||
}
|
||||
|
@ -205,7 +211,14 @@ SwFixed mathLength(const SwPoint& pt)
|
|||
if (pt.y == 0) return abs(pt.x);
|
||||
|
||||
auto v = pt.toPoint();
|
||||
return static_cast<SwFixed>(sqrtf(v.x * v.x + v.y * v.y) / 64.0f);
|
||||
//return static_cast<SwFixed>(sqrtf(v.x * v.x + v.y * v.y) * 65536.0f);
|
||||
|
||||
/* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
|
||||
With alpha = 1, beta = 3/8, giving results with the largest error less
|
||||
than 7% compared to the exact value. */
|
||||
if (v.x < 0) v.x = -v.x;
|
||||
if (v.y < 0) v.y = -v.y;
|
||||
return (v.x > v.y) ? (v.x + v.y * 0.375f) : (v.y + v.x * 0.375f);
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,22 +229,22 @@ void mathSplitCubic(SwPoint* base)
|
|||
base[6].x = base[3].x;
|
||||
c = base[1].x;
|
||||
d = base[2].x;
|
||||
base[1].x = a = (base[0].x + c) / 2;
|
||||
base[5].x = b = (base[3].x + d) / 2;
|
||||
c = (c + d) / 2;
|
||||
base[2].x = a = (a + c) / 2;
|
||||
base[4].x = b = (b + c) / 2;
|
||||
base[3].x = (a + b) / 2;
|
||||
base[1].x = a = (base[0].x + c) >> 1;
|
||||
base[5].x = b = (base[3].x + d) >> 1;
|
||||
c = (c + d) >> 1;
|
||||
base[2].x = a = (a + c) >> 1;
|
||||
base[4].x = b = (b + c) >> 1;
|
||||
base[3].x = (a + b) >> 1;
|
||||
|
||||
base[6].y = base[3].y;
|
||||
c = base[1].y;
|
||||
d = base[2].y;
|
||||
base[1].y = a = (base[0].y + c) / 2;
|
||||
base[5].y = b = (base[3].y + d) / 2;
|
||||
c = (c + d) / 2;
|
||||
base[2].y = a = (a + c) / 2;
|
||||
base[4].y = b = (b + c) / 2;
|
||||
base[3].y = (a + b) / 2;
|
||||
base[1].y = a = (base[0].y + c) >> 1;
|
||||
base[5].y = b = (base[3].y + d) >> 1;
|
||||
c = (c + d) >> 1;
|
||||
base[2].y = a = (a + c) >> 1;
|
||||
base[4].y = b = (b + c) >> 1;
|
||||
base[3].y = (a + b) >> 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue