158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/* 258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2013 Google Inc. 358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * 458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file. 658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */ 758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr 1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string 1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_BUILD_FOR_MAC 1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// Note that some macs don't have this header and it can be downloaded from the Khronos registry 1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger# include <OpenCL/cl.hpp> 1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#else 1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger# include <CL/cl.hpp> 1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkCommandLineFlags.h" 2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkGraphics.h" 2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkStream.h" 2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTDArray.h" 2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkDifferentPixelsMetric.h" 2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkDiffContext.h" 2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkImageDiffer.h" 2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkPMetric.h" 3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "skpdiff_util.h" 3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkForceLinking.h" 3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger__SK_FORCE_IMAGE_DECODER_LINKING; 3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// Command line argument definitions go here 3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_bool2(list, l, false, "List out available differs"); 3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(differs, d, "", "The names of the differs to use or all of them by default"); 3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(folders, f, "", "Compare two folders with identical subfile names: <baseline folder> <test folder>"); 3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline> <test>"); 4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string2(output, o, "", "Writes the output of these diffs to output: <output>"); 41910f694aefb0b671dd8522a9afe9b6be645701c1Derek SollenbergerDEFINE_string(alphaDir, "", "Writes the alpha mask of these diffs to output: <output>"); 4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_bool(jsonp, true, "Output JSON with padding"); 4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_string(csv, "", "Writes the output of these diffs to a csv file"); 440a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEFINE_int32(threads, -1, "run N threads in parallel [default is derived from CPUs available]"); 4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/// A callback for any OpenCL errors 4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void CL_CALLBACK error_notify(const char* errorInfo, const void* privateInfoSize, ::size_t cb, void* userData) { 4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("OpenCL error notify: %s\n", errorInfo); 5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger exit(1); 5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/// Creates a device and context with OpenCL 5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool init_device_and_context(cl::Device* device, cl::Context* context) { 5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Query for a platform 5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::vector<cl::Platform> platformList; 5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Platform::get(&platformList); 5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("The number of platforms is %u\n", platformList.size()); 5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Print some information about the platform for debugging 6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Platform& platform = platformList[0]; 6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::STRING_CLASS platformName; 6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger platform.getInfo(CL_PLATFORM_NAME, &platformName); 6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Platform index 0 is named %s\n", platformName.c_str()); 6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Query for a device 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::vector<cl::Device> deviceList; 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger platform.getDevices(CL_DEVICE_TYPE_ALL, &deviceList); 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("The number of devices is %u\n", deviceList.size()); 7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Print some information about the device for debugging 7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *device = deviceList[0]; 7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::STRING_CLASS deviceName; 7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger device->getInfo(CL_DEVICE_NAME, &deviceName); 7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Device index 0 is named %s\n", deviceName.c_str()); 7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Create a CL context and check for all errors 7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl_int contextErr = CL_SUCCESS; 7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *context = cl::Context(deviceList, NULL, error_notify, NULL, &contextErr); 8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (contextErr != CL_SUCCESS) { 8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Context creation failed: %s\n", cl_error_to_string(contextErr)); 8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return false; 8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return true; 8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool init_cl_diff(SkImageDiffer* differ) { 8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup OpenCL 9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Device device; 9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger cl::Context context; 9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!init_device_and_context(&device, &context)) { 9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return false; 9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup our differ of choice 9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCLImageDiffer* clDiffer = (SkCLImageDiffer*)differ; 9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return clDiffer->init(device(), context()); 9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// TODO Find a better home for the diff registry. One possibility is to have the differs self 10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// register. 10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// List here every differ 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkDifferentPixelsMetric gDiffPixel; 10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPMetric gPDiff; 10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// A null terminated array of pointer to every differ declared above 11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkImageDiffer* gDiffers[] = { &gDiffPixel, &gPDiff, NULL }; 11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint tool_main(int argc, char * argv[]); 11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint tool_main(int argc, char * argv[]) { 11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Setup command line parsing 11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCommandLineFlags::SetUsage("Compare images using various metrics."); 11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkCommandLineFlags::Parse(argc, argv); 11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Needed by various Skia components 11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoGraphics ag; 12058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_list) { 12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Available Metrics:\n"); 12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Figure which differs the user chose, and optionally print them if the user requests it 12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkTDArray<SkImageDiffer*> chosenDiffers; 12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) { 12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkImageDiffer* differ = gDiffers[differIndex]; 12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_list) { 13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf(" %s", differ->getName()); 13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("\n"); 13258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 13358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 13458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Check if this differ was chosen by any of the flags. Initialize them if they were chosen. 13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_differs.isEmpty()) { 13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // If no differs were chosen, they all get added 13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (differ->requiresOpenCL()) { 13858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 13958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger init_cl_diff(differ); 14058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 14158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 14258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 14358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger for (int flagIndex = 0; flagIndex < FLAGS_differs.count(); flagIndex++) { 14758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (SkString(FLAGS_differs[flagIndex]).equals(differ->getName())) { 14858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Initialize OpenCL for the differ if it needs it and support was compiled in. 14958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (differ->requiresOpenCL()) { 15058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if SK_SUPPORT_OPENCL 15158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger init_cl_diff(differ); 15258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger chosenDiffers.push(differ); 15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger break; 15858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 16358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Don't attempt to initialize the differ if we aren't going to use it 16458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (FLAGS_folders.isEmpty() && FLAGS_patterns.isEmpty()) { 16558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 0; 16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 16858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Validate command line flags 16958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_folders.isEmpty()) { 17058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (2 != FLAGS_folders.count()) { 17158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Folders flag expects two arguments: <baseline folder> <test folder>\n"); 17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 17658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_patterns.isEmpty()) { 17758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (2 != FLAGS_patterns.count()) { 17858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("Patterns flag expects two arguments: <baseline pattern> <test pattern>\n"); 17958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 18058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 18358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_csv.isEmpty()) { 18458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (1 != FLAGS_csv.count()) { 18558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDebugf("csv flag expects one argument: <csv file>\n"); 18658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 1; 18758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 18958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 190910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (!FLAGS_alphaDir.isEmpty()) { 191910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (1 != FLAGS_alphaDir.count()) { 192910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger SkDebugf("alphaDir flag expects one argument: <directory>\n"); 193910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger return 1; 194910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger } 195910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger } 196910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 19758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkDiffContext ctx; 19858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.setDiffers(chosenDiffers); 19958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 200910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger if (!FLAGS_alphaDir.isEmpty()) { 201910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger ctx.setDifferenceDir(SkString(FLAGS_alphaDir[0])); 202910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger } 203910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 2040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (FLAGS_threads >= 0) { 2050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ctx.setThreadCount(FLAGS_threads); 2060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 2070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 20858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Perform a folder diff if one is requested 20958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_folders.isEmpty()) { 21058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.diffDirectories(FLAGS_folders[0], FLAGS_folders[1]); 21158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 21258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 21358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Perform a pattern diff if one is requested 21458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_patterns.isEmpty()) { 21558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.diffPatterns(FLAGS_patterns[0], FLAGS_patterns[1]); 21658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 21758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 21858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Output to the file specified 21958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_output.isEmpty()) { 22058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkFILEWStream outputStream(FLAGS_output[0]); 22158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.outputRecords(outputStream, FLAGS_jsonp); 22258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 22358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 22458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!FLAGS_csv.isEmpty()) { 22558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkFILEWStream outputStream(FLAGS_csv[0]); 22658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ctx.outputCsv(outputStream); 22758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 22858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 22958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 0; 23058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 23158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 23258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 23358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerint main(int argc, char * argv[]) { 23458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return tool_main(argc, (char**) argv); 23558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 23658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif 237