Automatic update from web-platform-tests Add JPEG XL canvas reftest coverage Convert the canvas decode paths test to a PNG-backed reftest and add a WebGPU copyExternalImageToTexture case. Bug: 484065185 Change-Id: I6f9153f24fb550848f127e0da9847a1c5c3e3cd9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7666126 Commit-Queue: Helmut Januschka <helmut@januschka.com> Reviewed-by: Philip Jägenstedt <foolip@chromium.org> Cr-Commit-Position: refs/heads/main@{#1614800} -- wpt-commits: d75b4f943ae538aa22631dfbbc57fb109a3e8c09 wpt-pr: 59224
100 lines
2.8 KiB
HTML
100 lines
2.8 KiB
HTML
<!DOCTYPE html>
|
|
<title>JPEG XL integration: canvas WebGPU decode path</title>
|
|
<link rel="help" href="https://github.com/web-platform-tests/interop-jpegxl">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<script>
|
|
async function loadImage(src) {
|
|
const image = new Image();
|
|
await new Promise((resolve, reject) => {
|
|
image.onload = resolve;
|
|
image.onerror = () => reject(new Error(`image load failed: ${src}`));
|
|
image.src = src;
|
|
});
|
|
return image;
|
|
}
|
|
|
|
function sampleCenterPixelWith2d(image) {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 3;
|
|
canvas.height = 3;
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
assert_true(!!ctx, '2D context available');
|
|
ctx.drawImage(image, 0, 0);
|
|
return ctx.getImageData(1, 1, 1, 1).data;
|
|
}
|
|
|
|
function assertPixelsApproxEqual(actual, expected, tolerance, messagePrefix) {
|
|
for (let i = 0; i < 4; ++i) {
|
|
assert_approx_equals(
|
|
actual[i], expected[i], tolerance, `${messagePrefix} channel ${i}`);
|
|
}
|
|
}
|
|
|
|
async function sampleCenterPixelWithWebGPU(image) {
|
|
if (!('gpu' in navigator)) {
|
|
return null;
|
|
}
|
|
|
|
const adapter = await navigator.gpu.requestAdapter();
|
|
if (!adapter) {
|
|
return null;
|
|
}
|
|
|
|
const device = await adapter.requestDevice();
|
|
const width = image.naturalWidth || image.width;
|
|
const height = image.naturalHeight || image.height;
|
|
assert_greater_than(width, 0);
|
|
assert_greater_than(height, 0);
|
|
|
|
const texture = device.createTexture({
|
|
size: {width, height, depthOrArrayLayers: 1},
|
|
format: 'rgba8unorm',
|
|
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC,
|
|
});
|
|
|
|
device.queue.copyExternalImageToTexture(
|
|
{source: image},
|
|
{texture},
|
|
{width, height, depthOrArrayLayers: 1});
|
|
|
|
const buffer = device.createBuffer({
|
|
size: 4,
|
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
});
|
|
|
|
const encoder = device.createCommandEncoder();
|
|
encoder.copyTextureToBuffer(
|
|
{texture, origin: {x: 1, y: 1, z: 0}},
|
|
{buffer},
|
|
{width: 1, height: 1, depthOrArrayLayers: 1});
|
|
device.queue.submit([encoder.finish()]);
|
|
|
|
await buffer.mapAsync(GPUMapMode.READ);
|
|
const pixel = new Uint8Array(buffer.getMappedRange()).slice(0, 4);
|
|
|
|
buffer.unmap();
|
|
buffer.destroy();
|
|
texture.destroy();
|
|
|
|
return pixel;
|
|
}
|
|
|
|
promise_test(async () => {
|
|
const [jxlImage, pngImage] = await Promise.all([
|
|
loadImage('resources/3x3_srgb_lossless.jxl'),
|
|
loadImage('resources/3x3_srgb_lossless.png'),
|
|
]);
|
|
|
|
const actual = await sampleCenterPixelWithWebGPU(jxlImage);
|
|
if (!actual) {
|
|
return;
|
|
}
|
|
|
|
const expected = sampleCenterPixelWith2d(pngImage);
|
|
assertPixelsApproxEqual(actual, expected, 1, 'WebGPU copyExternalImageToTexture');
|
|
}, 'WebGPU copyExternalImageToTexture path with JPEG XL image.');
|
|
</script>
|