summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjunov <junov@chromium.org>2016-03-14 15:10:19 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-14 22:11:22 +0000
commit3e81032f06d758c0e79fec2158f1b928f3487036 (patch)
treeefb98bb393157b469a46ad3f97b64b8c9503a89b
parentcb3cc25f0064533ad7f1480cc4b0b39675521c61 (diff)
downloadchromium_src-3e81032f06d758c0e79fec2158f1b928f3487036.zip
chromium_src-3e81032f06d758c0e79fec2158f1b928f3487036.tar.gz
chromium_src-3e81032f06d758c0e79fec2158f1b928f3487036.tar.bz2
Make OffscreenCanvasRenderingContext2D renderable on a worker
This change makes 2D contexts renderable on workers. It only implements the bare minimum interfaces required to draw rectangles on a worker and bring the results to screen via ImageBitmap transfer. The new Web APIs that are implemented are: * OffscreenCanvasRendering2D.fillStyle * OffscreenCanvasRendering2D.strokeStyle * OffscreenCanvasRendering2D.fillRect * OffscreenCanvasRendering2D.strokeRect * OffscreenCanvasRendering2D.clearRect * OffscreenCanvas.transferToImageBitmap BUG=563856, 563832 Review URL: https://codereview.chromium.org/1775153002 Cr-Commit-Position: refs/heads/master@{#381085}
-rw-r--r--third_party/WebKit/LayoutTests/TestExpectations3
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker-expected.html13
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker.html37
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor-expected.txt11
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor.html17
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker-expected.html6
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker.html33
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker-expected.html12
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker.html33
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap-expected.txt16
-rw-r--r--third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap.html41
-rw-r--r--third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt8
-rw-r--r--third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt8
-rw-r--r--third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt8
-rw-r--r--third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt8
-rw-r--r--third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp2
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp30
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h9
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl3
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h3
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp79
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h4
-rw-r--r--third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl9
23 files changed, 356 insertions, 37 deletions
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index baf5e5e..bd9efe7 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -115,6 +115,9 @@ crbug.com/539226 http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-c
crbug.com/539226 [ Win ] http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-redirect-response-handling.html [ Timeout Pass ]
crbug.com/539226 [ Win ] http/tests/xmlhttprequest/open-in-body-onload-sync-to-invalid-preflight-handling.html [ Timeout Pass ]
+# Expected to fail until OffscreenCanvas can render on the gpu
+crbug.com/593514 virtual/gpu/fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Failure ]
+
crbug.com/417782 [ Linux Win ] virtual/rootlayerscrolls/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ]
crbug.com/492664 [ Linux ] imported/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vlr-005.xht [ Failure ]
crbug.com/492664 [ Linux ] imported/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vrl-004.xht [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker-expected.html
new file mode 100644
index 0000000..a2fcc69
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker-expected.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100'></canvas>
+<script>
+var aCanvas = document.getElementById('output');
+var ctx = aCanvas.getContext('2d');
+ctx.fillStyle = 'green';
+ctx.fillRect(20, 20, 60, 60);
+ctx.clearRect(25, 25, 50, 50);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker.html
new file mode 100644
index 0000000..392fcdf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-clearRect-in-worker.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100'></canvas>
+
+<script id='myWorker' type='text/worker'>
+self.onmessage = function(e) {
+ var aCanvas = new OffscreenCanvas(100, 100);
+ var ctx = aCanvas.getContext('2d');
+ ctx.fillStyle = 'green';
+ ctx.fillRect(20, 20, 60, 60);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(25, 25, 50, 50);
+ // No red should be visible after this
+ ctx.clearRect(25, 25, 50, 50);
+ var image = aCanvas.transferToImageBitmap();
+ self.postMessage(image, [image]);
+};
+</script>
+
+<script>
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+}
+var blob = new Blob([document.getElementById('myWorker').textContent]);
+var worker = new Worker(URL.createObjectURL(blob));
+worker.addEventListener('message', msg => {
+ var outputCtx = document.getElementById('output').getContext('imagebitmap');
+ outputCtx.transferImageBitmap(msg.data);
+ if (window.testRunner) {
+ testRunner.notifyDone();
+ }
+});
+worker.postMessage("");
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor-expected.txt
new file mode 100644
index 0000000..958372d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor-expected.txt
@@ -0,0 +1,11 @@
+Test that the fill and stroke style attribute yield opaque black when set to 'currentcolor' on an OffscreenCanvasRenderingContext2D
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS ctx.fillStyle is '#000000'
+PASS ctx.strokeStyle is '#000000'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor.html
new file mode 100644
index 0000000..b530d522
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-currentColor.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Test that the fill and stroke style attribute yield opaque black when set to 'currentcolor' on an OffscreenCanvasRenderingContext2D");
+
+// Tests onstructor of OffscreenCanvas and length/width change
+var aCanvas = new OffscreenCanvas(50, 50);
+var ctx = aCanvas.getContext('2d');
+ctx.fillStyle = 'red';
+ctx.fillStyle = 'currentcolor'
+shouldBe("ctx.fillStyle", "'#000000'");
+
+ctx.strokeStyle = 'red';
+ctx.strokeStyle = 'currentcolor'
+shouldBe("ctx.strokeStyle", "'#000000'");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker-expected.html
new file mode 100644
index 0000000..b0b5cd2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker-expected.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100' style='background:green'></canvas>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker.html
new file mode 100644
index 0000000..08a110f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-fillRect-in-worker.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100' style='background:red'></canvas>
+
+<script id='myWorker' type='text/worker'>
+self.onmessage = function(e) {
+ var aCanvas = new OffscreenCanvas(100, 100);
+ var ctx = aCanvas.getContext('2d');
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+ var image = aCanvas.transferToImageBitmap();
+ self.postMessage(image, [image]);
+};
+</script>
+
+<script>
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+}
+var blob = new Blob([document.getElementById('myWorker').textContent]);
+var worker = new Worker(URL.createObjectURL(blob));
+worker.addEventListener('message', msg => {
+ var outputCtx = document.getElementById('output').getContext('imagebitmap');
+ outputCtx.transferImageBitmap(msg.data);
+ if (window.testRunner) {
+ testRunner.notifyDone();
+ }
+});
+worker.postMessage("");
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker-expected.html
new file mode 100644
index 0000000..120af09
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker-expected.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100'></canvas>
+<script>
+var aCanvas = document.getElementById('output');
+var ctx = aCanvas.getContext('2d');
+ctx.strokeStyle = 'green';
+ctx.strokeRect(25, 25, 50, 50);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker.html
new file mode 100644
index 0000000..aa8324af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-strokeRect-in-worker.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<body>
+<canvas id='output' width='100' height='100'></canvas>
+
+<script id='myWorker' type='text/worker'>
+self.onmessage = function(e) {
+ var aCanvas = new OffscreenCanvas(100, 100);
+ var ctx = aCanvas.getContext('2d');
+ ctx.strokeStyle = 'green';
+ ctx.strokeRect(25, 25, 50, 50);
+ var image = aCanvas.transferToImageBitmap();
+ self.postMessage(image, [image]);
+};
+</script>
+
+<script>
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+}
+var blob = new Blob([document.getElementById('myWorker').textContent]);
+var worker = new Worker(URL.createObjectURL(blob));
+worker.addEventListener('message', msg => {
+ var outputCtx = document.getElementById('output').getContext('imagebitmap');
+ outputCtx.transferImageBitmap(msg.data);
+ if (window.testRunner) {
+ testRunner.notifyDone();
+ }
+});
+worker.postMessage("");
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap-expected.txt
new file mode 100644
index 0000000..4b61f00
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap-expected.txt
@@ -0,0 +1,16 @@
+PASS aCanvas.transferToImageBitmap() threw exception InvalidStateError: Failed to execute 'transferToImageBitmap' on 'OffscreenCanvas': Cannot transfer an ImageBitmap from an OffscreenCanvas with no context.
+PASS image.width is 60
+PASS image.height is 40
+PASS ctx.lineWidth is 5
+PASS imgData[0] is 255
+PASS imgData[1] is 0
+PASS imgData[2] is 0
+PASS imgData[3] is 255
+PASS imgData[0] is 0
+PASS imgData[1] is 0
+PASS imgData[2] is 0
+PASS imgData[3] is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap.html
new file mode 100644
index 0000000..c0bc6ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-transferToImageBitmap.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<script>
+var aCanvas = new OffscreenCanvas(60, 40);
+
+// TransferToImageBitmap on an OffscreenCanvas with no context
+shouldThrow("aCanvas.transferToImageBitmap()");
+ctx = aCanvas.getContext('2d');
+
+// Verify ImageBitmap is correctly sized
+var image = aCanvas.transferToImageBitmap();
+shouldBe("image.width", "60");
+shouldBe("image.height", "40");
+
+// Verify state is preserved through transferToImageBitmap()
+ctx.lineWidth = 5;
+aCanvas.transferToImageBitmap();
+shouldBe("ctx.lineWidth", "5");
+
+// Verify backing is reset through transferToImageBitmap()
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, aCanvas.width, aCanvas.height);
+var firstImage = aCanvas.transferToImageBitmap();
+var secondImage = aCanvas.transferToImageBitmap();
+var testCanvas = document.createElement('canvas');
+var testCtx = testCanvas.getContext('2d');
+testCtx.drawImage(firstImage, 0, 0);
+var imgData = testCtx.getImageData(0, 0, 1, 1).data;
+shouldBe("imgData[0]", "255");
+shouldBe("imgData[1]", "0");
+shouldBe("imgData[2]", "0");
+shouldBe("imgData[3]", "255");
+testCtx.clearRect(0, 0, testCanvas.width, testCanvas.height);
+testCtx.drawImage(secondImage, 0, 0);
+imgData = testCtx.getImageData(0, 0, 1, 1).data;
+shouldBe("imgData[0]", "0");
+shouldBe("imgData[1]", "0");
+shouldBe("imgData[2]", "0");
+shouldBe("imgData[3]", "0");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 7890480..f0ed794 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -477,20 +477,28 @@ interface OffscreenCanvas
getter width
method constructor
method getContext
+ method transferToImageBitmap
setter height
setter width
interface OffscreenCanvasRenderingContext2D
+ getter fillStyle
getter offscreenCanvas
+ getter strokeStyle
method arc
method arcTo
method bezierCurveTo
+ method clearRect
method closePath
method constructor
method ellipse
+ method fillRect
method lineTo
method moveTo
method quadraticCurveTo
method rect
+ method strokeRect
+ setter fillStyle
+ setter strokeStyle
interface PerformanceObserverEntryList
method constructor
method getEntries
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 6206ef4..ecf1b96 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -495,21 +495,29 @@ Starting worker: resources/global-interface-listing.js
[Worker] getter width
[Worker] method constructor
[Worker] method getContext
+[Worker] method transferToImageBitmap
[Worker] setter height
[Worker] setter width
[Worker] interface OffscreenCanvasRenderingContext2D
[Worker] attribute @@toStringTag
+[Worker] getter fillStyle
[Worker] getter offscreenCanvas
+[Worker] getter strokeStyle
[Worker] method arc
[Worker] method arcTo
[Worker] method bezierCurveTo
+[Worker] method clearRect
[Worker] method closePath
[Worker] method constructor
[Worker] method ellipse
+[Worker] method fillRect
[Worker] method lineTo
[Worker] method moveTo
[Worker] method quadraticCurveTo
[Worker] method rect
+[Worker] method strokeRect
+[Worker] setter fillStyle
+[Worker] setter strokeStyle
[Worker] interface PerformanceObserverEntryList
[Worker] attribute @@toStringTag
[Worker] method constructor
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 3b93cdb..bf639ce 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3996,21 +3996,29 @@ interface OffscreenCanvas
getter width
method constructor
method getContext
+ method transferToImageBitmap
setter height
setter width
interface OffscreenCanvasRenderingContext2D
attribute @@toStringTag
+ getter fillStyle
getter offscreenCanvas
+ getter strokeStyle
method arc
method arcTo
method bezierCurveTo
+ method clearRect
method closePath
method constructor
method ellipse
+ method fillRect
method lineTo
method moveTo
method quadraticCurveTo
method rect
+ method strokeRect
+ setter fillStyle
+ setter strokeStyle
interface Option
method constructor
interface OscillatorNode : AudioSourceNode
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 6c706db..55ec6ed 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -482,21 +482,29 @@ Starting worker: resources/global-interface-listing.js
[Worker] getter width
[Worker] method constructor
[Worker] method getContext
+[Worker] method transferToImageBitmap
[Worker] setter height
[Worker] setter width
[Worker] interface OffscreenCanvasRenderingContext2D
[Worker] attribute @@toStringTag
+[Worker] getter fillStyle
[Worker] getter offscreenCanvas
+[Worker] getter strokeStyle
[Worker] method arc
[Worker] method arcTo
[Worker] method bezierCurveTo
+[Worker] method clearRect
[Worker] method closePath
[Worker] method constructor
[Worker] method ellipse
+[Worker] method fillRect
[Worker] method lineTo
[Worker] method moveTo
[Worker] method quadraticCurveTo
[Worker] method rect
+[Worker] method strokeRect
+[Worker] setter fillStyle
+[Worker] setter strokeStyle
[Worker] interface PerformanceObserverEntryList
[Worker] attribute @@toStringTag
[Worker] method constructor
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
index ac378f1..d7f716a 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
@@ -69,7 +69,7 @@ bool parseColorOrCurrentColor(Color& parsedColor, const String& colorString, HTM
case ParsedSystemColor:
return true;
case ParsedCurrentColor:
- parsedColor = currentColor(canvas);
+ parsedColor = canvas ? currentColor(canvas) : Color::black;
return true;
case ParseFailed:
return false;
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp
index df10393..d63ae11 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.cpp
@@ -4,6 +4,10 @@
#include "modules/offscreencanvas/OffscreenCanvas.h"
+#include "core/dom/ExceptionCode.h"
+#if !ENABLE(OILPAN)
+#include "core/frame/ImageBitmap.h" // So ~RefPtr can call unref()
+#endif
#include "core/html/canvas/CanvasContextCreationAttributes.h"
#include "modules/offscreencanvas/OffscreenCanvasRenderingContext.h"
#include "modules/offscreencanvas/OffscreenCanvasRenderingContextFactory.h"
@@ -12,6 +16,13 @@
namespace blink {
+OffscreenCanvas::OffscreenCanvas(const IntSize& size)
+ : m_size(size)
+{ }
+
+OffscreenCanvas::~OffscreenCanvas()
+{ }
+
OffscreenCanvas* OffscreenCanvas::create(unsigned width, unsigned height)
{
return new OffscreenCanvas(IntSize(clampTo<int>(width), clampTo<int>(height)));
@@ -27,11 +38,6 @@ void OffscreenCanvas::setHeight(unsigned height)
m_size.setHeight(clampTo<int>(height));
}
-OffscreenCanvas::OffscreenCanvas(const IntSize& size)
- : m_size(size)
-{
-}
-
OffscreenCanvasRenderingContext2D* OffscreenCanvas::getContext(const String& id, const CanvasContextCreationAttributes& attributes)
{
OffscreenCanvasRenderingContext::ContextType contextType = OffscreenCanvasRenderingContext::contextTypeFromId(id);
@@ -59,6 +65,20 @@ OffscreenCanvasRenderingContext2D* OffscreenCanvas::getContext(const String& id,
return static_cast<OffscreenCanvasRenderingContext2D*>(m_context.get());
}
+PassRefPtrWillBeRawPtr<ImageBitmap> OffscreenCanvas::transferToImageBitmap(ExceptionState& exceptionState)
+{
+ if (!m_context) {
+ exceptionState.throwDOMException(InvalidStateError, "Cannot transfer an ImageBitmap from an OffscreenCanvas with no context");
+ return nullptr;
+ }
+ RefPtrWillBeRawPtr<ImageBitmap> image = m_context->transferToImageBitmap(exceptionState);
+ if (!image) {
+ // Undocumented exception (not in spec)
+ exceptionState.throwDOMException(V8GeneralError, "Out of memory");
+ }
+ return image.release();
+}
+
OffscreenCanvasRenderingContext2D* OffscreenCanvas::renderingContext() const
{
// TODO: When there're more than one context type implemented in the future,
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h
index abfc419..0e2e957 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.h
@@ -15,6 +15,7 @@
namespace blink {
class CanvasContextCreationAttributes;
+class ImageBitmap;
class OffscreenCanvasRenderingContext;
class OffscreenCanvasRenderingContext2D;
class OffscreenCanvasRenderingContextFactory;
@@ -23,15 +24,19 @@ class MODULES_EXPORT OffscreenCanvas final : public GarbageCollectedFinalized<Of
DEFINE_WRAPPERTYPEINFO();
public:
static OffscreenCanvas* create(unsigned width, unsigned height);
- ~OffscreenCanvas() {}
+ ~OffscreenCanvas();
- IntSize size() const { return m_size; }
+ // IDL attributes
unsigned width() const { return m_size.width(); }
unsigned height() const { return m_size.height(); }
void setWidth(unsigned);
void setHeight(unsigned);
+ // API Methods
OffscreenCanvasRenderingContext2D* getContext(const String&, const CanvasContextCreationAttributes&);
+ PassRefPtrWillBeRawPtr<ImageBitmap> transferToImageBitmap(ExceptionState&);
+
+ IntSize size() const { return m_size; }
OffscreenCanvasRenderingContext2D* renderingContext() const;
static void registerRenderingContextFactory(PassOwnPtr<OffscreenCanvasRenderingContextFactory>);
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl
index b1436b0..91a95a4 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvas.idl
@@ -15,5 +15,6 @@ typedef OffscreenCanvasRenderingContext2D OffscreenRenderingContext;
[EnforceRange] attribute unsigned long width;
[EnforceRange] attribute unsigned long height;
- OffscreenRenderingContext? getContext(DOMString contextId, optional CanvasContextCreationAttributes attributes);
+ OffscreenRenderingContext? getContext(DOMString contextId, optional CanvasContextCreationAttributes attributes);
+ [RaisesException] ImageBitmap transferToImageBitmap();
};
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h
index 341baa7..ca3f222 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OffscreenCanvasRenderingContext.h
@@ -10,6 +10,8 @@
namespace blink {
+class ImageBitmap;
+
class MODULES_EXPORT OffscreenCanvasRenderingContext : public GarbageCollectedFinalized<OffscreenCanvasRenderingContext>, public ScriptWrappable {
WTF_MAKE_NONCOPYABLE(OffscreenCanvasRenderingContext);
public:
@@ -24,6 +26,7 @@ public:
OffscreenCanvas* getOffscreenCanvas() const { return m_offscreenCanvas; }
virtual ContextType getContextType() const = 0;
+ virtual PassRefPtrWillBeRawPtr<ImageBitmap> transferToImageBitmap(ExceptionState&) = 0;
virtual bool is2d() const { return false; }
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
index 769e0a2..9b0b81c 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -5,7 +5,10 @@
#include "modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h"
#include "bindings/modules/v8/UnionTypesModules.h"
+#include "core/frame/ImageBitmap.h"
#include "platform/NotImplemented.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "platform/graphics/StaticBitmapImage.h"
#include "wtf/Assertions.h"
#define UNIMPLEMENTED ASSERT_NOT_REACHED
@@ -31,13 +34,12 @@ DEFINE_TRACE(OffscreenCanvasRenderingContext2D)
// BaseRenderingContext2D implementation
bool OffscreenCanvasRenderingContext2D::originClean() const
{
- notImplemented();
- return true;
+ return m_originClean;
}
void OffscreenCanvasRenderingContext2D::setOriginTainted()
{
- notImplemented();
+ m_originClean = false;
}
bool OffscreenCanvasRenderingContext2D::wouldTaintOrigin(CanvasImageSource* source)
@@ -48,80 +50,101 @@ bool OffscreenCanvasRenderingContext2D::wouldTaintOrigin(CanvasImageSource* sour
int OffscreenCanvasRenderingContext2D::width() const
{
- return getOffscreenCanvas()->height();
+ return getOffscreenCanvas()->width();
}
int OffscreenCanvasRenderingContext2D::height() const
{
- return getOffscreenCanvas()->width();
+ return getOffscreenCanvas()->height();
}
bool OffscreenCanvasRenderingContext2D::hasImageBuffer() const
{
- notImplemented();
- return false;
+ return !!m_imageBuffer;
}
ImageBuffer* OffscreenCanvasRenderingContext2D::imageBuffer() const
{
- notImplemented();
- return nullptr;
+ if (!m_imageBuffer) {
+ // TODO: crbug.com/593514 Add support for GPU rendering
+ OffscreenCanvasRenderingContext2D* nonConstThis = const_cast<OffscreenCanvasRenderingContext2D*>(this);
+ nonConstThis->m_imageBuffer = ImageBuffer::create(IntSize(width(), height()), m_hasAlpha ? NonOpaque : Opaque, InitializeImagePixels);
+ // TODO: crbug.com/593349 Restore matrix and clip state on the new ImageBuffer.
+ }
+
+ return m_imageBuffer.get();
}
-bool OffscreenCanvasRenderingContext2D::parseColorOrCurrentColor(Color&, const String& colorString) const
+PassRefPtrWillBeRawPtr<ImageBitmap> OffscreenCanvasRenderingContext2D::transferToImageBitmap(ExceptionState& exceptionState)
{
- notImplemented();
- return false;
+ if (!imageBuffer())
+ return nullptr;
+ // TODO: crbug.com/593514 Add support for GPU rendering
+ RefPtr<SkImage> skImage = m_imageBuffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
+ RefPtr<StaticBitmapImage> image = StaticBitmapImage::create(skImage.release());
+ m_imageBuffer.clear(); // "Transfer" means no retained buffer
+ return ImageBitmap::create(image.release());
+}
+
+bool OffscreenCanvasRenderingContext2D::parseColorOrCurrentColor(Color& color, const String& colorString) const
+{
+ return ::blink::parseColorOrCurrentColor(color, colorString, nullptr);
}
SkCanvas* OffscreenCanvasRenderingContext2D::drawingCanvas() const
{
- notImplemented();
- return nullptr;
+ ImageBuffer* buffer = imageBuffer();
+ if (!buffer)
+ return nullptr;
+ return imageBuffer()->canvas();
}
SkCanvas* OffscreenCanvasRenderingContext2D::existingDrawingCanvas() const
{
- notImplemented();
- return nullptr;
+ if (!m_imageBuffer)
+ return nullptr;
+ return m_imageBuffer->canvas();
}
void OffscreenCanvasRenderingContext2D::disableDeferral(DisableDeferralReason)
-{
- notImplemented();
-}
+{ }
AffineTransform OffscreenCanvasRenderingContext2D::baseTransform() const
{
- notImplemented();
- return 0;
+ if (!m_imageBuffer)
+ return AffineTransform(); // identity
+ return m_imageBuffer->baseTransform();
}
void OffscreenCanvasRenderingContext2D::didDraw(const SkIRect& dirtyRect)
-{
- notImplemented();
-}
+{ }
bool OffscreenCanvasRenderingContext2D::stateHasFilter()
{
- notImplemented();
+ // TODO: crbug.com/593838 make hasFilter accept nullptr
+ // return state().hasFilter(nullptr, nullptr, IntSize(width(), height()), this);
return false;
}
SkImageFilter* OffscreenCanvasRenderingContext2D::stateGetFilter()
{
- notImplemented();
+ // TODO: make getFilter accept nullptr
+ // return state().getFilter(nullptr, nullptr, IntSize(width(), height()), this);
return nullptr;
}
void OffscreenCanvasRenderingContext2D::validateStateStack()
{
- notImplemented();
+#if ENABLE(ASSERT)
+ SkCanvas* skCanvas = existingDrawingCanvas();
+ if (skCanvas) {
+ ASSERT(static_cast<size_t>(skCanvas->getSaveCount()) == m_stateStack.size());
+ }
+#endif
}
bool OffscreenCanvasRenderingContext2D::isContextLost() const
{
- notImplemented();
return false;
}
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
index defa199..0eb2cf9 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -67,12 +67,16 @@ public:
bool hasAlpha() const override { return m_hasAlpha; }
bool isContextLost() const override;
+ PassRefPtrWillBeRawPtr<ImageBitmap> transferToImageBitmap(ExceptionState&) final;
+
protected:
OffscreenCanvasRenderingContext2D(OffscreenCanvas*, const CanvasContextCreationAttributes& attrs);
DECLARE_VIRTUAL_TRACE();
private:
bool m_hasAlpha;
+ bool m_originClean = true;
+ OwnPtr<ImageBuffer> m_imageBuffer;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
index 88cee00..29a3d06 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
@@ -11,6 +11,15 @@
] interface OffscreenCanvasRenderingContext2D {
// back-reference to the canvas
[ImplementedAs=getOffscreenCanvas] readonly attribute OffscreenCanvas offscreenCanvas;
+
+ // colors and styles (see also the CanvasDrawingStyles interface)
+ attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
+ attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black)
+
+ //CanvasRect interface
+ void clearRect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height);
+ void fillRect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height);
+ void strokeRect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height);
};
OffscreenCanvasRenderingContext2D implements CanvasPathMethods;