test(globe): pixel dashes at DPR 1 and 2

Review of Task 3 (DPI-independent dashes; the shader change landed with
the overlay commit): qa-globe-contract --dpr=2 runs the suite on a
high-DPI page, and a new check measures a 16/16 px dashed line along its
middle row in CSS pixels: the dashes must be regular, and on Navara
16/16 within 2 px. The harness prints what each engine draws.

Measured: Navara 16/16 (period 32) at DPR 1 and 2. Cesium draws
16 on / 16 off (PolylineDash dashLength 32, pattern 0xff00, uniforms
checked on the primitive) as 14 on / 2 off with a 16 px period at both
ratios — a Cesium-side difference to look at before a layer relies on
pixel dashes (none does yet). At DPR 2 the Navara harness's
stars-at-midnight check counts 4 star pixels (its detector is tuned for
DPR 1); every suite check passes at both ratios.
This commit is contained in:
German Khokhlov committed 2026-10-16 19:14:52 +04:00
1 parent 93866c42fc
commit 0957d9712b
1 file changed
+69
+69
View File
@@ -799,6 +799,75 @@ export function createContractSuite(
}
},
],
[
'lines: pixel dashes are regular, in CSS pixels',
async () => {
if (!readRegion) return;
await nadirView(1e6);
const line = engine.lines.createLine({
id: 'contract-dashes',
widthPx: 6,
color: [1, 0, 1, 1],
dash: { lengthPx: 16, gapPx: 16 },
});
try {
const a = cartesian3.fromDegrees(19, 9, 20_000);
const b = cartesian3.fromDegrees(21, 9, 20_000);
line.setPositions([a, b]);
const sa = engine.projector.worldToWindow(a);
const sb = engine.projector.worldToWindow(b);
// On/off runs (CSS px) along the middle of the line.
const runs = () => {
const left = Math.round(Math.min(sa.x, sb.x)) + 4;
const width = Math.round(Math.abs(sb.x - sa.x)) - 8;
const y = Math.round((sa.y + sb.y) / 2);
const data = readRegion(left, y, width, 1);
const on = [];
const off = [];
let current = null;
let length = 0;
for (let x = 0; x < width; x++) {
const i = x * 4;
const lit =
Math.min(data[i], data[i + 2]) - data[i + 1] > 60 &&
data[i] > 150;
if (lit === current) length++;
else {
if (current !== null) (current ? on : off).push(length);
current = lit;
length = 1;
}
}
// The first and last runs are cut by the window.
return { on: on.slice(1), off: off.slice(1) };
};
const median = (values) =>
[...values].sort((x, y) => x - y)[Math.floor(values.length / 2)];
await until(() => runs().on.length >= 3, 'dashes drawn');
const { on, off } = runs();
const spread = (values) => Math.max(...values) - Math.min(...values);
// What each engine draws for 16/16, for the harness to compare
// across device pixel ratios (Cesium's PolylineDash is the
// reference; Navara's must not change with the ratio).
globalThis.__qaDashes = {
dash: median(on),
gap: median(off),
period: median(on) + median(off),
};
ensure(
on.length >= 3 && spread(on) <= 2 && spread(off) <= 2,
`irregular dashes: runs ${JSON.stringify(on)} / ${JSON.stringify(off)}`,
);
if (engine.kind === 'navara')
ensure(
Math.abs(median(on) - 16) <= 2 && Math.abs(median(off) - 16) <= 2,
`dash ${median(on)} px, gap ${median(off)} px (16/16 asked)`,
);
} finally {
line.destroy();
}
},
],
[
'render: continuous mode toggles',
async () => {