]> Cypherpunks repositories - gostls13.git/commitdiff
image/draw: optimize drawFillOver as drawFillSrc for opaque fills.
authorNigel Tao <nigeltao@golang.org>
Thu, 14 Jul 2016 00:51:30 +0000 (10:51 +1000)
committerNigel Tao <nigeltao@golang.org>
Fri, 9 Sep 2016 01:17:26 +0000 (01:17 +0000)
Benchmarks are much better for opaque fills and slightly worse on non
opaque fills. I think that on balance, this is still a win.

When the source is uniform(color.RGBA{0x11, 0x22, 0x33, 0xff}):
name        old time/op  new time/op  delta
FillOver-8   966µs ± 1%    32µs ± 1%  -96.67%  (p=0.000 n=10+10)
FillSrc-8   32.4µs ± 1%  32.2µs ± 1%     ~      (p=0.053 n=9+10)

When the source is uniform(color.RGBA{0x11, 0x22, 0x33, 0x44}):
name        old time/op  new time/op  delta
FillOver-8   962µs ± 0%  1018µs ± 0%  +5.85%   (p=0.000 n=9+10)
FillSrc-8   32.2µs ± 1%  32.1µs ± 0%    ~     (p=0.148 n=10+10)

Change-Id: I52ec6d5fcd0fbc6710cef0e973a21ee7827c0dd9
Reviewed-on: https://go-review.googlesource.com/28790
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/image/draw/bench_test.go
src/image/draw/draw.go

index 7b89f95d11889dc3899e6097ddb07776cf5f6b0a..a41d7e7dfb7ec783c41235f0d7bdd18276ba7f90 100644 (file)
@@ -74,7 +74,7 @@ func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
        var src image.Image
        switch scm {
        case nil:
-               src = &image.Uniform{C: color.RGBA{0x11, 0x22, 0x33, 0xff}}
+               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++ {
index 6a16cd39cf8ef2b6e474293b51fe29706d496d90..a31dd427ce1fd947810f1db452832be2192d43ee 100644 (file)
@@ -116,7 +116,12 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
                        if mask == nil {
                                switch src0 := src.(type) {
                                case *image.Uniform:
-                                       drawFillOver(dst0, r, src0)
+                                       sr, sg, sb, sa := src0.RGBA()
+                                       if sa == 0xffff {
+                                               drawFillSrc(dst0, r, sr, sg, sb, sa)
+                                       } else {
+                                               drawFillOver(dst0, r, sr, sg, sb, sa)
+                                       }
                                        return
                                case *image.RGBA:
                                        drawCopyOver(dst0, r, src0, sp)
@@ -150,7 +155,8 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
                        if mask == nil {
                                switch src0 := src.(type) {
                                case *image.Uniform:
-                                       drawFillSrc(dst0, r, src0)
+                                       sr, sg, sb, sa := src0.RGBA()
+                                       drawFillSrc(dst0, r, sr, sg, sb, sa)
                                        return
                                case *image.RGBA:
                                        drawCopySrc(dst0, r, src0, sp)
@@ -232,8 +238,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
        }
 }
 
-func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
-       sr, sg, sb, sa := src.RGBA()
+func drawFillOver(dst *image.RGBA, r image.Rectangle, sr, sg, sb, sa uint32) {
        // The 0x101 is here for the same reason as in drawRGBA.
        a := (m - sa) * 0x101
        i0 := dst.PixOffset(r.Min.X, r.Min.Y)
@@ -255,8 +260,7 @@ func drawFillOver(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
        }
 }
 
-func drawFillSrc(dst *image.RGBA, r image.Rectangle, src *image.Uniform) {
-       sr, sg, sb, sa := src.RGBA()
+func drawFillSrc(dst *image.RGBA, r image.Rectangle, sr, sg, sb, sa uint32) {
        sr8 := uint8(sr >> 8)
        sg8 := uint8(sg >> 8)
        sb8 := uint8(sb >> 8)