Repository navigation
Conversation
…it touched them Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… and the order goes Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
Author
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Made by: claude
Part of fizzyedit/plans#65 (step A). Stacked on #68 (base is feat/stroke-order); retarget to main once #68 merges.
Why: the pencil/brush always uses the deferred-undo snapshot, so #68's order never reached it (pen-up found pixels by scanning the stroke's whole bounding box, row-major, and #68 correctly skips motion for that). The same scan is the pen-up hitch: its cost is the box's area, however short the stroke.
What:
src/internal/stroke_diff.zig:Touch(layer-sized bitset + ordered list),diffTouched(only noted pixels),diffScan(the old whole-box compare, kept as fallback).drawOffsetsnotes each pixel it paints in deferred mode (O(stroke));strokeUndoBeginresets the notes,strokeUndoFreeSnapshotclears them.appendStrokeused by the deferred and the live (non-deferred) paths, so both carry first-touch order asStep.motion. Tools that append live are unchanged. Overdraw records first touch once; only pixels the brush wrote are noted, so a selection or bounds cannot add untouched pixels.Pen-up diff cost, before (box scan) -> after (touched only), headless replica, random pixels in a full-layer box:
Ran:
zig fmt --check src build.zig,zig build test(new: random-stroke property test touched-vs-scan incl. overdraw and same-colour pixels, outside-snapshot and out-of-layer, reset),zig build; CI on the PR.Not done: I did not draw in the running app.
drawOffsets/flush/appendStrokewiring in File.zig is covered only by compile + the purestroke_difftests, so a human stroke (pencil, eraser, line, shift-line; then undo/redo and a tape export) must be tried before ready.Large brushes (headless,
Brush.zigshapes circle and square, long stroke moved 8 px per frame, brush steps one pixel at a time so only each step's edge is painted, except the first full stamp and any jump). Per-frame cost WHILE dragging: pixel writes alone vs writes + the newTouch.markper painted pixel (avg over 400 frames):(512² numbers are the same within noise at sizes 1-64.) The mark adds ~2-3x the cost of the writes themselves, ~0.3-0.6 ms per frame in ReleaseFast at 255 px; Debug at 255 px is a few ms per frame. The marks/frame at 255 px include the whole-stamp jumps in my path, so it is a worst-ish case.
Memory budget: the bitset is one bit a layer pixel (512 KiB at 2048²); the order list is capped at
stroke_diff.max_order= 4 Mi entries (16 MiB). Past it (or if the list cannot grow) the notes are freed and the stroke isvalid = falsefor its remainder: pen-up compares the box (diffScan) so the change is exactly the pixels that changed, no pixel is lost and nothing crashes; only the drawn order is dropped (no motion on that step, so it replays as before). Test:a stroke past the budget keeps its change, not its order. At 2048² the cap is about the layer's pixel count, so it only trips on very long big-brush strokes.Replay quality note (for plans#65 step B, not implemented): pixel-order motion replays a big brush as each stamp's new pixels appearing in raster order within the stamp (edge order), so a 64-256 px brush looks like blobs growing, not a pen line. To replay as a pen path the format needs, per input sample, the brush centre (x, y as deltas, ~2 bytes), and once per stroke the brush size + shape (+ colour or erase flag) and a per-sample timestamp delta (~1-2 bytes): a few bytes a sample instead of one entry a pixel, and a player re-stamps the brush at each sample (the pixels are then the effect already stored). Repeated samples/overdraw are allowed there, unlike
Motiontoday.🤖 Generated with Claude Code