perf(preview): throttler le seek du <video> caché pendant un scrub natif en pause - #210
perf(preview): throttler le seek du <video> caché pendant un scrub natif en pause#210EtienneLescot wants to merge 1 commit into
Conversation
…tif en pause Le `<video>` de VirtualPreview ne dessine plus rien : le canvas natif D3D est la seule source de pixels et l'occulte. Le `<video>` reste monté uniquement pour l'horloge de lecture, le son et la metadata. Or pendant un scrub EN PAUSE, l'effet `seekTarget` posait `video.currentTime = …` à chaque pas (~60 Hz, cadence du rAF de scrub), donc un décodage GPU par pas — pour des pixels jamais montrés et sans son. Ce décodage double exactement celui que fait déjà le compositeur natif (piloté séparément par `useNativePlaybackSync` → `setNativeTime`, depuis le store). C'est du pur gaspillage, et le vrai coût GPU d'un scrub. On throttle donc ce seek à ~15 Hz (bord de fuite garanti), ce qui supprime ~3/4 des décodages dupliqués. Le `<video>` reste à ≤~66 ms de la position — imperceptible pour un Play qui suit, car `togglePlay` ne re-seek pas : il lit `video.currentTime` tel quel. Le bord de fuite garantit qu'aucun scrub ne laisse le `<video>` sur une position périmée après relâchement (sinon départ audio décalé au Play). Le `<video>` webcam suit indirectement : son rAF chasse l'horloge publiée par l'écran, qui n'avance plus qu'à ~15 Hz → il se re-seek d'autant moins. Strictement borné au cas où c'est redondant : - LECTURE → le `<video>` est l'horloge maître + la source audio : seek immédiat, inchangé. - natif ABSENT (dev web, addon en échec) → le `<video>` EST la preview visible : immédiat. - seeks SOURCE (rares, discrets) : non throttlés. Rien de visible ne change : le natif affiche déjà le scrub à pleine cadence. Le gain est indirect — moins de contention GPU pendant le scrub — à confirmer à la sonde. Vérifié : tsc, biome, 72/72 src/components/ai-edition dont 2 nouveaux tests (coalescence + bord de fuite quand natif actif & en pause ; immédiat sinon).
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Fermée volontairement. Gain non mesurable : le coût du scrub est dominé par la réouverture des décodeurs au franchissement de clip (voir #209, décodeur pool), que ce throttle ne touche pas. Et le correctif fait dépendre VirtualPreview (jusqu'ici agnostique du natif) du store natif — un couplage qui ne se justifie pas pour une redondance imperceptible. On rouvrira si un profil futur montre le décodage |
Contexte
Le
<video>deVirtualPreviewne dessine plus rien : le canvas natif D3D est la seule source de pixels et l'occulte. Le<video>reste monté uniquement pour l'horloge de lecture, le son et la metadata. Or pendant un scrub en pause, l'effetseekTargetposaitvideo.currentTime = …à chaque pas (~60 Hz, cadence du rAF de scrub) → un décodage GPU par pas, pour des pixels jamais montrés et sans son. Ce décodage double exactement celui que fait déjà le compositeur natif (piloté séparément paruseNativePlaybackSync→setNativeTime, depuis le store). Confirmé par instrumentation : le readback natif bloque ~9 ms/frame ; ce<video>fantôme ajoute un décodage complet du même fichier par-dessus, en pure perte.Le correctif
On throttle ce seek à ~15 Hz (bord de fuite garanti) uniquement dans le cas où il est redondant :
<video>est l'horloge maître + la source audio : seek immédiat, inchangé.<video>EST la preview visible : immédiat.Le
<video>reste à ≤ ~66 ms de la position — imperceptible pour un Play qui suit, cartogglePlayne re-seek pas, il litvideo.currentTimetel quel. Le bord de fuite garantit qu'aucun scrub ne laisse le<video>sur une position périmée après relâchement. Le<video>webcam suit indirectement (son rAF chasse l'horloge de l'écran, qui n'avance plus qu'à ~15 Hz).Honnêteté sur le gain
Rien de visible ne change : le natif affiche déjà le scrub à pleine cadence. Le gain est de la charge GPU en moins (un décodage dupliqué supprimé aux ¾). Il n'est pas isolable à la sonde — le coût d'un scrub est dominé par les franchissements de clip (voir la PR pool de décodeurs), qui le noient. Ce commit se justifie donc comme suppression d'une redondance prouvée, à downside nul, pas comme un gain de fluidité chiffré. C'est le plus petit des deux leviers ; à prendre ou laisser selon l'appétit pour un diff sûr mais non mesurable.
Vérification
tsc --noEmitpropre, biome propre (re-vérifié après rebase sur la base courante).VirtualPreview: coalescence des seeks rapprochés + bord de fuite quand le natif est actif & en pause ; application immédiate sinon (les deux chemins sont bien distingués).