| OLD | NEW |
| 1 <!DOCTYPE HTML> | 1 <!DOCTYPE HTML> |
| 2 | 2 |
| 3 <!-- READ BEFORE UPDATING: | 3 <!-- READ BEFORE UPDATING: |
| 4 If this test is updated make sure to increment the "revision" value of the | 4 If this test is updated make sure to increment the "revision" value of the |
| 5 associated test in content/test/gpu/gpu_tests/pixel_test_pages.py. This will ens
ure | 5 associated test in content/test/gpu/gpu_tests/pixel_test_pages.py. This will ens
ure |
| 6 that the baseline images are regenerated on the next run. | 6 that the baseline images are regenerated on the next run. |
| 7 --> | 7 --> |
| 8 | 8 |
| 9 <html> | 9 <html> |
| 10 <head> | 10 <head> |
| 11 <title>OffscreenCanvas 2d commit flow on worker thread: Four-color square on whi
te background.</title> | 11 <title>OffscreenCanvas 2d commit flow on worker thread: Two Canvases</title> |
| 12 <style type="text/css"> | 12 <style type="text/css"> |
| 13 .nomargin { | 13 .nomargin { |
| 14 margin: 0px auto; | 14 margin: 0px auto; |
| 15 } | 15 } |
| 16 </style> | 16 </style> |
| 17 <script id="myWorker" type="text/worker"> | 17 <script id="myWorker" type="text/worker"> |
| 18 /* This pixel test checks the following: |
| 19 1. Whether submission of frames for multiple canvases happen about the same |
| 20 time for OffscreenCanvas.commit() that are invoked in the same JS task. |
| 21 2. Whether overdraw frame in one animation loop is handled well. |
| 22 3. Whether the drawn 2d image is position upright in commit(). |
| 23 4. Drawing to OffscreenCanvas without commit() has no rendering results. |
| 18 | 24 |
| 19 var g_offscreen2d; | 25 Correct end result of this test: The left canvas shows a seven-spike skyblue |
| 20 var g_animationFrameNumber = 0; | 26 star on the top-left corner of a blue background and the right canvas shows |
| 27 a sky-blue fill. |
| 28 */ |
| 29 var g_ctx1, g_ctx2; |
| 30 var g_asyncCallbackNumber = 2; |
| 21 | 31 |
| 22 self.onmessage = function(e) { | 32 self.onmessage = function(e) { |
| 23 var transferredCanvas = e.data; | 33 g_ctx1 = e.data.offscreenCanvas1.getContext("2d"); |
| 24 g_offscreen2d = transferredCanvas.getContext("2d"); | 34 g_ctx2 = e.data.offscreenCanvas2.getContext("2d"); |
| 25 g_offscreen2d.fillStyle = "red"; | 35 |
| 26 g_offscreen2d.fillRect(0, 0, 200, 200); | 36 startTest(); |
| 27 drawLoop(); | |
| 28 } | 37 } |
| 29 | 38 |
| 30 function drawLoop() | 39 function startTest() { |
| 31 { | 40 g_ctx1.fillStyle = "green"; |
| 32 if (g_animationFrameNumber < 10) { | 41 g_ctx1.fillRect(0, 0, 300, 300); |
| 33 g_animationFrameNumber++; | 42 // The promise returned by this g_ctx1.commit() must be resolved at |
| 34 // Purposely intersperse overdraw and non-overdraw commit cases to see | 43 // about the same time as the other g_ctx2.commit() below as they are in the |
| 35 // if OffscreenCanvas commit() handles both cases well. | 44 // same JS task. |
| 36 if (0 == g_animationFrameNumber % 2) { | 45 g_ctx1.commit().then(function() { |
| 37 // When promise is used, the next drawLoop() is called after the first | 46 g_ctx2.fillRect(0, 0, 300, 300); |
| 38 // frame is resolved; therefore there is no overdraw in this case. | 47 // This g_ctx2.commit() must happen after the other g_ctx2.commit() below. |
| 39 g_offscreen2d.commit().then(drawLoop); | 48 g_ctx2.commit(); |
| 40 } else { | 49 if (--g_asyncCallbackNumber == 0) self.postMessage(""); |
| 41 // When the next drawLoop() is invoked regardless the promise resolve | 50 }); |
| 42 // status of the previous commit(), the frame committed in the next | 51 |
| 43 // drawLoop() is very likely to be overdrawn. | 52 function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius) { |
| 44 g_offscreen2d.commit(); | 53 var rot = Math.PI / 2 * 3; |
| 45 drawLoop(); | 54 var x = cx; |
| 55 var y = cy; |
| 56 var step = Math.PI / spikes; |
| 57 |
| 58 ctx.beginPath(); |
| 59 ctx.moveTo(cx, cy - outerRadius); |
| 60 for (i = 0; i < spikes; i++) { |
| 61 x = cx + Math.cos(rot) * outerRadius; |
| 62 y = cy + Math.sin(rot) * outerRadius; |
| 63 ctx.lineTo(x, y); |
| 64 rot += step; |
| 65 |
| 66 x = cx + Math.cos(rot) * innerRadius; |
| 67 y = cy + Math.sin(rot) * innerRadius; |
| 68 ctx.lineTo(x, y); |
| 69 rot += step; |
| 46 } | 70 } |
| 47 } else { | 71 ctx.lineTo(cx, cy - outerRadius); |
| 48 g_offscreen2d.fillStyle = "red"; | 72 ctx.closePath(); |
| 49 g_offscreen2d.fillRect(0, 0, 100, 100); | 73 ctx.lineWidth = 5; |
| 50 g_offscreen2d.fillStyle = "green"; | 74 ctx.strokeStyle = 'black'; |
| 51 g_offscreen2d.fillRect(100, 0, 100, 100); | 75 ctx.stroke(); |
| 52 g_offscreen2d.fillStyle = "blue"; | 76 ctx.fillStyle = 'skyblue'; |
| 53 g_offscreen2d.fillRect(0, 100, 100, 100); | 77 ctx.fill(); |
| 54 g_offscreen2d.fillStyle = "black"; | 78 } |
| 55 g_offscreen2d.fillRect(100, 100, 100, 100); | 79 |
| 56 g_offscreen2d.commit() | 80 // Do something complex to g_ctx2. |
| 81 g_ctx2.fillStyle = "blue"; |
| 82 g_ctx2.fillRect(0, 0, 300, 300); |
| 83 drawStar(g_ctx2, 150, 150, 25, 80, 60); |
| 84 // This g_ctx2.commit() must be resolved at about the same time as the first |
| 85 // g_ctx1.commit() above because they are in the same JS task, no matter how |
| 86 // complex the drawing operation is. |
| 87 g_ctx2.commit().then(function() { |
| 88 drawStar(g_ctx1, 100, 100, 7, 80, 30); |
| 89 g_ctx1.commit(); |
| 57 | 90 |
| 58 // The following fill is never committed | 91 // The following fill is never committed |
| 59 g_offscreen2d.fillStyle = "blue"; | 92 g_ctx1.fillStyle = "red"; |
| 60 g_offscreen2d.fillRect(0, 0, 200, 200); | 93 g_ctx1.fillRect(0, 0, 200, 200); |
| 61 self.postMessage(""); | 94 if (--g_asyncCallbackNumber == 0) self.postMessage(""); |
| 62 } | 95 }); |
| 96 |
| 63 } | 97 } |
| 98 |
| 64 </script> | 99 </script> |
| 65 <script> | 100 <script> |
| 66 var g_swapsBeforeAck = 15; | 101 var g_swapsBeforeAck = 15; |
| 67 | 102 |
| 68 function makeWorker(script) | 103 function makeWorker(script) |
| 69 { | 104 { |
| 70 var blob = new Blob([script]); | 105 var blob = new Blob([script]); |
| 71 return new Worker(URL.createObjectURL(blob)); | 106 return new Worker(URL.createObjectURL(blob)); |
| 72 } | 107 } |
| 73 | 108 |
| 74 function waitForFinish() | 109 function waitForFinish() |
| 75 { | 110 { |
| 76 if (g_swapsBeforeAck == 0) { | 111 if (g_swapsBeforeAck == 0) { |
| 77 domAutomationController.setAutomationId(1); | 112 domAutomationController.setAutomationId(1); |
| 78 domAutomationController.send("SUCCESS"); | 113 domAutomationController.send("SUCCESS"); |
| 79 } else { | 114 } else { |
| 80 g_swapsBeforeAck--; | 115 g_swapsBeforeAck--; |
| 81 document.getElementById('container').style.zIndex = g_swapsBeforeAck + 1; | 116 document.getElementById('container').style.zIndex = g_swapsBeforeAck + 1; |
| 82 window.requestAnimationFrame(waitForFinish); | 117 requestAnimationFrame(waitForFinish); |
| 83 } | 118 } |
| 84 } | 119 } |
| 85 | 120 |
| 86 function main() | 121 function main() |
| 87 { | 122 { |
| 88 var canvas2D = document.getElementById("c"); | 123 var offscreenCanvas1 = document.getElementById("canvas1").transferControlToOff
screen(); |
| 89 var offscreenCanvas = canvas2D.transferControlToOffscreen(); | 124 var offscreenCanvas2 = document.getElementById("canvas2").transferControlToOff
screen(); |
| 125 |
| 90 var worker = makeWorker(document.getElementById("myWorker").textContent); | 126 var worker = makeWorker(document.getElementById("myWorker").textContent); |
| 91 worker.onmessage = function (e) { | 127 worker.onmessage = function (e) { |
| 92 waitForFinish(); | 128 waitForFinish(); |
| 93 }; | 129 }; |
| 94 worker.postMessage(offscreenCanvas, [offscreenCanvas]); | 130 worker.postMessage( |
| 131 {offscreenCanvas1: offscreenCanvas1, |
| 132 offscreenCanvas2: offscreenCanvas2}, |
| 133 [offscreenCanvas1, offscreenCanvas2]); |
| 95 } | 134 } |
| 96 </script> | 135 </script> |
| 97 </head> | 136 </head> |
| 98 <body onload="main()"> | 137 <body onload="main()"> |
| 99 <div style="position:relative; width:300px; height:300px; background-color:white
"> | 138 <div style="position:relative; width:600px; height:300px; background-color:white
"> |
| 100 </div> | 139 </div> |
| 101 <div id="container" style="position:absolute; top:0px; left:0px"> | 140 <div id="container" style="position:absolute; top:0px; left:0px"> |
| 102 <canvas id="c" width="200" height="200" class="nomargin"></canvas> | 141 <canvas id="canvas1" width="300" height="300" class="nomargin"></canvas> |
| 142 <canvas id="canvas2" width="300" height="300" class="nomargin"></canvas> |
| 103 </div> | 143 </div> |
| 104 </body> | 144 </body> |
| 105 </html> | 145 </html> |
| OLD | NEW |