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 |