--- id: AGD-0042 ticket: real-render-worker-establishment title: Real Render Worker Establishment status: open created: 2026-06-06 resolved: decision: tags: [runtime, renderer, worker, concurrency, host, hal, architecture] --- ## Contexto `DEC-0031` fechou a arquitetura base da fronteira VM/render: submissions fechadas, handoff single-slot latest-wins, pacing por `FrameScheduler`, politica explicita por `AppMode`, ownership/epoch e telemetria. A implementacao atual ja tem a base local/sincrona e um `LocalRenderWorker` cooperativo por capability flag. Isso valida o roteamento e a politica, mas ainda nao estabelece um worker real em outra thread/core. O proximo passo arquitetural e transformar esse prototipo em uma unidade de execucao real sem reabrir a decisao base. Esta agenda existe para discutir somente o estabelecimento do worker real. Ela nao deve redecidir `gfx2d` como overlay, o packet boundary, AppMode policy, ou latest-wins; esses pontos pertencem a `DEC-0031`. ## Problema Um worker real precisa cruzar fronteiras que o prototipo local ainda evita: - ownership e lifetime de recursos compartilhados entre VM/logical core e render worker; - como o worker recebe, consome, rasteriza e apresenta submissions sem `&mut Hardware`, `&mut Gfx`, `FrameComposer` vivo ou estado mutavel da VM; - como o viewport cache/read model fica seguro e barato; - como shutdown, stop token, current work e stale owner funcionam quando ha trabalho realmente em voo; - onde fica o present loop e se ele roda a 60Hz independentemente da VM; - como erros de render/present deixam de ser apenas panic containment e viram resultado tipado; - como host desktop, hardware proprio, outro core, DMA ou coprocessador mapeiam para o mesmo contrato. ## Pontos Criticos ### 1. Ownership do worker Precisamos decidir se o worker real pertence ao runtime, ao host, a HAL, ou a uma camada hibrida. `DEC-0031` diz que host/HAL fornece capability concreta, mas `RenderManager` coordena contrato. Falta definir o boundary operacional. ### 2. Surface e backend renderizavel O worker nao pode receber `&mut Hardware` ou `&mut Gfx` da VM thread. Precisamos de um objeto/capability renderizavel que seja owned pelo worker ou mediado por host. ### 3. Recursos read-only e viewport cache Glyph/scene banks ja tem boundary read-only inicial. O viewport cache ainda precisa de um modelo concreto: snapshot, `Arc` read-only, double-buffer cache, cache materializado por frame, ou service proprietario. ### 4. Current work e cancelamento O `RenderManager` ja descarta pending e rejeita stale epoch antes de present. Com worker real, uma submission pode estar em rasterizacao. Precisamos definir stop token, epoch check antes de present, bounded join e descarte de current work. ### 5. Present loop e frame repeat Hoje repeated present e telemetria/hook. Um worker real provavelmente precisa de loop de present/display cadence. Falta decidir se o worker apresenta a 60Hz, se o host faz scanout/repeat, e como isso conversa com `FrameScheduler`. ### 6. Erros tipados `RenderSurface` hoje e infalivel e panic containment vira `PresentFailed`. Para worker real, render/present deveria retornar erro tipado, distinguindo falha recuperavel, backend lost, surface lost, panic, shutdown e stale discard. ### 7. Testabilidade Precisamos de testes que provem thread boundary, latest-wins sob atraso real, shutdown com current work em voo, stale epoch durante rasterizacao, repeat do ultimo frame e ausencia de bloqueio da VM. ## Opcoes ### Opcao A - Worker real dentro do runtime **Abordagem:** `RenderManager` ou um novo `RenderWorkerRuntime` cria e gerencia uma thread de render, canais/slots, stop token e lifecycle. **Pros:** - contrato fica perto de `RenderManager`; - facil testar com runtime puro; - menos dependencia de host desktop. **Contras:** - risco de runtime assumir detalhes de surface/window que pertencem ao host; - pode ficar ruim para hardware proprio, DMA ou coprocessador; - exige abstrair muito bem o backend renderizavel. **Manutenibilidade:** boa se o backend for uma trait pequena e owned pelo worker; ruim se vazar `Hardware`/`Gfx` vivo. ### Opcao B - Worker real como responsabilidade do host **Abordagem:** runtime fecha submissions e handoff; host implementa thread/core/present loop usando uma capability HAL/host. **Pros:** - encaixa melhor desktop windowing, swapchain, surface lost e display cadence; - facilita mapeamento para plataformas diferentes; - runtime continua sem detalhe de thread/window. **Contras:** - testes de contrato podem ficar mais integrados e menos unitarios; - risco de cada host reinterpretar o contrato; - `RenderManager` precisa expor hooks suficientes sem virar passivo demais. **Manutenibilidade:** boa para plataformas diversas, desde que exista uma suite de contrato obrigatoria. ### Opcao C - Worker como HAL/backend owned, coordenado pelo runtime **Abordagem:** runtime possui `RenderManager` e policy; HAL/host fornece um `RenderBackend`/`RenderWorkerBackend` owned e thread-safe. Um `RenderWorkerController` conecta handoff, stop token, epoch e telemetry. **Pros:** - separa contrato runtime de implementacao de host; - permite worker thread no desktop e outro core/DMA em hardware; - cria ponto unico para testes de contrato; - evita passar `&mut Hardware` ou `&mut Gfx` pela fronteira. **Contras:** - mais desenho inicial; - exige definir traits novas com cuidado; - pode ser excessivo se o primeiro worker real for apenas desktop. **Manutenibilidade:** melhor direcao se quisermos preservar portabilidade e nao acoplar runtime a winit/surface. ### Opcao D - Adiar worker real e manter prototipo local **Abordagem:** nao implementar worker real agora; apenas fortalecer testes/spec e manter `LocalRenderWorker`. **Pros:** - menor risco imediato; - evita mexer em host/surface antes da necessidade real. **Contras:** - nao valida thread/core real; - deixa lacunas de Send/Sync, shutdown current work e present cadence; - pode mascarar problemas de ownership ate tarde. **Manutenibilidade:** aceitavel por curto prazo, fraca se a demanda agora e paralelismo real. ## Sugestao / Recomendacao Recomendo seguir pela **Opcao C - Worker como HAL/backend owned, coordenado pelo runtime**. O desenho deve manter `RenderManager` como dono de policy, epoch, handoff e telemetry, mas introduzir uma camada operacional para worker real com: - backend/render surface owned pelo worker ou pelo host; - handoff single-slot sem bloquear VM; - stop token e bounded shutdown; - check de epoch/owner antes de present; - erro tipado para render/present; - present cadence explicita, com repeat do ultimo frame quando nao houver submission nova; - testes de contrato que rodem sem janela nativa sempre que possivel. Essa recomendacao preserva `DEC-0031` e evita transformar o runtime puro em dono de detalhes de window/swapchain. ## Perguntas em Aberto - [ ] O primeiro worker real deve nascer no host desktop/winit ou em uma abstracao runtime/HAL testavel sem janela? - [ ] Qual trait substitui `RenderSurface::consume_submission(&RenderSubmission) -> ()` para erro tipado? - [ ] O worker owns `Gfx`/framebuffer, ou `Gfx` continua em `Hardware` e precisa ser dividido? - [ ] Como o viewport cache sera exposto ao worker: snapshot por frame, `Arc` read-only, double-buffer, ou service proprietario? - [ ] Quem roda o present loop de 60Hz: worker, host event loop, ou uma autoridade de display separada? - [ ] Como testar current work em voo sem depender de sleeps/flakiness? - [ ] Como mapear shutdown: stop accepting, discard pending, cancel current, join bounded, preserve last surface? - [ ] Quais tipos precisam de prova `Send + Sync` antes do primeiro worker real? - [ ] Shell continua fora do worker no primeiro passo, ou devemos provar explicitamente que capability Game nao afeta Shell? ## Criterio para Encerrar Esta agenda pode virar decision quando tivermos uma resposta clara para: - ownership/layer responsavel pelo worker real; - trait/backend de render/present e modelo de erro; - modelo de recurso read-only, especialmente viewport cache; - protocolo de shutdown/current work; - present cadence/repeat; - plano de testes para thread/core real; - escopo do primeiro worker real, incluindo o que fica explicitamente fora. ## Discussion - 2026-06-06: Agenda criada apos a execucao de `DSC-0040`, que fechou a arquitetura base mas deixou o worker real como etapa futura deliberada. ## Resolution