Skip to content

Let the destination bus decide DMA for sprites; fix clipped images on Panel_AMOLED - #360

Merged
lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:sprite_dma_bus
Oct 16, 2026
Merged

lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:sprite_dma_bus

Conversation

@ainyan03

Copy link
Copy Markdown
Contributor

Let the destination bus decide DMA for sprites

  • pushSprite passed SpriteBuffer::use_dma() to the panel, deciding on the caller side whether the sprite buffer could be read by DMA. The bus already checks the source itself (SPI / parallel copy or use the CPU when the source is not DMA-capable), so pushSprite now always passes true and use_dma() is deprecated. Nothing new is read by DMA on the ESP32 family.
  • The meaning of use_dma is documented on Bus / Panel / LGFXBase::pushImage: true allows the bus to keep reading the caller's buffer until the transfer completes; false means the buffer is not read after the call returns. Wait on the destination with waitDMA() before reusing the buffer while startWrite() is held. pushImage keeps false and pushImageDMA keeps true.

Panel_AMOLED: clipped images

  • Rows of a horizontally clipped image were sent separately: with use_dma they were queued without the pixel-write start, and without it every row restarted the write (RAMWR), which rewinds to the window start. On a CO5300 panel driven without the frame buffer, a clipped pushSprite / pushImage drew nothing. The write is now started once and all rows go in that frame. (StopWatch normally draws through its frame buffer, so it was not affected in normal use.)

Testing

  • StopWatch with the frame buffer bypassed: a sprite clipped to its left half (internal RAM sprite, flash setBuffer sprite, pushImage from flash) matches the unclipped reference; before this change the clipped cases drew nothing.
  • Local build matrix of this repository's and M5Unified's CI versions (Arduino 2.x / 3.x, ESP-IDF 5.1 to 6.1, all chips) plus the native (SDL) build, with no deprecation warning from the library. CI on the fork: passed.
  • The same change is proposed to LovyanGFX (the shared lgfx/v1 sources).

When an image was clipped horizontally (its rows are not contiguous in the
source), Panel_AMOLED sent each row separately: with use_dma the rows were
queued without ever sending the pixel-write start, and without it every row
restarted the write (RAMWR), which rewinds to the start of the window. On a
CO5300 panel without a frame buffer, a clipped pushSprite or pushImage drew
nothing on either path. The write is now started once and every row is
streamed in that frame.
…r::use_dma()

pushSprite passed SpriteBuffer::use_dma() to the panel, deciding on the
caller side whether the sprite buffer could be read by DMA. The bus already
checks the source itself, so pushSprite now always passes true and
use_dma() is deprecated.

The meaning of use_dma is documented on Bus / Panel / LGFXBase: true
allows the bus to keep reading the caller's buffer until the transfer
completes (it copies or uses the CPU when it cannot read the source
directly); false means the buffer is not read after the call returns. Wait
on the destination with waitDMA() before reusing the buffer while
startWrite() is held. pushImage keeps false and pushImageDMA keeps true.
@lovyan03
lovyan03 merged commit 8a25eaf into m5stack:develop Oct 16, 2026
25 checks passed
@ainyan03
ainyan03 deleted the sprite_dma_bus branch October 16, 2026 03:20
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