aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/skqp/make_gmkb.go
diff options
context:
space:
mode:
Diffstat (limited to 'tools/skqp/make_gmkb.go')
-rw-r--r--tools/skqp/make_gmkb.go223
1 files changed, 223 insertions, 0 deletions
diff --git a/tools/skqp/make_gmkb.go b/tools/skqp/make_gmkb.go
new file mode 100644
index 0000000000..b8b67a3634
--- /dev/null
+++ b/tools/skqp/make_gmkb.go
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+package main
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "image"
+ "image/draw"
+ "image/png"
+ "log"
+ "net/http"
+ "os"
+ "path"
+ "sort"
+ "strings"
+ "sync"
+
+ "go.skia.org/infra/golden/go/search"
+)
+
+const (
+ min_png = "min.png"
+ max_png = "max.png"
+)
+
+type ExportTestRecordArray []search.ExportTestRecord
+
+func (a ExportTestRecordArray) Len() int { return len(a) }
+func (a ExportTestRecordArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a ExportTestRecordArray) Less(i, j int) bool { return a[i].TestName < a[j].TestName }
+
+func in(v string, a []string) bool {
+ for _, u := range a {
+ if u == v {
+ return true
+ }
+ }
+ return false
+}
+
+// TODO(halcanary): clean up this blacklist.
+var blacklist = []string{
+ "circular-clips",
+ "colorcomposefilter_wacky",
+ "coloremoji_blendmodes",
+ "colormatrix",
+ "complexclip_bw",
+ "complexclip_bw_invert",
+ "complexclip_bw_layer",
+ "complexclip_bw_layer_invert",
+ "convex-lineonly-paths-stroke-and-fill",
+ "dftext",
+ "downsamplebitmap_image_high_mandrill_512.png",
+ "downsamplebitmap_image_medium_mandrill_512.png",
+ "filterbitmap_image_mandrill_16.png",
+ "filterbitmap_image_mandrill_64.png",
+ "filterbitmap_image_mandrill_64.png_g8",
+ "gradients_degenerate_2pt",
+ "gradients_degenerate_2pt_nodither",
+ "gradients_local_perspective",
+ "gradients_local_perspective_nodither",
+ "imagefilterstransformed",
+ "image_scale_aligned",
+ "lattice",
+ "linear_gradient",
+ "mipmap_srgb",
+ "mixedtextblobs",
+ "OverStroke",
+ "simple-offsetimagefilter",
+ "strokerect",
+ "textblobmixedsizes",
+ "textblobmixedsizes_df"}
+
+func processTest(testName string, imgUrls []string, output string) error {
+ if strings.ContainsRune(testName, '/') {
+ return nil
+ }
+ output_directory := path.Join(output, testName)
+ var img_max image.NRGBA
+ var img_min image.NRGBA
+ for _, url := range imgUrls {
+ resp, err := http.Get(url)
+ if err != nil {
+ return err
+ }
+ img, err := png.Decode(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ if img_max.Rect.Max.X == 0 {
+ // N.B. img_max.Pix may alias img.Pix (if they're already NRGBA).
+ img_max = toNrgba(img)
+ img_min = copyNrgba(img_max)
+ continue
+ }
+ w := img.Bounds().Max.X - img.Bounds().Min.X
+ h := img.Bounds().Max.Y - img.Bounds().Min.Y
+ if img_max.Rect.Max.X != w || img_max.Rect.Max.Y != h {
+ return errors.New("size mismatch")
+ }
+ img_nrgba := toNrgba(img)
+ for i, value := range img_nrgba.Pix {
+ if value > img_max.Pix[i] {
+ img_max.Pix[i] = value
+ } else if value < img_min.Pix[i] {
+ img_min.Pix[i] = value
+ }
+ }
+ }
+ if img_max.Rect.Max.X == 0 {
+ return nil
+ }
+ if err := os.Mkdir(output_directory, os.ModePerm); err != nil && !os.IsExist(err) {
+ return err
+ }
+ if err := writePngToFile(path.Join(output_directory, min_png), &img_min); err != nil {
+ return err
+ }
+ if err := writePngToFile(path.Join(output_directory, max_png), &img_max); err != nil {
+ return err
+ }
+ return nil
+
+}
+
+func readMetaJsonFile(filename string) ([]search.ExportTestRecord, error) {
+ file, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ dec := json.NewDecoder(file)
+ var records []search.ExportTestRecord
+ err = dec.Decode(&records)
+ return records, err
+}
+
+func writePngToFile(path string, img image.Image) error {
+ file, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ return png.Encode(file, img)
+}
+
+// to_nrgb() may return a shallow copy of img if it's already NRGBA.
+func toNrgba(img image.Image) image.NRGBA {
+ switch v := img.(type) {
+ case *image.NRGBA:
+ return *v
+ }
+ nimg := *image.NewNRGBA(img.Bounds())
+ draw.Draw(&nimg, img.Bounds(), img, image.Point{0, 0}, draw.Src)
+ return nimg
+}
+
+func copyNrgba(src image.NRGBA) image.NRGBA {
+ dst := image.NRGBA{make([]uint8, len(src.Pix)), src.Stride, src.Rect}
+ copy(dst.Pix, src.Pix)
+ return dst
+}
+
+func main() {
+ if len(os.Args) != 3 {
+ log.Printf("Usage:\n %s INPUT.json OUTPUT_DIRECTORY\n\n", os.Args[0])
+ os.Exit(1)
+ }
+ input := os.Args[1]
+ output := os.Args[2]
+ err := os.MkdirAll(output, os.ModePerm)
+ if err != nil && !os.IsExist(err) {
+ log.Fatal(err)
+ }
+
+ records, err := readMetaJsonFile(input)
+ if err != nil {
+ log.Fatal(err)
+ }
+ sort.Sort(ExportTestRecordArray(records))
+
+ index, err := os.Create(path.Join(output, "index.txt"))
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer index.Close()
+
+ var wg sync.WaitGroup
+ for _, record := range records {
+ if in(record.TestName, blacklist) {
+ continue
+ }
+ var goodUrls []string
+ for _, digest := range record.Digests {
+ if (in("vk", digest.ParamSet["config"]) ||
+ in("gles", digest.ParamSet["config"])) &&
+ digest.Status == "positive" {
+ goodUrls = append(goodUrls, digest.URL)
+ }
+ }
+ wg.Add(1)
+ go func(testName string, imgUrls []string, output string) {
+ defer wg.Done()
+ if err := processTest(testName, imgUrls, output); err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("\r%-60s", testName)
+ }(record.TestName, goodUrls, output)
+
+ _, err = fmt.Fprintf(index, "%s\n", record.TestName)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+ wg.Wait()
+ fmt.Printf("\r%60s\n", "")
+}