Repository navigation
Conversation
Partial screen updates need a compact description of the areas that must be repainted. DisplayDamage collects up to eight rectangles clipped to the screen, drops rectangles already covered and, once full, merges new ones into the rectangle that grows the least, so the set is always a superset of what was added while staying bounded in size. rows_span() serves drivers that transfer whole lines or 8-row pages. Signed-off-by: Davide Bettio <davide@uninstall.it>
Partial updates need the areas where the new display list differs from the one on screen. Items are matched as a common subsequence, comparing fields but never image pixels (a different buffer counts as a change, to keep updates quick); shapes compare by geometry and scaled images include their flips. The bounding box of every unmatched item is damaged, so pixels outside the damage keep their color. Signed-off-by: Davide Bettio <davide@uninstall.it>
Partial updates need the binaries of the previous display list to stay valid until the next list has been compared against it. Let the driver's process_message_fn return whether it kept the message, and have the task dispose it only when it did not. Every driver still returns false, so nothing changes yet. Also leave a note in the e-paper driver about skipping refreshes of identical display lists once it adopts the shared frame state. Signed-off-by: Davide Bettio <davide@uninstall.it>
The scanline renderer implicitly stopped at the screen width. Partial updates need to stop at the right edge of the area being repainted, so make the limit an explicit x_end argument. Every caller passes the screen width, no behavior change. Signed-off-by: Davide Bettio <davide@uninstall.it>
Partial updates need to know what is on screen: the items of the last update, the message owning the binaries they point to, and the areas the next update must repaint regardless of the diff. Keeping the message alive until the next commit is what makes comparing image data by pointer sound: libAtomVM shares reference counted binaries across message copies, so the same binary yields the same pointer frame after frame and nothing the old items point to is freed meanwhile. No driver uses it yet. Signed-off-by: Davide Bettio <davide@uninstall.it>
Use the shared display_frame and display_diff modules: only the areas that differ from the previous frame are rendered and copied to the SDL surface, and identical lists cost nothing. Pixels no item covers are black, so the output is a pure function of the display list. AVM_SDL_DISPLAY_VERIFY_DAMAGE=1 renders every frame again from scratch and reports pixels differing from the incrementally updated frame buffer; test_damage.erl exercises it, headless with SDL_VIDEODRIVER=dummy. Signed-off-by: Davide Bettio <davide@uninstall.it>
Use the shared frame state to repaint just the rectangles that changed, each through its own CASET/PASET window: a changing label costs a few scanlines instead of a whole frame and an identical list costs no SPI traffic. The window is set before acquiring the bus and the last DMA transfer awaited before releasing it, since the bus lock is not reentrant and the DC line must not toggle during a transfer. Pixels no item covers are cleared to black, so the panel content depends only on the display list. The area painted by draw_buffer is invalidated so the next update repaints it. The profiling line gains the rectangle count and the pixels sent. Signed-off-by: Davide Bettio <davide@uninstall.it>
Use the shared frame state and skip the 8-row pages the damage does not touch. Touched pages are still sent in full, so the I2C addressing does not change. Signed-off-by: Davide Bettio <davide@uninstall.it>
Sharp memory LCDs address lines individually, so use the shared frame state to render and send just the lines the damage touches. When nothing changed, send the two-byte VCOM-only frame so VCOM keeps alternating on every update as before. Both DMA buffers are always allocated, so the dead single buffer path is removed. Signed-off-by: Davide Bettio <davide@uninstall.it>
Describe what each driver repaints, that uncovered pixels are black on the DCS LCDs and SDL, how draw_buffer interacts with updates, and how to run the host unit tests and the headless SDL verification. Signed-off-by: Davide Bettio <davide@uninstall.it>
mono_draw_x leaves pixels no item covers untouched, and the bitmap it draws into was cleared only once per page: a lit pixel smeared down to the end of its page wherever nothing covered the rows below it. Uncovered pixels are now off, as documented. Signed-off-by: Davide Bettio <davide@uninstall.it>
The items, the ufont bitmaps, the message heap and a reference on every binary in the list stay allocated between updates, which only pays off while updates keep coming. After 10 seconds without messages the display task releases them and the next update repaints the whole screen, as the first one does. Applications refreshing less often pay one full repaint per update, as they did before partial updates; interactive ones never idle that long. Signed-off-by: Davide Bettio <davide@uninstall.it>
The ESP32 display task unregisters a font on deregister_font; the SDL plugin reported the command as unexpected, so a font could not be replaced under the same handle on the host.
Text drawn with a ufont is rasterized into a new buffer on every update, so comparing buffer pointers found it changed every time and it was repainted on every update. The item now keeps the text, the font handle and the color its pixels are a function of, and two rasterizations of the same source compare equal. Registering or unregistering a font bumps a generation the item records too, so text rasterized before a font was replaced under the same handle is repainted.
A retained display list is compared with the next one, never drawn, so the bitmaps of its ufont texts were kept for nothing: at four bytes per pixel they outweighed everything else the frame holds. Parsing now only measures the text; each driver rasterizes the texts inside the area it is about to draw before sending the first row, so an unchanged label outside the damage costs a measurement instead of a zlib inflate per glyph and a bitmap, and the pixels are released at commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every update rendered and transferred the whole screen, even when a
single label changed. The drivers now keep the last display list,
compare the new one with it and repaint only the areas that differ, so
an identical list costs nothing. The retained list is released after
10 seconds without messages.
Pixels no item covers are now black on the DCS LCDs and SDL and off on
OLEDs. Memory LCD and OLED paths are compile-tested only.
See also: #20, #23