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

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

Issue 2613733002: Enforce OffscreenCanvas.convertToBlob to terminate after idling for too long (Closed)
Patch Set: test Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
index 562b71804a99ec8c68e101b0b88e245be86b8542..6d1eff20d0ca5ba303079d7c23f4d0be79022061 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -275,17 +275,13 @@ void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(const double& quality) {
NOTREACHED();
}
- // TODO: Enforce OffscreenCanvas.convertToBlob to finish within deadline.
- // See crbug.com/657102.
- if (m_functionType == HTMLCanvasToBlobCallback) {
- // We post the below task to check if the above idle task isn't late.
- // There's no risk of concurrency as both tasks are on main thread.
- this->postDelayedTaskToMainThread(
- BLINK_FROM_HERE,
- WTF::bind(&CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent,
- wrapPersistent(this), quality),
- IdleTaskStartTimeoutDelay);
- }
+ // We post the below task to check if the above idle task isn't late.
+ // There's no risk of concurrency as both tasks are on the same thread.
+ this->postDelayedTaskToCurrentThread(
+ BLINK_FROM_HERE,
+ WTF::bind(&CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent,
+ wrapPersistent(this), quality),
+ IdleTaskStartTimeoutDelay);
}
}
@@ -412,7 +408,7 @@ void CanvasAsyncBlobCreator::idleEncodeRowsJpeg(double deadlineSeconds) {
}
}
-void CanvasAsyncBlobCreator::encodeRowsPngOnMainThread() {
+void CanvasAsyncBlobCreator::forceEncodeRowsPngOnCurrentThread() {
DCHECK(m_idleTaskStatus == IdleTaskSwitchedToImmediateTask);
// Continue encoding from the last completed row
@@ -423,20 +419,39 @@ void CanvasAsyncBlobCreator::encodeRowsPngOnMainThread() {
inputPixels += m_pixelRowStride;
}
PNGImageEncoder::finalizePng(m_pngEncoderState.get());
- this->createBlobAndReturnResult();
+
+ if (isMainThread()) {
+ this->createBlobAndReturnResult();
+ } else {
+ TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
+ ->postTask(
+ BLINK_FROM_HERE,
+ crossThreadBind(&CanvasAsyncBlobCreator::createBlobAndReturnResult,
+ wrapCrossThreadPersistent(this)));
+ }
this->signalAlternativeCodePathFinishedForTesting();
}
-void CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread() {
+void CanvasAsyncBlobCreator::forceEncodeRowsJpegOnCurrentThread() {
DCHECK(m_idleTaskStatus == IdleTaskSwitchedToImmediateTask);
// Continue encoding from the last completed row
+ void (CanvasAsyncBlobCreator::*functionToBeCalled)(void);
if (JPEGImageEncoder::encodeWithPreInitializedState(
std::move(m_jpegEncoderState), m_data->data(), m_numRowsCompleted)) {
- this->createBlobAndReturnResult();
+ functionToBeCalled = &CanvasAsyncBlobCreator::createBlobAndReturnResult;
} else {
- this->createNullAndReturnResult();
+ functionToBeCalled = &CanvasAsyncBlobCreator::createNullAndReturnResult;
+ }
+
+ if (isMainThread()) {
+ (this->*functionToBeCalled)();
+ } else {
+ TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
+ ->postTask(BLINK_FROM_HERE,
+ crossThreadBind(functionToBeCalled,
+ wrapCrossThreadPersistent(this)));
}
this->signalAlternativeCodePathFinishedForTesting();
@@ -523,7 +538,7 @@ bool CanvasAsyncBlobCreator::initializeJpegStruct(double quality) {
void CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent(double quality) {
if (m_idleTaskStatus == IdleTaskStarted) {
// Even if the task started quickly, we still want to ensure completion
- this->postDelayedTaskToMainThread(
+ this->postDelayedTaskToCurrentThread(
BLINK_FROM_HERE,
WTF::bind(&CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent,
wrapPersistent(this)),
@@ -540,8 +555,9 @@ void CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent(double quality) {
TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
->postTask(
BLINK_FROM_HERE,
- WTF::bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread,
- wrapPersistent(this)));
+ WTF::bind(
+ &CanvasAsyncBlobCreator::forceEncodeRowsPngOnCurrentThread,
+ wrapPersistent(this)));
} else {
// Failing in initialization of png struct
this->signalAlternativeCodePathFinishedForTesting();
@@ -552,8 +568,9 @@ void CanvasAsyncBlobCreator::idleTaskStartTimeoutEvent(double quality) {
TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
->postTask(
BLINK_FROM_HERE,
- WTF::bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread,
- wrapPersistent(this)));
+ WTF::bind(
+ &CanvasAsyncBlobCreator::forceEncodeRowsJpegOnCurrentThread,
+ wrapPersistent(this)));
} else {
// Failing in initialization of jpeg struct
this->signalAlternativeCodePathFinishedForTesting();
@@ -578,15 +595,17 @@ void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent() {
TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
->postTask(
BLINK_FROM_HERE,
- WTF::bind(&CanvasAsyncBlobCreator::encodeRowsPngOnMainThread,
- wrapPersistent(this)));
+ WTF::bind(
+ &CanvasAsyncBlobCreator::forceEncodeRowsPngOnCurrentThread,
+ wrapPersistent(this)));
} else {
DCHECK(m_mimeType == MimeTypeJpeg);
TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
->postTask(
BLINK_FROM_HERE,
- WTF::bind(&CanvasAsyncBlobCreator::encodeRowsJpegOnMainThread,
- wrapPersistent(this)));
+ WTF::bind(
+ &CanvasAsyncBlobCreator::forceEncodeRowsJpegOnCurrentThread,
+ wrapPersistent(this)));
}
} else {
DCHECK(m_idleTaskStatus == IdleTaskFailed ||
@@ -595,11 +614,10 @@ void CanvasAsyncBlobCreator::idleTaskCompleteTimeoutEvent() {
}
}
-void CanvasAsyncBlobCreator::postDelayedTaskToMainThread(
+void CanvasAsyncBlobCreator::postDelayedTaskToCurrentThread(
const WebTraceLocation& location,
std::unique_ptr<WTF::Closure> task,
double delayMs) {
- DCHECK(isMainThread());
TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, m_document)
->postDelayedTask(location, std::move(task), delayMs);
}

Powered by Google App Engine
This is Rietveld 408576698