new features : partial refresh, gallery thumbnail, SD file read and thumbnail generator#2
Open
pierrehenrymuller wants to merge 9 commits into
Open
new features : partial refresh, gallery thumbnail, SD file read and thumbnail generator#2pierrehenrymuller wants to merge 9 commits into
pierrehenrymuller wants to merge 9 commits into
Conversation
Pourquoi: en mode live alimente sur secteur, rafraichir tout l'ecran en GC16 (flash ~0.5-1s) a chaque changement de capteur est lent et visuellement penible. Le materiel IT8951 sait deja rafraichir un sous-rectangle avec une waveform rapide (DU mode 1, sans flash) mais le composant cablait update() en plein ecran. Approche: exposer deux methodes publiques sans casser l'existant. - full_refresh(): comportement historique (INIT mode 0 + GC16 mode 2), utilise au boot et pour le deghost nocturne; reset le compteur de partiels. - refresh_zone(x,y,w,h,mode=1): re-rend le framebuffer complet (pour refleter les valeurs courantes) puis ne pousse que le rectangle demande en DU. Conversion des coordonnees logiques vers panneau (framebuffer miroir en X) et alignement x/w sur 4px (contrainte 4bpp). Garde-fou: full_refresh force tous les 60 partiels pour purger le ghosting. update() delegue desormais a full_refresh(). Extraction de wake_panel_/sleep_panel_ pour mutualiser la sequence reveil/sommeil de l'IT8951. Alternatives ecartees: chemin 1bpp partiel (alignement 16px plus contraignant et re-packing complexe) -> on reutilise le slice direct du framebuffer 4bpp, byte-order identique au chemin plein ecran. Pas de patch du flux de sommeil (le panneau dort toujours entre rafraichissements: ~10ms de reveil, image bistable conservee). Impact: aucune regression sur le mode plein ecran; nouvelles methodes opt-in appelables depuis un lambda ESPHome. Securite: bornage/clamp des rectangles, buffer de ligne borne a 936 octets (largeur max 1872px en 4bpp).
Pourquoi: en mode live, refresh_zone() re-rendait le framebuffer complet (do_update_, lambda ~3.3s a cause des ecritures PSRAM) a CHAQUE zone. Un tick multi-zones bloquait la boucle principale ~12s (3 zones), gelant WiFi/API. Approche: separer le rendu (couteux, 1x) du push (rapide, par zone). - render_framebuffer(): execute la lambda une fois (remplit le framebuffer RAM). - flush_zone(x,y,w,h,mode=1): pousse seulement le rectangle, SANS re-rendre (suppose le framebuffer a jour). Coeur deplace depuis l'ancien refresh_zone. - refresh_zone(): devient render_framebuffer() + flush_zone() (zone isolee/event). Le YAML appelle render_framebuffer() une fois puis flush_zone() par zone -> un seul rendu par tick au lieu de N. Impact: tick multi-zones passe de ~N*3.3s a ~3.3s + N*0.4s. Pas de changement de comportement par zone; aucune regression plein ecran.
Mesure live: chaque flush_zone (DU) coute ~2.4s (sequencage d'alim EPD par appel DPY_AREA, inherent au panneau 10"), independamment de la taille -> N zones = N*2.4s. Le rendu (do_update_) coutait ~3.3s a cause de fill() qui bouclait pixel par pixel (~2.6M appels draw_absolute_pixel) pour l'auto-clear. Corrections: - fill(Color) override en memset sur le framebuffer 4bpp (nibble*0x11). L'auto-clear par frame devient quasi instantane -> rendu ~0.3s. - Consequence strategie: un DU PLEIN ECRAN (flush_zone(0,0,1872,1404,1)) coute ~le meme qu'une zone (~2.4s) et reste sans flash. Donc 1 DU plein ecran >> N zones. Le YAML rafraichit tout en un seul DU au lieu de decouper en zones. - MAX_PARTIALS_BEFORE_FULL 60 -> 180 (avec un DU/minute, GC16 toutes les ~3h au lieu de chaque heure). Impact: tick live ~0.3s (rendu) + ~2.4s (DU) au lieu de ~17s. Pas de regression plein ecran GC16 (deghost). fill() override est transparent pour le reste.
Phase A photos: lire un fichier .raw (1872x1404 4bpp, format exact du framebuffer) depuis la carte SD et l'afficher en 16 gris (GC16). - SD sur le bus SPI PARTAGE avec l'IT8951 (un seul maitre Arduino SPI, CS distincts: ecran=10, SD=14). Alim SD = GPIO39 (SD_EN) activee au setup. - setup(): SD.begin(14, SPI, 10MHz) apres l'init IT8951; flag sd_ok_. - show_sd_image(path): SD.open + lecture par blocs dans framebuffer_ (1.3 Mo), puis upload 4bpp + INIT + GC16. Reutilise wake/sleep_panel_. Risque connu (a valider sur hard): coexistence SD.h / Arduino SPI direct de l'IT8951 sur le meme bus. CS coordonnes, transactions sequentielles.
Pourquoi: le mode photo n'offrait qu'une navigation lineaire (suivante/precedente). Pour selectionner directement une image il faut une grille de miniatures cliquables. Generer une miniature a chaque affichage serait lent (lecture de tout le .raw plein ecran ~1,3 Mo par vignette); d'ou un cache SD. Approche: trois methodes publiques sur le driver IT8951. - make_thumbnail(src,dst): charge le .raw plein ecran dans le framebuffer (reutilise la boucle de lecture de show_sd_image), sous-echantillonne en nearest d'un facteur THUMB_FACTOR=4 (468x351) puis ecrit un .raw miniature 4bpp row-major LOGIQUE. - draw_sd_thumbnail(path,dx,dy): blit de la miniature dans le framebuffer au coin logique (dx,dy), sans declencher de refresh (a appeler depuis le lambda d'affichage). - sd_file_exists(path): test du cache (genere une seule fois par image). Helpers get_pixel_logical_/set_pixel_nibble_ pour rester en coordonnees logiques (le framebuffer stocke l'image inversee en X comme draw_absolute_pixel_internal), ce qui rend generation et blit symetriques: le mirror s'annule. Alternatives ecartees: generation hors-appareil via outil + recopie SD (impose de regenerer/recopier la carte a chaque ajout de photo); sous-echantillon a la volee sans cache (trop lent, relit toute la source a chaque rendu de menu). Compromis: nearest (pas de moyenne de bloc) -> vignettes un peu crues mais generation rapide; ~82 Ko par miniature sur SD. La generation ecrase le framebuffer (chargement de la source) -> make_thumbnail doit etre appele AVANT un rendu, jamais pendant. Impact: aucune regression sur show_sd_image (boucle de lecture inchangee, reutilisee). Bus SPI SD partage deja gere. Teste sur le modele E1003.
The driver added several public methods on top of the upstream art-frame flow (render_framebuffer/flush_zone/refresh_zone for flash-free partial updates, show_sd_image for network-free rendering from the SD card, and make_thumbnail/draw_sd_thumbnail/sd_file_exists for a cached gallery). None of these were documented, so adopters had to read the header to discover them. Add a reference section per feature plus an 'Interactive examples' section with copy-pasteable YAML: clock zone refresh, a touch button calling a HA action, a paginated thumbnail grid, and touch photo navigation. Documentation only, no code change; keeps the PR series self-explanatory for upstream review.
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.
Why
What
Public driver additions, with no change to the existing art-frame path:
render_framebuffer()+flush_zone(x, y, w, h, mode = 1)(and therefresh_zone()convenience) for partial-area DU updates with no full-screen flash.full_refresh()is kept for boot and the periodic deghost.show_sd_image(path): load a 1872x1404 4bpp.rawstraight from the microSD card (shared SPI bus) and push it in GC16, no network needed.make_thumbnail(),sd_file_exists(),draw_sd_thumbnail()for a paginated 3x3 gallery.Alternatives considered
online_imagepath): needs the network and HA up. The SD path keeps a photo frame working offline.Tradeoffs and impact
full_refresh()(documented).