OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
| 8 #if SK_SUPPORT_OPENCL |
8 #define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr | 9 #define __NO_STD_VECTOR // Uses cl::vectpr instead of std::vectpr |
9 #define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string | 10 #define __NO_STD_STRING // Uses cl::STRING_CLASS instead of std::string |
10 #include <CL/cl.hpp> | 11 #include <CL/cl.hpp> |
| 12 #endif |
11 | 13 |
12 #include "SkCommandLineFlags.h" | 14 #include "SkCommandLineFlags.h" |
13 #include "SkGraphics.h" | 15 #include "SkGraphics.h" |
14 #include "SkStream.h" | 16 #include "SkStream.h" |
15 #include "SkTDArray.h" | 17 #include "SkTDArray.h" |
16 | 18 |
17 #include "SkCLImageDiffer.h" | 19 #include "SkDifferentPixelsMetric.h" |
18 #include "SkDiffContext.h" | 20 #include "SkDiffContext.h" |
19 #include "SkImageDiffer.h" | 21 #include "SkImageDiffer.h" |
20 #include "SkPMetric.h" | 22 #include "SkPMetric.h" |
21 #include "skpdiff_util.h" | 23 #include "skpdiff_util.h" |
22 | 24 |
23 #include "SkForceLinking.h" | 25 #include "SkForceLinking.h" |
24 __SK_FORCE_IMAGE_DECODER_LINKING; | 26 __SK_FORCE_IMAGE_DECODER_LINKING; |
25 | 27 |
26 // Command line argument definitions go here | 28 // Command line argument definitions go here |
27 DEFINE_bool2(list, l, false, "List out available differs"); | 29 DEFINE_bool2(list, l, false, "List out available differs"); |
28 DEFINE_string2(differs, d, "", "The names of the differs to use or all of them b
y default"); | 30 DEFINE_string2(differs, d, "", "The names of the differs to use or all of them b
y default"); |
29 DEFINE_string2(folders, f, "", "Compare two folders with identical subfile names
: <baseline folder> <test folder>"); | 31 DEFINE_string2(folders, f, "", "Compare two folders with identical subfile names
: <baseline folder> <test folder>"); |
30 DEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline>
<test>"); | 32 DEFINE_string2(patterns, p, "", "Use two patterns to compare images: <baseline>
<test>"); |
31 DEFINE_string2(output, o, "skpdiff_output.json", "Writes the output of these dif
fs to output: <output>"); | 33 DEFINE_string2(output, o, "skpdiff_output.json", "Writes the output of these dif
fs to output: <output>"); |
32 DEFINE_bool(jsonp, true, "Output JSON with padding"); | 34 DEFINE_bool(jsonp, true, "Output JSON with padding"); |
33 | 35 |
| 36 #if SK_SUPPORT_OPENCL |
34 /// A callback for any OpenCL errors | 37 /// A callback for any OpenCL errors |
35 CL_CALLBACK void error_notify(const char* errorInfo, const void* privateInfoSize
, ::size_t cb, void* userData) { | 38 CL_CALLBACK void error_notify(const char* errorInfo, const void* privateInfoSize
, ::size_t cb, void* userData) { |
36 SkDebugf("OpenCL error notify: %s\n", errorInfo); | 39 SkDebugf("OpenCL error notify: %s\n", errorInfo); |
37 exit(1); | 40 exit(1); |
38 } | 41 } |
39 | 42 |
40 /// Creates a device and context with OpenCL | 43 /// Creates a device and context with OpenCL |
41 static bool init_device_and_context(cl::Device* device, cl::Context* context) { | 44 static bool init_device_and_context(cl::Device* device, cl::Context* context) { |
42 // Query for a platform | 45 // Query for a platform |
43 cl::vector<cl::Platform> platformList; | 46 cl::vector<cl::Platform> platformList; |
(...skipping 21 matching lines...) Expand all Loading... |
65 cl_int contextErr = CL_SUCCESS; | 68 cl_int contextErr = CL_SUCCESS; |
66 *context = cl::Context(deviceList, NULL, error_notify, NULL, &contextErr); | 69 *context = cl::Context(deviceList, NULL, error_notify, NULL, &contextErr); |
67 if (contextErr != CL_SUCCESS) { | 70 if (contextErr != CL_SUCCESS) { |
68 SkDebugf("Context creation failed: %s\n", cl_error_to_string(contextErr)
); | 71 SkDebugf("Context creation failed: %s\n", cl_error_to_string(contextErr)
); |
69 return false; | 72 return false; |
70 } | 73 } |
71 | 74 |
72 return true; | 75 return true; |
73 } | 76 } |
74 | 77 |
75 | |
76 | |
77 static bool init_cl_diff(SkImageDiffer* differ) { | 78 static bool init_cl_diff(SkImageDiffer* differ) { |
78 // Setup OpenCL | 79 // Setup OpenCL |
79 cl::Device device; | 80 cl::Device device; |
80 cl::Context context; | 81 cl::Context context; |
81 if (!init_device_and_context(&device, &context)) { | 82 if (!init_device_and_context(&device, &context)) { |
82 return false; | 83 return false; |
83 } | 84 } |
84 | 85 |
85 // Setup our differ of choice | 86 // Setup our differ of choice |
86 SkCLImageDiffer* clDiffer = (SkCLImageDiffer*)differ; | 87 SkCLImageDiffer* clDiffer = (SkCLImageDiffer*)differ; |
87 return clDiffer->init(device(), context()); | 88 return clDiffer->init(device(), context()); |
88 } | 89 } |
89 | 90 #endif |
90 static bool init_dummy(SkImageDiffer* differ) { | |
91 return true; | |
92 } | |
93 | |
94 | 91 |
95 // TODO Find a better home for the diff registry. One possibility is to have the
differs self | 92 // TODO Find a better home for the diff registry. One possibility is to have the
differs self |
96 // register. | 93 // register. |
97 | 94 |
98 // List here every differ | 95 // List here every differ |
99 SkDifferentPixelsImageDiffer gDiffPixel; | 96 SkDifferentPixelsMetric gDiffPixel; |
100 SkPMetric gPDiff; | 97 SkPMetric gPDiff; |
101 | 98 |
102 // A null terminated array of pointer to every differ declared above | 99 // A null terminated array of pointer to every differ declared above |
103 SkImageDiffer* gDiffers[] = { &gDiffPixel, &gPDiff, NULL }; | 100 SkImageDiffer* gDiffers[] = { &gDiffPixel, &gPDiff, NULL }; |
104 | 101 |
105 // A parallel array of functions to initialize the above differs. The reason we
don't initialize | |
106 // everything immediately is that certain differs may require special initializa
tion, but we still | |
107 // want to construct all of them globally so they can be queried for things like
their name and | |
108 // description. | |
109 bool (*gDiffInits[])(SkImageDiffer*) = { init_cl_diff, init_dummy, NULL }; | |
110 | |
111 | |
112 int main(int argc, char** argv) { | 102 int main(int argc, char** argv) { |
113 // Setup command line parsing | 103 // Setup command line parsing |
114 SkCommandLineFlags::SetUsage("Compare images using various metrics."); | 104 SkCommandLineFlags::SetUsage("Compare images using various metrics."); |
115 SkCommandLineFlags::Parse(argc, argv); | 105 SkCommandLineFlags::Parse(argc, argv); |
116 | 106 |
117 // Needed by various Skia components | 107 // Needed by various Skia components |
118 SkAutoGraphics ag; | 108 SkAutoGraphics ag; |
119 | 109 |
120 if (FLAGS_list) { | 110 if (FLAGS_list) { |
121 SkDebugf("Available Metrics:\n"); | 111 SkDebugf("Available Metrics:\n"); |
122 } | 112 } |
123 | 113 |
124 // Figure which differs the user chose, and optionally print them if the use
r requests it | 114 // Figure which differs the user chose, and optionally print them if the use
r requests it |
125 SkTDArray<SkImageDiffer*> chosenDiffers; | 115 SkTDArray<SkImageDiffer*> chosenDiffers; |
126 for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) { | 116 for (int differIndex = 0; NULL != gDiffers[differIndex]; differIndex++) { |
127 SkImageDiffer* differ = gDiffers[differIndex]; | 117 SkImageDiffer* differ = gDiffers[differIndex]; |
128 if (FLAGS_list) { | 118 if (FLAGS_list) { |
129 SkDebugf(" %s", differ->getName()); | 119 SkDebugf(" %s", differ->getName()); |
130 SkDebugf("\n"); | 120 SkDebugf("\n"); |
131 } | 121 } |
132 | 122 |
133 // Check if this differ was chosen by any of the flags. Initialize them
if they were chosen. | 123 // Check if this differ was chosen by any of the flags. Initialize them
if they were chosen. |
134 if (FLAGS_differs.isEmpty()) { | 124 if (FLAGS_differs.isEmpty()) { |
135 // If no differs were chosen, they all get added | 125 // If no differs were chosen, they all get added |
136 chosenDiffers.push(differ); | 126 if (differ->requiresOpenCL()) { |
137 gDiffInits[differIndex](differ); | 127 #if SK_SUPPORT_OPENCL |
| 128 init_cl_diff(differ); |
| 129 chosenDiffers.push(differ); |
| 130 #endif |
| 131 } else { |
| 132 chosenDiffers.push(differ); |
| 133 } |
138 } else { | 134 } else { |
139 for (int flagIndex = 0; flagIndex < FLAGS_differs.count(); flagIndex
++) { | 135 for (int flagIndex = 0; flagIndex < FLAGS_differs.count(); flagIndex
++) { |
140 if (SkString(FLAGS_differs[flagIndex]).equals(differ->getName())
) { | 136 if (SkString(FLAGS_differs[flagIndex]).equals(differ->getName())
) { |
141 chosenDiffers.push(differ); | 137 // Initialize OpenCL for the differ if it needs it and suppo
rt was compiled in. |
142 gDiffInits[differIndex](differ); | 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 } |
143 break; | 146 break; |
144 } | 147 } |
145 } | 148 } |
146 } | 149 } |
147 } | 150 } |
148 | 151 |
149 // Don't attempt to initialize the differ if we aren't going to use it | 152 // Don't attempt to initialize the differ if we aren't going to use it |
150 if (FLAGS_folders.isEmpty() && FLAGS_patterns.isEmpty()) { | 153 if (FLAGS_folders.isEmpty() && FLAGS_patterns.isEmpty()) { |
151 return 0; | 154 return 0; |
152 } | 155 } |
(...skipping 27 matching lines...) Expand all Loading... |
180 } | 183 } |
181 | 184 |
182 // Output to the file specified | 185 // Output to the file specified |
183 if (!FLAGS_output.isEmpty()) { | 186 if (!FLAGS_output.isEmpty()) { |
184 SkFILEWStream outputStream(FLAGS_output[0]); | 187 SkFILEWStream outputStream(FLAGS_output[0]); |
185 ctx.outputRecords(outputStream, FLAGS_jsonp); | 188 ctx.outputRecords(outputStream, FLAGS_jsonp); |
186 } | 189 } |
187 | 190 |
188 return 0; | 191 return 0; |
189 } | 192 } |
OLD | NEW |