Source file src/image/draw/bench_test.go

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package draw
     6  
     7  import (
     8  	"image"
     9  	"image/color"
    10  	"reflect"
    11  	"testing"
    12  )
    13  
    14  const (
    15  	dstw, dsth = 640, 480
    16  	srcw, srch = 400, 300
    17  )
    18  
    19  var palette = color.Palette{
    20  	color.Black,
    21  	color.White,
    22  }
    23  
    24  // bench benchmarks drawing src and mask images onto a dst image with the
    25  // given op and the color models to create those images from.
    26  // The created images' pixels are initialized to non-zero values.
    27  func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
    28  	b.StopTimer()
    29  
    30  	var dst Image
    31  	switch dcm {
    32  	case color.RGBAModel:
    33  		dst1 := image.NewRGBA(image.Rect(0, 0, dstw, dsth))
    34  		for y := 0; y < dsth; y++ {
    35  			for x := 0; x < dstw; x++ {
    36  				dst1.SetRGBA(x, y, color.RGBA{
    37  					uint8(5 * x % 0x100),
    38  					uint8(7 * y % 0x100),
    39  					uint8((7*x + 5*y) % 0x100),
    40  					0xff,
    41  				})
    42  			}
    43  		}
    44  		dst = dst1
    45  	case color.RGBA64Model:
    46  		dst1 := image.NewRGBA64(image.Rect(0, 0, dstw, dsth))
    47  		for y := 0; y < dsth; y++ {
    48  			for x := 0; x < dstw; x++ {
    49  				dst1.SetRGBA64(x, y, color.RGBA64{
    50  					uint16(53 * x % 0x10000),
    51  					uint16(59 * y % 0x10000),
    52  					uint16((59*x + 53*y) % 0x10000),
    53  					0xffff,
    54  				})
    55  			}
    56  		}
    57  		dst = dst1
    58  	default:
    59  		// The == operator isn't defined on a color.Palette (a slice), so we
    60  		// use reflection.
    61  		if reflect.DeepEqual(dcm, palette) {
    62  			dst1 := image.NewPaletted(image.Rect(0, 0, dstw, dsth), palette)
    63  			for y := 0; y < dsth; y++ {
    64  				for x := 0; x < dstw; x++ {
    65  					dst1.SetColorIndex(x, y, uint8(x^y)&1)
    66  				}
    67  			}
    68  			dst = dst1
    69  		} else {
    70  			b.Fatal("unknown destination color model", dcm)
    71  		}
    72  	}
    73  
    74  	var src image.Image
    75  	switch scm {
    76  	case nil:
    77  		src = &image.Uniform{C: color.RGBA{0x11, 0x22, 0x33, 0x44}}
    78  	case color.CMYKModel:
    79  		src1 := image.NewCMYK(image.Rect(0, 0, srcw, srch))
    80  		for y := 0; y < srch; y++ {
    81  			for x := 0; x < srcw; x++ {
    82  				src1.SetCMYK(x, y, color.CMYK{
    83  					uint8(13 * x % 0x100),
    84  					uint8(11 * y % 0x100),
    85  					uint8((11*x + 13*y) % 0x100),
    86  					uint8((31*x + 37*y) % 0x100),
    87  				})
    88  			}
    89  		}
    90  		src = src1
    91  	case color.GrayModel:
    92  		src1 := image.NewGray(image.Rect(0, 0, srcw, srch))
    93  		for y := 0; y < srch; y++ {
    94  			for x := 0; x < srcw; x++ {
    95  				src1.SetGray(x, y, color.Gray{
    96  					uint8((11*x + 13*y) % 0x100),
    97  				})
    98  			}
    99  		}
   100  		src = src1
   101  	case color.RGBAModel:
   102  		src1 := image.NewRGBA(image.Rect(0, 0, srcw, srch))
   103  		for y := 0; y < srch; y++ {
   104  			for x := 0; x < srcw; x++ {
   105  				src1.SetRGBA(x, y, color.RGBA{
   106  					uint8(13 * x % 0x80),
   107  					uint8(11 * y % 0x80),
   108  					uint8((11*x + 13*y) % 0x80),
   109  					0x7f,
   110  				})
   111  			}
   112  		}
   113  		src = src1
   114  	case color.RGBA64Model:
   115  		src1 := image.NewRGBA64(image.Rect(0, 0, srcw, srch))
   116  		for y := 0; y < srch; y++ {
   117  			for x := 0; x < srcw; x++ {
   118  				src1.SetRGBA64(x, y, color.RGBA64{
   119  					uint16(103 * x % 0x8000),
   120  					uint16(101 * y % 0x8000),
   121  					uint16((101*x + 103*y) % 0x8000),
   122  					0x7fff,
   123  				})
   124  			}
   125  		}
   126  		src = src1
   127  	case color.NRGBAModel:
   128  		src1 := image.NewNRGBA(image.Rect(0, 0, srcw, srch))
   129  		for y := 0; y < srch; y++ {
   130  			for x := 0; x < srcw; x++ {
   131  				src1.SetNRGBA(x, y, color.NRGBA{
   132  					uint8(13 * x % 0x100),
   133  					uint8(11 * y % 0x100),
   134  					uint8((11*x + 13*y) % 0x100),
   135  					0x7f,
   136  				})
   137  			}
   138  		}
   139  		src = src1
   140  	case color.YCbCrModel:
   141  		yy := make([]uint8, srcw*srch)
   142  		cb := make([]uint8, srcw*srch)
   143  		cr := make([]uint8, srcw*srch)
   144  		for i := range yy {
   145  			yy[i] = uint8(3 * i % 0x100)
   146  			cb[i] = uint8(5 * i % 0x100)
   147  			cr[i] = uint8(7 * i % 0x100)
   148  		}
   149  		src = &image.YCbCr{
   150  			Y:              yy,
   151  			Cb:             cb,
   152  			Cr:             cr,
   153  			YStride:        srcw,
   154  			CStride:        srcw,
   155  			SubsampleRatio: image.YCbCrSubsampleRatio444,
   156  			Rect:           image.Rect(0, 0, srcw, srch),
   157  		}
   158  	default:
   159  		b.Fatal("unknown source color model", scm)
   160  	}
   161  
   162  	var mask image.Image
   163  	switch mcm {
   164  	case nil:
   165  		// No-op.
   166  	case color.AlphaModel:
   167  		mask1 := image.NewAlpha(image.Rect(0, 0, srcw, srch))
   168  		for y := 0; y < srch; y++ {
   169  			for x := 0; x < srcw; x++ {
   170  				a := uint8((23*x + 29*y) % 0x100)
   171  				// Glyph masks are typically mostly zero,
   172  				// so we only set a quarter of mask1's pixels.
   173  				if a >= 0xc0 {
   174  					mask1.SetAlpha(x, y, color.Alpha{a})
   175  				}
   176  			}
   177  		}
   178  		mask = mask1
   179  	default:
   180  		b.Fatal("unknown mask color model", mcm)
   181  	}
   182  
   183  	b.StartTimer()
   184  	for i := 0; i < b.N; i++ {
   185  		// Scatter the destination rectangle to draw into.
   186  		x := 3 * i % (dstw - srcw)
   187  		y := 7 * i % (dsth - srch)
   188  
   189  		DrawMask(dst, dst.Bounds().Add(image.Pt(x, y)), src, image.Point{}, mask, image.Point{}, op)
   190  	}
   191  }
   192  
   193  // The BenchmarkFoo functions exercise a drawFoo fast-path function in draw.go.
   194  
   195  func BenchmarkFillOver(b *testing.B) {
   196  	bench(b, color.RGBAModel, nil, nil, Over)
   197  }
   198  
   199  func BenchmarkFillSrc(b *testing.B) {
   200  	bench(b, color.RGBAModel, nil, nil, Src)
   201  }
   202  
   203  func BenchmarkCopyOver(b *testing.B) {
   204  	bench(b, color.RGBAModel, color.RGBAModel, nil, Over)
   205  }
   206  
   207  func BenchmarkCopySrc(b *testing.B) {
   208  	bench(b, color.RGBAModel, color.RGBAModel, nil, Src)
   209  }
   210  
   211  func BenchmarkNRGBAOver(b *testing.B) {
   212  	bench(b, color.RGBAModel, color.NRGBAModel, nil, Over)
   213  }
   214  
   215  func BenchmarkNRGBASrc(b *testing.B) {
   216  	bench(b, color.RGBAModel, color.NRGBAModel, nil, Src)
   217  }
   218  
   219  func BenchmarkYCbCr(b *testing.B) {
   220  	bench(b, color.RGBAModel, color.YCbCrModel, nil, Over)
   221  }
   222  
   223  func BenchmarkGray(b *testing.B) {
   224  	bench(b, color.RGBAModel, color.GrayModel, nil, Over)
   225  }
   226  
   227  func BenchmarkCMYK(b *testing.B) {
   228  	bench(b, color.RGBAModel, color.CMYKModel, nil, Over)
   229  }
   230  
   231  func BenchmarkGlyphOver(b *testing.B) {
   232  	bench(b, color.RGBAModel, nil, color.AlphaModel, Over)
   233  }
   234  
   235  func BenchmarkRGBAMaskOver(b *testing.B) {
   236  	bench(b, color.RGBAModel, color.RGBAModel, color.AlphaModel, Over)
   237  }
   238  
   239  func BenchmarkGrayMaskOver(b *testing.B) {
   240  	bench(b, color.RGBAModel, color.GrayModel, color.AlphaModel, Over)
   241  }
   242  
   243  func BenchmarkRGBA64ImageMaskOver(b *testing.B) {
   244  	bench(b, color.RGBAModel, color.RGBA64Model, color.AlphaModel, Over)
   245  }
   246  
   247  func BenchmarkRGBA(b *testing.B) {
   248  	bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
   249  }
   250  
   251  func BenchmarkPalettedFill(b *testing.B) {
   252  	bench(b, palette, nil, nil, Src)
   253  }
   254  
   255  func BenchmarkPalettedRGBA(b *testing.B) {
   256  	bench(b, palette, color.RGBAModel, nil, Src)
   257  }
   258  
   259  // The BenchmarkGenericFoo functions exercise the generic, slow-path code.
   260  
   261  func BenchmarkGenericOver(b *testing.B) {
   262  	bench(b, color.RGBA64Model, color.RGBA64Model, nil, Over)
   263  }
   264  
   265  func BenchmarkGenericMaskOver(b *testing.B) {
   266  	bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Over)
   267  }
   268  
   269  func BenchmarkGenericSrc(b *testing.B) {
   270  	bench(b, color.RGBA64Model, color.RGBA64Model, nil, Src)
   271  }
   272  
   273  func BenchmarkGenericMaskSrc(b *testing.B) {
   274  	bench(b, color.RGBA64Model, color.RGBA64Model, color.AlphaModel, Src)
   275  }
   276  

View as plain text