Skip to content

Feature request: Draw at once #8

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

Open
tansiret opened this issue Mar 17, 2025 · 2 comments
Open

Feature request: Draw at once #8

tansiret opened this issue Mar 17, 2025 · 2 comments

Comments

@tansiret
Copy link

tansiret commented Mar 17, 2025

Hi, me again

I think the flickering issues can be boiled down to trying to draw layer upon layer. As far as I understand, old gaming consoles solve this by uniting different drawing layers on top of each other before drawing anything, then drawing the united 1 layer as the frame. Can this be achieved in the following pseudo code format?

hold(); //Command to tell the pico to hold draw information but not draw them

...
multiple tft draw etc;
...

draw(); //Draws the single frame where different colliding draw layers are united

Thanks for your incredible libraries and accessibility!

@gavinlyonsrepo
Copy link
Owner

Hi

You are taking about implementing a frame buffer.
I already use frame buffers in my one bit color library.

https://github.com/gavinlyonsrepo/displaylib_1bit_PICO

Required changes to implement concept are:

  1. A function to assign memory to buffer at start.
  2. A function to write the buffer to screen, in a single SPI buffer operation.
  3. A function to clear buffer, fill it with zeros.
  4. A function to destroy buffer object and de-allocate memory(optional)
  5. Modify the DrawPixel() function so its writes to buffer not screen ,taking rotation into account.

All easy. In theory it should result in higher FPS. The problem comes with the amount of memory required to hold frame-buffer. In the one bit color library for example for a screen 84x48. Width X Height/8 ,
only 504 (84 X 48/8) bytes are needed for frame buffer.

However for your specific 16-bit color use case, the required frame-buffer size can be calculated as:
Width × Height × Bytes per Pixel 128 × 160 × 2 = 40,960 bytes
for larger devices, the ili9341 for example, the problem becomes even more acute
Width × Height × Bytes per Pixel 240 ×320 × 2 = 153600 bytes

The large size means memory must be dynamically allocated on the heap. While ~41 KB may seem manageable, the RP2040 micro-controller only has 264 KB of SRAM, which is shared among all program variables, stack, and heap allocations. A full-screen frame-buffer would consume a large portion of available memory, leaving little room for other operations. Additionally, for effective double buffering, two such buffers would be needed, doubling the memory requirements to 81,920 bytes (≈80 KB), which is impractical for many applications. Using Heap allocations should generally be avoided on micro controllers due to implications of memory fragmentation , program stability, stack overflows.

I will have to conduct more research and testing in order to evaluate the technicality viability of this approach for the PICO.

@gavinlyonsrepo
Copy link
Owner

Hi

I have added a frame buffer mode in Version 2.1.0, available now. Link in main readme to the readme explaining how to use it. Its off by default.

I updated your demo it looks good now. I created a tile for the "sky" rather than use fillRectangle function() I think this removed the flickering. I will delete this repo once you download it. You could draw the upper part of sky as one big rectangle as well.
https://github.com/gavinlyonsrepo/super_mario_demo

Also note I have created a new function that can draw 8-bit colour bitmaps . These take up only half the room of 16-bit bitmaps at expense of colour resolution 256 colours instead of 65536.

regards

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

No branches or pull requests

2 participants