Open jepler opened 4 years ago
I had started work changing the progress bar implementation over to vectorio the other day but ran into trouble.
I think with the absolute latest builds of the system the required fixes inside vectorio are in and I made a few more fixes in my working branch of the library.
I've created #11 with those changes. I did end up seeing a decent memory reduction with that approach.
What do you think about vectorio.Polygons vs. the wider tilemap with slices? I don't think I grok enough of the larger picture to know which is likely to be more efficient.
I think vectorio has a good shot at being more efficient, but if compatibility with 5.x is desired then there might have to be two sets of code...
Ah, I definitely overlooked the compatibility issue. I think it would be good to offer backward compatibility at least for a while.
Same with Blinka until there's a vectorio module added.
I think a TileGrid with multiple tiles will be more efficient than a bitmap if the height of the bar is more than 8 because TileGrid allocates a byte for each tile it shows.
vectorio
or displayio.Shape
will be much more efficient because they just save bounds, not each pixel.
Is there any further documentation or an example of how to use displayio.Shape
? From the docs here: https://circuitpython.readthedocs.io/en/latest/shared-bindings/displayio/#displayio.Shape I'm not sure how to create one and get it showing on the screen.
I have a test somewhere but I can probably describe it.
You can use it in place of a Bitmap. Instead of storing each pixel, it stores a start and stop x value for every y. x values in the range are 1 and the rest are zero. In other words, for every row, you can store one range of "on" pixels.
This makes it easy to store a solid shape. With mirror_x and mirror_y you can define a half or quarter of the shape instead and have it mirror the pixel ranges (creating two stretches of pixels per row and therefore outlines of symmetric shapes).
set_boundary
is used to set that x range for a given row. (and wow, the docs of set_boundary
aren't right) I meant to add the index ability that would be ok as long as you set a pixel to 1 if it's adjacent to a 1.
A rectangle would be something like:
s = displayio.Shape(w, h, mirror_x=True, mirror_y=True)
for y in range(h // 2):
s.set_boundary(y, 0, (w + 1) // 2)
You can then also alter the start of the first few rows to round the corners too.
The ProgressBar is a 1×1 tilegrid configured to display a W×H bitmap. Instead, it could be a W×1 tile grid, displaying 1×H slices from a 3×H bitmap.
Three tall elements are needed: One which is entirely the outline color; one which is the outline color at the top and bottom and transparent/black in the middle, and one that is the outline color at the top and bottom and the bar color in the middle.
This should reduce memory consumption (from W×H to W+3×H times some constant) and speed updates, since a progress change P pixels wide would only have to update P tilegrid entries instead of P×H bitmap entries. (however, the amount of data actually sent over SPI/I2C to the display would not change)