-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Un update of a vectorio object palette slow down the microcontroller indefinitely #9666
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
Comments
I suspected this was the palette being marked dirty and then never cleared. BUT it looks like it should be cleared. There may be a bug further upstream that is preventing the palette dirty bit from being cleared. |
I'm learning how this works, but what I see is that when the palette is modified, the shape is not impacted: circuitpython/shared-module/vectorio/VectorShape.c Lines 502 to 503 in ad73d0b
Causing this section to be executed: circuitpython/shared-module/vectorio/VectorShape.c Lines 541 to 545 in ad73d0b
However it's circuitpython/shared-module/vectorio/VectorShape.c Lines 478 to 480 in ad73d0b
I tried adding a test for the palette's "needs refresh" to make So maybe we should set the dirty bit in I tested this and it does fix this issue. index 75e1de8b96..51e7e0a9da 100644
--- a/shared-module/vectorio/VectorShape.c
+++ b/shared-module/vectorio/VectorShape.c
@@ -539,6 +539,7 @@ displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_
self->ephemeral_dirty_area.next = tail;
tail = &self->ephemeral_dirty_area;
} else {
+ self->current_area_dirty = true;
self->current_area.next = tail;
tail = &self->current_area;
VECTORIO_SHAPE_DEBUG("%p get_refresh_area: redrawing current: {(%3d,%3d), (%3d,%3d)}\n", self, self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); My test code uses auto refresh False and measures how long display.refresh() takes drawing a big circle before and after changing a value in the palette. import time
import board
import displayio
import vectorio
display = board.DISPLAY
main_group = displayio.Group()
display.root_group = main_group
display.auto_refresh = False
pal = displayio.Palette(1)
pal[0] = 0xFF0000
shape1 = vectorio.Circle(pixel_shader=pal, x=display.width//2, y=display.height//2, radius=min(display.width,display.height)//2)
main_group.append(shape1)
def measure_sleep(texte):
t0 = time.monotonic_ns()
display.refresh()
t1 = time.monotonic_ns()
dt = (t1 - t0) // 1_000_000
print(f"{texte}: {dt:3d} ms")
while True:
print("\n" + "#"*70)
measure_sleep("Initial display ")
measure_sleep("Refresh no changes ")
time.sleep(0.5)
pal[0] = 0x0000FF
measure_sleep("Switched color ")
measure_sleep("Refresh no changes ")
measure_sleep("Refresh no changes ")
time.sleep(4)
# reset
pal[0] = 0xFF0000
main_group.remove(shape1)
main_group.append(shape1) Before:
After:
|
Good sleuthing @Neradoc! I think your fix would be great! We need to make sure all users of palette do this too. |
Uh oh!
There was an error while loading. Please reload this page.
CircuitPython version
Code/REPL
Behavior
Description
There's something wrong with the vectorio display update, once the palette color change the microcontroller slow down and never recover. To replicate the bug I made the above example.
First the script run an emty loop and measure how many loops are performed in a second. It runs about 65k loops per second,
After the script create a rectangle with vectiorio as big as the screen and measure the looping time again. Now it runs about 75k loops per second. It make sense, the display do not show anymore the console.
Finally the script change the palette color of the rectange and measure for the third time the empty looping time. The loops per second drop below 9k and never recover even after the screen updates are done
Additional information
No response
The text was updated successfully, but these errors were encountered: