summaryrefslogtreecommitdiffstats
path: root/src/image/draw/bench_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/image/draw/bench_test.go')
-rw-r--r--src/image/draw/bench_test.go275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/image/draw/bench_test.go b/src/image/draw/bench_test.go
new file mode 100644
index 0000000..55d25b8
--- /dev/null
+++ b/src/image/draw/bench_test.go
@@ -0,0 +1,275 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package draw
+
+import (
+ "image"
+ "image/color"
+ "reflect"
+ "testing"
+)
+
+const (
+ dstw, dsth = 640, 480
+ srcw, srch = 400, 300
+)
+
+var palette = color.Palette{
+ color.Black,
+ color.White,
+}
+
+// bench benchmarks drawing src and mask images onto a dst image with the
+// given op and the color models to create those images from.
+// The created images' pixels are initialized to non-zero values.
+func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
+ b.StopTimer()
+
+ var dst Image
+ switch dcm {
+ case color.RGBAModel:
+ dst1 := image.NewRGBA(image.Rect(0, 0, dstw, dsth))
+ for y := 0; y < dsth; y++ {
+ for x := 0; x < dstw; x++ {
+ dst1.SetRGBA(x, y, color.RGBA{
+ uint8(5 * x % 0x100),
+ uint8(7 * y % 0x100),
+ uint8((7*x + 5*y) % 0x100),
+ 0xff,
+ })
+ }
+ }
+ dst = dst1
+ case color.RGBA64Model:
+ dst1 := image.NewRGBA64(image.Rect(0, 0, dstw, dsth))
+ for y := 0; y < dsth; y++ {
+ for x := 0; x < dstw; x++ {
+ dst1.SetRGBA64(x, y, color.RGBA64{
+ uint16(53 * x % 0x10000),
+ uint16(59 * y % 0x10000),
+ uint16((59*x + 53*y) % 0x10000),
+ 0xffff,
+ })
+ }
+ }
+ dst = dst1
+ default:
+ // The == operator isn't defined on a color.Palette (a slice), so we
+ // use reflection.
+ if reflect.DeepEqual(dcm, palette) {
+ dst1 := image.NewPaletted(image.Rect(0, 0, dstw, dsth), palette)
+ for y := 0; y < dsth; y++ {
+ for x := 0; x < dstw; x++ {
+ dst1.SetColorIndex(x, y, uint8(x^y)&1)
+ }
+ }
+ dst = dst1
+ } else {
+ b.Fatal("unknown destination color model", dcm)
+ }
+ }
+
+ var src image.Image
+ switch scm {
+ case nil:
+ src = &image.Uniform{C: color.RGBA{0x11, 0x22, 0x33, 0x44}}
+ case color.CMYKModel:
+ src1 := image.NewCMYK(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetCMYK(x, y, color.CMYK{
+ uint8(13 * x % 0x100),
+ uint8(11 * y % 0x100),
+ uint8((11*x + 13*y) % 0x100),
+ uint8((31*x + 37*y) % 0x100),
+ })
+ }
+ }
+ src = src1
+ case color.GrayModel:
+ src1 := image.NewGray(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetGray(x, y, color.Gray{
+ uint8((11*x + 13*y) % 0x100),
+ })
+ }
+ }
+ src = src1
+ case color.RGBAModel:
+ src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetRGBA(x, y, color.RGBA{
+ uint8(13 * x % 0x80),
+ uint8(11 * y % 0x80),
+ uint8((11*x + 13*y) % 0x80),
+ 0x7f,
+ })
+ }
+ }
+ src = src1
+ case color.RGBA64Model:
+ src1 := image.NewRGBA64(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetRGBA64(x, y, color.RGBA64{
+ uint16(103 * x % 0x8000),
+ uint16(101 * y % 0x8000),
+ uint16((101*x + 103*y) % 0x8000),
+ 0x7fff,
+ })
+ }
+ }
+ src = src1
+ case color.NRGBAModel:
+ src1 := image.NewNRGBA(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ src1.SetNRGBA(x, y, color.NRGBA{
+ uint8(13 * x % 0x100),
+ uint8(11 * y % 0x100),
+ uint8((11*x + 13*y) % 0x100),
+ 0x7f,
+ })
+ }
+ }
+ src = src1
+ case color.YCbCrModel:
+ yy := make([]uint8, srcw*srch)
+ cb := make([]uint8, srcw*srch)
+ cr := make([]uint8, srcw*srch)
+ for i := range yy {
+ yy[i] = uint8(3 * i % 0x100)
+ cb[i] = uint8(5 * i % 0x100)
+ cr[i] = uint8(7 * i % 0x100)
+ }
+ src = &image.YCbCr{
+ Y: yy,
+ Cb: cb,
+ Cr: cr,
+ YStride: srcw,
+ CStride: srcw,
+ SubsampleRatio: image.YCbCrSubsampleRatio444,
+ Rect: image.Rect(0, 0, srcw, srch),
+ }
+ default:
+ b.Fatal("unknown source color model", scm)
+ }
+
+ var mask image.Image
+ switch mcm {
+ case nil:
+ // No-op.
+ case color.AlphaModel:
+ mask1 := image.NewAlpha(image.Rect(0, 0, srcw, srch))
+ for y := 0; y < srch; y++ {
+ for x := 0; x < srcw; x++ {
+ a := uint8((23*x + 29*y) % 0x100)
+ // Glyph masks are typically mostly zero,
+ // so we only set a quarter of mask1's pixels.
+ if a >= 0xc0 {
+ mask1.SetAlpha(x, y, color.Alpha{a})
+ }
+ }
+ }
+ mask = mask1
+ default:
+ b.Fatal("unknown mask color model", mcm)
+ }
+
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ // Scatter the destination rectangle to draw into.
+ x := 3 * i % (dstw - srcw)
+ y := 7 * i % (dsth - srch)
+
+ DrawMask(dst, dst.Bounds().Add(image.Pt(x, y)), src, image.ZP, mask, image.ZP, op)
+ }
+}
+
+// The BenchmarkFoo functions exercise a drawFoo fast-path function in draw.go.
+
+func BenchmarkFillOver(b *testing.B) {
+ bench(b, color.RGBAModel, nil, nil, Over)
+}
+
+func BenchmarkFillSrc(b *testing.B) {
+ bench(b, color.RGBAModel, nil, nil, Src)
+}
+
+func BenchmarkCopyOver(b *testing.B) {
+ bench(b, color.RGBAModel, color.RGBAModel, nil, Over)
+}
+
+func BenchmarkCopySrc(b *testing.B) {
+ bench(b, color.RGBAModel, color.RGBAModel, nil, Src)
+}
+
+func BenchmarkNRGBAOver(b *testing.B) {
+ bench(b, color.RGBAModel, color.NRGBAModel, nil, Over)
+}
+
+func BenchmarkNRGBASrc(b *testing.B) {
+ bench(b, color.RGBAModel, color.NRGBAModel, nil, Src)
+}
+
+func BenchmarkYCbCr(b *testing.B) {
+ bench(b, color.RGBAModel, color.YCbCrModel, nil, Over)
+}
+
+func BenchmarkGray(b *testing.B) {
+ bench(b, color.RGBAModel, color.GrayModel, nil, Over)
+}
+
+func BenchmarkCMYK(b *testing.B) {
+ bench(b, color.RGBAModel, color.CMYKModel, nil, Over)
+}
+
+func BenchmarkGlyphOver(b *testing.B) {
+ bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
+}
+
+func BenchmarkRGBAMaskOver(b *testing.B) {
+ bench(b, color.RGBAModel, color.RGBAModel, color.AlphaModel, Over)
+}
+
+func BenchmarkGrayMaskOver(b *testing.B) {
+ bench(b, color.RGBAModel, color.GrayModel, color.AlphaModel, Over)
+}
+
+func BenchmarkRGBA64ImageMaskOver(b *testing.B) {
+ bench(b, color.RGBAModel, color.RGBA64Model, color.AlphaModel, Over)
+}
+
+func BenchmarkRGBA(b *testing.B) {
+ bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
+}
+
+func BenchmarkPalettedFill(b *testing.B) {
+ bench(b, palette, nil, nil, Src)
+}
+
+func BenchmarkPalettedRGBA(b *testing.B) {
+ bench(b, palette, color.RGBAModel, nil, Src)
+}
+
+// The BenchmarkGenericFoo functions exercise the generic, slow-path code.
+
+func BenchmarkGenericOver(b *testing.B) {
+ bench(b, color.RGBA64Model, color.RGBA64Model, nil, Over)
+}
+
+func BenchmarkGenericMaskOver(b *testing.B) {
+ bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Over)
+}
+
+func BenchmarkGenericSrc(b *testing.B) {
+ bench(b, color.RGBA64Model, color.RGBA64Model, nil, Src)
+}
+
+func BenchmarkGenericMaskSrc(b *testing.B) {
+ bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Src)
+}