Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 } else if (mimeType == "image/webp") { | 72 } else if (mimeType == "image/webp") { |
| 72 mimeTypeEnum = CanvasAsyncBlobCreator::MimeTypeWebp; | 73 mimeTypeEnum = CanvasAsyncBlobCreator::MimeTypeWebp; |
| 73 } else { | 74 } else { |
| 74 mimeTypeEnum = CanvasAsyncBlobCreator::NumberOfMimeTypeSupported; | 75 mimeTypeEnum = CanvasAsyncBlobCreator::NumberOfMimeTypeSupported; |
| 75 } | 76 } |
| 76 return mimeTypeEnum; | 77 return mimeTypeEnum; |
| 77 } | 78 } |
| 78 | 79 |
| 79 } // anonymous namespace | 80 } // anonymous namespace |
| 80 | 81 |
| 81 CanvasAsyncBlobCreator* CanvasAsyncBlobCreator::create(DOMUint8ClampedArray* unp remultipliedRGBAImageData, const String& mimeType, const IntSize& size, BlobCall back* callback) | 82 CanvasAsyncBlobCreator* CanvasAsyncBlobCreator::create(DOMUint8ClampedArray* unp remultipliedRGBAImageData, const String& mimeType, const IntSize& size, BlobCall back* callback, double startTime) |
| 82 { | 83 { |
| 83 return new CanvasAsyncBlobCreator(unpremultipliedRGBAImageData, convertMimeT ypeStringToEnum(mimeType), size, callback); | 84 return new CanvasAsyncBlobCreator(unpremultipliedRGBAImageData, convertMimeT ypeStringToEnum(mimeType), size, callback, startTime); |
| 84 } | 85 } |
| 85 | 86 |
| 86 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(DOMUint8ClampedArray* data, MimeT ype mimeType, const IntSize& size, BlobCallback* callback) | 87 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(DOMUint8ClampedArray* data, MimeT ype mimeType, const IntSize& size, BlobCallback* callback, double startTime) |
| 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) |
| 92 , m_startTime(startTime) | |
| 91 { | 93 { |
| 92 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); | 94 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); |
| 93 m_encodedImage = adoptPtr(new Vector<unsigned char>()); | 95 m_encodedImage = adoptPtr(new Vector<unsigned char>()); |
| 94 m_pixelRowStride = size.width() * NumChannelsPng; | 96 m_pixelRowStride = size.width() * NumChannelsPng; |
| 95 m_idleTaskStatus = IdleTaskNotSupported; | 97 m_idleTaskStatus = IdleTaskNotSupported; |
| 96 m_numRowsCompleted = 0; | 98 m_numRowsCompleted = 0; |
| 97 } | 99 } |
| 98 | 100 |
| 99 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() | 101 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() |
| 100 { | 102 { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 111 } else if (m_mimeType == MimeTypeJpeg) { | 113 } else if (m_mimeType == MimeTypeJpeg) { |
| 112 this->scheduleInitiateJpegEncoding(quality); | 114 this->scheduleInitiateJpegEncoding(quality); |
| 113 } else { | 115 } else { |
| 114 // Progressive encoding is only applicable to png and jpeg image for mat, | 116 // Progressive encoding is only applicable to png and jpeg image for mat, |
| 115 // and thus idle tasks scheduling can only be applied to these image formats. | 117 // and thus idle tasks scheduling can only be applied to these image formats. |
| 116 // TODO(xlai): Progressive encoding on webp image formats (crbug.com /571399) | 118 // TODO(xlai): Progressive encoding on webp image formats (crbug.com /571399) |
| 117 ASSERT_NOT_REACHED(); | 119 ASSERT_NOT_REACHED(); |
| 118 } | 120 } |
| 119 // We post the below task to check if the above idle task isn't late. | 121 // We post the below task to check if the above idle task isn't late. |
| 120 // There's no risk of concurrency as both tasks are on main thread. | 122 // There's no risk of concurrency as both tasks are on main thread. |
| 121 this->postDelayedTaskToMainThread(BLINK_FROM_HERE, bind(&CanvasAsyncBlob Creator::idleTaskStartTimeoutEvent, this, quality), IdleTaskStartTimeoutDelay); | 123 double startTime = WTF::monotonicallyIncreasingTime(); |
| 124 this->postDelayedTaskToMainThread(BLINK_FROM_HERE, bind(&CanvasAsyncBlob Creator::idleTaskStartTimeoutEvent, this, quality, startTime), IdleTaskStartTime outDelay); | |
| 122 } else if (m_mimeType == MimeTypeWebp) { | 125 } else if (m_mimeType == MimeTypeWebp) { |
| 123 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa sk : BackgroundTaskRunner::TaskSizeShortRunningTask; | 126 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa sk : BackgroundTaskRunner::TaskSizeShortRunningTask; |
| 124 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, wrapCrossThreadPersist ent(this), quality), taskSize); | 127 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, wrapCrossThreadPersist ent(this), quality), taskSize); |
| 125 } | 128 } |
| 126 } | 129 } |
| 127 | 130 |
| 128 void CanvasAsyncBlobCreator::scheduleInitiateJpegEncoding(const double& quality) | 131 void CanvasAsyncBlobCreator::scheduleInitiateJpegEncoding(const double& quality) |
| 129 { | 132 { |
| 130 Platform::current()->mainThread()->scheduler()->postIdleTask(BLINK_FROM_HERE , bind<double>(&CanvasAsyncBlobCreator::initiateJpegEncoding, this, quality)); | 133 Platform::current()->mainThread()->scheduler()->postIdleTask(BLINK_FROM_HERE , bind<double>(&CanvasAsyncBlobCreator::initiateJpegEncoding, this, quality)); |
| 131 } | 134 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 | 256 |
| 254 void CanvasAsyncBlobCreator::createBlobAndInvokeCallback() | 257 void CanvasAsyncBlobCreator::createBlobAndInvokeCallback() |
| 255 { | 258 { |
| 256 ASSERT(isMainThread()); | 259 ASSERT(isMainThread()); |
| 257 Blob* resultBlob = Blob::create(m_encodedImage->data(), m_encodedImage->size (), convertMimeTypeEnumToString(m_mimeType)); | 260 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)); | 261 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 | 262 // Since toBlob is done, timeout events are no longer needed. So we clear |
| 260 // non-GC members to allow teardown of CanvasAsyncBlobCreator. | 263 // non-GC members to allow teardown of CanvasAsyncBlobCreator. |
| 261 m_data.clear(); | 264 m_data.clear(); |
| 262 m_callback.clear(); | 265 m_callback.clear(); |
| 266 double elapsedTime = WTF::monotonicallyIncreasingTime() - m_startTime; | |
| 267 if (m_mimeType == MimeTypePng) { | |
| 268 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobPNGCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.PNG", 0, 10000000, 50)); | |
| 269 toBlobPNGCounter.count(elapsedTime * 1000000.0); | |
| 270 } else if (m_mimeType == MimeTypeJpeg) { | |
| 271 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobJPEGCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.JPEG", 0, 10000000, 50)); | |
| 272 toBlobJPEGCounter.count(elapsedTime * 1000000.0); | |
| 273 } else { | |
| 274 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobWEBPCounter, new CustomCountHistogram("Blink.Canvas.ToBlob.WEBP", 0, 10000000, 50)); | |
| 275 toBlobWEBPCounter.count(elapsedTime * 1000000.0); | |
| 276 } | |
| 263 } | 277 } |
| 264 | 278 |
| 265 void CanvasAsyncBlobCreator::createNullAndInvokeCallback() | 279 void CanvasAsyncBlobCreator::createNullAndInvokeCallback() |
| 266 { | 280 { |
| 267 ASSERT(isMainThread()); | 281 ASSERT(isMainThread()); |
| 268 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); | 282 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 | 283 // Since toBlob is done (failed), timeout events are no longer needed. So we |
| 270 // clear non-GC members to allow teardown of CanvasAsyncBlobCreator. | 284 // clear non-GC members to allow teardown of CanvasAsyncBlobCreator. |
| 271 m_data.clear(); | 285 m_data.clear(); |
| 272 m_callback.clear(); | 286 m_callback.clear(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 298 bool CanvasAsyncBlobCreator::initializeJpegStruct(double quality) | 312 bool CanvasAsyncBlobCreator::initializeJpegStruct(double quality) |
| 299 { | 313 { |
| 300 m_jpegEncoderState = JPEGImageEncoderState::create(m_size, quality, m_encode dImage.get()); | 314 m_jpegEncoderState = JPEGImageEncoderState::create(m_size, quality, m_encode dImage.get()); |
| 301 if (!m_jpegEncoderState) { | 315 if (!m_jpegEncoderState) { |
| 302 this->createNullAndInvokeCallback(); | 316 this->createNullAndInvokeCallback(); |
| 303 return false; | 317 return false; |
| 304 } | 318 } |
| 305 return true; | 319 return true; |
| 306 } | 320 } |
| 307 | 321 |
| 308 void CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent(double quality) | 322 void CanvasAsyncBlobCreator::recordTimeoutSwitch(IdleTaskTimeoutType type) |
| 309 { | 323 { |
| 324 if (m_mimeType == MimeTypePng) { | |
| 325 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, idleTaskTimeoutSwi tchPNG, new EnumerationHistogram("Canvas.ToBlob.IdleTaskTimeoutSwitch.PNG", Idle TaskTimeoutSupported)); | |
| 326 idleTaskTimeoutSwitchPNG.count(type); | |
| 327 } else { | |
| 328 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, idleTaskTimeoutSwi tchJPEG, new EnumerationHistogram("Canvas.ToBlob.IdleTaskTimeoutSwitch.JPEG", Id leTaskTimeoutSupported)); | |
| 329 idleTaskTimeoutSwitchJPEG.count(type); | |
| 330 } | |
| 331 } | |
| 332 | |
| 333 void CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent(double quality, double st artTime) | |
| 334 { | |
| 335 double elapsedTime = WTF::monotonicallyIncreasingTime() - startTime; | |
| 336 if (m_mimeType == MimeTypePng) { | |
| 337 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobPNGStartTime outCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.PNG.Sta rt", 0, 10000000, 50)); | |
| 338 toBlobPNGStartTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 339 } else if (m_mimeType == MimeTypeJpeg) { | |
| 340 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobJPEGStartTim eoutCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.JPEG.S tart", 0, 10000000, 50)); | |
| 341 toBlobJPEGStartTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 342 } else { | |
| 343 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobWEBPStartTim eoutCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.WEBP.S tart", 0, 10000000, 50)); | |
| 344 toBlobWEBPStartTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 345 } | |
|
xidachen
2016/06/07 20:46:29
Is this recording meaningful now that we change to
| |
| 346 | |
| 310 if (m_idleTaskStatus == IdleTaskStarted) { | 347 if (m_idleTaskStatus == IdleTaskStarted) { |
| 311 // Even if the task started quickly, we still want to ensure completion | 348 // Even if the task started quickly, we still want to ensure completion |
| 312 this->postDelayedTaskToMainThread(BLINK_FROM_HERE, bind(&CanvasAsyncBlob Creator::idleTaskCompleteTimeoutEvent, this), IdleTaskCompleteTimeoutDelay); | 349 startTime = WTF::monotonicallyIncreasingTime(); |
| 350 this->postDelayedTaskToMainThread(BLINK_FROM_HERE, bind(&CanvasAsyncBlob Creator::idleTaskCompleteTimeoutEvent, this, startTime), IdleTaskCompleteTimeout Delay); | |
| 313 } else if (m_idleTaskStatus == IdleTaskNotStarted) { | 351 } else if (m_idleTaskStatus == IdleTaskNotStarted) { |
| 314 // If the idle task does not start after a delay threshold, we will | 352 // If the idle task does not start after a delay threshold, we will |
| 315 // force it to happen on main thread (even though it may cause more | 353 // force it to happen on main thread (even though it may cause more |
| 316 // janks) to prevent toBlob being postponed forever in extreme cases. | 354 // janks) to prevent toBlob being postponed forever in extreme cases. |
| 317 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask; | 355 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask; |
| 318 signalTaskSwitchInStartTimeoutEventForTesting(); | 356 signalTaskSwitchInStartTimeoutEventForTesting(); |
| 319 | 357 |
| 320 if (m_mimeType == MimeTypePng) { | 358 if (m_mimeType == MimeTypePng) { |
| 321 if (initializePngStruct()) { | 359 if (initializePngStruct()) { |
| 360 recordTimeoutSwitch(IdleTaskStartTimeout); | |
| 322 Platform::current()->mainThread()->getWebTaskRunner()->postTask( BLINK_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this)) ; | 361 Platform::current()->mainThread()->getWebTaskRunner()->postTask( BLINK_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this)) ; |
| 323 } else { | 362 } else { |
| 324 // Failing in initialization of png struct | 363 // Failing in initialization of png struct |
| 325 this->signalAlternativeCodePathFinishedForTesting(); | 364 this->signalAlternativeCodePathFinishedForTesting(); |
| 326 } | 365 } |
| 327 } else { | 366 } else { |
| 328 ASSERT(m_mimeType == MimeTypeJpeg); | 367 ASSERT(m_mimeType == MimeTypeJpeg); |
| 329 if (initializeJpegStruct(quality)) { | 368 if (initializeJpegStruct(quality)) { |
| 369 recordTimeoutSwitch(IdleTaskStartTimeout); | |
| 330 Platform::current()->mainThread()->getWebTaskRunner()->postTask( BLINK_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this) ); | 370 Platform::current()->mainThread()->getWebTaskRunner()->postTask( BLINK_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this) ); |
| 331 } else { | 371 } else { |
| 332 // Failing in initialization of jpeg struct | 372 // Failing in initialization of jpeg struct |
| 333 this->signalAlternativeCodePathFinishedForTesting(); | 373 this->signalAlternativeCodePathFinishedForTesting(); |
| 334 } | 374 } |
| 335 } | 375 } |
| 336 } else { | 376 } else { |
| 337 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); | 377 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); |
| 338 this->signalAlternativeCodePathFinishedForTesting(); | 378 this->signalAlternativeCodePathFinishedForTesting(); |
| 339 } | 379 } |
| 340 | 380 |
| 341 } | 381 } |
| 342 | 382 |
| 343 void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent() | 383 void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent(double startTime) |
| 344 { | 384 { |
| 345 ASSERT(m_idleTaskStatus != IdleTaskNotStarted); | 385 ASSERT(m_idleTaskStatus != IdleTaskNotStarted); |
| 386 double elapsedTime = WTF::monotonicallyIncreasingTime() - startTime; | |
| 387 if (m_mimeType == MimeTypePng) { | |
| 388 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobPNGCompleteT imeoutCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.PNG. Complete", 0, 10000000, 50)); | |
| 389 toBlobPNGCompleteTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 390 } else if (m_mimeType == MimeTypeJpeg) { | |
| 391 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobJPEGComplete TimeoutCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.JPE G.Complete", 0, 10000000, 50)); | |
| 392 toBlobJPEGCompleteTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 393 } else { | |
| 394 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, toBlobWEBPComplete TimeoutCounter, new CustomCountHistogram("Blink.Canvas.ToBlobTimeoutDuration.WEB P.Complete", 0, 10000000, 50)); | |
| 395 toBlobWEBPCompleteTimeoutCounter.count(elapsedTime * 1000000.0); | |
| 396 } | |
| 346 | 397 |
| 347 if (m_idleTaskStatus == IdleTaskStarted) { | 398 if (m_idleTaskStatus == IdleTaskStarted) { |
| 348 // It has taken too long to complete for the idle task. | 399 // It has taken too long to complete for the idle task. |
| 349 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask; | 400 m_idleTaskStatus = IdleTaskSwitchedToMainThreadTask; |
| 350 signalTaskSwitchInCompleteTimeoutEventForTesting(); | 401 signalTaskSwitchInCompleteTimeoutEventForTesting(); |
| 351 | 402 |
| 352 if (m_mimeType == MimeTypePng) { | 403 if (m_mimeType == MimeTypePng) { |
| 404 recordTimeoutSwitch(IdleTaskCompleteTimeout); | |
| 353 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this)); | 405 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread, this)); |
| 354 } else { | 406 } else { |
| 355 ASSERT(m_mimeType == MimeTypeJpeg); | 407 ASSERT(m_mimeType == MimeTypeJpeg); |
| 408 recordTimeoutSwitch(IdleTaskCompleteTimeout); | |
| 356 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this)); | 409 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN K_FROM_HERE, bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread, this)); |
| 357 } | 410 } |
| 358 } else { | 411 } else { |
| 359 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); | 412 ASSERT(m_idleTaskStatus == IdleTaskFailed || m_idleTaskStatus == IdleTas kCompleted); |
| 360 this->signalAlternativeCodePathFinishedForTesting(); | 413 this->signalAlternativeCodePathFinishedForTesting(); |
| 361 } | 414 } |
| 362 } | 415 } |
| 363 | 416 |
| 364 void CanvasAsyncBlobCreator::postDelayedTaskToMainThread(const WebTraceLocation& location, std::unique_ptr<SameThreadClosure> task, double delayMs) | 417 void CanvasAsyncBlobCreator::postDelayedTaskToMainThread(const WebTraceLocation& location, std::unique_ptr<SameThreadClosure> task, double delayMs) |
| 365 { | 418 { |
| 366 DCHECK(isMainThread()); | 419 DCHECK(isMainThread()); |
| 367 Platform::current()->mainThread()->getWebTaskRunner()->postDelayedTask(locat ion, std::move(task), delayMs); | 420 Platform::current()->mainThread()->getWebTaskRunner()->postDelayedTask(locat ion, std::move(task), delayMs); |
| 368 } | 421 } |
| 369 | 422 |
| 370 } // namespace blink | 423 } // namespace blink |
| OLD | NEW |