]> Cypherpunks repositories - gostls13.git/commitdiff
image/draw: fix double-draw when the dst is paletted.
authorNigel Tao <nigeltao@golang.org>
Fri, 3 Jul 2015 01:34:18 +0000 (11:34 +1000)
committerNigel Tao <nigeltao@golang.org>
Fri, 3 Jul 2015 03:08:40 +0000 (03:08 +0000)
The second (fallback) draw is a no-op, but it's a non-trivial amount of work.

Fixes #11550.

benchmark               old ns/op     new ns/op     delta
BenchmarkPaletted-4     16301219      7309568       -55.16%

Change-Id: Ic88c537b2b0c710cf517888f3dd15cb702dd142f
Reviewed-on: https://go-review.googlesource.com/11858
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/image/draw/bench_test.go
src/image/draw/draw.go

index 51145d11270c903a7d598b6be47f1713243d2f62..7b89f95d11889dc3899e6097ddb07776cf5f6b0a 100644 (file)
@@ -7,6 +7,7 @@ package draw
 import (
        "image"
        "image/color"
+       "reflect"
        "testing"
 )
 
@@ -15,6 +16,11 @@ const (
        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.
@@ -50,7 +56,19 @@ func bench(b *testing.B, dcm, scm, mcm color.Model, op Op) {
                }
                dst = dst1
        default:
-               b.Fatal("unknown destination color model", dcm)
+               // 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
@@ -218,6 +236,10 @@ func BenchmarkRGBA(b *testing.B) {
        bench(b, color.RGBAModel, color.RGBA64Model, nil, Src)
 }
 
+func BenchmarkPaletted(b *testing.B) {
+       bench(b, palette, color.RGBAModel, nil, Src)
+}
+
 // The BenchmarkGenericFoo functions exercise the generic, slow-path code.
 
 func BenchmarkGenericOver(b *testing.B) {
index ee1126cd08bc0bdb4d2fc44b4dec2b70d7f269ca..3087c07ff5a210d4cf18b595e1f71f3bd28ea9fe 100644 (file)
@@ -176,6 +176,7 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas
        case *image.Paletted:
                if op == Src && mask == nil && !processBackward(dst, r, src, sp) {
                        drawPaletted(dst0, r, src, sp, false)
+                       return
                }
        }