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

Side by Side Diff: third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp

Issue 2039673002: Track performance of toBlob and its complete timeout delay (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change to thread safe static local histogram Created 4 years, 6 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/html/canvas/CanvasAsyncBlobCreator.h" 5 #include "core/html/canvas/CanvasAsyncBlobCreator.h"
6 6
7 #include "core/fileapi/Blob.h" 7 #include "core/fileapi/Blob.h"
8 #include "platform/Histogram.h"
8 #include "platform/ThreadSafeFunctional.h" 9 #include "platform/ThreadSafeFunctional.h"
9 #include "platform/graphics/ImageBuffer.h" 10 #include "platform/graphics/ImageBuffer.h"
10 #include "platform/image-encoders/JPEGImageEncoder.h" 11 #include "platform/image-encoders/JPEGImageEncoder.h"
11 #include "platform/image-encoders/PNGImageEncoder.h" 12 #include "platform/image-encoders/PNGImageEncoder.h"
12 #include "platform/threading/BackgroundTaskRunner.h" 13 #include "platform/threading/BackgroundTaskRunner.h"
13 #include "public/platform/Platform.h" 14 #include "public/platform/Platform.h"
14 #include "public/platform/WebScheduler.h" 15 #include "public/platform/WebScheduler.h"
15 #include "public/platform/WebTaskRunner.h" 16 #include "public/platform/WebTaskRunner.h"
16 #include "public/platform/WebThread.h" 17 #include "public/platform/WebThread.h"
17 #include "public/platform/WebTraceLocation.h" 18 #include "public/platform/WebTraceLocation.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 : m_data(data) 88 : m_data(data)
88 , m_size(size) 89 , m_size(size)
89 , m_mimeType(mimeType) 90 , m_mimeType(mimeType)
90 , m_callback(callback) 91 , m_callback(callback)
91 { 92 {
92 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); 93 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4));
93 m_encodedImage = adoptPtr(new Vector<unsigned char>()); 94 m_encodedImage = adoptPtr(new Vector<unsigned char>());
94 m_pixelRowStride = size.width() * NumChannelsPng; 95 m_pixelRowStride = size.width() * NumChannelsPng;
95 m_idleTaskStatus = IdleTaskNotSupported; 96 m_idleTaskStatus = IdleTaskNotSupported;
96 m_numRowsCompleted = 0; 97 m_numRowsCompleted = 0;
98 m_startTime = WTF::monotonicallyIncreasingTime();
97 } 99 }
98 100
99 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() 101 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator()
100 { 102 {
101 } 103 }
102 104
103 void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(bool canUseIdlePeriodSche duling, const double& quality) 105 void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(bool canUseIdlePeriodSche duling, const double& quality)
104 { 106 {
105 ASSERT(isMainThread()); 107 ASSERT(isMainThread());
106 108
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // Continue encoding from the last completed row 246 // Continue encoding from the last completed row
245 if (JPEGImageEncoder::encodeWithPreInitializedState(std::move(m_jpegEncoderS tate), m_data->data(), m_numRowsCompleted)) { 247 if (JPEGImageEncoder::encodeWithPreInitializedState(std::move(m_jpegEncoderS tate), m_data->data(), m_numRowsCompleted)) {
246 this->createBlobAndInvokeCallback(); 248 this->createBlobAndInvokeCallback();
247 } else { 249 } else {
248 this->createNullAndInvokeCallback(); 250 this->createNullAndInvokeCallback();
249 } 251 }
250 252
251 this->signalAlternativeCodePathFinishedForTesting(); 253 this->signalAlternativeCodePathFinishedForTesting();
252 } 254 }
253 255
256 void CanvasAsyncBlobCreator::recordElapsedTime()
257 {
258 double elapsedTime = WTF::monotonicallyIncreasingTime() - m_startTime;
259 if (m_mimeType == MimeTypePng) {
260 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobPNGCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.PNG", 0, 10000000, 50));
261 toBlobPNGCounter.count(elapsedTime * 1000000.0);
262 } else if (m_mimeType == MimeTypeJpeg) {
263 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobJPEGCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.JPEG", 0, 10000000, 50));
264 toBlobJPEGCounter.count(elapsedTime * 1000000.0);
265 } else if (m_mimeType == MimeTypeWebp) {
266 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobWEBPCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.WEBP", 0, 10000000, 50));
267 toBlobWEBPCounter.count(elapsedTime * 1000000.0);
268 } else {
269 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobUnknownCount er, new CustomCountHistogram("Blink.Canvas.ToBlob.Unknown", 0, 10000000, 50));
270 toBlobUnknownCounter.count(elapsedTime * 1000000.0);
271 }
272 }
273
254 void CanvasAsyncBlobCreator::createBlobAndInvokeCallback() 274 void CanvasAsyncBlobCreator::createBlobAndInvokeCallback()
255 { 275 {
256 ASSERT(isMainThread()); 276 ASSERT(isMainThread());
257 Blob* resultBlob = Blob::create(m_encodedImage->data(), m_encodedImage->size (), convertMimeTypeEnumToString(m_mimeType)); 277 Blob* resultBlob = Blob::create(m_encodedImage->data(), m_encodedImage->size (), convertMimeTypeEnumToString(m_mimeType));
258 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, bind(&BlobCallback::handleEvent, m_callback, resultBlob)); 278 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, bind(&BlobCallback::handleEvent, m_callback, resultBlob));
259 // Since toBlob is done, timeout events are no longer needed. So we clear 279 // Since toBlob is done, timeout events are no longer needed. So we clear
260 // non-GC members to allow teardown of CanvasAsyncBlobCreator. 280 // non-GC members to allow teardown of CanvasAsyncBlobCreator.
261 m_data.clear(); 281 m_data.clear();
262 m_callback.clear(); 282 m_callback.clear();
283 recordElapsedTime();
263 } 284 }
264 285
265 void CanvasAsyncBlobCreator::createNullAndInvokeCallback() 286 void CanvasAsyncBlobCreator::createNullAndInvokeCallback()
266 { 287 {
267 ASSERT(isMainThread()); 288 ASSERT(isMainThread());
268 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); 289 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, bind(&BlobCallback::handleEvent, m_callback, nullptr));
269 // Since toBlob is done (failed), timeout events are no longer needed. So we 290 // Since toBlob is done (failed), timeout events are no longer needed. So we
270 // clear non-GC members to allow teardown of CanvasAsyncBlobCreator. 291 // clear non-GC members to allow teardown of CanvasAsyncBlobCreator.
271 m_data.clear(); 292 m_data.clear();
272 m_callback.clear(); 293 m_callback.clear();
294 recordElapsedTime();
Justin Novosad 2016/06/06 15:16:03 The failure case should not be recording to the sa
273 } 295 }
274 296
275 void CanvasAsyncBlobCreator::encodeImageOnEncoderThread(double quality) 297 void CanvasAsyncBlobCreator::encodeImageOnEncoderThread(double quality)
276 { 298 {
277 ASSERT(!isMainThread()); 299 ASSERT(!isMainThread());
278 ASSERT(m_mimeType == MimeTypeWebp); 300 ASSERT(m_mimeType == MimeTypeWebp);
279 301
280 if (!ImageDataBuffer(m_size, m_data->data()).encodeImage("image/webp", quali ty, m_encodedImage.get())) { 302 if (!ImageDataBuffer(m_size, m_data->data()).encodeImage("image/webp", quali ty, m_encodedImage.get())) {
281 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, threadSafeBind(&BlobCallback::handleEvent, wrapCrossThreadPersistent(m_ callback.get()), nullptr)); 303 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, threadSafeBind(&BlobCallback::handleEvent, wrapCrossThreadPersistent(m_ callback.get()), nullptr));
282 return; 304 return;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); 359 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted);
338 this->signalAlternativeCodePathFinishedForTesting(); 360 this->signalAlternativeCodePathFinishedForTesting();
339 } 361 }
340 362
341 } 363 }
342 364
343 void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent() 365 void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent()
344 { 366 {
345 ASSERT(m_idleTaskStatus != IdleTaskNotStarted); 367 ASSERT(m_idleTaskStatus != IdleTaskNotStarted);
346 368
369 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, idleTaskCompleteTimeou tDelayHistogram, new EnumerationHistogram("Canvas.ToBlob.IdleTaskCompleteTimeout Delay", NumberOfMimeTypeSupported));
Justin Novosad 2016/06/06 15:16:03 This histogram does not provide very significant i
370 idleTaskCompleteTimeoutDelayHistogram.count(m_mimeType);
371
347 if (m_idleTaskStatus == IdleTaskStarted) { 372 if (m_idleTaskStatus == IdleTaskStarted) {
348 // It has taken too long to complete for the idle task. 373 // It has taken too long to complete for the idle task.
349 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask; 374 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask;
350 signalTaskSwitchInCompleteTimeoutEventForTesting(); 375 signalTaskSwitchInCompleteTimeoutEventForTesting();
351 376
352 if (m_mimeType == MimeTypePng) { 377 if (m_mimeType == MimeTypePng) {
353 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this)); 378 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this));
354 } else { 379 } else {
355 ASSERT(m_mimeType == MimeTypeJpeg); 380 ASSERT(m_mimeType == MimeTypeJpeg);
356 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this)); 381 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this));
357 } 382 }
358 } else { 383 } else {
359 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); 384 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted);
360 this->signalAlternativeCodePathFinishedForTesting(); 385 this->signalAlternativeCodePathFinishedForTesting();
361 } 386 }
362 } 387 }
363 388
364 void CanvasAsyncBlobCreator::postDelayedTaskToMainThread(const WebTraceLocation& location, std::unique_ptr<SameThreadClosure> task, double delayMs) 389 void CanvasAsyncBlobCreator::postDelayedTaskToMainThread(const WebTraceLocation& location, std::unique_ptr<SameThreadClosure> task, double delayMs)
365 { 390 {
366 DCHECK(isMainThread()); 391 DCHECK(isMainThread());
367 Platform::current()->mainThread()->getWebTaskRunner()->postDelayedTask(locat ion, std::move(task), delayMs); 392 Platform::current()->mainThread()->getWebTaskRunner()->postDelayedTask(locat ion, std::move(task), delayMs);
368 } 393 }
369 394
370 } // namespace blink 395 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698