| 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 "CanvasAsyncBlobCreator.h" | 5 #include "CanvasAsyncBlobCreator.h" |
| 6 | 6 |
| 7 #include "core/dom/ContextLifecycleObserver.h" | 7 #include "core/dom/ContextLifecycleObserver.h" |
| 8 #include "core/fileapi/File.h" | 8 #include "core/fileapi/Blob.h" |
| 9 #include "platform/Task.h" | 9 #include "platform/Task.h" |
| 10 #include "platform/ThreadSafeFunctional.h" | 10 #include "platform/ThreadSafeFunctional.h" |
| 11 #include "platform/graphics/ImageBuffer.h" | 11 #include "platform/graphics/ImageBuffer.h" |
| 12 #include "platform/heap/Handle.h" | 12 #include "platform/heap/Handle.h" |
| 13 #include "platform/image-encoders/skia/PNGImageEncoder.h" | 13 #include "platform/image-encoders/skia/PNGImageEncoder.h" |
| 14 #include "platform/threading/BackgroundTaskRunner.h" | 14 #include "platform/threading/BackgroundTaskRunner.h" |
| 15 #include "public/platform/Platform.h" | 15 #include "public/platform/Platform.h" |
| 16 #include "public/platform/WebScheduler.h" | 16 #include "public/platform/WebScheduler.h" |
| 17 #include "public/platform/WebTaskRunner.h" | 17 #include "public/platform/WebTaskRunner.h" |
| 18 #include "public/platform/WebThread.h" | 18 #include "public/platform/WebThread.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 // off-heap CanvasAsyncBlobCreator, thus we need to dispose backref to | 62 // off-heap CanvasAsyncBlobCreator, thus we need to dispose backref to |
| 63 // m_asyncBlobCreator here when its destructor is called to avoid | 63 // m_asyncBlobCreator here when its destructor is called to avoid |
| 64 // heap-use-after-free error. | 64 // heap-use-after-free error. |
| 65 m_asyncBlobCreator = nullptr; | 65 m_asyncBlobCreator = nullptr; |
| 66 } | 66 } |
| 67 | 67 |
| 68 private: | 68 private: |
| 69 CanvasAsyncBlobCreator* m_asyncBlobCreator; | 69 CanvasAsyncBlobCreator* m_asyncBlobCreator; |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 PassRefPtr<CanvasAsyncBlobCreator> CanvasAsyncBlobCreator::create(PassRefPtr<DOM
Uint8ClampedArray> unpremultipliedRGBAImageData, const String& mimeType, const I
ntSize& size, FileCallback* callback, ExecutionContext* executionContext) | 72 PassRefPtr<CanvasAsyncBlobCreator> CanvasAsyncBlobCreator::create(PassRefPtr<DOM
Uint8ClampedArray> unpremultipliedRGBAImageData, const String& mimeType, const I
ntSize& size, BlobCallback* callback, ExecutionContext* executionContext) |
| 73 { | 73 { |
| 74 RefPtr<CanvasAsyncBlobCreator> asyncBlobCreator = adoptRef(new CanvasAsyncBl
obCreator(unpremultipliedRGBAImageData, mimeType, size, callback)); | 74 RefPtr<CanvasAsyncBlobCreator> asyncBlobCreator = adoptRef(new CanvasAsyncBl
obCreator(unpremultipliedRGBAImageData, mimeType, size, callback)); |
| 75 asyncBlobCreator->createContextObserver(executionContext); | 75 asyncBlobCreator->createContextObserver(executionContext); |
| 76 return asyncBlobCreator.release(); | 76 return asyncBlobCreator.release(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(PassRefPtr<DOMUint8ClampedArray>
data, const String& mimeType, const IntSize& size, FileCallback* callback) | 79 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(PassRefPtr<DOMUint8ClampedArray>
data, const String& mimeType, const IntSize& size, BlobCallback* callback) |
| 80 : m_cancelled(false) | 80 : m_cancelled(false) |
| 81 , m_data(data) | 81 , m_data(data) |
| 82 , m_size(size) | 82 , m_size(size) |
| 83 , m_mimeType(mimeType) | 83 , m_mimeType(mimeType) |
| 84 , m_callback(callback) | 84 , m_callback(callback) |
| 85 { | 85 { |
| 86 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); | 86 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); |
| 87 m_encodedImage = adoptPtr(new Vector<unsigned char>()); | 87 m_encodedImage = adoptPtr(new Vector<unsigned char>()); |
| 88 m_pixelRowStride = size.width() * NumChannelsPng; | 88 m_pixelRowStride = size.width() * NumChannelsPng; |
| 89 m_numRowsCompleted = 0; | 89 m_numRowsCompleted = 0; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 114 } else { | 114 } else { |
| 115 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt
h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa
sk : BackgroundTaskRunner::TaskSizeShortRunningTask; | 115 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt
h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa
sk : BackgroundTaskRunner::TaskSizeShortRunningTask; |
| 116 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe
Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess
(this), quality), taskSize); | 116 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe
Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess
(this), quality), taskSize); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 | 119 |
| 120 void CanvasAsyncBlobCreator::initiatePngEncoding(double deadlineSeconds) | 120 void CanvasAsyncBlobCreator::initiatePngEncoding(double deadlineSeconds) |
| 121 { | 121 { |
| 122 m_encoderState = PNGImageEncoderState::create(m_size, m_encodedImage.get()); | 122 m_encoderState = PNGImageEncoderState::create(m_size, m_encodedImage.get()); |
| 123 if (!m_encoderState) { | 123 if (!m_encoderState) { |
| 124 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER
E, bind(&FileCallback::handleEvent, m_callback, nullptr)); | 124 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER
E, bind(&BlobCallback::handleEvent, m_callback, nullptr)); |
| 125 m_selfRef.clear(); | 125 m_selfRef.clear(); |
| 126 return; | 126 return; |
| 127 } | 127 } |
| 128 | 128 |
| 129 CanvasAsyncBlobCreator::idleEncodeRowsPng(deadlineSeconds); | 129 CanvasAsyncBlobCreator::idleEncodeRowsPng(deadlineSeconds); |
| 130 } | 130 } |
| 131 | 131 |
| 132 void CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng() | 132 void CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng() |
| 133 { | 133 { |
| 134 Platform::current()->currentThread()->scheduler()->postIdleTask(BLINK_FROM_H
ERE, WTF::bind<double>(&CanvasAsyncBlobCreator::idleEncodeRowsPng, this)); | 134 Platform::current()->currentThread()->scheduler()->postIdleTask(BLINK_FROM_H
ERE, WTF::bind<double>(&CanvasAsyncBlobCreator::idleEncodeRowsPng, this)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 151 | 151 |
| 152 if (isDeadlineNearOrPassed(deadlineSeconds)) { | 152 if (isDeadlineNearOrPassed(deadlineSeconds)) { |
| 153 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER
E, bind(&CanvasAsyncBlobCreator::createBlobAndCall, this)); | 153 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER
E, bind(&CanvasAsyncBlobCreator::createBlobAndCall, this)); |
| 154 } else { | 154 } else { |
| 155 this->createBlobAndCall(); | 155 this->createBlobAndCall(); |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 void CanvasAsyncBlobCreator::createBlobAndCall() | 159 void CanvasAsyncBlobCreator::createBlobAndCall() |
| 160 { | 160 { |
| 161 File* resultBlob = File::create(m_encodedImage->data(), m_encodedImage->size
(), m_mimeType); | 161 Blob* resultBlob = Blob::create(m_encodedImage->data(), m_encodedImage->size
(), m_mimeType); |
| 162 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, b
ind(&FileCallback::handleEvent, m_callback, resultBlob)); | 162 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, b
ind(&BlobCallback::handleEvent, m_callback, resultBlob)); |
| 163 clearSelfReference(); // self-destruct once job is done. | 163 clearSelfReference(); // self-destruct once job is done. |
| 164 } | 164 } |
| 165 | 165 |
| 166 void CanvasAsyncBlobCreator::encodeImageOnEncoderThread(double quality) | 166 void CanvasAsyncBlobCreator::encodeImageOnEncoderThread(double quality) |
| 167 { | 167 { |
| 168 ASSERT(!isMainThread()); | 168 ASSERT(!isMainThread()); |
| 169 if (initializeEncodeImageOnEncoderThread()) { | 169 if (initializeEncodeImageOnEncoderThread()) { |
| 170 if (m_mimeType == "image/png") { | 170 if (m_mimeType == "image/png") { |
| 171 // At the time being, progressive encoding is only applicable to png
image format | 171 // At the time being, progressive encoding is only applicable to png
image format |
| 172 // TODO(xlai): Progressive encoding on jpeg and webp image formats (
crbug.com/571398, crbug.com/571399) | 172 // TODO(xlai): Progressive encoding on jpeg and webp image formats (
crbug.com/571398, crbug.com/571399) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThreadAcces
s(this))); | 246 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThreadAcces
s(this))); |
| 247 } | 247 } |
| 248 | 248 |
| 249 void CanvasAsyncBlobCreator::scheduleCreateBlobAndCallOnMainThread() | 249 void CanvasAsyncBlobCreator::scheduleCreateBlobAndCallOnMainThread() |
| 250 { | 250 { |
| 251 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::createBlobAndCall, AllowCrossThreadAccess
(this))); | 251 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::createBlobAndCall, AllowCrossThreadAccess
(this))); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void CanvasAsyncBlobCreator::scheduleCreateNullptrAndCallOnMainThread() | 254 void CanvasAsyncBlobCreator::scheduleCreateNullptrAndCallOnMainThread() |
| 255 { | 255 { |
| 256 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, b
ind(&FileCallback::handleEvent, m_callback, nullptr)); | 256 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, b
ind(&BlobCallback::handleEvent, m_callback, nullptr)); |
| 257 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThreadAcces
s(this))); | 257 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t
hreadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThreadAcces
s(this))); |
| 258 } | 258 } |
| 259 | 259 |
| 260 } // namespace blink | 260 } // namespace blink |
| OLD | NEW |