Keep the queued-card check off the per-frame allocation path

Writing a fractional alpha onto the overlay record for every paint item
boxed a heap number per item per frame. The allocation gate caught it:
the generic 60-entry workload went from 2,838 to 12,614 B/frame. The
record now keeps only the frame stamp and a pointer to its paint item,
and isOverlayEntryQueued multiplies the alphas when it is asked. The
gate is back to main's numbers on Node 24.
This commit is contained in:
German Khokhlov committed 2026-11-05 13:14:00 +04:00
1 parent 092e7e71a8
commit ee3466dff9
1 file changed
+11 -8
+11 -8
View File
@@ -1076,8 +1076,14 @@ export function getOverlayPaintRect(sourceId, entryId) {
export function isOverlayEntryQueued(sourceId, entryId) {
if (_destroyed) return false;
const record = _records.get(entryKey(String(sourceId), String(entryId)));
if (!record || record.queuedStamp !== _frameStamp) return false;
// Same channels as the paint, minus the per-frame keyhole and sonar fades.
return (
!!record && record.queuedStamp === _frameStamp && record.queuedAlpha > 0.001
record.sourceAlpha *
record.queuedItem.temporalAlpha *
record.distanceAlpha *
record.altitudeAlpha >
0.001
);
}
@@ -1754,7 +1760,7 @@ function getProjectionRecord(entry) {
altitudeAlpha: 1,
sourceAlpha: 1,
queuedStamp: 0,
queuedAlpha: 0,
queuedItem: null,
protectedPlacement: null,
distanceOptions: {},
altitudeOptions: {},
@@ -2273,13 +2279,10 @@ function addPaintItem(record, placement, temporalAlpha, selected) {
item.key = record.key;
_paintQueue[_paintCount++] = item;
// Read by `isOverlayEntryQueued` while the custom lanes paint, before this
// item publishes its paint rect. Keyhole and sonar fades are left out.
// item publishes its paint rect. Only a stamp and a pointer: storing the
// item's alpha here would box a double per paint item per frame.
record.queuedStamp = _frameStamp;
record.queuedAlpha =
record.sourceAlpha *
temporalAlpha *
record.distanceAlpha *
record.altitudeAlpha;
record.queuedItem = item;
}
function sourceCanPaint(sourceId) {