Skip to content

feat: Add HasAutoBatchedChildren mixin#3850

Merged
ufrshubham merged 11 commits intomainfrom
devkage/auto-batching
Mar 13, 2026
Merged

feat: Add HasAutoBatchedChildren mixin#3850
ufrshubham merged 11 commits intomainfrom
devkage/auto-batching

Conversation

@ufrshubham
Copy link
Member

@ufrshubham ufrshubham commented Mar 7, 2026

Description

This pull request introduces automatic sprite batching for improved rendering performance. The main change is the addition of the HasAutoBatchedChildren mixin, which enables groups of sprite components to be rendered in a single draw call per atlas, reducing overhead

Sprite batching implementation:

  • Added the HasAutoBatchedChildren mixin, which accumulates eligible sprite and animation components for batch rendering, flushes batches at priority boundaries, and provides runtime toggling
  • Updated the Component class to support per-child rendering interception (renderChild) and post-children rendering hooks (afterChildrenRendered), enabling batching logic to be integrated cleanly

Updated the Rogue Shooter example to use auto-batching with a toggle to see the performance difference.

Flame-AutoBatch.mp4

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

Introduce protected renderChild(Canvas, Component) to centralize per-child rendering (propagates parent's render contexts to the child and cleans them up). Add afterChildrenRendered(Canvas) as a hook to flush state after all children are rendered (useful for batching). Update renderTree to delegate child rendering to renderChild and call afterChildrenRendered once after the child loop.
Introduce `HasAutoBatchedChildren`. The mixin batches eligible `SpriteComponent` and `SpriteAnimationComponent` leaf children into per-atlas `SpriteBatch` draws (using `RSTransform`) to reduce draw calls, while preserving render order by flushing at priority-group boundaries and after children. Eligibility checks reject non-uniform scale, decorators, snapshot caching, complex paint effects, and non-leaf or non-sprite children. Adds a runtime `batchingEnabled` toggle, per-image accumulators reused across frames, and safe fallbacks to individual rendering when batching is not possible.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an auto-batching mechanism for sprite rendering to reduce draw calls, by adding a HasAutoBatchedChildren mixin and extending the core Component rendering pipeline with child-level interception hooks. It also updates the Rogue Shooter example to demonstrate the feature with a runtime toggle, and adds tests to validate batching behavior.

Changes:

  • Added HasAutoBatchedChildren mixin to batch eligible SpriteComponent / SpriteAnimationComponent children via Canvas.drawAtlas.
  • Extended Component with renderChild and afterChildrenRendered hooks to enable clean per-child render interception and post-pass flushing.
  • Updated Rogue Shooter example to organize sprites into batching groups and toggle batching via keyboard input; added comprehensive batching tests.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/flame/lib/src/components/mixins/has_auto_batched_children.dart New mixin implementing automatic sprite batching with eligibility checks and per-priority flushing.
packages/flame/lib/src/components/core/component.dart Adds render pipeline hooks (renderChild, afterChildrenRendered) used by batching and similar features.
packages/flame/lib/components.dart Exports the new HasAutoBatchedChildren mixin from the public API.
packages/flame/test/components/has_auto_batched_children_test.dart New tests validating batching behavior, eligibility rules, and render-order correctness.
examples/games/rogue_shooter/lib/rogue_shooter_game.dart Introduces BatchGroups, batching toggle UI/keyboard control, and adjusts component counting.
examples/games/rogue_shooter/lib/components/star_background_creator.dart Routes star creation into the new starGroup batch group and adds typed game reference.
examples/games/rogue_shooter/lib/components/player_component.dart Routes bullets/explosions into batch groups and adds typed game reference.
examples/games/rogue_shooter/lib/components/enemy_creator.dart Routes enemies into enemyGroup and adds typed game reference.
examples/games/rogue_shooter/lib/components/enemy_component.dart Routes explosions into explosionGroup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix render-context cleanup in `Component.renderChild` to use the child's original context length
- Accumulators key by `Image` (instead of identity hash)
- Allow `ShapeHitbox` children to render hitbox debug visuals when needed
- Add stricter eligibility checks (decorator constraints, and excluding non-srcOver blend modes)
- Minor test string updates and removal of an unused import in the example.
@ufrshubham ufrshubham requested a review from a team March 8, 2026 03:40
@ufrshubham ufrshubham force-pushed the devkage/auto-batching branch from 75c6855 to 913d93a Compare March 8, 2026 03:43
Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

Lgtm! Just stylistic comments

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

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

Lgtm!

@ufrshubham ufrshubham merged commit a2b7f93 into main Mar 13, 2026
69 checks passed
@ufrshubham ufrshubham deleted the devkage/auto-batching branch March 13, 2026 09:16
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.

4 participants