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 <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2018-01-29 12:44:50 -05:00 committed by Skia Commit-Bot
parent 10105308dc
commit 51494f6615
2 changed files with 87 additions and 29 deletions

View File

@ -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<std::mutex> 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()));

View File

@ -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,