Bug 1945965 – remove new tab April Fools logo. r=home-newtab-reviewers,reemhamz
[gecko.git] / dom / webgpu / mochitest / test_queue_copyExternalImageToTexture.html
blob07937d5d14800bc382f7fa2279a793533f280ef9
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <script src="/tests/SimpleTest/SimpleTest.js"></script>
6 <link rel="stylesheet" href="/tests/SimpleTest/test.css" />
7 </head>
9 <body>
10 <script type="text/javascript">
11 "use strict";
13 ok(
14 SpecialPowers.getBoolPref("dom.webgpu.enabled"),
15 "WebGPU pref should be enabled."
18 SimpleTest.waitForExplicitFinish();
20 function requestAnimationFramePromise() {
21 return new Promise(requestAnimationFrame);
24 function createSourceCanvasWebgl() {
25 const offscreenCanvas = new OffscreenCanvas(200, 200);
26 const gl = offscreenCanvas.getContext("webgl");
28 const COLOR_VALUE = 127.0 / 255.0;
29 const ALPHA_VALUE = 127.0 / 255.0;
31 gl.enable(gl.SCISSOR_TEST);
33 gl.scissor(0, 0, 100, 100);
34 gl.clearColor(COLOR_VALUE, 0.0, 0.0, ALPHA_VALUE);
35 gl.clear(gl.COLOR_BUFFER_BIT);
37 gl.scissor(100, 0, 100, 100);
38 gl.clearColor(0.0, COLOR_VALUE, 0.0, ALPHA_VALUE);
39 gl.clear(gl.COLOR_BUFFER_BIT);
41 gl.scissor(0, 100, 100, 100);
42 gl.clearColor(0.0, 0.0, COLOR_VALUE, ALPHA_VALUE);
43 gl.clear(gl.COLOR_BUFFER_BIT);
45 gl.scissor(100, 100, 100, 100);
46 gl.clearColor(0.0, 0.0, 0.0, ALPHA_VALUE);
47 gl.clear(gl.COLOR_BUFFER_BIT);
49 return {
50 source: offscreenCanvas,
51 origin: { x: 0, y: 0 },
52 flipY: true,
56 function createSourceCanvas2d() {
57 const offscreenCanvas = new OffscreenCanvas(200, 200);
58 const context = offscreenCanvas.getContext("2d");
60 context.fillStyle = "rgba(255,0,0,0.498)";
61 context.fillRect(0, 0, 100, 100);
63 context.fillStyle = "rgba(0,255,0,0.498)";
64 context.fillRect(100, 0, 100, 100);
66 context.fillStyle = "rgba(0,0,255,0.498)";
67 context.fillRect(0, 100, 100, 100);
69 context.fillStyle = "rgba(0,0,0,0.498)";
70 context.fillRect(100, 100, 100, 100);
72 return {
73 source: offscreenCanvas,
74 origin: { x: 0, y: 0 },
75 flipY: false,
79 function createSourceImageBitmap() {
80 const sourceCanvas = createSourceCanvas2d();
81 return {
82 source: sourceCanvas.source.transferToImageBitmap(),
83 origin: { x: 0, y: 0 },
84 flipY: false,
88 async function mapDestTexture(
89 device,
90 source,
91 destFormat,
92 premultiply,
93 copySize
94 ) {
95 const bytesPerRow = 256 * 4; // 256 aligned for 200 pixels
96 const texture = device.createTexture({
97 format: destFormat,
98 size: copySize,
99 usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST,
102 device.queue.copyExternalImageToTexture(
103 source,
104 { texture, premultipliedAlpha: premultiply },
105 copySize
108 const buffer = device.createBuffer({
109 size: 1024 * 200,
110 usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
113 const encoder = device.createCommandEncoder();
114 encoder.copyTextureToBuffer(
115 { texture },
116 { buffer, bytesPerRow },
117 copySize
119 device.queue.submit([encoder.finish()]);
121 await buffer.mapAsync(GPUMapMode.READ);
122 return buffer;
125 async function verifyBuffer(
126 test,
127 device,
128 source,
129 format,
130 premultiply,
131 copyDim,
132 topLeftPixelData
134 try {
135 const buffer = await mapDestTexture(
136 device,
137 source,
138 format,
139 premultiply,
140 copyDim
142 const arrayBuffer = buffer.getMappedRange();
143 const view = new Uint8Array(arrayBuffer);
144 for (let i = 0; i < topLeftPixelData.length; ++i) {
146 view[i],
147 topLeftPixelData[i],
148 test +
149 " " +
150 format +
151 " (" +
152 source.origin.x +
153 "," +
154 source.origin.y +
155 ") channel " +
159 } catch (e) {
160 ok(false, "WebGPU exception: " + e);
164 async function verifySourceCanvas(test, device, source) {
165 await verifyBuffer(
166 test,
167 device,
168 source,
169 "rgba8unorm",
170 /* premultiply */ true,
171 { width: 200, height: 200 },
172 [127, 0, 0, 127]
174 await verifyBuffer(
175 test,
176 device,
177 source,
178 "bgra8unorm",
179 /* premultiply */ true,
180 { width: 200, height: 200 },
181 [0, 0, 127, 127]
183 await verifyBuffer(
184 test,
185 device,
186 source,
187 "rgba8unorm",
188 /* premultiply */ false,
189 { width: 200, height: 200 },
190 [255, 0, 0, 127]
192 await verifyBuffer(
193 test,
194 device,
195 source,
196 "bgra8unorm",
197 /* premultiply */ false,
198 { width: 200, height: 200 },
199 [0, 0, 255, 127]
202 // The copy is flipped but the origin is relative to the original source data,
203 // so we need to invert for WebGL.
204 const topRightPixelData =
205 test === "webgl" ? [0, 0, 0, 127] : [0, 127, 0, 127];
206 const topRightOrigin = { origin: { x: 100, y: 0 } };
207 await verifyBuffer(
208 test,
209 device,
210 { ...source, ...topRightOrigin },
211 "bgra8unorm",
212 /* premultiply */ true,
213 { width: 100, height: 100 },
214 topRightPixelData
217 const bottomLeftPixelData =
218 test === "webgl" ? [0, 0, 127, 127] : [127, 0, 0, 127];
219 const bottomLeftOrigin = { origin: { x: 0, y: 100 } };
220 await verifyBuffer(
221 test,
222 device,
223 { ...source, ...bottomLeftOrigin },
224 "bgra8unorm",
225 /* premultiply */ true,
226 { width: 100, height: 100 },
227 bottomLeftPixelData
231 async function writeDestCanvas(source2d, sourceWebgl, sourceImageBitmap) {
232 const adapter = await navigator.gpu.requestAdapter();
233 const device = await adapter.requestDevice();
234 await verifySourceCanvas("2d", device, source2d);
235 await verifySourceCanvas("imageBitmap", device, sourceImageBitmap);
236 await verifySourceCanvas("webgl", device, sourceWebgl);
239 async function runTest() {
240 try {
241 const source2d = createSourceCanvas2d();
242 const sourceWebgl = createSourceCanvasWebgl();
243 const sourceImageBitmap = createSourceImageBitmap();
244 await requestAnimationFramePromise();
245 await requestAnimationFramePromise();
246 await writeDestCanvas(source2d, sourceWebgl, sourceImageBitmap);
247 } catch (e) {
248 ok(false, "Uncaught exception: " + e);
249 } finally {
250 SimpleTest.finish();
254 runTest();
255 </script>
256 </body>
257 </html>