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 "CanvasAsyncBlobCreator.h" | 5 #include "CanvasAsyncBlobCreator.h" |
| 6 | 6 |
| 7 #include "core/fileapi/Blob.h" | 7 #include "core/fileapi/Blob.h" |
| 8 #include "platform/ThreadSafeFunctional.h" | 8 #include "platform/ThreadSafeFunctional.h" |
| 9 #include "platform/graphics/ImageBuffer.h" | 9 #include "platform/graphics/ImageBuffer.h" |
| 10 #include "platform/heap/Handle.h" | 10 #include "platform/heap/Handle.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 const int NumChannelsPng = 4; | 27 const int NumChannelsPng = 4; |
| 28 const int LongTaskImageSizeThreshold = 1000 * 1000; // The max image size we exp ect to encode in 14ms on Linux in PNG format | 28 const int LongTaskImageSizeThreshold = 1000 * 1000; // The max image size we exp ect to encode in 14ms on Linux in PNG format |
| 29 | 29 |
| 30 bool isDeadlineNearOrPassed(double deadlineSeconds) | 30 bool isDeadlineNearOrPassed(double deadlineSeconds) |
| 31 { | 31 { |
| 32 return (deadlineSeconds - SlackBeforeDeadline - monotonicallyIncreasingTime( ) <= 0); | 32 return (deadlineSeconds - SlackBeforeDeadline - monotonicallyIncreasingTime( ) <= 0); |
| 33 } | 33 } |
| 34 | 34 |
| 35 } // anonymous namespace | 35 } // anonymous namespace |
| 36 | 36 |
| 37 PassRefPtr<CanvasAsyncBlobCreator> CanvasAsyncBlobCreator::create(PassRefPtr<DOM Uint8ClampedArray> unpremultipliedRGBAImageData, const String& mimeType, const I ntSize& size, BlobCallback* callback) | 37 CanvasAsyncBlobCreator* CanvasAsyncBlobCreator::create(DOMUint8ClampedArray* unp remultipliedRGBAImageData, const String& mimeType, const IntSize& size, BlobCall back* callback) |
| 38 { | 38 { |
| 39 RefPtr<CanvasAsyncBlobCreator> asyncBlobCreator = adoptRef(new CanvasAsyncBl obCreator(unpremultipliedRGBAImageData, mimeType, size, callback)); | 39 return new CanvasAsyncBlobCreator(unpremultipliedRGBAImageData, mimeType, si ze, callback); |
| 40 return asyncBlobCreator.release(); | |
| 41 } | 40 } |
| 42 | 41 |
| 43 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(PassRefPtr<DOMUint8ClampedArray> data, const String& mimeType, const IntSize& size, BlobCallback* callback) | 42 CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(DOMUint8ClampedArray* data, const String& mimeType, const IntSize& size, BlobCallback* callback) |
| 44 : m_data(data) | 43 : m_data(data) |
| 45 , m_size(size) | 44 , m_size(size) |
| 46 , m_mimeType(mimeType) | 45 , m_mimeType(mimeType) |
| 47 , m_callback(callback) | 46 , m_callback(callback) |
| 48 { | 47 { |
| 49 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); | 48 ASSERT(m_data->length() == (unsigned) (size.height() * size.width() * 4)); |
| 50 m_encodedImage = adoptPtr(new Vector<unsigned char>()); | 49 m_encodedImage = adoptPtr(new Vector<unsigned char>()); |
| 51 m_pixelRowStride = size.width() * NumChannelsPng; | 50 m_pixelRowStride = size.width() * NumChannelsPng; |
| 52 m_numRowsCompleted = 0; | 51 m_numRowsCompleted = 0; |
| 53 } | 52 } |
| 54 | 53 |
| 55 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() | 54 CanvasAsyncBlobCreator::~CanvasAsyncBlobCreator() |
| 56 { | 55 { |
| 57 } | 56 } |
| 58 | 57 |
| 59 void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(bool canUseIdlePeriodSche duling, double quality) | 58 void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(bool canUseIdlePeriodSche duling, double quality) |
| 60 { | 59 { |
| 61 // TODO: async blob creation should be supported in worker_pool threads as w ell. but right now blink does not have that | 60 // TODO: async blob creation should be supported in worker_pool threads as w ell. but right now blink does not have that |
| 62 ASSERT(isMainThread()); | 61 ASSERT(isMainThread()); |
| 63 | 62 |
| 64 // Make self-reference to keep this object alive until the final task comple tes | 63 // Make self-reference to keep this object alive until the final task comple tes |
| 65 m_selfRef = this; | 64 m_keepAlive = this; |
|
haraken
2016/04/11 04:34:33
Isn't the |this| object kept alive by the persiste
sof
2016/04/11 05:14:21
I believe that's correct, but https://code.google.
| |
| 66 | 65 |
| 67 // At the time being, progressive encoding is only applicable to png image f ormat, | 66 // At the time being, progressive encoding is only applicable to png image f ormat, |
| 68 // and thus idle tasks scheduling can only be applied to png image format. | 67 // and thus idle tasks scheduling can only be applied to png image format. |
| 69 // TODO(xlai): Progressive encoding on jpeg and webp image formats (crbug.co m/571398, crbug.com/571399) | 68 // TODO(xlai): Progressive encoding on jpeg and webp image formats (crbug.co m/571398, crbug.com/571399) |
| 70 if (canUseIdlePeriodScheduling) { | 69 if (canUseIdlePeriodScheduling) { |
| 71 ASSERT(m_mimeType == "image/png"); | 70 ASSERT(m_mimeType == "image/png"); |
| 72 Platform::current()->mainThread()->scheduler()->postIdleTask(BLINK_FROM_ HERE, bind<double>(&CanvasAsyncBlobCreator::initiatePngEncoding, this)); | 71 Platform::current()->mainThread()->scheduler()->postIdleTask(BLINK_FROM_ HERE, bind<double>(&CanvasAsyncBlobCreator::initiatePngEncoding, this)); |
| 73 } else if (m_mimeType == "image/jpeg") { | 72 } else if (m_mimeType == "image/jpeg") { |
| 74 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&CanvasAsyncBlobCreator::initiateJpegEncoding, this, quality)); | 73 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&CanvasAsyncBlobCreator::initiateJpegEncoding, this, quality)); |
| 75 } else { | 74 } else { |
| 76 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa sk : BackgroundTaskRunner::TaskSizeShortRunningTask; | 75 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.widt h() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTa sk : BackgroundTaskRunner::TaskSizeShortRunningTask; |
| 77 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess (this), quality), taskSize); | 76 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafe Bind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess (this), quality), taskSize); |
| 78 } | 77 } |
| 79 } | 78 } |
| 80 | 79 |
| 81 void CanvasAsyncBlobCreator::initiateJpegEncoding(const double& quality) | 80 void CanvasAsyncBlobCreator::initiateJpegEncoding(const double& quality) |
| 82 { | 81 { |
| 83 m_jpegEncoderState = JPEGImageEncoderState::create(m_size, quality, m_encode dImage.get()); | 82 m_jpegEncoderState = JPEGImageEncoderState::create(m_size, quality, m_encode dImage.get()); |
| 84 if (!m_jpegEncoderState) { | 83 if (!m_jpegEncoderState) { |
| 85 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); | 84 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); |
| 86 m_selfRef.clear(); | 85 m_keepAlive.clear(); |
| 87 return; | 86 return; |
| 88 } | 87 } |
| 89 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.width() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTask : BackgroundTaskRunner::TaskSizeShortRunningTask; | 88 BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.width() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTask : BackgroundTaskRunner::TaskSizeShortRunningTask; |
| 90 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind (&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess(thi s), quality), taskSize); | 89 BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind (&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess(thi s), quality), taskSize); |
| 91 } | 90 } |
| 92 | 91 |
| 93 void CanvasAsyncBlobCreator::initiatePngEncoding(double deadlineSeconds) | 92 void CanvasAsyncBlobCreator::initiatePngEncoding(double deadlineSeconds) |
| 94 { | 93 { |
| 95 ASSERT(isMainThread()); | 94 ASSERT(isMainThread()); |
| 96 m_pngEncoderState = PNGImageEncoderState::create(m_size, m_encodedImage.get( )); | 95 m_pngEncoderState = PNGImageEncoderState::create(m_size, m_encodedImage.get( )); |
| 97 if (!m_pngEncoderState) { | 96 if (!m_pngEncoderState) { |
| 98 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); | 97 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FR OM_HERE, bind(&BlobCallback::handleEvent, m_callback, nullptr)); |
| 99 m_selfRef.clear(); | 98 m_keepAlive.clear(); |
| 100 return; | 99 return; |
| 101 } | 100 } |
| 102 | 101 |
| 103 CanvasAsyncBlobCreator::idleEncodeRowsPng(deadlineSeconds); | 102 CanvasAsyncBlobCreator::idleEncodeRowsPng(deadlineSeconds); |
| 104 } | 103 } |
| 105 | 104 |
| 106 void CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng() | 105 void CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng() |
| 107 { | 106 { |
| 108 ASSERT(isMainThread()); | 107 ASSERT(isMainThread()); |
| 109 Platform::current()->currentThread()->scheduler()->postIdleTask(BLINK_FROM_H ERE, WTF::bind<double>(&CanvasAsyncBlobCreator::idleEncodeRowsPng, this)); | 108 Platform::current()->currentThread()->scheduler()->postIdleTask(BLINK_FROM_H ERE, WTF::bind<double>(&CanvasAsyncBlobCreator::idleEncodeRowsPng, this)); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 } | 156 } |
| 158 | 157 |
| 159 scheduleCreateBlobAndCallOnMainThread(); | 158 scheduleCreateBlobAndCallOnMainThread(); |
| 160 } | 159 } |
| 161 | 160 |
| 162 void CanvasAsyncBlobCreator::clearSelfReference() | 161 void CanvasAsyncBlobCreator::clearSelfReference() |
| 163 { | 162 { |
| 164 // Some persistent members in CanvasAsyncBlobCreator can only be destroyed | 163 // Some persistent members in CanvasAsyncBlobCreator can only be destroyed |
| 165 // on the thread that creates them. In this case, it's the main thread. | 164 // on the thread that creates them. In this case, it's the main thread. |
| 166 ASSERT(isMainThread()); | 165 ASSERT(isMainThread()); |
| 167 m_selfRef.clear(); | 166 m_keepAlive.clear(); |
| 168 } | 167 } |
| 169 | 168 |
| 170 void CanvasAsyncBlobCreator::scheduleCreateBlobAndCallOnMainThread() | 169 void CanvasAsyncBlobCreator::scheduleCreateBlobAndCallOnMainThread() |
| 171 { | 170 { |
| 172 ASSERT(!isMainThread()); | 171 ASSERT(!isMainThread()); |
| 173 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&CanvasAsyncBlobCreator::createBlobAndCall, AllowCrossThread Access(this))); | 172 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&CanvasAsyncBlobCreator::createBlobAndCall, AllowCrossThread Access(this))); |
| 174 } | 173 } |
| 175 | 174 |
| 176 void CanvasAsyncBlobCreator::scheduleCreateNullptrAndCallOnMainThread() | 175 void CanvasAsyncBlobCreator::scheduleCreateNullptrAndCallOnMainThread() |
| 177 { | 176 { |
| 178 ASSERT(!isMainThread()); | 177 ASSERT(!isMainThread()); |
| 179 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&BlobCallback::handleEvent, m_callback.get(), nullptr)); | 178 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&BlobCallback::handleEvent, m_callback.get(), nullptr)); |
| 180 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThrea dAccess(this))); | 179 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_H ERE, threadSafeBind(&CanvasAsyncBlobCreator::clearSelfReference, AllowCrossThrea dAccess(this))); |
| 181 } | 180 } |
| 182 | 181 |
| 183 } // namespace blink | 182 } // namespace blink |
| OLD | NEW |