diff --git a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap-expected.html b/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap-expected.html deleted file mode 100644 index 36deca50f4a30f..00000000000000 --- a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap-expected.html +++ /dev/null @@ -1,24 +0,0 @@ - - -Canvas test: 2d.layer.render-opportunities.transferToImageBitmap -

2d.layer.render-opportunities.transferToImageBitmap

-

Checks that transferToImageBitmap flushes and rebuilds the state stack.

- -

FAIL (fallback content)

-
- diff --git a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.html b/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.html deleted file mode 100644 index 634d9e3a78c1a5..00000000000000 --- a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.html +++ /dev/null @@ -1,36 +0,0 @@ - - - -Canvas test: 2d.layer.render-opportunities.transferToImageBitmap -

2d.layer.render-opportunities.transferToImageBitmap

-

Checks that transferToImageBitmap flushes and rebuilds the state stack.

- -

FAIL (fallback content)

-
- diff --git a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.w.html b/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.w.html deleted file mode 100644 index 823bfac58b09ee..00000000000000 --- a/html/canvas/offscreen/layers/2d.layer.render-opportunities.transferToImageBitmap.w.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - -Canvas test: 2d.layer.render-opportunities.transferToImageBitmap -

2d.layer.render-opportunities.transferToImageBitmap

-

Checks that transferToImageBitmap flushes and rebuilds the state stack.

- -

FAIL (fallback content)

-
- - - diff --git a/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.html b/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.html new file mode 100644 index 00000000000000..5e5d6d16c6b11d --- /dev/null +++ b/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.html @@ -0,0 +1,34 @@ + + +OffscreenCanvas test: 2d.layer.transferToImageBitmap + + + + +

2d.layer.transferToImageBitmap

+

Check that calling transferToImageBitmap in a layer throws an exception.

+ + + diff --git a/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.worker.js b/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.worker.js new file mode 100644 index 00000000000000..073a3e84a486ac --- /dev/null +++ b/html/canvas/offscreen/layers/2d.layer.transferToImageBitmap.worker.js @@ -0,0 +1,29 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.layer.transferToImageBitmap +// Description:Check that calling transferToImageBitmap in a layer throws an exception. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Check that calling transferToImageBitmap in a layer throws an exception."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + // `transferToImageBitmap` shouldn't throw on it's own. + canvas.transferToImageBitmap(); + // Make sure the exception isn't caused by calling the function twice. + canvas.transferToImageBitmap(); + // Calling again inside a layer should throw. + ctx.beginLayer(); + assert_throws_dom("InvalidStateError", + () => canvas.transferToImageBitmap()); + t.done(); +}); +done(); diff --git a/html/canvas/offscreen/layers/2d.layer.unclosed-nested.w.html b/html/canvas/offscreen/layers/2d.layer.unclosed-nested.w.html index dd1c36ea471975..e330e1710cf488 100644 --- a/html/canvas/offscreen/layers/2d.layer.unclosed-nested.w.html +++ b/html/canvas/offscreen/layers/2d.layer.unclosed-nested.w.html @@ -13,20 +13,29 @@

2d.layer.unclosed-nested

const canvas = new OffscreenCanvas(200, 200); const ctx = canvas.getContext('2d'); - ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - ctx.fillRect(60, 60, 75, 50); - ctx.globalAlpha = 0.5; + // `transferToImageBitmap` is used to transfer the test result to the + // worker's parent, but `transferToImageBitmap` can't be called on canvas + // with unclosed layers. We can however draw to a separate offscreen canvas + // and write it to the main canvas using `drawImage`. + const canvas2 = new OffscreenCanvas(200, 200); + const ctx2 = canvas2.getContext('2d'); - ctx.beginLayer(); - ctx.fillStyle = 'rgba(225, 0, 0, 1)'; - ctx.fillRect(50, 50, 75, 50); + ctx2.fillStyle = 'rgba(0, 0, 255, 1)'; + ctx2.fillRect(60, 60, 75, 50); + ctx2.globalAlpha = 0.5; - ctx.beginLayer(); - ctx.fillStyle = 'rgba(0, 255, 0, 1)'; - ctx.fillRect(70, 70, 75, 50); + ctx2.beginLayer(); + ctx2.fillStyle = 'rgba(225, 0, 0, 1)'; + ctx2.fillRect(50, 50, 75, 50); - ctx.endLayer(); - // Missing ctx.endLayer() here. + ctx2.beginLayer(); + ctx2.fillStyle = 'rgba(0, 255, 0, 1)'; + ctx2.fillRect(70, 70, 75, 50); + + ctx2.endLayer(); + // Missing ctx2.endLayer() here. + + ctx.drawImage(canvas2, 0, 0); const bitmap = canvas.transferToImageBitmap(); self.postMessage(bitmap, bitmap); diff --git a/html/canvas/offscreen/layers/2d.layer.unclosed.w.html b/html/canvas/offscreen/layers/2d.layer.unclosed.w.html index 830dea7e3d1165..1da44c26c8661b 100644 --- a/html/canvas/offscreen/layers/2d.layer.unclosed.w.html +++ b/html/canvas/offscreen/layers/2d.layer.unclosed.w.html @@ -13,14 +13,23 @@

2d.layer.unclosed

const canvas = new OffscreenCanvas(200, 200); const ctx = canvas.getContext('2d'); - ctx.fillStyle = 'purple'; - ctx.fillRect(60, 60, 75, 50); - ctx.globalAlpha = 0.5; + // `transferToImageBitmap` is used to transfer the test result to the + // worker's parent, but `transferToImageBitmap` can't be called on canvas + // with unclosed layers. We can however draw to a separate offscreen canvas + // and write it to the main canvas using `drawImage`. + const canvas2 = new OffscreenCanvas(200, 200); + const ctx2 = canvas2.getContext('2d'); - ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); - ctx.fillRect(40, 40, 75, 50); - ctx.fillStyle = 'grey'; - ctx.fillRect(50, 50, 75, 50); + ctx2.fillStyle = 'purple'; + ctx2.fillRect(60, 60, 75, 50); + ctx2.globalAlpha = 0.5; + + ctx2.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); + ctx2.fillRect(40, 40, 75, 50); + ctx2.fillStyle = 'grey'; + ctx2.fillRect(50, 50, 75, 50); + + ctx.drawImage(canvas2, 0, 0); const bitmap = canvas.transferToImageBitmap(); self.postMessage(bitmap, bitmap); diff --git a/html/canvas/tools/yaml-new/layers.yaml b/html/canvas/tools/yaml-new/layers.yaml index 9145108bd3c27f..41cd2ddfb3d88a 100644 --- a/html/canvas/tools/yaml-new/layers.yaml +++ b/html/canvas/tools/yaml-new/layers.yaml @@ -312,14 +312,29 @@ desc: Check that layers are rendered even if not closed. size: [200, 200] code: | - ctx.fillStyle = 'purple'; - ctx.fillRect(60, 60, 75, 50); - ctx.globalAlpha = 0.5; + {% set ns = namespace(ctx='ctx') %} + {% if canvas_type == 'worker' %} + // `transferToImageBitmap` is used to transfer the test result to the + // worker's parent, but `transferToImageBitmap` can't be called on canvas + // with unclosed layers. We can however draw to a separate offscreen canvas + // and write it to the main canvas using `drawImage`. + const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }}); + const ctx2 = canvas2.getContext('2d'); + {% set ns.ctx = 'ctx2' %} + {% endif %} - ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); - ctx.fillRect(40, 40, 75, 50); - ctx.fillStyle = 'grey'; - ctx.fillRect(50, 50, 75, 50); + {{ ns.ctx }}.fillStyle = 'purple'; + {{ ns.ctx }}.fillRect(60, 60, 75, 50); + {{ ns.ctx }}.globalAlpha = 0.5; + + {{ ns.ctx }}.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); + {{ ns.ctx }}.fillRect(40, 40, 75, 50); + {{ ns.ctx }}.fillStyle = 'grey'; + {{ ns.ctx }}.fillRect(50, 50, 75, 50); + + {% if canvas_type == 'worker' %} + ctx.drawImage(canvas2, 0, 0); + {% endif %} reference: | ctx.fillStyle = 'purple'; ctx.fillRect(60, 60, 75, 50); @@ -336,20 +351,35 @@ desc: Check that layers are rendered even if not closed. size: [200, 200] code: | - ctx.fillStyle = 'rgba(0, 0, 255, 1)'; - ctx.fillRect(60, 60, 75, 50); - ctx.globalAlpha = 0.5; + {% set ns = namespace(ctx='ctx') %} + {% if canvas_type == 'worker' %} + // `transferToImageBitmap` is used to transfer the test result to the + // worker's parent, but `transferToImageBitmap` can't be called on canvas + // with unclosed layers. We can however draw to a separate offscreen canvas + // and write it to the main canvas using `drawImage`. + const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }}); + const ctx2 = canvas2.getContext('2d'); + {% set ns.ctx = 'ctx2' %} + {% endif %} - ctx.beginLayer(); - ctx.fillStyle = 'rgba(225, 0, 0, 1)'; - ctx.fillRect(50, 50, 75, 50); + {{ ns.ctx }}.fillStyle = 'rgba(0, 0, 255, 1)'; + {{ ns.ctx }}.fillRect(60, 60, 75, 50); + {{ ns.ctx }}.globalAlpha = 0.5; - ctx.beginLayer(); - ctx.fillStyle = 'rgba(0, 255, 0, 1)'; - ctx.fillRect(70, 70, 75, 50); + {{ ns.ctx }}.beginLayer(); + {{ ns.ctx }}.fillStyle = 'rgba(225, 0, 0, 1)'; + {{ ns.ctx }}.fillRect(50, 50, 75, 50); - ctx.endLayer(); - // Missing ctx.endLayer() here. + {{ ns.ctx }}.beginLayer(); + {{ ns.ctx }}.fillStyle = 'rgba(0, 255, 0, 1)'; + {{ ns.ctx }}.fillRect(70, 70, 75, 50); + + {{ ns.ctx }}.endLayer(); + // Missing {{ ns.ctx }}.endLayer() here. + + {% if canvas_type == 'worker' %} + ctx.drawImage(canvas2, 0, 0); + {% endif %} reference: | const canvas1 = document.createElement('canvas'); const ctx1 = canvas1.getContext('2d'); @@ -443,44 +473,18 @@ canvasType: ['HTMLCanvas'] flush_canvas: canvas.toDataURL(); - -- name: 2d.layer.render-opportunities.transferToImageBitmap - desc: Checks that transferToImageBitmap flushes and rebuilds the state stack. - size: [200, 200] +- name: 2d.layer.transferToImageBitmap + desc: Check that calling transferToImageBitmap in a layer throws an exception. canvasType: ['OffscreenCanvas', 'Worker'] code: | - ctx.fillStyle = 'purple'; - ctx.fillRect(60, 60, 75, 50); - ctx.globalAlpha = 0.5; - - ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); - ctx.fillRect(40, 40, 75, 50); - ctx.fillStyle = 'grey'; - ctx.fillRect(50, 50, 75, 50); - - // Force a flush and restoration of the state stack. - // `transferToImageBitmap` clears the frame but preserves render states. + // `transferToImageBitmap` shouldn't throw on it's own. canvas.transferToImageBitmap(); - - ctx.fillRect(70, 70, 75, 50); - ctx.fillStyle = 'orange'; - ctx.fillRect(80, 80, 75, 50); - ctx.endLayer(); - - ctx.fillRect(80, 40, 75, 50); - reference: | - ctx.fillStyle = 'purple'; - ctx.globalAlpha = 0.5; - - ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}}); - ctx.fillStyle = 'grey'; - ctx.fillRect(70, 70, 75, 50); - ctx.fillStyle = 'orange'; - ctx.fillRect(80, 80, 75, 50); - ctx.endLayer(); - - ctx.fillRect(80, 40, 75, 50); - + // Make sure the exception isn't caused by calling the function twice. + canvas.transferToImageBitmap(); + // Calling again inside a layer should throw. + ctx.beginLayer(); + assert_throws_dom("InvalidStateError", + () => canvas.transferToImageBitmap()); - name: 2d.layer.several-complex desc: >-