зеркало из https://github.com/mozilla/moz-skia.git
Write/compare against expectations in skimage tool.
skimage: Add two new modes: one to write expectations to a json file, and another to compare results against expectations. Use SkPATH_SEPARATOR instead of '/'. gm_expectations: Split into a static library so it can be used by skimage. Make functions non static and move function definitions into source file. Capitalize static member functions to follow the coding style guidelines. BUG=https://code.google.com/p/skia/issues/detail?id=1241 R=epoger@google.com Review URL: https://codereview.chromium.org/14670021 git-svn-id: http://skia.googlecode.com/svn/trunk@9069 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
94b366a3e8
Коммит
6843bdb706
|
@ -24,6 +24,27 @@ const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-f
|
||||||
|
|
||||||
namespace skiagm {
|
namespace skiagm {
|
||||||
|
|
||||||
|
void gm_fprintf(FILE *stream, const char format[], ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
fprintf(stream, "GM: ");
|
||||||
|
vfprintf(stream, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkString make_filename(const char path[],
|
||||||
|
const char renderModeDescriptor[],
|
||||||
|
const char *name,
|
||||||
|
const char suffix[]) {
|
||||||
|
SkString filename(path);
|
||||||
|
if (filename.endsWith(SkPATH_SEPARATOR)) {
|
||||||
|
filename.remove(filename.size() - 1, 1);
|
||||||
|
}
|
||||||
|
filename.appendf("%c%s%s.%s", SkPATH_SEPARATOR,
|
||||||
|
name, renderModeDescriptor, suffix);
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(epoger): This currently assumes that the result SkHashDigest was
|
// TODO(epoger): This currently assumes that the result SkHashDigest was
|
||||||
// generated as an SkHashDigest of an SkBitmap. We'll need to allow for other
|
// generated as an SkHashDigest of an SkBitmap. We'll need to allow for other
|
||||||
// hash types to cover non-bitmaps.
|
// hash types to cover non-bitmaps.
|
||||||
|
@ -160,7 +181,7 @@ namespace skiagm {
|
||||||
// JsonExpectationsSource class...
|
// JsonExpectationsSource class...
|
||||||
|
|
||||||
JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) {
|
JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) {
|
||||||
parse(jsonPath, &fJsonRoot);
|
Parse(jsonPath, &fJsonRoot);
|
||||||
fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults];
|
fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +189,7 @@ namespace skiagm {
|
||||||
return Expectations(fJsonExpectedResults[testName]);
|
return Expectations(fJsonExpectedResults[testName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ SkData* JsonExpectationsSource::readIntoSkData(SkStream &stream, size_t maxBytes) {
|
/*static*/ SkData* JsonExpectationsSource::ReadIntoSkData(SkStream &stream, size_t maxBytes) {
|
||||||
if (0 == maxBytes) {
|
if (0 == maxBytes) {
|
||||||
return SkData::NewEmpty();
|
return SkData::NewEmpty();
|
||||||
}
|
}
|
||||||
|
@ -186,7 +207,7 @@ namespace skiagm {
|
||||||
return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining);
|
return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ bool JsonExpectationsSource::parse(const char *jsonPath, Json::Value *jsonRoot) {
|
/*static*/ bool JsonExpectationsSource::Parse(const char *jsonPath, Json::Value *jsonRoot) {
|
||||||
SkFILEStream inFile(jsonPath);
|
SkFILEStream inFile(jsonPath);
|
||||||
if (!inFile.isValid()) {
|
if (!inFile.isValid()) {
|
||||||
gm_fprintf(stderr, "unable to read JSON file %s\n", jsonPath);
|
gm_fprintf(stderr, "unable to read JSON file %s\n", jsonPath);
|
||||||
|
@ -194,7 +215,7 @@ namespace skiagm {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoDataUnref dataRef(readFileIntoSkData(inFile));
|
SkAutoDataUnref dataRef(ReadFileIntoSkData(inFile));
|
||||||
if (NULL == dataRef.get()) {
|
if (NULL == dataRef.get()) {
|
||||||
gm_fprintf(stderr, "error reading JSON file %s\n", jsonPath);
|
gm_fprintf(stderr, "error reading JSON file %s\n", jsonPath);
|
||||||
DEBUGFAIL_SEE_STDERR;
|
DEBUGFAIL_SEE_STDERR;
|
||||||
|
|
|
@ -39,26 +39,12 @@ namespace skiagm {
|
||||||
return jsonValue.asUInt64();
|
return jsonValue.asUInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gm_fprintf(FILE *stream, const char format[], ...) {
|
void gm_fprintf(FILE *stream, const char format[], ...);
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
fprintf(stream, "GM: ");
|
|
||||||
vfprintf(stream, format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SkString make_filename(const char path[],
|
SkString make_filename(const char path[],
|
||||||
const char renderModeDescriptor[],
|
const char renderModeDescriptor[],
|
||||||
const char *name,
|
const char *name,
|
||||||
const char suffix[]) {
|
const char suffix[]);
|
||||||
SkString filename(path);
|
|
||||||
if (filename.endsWith(SkPATH_SEPARATOR)) {
|
|
||||||
filename.remove(filename.size() - 1, 1);
|
|
||||||
}
|
|
||||||
filename.appendf("%c%s%s.%s", SkPATH_SEPARATOR,
|
|
||||||
name, renderModeDescriptor, suffix);
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value ActualResultAsJsonValue(const SkHashDigest& result);
|
Json::Value ActualResultAsJsonValue(const SkHashDigest& result);
|
||||||
|
|
||||||
|
@ -208,15 +194,15 @@ namespace skiagm {
|
||||||
*/
|
*/
|
||||||
// TODO(epoger): Move this, into SkStream.[cpp|h] as attempted in
|
// TODO(epoger): Move this, into SkStream.[cpp|h] as attempted in
|
||||||
// https://codereview.appspot.com/7300071 ?
|
// https://codereview.appspot.com/7300071 ?
|
||||||
// And maybe readFileIntoSkData() also?
|
// And maybe ReadFileIntoSkData() also?
|
||||||
static SkData* readIntoSkData(SkStream &stream, size_t maxBytes);
|
static SkData* ReadIntoSkData(SkStream &stream, size_t maxBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around readIntoSkData for files: reads the entire file into
|
* Wrapper around ReadIntoSkData for files: reads the entire file into
|
||||||
* an SkData object.
|
* an SkData object.
|
||||||
*/
|
*/
|
||||||
static SkData* readFileIntoSkData(SkFILEStream &stream) {
|
static SkData* ReadFileIntoSkData(SkFILEStream &stream) {
|
||||||
return readIntoSkData(stream, stream.getLength());
|
return ReadIntoSkData(stream, stream.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,7 +210,7 @@ namespace skiagm {
|
||||||
*
|
*
|
||||||
* Returns true if successful.
|
* Returns true if successful.
|
||||||
*/
|
*/
|
||||||
static bool parse(const char *jsonPath, Json::Value *jsonRoot);
|
static bool Parse(const char *jsonPath, Json::Value *jsonRoot);
|
||||||
|
|
||||||
Json::Value fJsonRoot;
|
Json::Value fJsonRoot;
|
||||||
Json::Value fJsonExpectedResults;
|
Json::Value fJsonExpectedResults;
|
||||||
|
|
26
gyp/gm.gyp
26
gyp/gm.gyp
|
@ -4,6 +4,30 @@
|
||||||
'apptype_console.gypi',
|
'apptype_console.gypi',
|
||||||
],
|
],
|
||||||
'targets': [
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'gm_expectations',
|
||||||
|
'type': 'static_library',
|
||||||
|
'include_dirs' : [
|
||||||
|
'../include/core/',
|
||||||
|
'../src/utils/',
|
||||||
|
],
|
||||||
|
'sources': [
|
||||||
|
'../gm/gm_expectations.h',
|
||||||
|
'../gm/gm_expectations.cpp',
|
||||||
|
],
|
||||||
|
'dependencies': [
|
||||||
|
'skia_base_libs.gyp:skia_base_libs',
|
||||||
|
'core.gyp:core',
|
||||||
|
'images.gyp:images',
|
||||||
|
'jsoncpp.gyp:jsoncpp',
|
||||||
|
'utils.gyp:utils',
|
||||||
|
],
|
||||||
|
'direct_dependent_settings': {
|
||||||
|
'include_dirs': [
|
||||||
|
'../gm/',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'target_name': 'gm',
|
'target_name': 'gm',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
@ -26,7 +50,6 @@
|
||||||
'../debugger/SkObjectParser.cpp',
|
'../debugger/SkObjectParser.cpp',
|
||||||
|
|
||||||
'../gm/gm.cpp',
|
'../gm/gm.cpp',
|
||||||
'../gm/gm_expectations.cpp',
|
|
||||||
'../gm/gmmain.cpp',
|
'../gm/gmmain.cpp',
|
||||||
'../gm/system_preferences_default.cpp',
|
'../gm/system_preferences_default.cpp',
|
||||||
|
|
||||||
|
@ -37,6 +60,7 @@
|
||||||
'skia_base_libs.gyp:skia_base_libs',
|
'skia_base_libs.gyp:skia_base_libs',
|
||||||
'effects.gyp:effects',
|
'effects.gyp:effects',
|
||||||
'flags.gyp:flags',
|
'flags.gyp:flags',
|
||||||
|
'gm.gyp:gm_expectations',
|
||||||
'images.gyp:images',
|
'images.gyp:images',
|
||||||
'jsoncpp.gyp:jsoncpp',
|
'jsoncpp.gyp:jsoncpp',
|
||||||
'pdf.gyp:pdf',
|
'pdf.gyp:pdf',
|
||||||
|
|
|
@ -78,11 +78,18 @@
|
||||||
'sources': [
|
'sources': [
|
||||||
'../tools/skimage_main.cpp',
|
'../tools/skimage_main.cpp',
|
||||||
],
|
],
|
||||||
|
'include_dirs': [
|
||||||
|
# For SkBitmapHasher.h
|
||||||
|
'../src/utils/',
|
||||||
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'skia_base_libs.gyp:skia_base_libs',
|
'skia_base_libs.gyp:skia_base_libs',
|
||||||
'effects.gyp:effects',
|
'effects.gyp:effects',
|
||||||
'images.gyp:images',
|
|
||||||
'flags.gyp:flags',
|
'flags.gyp:flags',
|
||||||
|
'gm.gyp:gm_expectations',
|
||||||
|
'images.gyp:images',
|
||||||
|
'jsoncpp.gyp:jsoncpp',
|
||||||
|
'utils.gyp:utils',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "gm_expectations.h"
|
||||||
#include "SkBitmap.h"
|
#include "SkBitmap.h"
|
||||||
|
#include "SkBitmapHasher.h"
|
||||||
#include "SkColorPriv.h"
|
#include "SkColorPriv.h"
|
||||||
#include "SkCommandLineFlags.h"
|
#include "SkCommandLineFlags.h"
|
||||||
#include "SkData.h"
|
#include "SkData.h"
|
||||||
|
@ -18,7 +20,9 @@
|
||||||
#include "SkTArray.h"
|
#include "SkTArray.h"
|
||||||
#include "SkTemplates.h"
|
#include "SkTemplates.h"
|
||||||
|
|
||||||
|
DEFINE_string(createExpectationsPath, "", "Path to write JSON expectations.");
|
||||||
DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.");
|
DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.");
|
||||||
|
DEFINE_string(readExpectationsPath, "", "Path to read JSON expectations from.");
|
||||||
DEFINE_string2(writePath, w, "", "Write rendered images into this directory.");
|
DEFINE_string2(writePath, w, "", "Write rendered images into this directory.");
|
||||||
DEFINE_bool(reencode, true, "Reencode the images to test encoding.");
|
DEFINE_bool(reencode, true, "Reencode the images to test encoding.");
|
||||||
DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images.");
|
DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images.");
|
||||||
|
@ -97,6 +101,10 @@ static SkTArray<SkString, false> gSuccessfulDecodes;
|
||||||
static SkTArray<SkString, false> gSuccessfulSubsetDecodes;
|
static SkTArray<SkString, false> gSuccessfulSubsetDecodes;
|
||||||
static SkTArray<SkString, false> gFailedSubsetDecodes;
|
static SkTArray<SkString, false> gFailedSubsetDecodes;
|
||||||
|
|
||||||
|
// Expections read from a file specified by readExpectationsPath. The expectations must have been
|
||||||
|
// previously written using createExpectationsPath.
|
||||||
|
SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations;
|
||||||
|
|
||||||
static bool write_bitmap(const char outName[], SkBitmap* bm) {
|
static bool write_bitmap(const char outName[], SkBitmap* bm) {
|
||||||
SkBitmap bitmap8888;
|
SkBitmap bitmap8888;
|
||||||
if (SkBitmap::kARGB_8888_Config != bm->config()) {
|
if (SkBitmap::kARGB_8888_Config != bm->config()) {
|
||||||
|
@ -157,6 +165,79 @@ static SkIRect generate_random_rect(SkRandom* rand, int32_t maxX, int32_t maxY)
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stored expectations to be written to a file if createExpectationsPath is specified.
|
||||||
|
static Json::Value gExpectationsToWrite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If expectations are to be recorded, record the expected checksum of bitmap into global
|
||||||
|
* expectations array.
|
||||||
|
*/
|
||||||
|
static void write_expectations(const SkBitmap& bitmap, const char* filename) {
|
||||||
|
if (!FLAGS_createExpectationsPath.isEmpty()) {
|
||||||
|
// Creates an Expectations object, and add it to the list to write.
|
||||||
|
skiagm::Expectations expectation(bitmap);
|
||||||
|
Json::Value value = expectation.asJsonValue();
|
||||||
|
gExpectationsToWrite[filename] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the file, ignoring the directory structure.
|
||||||
|
* Does not create a new string.
|
||||||
|
* @param fullPath Full path to the file.
|
||||||
|
* @return string The basename of the file - anything beyond the final slash, or the full name
|
||||||
|
* if there is no slash.
|
||||||
|
* TODO: Might this be useful as a utility function in SkOSFile? Would it be more appropriate to
|
||||||
|
* create a new string?
|
||||||
|
*/
|
||||||
|
static const char* SkBasename(const char* fullPath) {
|
||||||
|
const char* filename = strrchr(fullPath, SkPATH_SEPARATOR);
|
||||||
|
if (NULL == filename || ++filename == '\0') {
|
||||||
|
filename = fullPath;
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare against an expectation for this filename, if there is one.
|
||||||
|
* @param bitmap SkBitmap to compare to the expected value.
|
||||||
|
* @param filename String used to find the expected value.
|
||||||
|
* @return bool True if the bitmap matched the expectation, or if there was no expectation. False
|
||||||
|
* if there was an expecation that the bitmap did not match, or if an expectation could not be
|
||||||
|
* computed from an expectation.
|
||||||
|
*/
|
||||||
|
static bool compare_to_expectations_if_necessary(const SkBitmap& bitmap, const char* filename,
|
||||||
|
SkTArray<SkString, false>* failureArray) {
|
||||||
|
if (NULL == gJsonExpectations.get()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
skiagm::Expectations jsExpectation = gJsonExpectations->get(filename);
|
||||||
|
if (jsExpectation.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkHashDigest checksum;
|
||||||
|
if (!SkBitmapHasher::ComputeDigest(bitmap, &checksum)) {
|
||||||
|
if (failureArray != NULL) {
|
||||||
|
failureArray->push_back().printf("decoded %s, but could not create a checksum.",
|
||||||
|
filename);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsExpectation.match(checksum)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failureArray != NULL) {
|
||||||
|
failureArray->push_back().printf("decoded %s, but the result does not match "
|
||||||
|
"expectations.",
|
||||||
|
filename);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) {
|
static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) {
|
||||||
SkBitmap bitmap;
|
SkBitmap bitmap;
|
||||||
SkFILEStream stream(srcPath);
|
SkFILEStream stream(srcPath);
|
||||||
|
@ -180,7 +261,15 @@ static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(), bitmap.height());
|
// Create a string representing just the filename itself, for use in json expectations.
|
||||||
|
const char* filename = SkBasename(srcPath);
|
||||||
|
|
||||||
|
if (compare_to_expectations_if_necessary(bitmap, filename, &gDecodeFailures)) {
|
||||||
|
gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(),
|
||||||
|
bitmap.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
write_expectations(bitmap, filename);
|
||||||
|
|
||||||
if (FLAGS_testSubsetDecoding) {
|
if (FLAGS_testSubsetDecoding) {
|
||||||
SkDEBUGCODE(bool couldRewind =) stream.rewind();
|
SkDEBUGCODE(bool couldRewind =) stream.rewind();
|
||||||
|
@ -199,8 +288,16 @@ static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
|
||||||
SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop,
|
SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop,
|
||||||
rect.fRight, rect.fBottom);
|
rect.fRight, rect.fBottom);
|
||||||
if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap::kNo_Config)) {
|
if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap::kNo_Config)) {
|
||||||
gSuccessfulSubsetDecodes.push_back().printf("Decoded subset %s from %s",
|
SkString subsetName = SkStringPrintf("%s_%s", filename, subsetDim.c_str());
|
||||||
subsetDim.c_str(), srcPath);
|
if (compare_to_expectations_if_necessary(bitmapFromDecodeSubset,
|
||||||
|
subsetName.c_str(),
|
||||||
|
&gFailedSubsetDecodes)) {
|
||||||
|
gSuccessfulSubsetDecodes.push_back().printf("Decoded subset %s from %s",
|
||||||
|
subsetDim.c_str(), srcPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_expectations(bitmapFromDecodeSubset, subsetName.c_str());
|
||||||
|
|
||||||
if (writePath != NULL) {
|
if (writePath != NULL) {
|
||||||
// Write the region to a file whose name includes the dimensions.
|
// Write the region to a file whose name includes the dimensions.
|
||||||
SkString suffix = SkStringPrintf("_%s.png", subsetDim.c_str());
|
SkString suffix = SkStringPrintf("_%s.png", subsetDim.c_str());
|
||||||
|
@ -322,6 +419,17 @@ static bool print_strings(const char* title, const SkTArray<SkString, false>& st
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If directory is non null and does not end with a path separator, append one.
|
||||||
|
* @param directory SkString representing the path to a directory. If the last character is not a
|
||||||
|
* path separator (specific to the current OS), append one.
|
||||||
|
*/
|
||||||
|
static void append_path_separator_if_necessary(SkString* directory) {
|
||||||
|
if (directory != NULL && directory->c_str()[directory->size() - 1] != SkPATH_SEPARATOR) {
|
||||||
|
directory->appendf("%c", SkPATH_SEPARATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int tool_main(int argc, char** argv);
|
int tool_main(int argc, char** argv);
|
||||||
int tool_main(int argc, char** argv) {
|
int tool_main(int argc, char** argv) {
|
||||||
SkCommandLineFlags::SetUsage("Decode files, and optionally write the results to files.");
|
SkCommandLineFlags::SetUsage("Decode files, and optionally write the results to files.");
|
||||||
|
@ -335,14 +443,17 @@ int tool_main(int argc, char** argv) {
|
||||||
|
|
||||||
SkAutoGraphics ag;
|
SkAutoGraphics ag;
|
||||||
|
|
||||||
|
if (!FLAGS_readExpectationsPath.isEmpty()) {
|
||||||
|
gJsonExpectations.reset(SkNEW_ARGS(skiagm::JsonExpectationsSource,
|
||||||
|
(FLAGS_readExpectationsPath[0])));
|
||||||
|
}
|
||||||
|
|
||||||
SkString outDir;
|
SkString outDir;
|
||||||
SkString* outDirPtr;
|
SkString* outDirPtr;
|
||||||
|
|
||||||
if (FLAGS_writePath.count() == 1) {
|
if (FLAGS_writePath.count() == 1) {
|
||||||
outDir.set(FLAGS_writePath[0]);
|
outDir.set(FLAGS_writePath[0]);
|
||||||
if (outDir.c_str()[outDir.size() - 1] != '/') {
|
append_path_separator_if_necessary(&outDir);
|
||||||
outDir.append("/");
|
|
||||||
}
|
|
||||||
outDirPtr = &outDir;
|
outDirPtr = &outDir;
|
||||||
} else {
|
} else {
|
||||||
outDirPtr = NULL;
|
outDirPtr = NULL;
|
||||||
|
@ -356,9 +467,7 @@ int tool_main(int argc, char** argv) {
|
||||||
SkString filename;
|
SkString filename;
|
||||||
if (iter.next(&filename)) {
|
if (iter.next(&filename)) {
|
||||||
SkString directory(FLAGS_readPath[i]);
|
SkString directory(FLAGS_readPath[i]);
|
||||||
if (directory[directory.size() - 1] != '/') {
|
append_path_separator_if_necessary(&directory);
|
||||||
directory.append("/");
|
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
SkString fullname(directory);
|
SkString fullname(directory);
|
||||||
fullname.append(filename);
|
fullname.append(filename);
|
||||||
|
@ -369,6 +478,18 @@ int tool_main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FLAGS_createExpectationsPath.isEmpty()) {
|
||||||
|
// Use an empty value for everything besides expectations, since the reader only cares
|
||||||
|
// about the expectations.
|
||||||
|
Json::Value nullValue;
|
||||||
|
Json::Value root = skiagm::CreateJsonTree(gExpectationsToWrite, nullValue, nullValue,
|
||||||
|
nullValue, nullValue);
|
||||||
|
std::string jsonStdString = root.toStyledString();
|
||||||
|
SkString path = SkStringPrintf("%s%cresults.json", FLAGS_createExpectationsPath[0],
|
||||||
|
SkPATH_SEPARATOR);
|
||||||
|
SkFILEWStream stream(path.c_str());
|
||||||
|
stream.write(jsonStdString.c_str(), jsonStdString.length());
|
||||||
|
}
|
||||||
// Add some space, since codecs may print warnings without newline.
|
// Add some space, since codecs may print warnings without newline.
|
||||||
SkDebugf("\n\n");
|
SkDebugf("\n\n");
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче