224 lines
11 KiB
Markdown
224 lines
11 KiB
Markdown
---
|
|
id: AGD-0043
|
|
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` 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
|