prometeu-runtime/discussion/workflow/agendas/AGD-0043-real-render-worker-establishment.md

11 KiB

id ticket title status created resolved decision tags
AGD-0043 real-render-worker-establishment Real Render Worker Establishment open 2026-06-06
runtime
renderer
worker
concurrency
host
hal
architecture

Contexto

DEC-0031 definiu o contrato arquitetural da fronteira VM/render. AGD-0042 preparou a fronteira host/hardware/render para que Hardware deixe de ser um objeto concreto atravessando o worker e passe a ser contrato/facades implementadas pelo host.

Esta agenda discute a implementacao do worker real propriamente dito, assumindo que a preparacao da fronteira ja foi resolvida antes da execucao.

Estado Atual Depois da AGD-0042

A preparacao de fronteira foi executada pelos planos PLN-0098 a PLN-0109:

  • HardwareBridge foi removido do codigo e deixou de ser contrato publico;
  • RuntimePlatform passou a ser a fronteira runtime-facing para render, input, audio, assets e telemetry;
  • RenderSubmissionSink aceita submissao owned;
  • Game2DFrameComposer separa fechamento logico de frame do backend de render;
  • syscalls gfx2d.* e gfxui.* bufferizam comandos e nao desenham imediatamente via Gfx;
  • firmware, Hub, runtime e host desktop passam por servicos de plataforma;
  • testes de runtime/firmware usam TestPlatform como fixture local;
  • specs de GFX/portabilidade documentam que o worker/render consumer nao deve depender de &mut Hardware, &mut Gfx, FrameComposer vivo ou estado mutavel da VM.

O estado atual ainda nao tem worker real. O LocalRenderWorker continua sendo o caminho local/cooperativo que consome RenderSubmission no mesmo processo. O proximo passo desta agenda e decidir onde vive o controller do worker real, qual handoff thread-safe ele usa, e qual backend renderizavel ele owns ou recebe.

Problema

O LocalRenderWorker atual e cooperativo/local. Ele prova o roteamento de policy, mas nao prova:

  • thread/core real;
  • ownership do backend renderizavel;
  • present loop;
  • stop token para current work;
  • bounded shutdown/join;
  • stale epoch durante rasterizacao;
  • erro tipado de render/present;
  • repeat real do ultimo frame valido;
  • ausencia de bloqueio da VM sob atraso do render.

Pontos Criticos

1. Ownership e lifecycle do worker

Precisamos decidir quem cria, inicia, para e reinicia o worker: runtime controller, host/HAL, ou ambos em contrato dividido.

2. Handoff real

O single-slot latest-wins ja existe como abstracao local. O worker real precisa de uma implementacao thread-safe, sem fila crescente e sem bloquear a VM.

3. Backend renderizavel

O worker deve owns um backend minimo ou receber capability host-owned. Esse backend deve consumir RenderSubmission, resolver recursos read-only e produzir/presentar frame sem &mut Hardware.

4. Present cadence

Precisamos decidir se o worker roda a 60Hz, se o host event loop dirige present, ou se ha uma autoridade separada de display cadence. Repeated present deve virar comportamento real, nao apenas hook.

5. Shutdown/current work

Quando houver uma submission em rasterizacao, shutdown e owner transition precisam impedir present obsoleto e terminar em tempo bounded.

6. Error model

Precisamos trocar o modelo infalivel/panic containment por erro tipado para render/present/worker failure.

7. Testes de concorrencia

Precisamos provar o contrato sem depender de janela nativa nem sleeps frageis.

Opcoes

Opcao A - Worker thread no runtime com backend mockavel

Abordagem: runtime cria um worker thread generico que recebe um backend implementando trait testavel.

Pros:

  • testes de contrato mais diretos;
  • menor dependencia do host desktop.

Contras:

  • runtime passa a owns detalhes de thread;
  • precisa cuidado para nao absorver politica de host/window.

Manutenibilidade: boa se o backend for limpo; ruim se virar acoplamento de host dentro do runtime.

Opcao B - Worker thread no host desktop primeiro

Abordagem: implementar o primeiro worker no host winit/pixels e adaptar o runtime a submit/policy.

Pros:

  • valida o caso real visual;
  • encaixa com surface/present/winit.

Contras:

  • mais dificil testar sem janela;
  • risco de contrato ficar host-specific;
  • portabilidade fica menos comprovada.

Manutenibilidade: boa para desktop, menos boa para hardware proprio.

Opcao C - Worker controller runtime + backend host/HAL

Abordagem: criar um controller de worker que implementa handoff, stop token, epoch check e telemetry; o backend concreto vem de host/HAL e pode ser mockado em testes.

Pros:

  • separa contrato de backend;
  • testavel sem janela;
  • mapeia para thread desktop, outro core ou fallback;
  • preserva RenderManager como coordenador.

Contras:

  • desenho inicial mais exigente;
  • depende da preparacao da AGD-0042.

Manutenibilidade: melhor opcao se queremos worker real sem amarrar a winit.

Sugestao / Recomendacao

Recomendo a Opcao C - Worker controller runtime + backend host/HAL.

O primeiro worker real deveria:

  • consumir um handoff thread-safe single-slot;
  • ter stop token e shutdown bounded;
  • checar ownership/epoch antes de present;
  • expor erros tipados;
  • repetir o ultimo frame valido em cadence definida;
  • sincronizar telemetry sem alterar semantica da VM;
  • ter backend fake/mocked para testes de concorrencia.

O host desktop pode ser a primeira integracao concreta, mas nao deve ser o unico lugar onde o contrato e testado.

Perguntas em Aberto

1. Onde vive o worker controller?

Pergunta: O worker controller vive em prometeu-system, prometeu-hal, prometeu-drivers, ou host?

Sugestao: colocar o controller contratual em prometeu-system, proximo de RenderManager, e manter traits pequenas em prometeu-hal quando forem superficie compartilhada. prometeu-drivers deve continuar oferecendo implementacoes locais/testaveis; host desktop deve integrar o controller, nao definir o contrato.

Motivo: o RenderManager ja owns policy de AppMode, ownership/epoch, latest-wins e telemetry. Se o controller nascer apenas no host, a semantica de worker vira desktop-specific e fica mais dificil provar o contrato sem janela nativa.

2. Qual handoff thread-safe usar?

Pergunta: O handoff thread-safe sera Mutex<Option<...>>, canal bounded, atomic slot, ou estrutura propria?

Sugestao: comecar com uma estrutura propria simples baseada em Mutex<Option<RenderSubmission>> + Condvar, encapsulada como single-slot latest-wins. O produtor substitui a pending submission sem bloquear em rasterizacao; o consumidor espera por nova submission ou shutdown.

Motivo: canal bounded tende a preservar historico ou bloquear produtor se nao for usado com cuidado. Um slot explicito modela diretamente a regra ja aceita: nao existe fila crescente, a ultima submissao completa vence.

3. Como modelar current work, shutdown e stale owner?

Pergunta: Como modelar current work para shutdown e stale owner?

Sugestao: separar pending de in_flight. Ao tomar uma submission, o worker carimba in_flight localmente, renderiza, e checa ownership/epoch contra um snapshot atomico ou handle compartilhado antes de present. Shutdown sinaliza stop, acorda o worker e faz join bounded; se houver trabalho em andamento, ele pode terminar rasterizacao, mas nao pode apresentar se o owner/epoch estiver obsoleto ou o stop ja exigir descarte.

Motivo: isso evita que shutdown dependa de cancelar mid-raster em codigo que talvez nao seja cancelavel, mas ainda impede present obsoleto.

4. Quem chama present?

Pergunta: Quem chama present: worker, host event loop, ou display cadence service?

Sugestao: no primeiro corte, o worker deve produzir/publish uma superficie pronta e notificar host invalidation; o host event loop continua sendo autoridade de apresentacao da janela nativa. O "repeat ultimo frame valido" deve ser modelado no controller/telemetry como comportamento de consumo/cadence, mas o swap/window present concreto deve respeitar o host.

Motivo: winit/pixels e plataformas graficas frequentemente tem afinidade com thread/event loop. Colocar o swap real dentro do worker pode funcionar em alguns hosts e quebrar portabilidade. O contrato importante e que a VM nao bloqueie e que o host tenha uma superficie publicada coerente.

5. Como o worker recebe recursos read-only?

Pergunta: Como o worker recebe recursos read-only preparados na AGD-0042?

Sugestao: o primeiro backend deve receber RenderSubmission owned e handles/read-only resource accessors necessarios para resolver glyph/scene banks. Esses accessors devem ser compartilhaveis e imutaveis durante o consumo, evitando &mut Hardware, &mut Gfx e FrameComposer vivo.

Motivo: AGD-0042 eliminou o bridge monolitico exatamente para impedir que o worker dependa do hardware inteiro. A proxima decisao precisa declarar quais recursos sao lidos pelo render backend e como sua estabilidade e garantida durante uma submissao em voo.

6. Qual erro tipado minimo?

Pergunta: Qual erro tipado minimo precisamos no primeiro worker?

Sugestao: introduzir um erro pequeno, por exemplo RenderWorkerError, cobrindo pelo menos: backend unavailable, render failed, present/publish failed, shutdown timeout, stale submission discarded. Panics continuam sendo capturados como falha interna, mas nao devem ser o modelo operacional normal.

Motivo: LocalRenderWorker hoje prova policy, mas nao diferencia falhas reais de render/present. O worker real precisa reportar falhas sem contaminar a VM com detalhes de host.

7. Como provar que a VM nao bloqueia?

Pergunta: Como provar que a VM nao bloqueia quando o worker atrasa?

Sugestao: criar testes deterministas com backend fake controlado por barreiras/condvars, nao sleeps. O teste deve segurar o worker em rasterizacao, produzir frames adicionais no runtime, verificar substituicao latest-wins/drop telemetry, e provar que o tick da VM retorna sem esperar o consumo terminar.

Motivo: sleeps tornam teste de concorrencia fragil. Barreiras permitem provar especificamente a propriedade desejada: produtor nao bloqueia em raster/present lento.

8. Qual primeiro backend real?

Pergunta: Qual sera o primeiro backend real: desktop Gfx/pixels, framebuffer local, ou fake backend?

Sugestao: implementar primeiro um backend fake/mocked para contrato e um backend local framebuffer para integracao sem janela. A integracao desktop deve vir em seguida como consumidor concreto, usando a mesma trait.

Motivo: se o primeiro backend for desktop/winit, o contrato corre risco de nascer acoplado a detalhes de janela. Se o primeiro for fake/local, a semantica do worker fica testavel antes da integracao visual.

Criterio para Encerrar

Esta agenda pode virar decision quando tivermos:

  • local/camada do worker controller;
  • estrutura thread-safe de handoff;
  • trait/backend de render/present;
  • present cadence/repeat;
  • shutdown/current work;
  • error model;
  • test matrix de concorrencia;
  • escopo do primeiro worker real.

Discussion

  • 2026-06-06: Agenda criada dentro da DSC-0042 para separar worker real da preparacao de fronteira discutida em AGD-0042.

Resolution