vector: add benchmarks.
Change-Id: I4946ccc3a915c7e9365cd5fe860da673a2270fbb Reviewed-on: https://go-review.googlesource.com/29631 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
cd8486aac9
commit
50ce1ebf58
|
@ -8,8 +8,10 @@ package vector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -93,3 +95,109 @@ func TestBasicPath(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
benchmarkGlyphWidth = 893
|
||||||
|
benchmarkGlyphHeight = 1122
|
||||||
|
)
|
||||||
|
|
||||||
|
// benchmarkGlyphData is the 'a' glyph from the Roboto Regular font, translated
|
||||||
|
// so that its top left corner is (0, 0).
|
||||||
|
var benchmarkGlyphData = []struct {
|
||||||
|
// n being 0, 1 or 2 means moveTo, lineTo or quadTo.
|
||||||
|
n uint32
|
||||||
|
p f32.Vec2
|
||||||
|
q f32.Vec2
|
||||||
|
}{
|
||||||
|
{0, f32.Vec2{699, 1102}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{683, 1070}, f32.Vec2{673, 988}},
|
||||||
|
{2, f32.Vec2{544, 1122}, f32.Vec2{365, 1122}},
|
||||||
|
{2, f32.Vec2{205, 1122}, f32.Vec2{102.5, 1031.5}},
|
||||||
|
{2, f32.Vec2{0, 941}, f32.Vec2{0, 802}},
|
||||||
|
{2, f32.Vec2{0, 633}, f32.Vec2{128.5, 539.5}},
|
||||||
|
{2, f32.Vec2{257, 446}, f32.Vec2{490, 446}},
|
||||||
|
{1, f32.Vec2{670, 446}, f32.Vec2{0, 0}},
|
||||||
|
{1, f32.Vec2{670, 361}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{670, 264}, f32.Vec2{612, 206.5}},
|
||||||
|
{2, f32.Vec2{554, 149}, f32.Vec2{441, 149}},
|
||||||
|
{2, f32.Vec2{342, 149}, f32.Vec2{275, 199}},
|
||||||
|
{2, f32.Vec2{208, 249}, f32.Vec2{208, 320}},
|
||||||
|
{1, f32.Vec2{22, 320}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{22, 239}, f32.Vec2{79.5, 163.5}},
|
||||||
|
{2, f32.Vec2{137, 88}, f32.Vec2{235.5, 44}},
|
||||||
|
{2, f32.Vec2{334, 0}, f32.Vec2{452, 0}},
|
||||||
|
{2, f32.Vec2{639, 0}, f32.Vec2{745, 93.5}},
|
||||||
|
{2, f32.Vec2{851, 187}, f32.Vec2{855, 351}},
|
||||||
|
{1, f32.Vec2{855, 849}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{855, 998}, f32.Vec2{893, 1086}},
|
||||||
|
{1, f32.Vec2{893, 1102}, f32.Vec2{0, 0}},
|
||||||
|
{1, f32.Vec2{699, 1102}, f32.Vec2{0, 0}},
|
||||||
|
{0, f32.Vec2{392, 961}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{479, 961}, f32.Vec2{557, 916}},
|
||||||
|
{2, f32.Vec2{635, 871}, f32.Vec2{670, 799}},
|
||||||
|
{1, f32.Vec2{670, 577}, f32.Vec2{0, 0}},
|
||||||
|
{1, f32.Vec2{525, 577}, f32.Vec2{0, 0}},
|
||||||
|
{2, f32.Vec2{185, 577}, f32.Vec2{185, 776}},
|
||||||
|
{2, f32.Vec2{185, 863}, f32.Vec2{243, 912}},
|
||||||
|
{2, f32.Vec2{301, 961}, f32.Vec2{392, 961}},
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchGlyph benchmarks rasterizing a TrueType glyph.
|
||||||
|
//
|
||||||
|
// Note that, compared to the github.com/google/font-go prototype, the height
|
||||||
|
// here is the height of the bounding box, not the pixels per em used to scale
|
||||||
|
// a glyph's vectors. A height of 64 corresponds to a ppem greater than 64.
|
||||||
|
func benchGlyph(b *testing.B, cm color.Model, height int, op draw.Op) {
|
||||||
|
scale := float32(height) / benchmarkGlyphHeight
|
||||||
|
|
||||||
|
// Clone the benchmarkGlyphData slice and scale its coordinates.
|
||||||
|
data := append(benchmarkGlyphData[:0:0], benchmarkGlyphData...)
|
||||||
|
for i := range data {
|
||||||
|
data[i].p[0] *= scale
|
||||||
|
data[i].p[1] *= scale
|
||||||
|
data[i].q[0] *= scale
|
||||||
|
data[i].q[1] *= scale
|
||||||
|
}
|
||||||
|
|
||||||
|
width := int(math.Ceil(float64(benchmarkGlyphWidth * scale)))
|
||||||
|
z := NewRasterizer(width, height)
|
||||||
|
|
||||||
|
dst, src := draw.Image(nil), image.Image(nil)
|
||||||
|
switch cm {
|
||||||
|
case color.AlphaModel:
|
||||||
|
dst = image.NewAlpha(z.Bounds())
|
||||||
|
src = image.Opaque
|
||||||
|
default:
|
||||||
|
b.Fatal("unsupported color model")
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
z.Reset(width, height)
|
||||||
|
z.DrawOp = op
|
||||||
|
for _, d := range data {
|
||||||
|
switch d.n {
|
||||||
|
case 0:
|
||||||
|
z.MoveTo(d.p)
|
||||||
|
case 1:
|
||||||
|
z.LineTo(d.p)
|
||||||
|
case 2:
|
||||||
|
z.QuadTo(d.p, d.q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
z.Draw(dst, dst.Bounds(), src, image.Point{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGlyphAlpha16Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 16, draw.Over) }
|
||||||
|
func BenchmarkGlyphAlpha16Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 16, draw.Src) }
|
||||||
|
func BenchmarkGlyphAlpha32Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 32, draw.Over) }
|
||||||
|
func BenchmarkGlyphAlpha32Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 32, draw.Src) }
|
||||||
|
func BenchmarkGlyphAlpha64Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 64, draw.Over) }
|
||||||
|
func BenchmarkGlyphAlpha64Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 64, draw.Src) }
|
||||||
|
func BenchmarkGlyphAlpha128Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 128, draw.Over) }
|
||||||
|
func BenchmarkGlyphAlpha128Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 128, draw.Src) }
|
||||||
|
func BenchmarkGlyphAlpha256Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 256, draw.Over) }
|
||||||
|
func BenchmarkGlyphAlpha256Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 256, draw.Src) }
|
||||||
|
|
||||||
|
// TODO: color.RGBAModel benchmarks.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user