OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2013 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #if SK_SUPPORT_OPENCL | |
9 #define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr | |
10 #define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string | |
11 #include <CL/cl.hpp> | |
12 #endif | |
13 | |
14 #include "SkCommandLineFlags.h" | |
15 #include "SkGraphics.h" | |
16 #include "SkStream.h" | |
17 #include "SkTDArray.h" | |
18 | |
19 #include "SkDifferentPixelsMetric.h" | |
20 #include "SkDiffContext.h" | |
21 #include "SkImageDiffer.h" | |
22 #include "SkPMetric.h" | |
23 #include "skpdiff_util.h" | |
24 | |
25 #include "SkForceLinking.h" | |
26 __SK_FORCE_IMAGE_DECODER_LINKING; | |
27 | |
28 // Command line argument definitions go here | |
29 DEFINE_bool2(list, l, false, "List out available differs"); | |
30 DEFINE_string2(differs, d, "", "The names of the differs to use or all of them b
y default"); | |
31 DEFINE_string2(folders, f, "", "Compare two folders with identical subfile names
: <baseline folder> <test folder>"); | |
32 DEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline>
<test>"); | |
33 DEFINE_string2(output, o, "skpdiff_output.json", "Writes the output of these dif
fs to output: <output>"); | |
34 DEFINE_bool(jsonp, true, "Output JSON with padding"); | |
35 | |
36 #if SK_SUPPORT_OPENCL | |
37 /// A callback for any OpenCL errors | |
38 CL_CALLBACK void error_notify(const char* errorInfo, const void* privateInfoSize
, ::size_t cb, void* userData) { | |
39 SkDebugf("OpenCL error notify: %s\n", errorInfo); | |
40 exit(1); | |
41 } | |
42 | |
43 /// Creates a device and context with OpenCL | |
44 static bool init_device_and_context(cl::Device* device, cl::Context* context) { | |
45 // Query for a platform | |
46 cl::vector<cl::Platform> platformList; | |
47 cl::Platform::get(&platformList); | |
48 SkDebugf("The number of platforms is %u\n", platformList.size()); | |
49 | |
50 // Print some information about the platform for debugging | |
51 cl::Platform& platform = platformList[0]; | |
52 cl::STRING_CLASS platformName; | |
53 platform.getInfo(CL_PLATFORM_NAME, &platformName); | |
54 SkDebugf("Platform index 0 is named %s\n", platformName.c_str()); | |
55 | |
56 // Query for a device | |
57 cl::vector<cl::Device> deviceList; | |
58 platform.getDevices(CL_DEVICE_TYPE_GPU, &deviceList); | |
59 SkDebugf("The number of GPU devices is %u\n", deviceList.size()); | |
60 | |
61 // Print some information about the device for debugging | |
62 *device = deviceList[0]; | |
63 cl::STRING_CLASS deviceName; | |
64 device->getInfo(CL_DEVICE_NAME, &deviceName); | |
65 SkDebugf("Device index 0 is named %s\n", deviceName.c_str()); | |
66 | |
67 // Create a CL context and check for all errors | |
68 cl_int contextErr = CL_SUCCESS; | |
69 *context = cl::Context(deviceList, NULL, error_notify, NULL, &contextErr); | |
70 if (contextErr != CL_SUCCESS) { | |
71 SkDebugf("Context creation failed: %s\n", cl_error_to_string(contextErr)
); | |
72 return false; | |
73 } | |
74 | |
75 return true; | |
76 } | |
77 | |
78 static bool init_cl_diff(SkImageDiffer* differ) { | |
79 // Setup OpenCL | |
80 cl::Device device; | |
81 cl::Context context; | |
82 if (!init_device_and_context(&device, &context)) { | |
83 return false; | |
84 } | |
85 | |
86 // Setup our differ of choice | |
87 SkCLImageDiffer* clDiffer = (SkCLImageDiffer*)differ; | |
88 return clDiffer->init(device(), context()); | |
89 } | |
90 #endif | |
91 | |
92 // TODO Find a better home for the diff registry. One possibility is to have the
differs self | |
93 // register. | |
94 | |
95 // List here every differ | |
96 SkDifferentPixelsMetric gDiffPixel; | |
97 SkPMetric gPDiff; | |
98 | |
99 // A null terminated array of pointer to every differ declared above | |
100 SkImageDiffer* gDiffers[] = { &gDiffPixel, &gPDiff, NULL }; | |
101 | |
102 int main(int argc, char** argv) { | |
103 // Setup command line parsing | |
104 SkCommandLineFlags::SetUsage("Compare images using various metrics."); | |
105 SkCommandLineFlags::Parse(argc, argv); | |
106 | |
107 // Needed by various Skia components | |
108 SkAutoGraphics ag; | |
109 | |
110 if (FLAGS_list) { | |
111 SkDebugf("Available Metrics:\n"); | |
112 } | |
113 | |
114 // Figure which differs the user chose, and optionally print them if the use
r requests it | |
115 SkTDArray<SkImageDiffer*> chosenDiffers; | |
116 for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) { | |
117 SkImageDiffer* differ = gDiffers[differIndex]; | |
118 if (FLAGS_list) { | |
119 SkDebugf(" %s", differ->getName()); | |
120 SkDebugf("\n"); | |
121 } | |
122 | |
123 // Check if this differ was chosen by any of the flags. Initialize them
if they were chosen. | |
124 if (FLAGS_differs.isEmpty()) { | |
125 // If no differs were chosen, they all get added | |
126 if (differ->requiresOpenCL()) { | |
127 #if SK_SUPPORT_OPENCL | |
128 init_cl_diff(differ); | |
129 chosenDiffers.push(differ); | |
130 #endif | |
131 } else { | |
132 chosenDiffers.push(differ); | |
133 } | |
134 } else { | |
135 for (int flagIndex = 0; flagIndex < FLAGS_differs.count(); flagIndex
++) { | |
136 if (SkString(FLAGS_differs[flagIndex]).equals(differ->getName())
) { | |
137 // Initialize OpenCL for the differ if it needs it and suppo
rt was compiled in. | |
138 if (differ->requiresOpenCL()) { | |
139 #if SK_SUPPORT_OPENCL | |
140 init_cl_diff(differ); | |
141 chosenDiffers.push(differ); | |
142 #endif | |
143 } else { | |
144 chosenDiffers.push(differ); | |
145 } | |
146 break; | |
147 } | |
148 } | |
149 } | |
150 } | |
151 | |
152 // Don't attempt to initialize the differ if we aren't going to use it | |
153 if (FLAGS_folders.isEmpty() && FLAGS_patterns.isEmpty()) { | |
154 return 0; | |
155 } | |
156 | |
157 // Validate command line flags | |
158 if (!FLAGS_folders.isEmpty()) { | |
159 if (2 != FLAGS_folders.count()) { | |
160 SkDebugf("Folders flag expects two arguments: <baseline folder> <tes
t folder>\n"); | |
161 return 1; | |
162 } | |
163 } | |
164 | |
165 if (!FLAGS_patterns.isEmpty()) { | |
166 if (2 != FLAGS_patterns.count()) { | |
167 SkDebugf("Patterns flag expects two arguments: <baseline pattern> <t
est pattern>\n"); | |
168 return 1; | |
169 } | |
170 } | |
171 | |
172 SkDiffContext ctx; | |
173 ctx.setDiffers(chosenDiffers); | |
174 | |
175 // Perform a folder diff if one is requested | |
176 if (!FLAGS_folders.isEmpty()) { | |
177 ctx.diffDirectories(FLAGS_folders[0], FLAGS_folders[1]); | |
178 } | |
179 | |
180 // Perform a pattern diff if one is requested | |
181 if (!FLAGS_patterns.isEmpty()) { | |
182 ctx.diffPatterns(FLAGS_patterns[0], FLAGS_patterns[1]); | |
183 } | |
184 | |
185 // Output to the file specified | |
186 if (!FLAGS_output.isEmpty()) { | |
187 SkFILEWStream outputStream(FLAGS_output[0]); | |
188 ctx.outputRecords(outputStream, FLAGS_jsonp); | |
189 } | |
190 | |
191 return 0; | |
192 } | |
OLD | NEW |