Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it faster #82

Open
svelterust opened this issue Oct 17, 2023 · 13 comments
Open

Make it faster #82

svelterust opened this issue Oct 17, 2023 · 13 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@svelterust
Copy link

Currently it is slow.

@almindor
Copy link
Owner

Could you provide more information please? Slow in which operation exactly and how would you propose to improve it?

@almindor almindor added enhancement New feature or request question Further information is requested labels Oct 17, 2023
@svelterust
Copy link
Author

It seems like the draw_continious trait implementations delegate to drawing pixel by pixel. Is it possibile to use hardware specific drawing methods instead? There's also quite a bit of tearing currently, any way to implement double buffering? In my case I use the ili9341 based on this code: https://github.com/almindor/mipidsi/blob/master/mipidsi/examples/spi-ili9486-esp32-c3/src/main.rs.

This library seems to provide super fast drawing for the same screen: https://github.com/vindar/ILI9341_T4

image

@svelterust
Copy link
Author

I can definitely help out writing the code, interested to see what we can achieve with this library.

@svelterust
Copy link
Author

I can implement following:

  • Double buffering
  • Differential redraws

Not sure exactly how these work:

  • Async DMA
  • VSync and screen tearing prevention by positioning scanline

@svelterust
Copy link
Author

Hardware specific methods like drawing rectangles using hardware commands is also something I could look into.

@almindor
Copy link
Owner

Feel free of course! Any help is most welcome.

From what I can say these things are doable without major rewrites or other crate changes:

  1. double buffering
  2. differential redraws
  3. vsync/tearing

However Async DMA would require adding support for the transport channel in display-interface and is I guess very MCU specific.

Also for things like diff redraw we need a big enough RAM amount. All such changes need to be feature gated (they could be default) because small RAM MCUs won't support them (e.g. my 16kb RAM one :D)

@fu5ha
Copy link

fu5ha commented Oct 18, 2023

VSync and screen tearing prevention by positioning scanline

I'm not familiar with all supported driver ICs but they're probably pretty similar to the ST7789. There are generally two methods. Both will use a separate input pin on the controller driven by an output from the display controller IC. That pin is usually called "TE" ("Tearing Effect") or sometimes VSYNC. It can be set in two modes.

The first is traditional "vsync" mode. In this mode, the TE line will be low when the display driver IC is reading its internal framebuffer and writing those values to the display. The TE line will be brought high for the duration that the driver IC is idle between frames, not reading its own memory. Thus our main controller mcu must write the full framebuffer into the display driver IC during the time the TE line is high to guarantee no tearing. This is usually a small fraction of a frametime.

The second is I believe what the library you refer to is describing. In this mode, the TE line will be brought high for the same vertical-blank period, but it will also be brought high for a pulse after the driver IC is done reading each scanline (horizontal row of pixels) from its memory and delivering it to the display. In the case of the ST7789 there will always be 320 hblank pulses + 1 vblank pulse per frame. If we keep track of which pulse we're at, we can know which are the valid memory locations our MCU can write into the driver IC's memory at any given time. We can therefore extend the time that we have to write a full frame, by "trailing" our memory writes behind where the IC is reading.

See ST7789VW section on "Tearing Effect" for more (start at page 132) https://www.waveshare.com/w/upload/a/ad/ST7789VW.pdf

@fu5ha
Copy link

fu5ha commented Oct 18, 2023

I'm also interested in helping to contribute some or all of these, fwiw :)

Doing it in a generic way sounds like it might be pretty tough though :P

@fu5ha
Copy link

fu5ha commented Oct 18, 2023

Well, looking closer at the driver you linked and ILI9341, that works differently for actually synchronizing but the idea of what's being accomplished is still as described

@fu5ha
Copy link

fu5ha commented Oct 18, 2023

Another note: IMO buffering and differential redraws are best left to another crate like embedded-graphics. This crate should just provide the ability to efficiently upload subregions of the display in a way that something like embedded-graphics can then leverage... This is already the idea of the embedded-graphics-core DrawTarget trait which this crate implements, I believe.

... that being said, trying to implement those externally and also take advantage of the trailing writes to the driver IC as described above sounds like it might not be possible, so maybe we do need to implement it in the driver.

@almindor
Copy link
Owner

Another note: IMO buffering and differential redraws are best left to another crate like embedded-graphics. This crate should just provide the ability to efficiently upload subregions of the display in a way that something like embedded-graphics can then leverage... This is already the idea of the embedded-graphics-core DrawTarget trait which this crate implements, I believe.

... that being said, trying to implement those externally and also take advantage of the trailing writes to the driver IC as described above sounds like it might not be possible, so maybe we do need to implement it in the driver.

That's a good point and I agree since those are more "on top of driver" operations.

@almindor
Copy link
Owner

Wanted to also add, if you could please join #rust-embedded-graphics:matrix.org channel on matrix. There are folks from embedded-graphics as well as display-interface. I feel like it'd be good to discuss some of this stuff in a more general way.

@almindor
Copy link
Owner

Related issue #142 although this one has a different optimization in mind so I'm keeping both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants