lottie/vector: refactor VPath class to use emplace_back instead of push_back to avoid temporary object creation.

Change-Id: I0abc1be410a3758c447de8b4600c472f6298bcc7
This commit is contained in:
subhransu mohanty 2018-08-16 14:30:57 +09:00
parent da553c4dab
commit 1a6b8c8e0e
2 changed files with 67 additions and 64 deletions

View File

@ -64,33 +64,35 @@ float VPath::VPathData::length() const
void VPath::VPathData::checkNewSegment() void VPath::VPathData::checkNewSegment()
{ {
if (mNewSegment) { if (mNewSegment) {
moveTo(VPointF(0, 0)); moveTo(0, 0);
mNewSegment = false; mNewSegment = false;
} }
} }
void VPath::VPathData::moveTo(const VPointF &p) void VPath::VPathData::moveTo(float x, float y)
{ {
mStartPoint = p; mStartPoint = {x, y};
mNewSegment = false; mNewSegment = false;
m_elements.push_back(VPath::Element::MoveTo); m_elements.emplace_back(VPath::Element::MoveTo);
m_points.push_back(p); m_points.emplace_back(x,y);
m_segments++; m_segments++;
} }
void VPath::VPathData::lineTo(const VPointF &p)
void VPath::VPathData::lineTo(float x, float y)
{ {
checkNewSegment(); checkNewSegment();
m_elements.push_back(VPath::Element::LineTo); m_elements.emplace_back(VPath::Element::LineTo);
m_points.push_back(p); m_points.emplace_back(x,y);
} }
void VPath::VPathData::cubicTo(const VPointF &c1, const VPointF &c2,
const VPointF &e) void VPath::VPathData::cubicTo(float cx1, float cy1, float cx2, float cy2,
float ex, float ey)
{ {
checkNewSegment(); checkNewSegment();
m_elements.push_back(VPath::Element::CubicTo); m_elements.emplace_back(VPath::Element::CubicTo);
m_points.push_back(c1); m_points.emplace_back(cx1, cy1);
m_points.push_back(c2); m_points.emplace_back(cx2, cy2);
m_points.push_back(e); m_points.emplace_back(ex, ey);
} }
void VPath::VPathData::close() void VPath::VPathData::close()
@ -99,7 +101,7 @@ void VPath::VPathData::close()
const VPointF &lastPt = m_points.back(); const VPointF &lastPt = m_points.back();
if (!fuzzyCompare(mStartPoint, lastPt)) { if (!fuzzyCompare(mStartPoint, lastPt)) {
lineTo(mStartPoint); lineTo(mStartPoint.x(), mStartPoint.y());
} }
m_elements.push_back(VPath::Element::Close); m_elements.push_back(VPath::Element::Close);
mNewSegment = true; mNewSegment = true;
@ -140,12 +142,13 @@ void VPath::VPathData::arcTo(const VRectF &rect, float startAngle,
reserve(point_count + 1, point_count / 3 + 1); reserve(point_count + 1, point_count / 3 + 1);
if (isEmpty() || forceMoveTo) { if (isEmpty() || forceMoveTo) {
moveTo(curve_start); moveTo(curve_start.x(), curve_start.y());
} else { } else {
lineTo(curve_start); lineTo(curve_start.x(), curve_start.y());
} }
for (int i = 0; i < point_count; i += 3) { for (int i = 0; i < point_count; i += 3) {
cubicTo(pts[i], pts[i + 1], pts[i + 2]); cubicTo(pts[i].x(), pts[i].y(), pts[i + 1].x(), pts[i + 1].y(),
pts[i + 2].x(), pts[i + 2].y());
} }
} }
@ -173,34 +176,34 @@ void VPath::VPathData::addOval(const VRectF &rect, VPath::Direction dir)
reserve(14, 7); // 1Move + 4Cubic + 1Close reserve(14, 7); // 1Move + 4Cubic + 1Close
if (dir == VPath::Direction::CW) { if (dir == VPath::Direction::CW) {
// moveto 12 o'clock. // moveto 12 o'clock.
moveTo(VPointF(x + w2, y)); moveTo(x + w2, y);
// 12 -> 3 o'clock // 12 -> 3 o'clock
cubicTo(VPointF(x + w2 + w2k, y), VPointF(x + w, y + h2 - h2k), cubicTo(x + w2 + w2k, y, x + w, y + h2 - h2k,
VPointF(x + w, y + h2)); x + w, y + h2);
// 3 -> 6 o'clock // 3 -> 6 o'clock
cubicTo(VPointF(x + w, y + h2 + h2k), VPointF(x + w2 + w2k, y + h), cubicTo(x + w, y + h2 + h2k, x + w2 + w2k, y + h,
VPointF(x + w2, y + h)); x + w2, y + h);
// 6 -> 9 o'clock // 6 -> 9 o'clock
cubicTo(VPointF(x + w2 - w2k, y + h), VPointF(x, y + h2 + h2k), cubicTo(x + w2 - w2k, y + h, x, y + h2 + h2k,
VPointF(x, y + h2)); x, y + h2);
// 9 -> 12 o'clock // 9 -> 12 o'clock
cubicTo(VPointF(x, y + h2 - h2k), VPointF(x + w2 - w2k, y), cubicTo(x, y + h2 - h2k, x + w2 - w2k, y,
VPointF(x + w2, y)); x + w2, y);
} else { } else {
// moveto 12 o'clock. // moveto 12 o'clock.
moveTo(VPointF(x + w2, y)); moveTo(x + w2, y);
// 12 -> 9 o'clock // 12 -> 9 o'clock
cubicTo(VPointF(x + w2 - w2k, y), VPointF(x, y + h2 - h2k), cubicTo(x + w2 - w2k, y, x, y + h2 - h2k,
VPointF(x, y + h2)); x, y + h2);
// 9 -> 6 o'clock // 9 -> 6 o'clock
cubicTo(VPointF(x, y + h2 + h2k), VPointF(x + w2 - w2k, y + h), cubicTo(x, y + h2 + h2k, x + w2 - w2k, y + h,
VPointF(x + w2, y + h)); x + w2, y + h);
// 6 -> 3 o'clock // 6 -> 3 o'clock
cubicTo(VPointF(x + w2 + w2k, y + h), VPointF(x + w, y + h2 + h2k), cubicTo(x + w2 + w2k, y + h, x + w, y + h2 + h2k,
VPointF(x + w, y + h2)); x + w, y + h2);
// 3 -> 12 o'clock // 3 -> 12 o'clock
cubicTo(VPointF(x + w, y + h2 - h2k), VPointF(x + w2 + w2k, y), cubicTo(x + w, y + h2 - h2k, x + w2 + w2k, y,
VPointF(x + w2, y)); x + w2, y);
} }
close(); close();
} }
@ -216,16 +219,16 @@ void VPath::VPathData::addRect(const VRectF &rect, VPath::Direction dir)
reserve(6, 6); // 1Move + 4Line + 1Close reserve(6, 6); // 1Move + 4Line + 1Close
if (dir == VPath::Direction::CW) { if (dir == VPath::Direction::CW) {
moveTo(VPointF(x + w, y)); moveTo(x + w, y);
lineTo(VPointF(x + w, y + h)); lineTo(x + w, y + h);
lineTo(VPointF(x, y + h)); lineTo(x, y + h);
lineTo(VPointF(x, y)); lineTo(x, y);
close(); close();
} else { } else {
moveTo(VPointF(x + w, y)); moveTo(x + w, y);
lineTo(VPointF(x, y)); lineTo(x, y);
lineTo(VPointF(x, y + h)); lineTo(x, y + h);
lineTo(VPointF(x + w, y + h)); lineTo(x + w, y + h);
close(); close();
} }
} }
@ -250,14 +253,14 @@ void VPath::VPathData::addRoundRect(const VRectF &rect, float rx, float ry,
reserve(14, 7); // 1Move + 4Cubic + 1Close reserve(14, 7); // 1Move + 4Cubic + 1Close
if (dir == VPath::Direction::CW) { if (dir == VPath::Direction::CW) {
moveTo(VPointF(x + w, y + ry / 2.f)); moveTo(x + w, y + ry / 2.f);
arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 0, -90, false); arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 0, -90, false);
arcTo(VRectF(x, y + h - ry, rx, ry), -90, -90, false); arcTo(VRectF(x, y + h - ry, rx, ry), -90, -90, false);
arcTo(VRectF(x, y, rx, ry), -180, -90, false); arcTo(VRectF(x, y, rx, ry), -180, -90, false);
arcTo(VRectF(x + w - rx, y, rx, ry), -270, -90, false); arcTo(VRectF(x + w - rx, y, rx, ry), -270, -90, false);
close(); close();
} else { } else {
moveTo(VPointF(x + w, y + ry / 2.f)); moveTo(x + w, y + ry / 2.f);
arcTo(VRectF(x + w - rx, y, rx, ry), 0, 90, false); arcTo(VRectF(x + w - rx, y, rx, ry), 0, 90, false);
arcTo(VRectF(x, y, rx, ry), 90, 90, false); arcTo(VRectF(x, y, rx, ry), 90, 90, false);
arcTo(VRectF(x, y + h - ry, rx, ry), 180, 90, false); arcTo(VRectF(x, y + h - ry, rx, ry), 180, 90, false);
@ -539,7 +542,7 @@ void VPath::VPathData::addPolystar(float points, float innerRadius,
hasRoundness = true; hasRoundness = true;
} }
moveTo(VPointF(x + cx, y + cy)); moveTo(x + cx, y + cy);
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < numPoints; i++) {
float radius = longSegment ? outerRadius : innerRadius; float radius = longSegment ? outerRadius : innerRadius;
@ -586,11 +589,11 @@ void VPath::VPathData::addPolystar(float points, float innerRadius,
cp2y *= partialPointAmount; cp2y *= partialPointAmount;
} }
cubicTo(VPointF(previousX - cp1x + cx, previousY - cp1y + cy), cubicTo(previousX - cp1x + cx, previousY - cp1y + cy,
VPointF(x + cp2x + cx, y + cp2y + cy), x + cp2x + cx, y + cp2y + cy,
VPointF(x + cx, y + cy)); x + cx, y + cy);
} else { } else {
lineTo(VPointF(x + cx, y + cy)); lineTo(x + cx, y + cy);
} }
currentAngle += dTheta * angleDir; currentAngle += dTheta * angleDir;
@ -630,7 +633,7 @@ void VPath::VPathData::addPolygon(float points, float radius, float roundness,
hasRoundness = true; hasRoundness = true;
} }
moveTo(VPointF(x + cx, y + cy)); moveTo(x + cx, y + cy);
for (int i = 0; i < numPoints; i++) { for (int i = 0; i < numPoints; i++) {
previousX = x; previousX = x;
@ -652,10 +655,10 @@ void VPath::VPathData::addPolygon(float points, float radius, float roundness,
float cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx; float cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx;
float cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy; float cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy;
cubicTo(VPointF(previousX - cp1x + cx, previousY - cp1y + cy), cubicTo(previousX - cp1x + cx, previousY - cp1y + cy,
VPointF(x + cp2x + cx, y + cp2y + cy), VPointF(x, y)); x + cp2x + cx, y + cp2y + cy, x, y);
} else { } else {
lineTo(VPointF(x + cx, y + cy)); lineTo(x + cx, y + cy);
} }
currentAngle += anglePerPoint * angleDir; currentAngle += anglePerPoint * angleDir;

View File

@ -52,9 +52,9 @@ private:
VPathData(); VPathData();
VPathData(const VPathData &o); VPathData(const VPathData &o);
bool isEmpty() const { return m_elements.empty(); } bool isEmpty() const { return m_elements.empty(); }
void moveTo(const VPointF &pt); void moveTo(float x, float y);
void lineTo(const VPointF &pt); void lineTo(float x, float y);
void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e); void cubicTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey);
void close(); void close();
void reset(); void reset();
void reserve(int, int); void reserve(int, int);
@ -96,12 +96,12 @@ inline bool VPath::isEmpty() const
inline void VPath::moveTo(const VPointF &p) inline void VPath::moveTo(const VPointF &p)
{ {
d.write().moveTo(p); d.write().moveTo(p.x(), p.y());
} }
inline void VPath::lineTo(const VPointF &p) inline void VPath::lineTo(const VPointF &p)
{ {
d.write().lineTo(p); d.write().lineTo(p.x(), p.y());
} }
inline void VPath::close() inline void VPath::close()
@ -133,23 +133,23 @@ inline float VPath::length() const
inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2, inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2,
const VPointF &e) const VPointF &e)
{ {
d.write().cubicTo(c1, c2, e); d.write().cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
} }
inline void VPath::lineTo(float x, float y) inline void VPath::lineTo(float x, float y)
{ {
lineTo(VPointF(x, y)); d.write().lineTo(x, y);
} }
inline void VPath::moveTo(float x, float y) inline void VPath::moveTo(float x, float y)
{ {
moveTo(VPointF(x, y)); d.write().moveTo(x, y);
} }
inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex,
float ey) float ey)
{ {
cubicTo(VPointF(c1x, c1y), VPointF(c2x, c2y), VPointF(ex, ey)); d.write().cubicTo(c1x, c1y, c2x, c2y, ex, ey);
} }
inline void VPath::transform(const VMatrix &m) inline void VPath::transform(const VMatrix &m)