Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: third_party/WebKit/Source/web/ImageDecodeBench.cpp

Issue 1954673002: Make ImageDecodeBench build again (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move ImageDecodeBench.cpp to platform/testing. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Provides a minimal wrapping of the Blink image decoders. Used to perform
6 // a non-threaded, memory-to-memory image decode using micro second accuracy
7 // clocks to measure image decode time. Optionally applies color correction
8 // during image decoding on supported platforms (default off). Usage:
9 //
10 // % ninja -C /out/Release image_decode_bench &&
11 // ./out/Release/image_decode_bench file [iterations]
12 //
13 // TODO(noel): Consider adding md5 checksum support to WTF. Use it to compute
14 // the decoded image frame md5 and output that value.
15 //
16 // TODO(noel): Consider integrating this tool in Chrome telemetry for realz,
17 // using the image corpii used to assess Blink image decode performance. Refer
18 // to http://crbug.com/398235#c103 and http://crbug.com/258324#c5
19
20 #include "platform/SharedBuffer.h"
21 #include "platform/image-decoders/ImageDecoder.h"
22 #include "platform/testing/TestingPlatformSupport.h"
23 #include "public/platform/Platform.h"
24 #include "public/web/WebKit.h"
25 #include "wtf/OwnPtr.h"
26 #include "wtf/PassRefPtr.h"
27
28 #if defined(_WIN32)
29 #if defined(WIN32_LEAN_AND_MEAN)
30 #error Fix: WIN32_LEAN_AND_MEAN disables timeBeginPeriod/TimeEndPeriod.
31 #endif
32 #include <mmsystem.h>
33 #include <sys/stat.h>
34 #include <time.h>
35 #define stat(x,y) _stat(x,y)
36 typedef struct _stat sttype;
37 #else
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 typedef struct stat sttype;
41 #endif
42
43 using namespace blink;
44
45 #if defined(_WIN32)
46
47 // There is no real platform support herein, so adopt the WIN32 performance coun ter from
48 // WTF http://trac.webkit.org/browser/trunk/Source/WTF/wtf/CurrentTime.cpp?rev=1 52438
49
50 static double lowResUTCTime()
51 {
52 FILETIME fileTime;
53 GetSystemTimeAsFileTime(&fileTime);
54
55 // As per Windows documentation for FILETIME, copy the resulting FILETIME st ructure to a
56 // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct ass ignment can
57 // prevent alignment faults on 64-bit Windows).
58 ULARGE_INTEGER dateTime;
59 memcpy(&dateTime, &fileTime, sizeof(dateTime));
60
61 // Number of 100 nanosecond between January 1, 1601 and January 1, 1970.
62 static const ULONGLONG epochBias = 116444736000000000ULL;
63 // Windows file times are in 100s of nanoseconds.
64 static const double hundredsOfNanosecondsPerMillisecond = 10000;
65 return (dateTime.QuadPart - epochBias) / hundredsOfNanosecondsPerMillisecond ;
66 }
67
68 static LARGE_INTEGER qpcFrequency;
69 static bool syncedTime;
70
71 static double highResUpTime()
72 {
73 // We use QPC, but only after sanity checking its result, due to bugs:
74 // http://support.microsoft.com/kb/274323 http://support.microsoft.com/kb/89 5980
75 // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("you can get diffe rent results
76 // on different processors due to bugs in the basic input/output system (BIO S) or the
77 // hardware abstraction layer (HAL).").
78
79 static LARGE_INTEGER qpcLast;
80 static DWORD tickCountLast;
81 static bool inited;
82
83 LARGE_INTEGER qpc;
84 QueryPerformanceCounter(&qpc);
85 DWORD tickCount = GetTickCount();
86
87 if (inited) {
88 __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFre quency.QuadPart;
89 __int64 tickCountElapsed;
90 if (tickCount >= tickCountLast) {
91 tickCountElapsed = (tickCount - tickCountLast);
92 } else {
93 __int64 tickCountLarge = tickCount + 0x100000000I64;
94 tickCountElapsed = tickCountLarge - tickCountLast;
95 }
96
97 // Force a re-sync if QueryPerformanceCounter differs from GetTickCount( ) by more than
98 // 500ms. (The 500ms value is from http://support.microsoft.com/kb/27432 3).
99 __int64 diff = tickCountElapsed - qpcElapsed;
100 if (diff > 500 || diff < -500)
101 syncedTime = false;
102 } else {
103 inited = true;
104 }
105
106 qpcLast = qpc;
107 tickCountLast = tickCount;
108
109 return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);
110 }
111
112 static bool qpcAvailable()
113 {
114 static bool available;
115 static bool checked;
116
117 if (checked)
118 return available;
119
120 available = QueryPerformanceFrequency(&qpcFrequency);
121 checked = true;
122 return available;
123 }
124
125 static double getCurrentTime()
126 {
127 // Use a combination of ftime and QueryPerformanceCounter.
128 // ftime returns the information we want, but doesn't have sufficient resolu tion.
129 // QueryPerformanceCounter has high resolution, but is only usable to measur e time intervals.
130 // To combine them, we call ftime and QueryPerformanceCounter initially. Lat er calls will
131 // use QueryPerformanceCounter by itself, adding the delta to the saved ftim e.
132 // We periodically re-sync to correct for drift.
133 static double syncLowResUTCTime;
134 static double syncHighResUpTime;
135 static double lastUTCTime;
136
137 double lowResTime = lowResUTCTime();
138 if (!qpcAvailable())
139 return lowResTime * (1.0 / 1000.0);
140
141 double highResTime = highResUpTime();
142 if (!syncedTime) {
143 timeBeginPeriod(1); // increase time resolution around low-res time gett er
144 syncLowResUTCTime = lowResTime = lowResUTCTime();
145 timeEndPeriod(1); // restore time resolution
146 syncHighResUpTime = highResTime;
147 syncedTime = true;
148 }
149
150 double highResElapsed = highResTime - syncHighResUpTime;
151 double utc = syncLowResUTCTime + highResElapsed;
152
153 // Force a clock re-sync if we've drifted.
154 double lowResElapsed = lowResTime - syncLowResUTCTime;
155 const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-r es accuracy
156 if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec)
157 syncedTime = false;
158
159 // Make sure time doesn't run backwards (only correct if the difference is < 2 seconds,
160 // since DST or clock changes could occur).
161 const double backwardTimeLimit = 2000.0;
162 if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit)
163 return lastUTCTime * (1.0 / 1000.0);
164
165 lastUTCTime = utc;
166 return utc * (1.0 / 1000.0);
167 }
168
169 #else
170
171 static double getCurrentTime()
172 {
173 struct timeval now;
174 gettimeofday(&now, 0);
175 return now.tv_sec + now.tv_usec * (1.0 / 1000000.0);
176 }
177
178 #endif
179
180 void getScreenColorProfile(WebVector<char>* profile)
181 {
182 static unsigned char profileData[] = {
183 0x00,0x00,0x01,0xea,0x54,0x45,0x53,0x54,0x00,0x00,0x00,0x00,
184 0x6d,0x6e,0x74,0x72,0x52,0x47,0x42,0x20,0x58,0x59,0x5a,0x20,
185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
186 0x61,0x63,0x73,0x70,0x74,0x65,0x73,0x74,0x00,0x00,0x00,0x00,
187 0x74,0x65,0x73,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0xd6,
189 0x00,0x01,0x00,0x00,0x00,0x00,0xd3,0x2d,0x74,0x65,0x73,0x74,
190 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
191 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
192 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
193 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,
194 0x63,0x70,0x72,0x74,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x0d,
195 0x64,0x65,0x73,0x63,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x8c,
196 0x77,0x74,0x70,0x74,0x00,0x00,0x01,0x8c,0x00,0x00,0x00,0x14,
197 0x72,0x58,0x59,0x5a,0x00,0x00,0x01,0xa0,0x00,0x00,0x00,0x14,
198 0x67,0x58,0x59,0x5a,0x00,0x00,0x01,0xb4,0x00,0x00,0x00,0x14,
199 0x62,0x58,0x59,0x5a,0x00,0x00,0x01,0xc8,0x00,0x00,0x00,0x14,
200 0x72,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
201 0x67,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
202 0x62,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
203 0x74,0x65,0x78,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
204 0x00,0x00,0x00,0x00,0x64,0x65,0x73,0x63,0x00,0x00,0x00,0x00,
205 0x00,0x00,0x00,0x10,0x77,0x68,0x61,0x63,0x6b,0x65,0x64,0x2e,
206 0x69,0x63,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
207 0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
208 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
209 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
211 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
212 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
213 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
214 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
215 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
216 0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xf3,0x52,
217 0x00,0x01,0x00,0x00,0x00,0x01,0x16,0xcc,0x58,0x59,0x5a,0x20,
218 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x8d,0x00,0x00,0xa0,0x2c,
219 0x00,0x00,0x0f,0x95,0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,
220 0x00,0x00,0x26,0x31,0x00,0x00,0x10,0x2f,0x00,0x00,0xbe,0x9b,
221 0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x18,
222 0x00,0x00,0x4f,0xa5,0x00,0x00,0x04,0xfc,0x63,0x75,0x72,0x76,
223 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x33
224 };
225
226 static struct WhackedColorProfile {
227
228 char* data() { return reinterpret_cast<char*>(profileData); }
229
230 const size_t profileSize = 490u;
231
232 size_t size() { return profileSize; }
233
234 } screenProfile;
235
236 profile->assign(screenProfile.data(), screenProfile.size());
237 }
238
239 PassRefPtr<SharedBuffer> readFile(const char* fileName)
240 {
241 FILE* fp = fopen(fileName, "rb");
242 if (!fp) {
243 fprintf(stderr, "Can't open file %s\n", fileName);
244 exit(2);
245 }
246
247 sttype s;
248 stat(fileName, &s);
249 size_t fileSize = s.st_size;
250 if (s.st_size <= 0)
251 return SharedBuffer::create();
252
253 OwnPtr<unsigned char[]> buffer = adoptArrayPtr(new unsigned char[fileSize]);
254 if (fileSize != fread(buffer.get(), 1, fileSize, fp)) {
255 fprintf(stderr, "Error reading file %s\n", fileName);
256 exit(2);
257 }
258
259 fclose(fp);
260 return SharedBuffer::create(buffer.get(), fileSize);
261 }
262
263 bool decodeImageData(SharedBuffer* data, bool colorCorrection, size_t packetSize )
264 {
265 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data,
266 ImageDecoder::AlphaPremultiplied, colorCorrection ?
267 ImageDecoder::GammaAndColorProfileApplied : ImageDecoder::GammaAndCo lorProfileIgnored);
268
269 if (!packetSize) {
270 bool allDataReceived = true;
271 decoder->setData(data, allDataReceived);
272
273 int frameCount = decoder->frameCount();
274 for (int i = 0; i < frameCount; ++i) {
275 if (!decoder->frameBufferAtIndex(i))
276 return false;
277 }
278
279 return !decoder->failed();
280 }
281
282 RefPtr<SharedBuffer> packetData = SharedBuffer::create();
283 unsigned position = 0;
284 while (true) {
285 const char* packet;
286 unsigned length = data->getSomeData(packet, position);
287
288 length = std::min(static_cast<size_t>(length), packetSize);
289 packetData->append(packet, length);
290 position += length;
291
292 bool allDataReceived = position == data->size();
293 decoder->setData(packetData.get(), allDataReceived);
294
295 int frameCount = decoder->frameCount();
296 for (int i = 0; i < frameCount; ++i) {
297 if (!decoder->frameBufferAtIndex(i))
298 break;
299 }
300
301 if (allDataReceived || decoder->failed())
302 break;
303 }
304
305 return !decoder->failed();
306 }
307
308 int main(int argc, char* argv[])
309 {
310 char* name = argv[0];
311
312 // If the platform supports color correction, allow it to be controlled.
313
314 bool applyColorCorrection = false;
315
316 #if USE(QCMSLIB)
317 if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0)
318 applyColorCorrection = (--argc, ++argv, true);
319
320 if (argc < 2) {
321 fprintf(stderr, "Usage: %s [--color-correct] file [iterations] [packetSi ze]\n", name);
322 exit(1);
323 }
324 #else
325 if (argc < 2) {
326 fprintf(stderr, "Usage: %s file [iterations] [packetSize]\n", name);
327 exit(1);
328 }
329 #endif
330
331 // Control decode bench iterations and packet size.
332
333 size_t iterations = 1;
334 if (argc >= 3) {
335 char* end = 0;
336 iterations = strtol(argv[2], &end, 10);
337 if (*end != '\0' || !iterations) {
338 fprintf(stderr, "Second argument should be number of iterations. "
339 "The default is 1. You supplied %s\n", argv[2]);
340 exit(1);
341 }
342 }
343
344 size_t packetSize = 0;
345 if (argc >= 4) {
346 char* end = 0;
347 packetSize = strtol(argv[3], &end, 10);
348 if (*end != '\0') {
349 fprintf(stderr, "Third argument should be packet size. Default is "
350 "0, meaning to decode the entire image in one packet. You "
351 "supplied %s\n", argv[3]);
352 exit(1);
353 }
354 }
355
356 // Create a web platform without V8.
357
358 class WebPlatform : public TestingPlatformSupport {
359 public:
360 void screenColorProfile(WebVector<char>* profile) override
361 {
362 getScreenColorProfile(profile); // Returns a whacked color profile.
363 }
364 };
365
366 Platform::initialize(new WebPlatform());
367
368 // Set image decoding Platform options.
369
370 #if USE(QCMSLIB)
371 ImageDecoder::qcmsOutputDeviceProfile(); // Initialize screen colorProfile.
372 #endif
373
374 // Read entire file content to data.
375
376 RefPtr<SharedBuffer> data = readFile(argv[1]);
377 if (!data.get() || !data->size()) {
378 fprintf(stderr, "Error reading image data from [%s]\n", argv[1]);
379 exit(2);
380 }
381
382 // Consolidate the SharedBuffer data segments into one, contiguous block of memory.
383 data->data();
384
385 // Image decode bench for iterations.
386
387 double totalTime = 0.0;
388
389 for (size_t i = 0; i < iterations; ++i) {
390 double startTime = getCurrentTime();
391 bool decoded = decodeImageData(data.get(), applyColorCorrection, packetS ize);
392 double elapsedTime = getCurrentTime() - startTime;
393 totalTime += elapsedTime;
394 if (!decoded) {
395 fprintf(stderr, "Image decode failed [%s]\n", argv[1]);
396 exit(3);
397 }
398 }
399
400 // Results to stdout.
401
402 double averageTime = totalTime / static_cast<double>(iterations);
403 printf("%f %f\n", totalTime, averageTime);
404 return 0;
405 }
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp ('k') | third_party/WebKit/Source/web/web.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698