9.0 KiB
| id | ticket | title | status | created | accepted | agenda | plans | tags | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DEC-0019 | perf-host-desktop-frame-pacing-and-presentation | Decision - [PERF] Host Desktop Frame Pacing and Presentation | accepted | 2026-04-20 | 2026-04-20 | AGD-0009 |
|
|
Status
Accepted. This decision is now normatively locked and is ready to drive planning and execution.
Contexto
O host desktop atual usa ControlFlow::Poll, pede redraw continuamente e reapresenta o framebuffer mesmo quando a maquina nao publicou um novo frame logico.
Esse comportamento conflita com o modelo temporal de docs/specs/runtime/01-time-model-and-cycles.md, onde a maquina opera em frames logicos de 60 Hz, e com o contrato de portabilidade e isolamento de debug em docs/specs/runtime/10-debug-inspection-and-profiling.md e docs/specs/runtime/11-portability-and-cross-platform-execution.md, onde apresentacao e overlay pertencem ao host, mas nao devem redefinir a semantica logica da maquina.
O problema a ser fechado aqui nao eh o desenho final do backend grafico. O problema eh definir quando o host desktop tem permissao para acordar, converter e apresentar pixels sem transformar a shell desktop em um loop de polling agressivo.
Decisao
O host desktop SHALL adotar pacing orientado por frame logico publicado e por eventos externos relevantes, e MUST NOT manter redraw continuo por padrao.
Normas desta decisao:
-
Gatilho canonico de redraw
- O host MUST considerar um novo frame logico publicado como gatilho principal de apresentacao.
- O host MAY solicitar redraw adicional quando houver evento externo relevante que altere apenas a superficie host-owned, incluindo resize da janela, expose/invalidate da janela, toggle de overlay, atualizacao visivel do debugger ou mudanca de estado local da shell.
- O host MUST NOT solicitar redraw continuo apenas para "ver se existe frame novo".
-
Politica do event loop
- O host desktop MUST sair de
ControlFlow::Pollcomo politica padrao. - O event loop SHOULD operar em modo de espera dirigida por deadline ou evento, usando
WaitUntilpara o proximo slice logico quando houver trabalho temporal agendado eWaitquando nao houver deadline imediato. PollMAY existir apenas em modo explicitamente opt-in de profiling/diagnostico host-owned e MUST NOT ser o comportamento normal de execucao.
- O host desktop MUST sair de
-
Conversao de framebuffer
- A conversao RGB565 -> RGBA8 permanece full-frame nesta fase.
- Essa conversao MUST acontecer apenas quando houver novo frame logico publicado ou quando um evento host-owned exigir recomposicao/apresentacao da superficie visivel.
- Dirty-region conversion e offload para shader/GPU ficam explicitamente fora do contrato desta decisao e poderao ser avaliados em discussao separada se o full-frame on-demand ainda for insuficiente.
-
Modo ocioso, pausa e debug
- Quando a VM estiver pausada, em breakpoint, esperando
start, ou sem cart carregado, o host MUST preservar o ultimo frame visivel valido e MUST NOT ficar redesenhando continuamente. - Nesses estados, redraw adicional so pode ocorrer por evento host-owned relevante, como overlay/debug data visivel, resize/expose ou transicao explicita de estado.
- Buffers logicos da maquina MUST NOT ser trocados durante pausa apenas para sustentar HUD host-owned.
- Quando a VM estiver pausada, em breakpoint, esperando
-
Sinal de "novo frame disponivel"
- O runtime/host boundary MUST ter um ponto canonico de observacao do "frame pronto", alinhado ao momento em que o frame logico e publicado para apresentacao.
- A implementacao inicial MAY usar um sinal explicito, contador monotonicamente crescente, dirty flag ou observacao do ponto de swap/publicacao, desde que a semantica seja unica e nao ambigua.
- Essa decisao MUST NOT introduzir uma ABI guest-visible nova. O sinal pertence ao boundary interno runtime-host e as superficies host-owned de inspecao.
Rationale
Poll com redraw continuo mascara custo de apresentacao, consome CPU sem beneficio visual e reduz a utilidade do desktop como referencia de comportamento energetico razoavel.
Ao mesmo tempo, a shell desktop nao deve ser tratada como uma plataforma "ultra-conservadora" a ponto de perder ergonomia de debug. Por isso a decisao nao proibe redraw extra; ela apenas restringe redraw extra a eventos com causa concreta e visivel.
Manter a conversao full-frame por enquanto evita reabrir a arquitetura de renderizacao durante um trabalho cujo alvo principal eh pacing. O ganho imediato vem de parar de converter e apresentar quando nada mudou. Se isso nao bastar, dirty regions ou shader path podem ser discutidos depois com evidencias.
Separar "frame logico publicado" de "overlay host-owned mudou" preserva o contrato de portabilidade: o host pode mostrar mais informacao tecnica sem forcar a VM a produzir frames adicionais nem adulterar o framebuffer logico.
Invariantes / Contrato
- A maquina continua definindo frames logicos em 60 Hz; o host nao redefine esse relogio.
- O host apresenta o ultimo frame logico publicado; ele nao inventa frames intermediarios.
- Overlay e debugger sao host-owned e MAY compor sobre uma superficie de apresentacao host-only.
- Overlay/debug MUST NOT exigir redraw continuo quando seu conteudo estiver estavel.
- Conversao/presentacao do framebuffer MUST ser dirigida por mudanca observavel, nao por polling agressivo.
- O boundary runtime-host MUST expor um criterio unico para detectar publicacao de frame logico.
- Esta decisao nao promove dirty regions nem GPU offload a contrato normativo.
- Esta decisao nao altera semantica guest-visible de
DRAW, buffers logicos, ciclos, ou telemetria de certificacao.
Alternativas Descartadas
Manter Poll permanente no desktop
Descartado porque esconde custo real de apresentacao, desperdiça CPU e cria uma shell cuja estabilidade aparente depende de trabalho inutil.
Redraw orientado apenas por vsync fisico
Descartado como contrato canonico porque o modelo PROMETEU e dirigido por frame logico e a portabilidade nao depende de sincronizar a semantica da maquina a uma frequencia fisica do host.
Reabrir o problema com dirty regions ou shader path como pre-condicao
Descartado nesta etapa porque mistura otimizacao secundaria com o contrato principal de pacing. O problema imediato pode e deve ser resolvido sem nova arquitetura de render backend.
Impactos
Spec
docs/specs/runtime/10-debug-inspection-and-profiling.mddeve refletir que a apresentacao host-owned observa frame publicado e nao requer redraw continuo para HUD/overlay estavel.docs/specs/runtime/11-portability-and-cross-platform-execution.mddeve explicitar que a superficie host de apresentacao pode recompor overlay por evento relevante, sem transformar isso em polling permanente.
Runtime
- O runtime pode precisar expor ou estabilizar um ponto interno de publicacao de frame pronto para o host desktop consumir de forma canonica.
- Nenhuma nova ABI guest-visible deve ser criada por este trabalho.
Host Desktop
- O loop winit deve migrar de
Pollpara espera dirigida por deadline/evento. request_redraw()deixa de ser incondicional no ciclo de idle.- A apresentacao passa a depender de novo frame logico ou evento host-owned relevante.
Firmware
- Sem mudanca de semantica guest-visible.
- Estados de pausa/breakpoint continuam impedindo avanco de tempo logico e swap de buffers logicos.
Tooling
- Overlay/debugger continuam host-owned, mas precisam declarar quando realmente invalidam a superficie visivel.
- Profiling host-only pode manter um modo opt-in de polling agressivo, separado do comportamento normal.
Referencias
- AGD-0009
- docs/specs/runtime/01-time-model-and-cycles.md
- docs/specs/runtime/10-debug-inspection-and-profiling.md
- docs/specs/runtime/11-portability-and-cross-platform-execution.md
- runner.rs
Propagacao Necessaria
- Escrever um
PLNpara implementar a mudanca no host desktop. - Atualizar as specs normativas citadas para refletir este contrato.
- Ajustar o host desktop para consumir um gatilho canonico de frame publicado.
- Adicionar testes para:
- ausencia de redraw continuo sem frame novo;
- redraw em evento host-owned relevante;
- preservacao do ultimo frame em pausa/breakpoint/no-cart;
- modo opt-in de polling apenas quando explicitamente habilitado.
Revision Log
- 2026-04-20: Initial draft from AGD-0009.
- 2026-04-20: Accepted and linked to PLN-0036.