зеркало из https://github.com/mozilla/moz-skia.git
Add option to ignore small pixel diffs for --validate. By default, right
now we will default to max diff of 256, which means that for now we report all pixels that are not as expected and we do not error out. Ideally we will decrease the value of max diff to something that does not have visual impact, e.g. 10, then we will report small changes with the intensity under 10, but we will error out for anything larger. Review URL: https://codereview.appspot.com/7137046 git-svn-id: http://skia.googlecode.com/svn/trunk@7232 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
edb7713cd5
Коммит
ca1b3ff634
|
@ -21,10 +21,6 @@
|
||||||
#include "PictureRenderer.h"
|
#include "PictureRenderer.h"
|
||||||
#include "picture_utils.h"
|
#include "picture_utils.h"
|
||||||
|
|
||||||
// Define this if validation failures should cause the tool to return failure
|
|
||||||
// If not, it will still printf the messages.
|
|
||||||
//#define VALIDATE_FAILURE_IS_A_TOOL_FAILURE
|
|
||||||
|
|
||||||
static void usage(const char* argv0) {
|
static void usage(const char* argv0) {
|
||||||
SkDebugf("SkPicture rendering tool\n");
|
SkDebugf("SkPicture rendering tool\n");
|
||||||
SkDebugf("\n"
|
SkDebugf("\n"
|
||||||
|
@ -36,7 +32,7 @@ static void usage(const char* argv0) {
|
||||||
" [--pipe]\n"
|
" [--pipe]\n"
|
||||||
" [--bbh bbhType]\n"
|
" [--bbh bbhType]\n"
|
||||||
" [--multi count]\n"
|
" [--multi count]\n"
|
||||||
" [--validate]\n"
|
" [--validate [--maxComponentDiff n]]\n"
|
||||||
" [--writeWholeImage]\n"
|
" [--writeWholeImage]\n"
|
||||||
" [--clone n]\n"
|
" [--clone n]\n"
|
||||||
" [--viewport width height][--scale sf]\n"
|
" [--viewport width height][--scale sf]\n"
|
||||||
|
@ -90,6 +86,8 @@ static void usage(const char* argv0) {
|
||||||
SkDebugf(
|
SkDebugf(
|
||||||
" --validate: Verify that the rendered image contains the same pixels as "
|
" --validate: Verify that the rendered image contains the same pixels as "
|
||||||
"the picture rendered in simple mode.\n"
|
"the picture rendered in simple mode.\n"
|
||||||
|
" --maxComponentDiff: maximum diff on a component. Default is 256, "
|
||||||
|
"which means we report but we do not generate an error.\n"
|
||||||
" --writeWholeImage: In tile mode, write the entire rendered image to a "
|
" --writeWholeImage: In tile mode, write the entire rendered image to a "
|
||||||
"file, instead of an image for each tile.\n");
|
"file, instead of an image for each tile.\n");
|
||||||
SkDebugf(
|
SkDebugf(
|
||||||
|
@ -178,11 +176,22 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int getByte(uint32_t value, int index) {
|
||||||
|
SkASSERT(0 <= index && index < 4);
|
||||||
|
return (value >> (index * 8)) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MaxByteDiff(uint32_t v1, uint32_t v2) {
|
||||||
|
return SkMax32(SkMax32(abs(getByte(v1, 0) - getByte(v2, 0)), abs(getByte(v1, 1) - getByte(v2, 1))),
|
||||||
|
SkMax32(abs(getByte(v1, 2) - getByte(v2, 2)), abs(getByte(v1, 3) - getByte(v2, 3))));
|
||||||
|
}
|
||||||
|
|
||||||
static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||||
sk_tools::PictureRenderer& renderer,
|
sk_tools::PictureRenderer& renderer,
|
||||||
bool validate,
|
bool validate, int maxComponentDiff,
|
||||||
bool writeWholeImage,
|
bool writeWholeImage,
|
||||||
int clones) {
|
int clones) {
|
||||||
|
int diffs[256] = {0};
|
||||||
SkBitmap* bitmap = NULL;
|
SkBitmap* bitmap = NULL;
|
||||||
bool success = render_picture(inputPath,
|
bool success = render_picture(inputPath,
|
||||||
writeWholeImage ? NULL : outputDir,
|
writeWholeImage ? NULL : outputDir,
|
||||||
|
@ -225,23 +234,30 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||||
|
|
||||||
for (int y = 0; success && y < bitmap->height(); y++) {
|
for (int y = 0; success && y < bitmap->height(); y++) {
|
||||||
for (int x = 0; success && x < bitmap->width(); x++) {
|
for (int x = 0; success && x < bitmap->width(); x++) {
|
||||||
if (*referenceBitmap->getAddr32(x, y) != *bitmap->getAddr32(x, y)) {
|
int diff = MaxByteDiff(*referenceBitmap->getAddr32(x, y),
|
||||||
SkDebugf("Expected pixel at (%i %i): 0x%x, actual 0x%x\n",
|
*bitmap->getAddr32(x, y));
|
||||||
x, y,
|
SkASSERT(diff >= 0 && diff <= 255);
|
||||||
|
diffs[diff]++;
|
||||||
|
|
||||||
|
if (diff > maxComponentDiff) {
|
||||||
|
SkDebugf("Expected pixel at (%i %i) exceedds maximum "
|
||||||
|
"component diff of %i: 0x%x, actual 0x%x\n",
|
||||||
|
x, y, maxComponentDiff,
|
||||||
*referenceBitmap->getAddr32(x, y),
|
*referenceBitmap->getAddr32(x, y),
|
||||||
*bitmap->getAddr32(x, y));
|
*bitmap->getAddr32(x, y));
|
||||||
#ifdef VALIDATE_FAILURE_IS_A_TOOL_FAILURE
|
|
||||||
SkDELETE(bitmap);
|
SkDELETE(bitmap);
|
||||||
SkDELETE(referenceBitmap);
|
SkDELETE(referenceBitmap);
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
goto DONE;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DONE:
|
|
||||||
SkDELETE(referenceBitmap);
|
SkDELETE(referenceBitmap);
|
||||||
|
|
||||||
|
for (int i = 1; i <= 255; ++i) {
|
||||||
|
if(diffs[i] > 0) {
|
||||||
|
SkDebugf("Number of pixels with max diff of %i is %i\n", i, diffs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeWholeImage) {
|
if (writeWholeImage) {
|
||||||
|
@ -267,7 +283,8 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||||
|
|
||||||
static int process_input(const SkString& input, const SkString* outputDir,
|
static int process_input(const SkString& input, const SkString* outputDir,
|
||||||
sk_tools::PictureRenderer& renderer,
|
sk_tools::PictureRenderer& renderer,
|
||||||
bool validate, bool writeWholeImage, int clones) {
|
bool validate, int maxComponentDiff,
|
||||||
|
bool writeWholeImage, int clones) {
|
||||||
SkOSFile::Iter iter(input.c_str(), "skp");
|
SkOSFile::Iter iter(input.c_str(), "skp");
|
||||||
SkString inputFilename;
|
SkString inputFilename;
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
|
@ -277,14 +294,16 @@ static int process_input(const SkString& input, const SkString* outputDir,
|
||||||
SkString inputPath;
|
SkString inputPath;
|
||||||
sk_tools::make_filepath(&inputPath, input, inputFilename);
|
sk_tools::make_filepath(&inputPath, input, inputFilename);
|
||||||
if (!render_picture(inputPath, outputDir, renderer,
|
if (!render_picture(inputPath, outputDir, renderer,
|
||||||
validate, writeWholeImage, clones)) {
|
validate, maxComponentDiff,
|
||||||
|
writeWholeImage, clones)) {
|
||||||
++failures;
|
++failures;
|
||||||
}
|
}
|
||||||
} while(iter.next(&inputFilename));
|
} while(iter.next(&inputFilename));
|
||||||
} else if (SkStrEndsWith(input.c_str(), ".skp")) {
|
} else if (SkStrEndsWith(input.c_str(), ".skp")) {
|
||||||
SkString inputPath(input);
|
SkString inputPath(input);
|
||||||
if (!render_picture(inputPath, outputDir, renderer,
|
if (!render_picture(inputPath, outputDir, renderer,
|
||||||
validate, writeWholeImage, clones)) {
|
validate, maxComponentDiff,
|
||||||
|
writeWholeImage, clones)) {
|
||||||
++failures;
|
++failures;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,7 +316,8 @@ static int process_input(const SkString& input, const SkString* outputDir,
|
||||||
|
|
||||||
static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
|
static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
|
||||||
sk_tools::PictureRenderer*& renderer, SkString*& outputDir,
|
sk_tools::PictureRenderer*& renderer, SkString*& outputDir,
|
||||||
bool* validate, bool* writeWholeImage,
|
bool* validate, int* maxComponentDiff,
|
||||||
|
bool* writeWholeImage,
|
||||||
int* clones){
|
int* clones){
|
||||||
const char* argv0 = argv[0];
|
const char* argv0 = argv[0];
|
||||||
char* const* stop = argv + argc;
|
char* const* stop = argv + argc;
|
||||||
|
@ -321,6 +341,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
|
||||||
sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
|
sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
|
||||||
sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
|
sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
|
||||||
*validate = false;
|
*validate = false;
|
||||||
|
*maxComponentDiff = 256;
|
||||||
*writeWholeImage = false;
|
*writeWholeImage = false;
|
||||||
*clones = 0;
|
*clones = 0;
|
||||||
SkISize viewport;
|
SkISize viewport;
|
||||||
|
@ -520,6 +541,25 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>*
|
||||||
outputDir = SkNEW_ARGS(SkString, (*argv));
|
outputDir = SkNEW_ARGS(SkString, (*argv));
|
||||||
} else if (0 == strcmp(*argv, "--validate")) {
|
} else if (0 == strcmp(*argv, "--validate")) {
|
||||||
*validate = true;
|
*validate = true;
|
||||||
|
} else if (0 == strcmp(*argv, "--maxComponentDiff")) {
|
||||||
|
if (!*validate) {
|
||||||
|
SkDebugf("--maxComponentDiff must be used only with --validate\n");
|
||||||
|
usage(argv0);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
++argv;
|
||||||
|
if (argv >= stop) {
|
||||||
|
SkDebugf("Missing arg for --maxComponentDiff\n");
|
||||||
|
usage(argv0);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
*maxComponentDiff = atoi(*argv);
|
||||||
|
if (*maxComponentDiff < 0 || *maxComponentDiff > 256) {
|
||||||
|
SkSafeUnref(renderer);
|
||||||
|
SkDebugf("maxComponentDiff: 0 - 256.\n");
|
||||||
|
usage(argv0);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
} else if (0 == strcmp(*argv, "--writeWholeImage")) {
|
} else if (0 == strcmp(*argv, "--writeWholeImage")) {
|
||||||
*writeWholeImage = true;
|
*writeWholeImage = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -685,16 +725,18 @@ int tool_main(int argc, char** argv) {
|
||||||
sk_tools::PictureRenderer* renderer = NULL;
|
sk_tools::PictureRenderer* renderer = NULL;
|
||||||
SkString* outputDir = NULL;
|
SkString* outputDir = NULL;
|
||||||
bool validate = false;
|
bool validate = false;
|
||||||
|
int maxComponentDiff = 256;
|
||||||
bool writeWholeImage = false;
|
bool writeWholeImage = false;
|
||||||
int clones = 0;
|
int clones = 0;
|
||||||
parse_commandline(argc, argv, &inputs, renderer, outputDir,
|
parse_commandline(argc, argv, &inputs, renderer, outputDir,
|
||||||
&validate, &writeWholeImage, &clones);
|
&validate, &maxComponentDiff, &writeWholeImage, &clones);
|
||||||
SkASSERT(renderer);
|
SkASSERT(renderer);
|
||||||
|
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
for (int i = 0; i < inputs.count(); i ++) {
|
for (int i = 0; i < inputs.count(); i ++) {
|
||||||
failures += process_input(inputs[i], outputDir, *renderer,
|
failures += process_input(inputs[i], outputDir, *renderer,
|
||||||
validate, writeWholeImage, clones);
|
validate, maxComponentDiff,
|
||||||
|
writeWholeImage, clones);
|
||||||
}
|
}
|
||||||
if (failures != 0) {
|
if (failures != 0) {
|
||||||
SkDebugf("Failed to render %i pictures.\n", failures);
|
SkDebugf("Failed to render %i pictures.\n", failures);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче