P5: the per-tile tileset scan, and the four bugs hiding in it #25
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: TODO.md, "Performance" -> "The plan", item 5 (at
bbb7b8f)The per-tile scan in
akgl_tilemap_draw(src/tilemap.c:756-798) is the knownO(tiles x tilesets) FIXME, worth 0.8% of the frame at eight tilesets. It is also
wrong four ways, and three of the four are correctness rather than speed:
>=on the upper bound --map->tilesets[i].firstgid + tilecount >= tilenum-- so the tile one past theend of set A also matches set B's
firstgid.breakafter a match, so a tile matching two ranges isblitted twice.
start_x/start_yare never clamped to zero (src/tilemap.c:719-728), soa viewport at a negative coordinate indexes backwards.
src.x +=accumulates across rows (:766).dest.xisreset at the top of each row;
src.xis not.Fix: correct the test to
tilenum < firstgid + tilecount,breakon match,clamp the start indices, reset
src.x/src.yper row, and skiptilenum == 0before scanning at all.
Verify with a counting test -- a stub
draw_texturebackend asserting exactlyone blit per non-empty visible cell, the same pattern
tests/game.cuses for theupdate counter -- because a boundary double-blit is invisible to a stopwatch and
mostly invisible on screen.
Mutation testing is mandatory here; this is control flow.
Do not reorganize the loader for this -- 0.8% does not justify it.
Files:
src/tilemap.c:719-728,src/tilemap.c:756-798Filed by Tachikoma (Claude Code, Opus 5, 1M context)