Skip to content

Commit ecf58b2

Browse files
graveljpmoz-wptsync-bot
authored andcommitted
Bug 1860278 [wpt PR 42662] - Throw an exception in putImageData if canvas layers are opened, a=testonly
Automatic update from web-platform-tests Throw an exception in putImageData if canvas layers are opened This API is incompatible with how the 2D canvas is rasterized when it contains unclosed layers. Because layers can have filters that get applied on their final content, they can't be presented until they are closed. Instead, we normally keep the layer content alive after a flush, so that it can be presented in a later frame when the layer is finally closed. putImageData however is supposed to write to the canvas bitmap wholesale, bypassing all render states. This means that we can't write to the layer's content because the written pixels would then get filtered when the layer is closed. We can't write to the main canvas either because these pixels would later be overwritten by the layer's result with draw calls that potentially happened before (e.g. in the sequence `beginLayer(); fillRect(); putImageData(); endLayer();`, `fillRect()` would write over `putImageData()`. This behavior is part of the current 2D Canvas Layer spec draft: Explainer: https://github.com/fserb/canvas2D/blob/master/spec/layers.md Spec draft: whatwg/html#9537 Change-Id: I266a3155c32919a68dbbb093e4aff9b1dd13a3b5 Bug: 1484741 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4943172 Reviewed-by: Fernando Serboncini <[email protected]> Commit-Queue: Jean-Philippe Gravel <[email protected]> Cr-Commit-Position: refs/heads/main@{#1212741} -- wpt-commits: 6e6f9fbb0746983001d7fe80ab717567c2f73bfc wpt-pr: 42662
1 parent af724d8 commit ecf58b2

9 files changed

+116
-191
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
3+
<title>Canvas test: 2d.layer.putImageData</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/html/canvas/resources/canvas-tests.js"></script>
7+
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
8+
<body class="show_output">
9+
10+
<h1>2d.layer.putImageData</h1>
11+
<p class="desc">Check that calling putImageData in a layer throws an exception.</p>
12+
13+
14+
<p class="output">Actual output:</p>
15+
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
16+
17+
<ul id="d"></ul>
18+
<script>
19+
var t = async_test("Check that calling putImageData in a layer throws an exception.");
20+
_addTest(function(canvas, ctx) {
21+
22+
const canvas2 = new OffscreenCanvas(100, 50);
23+
const ctx2 = canvas2.getContext('2d')
24+
const data = ctx2.getImageData(0, 0, 1, 1);
25+
// `putImageData` shouldn't throw on it's own.
26+
ctx.putImageData(data, 0, 0);
27+
// Make sure the exception isn't caused by calling the function twice.
28+
ctx.putImageData(data, 0, 0);
29+
// Calling again inside a layer should throw.
30+
ctx.beginLayer();
31+
assert_throws_dom("InvalidStateError", () => ctx.putImageData(data, 0, 0));
32+
33+
});
34+
</script>
35+

testing/web-platform/tests/html/canvas/element/layers/2d.layer.render-opportunities.putImageData-expected.html

Lines changed: 0 additions & 32 deletions
This file was deleted.

testing/web-platform/tests/html/canvas/element/layers/2d.layer.render-opportunities.putImageData.html

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!DOCTYPE html>
2+
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
3+
<title>OffscreenCanvas test: 2d.layer.putImageData</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/html/canvas/resources/canvas-tests.js"></script>
7+
8+
<h1>2d.layer.putImageData</h1>
9+
<p class="desc">Check that calling putImageData in a layer throws an exception.</p>
10+
11+
12+
<script>
13+
var t = async_test("Check that calling putImageData in a layer throws an exception.");
14+
var t_pass = t.done.bind(t);
15+
var t_fail = t.step_func(function(reason) {
16+
throw reason;
17+
});
18+
t.step(function() {
19+
20+
var canvas = new OffscreenCanvas(100, 50);
21+
var ctx = canvas.getContext('2d');
22+
23+
const canvas2 = new OffscreenCanvas(100, 50);
24+
const ctx2 = canvas2.getContext('2d')
25+
const data = ctx2.getImageData(0, 0, 1, 1);
26+
// `putImageData` shouldn't throw on it's own.
27+
ctx.putImageData(data, 0, 0);
28+
// Make sure the exception isn't caused by calling the function twice.
29+
ctx.putImageData(data, 0, 0);
30+
// Calling again inside a layer should throw.
31+
ctx.beginLayer();
32+
assert_throws_dom("InvalidStateError", () => ctx.putImageData(data, 0, 0));
33+
t.done();
34+
35+
});
36+
</script>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
2+
// OffscreenCanvas test in a worker:2d.layer.putImageData
3+
// Description:Check that calling putImageData in a layer throws an exception.
4+
// Note:
5+
6+
importScripts("/resources/testharness.js");
7+
importScripts("/html/canvas/resources/canvas-tests.js");
8+
9+
var t = async_test("Check that calling putImageData in a layer throws an exception.");
10+
var t_pass = t.done.bind(t);
11+
var t_fail = t.step_func(function(reason) {
12+
throw reason;
13+
});
14+
t.step(function() {
15+
16+
var canvas = new OffscreenCanvas(100, 50);
17+
var ctx = canvas.getContext('2d');
18+
19+
const canvas2 = new OffscreenCanvas(100, 50);
20+
const ctx2 = canvas2.getContext('2d')
21+
const data = ctx2.getImageData(0, 0, 1, 1);
22+
// `putImageData` shouldn't throw on it's own.
23+
ctx.putImageData(data, 0, 0);
24+
// Make sure the exception isn't caused by calling the function twice.
25+
ctx.putImageData(data, 0, 0);
26+
// Calling again inside a layer should throw.
27+
ctx.beginLayer();
28+
assert_throws_dom("InvalidStateError", () => ctx.putImageData(data, 0, 0));
29+
t.done();
30+
});
31+
done();

testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.render-opportunities.putImageData-expected.html

Lines changed: 0 additions & 32 deletions
This file was deleted.

testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.render-opportunities.putImageData.html

Lines changed: 0 additions & 37 deletions
This file was deleted.

testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.render-opportunities.putImageData.w.html

Lines changed: 0 additions & 51 deletions
This file was deleted.

testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,6 @@
459459
test_type: "promise"
460460
flush_canvas: |-
461461
await new Promise(resolve => requestAnimationFrame(resolve));
462-
putImageData:
463-
flush_canvas: |-
464-
const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
465-
const ctx2 = canvas2.getContext('2d');
466-
ctx.putImageData(ctx2.getImageData(0, 0, 1, 1), 0, 0);
467462
toBlob:
468463
test_type: "promise"
469464
canvasType: ['HTMLCanvas']
@@ -473,6 +468,20 @@
473468
canvasType: ['HTMLCanvas']
474469
flush_canvas: canvas.toDataURL();
475470

471+
- name: 2d.layer.putImageData
472+
desc: Check that calling putImageData in a layer throws an exception.
473+
code: |
474+
const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
475+
const ctx2 = canvas2.getContext('2d')
476+
const data = ctx2.getImageData(0, 0, 1, 1);
477+
// `putImageData` shouldn't throw on it's own.
478+
ctx.putImageData(data, 0, 0);
479+
// Make sure the exception isn't caused by calling the function twice.
480+
ctx.putImageData(data, 0, 0);
481+
// Calling again inside a layer should throw.
482+
ctx.beginLayer();
483+
assert_throws_dom("InvalidStateError", () => ctx.putImageData(data, 0, 0));
484+
476485
- name: 2d.layer.transferToImageBitmap
477486
desc: Check that calling transferToImageBitmap in a layer throws an exception.
478487
canvasType: ['OffscreenCanvas', 'Worker']

0 commit comments

Comments
 (0)