Hoist per-triangle mipmap metrics out of the per-tile paint path
- paintFlat no longer recomputes the screen-edge perimeter (3 sqrt) per
overlapped tile: callers pass it in. Object path already computed it
in paintTriangle (it was computed twice per paint); mesh handles read
a per-slot value computed once in TriangleMeshBlock.transform (queued
triangles only). Clipped fan sub-triangles compute inline (rare).
- TriangleMeshBlock UV perimeter (origTtd) precomputed once at build
into uvPerimeter[] instead of 3 sqrt over the final uv[] per paint.
Bit-exact: same expressions, same accumulation order, same inputs —
verified by identical golden diff counts against the pre-change run
(23/23 scenes).