prometeu-runtime/discussion/workflow/decisions/DEC-0019-host-desktop-frame-pacing-and-presentation.md

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
PLN-0036
perf
host
desktop
frame-pacing
presentation
debug

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:

  1. 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".
  2. Politica do event loop

    • O host desktop MUST sair de ControlFlow::Poll como politica padrao.
    • O event loop SHOULD operar em modo de espera dirigida por deadline ou evento, usando WaitUntil para o proximo slice logico quando houver trabalho temporal agendado e Wait quando nao houver deadline imediato.
    • Poll MAY existir apenas em modo explicitamente opt-in de profiling/diagnostico host-owned e MUST NOT ser o comportamento normal de execucao.
  3. 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.
  4. 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.
  5. 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.md deve 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.md deve 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 Poll para 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

Propagacao Necessaria

  • Escrever um PLN para 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.