From 51494f6615b8bd637caf0fd6d0d577ea19d50948 Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Mon, 29 Jan 2018 12:44:50 -0500 Subject: SkQP: Allow checking against nearby pixel's expectations. Also more verbose logging. Change-Id: Ib2d9e3074d155140f14ab8818a332ce926488b79 Reviewed-on: https://skia-review.googlesource.com/101543 Reviewed-by: Hal Canary Commit-Queue: Hal Canary --- tools/skqp/gm_knowledge.cpp | 88 ++++++++++++++++++++++++++++++++++++++------- tools/skqp/make_gmkb.go | 28 +++++++-------- 2 files changed, 87 insertions(+), 29 deletions(-) (limited to 'tools/skqp') diff --git a/tools/skqp/gm_knowledge.cpp b/tools/skqp/gm_knowledge.cpp index 67731c5366..0bdb8303b0 100644 --- a/tools/skqp/gm_knowledge.cpp +++ b/tools/skqp/gm_knowledge.cpp @@ -50,6 +50,60 @@ static int get_error(uint32_t value, uint32_t value_max, uint32_t value_min) { return error; } +static int get_error_with_nearby(int x, int y, const SkPixmap& pm, + const SkPixmap& pm_max, const SkPixmap& pm_min) { + struct NearbyPixels { + const int x, y, w, h; + struct Iter { + const int x, y, w, h; + int8_t curr; + SkIPoint operator*() const { return this->get(); } + SkIPoint get() const { + switch (curr) { + case 0: return {x - 1, y - 1}; + case 1: return {x , y - 1}; + case 2: return {x + 1, y - 1}; + case 3: return {x - 1, y }; + case 4: return {x + 1, y }; + case 5: return {x - 1, y + 1}; + case 6: return {x , y + 1}; + case 7: return {x + 1, y + 1}; + default: SkASSERT(false); return {0, 0}; + } + } + void skipBad() { + do { + SkIPoint p = this->get(); + if (p.x() >= 0 && p.y() >= 0 && p.x() < w && p.y() < h) { + return; + } + ++curr; + } while (curr < 8); + curr = -1; + } + void operator++() { + if (-1 == curr) { return; } + ++curr; + this->skipBad(); + } + bool operator!=(const Iter& other) const { return curr != other.curr; } + }; + Iter begin() const { Iter i{x, y, w, h, 0}; i.skipBad(); return i; } + Iter end() const { return Iter{x, y, w, h, -1}; } + }; + + uint32_t c = *pm.addr32(x, y); + int error = get_error(c, *pm_max.addr32(x, y), *pm_min.addr32(x, y)); + for (SkIPoint p : NearbyPixels{x, y, pm.width(), pm.height()}) { + if (error == 0) { + return 0; + } + error = SkTMin(error, get_error( + c, *pm_max.addr32(p.x(), p.y()), *pm_min.addr32(p.x(), p.y()))); + } + return error; +} + static float set_error_code(gmkb::Error* error_out, gmkb::Error error) { SkASSERT(error != gmkb::Error::kNone); if (error_out) { @@ -125,7 +179,6 @@ float Check(const uint32_t* pixels, if (width <= 0 || height <= 0) { return set_error_code(error_out, Error::kBadInput); } - size_t N = (unsigned)width * (unsigned)height; constexpr char PATH_ROOT[] = "gmkb"; SkString img_path = SkOSPath::Join(PATH_ROOT, name); SkString max_path = SkOSPath::Join(img_path.c_str(), PATH_MAX_PNG); @@ -147,18 +200,23 @@ float Check(const uint32_t* pixels, if (max_image.width() != width || max_image.height() != height) { return set_error_code(error_out, Error::kBadInput); } + int badness = 0; int badPixelCount = 0; - const uint32_t* max_pixels = (uint32_t*)max_image.getPixels(); - const uint32_t* min_pixels = (uint32_t*)min_image.getPixels(); - - for (size_t i = 0; i < N; ++i) { - int error = get_error(pixels[i], max_pixels[i], min_pixels[i]); - if (error > 0) { - badness = SkTMax(error, badness); - ++badPixelCount; + SkPixmap pm(SkImageInfo::Make(width, height, kColorType, kAlphaType), + pixels, width * sizeof(uint32_t)); + SkPixmap pm_max = max_image.pixmap(); + SkPixmap pm_min = min_image.pixmap(); + for (int y = 0; y < pm.height(); ++y) { + for (int x = 0; x < pm.width(); ++x) { + int error = get_error_with_nearby(x, y, pm, pm_max, pm_min) ; + if (error > 0) { + badness = SkTMax(error, badness); + ++badPixelCount; + } } } + if (badness == 0) { std::lock_guard lock(gMutex); gErrors.push_back(Run{SkString(backend), SkString(name), 0, 0}); @@ -176,11 +234,15 @@ float Check(const uint32_t* pixels, error_path.c_str())); SkBitmap errorBitmap; errorBitmap.allocPixels(SkImageInfo::Make(width, height, kColorType, kAlphaType)); - uint32_t* errors = (uint32_t*)errorBitmap.getPixels(); - for (size_t i = 0; i < N; ++i) { - int error = get_error(pixels[i], max_pixels[i], min_pixels[i]); - errors[i] = error > 0 ? 0xFF000000 + (unsigned)error : 0xFFFFFFFF; + + for (int y = 0; y < pm.height(); ++y) { + for (int x = 0; x < pm.width(); ++x) { + int error = get_error_with_nearby(x, y, pm, pm_max, pm_min); + *errorBitmap.getAddr32(x, y) = + error > 0 ? 0xFF000000 + (unsigned)error : 0xFFFFFFFF; + } } + error_path = SkOSPath::Join(report_subdirectory.c_str(), PATH_ERR_PNG); SkAssertResult(WritePixmapToFile(errorBitmap.pixmap(), error_path.c_str())); diff --git a/tools/skqp/make_gmkb.go b/tools/skqp/make_gmkb.go index fae954a94a..10400f7ec8 100644 --- a/tools/skqp/make_gmkb.go +++ b/tools/skqp/make_gmkb.go @@ -32,6 +32,7 @@ const ( // `slack` is an amount to add to the max and subtract from the minimim channel // value for each pixel for the given test. By default, slack is 0. var slack = map[string]int{ + "addarc": 1, "animated-image-blurs": 1, "anisotropic_hq": 1, "bitmapfilters": 1, @@ -42,25 +43,21 @@ var slack = map[string]int{ "bleed_alpha_image_shader": 1, "bleed_image": 1, "blur2rectsnonninepatch": 1, - "blur_ignore_xform_rect": 1, - "blur_ignore_xform_rrect": 1, "blurcircles2": 1, "blurimagevmask": 1, "blurs": 1, + "bmp_filter_quality_repeat": 1, "circular_arcs_stroke_butt": 1, "circular_arcs_stroke_square": 1, "cliperror": 1, + "colormatrix": 1, "complexclip_aa_invert": 1, "complexclip_aa_layer_invert": 1, "concavepaths": 1, "const_color_processor": 1, "convex-polygon-inset": 1, - "dash_line_zero_off_interval": 1, "dashcircle": 1, - "dashing5_aa": 1, - "downsamplebitmap_checkerboard_high_512_256": 1, - "downsamplebitmap_checkerboard_low_512_256": 1, - "downsamplebitmap_checkerboard_medium_512_256": 1, + "dash_line_zero_off_interval": 1, "downsamplebitmap_image_high": 1, "downsamplebitmap_image_low": 1, "downsamplebitmap_image_medium": 1, @@ -69,15 +66,18 @@ var slack = map[string]int{ "downsamplebitmap_text_medium_72.00pt": 1, "drawregionmodes": 1, "dstreadshuffle": 1, - "encode-srgb-jpg": 1, "extractalpha": 1, "fillcircle": 1, + "filterbitmap_checkerboard_192_192": 1, "filterbitmap_checkerboard_32_2": 1, "filterbitmap_checkerboard_32_32": 1, "filterbitmap_checkerboard_32_32_g8": 1, "filterbitmap_checkerboard_32_8": 1, "filterbitmap_checkerboard_4_4": 1, + "filterbitmap_image_color_wheel.png": 1, + "filterbitmap_image_mandrill_16.png": 1, "filterbitmap_image_mandrill_32.png": 1, + "filterbitmap_image_mandrill_64.png": 1, "filterbitmap_image_mandrill_64.png_g8": 1, "filterbitmap_text_10.00pt": 1, "filterbitmap_text_3.00pt": 1, @@ -85,8 +85,6 @@ var slack = map[string]int{ "fontmgr_bounds": 1, "fontmgr_bounds_1_-0.25": 1, "glyph_pos_h_s": 1, - "gradients": 1, - "gradients4f": 1, "gradients_2pt_conical_edge": 1, "gradients_many": 1, "gradients_no_texture": 1, @@ -100,29 +98,27 @@ var slack = map[string]int{ "imagefilterscropped": 1, "imagefiltersscaled": 1, "imagefiltersstroked": 1, - "imagemagnifier": 1, - "largeglyphblur": 1, + "linear_gradient": 1, "manycircles": 1, "nested_aa": 1, "nested_flipY_aa": 1, "ninepatch-stretch": 1, "nonclosedpaths": 1, - "occludedrrectblur": 1, "parsedpaths": 1, - "patheffect": 1, "pathfill": 1, "polygons": 1, "rects": 1, "savelayer_with_backdrop": 1, "scaled_tilemodes_npot": 1, + "shadertext2": 1, "shadertext3": 1, "shadow_utils_occl": 1, "smallpaths": 1, "spritebitmap": 1, - "stroke-fill": 1, - "stroke_rect_shader": 1, "strokecircle": 1, + "stroke-fill": 1, "strokerects": 1, + "strokes3": 1, "strokes_round": 1, "tall_stretched_bitmaps": 1, "thinconcavepaths": 1, -- cgit v1.2.3