// Wait kPollDelayMs between snapshotRect calls so we don't overwelm test
// verify android jobs that can hit oom if we do it every frame.
const kPollDelayMs = 500;
async function nextPollTick() {
await new Promise(r => setTimeout(r, kPollDelayMs));
await new Promise(requestAnimationFrame);
}
function getPixel(imgElement, x, y) {
let r = imgElement.getBoundingClientRect();
let canvas = snapshotRect(window, r);
let ctx = canvas.getContext("2d");
let data = ctx.getImageData(x, y, 1, 1).data;
return { r: data[0], g: data[1], b: data[2], a: data[3] };
}
// Sample points: inside corners of the 4x4 grid in progressive.jxl. Same
// coordinates the gtest uses (kJxlGridSamplePoints).
const samplePoints = [
{ x: 127, y: 127 },
{ x: 384, y: 127 },
{ x: 127, y: 384 },
{ x: 384, y: 384 },
];
async function waitForStop(img, stop) {
// Poll every animation frame until every sample point matches the
// recorded expected RGB. After kStopDiagnosticDeadlineMs without a match
// we record each non-matching point's expected/actual/delta once so that
// whoever has to update the recorded values has something concrete to
// work from. We then keep polling and let the harness time out the test
// as a whole.
let logged = false;
let deadline = performance.now() + kStopDiagnosticDeadlineMs;
while (true) {
await nextPollTick();
let pixels = samplePoints.map(p => getPixel(img, p.x, p.y));
let allMatch = pixels.every((px, i) => pixelsMatch(px, stop.samples[i]));
if (allMatch) {
ok(true, `${stop.label}: all samples match`);
return;
}
if (!logged && performance.now() >= deadline) {
logged = true;
for (let i = 0; i < samplePoints.length; i++) {
let p = samplePoints[i];
let a = pixels[i];
let e = stop.samples[i];
if (!pixelsMatch(a, e)) {
ok(false,
`${stop.label} (${p.x},${p.y}): expected=(${e.r},${e.g},${e.b}) ` +
`actual=(${a.r},${a.g},${a.b}) delta=(${a.r - e.r},${a.g - e.g},${a.b - e.b})`
);
}
}
}
}
}
// Stop 0: the SJS writes the first chunk immediately; just wait for it.
await waitForStop(img, stops[0]);
// Subsequent stops: signal continue=N then wait for those samples. The
// final iteration's continue=stops.length tells the SJS to write the
// rest of the file and finish the response.
for (let i = 1; i < stops.length; i++) {
await fetch(`sendprogressivejxl.sjs?continue=${i}`);
await waitForStop(img, stops[i]);
}
await loadedPromise;
ok(imageLoaded, "image finished loading after all stops");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.