173 lines
8.3 KiB
Markdown
173 lines
8.3 KiB
Markdown
---
|
|
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
|