summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/WebKit')
-rw-r--r--third_party/WebKit/LayoutTests/VirtualTestSuites5
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng-expected.txt (renamed from third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng-expected.txt)0
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng.html (renamed from third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng.html)2
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt (renamed from third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt)0
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png.html (renamed from third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html)4
-rw-r--r--third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp6
-rw-r--r--third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp62
-rw-r--r--third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h6
8 files changed, 77 insertions, 8 deletions
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index 6c191d5..48c7271 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -12,6 +12,11 @@
},
{
"prefix": "threaded",
+ "base": "fast/canvas/toBlob",
+ "args": ["--enable-threaded-compositing"]
+ },
+ {
+ "prefix": "threaded",
"base": "compositing/visibility",
"args": ["--enable-threaded-compositing"]
},
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng-expected.txt
index fed3498..fed3498 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng.html b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng.html
index 14cab66..c68d3ea 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-defaultpng.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-defaultpng.html
@@ -1,4 +1,4 @@
-<script src = "../../resources/js-test.js"></script>
+<script src = "../../../resources/js-test.js"></script>
<script type = 'text/javascript'>
jsTestIsAsync = true;
description("Test that verifies whether the image data survives the toBlob process after async image encoding");
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt
index ac789eb..ac789eb 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png.html
index 3bbcaa7..806cc27 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/toBlob/canvas-toBlob-toDataURL-race-imageEncoder-png.html
@@ -1,5 +1,5 @@
-<script src = "../../resources/js-test.js"></script>
-<script src = "script-tests/canvas-toBlob-toDataURL-race.js"></script>
+<script src = "../../../resources/js-test.js"></script>
+<script src = "../script-tests/canvas-toBlob-toDataURL-race.js"></script>
<script type = 'text/javascript'>
description("Verifies if synchronous PNG image encoding (toDataURL) conflicts with asynchronous image encoding (toBlob)");
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 6fa3c4b..2b554b5 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -611,7 +611,11 @@ void HTMLCanvasElement::toBlob(ScriptState* scriptState, BlobCallback* callback,
RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::create(imageDataRef.release(), encodingMimeType, imageData->size(), callback, scriptState->executionContext());
- asyncCreatorRef->scheduleAsyncBlobCreation(quality);
+ if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType == DefaultMimeType)) {
+ asyncCreatorRef->scheduleAsyncBlobCreation(true);
+ } else {
+ asyncCreatorRef->scheduleAsyncBlobCreation(false, quality);
+ }
}
void HTMLCanvasElement::addListener(CanvasDrawListener* listener)
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
index d2fb12d..3f7d29e 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -13,15 +13,27 @@
#include "platform/image-encoders/skia/PNGImageEncoder.h"
#include "platform/threading/BackgroundTaskRunner.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebScheduler.h"
+#include "public/platform/WebTaskRunner.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebTraceLocation.h"
#include "wtf/Functional.h"
namespace blink {
+namespace {
+
+const double SlackBeforeDeadline = 0.001; // a small slack period between deadline and current time for safety
const int NumChannelsPng = 4;
const int LongTaskImageSizeThreshold = 1000 * 1000; // The max image size we expect to encode in 14ms on Linux in PNG format
+bool isDeadlineNearOrPassed(double deadlineSeconds)
+{
+ return (deadlineSeconds - SlackBeforeDeadline - Platform::current()->monotonicallyIncreasingTimeSeconds() <= 0);
+}
+
+} // anonymous namespace
+
class CanvasAsyncBlobCreator::ContextObserver final : public NoBaseWillBeGarbageCollected<CanvasAsyncBlobCreator::ContextObserver>, public ContextLifecycleObserver {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(CanvasAsyncBlobCreator::ContextObserver);
public:
@@ -88,7 +100,7 @@ DEFINE_TRACE(CanvasAsyncBlobCreator::ContextObserver)
ContextLifecycleObserver::trace(visitor);
}
-void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(double quality)
+void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(bool canUseIdlePeriodScheduling, double quality)
{
// TODO: async blob creation should be supported in worker_pool threads as well. but right now blink does not have that
ASSERT(isMainThread());
@@ -96,8 +108,52 @@ void CanvasAsyncBlobCreator::scheduleAsyncBlobCreation(double quality)
// Make self-reference to keep this object alive until the final task completes
m_selfRef = this;
- BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.width() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTask : BackgroundTaskRunner::TaskSizeShortRunningTask;
- BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess(this), quality), taskSize);
+ if (canUseIdlePeriodScheduling) {
+ ASSERT(m_mimeType == "image/png");
+ Platform::current()->mainThread()->scheduler()->postIdleTask(BLINK_FROM_HERE, WTF::bind<double>(&CanvasAsyncBlobCreator::initiatePngEncoding, this));
+ } else {
+ BackgroundTaskRunner::TaskSize taskSize = (m_size.height() * m_size.width() >= LongTaskImageSizeThreshold) ? BackgroundTaskRunner::TaskSizeLongRunningTask : BackgroundTaskRunner::TaskSizeShortRunningTask;
+ BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind(&CanvasAsyncBlobCreator::encodeImageOnEncoderThread, AllowCrossThreadAccess(this), quality), taskSize);
+ }
+}
+
+void CanvasAsyncBlobCreator::initiatePngEncoding(double deadlineSeconds)
+{
+ m_encoderState = PNGImageEncoderState::create(m_size, m_encodedImage.get());
+ if (!m_encoderState) {
+ Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, bind(&BlobCallback::handleEvent, m_callback, nullptr));
+ m_selfRef.clear();
+ return;
+ }
+
+ CanvasAsyncBlobCreator::idleEncodeRowsPng(deadlineSeconds);
+}
+
+void CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng()
+{
+ Platform::current()->currentThread()->scheduler()->postIdleTask(BLINK_FROM_HERE, WTF::bind<double>(&CanvasAsyncBlobCreator::idleEncodeRowsPng, this));
+}
+
+void CanvasAsyncBlobCreator::idleEncodeRowsPng(double deadlineSeconds)
+{
+ unsigned char* inputPixels = m_data->data() + m_pixelRowStride * m_numRowsCompleted;
+ for (int y = m_numRowsCompleted; y < m_size.height(); ++y) {
+ if (isDeadlineNearOrPassed(deadlineSeconds)) {
+ m_numRowsCompleted = y;
+ CanvasAsyncBlobCreator::scheduleIdleEncodeRowsPng();
+ return;
+ }
+ PNGImageEncoder::writeOneRowToPng(inputPixels, m_encoderState.get());
+ inputPixels += m_pixelRowStride;
+ }
+ m_numRowsCompleted = m_size.height();
+ PNGImageEncoder::finalizePng(m_encoderState.get());
+
+ if (isDeadlineNearOrPassed(deadlineSeconds)) {
+ Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, bind(&CanvasAsyncBlobCreator::createBlobAndCall, this));
+ } else {
+ this->createBlobAndCall();
+ }
}
void CanvasAsyncBlobCreator::createBlobAndCall()
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
index ccda72a..d06a843 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.h
@@ -21,7 +21,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
: public RefCounted<CanvasAsyncBlobCreator> {
public:
static PassRefPtr<CanvasAsyncBlobCreator> create(PassRefPtr<DOMUint8ClampedArray> unpremultipliedRGBAImageData, const String& mimeType, const IntSize&, BlobCallback*, ExecutionContext*);
- void scheduleAsyncBlobCreation(double quality = 0.0);
+ void scheduleAsyncBlobCreation(bool canUseIdlePeriodScheduling, double quality = 0.0);
virtual ~CanvasAsyncBlobCreator();
protected:
@@ -47,6 +47,10 @@ private:
RefPtr<CanvasAsyncBlobCreator> m_selfRef;
void clearSelfReference();
+ void initiatePngEncoding(double deadlineSeconds);
+ void scheduleIdleEncodeRowsPng();
+ void idleEncodeRowsPng(double deadlineSeconds);
+
void createBlobAndCall();
void encodeImageOnEncoderThread(double quality);