Skip to content

picogame: two dirty-rectangle fixes - #11290

Open
lynt-smitka wants to merge 2 commits into
adafruit:mainfrom
MakerClassCZ:picogame-dirty-rects
Open

picogame: two dirty-rectangle fixes#11290
lynt-smitka wants to merge 2 commits into
adafruit:mainfrom
MakerClassCZ:picogame-dirty-rects

Conversation

@lynt-smitka

Copy link
Copy Markdown

Two independent fixes in picogame's dirty-rectangle pass.

StripDraw and Triangles were shifted by the scene view. Both composite in screen coordinates - the draw path never applies the view offset to them - but the dirty pass did, for every non-fixed layer. With a scrolled view, invalidate() repainted the wrong region and left the layer's own rectangle stale.

Off-screen changes consumed dirty slots. A change entirely outside the screen took a slot anyway, and wide scrolling strips burned two slots each, so a busy scene fell back to a full repaint every frame. Rectangles are now clipped to the screen first: invisible changes take no slot, partly visible ones are stored at their visible size.

Both layer kinds are documented and composited in screen coordinates: the
draw path never applies the view offset to them. The dirty-rect pass
applied it anyway to every non-fixed layer, so with a scrolled view a
non-fixed StripDraw's invalidate() repainted an unrelated region while
the layer's actual rectangle kept its stale pixels. A non-fixed
Triangles batch similarly missed the band above/left of the view offset.

Repro (device): StripDraw(cb, 100, 60, 40, 30, always_dirty=False) +
scene.set_view(50, 20) + sd.invalidate() -> refresh() returned
(150, 80, 190, 110) and the layer at (100, 60) never repainted.
A change wholly off-screen (the off-screen half of a wrapping parallax pair, a sprite parked
outside) took a dirty slot anyway, and a scrolling background of wide strips burned two slots per
strip - pushing a busy scene into the full-repaint overflow every frame. Clip to the screen first:
fully invisible changes take no slot, partly visible ones are stored at their visible size, so the
merge pass works on what actually gets repainted.

Measured on a PicoPad (2026-08): the artifact-repro scene went from full repaints every frame to
staying inside the 6-slot budget.

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants