mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 18:52:44 +01:00
vector: reduce memory allocations by reusing the same Path objects
This commit is contained in:
parent
cdb430b2a5
commit
68380e506e
@ -103,6 +103,11 @@ type Path struct {
|
|||||||
subpaths []*subpath
|
subpaths []*subpath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Path) reset() {
|
||||||
|
p.ops = p.ops[:0]
|
||||||
|
p.subpaths = p.subpaths[:0]
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Path) ensureSubpaths() []*subpath {
|
func (p *Path) ensureSubpaths() []*subpath {
|
||||||
// TODO: Probably it is better to avoid returning a slice since allocation is heavy.
|
// TODO: Probably it is better to avoid returning a slice since allocation is heavy.
|
||||||
// What about walkSubpaths(func(*subpath))?
|
// What about walkSubpaths(func(*subpath))?
|
||||||
@ -558,6 +563,7 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
|||||||
}
|
}
|
||||||
|
|
||||||
var rects [][4]point
|
var rects [][4]point
|
||||||
|
var tmpPath Path
|
||||||
for _, subpath := range p.ensureSubpaths() {
|
for _, subpath := range p.ensureSubpaths() {
|
||||||
if subpath.pointCount() < 2 {
|
if subpath.pointCount() < 2 {
|
||||||
continue
|
continue
|
||||||
@ -643,46 +649,49 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
|||||||
delta := math.Pi - da
|
delta := math.Pi - da
|
||||||
exceed := float32(math.Abs(1/math.Sin(float64(delta/2)))) > op.MiterLimit
|
exceed := float32(math.Abs(1/math.Sin(float64(delta/2)))) > op.MiterLimit
|
||||||
|
|
||||||
var quad Path
|
// Quadrilateral
|
||||||
quad.MoveTo(c.x, c.y)
|
tmpPath.reset()
|
||||||
|
tmpPath.MoveTo(c.x, c.y)
|
||||||
if da < math.Pi {
|
if da < math.Pi {
|
||||||
quad.LineTo(rect[1].x, rect[1].y)
|
tmpPath.LineTo(rect[1].x, rect[1].y)
|
||||||
if !exceed {
|
if !exceed {
|
||||||
pt := crossingPointForTwoLines(rect[0], rect[1], nextRect[0], nextRect[1])
|
pt := crossingPointForTwoLines(rect[0], rect[1], nextRect[0], nextRect[1])
|
||||||
quad.LineTo(pt.x, pt.y)
|
tmpPath.LineTo(pt.x, pt.y)
|
||||||
}
|
}
|
||||||
quad.LineTo(nextRect[0].x, nextRect[0].y)
|
tmpPath.LineTo(nextRect[0].x, nextRect[0].y)
|
||||||
} else {
|
} else {
|
||||||
quad.LineTo(rect[3].x, rect[3].y)
|
tmpPath.LineTo(rect[3].x, rect[3].y)
|
||||||
if !exceed {
|
if !exceed {
|
||||||
pt := crossingPointForTwoLines(rect[2], rect[3], nextRect[2], nextRect[3])
|
pt := crossingPointForTwoLines(rect[2], rect[3], nextRect[2], nextRect[3])
|
||||||
quad.LineTo(pt.x, pt.y)
|
tmpPath.LineTo(pt.x, pt.y)
|
||||||
}
|
}
|
||||||
quad.LineTo(nextRect[2].x, nextRect[2].y)
|
tmpPath.LineTo(nextRect[2].x, nextRect[2].y)
|
||||||
}
|
}
|
||||||
vertices, indices = quad.AppendVerticesAndIndicesForFilling(vertices, indices)
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
|
|
||||||
case LineJoinBevel:
|
case LineJoinBevel:
|
||||||
var tri Path
|
// Triangle
|
||||||
tri.MoveTo(c.x, c.y)
|
tmpPath.reset()
|
||||||
|
tmpPath.MoveTo(c.x, c.y)
|
||||||
if da < math.Pi {
|
if da < math.Pi {
|
||||||
tri.LineTo(rect[1].x, rect[1].y)
|
tmpPath.LineTo(rect[1].x, rect[1].y)
|
||||||
tri.LineTo(nextRect[0].x, nextRect[0].y)
|
tmpPath.LineTo(nextRect[0].x, nextRect[0].y)
|
||||||
} else {
|
} else {
|
||||||
tri.LineTo(rect[3].x, rect[3].y)
|
tmpPath.LineTo(rect[3].x, rect[3].y)
|
||||||
tri.LineTo(nextRect[2].x, nextRect[2].y)
|
tmpPath.LineTo(nextRect[2].x, nextRect[2].y)
|
||||||
}
|
}
|
||||||
vertices, indices = tri.AppendVerticesAndIndicesForFilling(vertices, indices)
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
|
|
||||||
case LineJoinRound:
|
case LineJoinRound:
|
||||||
var arc Path
|
// Arc
|
||||||
arc.MoveTo(c.x, c.y)
|
tmpPath.reset()
|
||||||
|
tmpPath.MoveTo(c.x, c.y)
|
||||||
if da < math.Pi {
|
if da < math.Pi {
|
||||||
arc.Arc(c.x, c.y, op.Width/2, a0, a1, Clockwise)
|
tmpPath.Arc(c.x, c.y, op.Width/2, a0, a1, Clockwise)
|
||||||
} else {
|
} else {
|
||||||
arc.Arc(c.x, c.y, op.Width/2, a0+math.Pi, a1+math.Pi, CounterClockwise)
|
tmpPath.Arc(c.x, c.y, op.Width/2, a0+math.Pi, a1+math.Pi, CounterClockwise)
|
||||||
}
|
}
|
||||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,10 +716,11 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
|||||||
y: (startR[0].y + startR[2].y) / 2,
|
y: (startR[0].y + startR[2].y) / 2,
|
||||||
}
|
}
|
||||||
a := float32(math.Atan2(float64(startR[0].y-startR[2].y), float64(startR[0].x-startR[2].x)))
|
a := float32(math.Atan2(float64(startR[0].y-startR[2].y), float64(startR[0].x-startR[2].x)))
|
||||||
var arc Path
|
// Arc
|
||||||
arc.MoveTo(startR[0].x, startR[0].y)
|
tmpPath.reset()
|
||||||
arc.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, CounterClockwise)
|
tmpPath.MoveTo(startR[0].x, startR[0].y)
|
||||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
tmpPath.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, CounterClockwise)
|
||||||
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
c := point{
|
c := point{
|
||||||
@ -718,10 +728,11 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
|||||||
y: (endR[1].y + endR[3].y) / 2,
|
y: (endR[1].y + endR[3].y) / 2,
|
||||||
}
|
}
|
||||||
a := float32(math.Atan2(float64(endR[1].y-endR[3].y), float64(endR[1].x-endR[3].x)))
|
a := float32(math.Atan2(float64(endR[1].y-endR[3].y), float64(endR[1].x-endR[3].x)))
|
||||||
var arc Path
|
// Arc
|
||||||
arc.MoveTo(endR[1].x, endR[1].y)
|
tmpPath.reset()
|
||||||
arc.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, Clockwise)
|
tmpPath.MoveTo(endR[1].x, endR[1].y)
|
||||||
vertices, indices = arc.AppendVerticesAndIndicesForFilling(vertices, indices)
|
tmpPath.Arc(c.x, c.y, op.Width/2, a, a+math.Pi, Clockwise)
|
||||||
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
case LineCapSquare:
|
case LineCapSquare:
|
||||||
@ -731,24 +742,26 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
|||||||
s, c := math.Sincos(a)
|
s, c := math.Sincos(a)
|
||||||
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
||||||
|
|
||||||
var quad Path
|
// Quadrilateral
|
||||||
quad.MoveTo(startR[0].x, startR[0].y)
|
tmpPath.reset()
|
||||||
quad.LineTo(startR[0].x+dx, startR[0].y+dy)
|
tmpPath.MoveTo(startR[0].x, startR[0].y)
|
||||||
quad.LineTo(startR[2].x+dx, startR[2].y+dy)
|
tmpPath.LineTo(startR[0].x+dx, startR[0].y+dy)
|
||||||
quad.LineTo(startR[2].x, startR[2].y)
|
tmpPath.LineTo(startR[2].x+dx, startR[2].y+dy)
|
||||||
vertices, indices = quad.AppendVerticesAndIndicesForFilling(vertices, indices)
|
tmpPath.LineTo(startR[2].x, startR[2].y)
|
||||||
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
a := math.Atan2(float64(endR[1].y-endR[0].y), float64(endR[1].x-endR[0].x))
|
a := math.Atan2(float64(endR[1].y-endR[0].y), float64(endR[1].x-endR[0].x))
|
||||||
s, c := math.Sincos(a)
|
s, c := math.Sincos(a)
|
||||||
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
dx, dy := float32(c)*op.Width/2, float32(s)*op.Width/2
|
||||||
|
|
||||||
var quad Path
|
// Quadrilateral
|
||||||
quad.MoveTo(endR[1].x, endR[1].y)
|
tmpPath.reset()
|
||||||
quad.LineTo(endR[1].x+dx, endR[1].y+dy)
|
tmpPath.MoveTo(endR[1].x, endR[1].y)
|
||||||
quad.LineTo(endR[3].x+dx, endR[3].y+dy)
|
tmpPath.LineTo(endR[1].x+dx, endR[1].y+dy)
|
||||||
quad.LineTo(endR[3].x, endR[3].y)
|
tmpPath.LineTo(endR[3].x+dx, endR[3].y+dy)
|
||||||
vertices, indices = quad.AppendVerticesAndIndicesForFilling(vertices, indices)
|
tmpPath.LineTo(endR[3].x, endR[3].y)
|
||||||
|
vertices, indices = tmpPath.AppendVerticesAndIndicesForFilling(vertices, indices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user