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 |