-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Volunteer: Framebuffer.get_rect_raw(x,y,w,h) #7750
Comments
This could benefit all displays, not just eink. When extracting the “window” rectangle, you may need to align the x or y in steps that match the byte orientation of the display. Only an issue for mono or greyscale displays where 1x framebuf byte is more than 1x pixel on the display. |
@mcauser My first goal is to come up with a function for BW display coding. Also I have only the esp32 facility to test the code. Any comments appreciated Volker |
While I see the merits of this it would be good to get some input from the maintainers. Any enhancements to framebuf inevitably add bytes, so there is a tradeoff between functionality and size. I'd be interested in adding graphics primitives (circle (ellipse?), fill_circle, triangle, fill_triangle) but haven't submitted a PR because of doubts whether the increased size would be acceptable. It would be good to see a plan for framebuf prioritising features to add. Possibly the maintainers consider it complete. |
Dear @peterhinch A second thought: Why is framebuf in the micropython core at all? Not all systems utilizing micropython have a graphical display. It makes sense to put things like the machine lib in the core as well as the RTC and other hardware drivers. But frambuf is an 'abstract' dataclass not bound to hardware at all. So I hope that we can agree that the best option would be to separate framebuf out of the core. In that case the core becomes smaller and the framebuf users get more functionality (e.g. circles) without bloat in the core. A second option may be to write a mpy-module which adds the missing output-functionality to a given buffer instance. But I do not like this since IMHO this functionality is a crucial part of the framebuffer. [Imagine a desktop manager which can only write to the display and is not capable to read rectangle regions efficiently back.] I will come up with a PR for implementing the missing functionality in the core. Then it is the decision of the community if the PR will find its way eventually into the core. Cheers, |
How about:
I just finished micropython functions for these, triangle width option is missing yet but WIP.
I do not fully understand the original intent behind @volkerjaenisch s request for Nice regards, Raul |
Correctly! E-Ink displays are quite slow - a complete refresh can take a good portion of a second. So to use them interactively or with rapid updates one needs partial updates, which are well supported by these displays. The art is to stream the partial update as a byte stream via SPI. And even if the performance in the ESP32 class of controller is available to do it in Python on smaller controllers it may be not. And in any case I like to build software as
The architecture of the framebuffer code is good. For each display low level byte orientation there is a special driver. This is cool since to refresh your display you only have to copy the bytes of the whole buffer and bang the display is refreshed. But on partial updates you have border problems which lead to bit banging which is not really effective to solve in Python. Also the rotation of bit fields is better done in C than in python. Cheers, |
Hi Volker, thank you for the explanation. |
You are welcome |
Dear @peterhinch I am a bit rusted (25 years no contact) in C. So I looked for the implementation of fill_rect which is in a way the inverse function to my proposed get_rect_raw function. The most simple case is the horizontal aligned buffer you implemented in 2017.
Reviewing your code I noticed:
In my fork https://github.com/Inqbus/micropython/blob/master/extmod/modframebuf.c I optimized your code by a factor of five in runtime, at the cost of 160 additional bytes at a total of 1521456 Bytes. My test routine instantiates two buffers. One with your method and a second with my method. Then 100 random fill_rect operations will be made to the two buffers. I think that this is a fair test. The controller is under stress and not in a particulary nice condition to be measured.
Results:
Mean/standard-deviation normal (335.13, 407.4322) fast (70.56, 57.20432) Normal is your code, fast is mine.You may like to notice that the standard deviation in your code is above the mean. In my code it is a bit below. This states for robustness of my algorithm. My optimization is not done. Theoretically a factor of eight can be gained against your implementation but I only achieved 4.7. As I said, I am not familiar with C. Coming back to your point of code bytes.
Don't get me wrong. I am solely interested in clear documented code on which I base my fortune. Cheers, |
That was the idea. In general MP is optimised for size rather than performance.
When submitting a PR I follow the project guidelines. Comments are used for code which is not readily understood by an experienced C programmer. Comments that explain C are considered to be noise.
The aim is to be much faster than Python in the smallest number of bytes. Congratulations on optimising for performance. By all means submit a PR: it's up to the maintainers whether to prefer fast or small. I will not get involved in debate on the merits of these MP conventions. I am not a maintainer. |
Dear @peterhinch Sorry for the whole disturbance. It is my fault. I did not read the manual. Sorry for the criticism of your code. Your code is perfect for a Code-ROM constricted environment.
IMHO these Guidelines are Bullshit. Any code in any language has to be documented, thoroungly. But your famous 8 lines of code express an algorithm. This algorithm goes straight against all normal tackling of the problem. You roll up the problem in columns while the data structure is organized in rows. This is no straight forward code. This has to be explained. And IMHO any algorithm has to be documented. And in most cases the paper where the algorithm has come from has to be cited. Just look at the C-Python code for a positive example. Sorry for exposing you here. My critic holds for the whole micropython core. Cheers |
Add Lilygo TTGO T-display ESP32 board
Hi Micropython People! You are doing a great job!
I am currently developing a MicroPython Eink-Driver for the popular DollaTek T5 Microcontrollers.
My code heavily depends on the framebuffer lib of micropython.
Eink-Displays are quite slow. So the usual way to deal with them is to make partial updates of the display from the framebuffer: Copying a rectangle of the framebuffer to an rectangle in the display.
So I crave for a framebuffer method
get_rect_raw(x,y,w,h)
which returns the raw pixel information of the given area as a byte stream.
For BW this is easy, but with color/intensity things become complicated, since there are quite different pixel representations.
But I think that the functionality to extract a rectangle of the framebuffer as byte-stream is a nice feature to boost performance. Even if the byte-stream has to be postprocessed for the pixel encoding on the python side it is an order of magnitude faster than to query each pixel independently.
I volunteer to come up with a BW pull request.
I am aware that E-Ink displays are slow and that the framebuffer even queried from python by pixel will never be the bottleneck. But why not make the code better?
Cheers,
Volker
The text was updated successfully, but these errors were encountered: