Skip to content

Density normalization should be shader-side: per-frame CPU re-tonemap, u8->f32->u8 round trip, and cached CPU grids #166

Description

@Alek99

From a full data-transport audit at b0f8780. Three related client costs that one design change removes:

  1. Per-frame re-tonemap + full texture re-upload during exposure animationlodStepNorm (js/src/45_lod.ts:111-132) calls lodWriteGridTexture (45_lod.ts:50-70) every animation frame: an O(w*h) log1p loop over the retained f32 grid plus a full R8 texImage2D upload (~1-2 ms per frame for a plot-sized grid, x2 when crossfading). The stored texel is 255*log1p(c)/log1p(norm), so a norm change is a pure scalar rescale — animate a u_normScale uniform in DENSITY_FS (js/src/40_gl.ts:386) against a texture baked once.
  2. log-u8 wire grid decoded u8→f32 then re-encoded f32→u8 for uploadlodDecodeLogU8 (45_lod.ts:32-42), consumed at 45_lod.ts:497-515 / 50_chartview.ts:2049-2062. At apply time normMax === d.max, so the wire u8 bytes could go straight into texImage2D: two avoidable full-grid copies + 4x transient memory per density update (fires per zoom gesture).
  3. CPU f32 grid retained per cached density windowlodRememberDensity (45_lod.ts:198-220, maxCached=8) keeps grid (wh4 B) only to re-encode on norm change: ~13 MB per density trace at cap. With shader-side normalization, drop the CPU grid from cached entries entirely.

Investigate: confirm the rescale identity holds across the crossfade path and pyramid-composed grids; check standalone kernel-less re-bin path uses the same upload helper.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs investigateAudit finding awaiting validation/measurementperformanceReduces copies, bytes, or CPU on the data path

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions