github.com/as/shiny@v0.8.2/driver/internal/swizzle/swizzle_test.go (about) 1 // Copyright 2018 as 2 // Copyright 2015 The Go Authors 3 4 package swizzle 5 6 import ( 7 "bytes" 8 "fmt" 9 "math/rand" 10 "os" 11 "strings" 12 "testing" 13 ) 14 15 var ( 16 rgbaslice = "abcdefghijklmnopqrstuvwxyz012345ABCDEFGHIJKLMNOPQRSTUVWXYZ6789@=" 17 bgraslice = "cbadgfehkjilonmpsrqtwvux0zy14325CBADGFEHKJILONMPSRQTWVUX6ZY7@98=" 18 19 supported = map[string]func(p, q []byte){ 20 "pure": pureBGRA, 21 "amd64.4": bgra4sd, 22 "ssse.16": bgra16sd, 23 "avx2.128": bgra128sd, 24 "avx2.256": bgra256sd, 25 } 26 ) 27 28 func TestMain(m *testing.M) { 29 const safe = 1024 30 rgbaslice = strings.Repeat(rgbaslice, safe) 31 bgraslice = strings.Repeat(bgraslice, safe) 32 33 if !haveAVX2() { 34 delete(supported, "avx2.256") 35 } 36 if !haveAVX() { 37 delete(supported, "avx2.128") 38 } 39 if !haveSSSE3() { 40 delete(supported, "ssse.16") 41 } 42 os.Exit(m.Run()) 43 } 44 45 func TestSwizzleDistinct(t *testing.T) { 46 for _, v := range []int{32, 64, 96, 128, 160, 192, 224, 256} { 47 t.Run(fmt.Sprint(v), func(t *testing.T) { 48 testSwizzle1(t, v, true) 49 }) 50 } 51 } 52 func TestSwizzleOverlap(t *testing.T) { 53 for _, v := range []int{32, 64, 96, 128, 160, 192, 224, 256} { 54 t.Run(fmt.Sprint(v), func(t *testing.T) { 55 testSwizzle1(t, v, false) 56 }) 57 } 58 } 59 60 func testSwizzle1(t *testing.T, N int, distinct bool) { 61 t.Helper() 62 s := []byte(rgbaslice[:N]) 63 d := s 64 if distinct { 65 d = make([]byte, N, N) 66 } 67 want := bgraslice[:N] 68 bgra256sd(s, d) 69 if string(d) != want { 70 t.Fatalf("have: %s\nwant: %s\n", d, want) 71 } 72 } 73 74 func makeRGBA(len int) []byte { 75 if len%4 != 0 { 76 panic("makeRGBA: len % 4 != 0") 77 } 78 return []byte(strings.Repeat("rgba", len/4)) 79 } 80 81 func TestBGRAShort(t *testing.T) { 82 var lens = []int{ 83 4, 8, 12, 16, 24, 32, 48, 64, 128, 192, 256, 512, 84 } 85 var tab []string 86 for _, v := range lens { 87 tab = append(tab, rgbaslice[:v]) 88 } 89 90 for name, fn := range supported { 91 t.Run(name, func(t *testing.T) { 92 for i, in := range tab { 93 want := append([]byte{}, in...) 94 pureBGRA(append([]byte{}, in...), want) 95 p := []byte(in) 96 q := make([]byte, len(p)) 97 fn(p, q) 98 have := string(q) 99 if want := string(want); have != want { 100 t.Errorf("len=%d: have %q, want %q", lens[i], have, want) 101 } 102 } 103 }) 104 } 105 } 106 107 func TestBGRARandom(t *testing.T) { 108 r := rand.New(rand.NewSource(1)) 109 var ( 110 p0, q0, 111 p1, q1 [1024]byte 112 ) 113 for i := range q0 { 114 p0[i] = byte(r.Intn(256)) 115 p1[i] = p0[0] 116 } 117 exp := Swizzle 118 ctl := pureBGRA 119 120 for i := 0; i < 100000; i++ { 121 o := r.Intn(len(p1)) 122 n := r.Intn(len(p1)-o) &^ 0x03 123 exp(p1[o:o+n], q1[o:o+n]) 124 ctl(p0[o:o+n], q0[o:o+n]) 125 if bytes.Equal(q0[:], q1[:]) { 126 continue 127 } 128 for j := range q1 { 129 x := q1[j] 130 y := q1[j] 131 if x != y { 132 t.Fatalf("iter %d: swizzling [%d:%d+%d]: bytes differ at offset %d (aka %d+%d): %#02x vs %#02x", 133 i, o, o, n, j, o, j-o, x, y) 134 } 135 } 136 } 137 } 138 139 func BenchmarkSwizzle(b *testing.B) { 140 sizes := []string{"64B", "64K", "64M"} 141 for name, fn := range supported { 142 for i, v := range sizes { 143 b.Run(name+"/"+v, func(b *testing.B) { 144 d := makeRGBA(64 * 1 << uint(i)) 145 s := make([]byte, len(d)) 146 b.SetBytes(int64(len(s))) 147 b.ResetTimer() 148 for i := 0; i < b.N; i++ { 149 fn(s, d) 150 } 151 152 }) 153 } 154 } 155 }